1
- use std:: env;
2
- use std:: ffi:: OsString ;
3
- use std:: fs;
4
- use std:: path:: Path ;
5
- use std:: process:: { Command , ExitStatus } ;
6
- use std:: str;
7
-
8
- // This code exercises the surface area that we expect of the std Backtrace
9
- // type. If the current toolchain is able to compile it, we go ahead and use
10
- // backtrace in eyre.
11
- const BACKTRACE_PROBE : & str = r#"
12
- #![feature(backtrace)]
1
+ use std:: {
2
+ env, fs,
3
+ path:: Path ,
4
+ process:: { Command , ExitStatus } ,
5
+ } ;
6
+
7
+ fn main ( ) {
8
+ let ac = autocfg:: new ( ) ;
9
+
10
+ // https://github.com/rust-lang/rust/issues/99301 [nightly]
11
+ //
12
+ // Autocfg does currently not support custom probes, or `nightly` only features
13
+ match compile_probe ( GENERIC_MEMBER_ACCESS_PROBE ) {
14
+ Some ( status) if status. success ( ) => autocfg:: emit ( "generic_member_access" ) ,
15
+ _ => { }
16
+ }
17
+
18
+ // https://github.com/rust-lang/rust/issues/47809 [rustc-1.46]
19
+ ac. emit_expression_cfg ( "std::panic::Location::caller" , "track_caller" ) ;
20
+
21
+ if ac. probe_rustc_version ( 1 , 52 ) {
22
+ autocfg:: emit ( "eyre_no_fmt_arguments_as_str" ) ;
23
+ }
24
+
25
+ if ac. probe_rustc_version ( 1 , 58 ) {
26
+ autocfg:: emit ( "eyre_no_fmt_args_capture" ) ;
27
+ }
28
+
29
+ if ac. probe_rustc_version ( 1 , 65 ) {
30
+ autocfg:: emit ( "backtrace" )
31
+ }
32
+ }
33
+
34
+ // This code exercises the surface area or the generic member access feature for the `std::error::Error` trait.
35
+ //
36
+ // This is use to detect and supply backtrace information through different errors types.
37
+ const GENERIC_MEMBER_ACCESS_PROBE : & str = r#"
38
+ #![feature(error_generic_member_access)]
13
39
#![allow(dead_code)]
14
40
15
- use std::backtrace::{Backtrace, BacktraceStatus};
16
- use std::error::Error;
41
+ use std::error::{Error, Request};
17
42
use std::fmt::{self, Display};
18
43
19
44
#[derive(Debug)]
20
- struct E;
45
+ struct E {
46
+ backtrace: MyBacktrace,
47
+ }
48
+
49
+ #[derive(Debug)]
50
+ struct MyBacktrace;
21
51
22
52
impl Display for E {
23
53
fn fmt(&self, _formatter: &mut fmt::Formatter) -> fmt::Result {
@@ -26,59 +56,44 @@ const BACKTRACE_PROBE: &str = r#"
26
56
}
27
57
28
58
impl Error for E {
29
- fn backtrace(&self) -> Option<&Backtrace> {
30
- let backtrace = Backtrace::capture();
31
- match backtrace.status() {
32
- BacktraceStatus::Captured | BacktraceStatus::Disabled | _ => {}
33
- }
34
- unimplemented!()
59
+ fn provide<'a>(&'a self, request: &mut Request<'a>) {
60
+ request
61
+ .provide_ref::<MyBacktrace>(&self.backtrace);
35
62
}
36
63
}
37
64
"# ;
38
65
39
- const TRACK_CALLER_PROBE : & str = r#"
40
- #![allow(dead_code)]
41
-
42
- #[track_caller]
43
- fn foo() {
44
- let _location = std::panic::Location::caller();
45
- }
46
- "# ;
47
-
48
- fn main ( ) {
49
- match compile_probe ( BACKTRACE_PROBE ) {
50
- Some ( status) if status. success ( ) => println ! ( "cargo:rustc-cfg=backtrace" ) ,
51
- _ => { }
52
- }
53
-
54
- match compile_probe ( TRACK_CALLER_PROBE ) {
55
- Some ( status) if status. success ( ) => println ! ( "cargo:rustc-cfg=track_caller" ) ,
56
- _ => { }
57
- }
66
+ fn compile_probe ( probe : & str ) -> Option < ExitStatus > {
67
+ let rustc = env:: var_os ( "RUSTC" ) ?;
68
+ let out_dir = env:: var_os ( "OUT_DIR" ) ?;
69
+ let probefile = Path :: new ( & out_dir) . join ( "probe.rs" ) ;
70
+ fs:: write ( & probefile, probe) . ok ( ) ?;
58
71
59
- let version = match rustc_version_info ( ) {
60
- Some ( version) => version,
61
- None => return ,
62
- } ;
72
+ let rustc_wrapper = env:: var_os ( "RUSTC_WRAPPER" ) . filter ( |wrapper| !wrapper. is_empty ( ) ) ;
73
+ let rustc_workspace_wrapper =
74
+ env:: var_os ( "RUSTC_WORKSPACE_WRAPPER" ) . filter ( |wrapper| !wrapper. is_empty ( ) ) ;
75
+ let mut rustc = rustc_wrapper
76
+ . into_iter ( )
77
+ . chain ( rustc_workspace_wrapper)
78
+ . chain ( std:: iter:: once ( rustc) ) ;
63
79
64
- version. toolchain . set_feature ( ) ;
80
+ let mut cmd = Command :: new ( rustc. next ( ) . unwrap ( ) ) ;
81
+ cmd. args ( rustc) ;
65
82
66
- if version . minor < 52 {
67
- println ! ( "cargo:rustc-cfg=eyre_no_fmt_arguments_as_str" ) ;
83
+ if let Some ( target ) = env :: var_os ( "TARGET" ) {
84
+ cmd . arg ( "--target" ) . arg ( target ) ;
68
85
}
69
86
70
- if version. minor < 58 {
71
- println ! ( "cargo:rustc-cfg=eyre_no_fmt_args_capture" ) ;
87
+ // If Cargo wants to set RUSTFLAGS, use that.
88
+ if let Ok ( rustflags) = env:: var ( "CARGO_ENCODED_RUSTFLAGS" ) {
89
+ if !rustflags. is_empty ( ) {
90
+ for arg in rustflags. split ( '\x1f' ) {
91
+ cmd. arg ( arg) ;
92
+ }
93
+ }
72
94
}
73
- }
74
95
75
- fn compile_probe ( probe : & str ) -> Option < ExitStatus > {
76
- let rustc = env:: var_os ( "RUSTC" ) ?;
77
- let out_dir = env:: var_os ( "OUT_DIR" ) ?;
78
- let probefile = Path :: new ( & out_dir) . join ( "probe.rs" ) ;
79
- fs:: write ( & probefile, probe) . ok ( ) ?;
80
- Command :: new ( rustc)
81
- . arg ( "--edition=2018" )
96
+ cmd. arg ( "--edition=2018" )
82
97
. arg ( "--crate-name=eyre_build" )
83
98
. arg ( "--crate-type=lib" )
84
99
. arg ( "--emit=metadata" )
@@ -88,45 +103,3 @@ fn compile_probe(probe: &str) -> Option<ExitStatus> {
88
103
. status ( )
89
104
. ok ( )
90
105
}
91
-
92
- // TODO factor this toolchain parsing and related tests into its own file
93
- #[ derive( PartialEq ) ]
94
- enum Toolchain {
95
- Stable ,
96
- Beta ,
97
- Nightly ,
98
- }
99
- impl Toolchain {
100
- fn set_feature ( self ) {
101
- match self {
102
- Toolchain :: Nightly => println ! ( "cargo:rustc-cfg=nightly" ) ,
103
- Toolchain :: Beta => println ! ( "cargo:rustc-cfg=beta" ) ,
104
- Toolchain :: Stable => println ! ( "cargo:rustc-cfg=stable" ) ,
105
- }
106
- }
107
- }
108
-
109
- struct VersionInfo {
110
- minor : u32 ,
111
- toolchain : Toolchain ,
112
- }
113
-
114
- fn rustc_version_info ( ) -> Option < VersionInfo > {
115
- let rustc = env:: var_os ( "RUSTC" ) . unwrap_or_else ( || OsString :: from ( "rustc" ) ) ;
116
- let output = Command :: new ( rustc) . arg ( "--version" ) . output ( ) . ok ( ) ?;
117
- let version = str:: from_utf8 ( & output. stdout ) . ok ( ) ?;
118
- let mut pieces = version. split ( [ '.' , ' ' , '-' ] ) ;
119
- if pieces. next ( ) != Some ( "rustc" ) {
120
- return None ;
121
- }
122
- let _major: u32 = pieces. next ( ) ?. parse ( ) . ok ( ) ?;
123
- let minor = pieces. next ( ) ?. parse ( ) . ok ( ) ?;
124
- let _patch: u32 = pieces. next ( ) ?. parse ( ) . ok ( ) ?;
125
- let toolchain = match pieces. next ( ) {
126
- Some ( "beta" ) => Toolchain :: Beta ,
127
- Some ( "nightly" ) => Toolchain :: Nightly ,
128
- _ => Toolchain :: Stable ,
129
- } ;
130
- let version = VersionInfo { minor, toolchain } ;
131
- Some ( version)
132
- }
0 commit comments