@@ -20,6 +20,46 @@ fn show_version() {
20
20
println ! ( env!( "CARGO_PKG_VERSION" ) ) ;
21
21
}
22
22
23
+ /// If a command-line option matches `find_arg`, then apply the predicate `pred` on its value. If
24
+ /// true, then return it. The parameter is assumed to be either `--arg=value` or `--arg value`.
25
+ fn arg_value < ' a > (
26
+ args : impl IntoIterator < Item = & ' a String > ,
27
+ find_arg : & str ,
28
+ pred : impl Fn ( & str ) -> bool ,
29
+ ) -> Option < & ' a str > {
30
+ let mut args = args. into_iter ( ) . map ( String :: as_str) ;
31
+
32
+ while let Some ( arg) = args. next ( ) {
33
+ let arg: Vec < _ > = arg. splitn ( 2 , '=' ) . collect ( ) ;
34
+ if arg. get ( 0 ) != Some ( & find_arg) {
35
+ continue ;
36
+ }
37
+
38
+ let value = arg. get ( 1 ) . cloned ( ) . or_else ( || args. next ( ) ) ;
39
+ if value. as_ref ( ) . map_or ( false , |p| pred ( p) ) {
40
+ return value;
41
+ }
42
+ }
43
+ None
44
+ }
45
+
46
+ #[ test]
47
+ fn test_arg_value ( ) {
48
+ let args: Vec < _ > = [ "--bar=bar" , "--foobar" , "123" , "--foo" ]
49
+ . iter ( )
50
+ . map ( |s| s. to_string ( ) )
51
+ . collect ( ) ;
52
+
53
+ assert_eq ! ( arg_value( None , "--foobar" , |_| true ) , None ) ;
54
+ assert_eq ! ( arg_value( & args, "--bar" , |_| false ) , None ) ;
55
+ assert_eq ! ( arg_value( & args, "--bar" , |_| true ) , Some ( "bar" ) ) ;
56
+ assert_eq ! ( arg_value( & args, "--bar" , |p| p == "bar" ) , Some ( "bar" ) ) ;
57
+ assert_eq ! ( arg_value( & args, "--bar" , |p| p == "foo" ) , None ) ;
58
+ assert_eq ! ( arg_value( & args, "--foobar" , |p| p == "foo" ) , None ) ;
59
+ assert_eq ! ( arg_value( & args, "--foobar" , |p| p == "123" ) , Some ( "123" ) ) ;
60
+ assert_eq ! ( arg_value( & args, "--foo" , |_| true ) , None ) ;
61
+ }
62
+
23
63
#[ allow( clippy:: too_many_lines) ]
24
64
pub fn main ( ) {
25
65
rustc_driver:: init_rustc_env_logger ( ) ;
@@ -32,8 +72,19 @@ pub fn main() {
32
72
exit ( 0 ) ;
33
73
}
34
74
35
- let sys_root = option_env ! ( "SYSROOT" )
36
- . map ( String :: from)
75
+ let mut orig_args: Vec < String > = env:: args ( ) . collect ( ) ;
76
+
77
+ // Get the sysroot, looking from most specific to this invocation to the least:
78
+ // - command line
79
+ // - runtime environment
80
+ // - SYSROOT
81
+ // - RUSTUP_HOME, MULTIRUST_HOME, RUSTUP_TOOLCHAIN, MULTIRUST_TOOLCHAIN
82
+ // - sysroot from rustc in the path
83
+ // - compile-time environment
84
+ let sys_root_arg = arg_value ( & orig_args, "--sysroot" , |_| true ) ;
85
+ let have_sys_root_arg = sys_root_arg. is_some ( ) ;
86
+ let sys_root = sys_root_arg
87
+ . map ( |s| s. to_string ( ) )
37
88
. or_else ( || std:: env:: var ( "SYSROOT" ) . ok ( ) )
38
89
. or_else ( || {
39
90
let home = option_env ! ( "RUSTUP_HOME" ) . or ( option_env ! ( "MULTIRUST_HOME" ) ) ;
@@ -49,11 +100,11 @@ pub fn main() {
49
100
. and_then ( |out| String :: from_utf8 ( out. stdout ) . ok ( ) )
50
101
. map ( |s| s. trim ( ) . to_owned ( ) )
51
102
} )
103
+ . or_else ( || option_env ! ( "SYSROOT" ) . map ( String :: from) )
52
104
. expect ( "need to specify SYSROOT env var during clippy compilation, or use rustup or multirust" ) ;
53
105
54
106
// Setting RUSTC_WRAPPER causes Cargo to pass 'rustc' as the first argument.
55
107
// We're invoking the compiler programmatically, so we ignore this/
56
- let mut orig_args: Vec < String > = env:: args ( ) . collect ( ) ;
57
108
if orig_args. len ( ) <= 1 {
58
109
std:: process:: exit ( 1 ) ;
59
110
}
@@ -64,7 +115,7 @@ pub fn main() {
64
115
// this conditional check for the --sysroot flag is there so users can call
65
116
// `clippy_driver` directly
66
117
// without having to pass --sysroot or anything
67
- let mut args: Vec < String > = if orig_args . iter ( ) . any ( |s| s == "--sysroot" ) {
118
+ let mut args: Vec < String > = if have_sys_root_arg {
68
119
orig_args. clone ( )
69
120
} else {
70
121
orig_args
@@ -79,7 +130,7 @@ pub fn main() {
79
130
// crate is
80
131
// linted but not built
81
132
let clippy_enabled = env:: var ( "CLIPPY_TESTS" ) . ok ( ) . map_or ( false , |val| val == "true" )
82
- || orig_args. iter ( ) . any ( |s| s == "--emit=dep-info, metadata" ) ;
133
+ || arg_value ( & orig_args, "--emit" , |val| val . split ( ',' ) . any ( |e| e == "metadata" ) ) . is_some ( ) ;
83
134
84
135
if clippy_enabled {
85
136
args. extend_from_slice ( & [ "--cfg" . to_owned ( ) , r#"feature="cargo-clippy""# . to_owned ( ) ] ) ;
0 commit comments