@@ -121,12 +121,65 @@ impl Cache {
121
121
}
122
122
}
123
123
124
+ cfg_if:: cfg_if! {
125
+ if #[ cfg( feature = "std_detect_env_override" ) ] {
126
+ #[ inline]
127
+ fn disable_features( disable: & [ u8 ] , value: & mut Initializer ) {
128
+ if let Ok ( disable) = core:: str :: from_utf8( disable) {
129
+ for v in disable. split( " " ) {
130
+ let _ = super :: Feature :: from_str( v) . map( |v| value. unset( v as u32 ) ) ;
131
+ }
132
+ }
133
+ }
134
+
135
+ #[ inline]
136
+ fn initialize( mut value: Initializer ) -> Initializer {
137
+ use core:: ffi:: CStr ;
138
+ const RUST_STD_DETECT_UNSTABLE : & CStr = c"RUST_STD_DETECT_UNSTABLE" ;
139
+ cfg_if:: cfg_if! {
140
+ if #[ cfg( windows) ] {
141
+ use alloc:: vec;
142
+ #[ link( name = "kernel32" ) ]
143
+ unsafe extern "system" {
144
+ fn GetEnvironmentVariableA ( name: * const u8 , buffer: * mut u8 , size: u32 ) -> u32 ;
145
+ }
146
+ let len = unsafe { GetEnvironmentVariableA ( RUST_STD_DETECT_UNSTABLE . as_ptr( ) . cast:: <u8 >( ) , core:: ptr:: null_mut( ) , 0 ) } ;
147
+ if len > 0 {
148
+ // +1 to include the null terminator.
149
+ let mut env = vec![ 0 ; len as usize + 1 ] ;
150
+ let len = unsafe { GetEnvironmentVariableA ( RUST_STD_DETECT_UNSTABLE . as_ptr( ) . cast:: <u8 >( ) , env. as_mut_ptr( ) , len + 1 ) } ;
151
+ if len > 0 {
152
+ disable_features( & env[ ..len as usize ] , & mut value) ;
153
+ }
154
+ }
155
+ } else {
156
+ let env = unsafe {
157
+ libc:: getenv( RUST_STD_DETECT_UNSTABLE . as_ptr( ) )
158
+ } ;
159
+ if !env. is_null( ) {
160
+ let len = unsafe { libc:: strlen( env) } ;
161
+ let env = unsafe { core:: slice:: from_raw_parts( env as * const u8 , len) } ;
162
+ disable_features( env, & mut value) ;
163
+ }
164
+ }
165
+ }
166
+ do_initialize( value) ;
167
+ value
168
+ }
169
+ } else {
170
+ #[ inline]
171
+ fn initialize( value: Initializer ) -> Initializer {
172
+ do_initialize( value) ;
173
+ value
174
+ }
175
+ }
176
+ }
177
+
124
178
#[ inline]
125
- fn initialize ( value : Initializer ) -> Initializer {
179
+ fn do_initialize ( value : Initializer ) {
126
180
CACHE [ 0 ] . initialize ( ( value. 0 ) as usize & Cache :: MASK ) ;
127
181
CACHE [ 1 ] . initialize ( ( value. 0 >> Cache :: CAPACITY ) as usize & Cache :: MASK ) ;
128
182
CACHE [ 2 ] . initialize ( ( value. 0 >> ( 2 * Cache :: CAPACITY ) ) as usize & Cache :: MASK ) ;
129
- value
130
183
}
131
184
132
185
// We only have to detect features once, and it's fairly costly, so hint to LLVM
@@ -151,6 +204,10 @@ fn detect_and_initialize() -> Initializer {
151
204
///
152
205
/// It uses the `Feature` variant to index into this variable as a bitset. If
153
206
/// the bit is set, the feature is enabled, and otherwise it is disabled.
207
+ ///
208
+ /// If the feature `std_detect_env_override` is enabled looks for the env
209
+ /// variable `RUST_STD_DETECT_UNSTABLE` and uses its content to disable
210
+ /// Features that would had been otherwise detected.
154
211
#[ inline]
155
212
pub ( crate ) fn test ( bit : u32 ) -> bool {
156
213
let ( relative_bit, idx) = if bit < Cache :: CAPACITY {
0 commit comments