@@ -736,16 +736,25 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
736
736
737
737
// Intrinsics are language primitives, not regular calls, so treat them separately.
738
738
if let Some ( intrinsic) = tcx. intrinsic ( callee) {
739
+ // We use `intrinsic.const_stable` to determine if this can be safely exposed to
740
+ // stable code, rather than `const_stable_indirect`. This is to make
741
+ // `#[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) ) ;
739
748
match tcx. lookup_const_stability ( callee) {
740
749
None => {
741
750
// Non-const intrinsic.
742
751
self . check_op ( ops:: IntrinsicNonConst { name : intrinsic. name } ) ;
743
752
}
744
- Some ( ConstStability { feature : None , const_stable_indirect , .. } ) => {
753
+ Some ( ConstStability { feature : None , .. } ) => {
745
754
// Intrinsic does not need a separate feature gate (we rely on the
746
755
// regular stability checker). However, we have to worry about recursive
747
756
// const stability.
748
- if !const_stable_indirect && self . enforce_recursive_const_stability ( ) {
757
+ if !is_const_stable && self . enforce_recursive_const_stability ( ) {
749
758
self . dcx ( ) . emit_err ( errors:: UnmarkedIntrinsicExposed {
750
759
span : self . span ,
751
760
def_path : self . tcx . def_path_str ( callee) ,
@@ -755,17 +764,19 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
755
764
Some ( ConstStability {
756
765
feature : Some ( feature) ,
757
766
level : StabilityLevel :: Unstable { .. } ,
758
- const_stable_indirect,
759
767
..
760
768
} ) => {
761
769
self . check_op ( ops:: IntrinsicUnstable {
762
770
name : intrinsic. name ,
763
771
feature,
764
- const_stable_indirect ,
772
+ const_stable : is_const_stable ,
765
773
} ) ;
766
774
}
767
775
Some ( ConstStability { level : StabilityLevel :: Stable { .. } , .. } ) => {
768
- // All good.
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.
769
780
}
770
781
}
771
782
// This completes the checks for intrinsics.
0 commit comments