@@ -37,9 +37,8 @@ pub mod lint_pass;
3737
3838use std:: env;
3939use std:: ops:: Deref ;
40- use std:: process:: Command ;
4140
42- use camino:: { Utf8Path , Utf8PathBuf } ;
41+ use camino:: Utf8Path ;
4342use marker_adapter:: { LintCrateInfo , LINT_CRATES_ENV } ;
4443use marker_error:: Context ;
4544
@@ -49,8 +48,10 @@ use crate::conversion::rustc::RustcConverter;
4948const RUSTC_TOOLCHAIN_VERSION : & str = "nightly-2023-11-16" ;
5049// endregion replace rust toolchain dev
5150
51+ pub const MARKER_SYSROOT_ENV : & str = "MARKER_SYSROOT" ;
52+
5253struct DefaultCallbacks {
53- env_vars : Vec < ( & ' static str , String ) > ,
54+ env_vars : Vec < & ' static str > ,
5455}
5556impl rustc_driver:: Callbacks for DefaultCallbacks {
5657 fn config ( & mut self , config : & mut rustc_interface:: Config ) {
@@ -62,7 +63,7 @@ impl rustc_driver::Callbacks for DefaultCallbacks {
6263}
6364
6465struct MarkerCallback {
65- env_vars : Vec < ( & ' static str , String ) > ,
66+ env_vars : Vec < & ' static str > ,
6667 lint_crates : Vec < LintCrateInfo > ,
6768}
6869
@@ -105,12 +106,15 @@ impl rustc_driver::Callbacks for MarkerCallback {
105106 }
106107}
107108
108- fn register_tracked_env ( sess : & mut rustc_session:: parse:: ParseSess , vars : & [ ( & ' static str , String ) ] ) {
109+ fn register_tracked_env ( sess : & mut rustc_session:: parse:: ParseSess , vars : & [ & ' static str ] ) {
109110 use rustc_span:: Symbol ;
110111 let env = sess. env_depinfo . get_mut ( ) ;
111112
112- for ( key, value) in vars {
113- env. insert ( ( Symbol :: intern ( key) , Some ( Symbol :: intern ( value) ) ) ) ;
113+ for key in vars {
114+ env. insert ( (
115+ Symbol :: intern ( key) ,
116+ Some ( Symbol :: intern ( & std:: env:: var ( key) . unwrap_or_default ( ) ) ) ,
117+ ) ) ;
114118 }
115119}
116120
@@ -167,17 +171,6 @@ fn arg_value<'a, T: Deref<Target = str>>(
167171 None
168172}
169173
170- fn toolchain_path ( home : Option < String > , toolchain : Option < String > ) -> Option < Utf8PathBuf > {
171- home. and_then ( |home| {
172- toolchain. map ( |toolchain| {
173- let mut path = Utf8PathBuf :: from ( home) ;
174- path. push ( "toolchains" ) ;
175- path. push ( toolchain) ;
176- path
177- } )
178- } )
179- }
180-
181174fn display_help ( ) {
182175 println ! (
183176 "\
@@ -208,15 +201,24 @@ pub fn try_main(args: impl Iterator<Item = String>) -> Result<(), MainError> {
208201 // values. These are usually driver-independent and handled by the adapter.
209202 let mut orig_args: Vec < String > = args. collect ( ) ;
210203
211- let sys_root_arg = arg_value ( & orig_args, "--sysroot" , |_| true ) ;
212- let has_sys_root_arg = sys_root_arg. is_some ( ) ;
213-
214- // Further invocation of rustc require the `--sysroot` flag. We add it here
215- // in preparation.
216- if !has_sys_root_arg {
217- let sys_root = find_sys_root ( sys_root_arg) ;
218- orig_args. extend ( [ "--sysroot" . into ( ) , sys_root] ) ;
219- } ;
204+ // Rustc will by default use the location of the rustc library as the system
205+ // root. Custom drivers, like Clippy, rustdoc, and Miri have options to override
206+ // this directory. This seems to be required for cross compiling and cases where
207+ // the driver is invoked directly.
208+ //
209+ // I haven't found a definite explanation which circumstances require it, but
210+ // it's probably best to support the same behavior. This code is an adaptation
211+ // of Clippy's solution, with the deviation, that we add the `--sysroot` directly
212+ // and have a `MARKER_` prefix for the `SYSROOT` environment value. This is similar
213+ // to Miri's `MIRI_SYSROOT` variable.
214+ //
215+ // The `ui_test` crate used by `marker_uitest` seems to also fiddle around with
216+ // the system root, if custom dependencies are defined.
217+ if arg_value ( & orig_args, "--sysroot" , |_| true ) . is_none ( )
218+ && let Ok ( env_sys_root) = std:: env:: var ( MARKER_SYSROOT_ENV )
219+ {
220+ orig_args. extend ( vec ! [ "--sysroot" . into( ) , env_sys_root] ) ;
221+ }
220222
221223 // make "marker_rustc_driver --rustc" work like a subcommand that passes
222224 // all args to "rustc" for example `marker_rustc_driver --rustc --version`
@@ -270,7 +272,7 @@ pub fn try_main(args: impl Iterator<Item = String>) -> Result<(), MainError> {
270272 let in_primary_package = env:: var ( "CARGO_PRIMARY_PACKAGE" ) . is_ok ( ) ;
271273
272274 let enable_marker = !cap_lints_allow && ( !no_deps || in_primary_package) ;
273- let env_vars = vec ! [ ( LINT_CRATES_ENV , std :: env :: var ( LINT_CRATES_ENV ) . unwrap_or_default ( ) ) ] ;
275+ let env_vars = vec ! [ LINT_CRATES_ENV , MARKER_SYSROOT_ENV ] ;
274276 if !enable_marker {
275277 rustc_driver:: RunCompiler :: new ( & orig_args, & mut DefaultCallbacks { env_vars } ) . run ( ) ?;
276278 return Ok ( ( ) ) ;
@@ -306,51 +308,6 @@ pub fn try_main(args: impl Iterator<Item = String>) -> Result<(), MainError> {
306308 Ok ( ( ) )
307309}
308310
309- /// Get the sysroot, looking from most specific to this invocation to the least:
310- /// - command line
311- /// - runtime environment
312- /// - `SYSROOT`
313- /// - `RUSTUP_HOME`, `MULTIRUST_HOME`, `RUSTUP_TOOLCHAIN`, `MULTIRUST_TOOLCHAIN`
314- /// - sysroot from rustc in the path
315- /// - compile-time environment
316- /// - `SYSROOT`
317- /// - `RUSTUP_HOME`, `MULTIRUST_HOME`, `RUSTUP_TOOLCHAIN`, `MULTIRUST_TOOLCHAIN`
318- fn find_sys_root ( sys_root_arg : Option < & str > ) -> String {
319- sys_root_arg
320- . map ( Utf8PathBuf :: from)
321- . or_else ( || std:: env:: var ( "SYSROOT" ) . ok ( ) . map ( Utf8PathBuf :: from) )
322- . or_else ( || {
323- let home = std:: env:: var ( "RUSTUP_HOME" )
324- . or_else ( |_| std:: env:: var ( "MULTIRUST_HOME" ) )
325- . ok ( ) ;
326- let toolchain = std:: env:: var ( "RUSTUP_TOOLCHAIN" )
327- . or_else ( |_| std:: env:: var ( "MULTIRUST_TOOLCHAIN" ) )
328- . ok ( ) ;
329- toolchain_path ( home, toolchain)
330- } )
331- . or_else ( || {
332- Command :: new ( "rustc" )
333- . arg ( "--print" )
334- . arg ( "sysroot" )
335- . output ( )
336- . ok ( )
337- . and_then ( |out| String :: from_utf8 ( out. stdout ) . ok ( ) )
338- . map ( |s| Utf8PathBuf :: from ( s. trim ( ) ) )
339- } )
340- . or_else ( || option_env ! ( "SYSROOT" ) . map ( Utf8PathBuf :: from) )
341- . or_else ( || {
342- let home = option_env ! ( "RUSTUP_HOME" )
343- . or ( option_env ! ( "MULTIRUST_HOME" ) )
344- . map ( ToString :: to_string) ;
345- let toolchain = option_env ! ( "RUSTUP_TOOLCHAIN" )
346- . or ( option_env ! ( "MULTIRUST_TOOLCHAIN" ) )
347- . map ( ToString :: to_string) ;
348- toolchain_path ( home, toolchain)
349- } )
350- . map ( Utf8PathBuf :: into_string)
351- . expect ( "need to specify SYSROOT env var during marker compilation, or use rustup or multirust" )
352- }
353-
354311pub enum MainError {
355312 Custom ( marker_error:: Error ) ,
356313 Rustc ( rustc_span:: ErrorGuaranteed ) ,
0 commit comments