@@ -739,6 +739,12 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
739739 // We use `intrinsic.const_stable` to determine if this can be safely exposed to
740740 // stable code, rather than `const_stable_indirect`. This is to make
741741 // `#[rustc_const_stable_indirect]` an attribute that is always safe to add.
742+ // We also ask is_safe_to_expose_on_stable_const_fn; this determines whether the intrinsic
743+ // fallback body is safe to expose on stable.
744+ let is_const_stable = intrinsic. const_stable
745+ || ( !intrinsic. must_be_overridden
746+ && tcx. is_const_fn ( callee)
747+ && is_safe_to_expose_on_stable_const_fn ( tcx, callee) ) ;
742748 match tcx. lookup_const_stability ( callee) {
743749 None => {
744750 // Non-const intrinsic.
@@ -748,7 +754,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
748754 // Intrinsic does not need a separate feature gate (we rely on the
749755 // regular stability checker). However, we have to worry about recursive
750756 // const stability.
751- if !intrinsic . const_stable && self . enforce_recursive_const_stability ( ) {
757+ if !is_const_stable && self . enforce_recursive_const_stability ( ) {
752758 self . dcx ( ) . emit_err ( errors:: UnmarkedIntrinsicExposed {
753759 span : self . span ,
754760 def_path : self . tcx . def_path_str ( callee) ,
@@ -763,12 +769,14 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
763769 self . check_op ( ops:: IntrinsicUnstable {
764770 name : intrinsic. name ,
765771 feature,
766- const_stable : intrinsic . const_stable ,
772+ const_stable : is_const_stable ,
767773 } ) ;
768774 }
769775 Some ( ConstStability { level : StabilityLevel :: Stable { .. } , .. } ) => {
770- // All good. But ensure this is indeed a const-stable intrinsic.
771- assert ! ( intrinsic. const_stable) ;
776+ // All good. Note that a `#[rustc_const_stable]` intrinsic (meaning it
777+ // can be *directly* invoked from stable const code) does not always
778+ // have the `#[rustc_const_stable_intrinsic]` attribute (which controls
779+ // exposing an intrinsic indirectly); we accept this call anyway.
772780 }
773781 }
774782 // This completes the checks for intrinsics.
0 commit comments