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