From 65f0b2549c35fb9cbfaa594ae190011187df1cec Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Mon, 28 Dec 2020 13:28:29 -0500 Subject: [PATCH 1/2] Always compile rustdoc with debug logging enabled when `download-rustc` is set Previously, logging at DEBUG or below would always be silenced, because rustc compiles tracing with the `static_max_level_info` feature. That makes sense for release artifacts, but not for developing rustdoc. Instead, this compiles two different versions of tracing: one in the release artifacts, distributed in the sysroot, and a new version compiled by rustdoc. Since `rustc_driver` is always linked to the version of sysroot, this copy/pastes `init_env_logging` into rustdoc. The builds the second version of tracing unconditionally; see the code for details on why. --- Cargo.lock | 3 ++ src/librustdoc/Cargo.toml | 7 ++++ src/librustdoc/lib.rs | 74 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 84 insertions(+) diff --git a/Cargo.lock b/Cargo.lock index 4ae1ab2070e29..73d3529b2211a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4452,6 +4452,9 @@ dependencies = [ "serde_json", "smallvec 1.6.1", "tempfile", + "tracing", + "tracing-subscriber", + "tracing-tree", ] [[package]] diff --git a/src/librustdoc/Cargo.toml b/src/librustdoc/Cargo.toml index 1b9a35e649172..44c2c3b17860b 100644 --- a/src/librustdoc/Cargo.toml +++ b/src/librustdoc/Cargo.toml @@ -19,6 +19,13 @@ tempfile = "3" itertools = "0.9" regex = "1" rustdoc-json-types = { path = "../rustdoc-json-types" } +tracing = "0.1" +tracing-tree = "0.1.6" + +[dependencies.tracing-subscriber] +version = "0.2.13" +default-features = false +features = ["fmt", "env-filter", "smallvec", "parking_lot", "ansi"] [dev-dependencies] expect-test = "1.0" diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs index d7978c4a0228d..2c43489e989ee 100644 --- a/src/librustdoc/lib.rs +++ b/src/librustdoc/lib.rs @@ -95,7 +95,19 @@ mod visit_lib; pub fn main() { rustc_driver::set_sigpipe_handler(); rustc_driver::install_ice_hook(); + + // When using CI artifacts (with `download_stage1 = true`), tracing is unconditionally built + // with `--features=static_max_level_info`, which disables almost all rustdoc logging. To avoid + // this, compile our own version of `tracing` that logs all levels. + // NOTE: this compiles both versions of tracing unconditionally, because + // - The compile time hit is not that bad, especially compared to rustdoc's incremental times, and + // - Otherwise, there's no warning that logging is being ignored when `download_stage1 = true`. + // NOTE: The reason this doesn't show double logging when `download_stage1 = false` and + // `debug_logging = true` is because all rustc logging goes to its version of tracing (the one + // in the sysroot), and all of rustdoc's logging goes to its version (the one in Cargo.toml). + init_logging(); rustc_driver::init_env_logger("RUSTDOC_LOG"); + let exit_code = rustc_driver::catch_with_exit_code(|| match get_args() { Some(args) => main_args(&args), _ => Err(ErrorReported), @@ -103,6 +115,68 @@ pub fn main() { process::exit(exit_code); } +fn init_logging() { + use std::io; + + // FIXME remove these and use winapi 0.3 instead + // Duplicates: bootstrap/compile.rs, librustc_errors/emitter.rs, rustc_driver/lib.rs + #[cfg(unix)] + fn stdout_isatty() -> bool { + extern crate libc; + unsafe { libc::isatty(libc::STDOUT_FILENO) != 0 } + } + + #[cfg(windows)] + fn stdout_isatty() -> bool { + extern crate winapi; + use winapi::um::consoleapi::GetConsoleMode; + use winapi::um::processenv::GetStdHandle; + use winapi::um::winbase::STD_OUTPUT_HANDLE; + + unsafe { + let handle = GetStdHandle(STD_OUTPUT_HANDLE); + let mut out = 0; + GetConsoleMode(handle, &mut out) != 0 + } + } + + let color_logs = match std::env::var("RUSTDOC_LOG_COLOR") { + Ok(value) => match value.as_ref() { + "always" => true, + "never" => false, + "auto" => stdout_isatty(), + _ => early_error( + ErrorOutputType::default(), + &format!( + "invalid log color value '{}': expected one of always, never, or auto", + value + ), + ), + }, + Err(std::env::VarError::NotPresent) => stdout_isatty(), + Err(std::env::VarError::NotUnicode(_value)) => early_error( + ErrorOutputType::default(), + "non-Unicode log color value: expected one of always, never, or auto", + ), + }; + let filter = tracing_subscriber::EnvFilter::from_env("RUSTDOC_LOG"); + let layer = tracing_tree::HierarchicalLayer::default() + .with_writer(io::stderr) + .with_indent_lines(true) + .with_ansi(color_logs) + .with_targets(true) + .with_wraparound(10) + .with_verbose_exit(true) + .with_verbose_entry(true) + .with_indent_amount(2); + #[cfg(parallel_compiler)] + let layer = layer.with_thread_ids(true).with_thread_names(true); + + use tracing_subscriber::layer::SubscriberExt; + let subscriber = tracing_subscriber::Registry::default().with(filter).with(layer); + tracing::subscriber::set_global_default(subscriber).unwrap(); +} + fn get_args() -> Option> { env::args_os() .enumerate() From 6dc99346413292f85cfe572f3ced29242c36e8e7 Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Sun, 28 Feb 2021 21:59:43 -0500 Subject: [PATCH 2/2] Remove deleted pass from rustdoc test suite `src/test/rustdoc-ui/deprecated-attrs.rs` tells rustdoc to run the `collapse-docs` pass, which no longer exists (it was removed in https://github.com/rust-lang/rust/pull/80261). Rustdoc doesn't actually give a proper diagnostic here; instead it prints an `error!` log. Now that tracing is compiled unconditionally, the log is now being emitted by default, because it's at the error level. rustdoc shouldn't be using `error!` logging for diagnostics in the first place, but in the meantime this change gets the testsuite to pass. --- src/test/rustdoc-ui/deprecated-attrs.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/rustdoc-ui/deprecated-attrs.rs b/src/test/rustdoc-ui/deprecated-attrs.rs index 0d5dfa733fab6..ca626afbe5359 100644 --- a/src/test/rustdoc-ui/deprecated-attrs.rs +++ b/src/test/rustdoc-ui/deprecated-attrs.rs @@ -1,6 +1,6 @@ // check-pass -#![doc(no_default_passes, passes = "collapse-docs unindent-comments")] +#![doc(no_default_passes, passes = "unindent-comments")] struct SomeStruct;