3
3
use std:: assert_matches:: assert_matches;
4
4
use std:: borrow:: Cow ;
5
5
use std:: mem;
6
+ use std:: num:: NonZero ;
6
7
use std:: ops:: Deref ;
7
8
8
9
use rustc_attr:: { ConstStability , StabilityLevel } ;
@@ -789,7 +790,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
789
790
}
790
791
}
791
792
Some ( ConstStability {
792
- level : StabilityLevel :: Unstable { implied_by : implied_feature, .. } ,
793
+ level : StabilityLevel :: Unstable { implied_by : implied_feature, issue , .. } ,
793
794
feature,
794
795
..
795
796
} ) => {
@@ -812,7 +813,23 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
812
813
// to allow this.
813
814
let feature_enabled = callee. is_local ( )
814
815
|| tcx. features ( ) . enabled ( feature)
815
- || implied_feature. is_some_and ( |f| tcx. features ( ) . enabled ( f) ) ;
816
+ || implied_feature. is_some_and ( |f| tcx. features ( ) . enabled ( f) )
817
+ || {
818
+ // When we're compiling the compiler itself we may pull in
819
+ // crates from crates.io, but those crates may depend on other
820
+ // crates also pulled in from crates.io. We want to ideally be
821
+ // able to compile everything without requiring upstream
822
+ // modifications, so in the case that this looks like a
823
+ // `rustc_private` crate (e.g., a compiler crate) and we also have
824
+ // the `-Z force-unstable-if-unmarked` flag present (we're
825
+ // compiling a compiler crate), then let this missing feature
826
+ // annotation slide.
827
+ // This matches what we do in `eval_stability_allow_unstable` for
828
+ // regular stability.
829
+ feature == sym:: rustc_private
830
+ && issue == NonZero :: new ( 27812 )
831
+ && self . tcx . sess . opts . unstable_opts . force_unstable_if_unmarked
832
+ } ;
816
833
// We do *not* honor this if we are in the "danger zone": we have to enforce
817
834
// recursive const-stability and the callee is not safe-to-expose. In that
818
835
// case we need `check_op` to do the check.
0 commit comments