@@ -315,7 +315,7 @@ fn check_place(
315315}
316316
317317/// 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 {
319319 // All features require that the corresponding gate be enabled,
320320 // even if the function has `#[allow_internal_unstable(the_gate)]`.
321321 if !tcx. features ( ) . enabled ( feature_gate) {
@@ -334,6 +334,26 @@ pub fn feature_allowed(tcx: TyCtxt<'tcx>, def_id: DefId, feature_gate: Symbol) -
334334 . map_or ( false , |mut features| features. any ( |name| name == feature_gate) )
335335}
336336
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+
337357fn check_terminator (
338358 tcx : TyCtxt < ' tcx > ,
339359 body : & ' a Body < ' tcx > ,
@@ -383,7 +403,8 @@ fn check_terminator(
383403 if !crate :: const_eval:: is_min_const_fn ( tcx, fn_def_id)
384404 && !crate :: const_eval:: is_unstable_const_fn ( tcx, fn_def_id)
385405 . 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)
387408 } )
388409 . unwrap_or ( false )
389410 {
0 commit comments