@@ -315,7 +315,7 @@ fn check_place(
315
315
}
316
316
317
317
/// Returns `true` if the given feature gate is allowed within the function with the given `DefId`.
318
- pub fn feature_allowed ( tcx : TyCtxt < ' tcx > , def_id : DefId , feature_gate : Symbol ) -> bool {
318
+ fn feature_allowed ( tcx : TyCtxt < ' tcx > , def_id : DefId , feature_gate : Symbol ) -> bool {
319
319
// All features require that the corresponding gate be enabled,
320
320
// even if the function has `#[allow_internal_unstable(the_gate)]`.
321
321
if !tcx. features ( ) . enabled ( feature_gate) {
@@ -334,6 +334,26 @@ pub fn feature_allowed(tcx: TyCtxt<'tcx>, def_id: DefId, feature_gate: Symbol) -
334
334
. map_or ( false , |mut features| features. any ( |name| name == feature_gate) )
335
335
}
336
336
337
+ /// Returns `true` if the given library feature gate is allowed within the function with the given `DefId`.
338
+ pub fn lib_feature_allowed ( tcx : TyCtxt < ' tcx > , def_id : DefId , feature_gate : Symbol ) -> bool {
339
+ // All features require that the corresponding gate be enabled,
340
+ // even if the function has `#[allow_internal_unstable(the_gate)]`.
341
+ if !tcx. features ( ) . declared_lib_features . iter ( ) . any ( |& ( sym, _) | sym == feature_gate) {
342
+ return false ;
343
+ }
344
+
345
+ // If this crate is not using stability attributes, or this function is not claiming to be a
346
+ // stable `const fn`, that is all that is required.
347
+ if !tcx. features ( ) . staged_api || tcx. has_attr ( def_id, sym:: rustc_const_unstable) {
348
+ return true ;
349
+ }
350
+
351
+ // However, we cannot allow stable `const fn`s to use unstable features without an explicit
352
+ // opt-in via `allow_internal_unstable`.
353
+ attr:: allow_internal_unstable ( & tcx. get_attrs ( def_id) , & tcx. sess . diagnostic ( ) )
354
+ . map_or ( false , |mut features| features. any ( |name| name == feature_gate) )
355
+ }
356
+
337
357
fn check_terminator (
338
358
tcx : TyCtxt < ' tcx > ,
339
359
body : & ' a Body < ' tcx > ,
@@ -383,7 +403,8 @@ fn check_terminator(
383
403
if !crate :: const_eval:: is_min_const_fn ( tcx, fn_def_id)
384
404
&& !crate :: const_eval:: is_unstable_const_fn ( tcx, fn_def_id)
385
405
. map ( |feature| {
386
- span. allows_unstable ( feature) || feature_allowed ( tcx, def_id, feature)
406
+ span. allows_unstable ( feature)
407
+ || lib_feature_allowed ( tcx, def_id, feature)
387
408
} )
388
409
. unwrap_or ( false )
389
410
{
0 commit comments