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 } ;
@@ -780,7 +781,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
780
781
}
781
782
}
782
783
Some ( ConstStability {
783
- level : StabilityLevel :: Unstable { implied_by : implied_feature, .. } ,
784
+ level : StabilityLevel :: Unstable { implied_by : implied_feature, issue , .. } ,
784
785
feature,
785
786
..
786
787
} ) => {
@@ -803,7 +804,23 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
803
804
// to allow this.
804
805
let feature_enabled = callee. is_local ( )
805
806
|| tcx. features ( ) . enabled ( feature)
806
- || implied_feature. is_some_and ( |f| tcx. features ( ) . enabled ( f) ) ;
807
+ || implied_feature. is_some_and ( |f| tcx. features ( ) . enabled ( f) )
808
+ || {
809
+ // When we're compiling the compiler itself we may pull in
810
+ // crates from crates.io, but those crates may depend on other
811
+ // crates also pulled in from crates.io. We want to ideally be
812
+ // able to compile everything without requiring upstream
813
+ // modifications, so in the case that this looks like a
814
+ // `rustc_private` crate (e.g., a compiler crate) and we also have
815
+ // the `-Z force-unstable-if-unmarked` flag present (we're
816
+ // compiling a compiler crate), then let this missing feature
817
+ // annotation slide.
818
+ // This matches what we do in `eval_stability_allow_unstable` for
819
+ // regular stability.
820
+ feature == sym:: rustc_private
821
+ && issue == NonZero :: new ( 27812 )
822
+ && self . tcx . sess . opts . unstable_opts . force_unstable_if_unmarked
823
+ } ;
807
824
// We do *not* honor this if we are in the "danger zone": we have to enforce
808
825
// recursive const-stability and the callee is not safe-to-expose. In that
809
826
// case we need `check_op` to do the check.
0 commit comments