@@ -23,7 +23,7 @@ use self::rustc_driver::{driver::CompileController, Compilation};
2323
2424use std:: convert:: TryInto ;
2525use std:: path:: Path ;
26- use std:: process:: exit;
26+ use std:: process:: { exit, Command } ;
2727
2828fn show_version ( ) {
2929 println ! ( env!( "CARGO_PKG_VERSION" ) ) ;
@@ -40,22 +40,54 @@ pub fn main() {
4040 exit ( 0 ) ;
4141 }
4242
43+ let sys_root = option_env ! ( "SYSROOT" )
44+ . map ( String :: from)
45+ . or_else ( || std:: env:: var ( "SYSROOT" ) . ok ( ) )
46+ . or_else ( || {
47+ let home = option_env ! ( "RUSTUP_HOME" ) . or ( option_env ! ( "MULTIRUST_HOME" ) ) ;
48+ let toolchain = option_env ! ( "RUSTUP_TOOLCHAIN" ) . or ( option_env ! ( "MULTIRUST_TOOLCHAIN" ) ) ;
49+ home. and_then ( |home| toolchain. map ( |toolchain| format ! ( "{}/toolchains/{}" , home, toolchain) ) )
50+ } )
51+ . or_else ( || {
52+ Command :: new ( "rustc" )
53+ . arg ( "--print" )
54+ . arg ( "sysroot" )
55+ . output ( )
56+ . ok ( )
57+ . and_then ( |out| String :: from_utf8 ( out. stdout ) . ok ( ) )
58+ . map ( |s| s. trim ( ) . to_owned ( ) )
59+ } )
60+ . expect ( "need to specify SYSROOT env var during clippy compilation, or use rustup or multirust" ) ;
61+
4362 // Setting RUSTC_WRAPPER causes Cargo to pass 'rustc' as the first argument.
4463 // We're invoking the compiler programmatically, so we ignore this/
45- let mut args : Vec < String > = env:: args ( ) . collect ( ) ;
46- if args . len ( ) <= 1 {
64+ let mut orig_args : Vec < String > = env:: args ( ) . collect ( ) ;
65+ if orig_args . len ( ) <= 1 {
4766 std:: process:: exit ( 1 ) ;
4867 }
49- if Path :: new ( & args [ 1 ] ) . file_stem ( ) == Some ( "rustc" . as_ref ( ) ) {
68+ if Path :: new ( & orig_args [ 1 ] ) . file_stem ( ) == Some ( "rustc" . as_ref ( ) ) {
5069 // we still want to be able to invoke it normally though
51- args . remove ( 1 ) ;
70+ orig_args . remove ( 1 ) ;
5271 }
72+ // this conditional check for the --sysroot flag is there so users can call
73+ // `clippy_driver` directly
74+ // without having to pass --sysroot or anything
75+ let mut args: Vec < String > = if orig_args. iter ( ) . any ( |s| s == "--sysroot" ) {
76+ orig_args. clone ( )
77+ } else {
78+ orig_args
79+ . clone ( )
80+ . into_iter ( )
81+ . chain ( Some ( "--sysroot" . to_owned ( ) ) )
82+ . chain ( Some ( sys_root) )
83+ . collect ( )
84+ } ;
5385
5486 // this check ensures that dependencies are built but not linted and the final
5587 // crate is
5688 // linted but not built
5789 let clippy_enabled = env:: var ( "CLIPPY_TESTS" ) . ok ( ) . map_or ( false , |val| val == "true" )
58- || args . iter ( ) . any ( |s| s == "--emit=dep-info,metadata" ) ;
90+ || orig_args . iter ( ) . any ( |s| s == "--emit=dep-info,metadata" ) ;
5991
6092 if clippy_enabled {
6193 args. extend_from_slice ( & [ "--cfg" . to_owned ( ) , r#"feature="cargo-clippy""# . to_owned ( ) ] ) ;
0 commit comments