@@ -7,6 +7,7 @@ use crate::io;
77use crate :: borrow:: Cow ;
88use crate :: io:: prelude:: * ;
99use crate :: path:: { self , Path , PathBuf } ;
10+ use crate :: sync:: atomic:: { self , Ordering } ;
1011use crate :: sys:: mutex:: Mutex ;
1112
1213use backtrace_rs:: { BacktraceFmt , BytesOrWideString , PrintFmt } ;
@@ -115,8 +116,10 @@ unsafe fn _print_fmt(fmt: &mut fmt::Formatter<'_>, print_fmt: PrintFmt) -> fmt::
115116 Ok ( ( ) )
116117}
117118
118- /// Fixed frame used to clean the backtrace with `RUST_BACKTRACE=1`.
119- #[ inline( never) ]
119+ /// Fixed frame used to clean the backtrace with `RUST_BACKTRACE=1`. Note that
120+ /// this is only inline(never) when backtraces in libstd are enabled, otherwise
121+ /// it's fine to optimize away.
122+ #[ cfg_attr( feature = "backtrace" , inline( never) ) ]
120123pub fn __rust_begin_short_backtrace < F , T > ( f : F ) -> T
121124where
122125 F : FnOnce ( ) -> T ,
@@ -126,42 +129,49 @@ where
126129 f ( )
127130}
128131
132+ pub enum RustBacktrace {
133+ Print ( PrintFmt ) ,
134+ Disabled ,
135+ RuntimeDisabled ,
136+ }
137+
129138// For now logging is turned off by default, and this function checks to see
130139// whether the magical environment variable is present to see if it's turned on.
131- pub fn log_enabled ( ) -> Option < PrintFmt > {
132- use crate :: sync:: atomic:: { self , Ordering } ;
140+ pub fn rust_backtrace_env ( ) -> RustBacktrace {
141+ // If the `backtrace` feature of this crate isn't enabled quickly return
142+ // `None` so this can be constant propagated all over the place to turn
143+ // optimize away callers.
144+ if !cfg ! ( feature = "backtrace" ) {
145+ return RustBacktrace :: Disabled ;
146+ }
133147
134148 // Setting environment variables for Fuchsia components isn't a standard
135149 // or easily supported workflow. For now, always display backtraces.
136150 if cfg ! ( target_os = "fuchsia" ) {
137- return Some ( PrintFmt :: Full ) ;
151+ return RustBacktrace :: Print ( PrintFmt :: Full ) ;
138152 }
139153
140154 static ENABLED : atomic:: AtomicIsize = atomic:: AtomicIsize :: new ( 0 ) ;
141155 match ENABLED . load ( Ordering :: SeqCst ) {
142156 0 => { }
143- 1 => return None ,
144- 2 => return Some ( PrintFmt :: Short ) ,
145- _ => return Some ( PrintFmt :: Full ) ,
157+ 1 => return RustBacktrace :: RuntimeDisabled ,
158+ 2 => return RustBacktrace :: Print ( PrintFmt :: Short ) ,
159+ _ => return RustBacktrace :: Print ( PrintFmt :: Full ) ,
146160 }
147161
148- let val = env:: var_os ( "RUST_BACKTRACE" ) . and_then ( |x| {
149- if & x == "0" {
150- None
151- } else if & x == "full" {
152- Some ( PrintFmt :: Full )
153- } else {
154- Some ( PrintFmt :: Short )
155- }
156- } ) ;
157- ENABLED . store (
158- match val {
159- Some ( v) => v as isize ,
160- None => 1 ,
161- } ,
162- Ordering :: SeqCst ,
163- ) ;
164- val
162+ let ( format, cache) = env:: var_os ( "RUST_BACKTRACE" )
163+ . map ( |x| {
164+ if & x == "0" {
165+ ( RustBacktrace :: RuntimeDisabled , 1 )
166+ } else if & x == "full" {
167+ ( RustBacktrace :: Print ( PrintFmt :: Full ) , 3 )
168+ } else {
169+ ( RustBacktrace :: Print ( PrintFmt :: Short ) , 2 )
170+ }
171+ } )
172+ . unwrap_or ( ( RustBacktrace :: RuntimeDisabled , 1 ) ) ;
173+ ENABLED . store ( cache, Ordering :: SeqCst ) ;
174+ format
165175}
166176
167177/// Prints the filename of the backtrace frame.
0 commit comments