@@ -23,7 +23,6 @@ use rustc_mir_dataflow::storage::always_storage_live_locals;
2323use rustc_span:: { DUMMY_SP , Span , Symbol , sym} ;
2424use rustc_trait_selection:: error_reporting:: InferCtxtErrorExt ;
2525use rustc_trait_selection:: traits:: { self , ObligationCauseCode , ObligationCtxt } ;
26- use smallvec:: SmallVec ;
2726use tracing:: { debug, instrument, trace} ;
2827
2928use super :: ops:: { self , NonConstOp , Status } ;
@@ -720,7 +719,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
720719 self . check_op ( ops:: IntrinsicNonConst { name : intrinsic. name } ) ;
721720 }
722721 Some ( ConstStability {
723- level : ConstStabilityLevel :: Implicit ,
722+ level : ConstStabilityLevel :: ImplicitUnstable ,
724723 const_stable_indirect,
725724 ..
726725 } ) => {
@@ -776,7 +775,10 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
776775 Some ( ConstStability { level : ConstStabilityLevel :: Stable { .. } , .. } ) => {
777776 // All good.
778777 }
779- None | Some ( ConstStability { level : ConstStabilityLevel :: Implicit , .. } ) => {
778+ None
779+ | Some ( ConstStability {
780+ level : ConstStabilityLevel :: ImplicitUnstable , ..
781+ } ) => {
780782 // This doesn't need a separate const-stability check -- const-stability equals
781783 // regular stability, and regular stability is checked separately.
782784 // However, we *do* have to worry about *recursive* const stability.
@@ -799,43 +801,33 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
799801
800802 // We only honor `span.allows_unstable` aka `#[allow_internal_unstable]` if
801803 // the callee is safe to expose, to avoid bypassing recursive stability.
802- let is_allowed_unstable = |u : & rustc_attr:: Unstability | {
803- callee_safe_to_expose_on_stable
804- && ( self . span . allows_unstable ( u. feature )
805- || u. implied_by . is_some_and ( |f| self . span . allows_unstable ( f) ) )
806- } ;
807- let mut needs_check =
808- unstables. iter ( ) . filter ( |u| !is_allowed_unstable ( u) ) . peekable ( ) ;
809- if needs_check. peek ( ) . is_none ( ) {
804+ if callee_safe_to_expose_on_stable
805+ && unstables. iter ( ) . all ( |u| {
806+ self . span . allows_unstable ( u. feature )
807+ || u. implied_by . is_some_and ( |f| self . span . allows_unstable ( f) )
808+ } )
809+ {
810810 return ;
811811 }
812812
813813 // We can't use `check_op` to check whether the feature is enabled because
814814 // the logic is a bit different than elsewhere: local functions don't need
815815 // the feature gate, and there might be an "implied" gate that also suffices
816816 // to allow this.
817- let is_feature_enabled = | u : & rustc_attr :: Unstability | {
818- callee . is_local ( )
819- || tcx. features ( ) . enabled ( u. feature )
820- || u. implied_by . is_some_and ( |f| tcx. features ( ) . enabled ( f) )
821- } ;
817+ let features_enabled = callee . is_local ( )
818+ || unstables . iter ( ) . all ( |u| {
819+ tcx. features ( ) . enabled ( u. feature )
820+ || u. implied_by . is_some_and ( |f| tcx. features ( ) . enabled ( f) )
821+ } ) ;
822822 // We do *not* honor this if we are in the "danger zone": we have to enforce
823823 // recursive const-stability and the callee is not safe-to-expose. In that
824824 // case we need `check_op` to do the check.
825825 let danger_zone = !callee_safe_to_expose_on_stable
826826 && self . enforce_recursive_const_stability ( ) ;
827- let missing_features: SmallVec < [ _ ; 1 ] > = if danger_zone {
828- needs_check. map ( |u| u. into ( ) ) . collect ( )
829- } else {
830- needs_check
831- . filter ( |u| !is_feature_enabled ( u) )
832- . map ( |u| u. into ( ) )
833- . collect ( )
834- } ;
835- if !missing_features. is_empty ( ) {
827+ if danger_zone || !features_enabled {
836828 self . check_op ( ops:: FnCallUnstable {
837829 def_id : callee,
838- features : missing_features ,
830+ features : unstables . iter ( ) . map ( |u| u . into ( ) ) . collect ( ) ,
839831 reason : * reason,
840832 safe_to_expose_on_stable : callee_safe_to_expose_on_stable,
841833 } ) ;
0 commit comments