@@ -702,6 +702,12 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
702
702
// We use `intrinsic.const_stable` to determine if this can be safely exposed to
703
703
// stable code, rather than `const_stable_indirect`. This is to make
704
704
// `#[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) ) ;
705
711
match tcx. lookup_const_stability ( callee) {
706
712
None => {
707
713
// Non-const intrinsic.
@@ -711,7 +717,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
711
717
// Intrinsic does not need a separate feature gate (we rely on the
712
718
// regular stability checker). However, we have to worry about recursive
713
719
// const stability.
714
- if !intrinsic . const_stable && self . enforce_recursive_const_stability ( ) {
720
+ if !is_const_stable && self . enforce_recursive_const_stability ( ) {
715
721
self . dcx ( ) . emit_err ( errors:: UnmarkedIntrinsicExposed {
716
722
span : self . span ,
717
723
def_path : self . tcx . def_path_str ( callee) ,
@@ -726,12 +732,14 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
726
732
self . check_op ( ops:: IntrinsicUnstable {
727
733
name : intrinsic. name ,
728
734
feature,
729
- const_stable : intrinsic . const_stable ,
735
+ const_stable : is_const_stable ,
730
736
} ) ;
731
737
}
732
738
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.
735
743
}
736
744
}
737
745
// This completes the checks for intrinsics.
0 commit comments