@@ -20,6 +20,46 @@ fn show_version() {
2020 println ! ( env!( "CARGO_PKG_VERSION" ) ) ;
2121}
2222
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+
2363#[ allow( clippy:: too_many_lines) ]
2464pub fn main ( ) {
2565 rustc_driver:: init_rustc_env_logger ( ) ;
@@ -32,8 +72,19 @@ pub fn main() {
3272 exit ( 0 ) ;
3373 }
3474
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 ( ) )
3788 . or_else ( || std:: env:: var ( "SYSROOT" ) . ok ( ) )
3889 . or_else ( || {
3990 let home = option_env ! ( "RUSTUP_HOME" ) . or ( option_env ! ( "MULTIRUST_HOME" ) ) ;
@@ -49,11 +100,11 @@ pub fn main() {
49100 . and_then ( |out| String :: from_utf8 ( out. stdout ) . ok ( ) )
50101 . map ( |s| s. trim ( ) . to_owned ( ) )
51102 } )
103+ . or_else ( || option_env ! ( "SYSROOT" ) . map ( String :: from) )
52104 . expect ( "need to specify SYSROOT env var during clippy compilation, or use rustup or multirust" ) ;
53105
54106 // Setting RUSTC_WRAPPER causes Cargo to pass 'rustc' as the first argument.
55107 // We're invoking the compiler programmatically, so we ignore this/
56- let mut orig_args: Vec < String > = env:: args ( ) . collect ( ) ;
57108 if orig_args. len ( ) <= 1 {
58109 std:: process:: exit ( 1 ) ;
59110 }
@@ -64,7 +115,7 @@ pub fn main() {
64115 // this conditional check for the --sysroot flag is there so users can call
65116 // `clippy_driver` directly
66117 // 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 {
68119 orig_args. clone ( )
69120 } else {
70121 orig_args
@@ -79,7 +130,7 @@ pub fn main() {
79130 // crate is
80131 // linted but not built
81132 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 ( ) ;
83134
84135 if clippy_enabled {
85136 args. extend_from_slice ( & [ "--cfg" . to_owned ( ) , r#"feature="cargo-clippy""# . to_owned ( ) ] ) ;
0 commit comments