Skip to content

Commit 49a3a86

Browse files
committed
adjust default sysroot when being rustc
Also while at it, refactor how we pass the default Miri flags
1 parent ba801a4 commit 49a3a86

File tree

1 file changed

+55
-41
lines changed

1 file changed

+55
-41
lines changed

src/bin/miri.rs

+55-41
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@ use log::debug;
1616
use rustc_session::CtfeBacktrace;
1717
use rustc_driver::Compilation;
1818
use rustc_hir::def_id::LOCAL_CRATE;
19-
use rustc_interface::{interface, Queries};
2019
use rustc_middle::ty::TyCtxt;
2120

2221
struct MiriCompilerCalls {
@@ -26,8 +25,8 @@ struct MiriCompilerCalls {
2625
impl rustc_driver::Callbacks for MiriCompilerCalls {
2726
fn after_analysis<'tcx>(
2827
&mut self,
29-
compiler: &interface::Compiler,
30-
queries: &'tcx Queries<'tcx>,
28+
compiler: &rustc_interface::interface::Compiler,
29+
queries: &'tcx rustc_interface::Queries<'tcx>,
3130
) -> Compilation {
3231
compiler.session().abort_if_errors();
3332

@@ -106,12 +105,12 @@ fn init_late_loggers(tcx: TyCtxt<'_>) {
106105
fn compile_time_sysroot() -> Option<String> {
107106
if option_env!("RUSTC_STAGE").is_some() {
108107
// This is being built as part of rustc, and gets shipped with rustup.
109-
// We can rely on the sysroot computation in librustc.
108+
// We can rely on the sysroot computation in librustc_session.
110109
return None;
111110
}
112111
// For builds outside rustc, we need to ensure that we got a sysroot
113-
// that gets used as a default. The sysroot computation in librustc would
114-
// end up somewhere in the build dir.
112+
// that gets used as a default. The sysroot computation in librustc_session would
113+
// end up somewhere in the build dir (see `get_or_default_sysroot`).
115114
// Taken from PR <https://github.com/Manishearth/rust-clippy/pull/911>.
116115
let home = option_env!("RUSTUP_HOME").or(option_env!("MULTIRUST_HOME"));
117116
let toolchain = option_env!("RUSTUP_TOOLCHAIN").or(option_env!("MULTIRUST_TOOLCHAIN"));
@@ -123,13 +122,48 @@ fn compile_time_sysroot() -> Option<String> {
123122
})
124123
}
125124

125+
/// Execute a compiler with the given CLI arguments and callbacks.
126+
fn run_compiler(mut args: Vec<String>, callbacks: &mut (dyn rustc_driver::Callbacks + Send)) {
127+
128+
// Make sure we use the right default sysroot. The default sysroot is wrong,
129+
// because `get_or_default_sysroot` in `librustc_session` bases that on `current_exe`.
130+
//
131+
// Make sure we always call `compile_time_sysroot` as that also does some sanity-checks
132+
// of the environment we were built in.
133+
// FIXME: Ideally we'd turn a bad build env into a compile-time error via CTFE or so.
134+
if let Some(sysroot) = compile_time_sysroot() {
135+
let sysroot_flag = "--sysroot";
136+
if !args.iter().any(|e| e == sysroot_flag) {
137+
// We need to overwrite the default that librustc_session would compute.
138+
args.push(sysroot_flag.to_owned());
139+
args.push(sysroot);
140+
}
141+
}
142+
143+
// Invoke compiler, and handle return code.
144+
let result = rustc_driver::catch_fatal_errors(move || {
145+
rustc_driver::run_compiler(&args, callbacks, None, None)
146+
})
147+
.and_then(|result| result);
148+
let exit_code = match result {
149+
Ok(()) => rustc_driver::EXIT_SUCCESS,
150+
Err(_) => rustc_driver::EXIT_FAILURE,
151+
};
152+
std::process::exit(exit_code);
153+
}
154+
126155
fn main() {
156+
rustc_driver::install_ice_hook();
157+
127158
// If the environment asks us to actually be rustc, then do that.
128159
if env::var_os("MIRI_BE_RUSTC").is_some() {
129-
eprintln!("miri-as-rustc called with args: {:?}", env::args());
130-
return rustc_driver::main();
160+
rustc_driver::init_rustc_env_logger();
161+
// We cannot use `rustc_driver::main` as we need to adjust the CLI arguments.
162+
let mut callbacks = rustc_driver::TimePassesCallbacks::default();
163+
return run_compiler(env::args().collect(), &mut callbacks);
131164
}
132165

166+
// Init loggers the Miri way.
133167
init_early_loggers();
134168

135169
// Parse our arguments and split them across `rustc` and `miri`.
@@ -142,16 +176,20 @@ fn main() {
142176
let mut tracked_pointer_tag: Option<miri::PtrId> = None;
143177
let mut tracked_alloc_id: Option<miri::AllocId> = None;
144178
let mut rustc_args = vec![];
145-
let mut miri_args = vec![];
179+
let mut crate_args = vec![];
146180
let mut after_dashdash = false;
147181
let mut excluded_env_vars = vec![];
148-
for arg in std::env::args() {
182+
for arg in env::args() {
149183
if rustc_args.is_empty() {
150-
// Very first arg: for `rustc`.
184+
// Very first arg: binary name.
151185
rustc_args.push(arg);
186+
// After this, push Miri default args (before everything else so they can be overwritten).
187+
for arg in miri::miri_default_args().iter() {
188+
rustc_args.push(arg.to_string());
189+
}
152190
} else if after_dashdash {
153-
// Everything that comes after are `miri` args.
154-
miri_args.push(arg);
191+
// Everything that comes after `--` is forwarded to the interpreted crate.
192+
crate_args.push(arg);
155193
} else {
156194
match arg.as_str() {
157195
"-Zmiri-disable-validation" => {
@@ -227,30 +265,15 @@ fn main() {
227265
tracked_alloc_id = Some(miri::AllocId(id));
228266
}
229267
_ => {
268+
// Forward to rustc.
230269
rustc_args.push(arg);
231270
}
232271
}
233272
}
234273
}
235274

236-
// Determine sysroot if needed. Make sure we always call `compile_time_sysroot`
237-
// as that also does some sanity-checks of the environment we were built in.
238-
// FIXME: Ideally we'd turn a bad build env into a compile-time error, but
239-
// CTFE does not seem powerful enough for that yet.
240-
if let Some(sysroot) = compile_time_sysroot() {
241-
let sysroot_flag = "--sysroot";
242-
if !rustc_args.iter().any(|e| e == sysroot_flag) {
243-
// We need to overwrite the default that librustc would compute.
244-
rustc_args.push(sysroot_flag.to_owned());
245-
rustc_args.push(sysroot);
246-
}
247-
}
248-
249-
// Finally, add the default flags all the way in the beginning, but after the binary name.
250-
rustc_args.splice(1..1, miri::miri_default_args().iter().map(ToString::to_string));
251-
252275
debug!("rustc arguments: {:?}", rustc_args);
253-
debug!("miri arguments: {:?}", miri_args);
276+
debug!("crate arguments: {:?}", crate_args);
254277
let miri_config = miri::MiriConfig {
255278
validate,
256279
stacked_borrows,
@@ -259,18 +282,9 @@ fn main() {
259282
ignore_leaks,
260283
excluded_env_vars,
261284
seed,
262-
args: miri_args,
285+
args: crate_args,
263286
tracked_pointer_tag,
264287
tracked_alloc_id,
265288
};
266-
rustc_driver::install_ice_hook();
267-
let result = rustc_driver::catch_fatal_errors(move || {
268-
rustc_driver::run_compiler(&rustc_args, &mut MiriCompilerCalls { miri_config }, None, None)
269-
})
270-
.and_then(|result| result);
271-
let exit_code = match result {
272-
Ok(()) => rustc_driver::EXIT_SUCCESS,
273-
Err(_) => rustc_driver::EXIT_FAILURE,
274-
};
275-
std::process::exit(exit_code);
289+
return run_compiler(rustc_args, &mut MiriCompilerCalls { miri_config });
276290
}

0 commit comments

Comments
 (0)