@@ -702,6 +702,12 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
702702 // We use `intrinsic.const_stable` to determine if this can be safely exposed to
703703 // stable code, rather than `const_stable_indirect`. This is to make
704704 // `#[rustc_const_stable_indirect]` an attribute that is always safe to add.
705+ // We also ask is_safe_to_expose_on_stable_const_fn; this determines whether the intrinsic
706+ // fallback body is safe to expose on stable.
707+ let is_const_stable = intrinsic. const_stable
708+ || ( !intrinsic. must_be_overridden
709+ && tcx. is_const_fn ( callee)
710+ && is_safe_to_expose_on_stable_const_fn ( tcx, callee) ) ;
705711 match tcx. lookup_const_stability ( callee) {
706712 None => {
707713 // Non-const intrinsic.
@@ -711,7 +717,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
711717 // Intrinsic does not need a separate feature gate (we rely on the
712718 // regular stability checker). However, we have to worry about recursive
713719 // const stability.
714- if !intrinsic . const_stable && self . enforce_recursive_const_stability ( ) {
720+ if !is_const_stable && self . enforce_recursive_const_stability ( ) {
715721 self . dcx ( ) . emit_err ( errors:: UnmarkedIntrinsicExposed {
716722 span : self . span ,
717723 def_path : self . tcx . def_path_str ( callee) ,
@@ -726,12 +732,14 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
726732 self . check_op ( ops:: IntrinsicUnstable {
727733 name : intrinsic. name ,
728734 feature,
729- const_stable : intrinsic . const_stable ,
735+ const_stable : is_const_stable ,
730736 } ) ;
731737 }
732738 Some ( ConstStability { level : StabilityLevel :: Stable { .. } , .. } ) => {
733- // All good. But ensure this is indeed a const-stable intrinsic.
734- assert ! ( intrinsic. const_stable) ;
739+ // All good. Note that a `#[rustc_const_stable]` intrinsic (meaning it
740+ // can be *directly* invoked from stable const code) does not always
741+ // have the `#[rustc_const_stable_intrinsic]` attribute (which controls
742+ // exposing an intrinsic indirectly); we accept this call anyway.
735743 }
736744 }
737745 // This completes the checks for intrinsics.
0 commit comments