@@ -20,7 +20,7 @@ pub const RUSTC_SPECIAL_FEATURES: &[&str] = &["backchain"];
20
20
/// `AllowToggle` is the type storing whether (un)stable features can be toggled:
21
21
/// this is initially a function since it can depend on `Target`, but for stable hashing
22
22
/// it needs to be something hashable to we have to make the type generic.
23
- #[ derive( Debug , Clone , Copy ) ]
23
+ #[ derive( Debug , Clone ) ]
24
24
pub enum Stability < AllowToggle > {
25
25
/// This target feature is stable, it can be used in `#[target_feature]` and
26
26
/// `#[cfg(target_feature)]`.
@@ -44,11 +44,21 @@ pub enum Stability<AllowToggle> {
44
44
Forbidden { reason : & ' static str } ,
45
45
}
46
46
47
- /// `Stability` where `allow_toggle` has not been computed yet.
48
47
/// 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 > ;
50
60
/// `Stability` where `allow_toggle` has already been computed.
51
- pub type StabilityComputed = Stability < Result < ( ) , & ' static str > > ;
61
+ pub type StabilityComputed = Stability < AllowToggleComputed > ;
52
62
53
63
impl < CTX , AllowToggle : HashStable < CTX > > HashStable < CTX > for Stability < AllowToggle > {
54
64
#[ inline]
@@ -69,51 +79,74 @@ impl<CTX, AllowToggle: HashStable<CTX>> HashStable<CTX> for Stability<AllowToggl
69
79
}
70
80
}
71
81
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
+
72
91
impl < AllowToggle > Stability < AllowToggle > {
73
92
/// Returns whether the feature can be queried in `cfg` ever.
74
93
/// (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 {
76
95
!matches ! ( self , Stability :: Forbidden { .. } )
77
96
}
78
97
79
98
/// Returns the nightly feature that is required to toggle or query this target feature. Ensure
80
99
/// 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 > {
82
101
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" ) ,
86
105
}
87
106
}
88
107
}
89
108
90
109
impl StabilityUncomputed {
91
- pub fn compute ( self , target : & Target ) -> StabilityComputed {
110
+ pub fn compute ( & self , target : & Target ) -> StabilityComputed {
92
111
use Stability :: * ;
112
+ let compute = |f : AllowToggleUncomputed | AllowToggleComputed {
113
+ enable : f ( target, true ) ,
114
+ disable : f ( target, false ) ,
115
+ } ;
93
116
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 ) }
97
120
}
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) ,
99
131
}
100
132
}
101
133
}
102
134
103
135
impl 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 {
106
138
Stability :: Stable { allow_toggle } => allow_toggle,
107
139
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 }
110
143
}
111
144
}
112
145
113
146
// 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 ( ( ) ) } ;
115
148
const 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 ( ( ) ) }
117
150
}
118
151
119
152
// 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)] = &[
174
207
"fpregs" ,
175
208
Stability :: Unstable {
176
209
nightly_feature : sym:: arm_target_feature,
177
- allow_toggle : |target : & Target | {
210
+ allow_toggle : |target : & Target , _enable | {
178
211
// Only allow toggling this if the target has `soft-float` set. With `soft-float`,
179
212
// `fpregs` isn't needed so changing it cannot affect the ABI.
180
213
if target. has_feature ( "soft-float" ) {
@@ -471,7 +504,7 @@ const X86_FEATURES: &[(&str, StabilityUncomputed, ImpliedFeatures)] = &[
471
504
"x87" ,
472
505
Stability :: Unstable {
473
506
nightly_feature : sym:: x87_target_feature,
474
- allow_toggle : |target : & Target | {
507
+ allow_toggle : |target : & Target , _enable | {
475
508
// Only allow toggling this if the target has `soft-float` set. With `soft-float`,
476
509
// `fpregs` isn't needed so changing it cannot affect the ABI.
477
510
if target. has_feature ( "soft-float" ) {
0 commit comments