Skip to content

Commit 693ade4

Browse files
committed
Auto merge of #117814 - RalfJung:rustc-logger-without-set-var, r=TaKO8Ki
rustc_log: provide a way to init logging based on the values, not names, of the env vars Miri wants to affect how rustc does logging. So far this required setting environment variables before calling `rustc_driver::init_rustc_env_logger`. However, `set_var` is a function one should really [avoid calling](rust-lang/rust#90308), so this adds the necessary APIs to rustc such that Miri can just pass it the *values* of all the log-relevant environment variables, rather than having to change the global environment.
2 parents 268957f + 55a233c commit 693ade4

File tree

1 file changed

+39
-29
lines changed

1 file changed

+39
-29
lines changed

src/bin/miri.rs

+39-29
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,12 @@ extern crate rustc_data_structures;
99
extern crate rustc_driver;
1010
extern crate rustc_hir;
1111
extern crate rustc_interface;
12+
extern crate rustc_log;
1213
extern crate rustc_metadata;
1314
extern crate rustc_middle;
1415
extern crate rustc_session;
1516

16-
use std::env;
17+
use std::env::{self, VarError};
1718
use std::num::NonZeroU64;
1819
use std::path::PathBuf;
1920
use std::str::FromStr;
@@ -183,45 +184,54 @@ macro_rules! show_error {
183184
($($tt:tt)*) => { show_error(&format_args!($($tt)*)) };
184185
}
185186

186-
fn init_early_loggers(handler: &EarlyErrorHandler) {
187-
// Note that our `extern crate log` is *not* the same as rustc's; as a result, we have to
188-
// initialize them both, and we always initialize `miri`'s first.
189-
let env = env_logger::Env::new().filter("MIRI_LOG").write_style("MIRI_LOG_STYLE");
190-
env_logger::init_from_env(env);
191-
// Enable verbose entry/exit logging by default if MIRI_LOG is set.
192-
if env::var_os("MIRI_LOG").is_some() && env::var_os("RUSTC_LOG_ENTRY_EXIT").is_none() {
193-
env::set_var("RUSTC_LOG_ENTRY_EXIT", "1");
194-
}
195-
// We only initialize `rustc` if the env var is set (so the user asked for it).
196-
// If it is not set, we avoid initializing now so that we can initialize
197-
// later with our custom settings, and *not* log anything for what happens before
198-
// `miri` gets started.
199-
if env::var_os("RUSTC_LOG").is_some() {
200-
rustc_driver::init_rustc_env_logger(handler);
201-
}
202-
}
187+
fn rustc_logger_config() -> rustc_log::LoggerConfig {
188+
// Start with the usual env vars.
189+
let mut cfg = rustc_log::LoggerConfig::from_env("RUSTC_LOG");
203190

204-
fn init_late_loggers(handler: &EarlyErrorHandler, tcx: TyCtxt<'_>) {
205-
// We initialize loggers right before we start evaluation. We overwrite the `RUSTC_LOG`
206-
// env var if it is not set, control it based on `MIRI_LOG`.
207-
// (FIXME: use `var_os`, but then we need to manually concatenate instead of `format!`.)
191+
// Overwrite if MIRI_LOG is set.
208192
if let Ok(var) = env::var("MIRI_LOG") {
209-
if env::var_os("RUSTC_LOG").is_none() {
193+
// MIRI_LOG serves as default for RUSTC_LOG, if that is not set.
194+
if matches!(cfg.filter, Err(VarError::NotPresent)) {
210195
// We try to be a bit clever here: if `MIRI_LOG` is just a single level
211196
// used for everything, we only apply it to the parts of rustc that are
212197
// CTFE-related. Otherwise, we use it verbatim for `RUSTC_LOG`.
213198
// This way, if you set `MIRI_LOG=trace`, you get only the right parts of
214199
// rustc traced, but you can also do `MIRI_LOG=miri=trace,rustc_const_eval::interpret=debug`.
215200
if log::Level::from_str(&var).is_ok() {
216-
env::set_var(
217-
"RUSTC_LOG",
218-
format!("rustc_middle::mir::interpret={var},rustc_const_eval::interpret={var}"),
219-
);
201+
cfg.filter = Ok(format!(
202+
"rustc_middle::mir::interpret={var},rustc_const_eval::interpret={var}"
203+
));
220204
} else {
221-
env::set_var("RUSTC_LOG", &var);
205+
cfg.filter = Ok(var);
222206
}
223-
rustc_driver::init_rustc_env_logger(handler);
224207
}
208+
// Enable verbose entry/exit logging by default if MIRI_LOG is set.
209+
if matches!(cfg.verbose_entry_exit, Err(VarError::NotPresent)) {
210+
cfg.verbose_entry_exit = Ok(format!("1"));
211+
}
212+
}
213+
214+
cfg
215+
}
216+
217+
fn init_early_loggers(handler: &EarlyErrorHandler) {
218+
// Note that our `extern crate log` is *not* the same as rustc's; as a result, we have to
219+
// initialize them both, and we always initialize `miri`'s first.
220+
let env = env_logger::Env::new().filter("MIRI_LOG").write_style("MIRI_LOG_STYLE");
221+
env_logger::init_from_env(env);
222+
// Now for rustc. We only initialize `rustc` if the env var is set (so the user asked for it).
223+
// If it is not set, we avoid initializing now so that we can initialize later with our custom
224+
// settings, and *not* log anything for what happens before `miri` gets started.
225+
if env::var_os("RUSTC_LOG").is_some() {
226+
rustc_driver::init_logger(handler, rustc_logger_config());
227+
}
228+
}
229+
230+
fn init_late_loggers(handler: &EarlyErrorHandler, tcx: TyCtxt<'_>) {
231+
// If `RUSTC_LOG` is not set, then `init_early_loggers` did not call
232+
// `rustc_driver::init_logger`, so we have to do this now.
233+
if env::var_os("RUSTC_LOG").is_none() {
234+
rustc_driver::init_logger(handler, rustc_logger_config());
225235
}
226236

227237
// If `MIRI_BACKTRACE` is set and `RUSTC_CTFE_BACKTRACE` is not, set `RUSTC_CTFE_BACKTRACE`.

0 commit comments

Comments
 (0)