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 } ;
@@ -818,7 +819,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
818
819
}
819
820
}
820
821
Some ( ConstStability {
821
- level : StabilityLevel :: Unstable { implied_by : implied_feature, .. } ,
822
+ level : StabilityLevel :: Unstable { implied_by : implied_feature, issue , .. } ,
822
823
feature,
823
824
..
824
825
} ) => {
@@ -841,7 +842,23 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
841
842
// to allow this.
842
843
let feature_enabled = callee. is_local ( )
843
844
|| tcx. features ( ) . enabled ( feature)
844
- || implied_feature. is_some_and ( |f| tcx. features ( ) . enabled ( f) ) ;
845
+ || implied_feature. is_some_and ( |f| tcx. features ( ) . enabled ( f) )
846
+ || {
847
+ // When we're compiling the compiler itself we may pull in
848
+ // crates from crates.io, but those crates may depend on other
849
+ // crates also pulled in from crates.io. We want to ideally be
850
+ // able to compile everything without requiring upstream
851
+ // modifications, so in the case that this looks like a
852
+ // `rustc_private` crate (e.g., a compiler crate) and we also have
853
+ // the `-Z force-unstable-if-unmarked` flag present (we're
854
+ // compiling a compiler crate), then let this missing feature
855
+ // annotation slide.
856
+ // This matches what we do in `eval_stability_allow_unstable` for
857
+ // regular stability.
858
+ feature == sym:: rustc_private
859
+ && issue == NonZero :: new ( 27812 )
860
+ && self . tcx . sess . opts . unstable_opts . force_unstable_if_unmarked
861
+ } ;
845
862
// We do *not* honor this if we are in the "danger zone": we have to enforce
846
863
// recursive const-stability and the callee is not safe-to-expose. In that
847
864
// case we need `check_op` to do the check.
0 commit comments