@@ -121,12 +121,65 @@ impl Cache {
121121 }
122122}
123123
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+
124178#[ inline]
125- fn initialize ( value : Initializer ) -> Initializer {
179+ fn do_initialize ( value : Initializer ) {
126180 CACHE [ 0 ] . initialize ( ( value. 0 ) as usize & Cache :: MASK ) ;
127181 CACHE [ 1 ] . initialize ( ( value. 0 >> Cache :: CAPACITY ) as usize & Cache :: MASK ) ;
128182 CACHE [ 2 ] . initialize ( ( value. 0 >> ( 2 * Cache :: CAPACITY ) ) as usize & Cache :: MASK ) ;
129- value
130183}
131184
132185// 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 {
151204///
152205/// It uses the `Feature` variant to index into this variable as a bitset. If
153206/// 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.
154211#[ inline]
155212pub ( crate ) fn test ( bit : u32 ) -> bool {
156213 let ( relative_bit, idx) = if bit < Cache :: CAPACITY {
0 commit comments