@@ -20,7 +20,7 @@ pub const RUSTC_SPECIAL_FEATURES: &[&str] = &["backchain"];
2020/// `AllowToggle` is the type storing whether (un)stable features can be toggled:
2121/// this is initially a function since it can depend on `Target`, but for stable hashing
2222/// it needs to be something hashable to we have to make the type generic.
23- #[ derive( Debug , Clone , Copy ) ]
23+ #[ derive( Debug , Clone ) ]
2424pub enum Stability < AllowToggle > {
2525 /// This target feature is stable, it can be used in `#[target_feature]` and
2626 /// `#[cfg(target_feature)]`.
@@ -44,11 +44,21 @@ pub enum Stability<AllowToggle> {
4444 Forbidden { reason : & ' static str } ,
4545}
4646
47- /// `Stability` where `allow_toggle` has not been computed yet.
4847/// Returns `Ok` if the toggle is allowed, `Err` with an explanation of not.
49- pub type StabilityUncomputed = Stability < fn ( & Target ) -> Result < ( ) , & ' static str > > ;
48+ /// The `bool` indicates whether the feature is being enabled (`true`) or disabled.
49+ pub type AllowToggleUncomputed = fn ( & Target , bool ) -> Result < ( ) , & ' static str > ;
50+
51+ /// The computed result of whether a feature can be enabled/disabled on the current target.
52+ #[ derive( Debug , Clone ) ]
53+ pub struct AllowToggleComputed {
54+ enable : Result < ( ) , & ' static str > ,
55+ disable : Result < ( ) , & ' static str > ,
56+ }
57+
58+ /// `Stability` where `allow_toggle` has not been computed yet.
59+ pub type StabilityUncomputed = Stability < AllowToggleUncomputed > ;
5060/// `Stability` where `allow_toggle` has already been computed.
51- pub type StabilityComputed = Stability < Result < ( ) , & ' static str > > ;
61+ pub type StabilityComputed = Stability < AllowToggleComputed > ;
5262
5363impl < CTX , AllowToggle : HashStable < CTX > > HashStable < CTX > for Stability < AllowToggle > {
5464 #[ inline]
@@ -69,51 +79,74 @@ impl<CTX, AllowToggle: HashStable<CTX>> HashStable<CTX> for Stability<AllowToggl
6979 }
7080}
7181
82+ impl < CTX > HashStable < CTX > for AllowToggleComputed {
83+ #[ inline]
84+ fn hash_stable ( & self , hcx : & mut CTX , hasher : & mut StableHasher ) {
85+ let AllowToggleComputed { enable, disable } = self ;
86+ enable. hash_stable ( hcx, hasher) ;
87+ disable. hash_stable ( hcx, hasher) ;
88+ }
89+ }
90+
7291impl < AllowToggle > Stability < AllowToggle > {
7392 /// Returns whether the feature can be queried in `cfg` ever.
7493 /// (It might still be nightly-only even if this returns `true`).
75- pub fn in_cfg ( self ) -> bool {
94+ pub fn in_cfg ( & self ) -> bool {
7695 !matches ! ( self , Stability :: Forbidden { .. } )
7796 }
7897
7998 /// Returns the nightly feature that is required to toggle or query this target feature. Ensure
8099 /// to also check `allow_toggle()` before allowing to toggle!
81- pub fn requires_nightly ( self ) -> Option < Symbol > {
100+ pub fn requires_nightly ( & self ) -> Option < Symbol > {
82101 match self {
83- Stability :: Unstable { nightly_feature, .. } => Some ( nightly_feature) ,
84- Stability :: Stable { .. } => None ,
85- Stability :: Forbidden { .. } => panic ! ( "forbidden features should not reach this far" ) ,
102+ & Stability :: Unstable { nightly_feature, .. } => Some ( nightly_feature) ,
103+ & Stability :: Stable { .. } => None ,
104+ & Stability :: Forbidden { .. } => panic ! ( "forbidden features should not reach this far" ) ,
86105 }
87106 }
88107}
89108
90109impl StabilityUncomputed {
91- pub fn compute ( self , target : & Target ) -> StabilityComputed {
110+ pub fn compute ( & self , target : & Target ) -> StabilityComputed {
92111 use Stability :: * ;
112+ let compute = |f : AllowToggleUncomputed | AllowToggleComputed {
113+ enable : f ( target, true ) ,
114+ disable : f ( target, false ) ,
115+ } ;
93116 match self {
94- Stable { allow_toggle } => Stable { allow_toggle : allow_toggle ( target ) } ,
95- Unstable { nightly_feature, allow_toggle } => {
96- Unstable { nightly_feature, allow_toggle : allow_toggle ( target ) }
117+ & Stable { allow_toggle } => Stable { allow_toggle : compute ( allow_toggle ) } ,
118+ & Unstable { nightly_feature, allow_toggle } => {
119+ Unstable { nightly_feature, allow_toggle : compute ( allow_toggle ) }
97120 }
98- Forbidden { reason } => Forbidden { reason } ,
121+ & Forbidden { reason } => Forbidden { reason } ,
122+ }
123+ }
124+
125+ pub fn allow_toggle ( & self , target : & Target , enable : bool ) -> Result < ( ) , & ' static str > {
126+ use Stability :: * ;
127+ match self {
128+ & Stable { allow_toggle } => allow_toggle ( target, enable) ,
129+ & Unstable { allow_toggle, .. } => allow_toggle ( target, enable) ,
130+ & Forbidden { reason } => Err ( reason) ,
99131 }
100132 }
101133}
102134
103135impl StabilityComputed {
104- pub fn allow_toggle ( self ) -> Result < ( ) , & ' static str > {
105- match self {
136+ pub fn allow_toggle ( & self , enable : bool ) -> Result < ( ) , & ' static str > {
137+ let allow_toggle = match self {
106138 Stability :: Stable { allow_toggle } => allow_toggle,
107139 Stability :: Unstable { allow_toggle, .. } => allow_toggle,
108- Stability :: Forbidden { reason } => Err ( reason) ,
109- }
140+ Stability :: Forbidden { reason } => return Err ( reason) ,
141+ } ;
142+ if enable { allow_toggle. enable } else { allow_toggle. disable }
110143 }
111144}
112145
113146// Constructors for the list below, defaulting to "always allow toggle".
114- const STABLE : StabilityUncomputed = Stability :: Stable { allow_toggle : |_target| Ok ( ( ) ) } ;
147+ const STABLE : StabilityUncomputed = Stability :: Stable { allow_toggle : |_target, _enable | Ok ( ( ) ) } ;
115148const fn unstable ( nightly_feature : Symbol ) -> StabilityUncomputed {
116- Stability :: Unstable { nightly_feature, allow_toggle : |_target| Ok ( ( ) ) }
149+ Stability :: Unstable { nightly_feature, allow_toggle : |_target, _enable | Ok ( ( ) ) }
117150}
118151
119152// Here we list target features that rustc "understands": they can be used in `#[target_feature]`
@@ -174,7 +207,7 @@ const ARM_FEATURES: &[(&str, StabilityUncomputed, ImpliedFeatures)] = &[
174207 "fpregs" ,
175208 Stability :: Unstable {
176209 nightly_feature : sym:: arm_target_feature,
177- allow_toggle : |target : & Target | {
210+ allow_toggle : |target : & Target , _enable | {
178211 // Only allow toggling this if the target has `soft-float` set. With `soft-float`,
179212 // `fpregs` isn't needed so changing it cannot affect the ABI.
180213 if target. has_feature ( "soft-float" ) {
@@ -465,7 +498,7 @@ const X86_FEATURES: &[(&str, StabilityUncomputed, ImpliedFeatures)] = &[
465498 "x87" ,
466499 Stability :: Unstable {
467500 nightly_feature : sym:: x87_target_feature,
468- allow_toggle : |target : & Target | {
501+ allow_toggle : |target : & Target , _enable | {
469502 // Only allow toggling this if the target has `soft-float` set. With `soft-float`,
470503 // `fpregs` isn't needed so changing it cannot affect the ABI.
471504 if target. has_feature ( "soft-float" ) {
0 commit comments