From 9f1abe89b819c3ee919f906a256fe7e2487bdd54 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Sat, 27 Feb 2021 22:02:41 +0100 Subject: [PATCH 01/16] Run some rustc passes in rustdoc --- src/librustdoc/core.rs | 1 + src/librustdoc/lib.rs | 1 + 2 files changed, 2 insertions(+) diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs index f0b3159f737a6..1625acafb5c1f 100644 --- a/src/librustdoc/core.rs +++ b/src/librustdoc/core.rs @@ -492,6 +492,7 @@ crate fn run_global_ctxt( tcx.ensure().check_mod_attrs(module); } }); + rustc_passes::stability::check_unused_or_stable_features(tcx); let access_levels = tcx.privacy_access_levels(LOCAL_CRATE); // Convert from a HirId set to a DefId set since we don't always have easy access diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs index 2342ed3ab670d..4b1b2252bb59d 100644 --- a/src/librustdoc/lib.rs +++ b/src/librustdoc/lib.rs @@ -49,6 +49,7 @@ extern crate rustc_metadata; extern crate rustc_middle; extern crate rustc_mir; extern crate rustc_parse; +extern crate rustc_passes; extern crate rustc_resolve; extern crate rustc_session; extern crate rustc_span as rustc_span; From 25e030bc4252bd23e1bed60dfbaca8a0ce7206bb Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Sat, 27 Feb 2021 18:36:15 +0100 Subject: [PATCH 02/16] Add test for rustdoc new check pass --- src/test/rustdoc-ui/rustc-check-passes.rs | 4 ++++ src/test/rustdoc-ui/rustc-check-passes.stderr | 9 +++++++++ 2 files changed, 13 insertions(+) create mode 100644 src/test/rustdoc-ui/rustc-check-passes.rs create mode 100644 src/test/rustdoc-ui/rustc-check-passes.stderr diff --git a/src/test/rustdoc-ui/rustc-check-passes.rs b/src/test/rustdoc-ui/rustc-check-passes.rs new file mode 100644 index 0000000000000..731cc8ba61750 --- /dev/null +++ b/src/test/rustdoc-ui/rustc-check-passes.rs @@ -0,0 +1,4 @@ +#![feature(box_syntax)] +#![feature(box_syntax)] //~ ERROR + +pub fn foo() {} diff --git a/src/test/rustdoc-ui/rustc-check-passes.stderr b/src/test/rustdoc-ui/rustc-check-passes.stderr new file mode 100644 index 0000000000000..9707895ff3dfe --- /dev/null +++ b/src/test/rustdoc-ui/rustc-check-passes.stderr @@ -0,0 +1,9 @@ +error[E0636]: the feature `box_syntax` has already been declared + --> $DIR/rustc-check-passes.rs:2:12 + | +LL | #![feature(box_syntax)] + | ^^^^^^^^^^ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0636`. From 5ab4d46e9ada163f7f6025500313d2b51c87f657 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Sat, 27 Feb 2021 22:17:31 +0100 Subject: [PATCH 03/16] Update rustdoc test to make it work with newly added rustc passes --- src/test/rustdoc/implementor-stable-version.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/test/rustdoc/implementor-stable-version.rs b/src/test/rustdoc/implementor-stable-version.rs index 0a065d8095bf2..a1f3fd5a8c5af 100644 --- a/src/test/rustdoc/implementor-stable-version.rs +++ b/src/test/rustdoc/implementor-stable-version.rs @@ -1,3 +1,4 @@ +#![stable(feature = "bar", since = "OLD 1.0")] #![crate_name = "foo"] #![feature(staged_api)] @@ -8,6 +9,7 @@ pub trait Bar {} #[stable(feature = "baz", since = "OLD 1.0")] pub trait Baz {} +#[stable(feature = "baz", since = "OLD 1.0")] pub struct Foo; // @has foo/trait.Bar.html '//div[@id="implementors-list"]//span[@class="since"]' 'NEW 2.0' From 2f8fa012cae17f6b8bf8295c075695725e773650 Mon Sep 17 00:00:00 2001 From: Giacomo Stevanato Date: Sun, 28 Feb 2021 20:44:54 +0100 Subject: [PATCH 04/16] Use identifier's span in unused lint --- compiler/rustc_passes/src/liveness.rs | 109 ++++++++++++++++---------- 1 file changed, 66 insertions(+), 43 deletions(-) diff --git a/compiler/rustc_passes/src/liveness.rs b/compiler/rustc_passes/src/liveness.rs index 82f19770a123b..a96f332374430 100644 --- a/compiler/rustc_passes/src/liveness.rs +++ b/compiler/rustc_passes/src/liveness.rs @@ -1494,12 +1494,13 @@ impl<'tcx> Liveness<'_, 'tcx> { // bindings, and we also consider the first pattern to be the "authoritative" set of ids. // However, we should take the ids and spans of variables with the same name from the later // patterns so the suggestions to prefix with underscores will apply to those too. - let mut vars: FxIndexMap)> = <_>::default(); + let mut vars: FxIndexMap)> = + <_>::default(); pat.each_binding(|_, hir_id, pat_sp, ident| { let ln = entry_ln.unwrap_or_else(|| self.live_node(hir_id, pat_sp)); let var = self.variable(hir_id, ident.span); - let id_and_sp = (hir_id, pat_sp); + let id_and_sp = (hir_id, pat_sp, ident.span); vars.entry(self.ir.variable_name(var)) .and_modify(|(.., hir_ids_and_spans)| hir_ids_and_spans.push(id_and_sp)) .or_insert_with(|| (ln, var, vec![id_and_sp])); @@ -1508,7 +1509,8 @@ impl<'tcx> Liveness<'_, 'tcx> { for (_, (ln, var, hir_ids_and_spans)) in vars { if self.used_on_entry(ln, var) { let id = hir_ids_and_spans[0].0; - let spans = hir_ids_and_spans.into_iter().map(|(_, sp)| sp).collect(); + let spans = + hir_ids_and_spans.into_iter().map(|(_, _, ident_span)| ident_span).collect(); on_used_on_entry(spans, id, ln, var); } else { self.report_unused(hir_ids_and_spans, ln, var); @@ -1516,7 +1518,12 @@ impl<'tcx> Liveness<'_, 'tcx> { } } - fn report_unused(&self, hir_ids_and_spans: Vec<(HirId, Span)>, ln: LiveNode, var: Variable) { + fn report_unused( + &self, + hir_ids_and_spans: Vec<(HirId, Span, Span)>, + ln: LiveNode, + var: Variable, + ) { let first_hir_id = hir_ids_and_spans[0].0; if let Some(name) = self.should_warn(var).filter(|name| name != "self") { @@ -1530,7 +1537,10 @@ impl<'tcx> Liveness<'_, 'tcx> { self.ir.tcx.struct_span_lint_hir( lint::builtin::UNUSED_VARIABLES, first_hir_id, - hir_ids_and_spans.into_iter().map(|(_, sp)| sp).collect::>(), + hir_ids_and_spans + .into_iter() + .map(|(_, _, ident_span)| ident_span) + .collect::>(), |lint| { lint.build(&format!("variable `{}` is assigned to, but never used", name)) .note(&format!("consider using `_{}` instead", name)) @@ -1538,54 +1548,67 @@ impl<'tcx> Liveness<'_, 'tcx> { }, ) } else { - self.ir.tcx.struct_span_lint_hir( - lint::builtin::UNUSED_VARIABLES, - first_hir_id, - hir_ids_and_spans.iter().map(|(_, sp)| *sp).collect::>(), - |lint| { - let mut err = lint.build(&format!("unused variable: `{}`", name)); - - let (shorthands, non_shorthands): (Vec<_>, Vec<_>) = - hir_ids_and_spans.into_iter().partition(|(hir_id, span)| { - let var = self.variable(*hir_id, *span); - self.ir.variable_is_shorthand(var) - }); - - let mut shorthands = shorthands - .into_iter() - .map(|(_, span)| (span, format!("{}: _", name))) - .collect::>(); - - // If we have both shorthand and non-shorthand, prefer the "try ignoring - // the field" message, and suggest `_` for the non-shorthands. If we only - // have non-shorthand, then prefix with an underscore instead. - if !shorthands.is_empty() { - shorthands.extend( - non_shorthands - .into_iter() - .map(|(_, span)| (span, "_".to_string())) - .collect::>(), - ); + let (shorthands, non_shorthands): (Vec<_>, Vec<_>) = + hir_ids_and_spans.iter().copied().partition(|(hir_id, _, ident_span)| { + let var = self.variable(*hir_id, *ident_span); + self.ir.variable_is_shorthand(var) + }); + // If we have both shorthand and non-shorthand, prefer the "try ignoring + // the field" message, and suggest `_` for the non-shorthands. If we only + // have non-shorthand, then prefix with an underscore instead. + if !shorthands.is_empty() { + let shorthands = shorthands + .into_iter() + .map(|(_, pat_span, _)| (pat_span, format!("{}: _", name))) + .chain( + non_shorthands + .into_iter() + .map(|(_, pat_span, _)| (pat_span, "_".to_string())), + ) + .collect::>(); + + self.ir.tcx.struct_span_lint_hir( + lint::builtin::UNUSED_VARIABLES, + first_hir_id, + hir_ids_and_spans + .iter() + .map(|(_, pat_span, _)| *pat_span) + .collect::>(), + |lint| { + let mut err = lint.build(&format!("unused variable: `{}`", name)); err.multipart_suggestion( "try ignoring the field", shorthands, Applicability::MachineApplicable, ); - } else { + err.emit() + }, + ); + } else { + let non_shorthands = non_shorthands + .into_iter() + .map(|(_, _, ident_span)| (ident_span, format!("_{}", name))) + .collect::>(); + + self.ir.tcx.struct_span_lint_hir( + lint::builtin::UNUSED_VARIABLES, + first_hir_id, + hir_ids_and_spans + .iter() + .map(|(_, _, ident_span)| *ident_span) + .collect::>(), + |lint| { + let mut err = lint.build(&format!("unused variable: `{}`", name)); err.multipart_suggestion( "if this is intentional, prefix it with an underscore", - non_shorthands - .into_iter() - .map(|(_, span)| (span, format!("_{}", name))) - .collect::>(), + non_shorthands, Applicability::MachineApplicable, ); - } - - err.emit() - }, - ); + err.emit() + }, + ); + } } } } From 6214ef8a0fd0f3275dc6954198be3ed9d960ac76 Mon Sep 17 00:00:00 2001 From: Giacomo Stevanato Date: Sun, 28 Feb 2021 21:03:36 +0100 Subject: [PATCH 05/16] Bless some tests --- ...ue-47390-unused-variable-in-struct-pattern.stderr | 12 ++++++------ src/test/ui/liveness/liveness-consts.stderr | 4 ++-- src/test/ui/liveness/liveness-dead.stderr | 8 ++++---- src/test/ui/liveness/liveness-unused.stderr | 8 ++++---- 4 files changed, 16 insertions(+), 16 deletions(-) diff --git a/src/test/ui/lint/issue-47390-unused-variable-in-struct-pattern.stderr b/src/test/ui/lint/issue-47390-unused-variable-in-struct-pattern.stderr index 3efd87f6a5f11..2ef655efdbdf0 100644 --- a/src/test/ui/lint/issue-47390-unused-variable-in-struct-pattern.stderr +++ b/src/test/ui/lint/issue-47390-unused-variable-in-struct-pattern.stderr @@ -12,16 +12,16 @@ LL | #![warn(unused)] // UI tests pass `-A unused` (#43896) = note: `#[warn(unused_variables)]` implied by `#[warn(unused)]` warning: unused variable: `mut_unused_var` - --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:33:9 + --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:33:13 | LL | let mut mut_unused_var = 1; - | ^^^^^^^^^^^^^^^^^^ help: if this is intentional, prefix it with an underscore: `_mut_unused_var` + | ^^^^^^^^^^^^^^ help: if this is intentional, prefix it with an underscore: `_mut_unused_var` warning: unused variable: `var` - --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:37:10 + --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:37:14 | LL | let (mut var, unused_var) = (1, 2); - | ^^^^^^^ help: if this is intentional, prefix it with an underscore: `_var` + | ^^^ help: if this is intentional, prefix it with an underscore: `_var` warning: unused variable: `unused_var` --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:37:19 @@ -36,10 +36,10 @@ LL | if let SoulHistory { corridors_of_light, | ^^^^^^^^^^^^^^^^^^ help: try ignoring the field: `corridors_of_light: _` warning: variable `hours_are_suns` is assigned to, but never used - --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:46:26 + --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:46:30 | LL | mut hours_are_suns, - | ^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^ | = note: consider using `_hours_are_suns` instead diff --git a/src/test/ui/liveness/liveness-consts.stderr b/src/test/ui/liveness/liveness-consts.stderr index fa8a590a819d1..b1beec97df568 100644 --- a/src/test/ui/liveness/liveness-consts.stderr +++ b/src/test/ui/liveness/liveness-consts.stderr @@ -1,8 +1,8 @@ warning: variable `a` is assigned to, but never used - --> $DIR/liveness-consts.rs:7:9 + --> $DIR/liveness-consts.rs:7:13 | LL | let mut a = 0; - | ^^^^^ + | ^ | note: the lint level is defined here --> $DIR/liveness-consts.rs:2:9 diff --git a/src/test/ui/liveness/liveness-dead.stderr b/src/test/ui/liveness/liveness-dead.stderr index e9d20cf981fbd..12680ab11568f 100644 --- a/src/test/ui/liveness/liveness-dead.stderr +++ b/src/test/ui/liveness/liveness-dead.stderr @@ -1,8 +1,8 @@ error: value assigned to `x` is never read - --> $DIR/liveness-dead.rs:9:9 + --> $DIR/liveness-dead.rs:9:13 | LL | let mut x: isize = 3; - | ^^^^^ + | ^ | note: the lint level is defined here --> $DIR/liveness-dead.rs:2:9 @@ -20,10 +20,10 @@ LL | x = 4; = help: maybe it is overwritten before being read? error: value passed to `x` is never read - --> $DIR/liveness-dead.rs:20:7 + --> $DIR/liveness-dead.rs:20:11 | LL | fn f4(mut x: i32) { - | ^^^^^ + | ^ | = help: maybe it is overwritten before being read? diff --git a/src/test/ui/liveness/liveness-unused.stderr b/src/test/ui/liveness/liveness-unused.stderr index 2c5550ac47f22..4a6122681a946 100644 --- a/src/test/ui/liveness/liveness-unused.stderr +++ b/src/test/ui/liveness/liveness-unused.stderr @@ -44,10 +44,10 @@ LL | let x = 3; | ^ help: if this is intentional, prefix it with an underscore: `_x` error: variable `x` is assigned to, but never used - --> $DIR/liveness-unused.rs:30:9 + --> $DIR/liveness-unused.rs:30:13 | LL | let mut x = 3; - | ^^^^^ + | ^ | = note: consider using `_x` instead @@ -65,10 +65,10 @@ LL | #![deny(unused_assignments)] = help: maybe it is overwritten before being read? error: variable `z` is assigned to, but never used - --> $DIR/liveness-unused.rs:37:9 + --> $DIR/liveness-unused.rs:37:13 | LL | let mut z = 3; - | ^^^^^ + | ^ | = note: consider using `_z` instead From 65f0b2549c35fb9cbfaa594ae190011187df1cec Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Mon, 28 Dec 2020 13:28:29 -0500 Subject: [PATCH 06/16] 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 07/16] 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; From 4d7a6484852603749f765479ee7288e6ae7186f4 Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Thu, 11 Feb 2021 21:29:22 -0500 Subject: [PATCH 08/16] Remove the dummy cache in `DocContext` The same information is available everywhere; the only reason the dummy cache was needed is because it waas previously stored in three different places. This consolidates the info a bit so the cache in `DocContext` is used throughout. As a bonus, it means `renderinfo` is used much much less. - Return a `Cache` from `run_global_ctxt`, not `RenderInfo` - Remove the unused `render_info` from `run_renderer` - Remove RefCell around `inlined` - Add intra-doc links --- src/librustdoc/clean/blanket_impl.rs | 2 +- src/librustdoc/clean/inline.rs | 13 +++-- src/librustdoc/clean/mod.rs | 2 +- src/librustdoc/clean/utils.rs | 12 ++-- src/librustdoc/core.rs | 25 ++++++--- src/librustdoc/formats/cache.rs | 55 ++++++++++--------- src/librustdoc/formats/renderer.rs | 17 +----- src/librustdoc/html/render/mod.rs | 3 +- src/librustdoc/json/mod.rs | 3 +- src/librustdoc/lib.rs | 12 ++-- .../passes/calculate_doc_coverage.rs | 2 +- src/librustdoc/passes/collect_trait_impls.rs | 2 +- src/librustdoc/passes/doc_test_lints.rs | 2 +- src/librustdoc/passes/strip_private.rs | 3 +- src/librustdoc/visit_ast.rs | 6 +- src/librustdoc/visit_lib.rs | 2 +- 16 files changed, 79 insertions(+), 82 deletions(-) diff --git a/src/librustdoc/clean/blanket_impl.rs b/src/librustdoc/clean/blanket_impl.rs index 5cda4cc5ada71..4e4e1e5cbce2f 100644 --- a/src/librustdoc/clean/blanket_impl.rs +++ b/src/librustdoc/clean/blanket_impl.rs @@ -21,7 +21,7 @@ impl<'a, 'tcx> BlanketImplFinder<'a, 'tcx> { debug!("get_blanket_impls({:?})", ty); let mut impls = Vec::new(); for &trait_def_id in self.cx.tcx.all_traits(LOCAL_CRATE).iter() { - if !self.cx.renderinfo.access_levels.is_public(trait_def_id) + if !self.cx.cache.access_levels.is_public(trait_def_id) || self.cx.generated_synthetics.get(&(ty, trait_def_id)).is_some() { continue; diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs index 9cfa72132cb5a..47a74238a7a3d 100644 --- a/src/librustdoc/clean/inline.rs +++ b/src/librustdoc/clean/inline.rs @@ -17,6 +17,7 @@ use rustc_span::Span; use crate::clean::{self, Attributes, GetDefId, ToSource, TypeKind}; use crate::core::DocContext; +use crate::formats::item_type::ItemType; use super::Clean; @@ -122,7 +123,7 @@ crate fn try_inline( let target_attrs = load_attrs(cx, did); let attrs = box merge_attrs(cx, Some(parent_module), target_attrs, attrs_clone); - cx.renderinfo.inlined.insert(did); + cx.inlined.insert(did); let what_rustc_thinks = clean::Item::from_def_id_and_parts(did, Some(name), kind, cx); ret.push(clean::Item { attrs, ..what_rustc_thinks }); Some(ret) @@ -181,9 +182,9 @@ crate fn record_extern_fqn(cx: &mut DocContext<'_>, did: DefId, kind: clean::Typ }; if did.is_local() { - cx.renderinfo.exact_paths.insert(did, fqn); + cx.cache.exact_paths.insert(did, fqn); } else { - cx.renderinfo.external_paths.insert(did, (fqn, kind)); + cx.cache.external_paths.insert(did, (fqn, ItemType::from(kind))); } } @@ -315,7 +316,7 @@ crate fn build_impl( attrs: Option>, ret: &mut Vec, ) { - if !cx.renderinfo.inlined.insert(did) { + if !cx.inlined.insert(did) { return; } @@ -327,7 +328,7 @@ crate fn build_impl( if !did.is_local() { if let Some(traitref) = associated_trait { let did = traitref.def_id; - if !cx.renderinfo.access_levels.is_public(did) { + if !cx.cache.access_levels.is_public(did) { return; } @@ -359,7 +360,7 @@ crate fn build_impl( // reachable in rustdoc generated documentation if !did.is_local() { if let Some(did) = for_.def_id() { - if !cx.renderinfo.access_levels.is_public(did) { + if !cx.cache.access_levels.is_public(did) { return; } diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 7aa34333e175d..5d81498f8d210 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -1304,7 +1304,7 @@ fn clean_qpath(hir_ty: &hir::Ty<'_>, cx: &mut DocContext<'_>) -> Type { // Substitute private type aliases if let Some(def_id) = def_id.as_local() { let hir_id = cx.tcx.hir().local_def_id_to_hir_id(def_id); - if !cx.renderinfo.access_levels.is_exported(def_id.to_def_id()) { + if !cx.cache.access_levels.is_exported(def_id.to_def_id()) { alias = Some(&cx.tcx.hir().expect_item(hir_id).kind); } } diff --git a/src/librustdoc/clean/utils.rs b/src/librustdoc/clean/utils.rs index 3414bf919401b..40f6c084a7178 100644 --- a/src/librustdoc/clean/utils.rs +++ b/src/librustdoc/clean/utils.rs @@ -17,21 +17,21 @@ use rustc_middle::ty::{self, DefIdTree, TyCtxt}; use rustc_span::symbol::{kw, sym, Symbol}; use std::mem; -crate fn krate(mut cx: &mut DocContext<'_>) -> Crate { +crate fn krate(cx: &mut DocContext<'_>) -> Crate { use crate::visit_lib::LibEmbargoVisitor; let krate = cx.tcx.hir().krate(); - let module = crate::visit_ast::RustdocVisitor::new(&mut cx).visit(krate); + let module = crate::visit_ast::RustdocVisitor::new(cx).visit(krate); - cx.renderinfo.deref_trait_did = cx.tcx.lang_items().deref_trait(); - cx.renderinfo.deref_mut_trait_did = cx.tcx.lang_items().deref_mut_trait(); - cx.renderinfo.owned_box_did = cx.tcx.lang_items().owned_box(); + cx.cache.deref_trait_did = cx.tcx.lang_items().deref_trait(); + cx.cache.deref_mut_trait_did = cx.tcx.lang_items().deref_mut_trait(); + cx.cache.owned_box_did = cx.tcx.lang_items().owned_box(); let mut externs = Vec::new(); for &cnum in cx.tcx.crates().iter() { externs.push((cnum, cnum.clean(cx))); // Analyze doc-reachability for extern items - LibEmbargoVisitor::new(&mut cx).visit_lib(cnum); + LibEmbargoVisitor::new(cx).visit_lib(cnum); } externs.sort_by(|&(a, _), &(b, _)| a.cmp(&b)); diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs index f0b3159f737a6..727b79d4e3b5a 100644 --- a/src/librustdoc/core.rs +++ b/src/librustdoc/core.rs @@ -52,8 +52,6 @@ crate struct DocContext<'tcx> { /// /// Most of this logic is copied from rustc_lint::late. crate param_env: ParamEnv<'tcx>, - /// Later on moved into `cache` - crate renderinfo: RenderInfo, /// Later on moved through `clean::Crate` into `cache` crate external_traits: Rc>>, /// Used while populating `external_traits` to ensure we don't process the same trait twice at @@ -81,8 +79,12 @@ crate struct DocContext<'tcx> { /// See `collect_intra_doc_links::traits_implemented_by` for more details. /// `map>` crate module_trait_cache: RefCell>>, - /// Fake empty cache used when cache is required as parameter. + /// This same cache is used throughout rustdoc, including in [`crate::html::render`]. crate cache: Cache, + /// Used by [`clean::inline`] to tell if an item has already been inlined. + crate inlined: FxHashSet, + /// Used by `calculate_doc_coverage`. + crate output_format: OutputFormat, } impl<'tcx> DocContext<'tcx> { @@ -465,7 +467,7 @@ crate fn run_global_ctxt( mut manual_passes: Vec, render_options: RenderOptions, output_format: OutputFormat, -) -> (clean::Crate, RenderInfo, RenderOptions) { +) -> (clean::Crate, RenderOptions, Cache) { // Certain queries assume that some checks were run elsewhere // (see https://github.com/rust-lang/rust/pull/73566#issuecomment-656954425), // so type-check everything other than function bodies in this crate before running lints. @@ -514,7 +516,6 @@ crate fn run_global_ctxt( param_env: ParamEnv::empty(), external_traits: Default::default(), active_extern_traits: Default::default(), - renderinfo, ty_substs: Default::default(), lt_substs: Default::default(), ct_substs: Default::default(), @@ -527,9 +528,11 @@ crate fn run_global_ctxt( .cloned() .filter(|trait_def_id| tcx.trait_is_auto(*trait_def_id)) .collect(), - render_options, module_trait_cache: RefCell::new(FxHashMap::default()), - cache: Cache::default(), + cache: Cache::new(renderinfo, render_options.document_private), + inlined: FxHashSet::default(), + output_format, + render_options, }; // Small hack to force the Sized trait to be present. @@ -647,10 +650,16 @@ crate fn run_global_ctxt( ctxt.sess().abort_if_errors(); + let render_options = ctxt.render_options; + let mut cache = ctxt.cache; + krate = tcx.sess.time("create_format_cache", || { + cache.populate(krate, tcx, &render_options.extern_html_root_urls, &render_options.output) + }); + // The main crate doc comments are always collapsed. krate.collapsed = true; - (krate, ctxt.renderinfo, ctxt.render_options) + (krate, render_options, cache) } /// Due to , diff --git a/src/librustdoc/formats/cache.rs b/src/librustdoc/formats/cache.rs index e9c5dd50d59a8..3b2ede577aa3e 100644 --- a/src/librustdoc/formats/cache.rs +++ b/src/librustdoc/formats/cache.rs @@ -131,14 +131,7 @@ struct CacheBuilder<'a, 'tcx> { } impl Cache { - crate fn from_krate<'tcx>( - render_info: RenderInfo, - document_private: bool, - extern_html_root_urls: &BTreeMap, - dst: &Path, - mut krate: clean::Crate, - tcx: TyCtxt<'tcx>, - ) -> (clean::Crate, Cache) { + crate fn new(render_info: RenderInfo, document_private: bool) -> Self { // Crawl the crate to build various caches used for the output let RenderInfo { inlined: _, @@ -154,21 +147,31 @@ impl Cache { let external_paths = external_paths.into_iter().map(|(k, (v, t))| (k, (v, ItemType::from(t)))).collect(); - let mut cache = Cache { + Cache { external_paths, exact_paths, - parent_is_trait_impl: false, - stripped_mod: false, access_levels, - crate_version: krate.version.take(), document_private, - traits: krate.external_traits.replace(Default::default()), deref_trait_did, deref_mut_trait_did, owned_box_did, - masked_crates: mem::take(&mut krate.masked_crates), ..Cache::default() - }; + } + } + + /// Populates the `Cache` with more data. The returned `Crate` will be missing some data that was + /// in `krate` due to the data being moved into the `Cache`. + crate fn populate( + &mut self, + mut krate: clean::Crate, + tcx: TyCtxt<'_>, + extern_html_root_urls: &BTreeMap, + dst: &Path, + ) -> clean::Crate { + self.crate_version = krate.version.take(); + debug!(?self.crate_version); + self.traits = krate.external_traits.take(); + self.masked_crates = mem::take(&mut krate.masked_crates); // Cache where all our extern crates are located // FIXME: this part is specific to HTML so it'd be nice to remove it from the common code @@ -181,12 +184,11 @@ impl Cache { _ => PathBuf::new(), }; let extern_url = extern_html_root_urls.get(&*e.name.as_str()).map(|u| &**u); - cache - .extern_locations + self.extern_locations .insert(n, (e.name, src_root, extern_location(e, extern_url, &dst))); let did = DefId { krate: n, index: CRATE_DEF_INDEX }; - cache.external_paths.insert(did, (vec![e.name.to_string()], ItemType::Module)); + self.external_paths.insert(did, (vec![e.name.to_string()], ItemType::Module)); } // Cache where all known primitives have their documentation located. @@ -195,27 +197,26 @@ impl Cache { // reverse topological order. for &(_, ref e) in krate.externs.iter().rev() { for &(def_id, prim) in &e.primitives { - cache.primitive_locations.insert(prim, def_id); + self.primitive_locations.insert(prim, def_id); } } for &(def_id, prim) in &krate.primitives { - cache.primitive_locations.insert(prim, def_id); + self.primitive_locations.insert(prim, def_id); } - cache.stack.push(krate.name.to_string()); + self.stack.push(krate.name.to_string()); - krate = CacheBuilder { tcx, cache: &mut cache, empty_cache: Cache::default() } - .fold_crate(krate); + krate = CacheBuilder { tcx, cache: self, empty_cache: Cache::default() }.fold_crate(krate); - for (trait_did, dids, impl_) in cache.orphan_trait_impls.drain(..) { - if cache.traits.contains_key(&trait_did) { + for (trait_did, dids, impl_) in self.orphan_trait_impls.drain(..) { + if self.traits.contains_key(&trait_did) { for did in dids { - cache.impls.entry(did).or_default().push(impl_.clone()); + self.impls.entry(did).or_default().push(impl_.clone()); } } } - (krate, cache) + krate } } diff --git a/src/librustdoc/formats/renderer.rs b/src/librustdoc/formats/renderer.rs index 6437ba45511a1..b779363e5c701 100644 --- a/src/librustdoc/formats/renderer.rs +++ b/src/librustdoc/formats/renderer.rs @@ -2,7 +2,7 @@ use rustc_middle::ty::TyCtxt; use rustc_span::edition::Edition; use crate::clean; -use crate::config::{RenderInfo, RenderOptions}; +use crate::config::RenderOptions; use crate::error::Error; use crate::formats::cache::Cache; @@ -18,7 +18,6 @@ crate trait FormatRenderer<'tcx>: Clone { fn init( krate: clean::Crate, options: RenderOptions, - render_info: RenderInfo, edition: Edition, cache: Cache, tcx: TyCtxt<'tcx>, @@ -49,26 +48,16 @@ crate trait FormatRenderer<'tcx>: Clone { crate fn run_format<'tcx, T: FormatRenderer<'tcx>>( krate: clean::Crate, options: RenderOptions, - render_info: RenderInfo, + cache: Cache, diag: &rustc_errors::Handler, edition: Edition, tcx: TyCtxt<'tcx>, ) -> Result<(), Error> { - let (krate, cache) = tcx.sess.time("create_format_cache", || { - Cache::from_krate( - render_info.clone(), - options.document_private, - &options.extern_html_root_urls, - &options.output, - krate, - tcx, - ) - }); let prof = &tcx.sess.prof; let (mut format_renderer, mut krate) = prof .extra_verbose_generic_activity("create_renderer", T::descr()) - .run(|| T::init(krate, options, render_info, edition, cache, tcx))?; + .run(|| T::init(krate, options, edition, cache, tcx))?; let mut item = match krate.module.take() { Some(i) => i, diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs index 58e9e41e6a53c..4e762a40f0849 100644 --- a/src/librustdoc/html/render/mod.rs +++ b/src/librustdoc/html/render/mod.rs @@ -66,7 +66,7 @@ use serde::ser::SerializeSeq; use serde::{Serialize, Serializer}; use crate::clean::{self, AttributesExt, GetDefId, RenderedLink, SelfTy, TypeKind}; -use crate::config::{RenderInfo, RenderOptions}; +use crate::config::RenderOptions; use crate::docfs::{DocFS, PathError}; use crate::error::Error; use crate::formats::cache::Cache; @@ -385,7 +385,6 @@ impl<'tcx> FormatRenderer<'tcx> for Context<'tcx> { fn init( mut krate: clean::Crate, options: RenderOptions, - _render_info: RenderInfo, edition: Edition, mut cache: Cache, tcx: TyCtxt<'tcx>, diff --git a/src/librustdoc/json/mod.rs b/src/librustdoc/json/mod.rs index a3b214677941b..bd5802a99dda2 100644 --- a/src/librustdoc/json/mod.rs +++ b/src/librustdoc/json/mod.rs @@ -19,7 +19,7 @@ use rustc_span::edition::Edition; use rustdoc_json_types as types; use crate::clean; -use crate::config::{RenderInfo, RenderOptions}; +use crate::config::RenderOptions; use crate::error::Error; use crate::formats::cache::Cache; use crate::formats::FormatRenderer; @@ -133,7 +133,6 @@ impl<'tcx> FormatRenderer<'tcx> for JsonRenderer<'tcx> { fn init( krate: clean::Crate, options: RenderOptions, - _render_info: RenderInfo, _edition: Edition, cache: Cache, tcx: TyCtxt<'tcx>, diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs index 2342ed3ab670d..be7e25925e733 100644 --- a/src/librustdoc/lib.rs +++ b/src/librustdoc/lib.rs @@ -479,12 +479,12 @@ fn wrap_return(diag: &rustc_errors::Handler, res: Result<(), String>) -> MainRes fn run_renderer<'tcx, T: formats::FormatRenderer<'tcx>>( krate: clean::Crate, renderopts: config::RenderOptions, - render_info: config::RenderInfo, + cache: formats::cache::Cache, diag: &rustc_errors::Handler, edition: rustc_span::edition::Edition, tcx: TyCtxt<'tcx>, ) -> MainResult { - match formats::run_format::(krate, renderopts, render_info, &diag, edition, tcx) { + match formats::run_format::(krate, renderopts, cache, &diag, edition, tcx) { Ok(_) => Ok(()), Err(e) => { let mut msg = diag.struct_err(&format!("couldn't generate documentation: {}", e.error)); @@ -553,7 +553,7 @@ fn main_options(options: config::Options) -> MainResult { let mut global_ctxt = abort_on_err(queries.global_ctxt(), sess).peek_mut(); global_ctxt.enter(|tcx| { - let (mut krate, render_info, render_opts) = sess.time("run_global_ctxt", || { + let (krate, render_opts, mut cache) = sess.time("run_global_ctxt", || { core::run_global_ctxt( tcx, resolver, @@ -565,7 +565,7 @@ fn main_options(options: config::Options) -> MainResult { }); info!("finished with rustc"); - krate.version = crate_version; + cache.crate_version = crate_version; if show_coverage { // if we ran coverage, bail early, we don't need to also generate docs at this point @@ -584,7 +584,7 @@ fn main_options(options: config::Options) -> MainResult { run_renderer::>( krate, render_opts, - render_info, + cache, &diag, edition, tcx, @@ -594,7 +594,7 @@ fn main_options(options: config::Options) -> MainResult { run_renderer::>( krate, render_opts, - render_info, + cache, &diag, edition, tcx, diff --git a/src/librustdoc/passes/calculate_doc_coverage.rs b/src/librustdoc/passes/calculate_doc_coverage.rs index c3365b844ecb8..bb54523871c3e 100644 --- a/src/librustdoc/passes/calculate_doc_coverage.rs +++ b/src/librustdoc/passes/calculate_doc_coverage.rs @@ -127,7 +127,7 @@ impl<'a, 'b> CoverageCalculator<'a, 'b> { } fn print_results(&self) { - let output_format = self.ctx.renderinfo.output_format; + let output_format = self.ctx.output_format; if output_format.is_json() { println!("{}", self.to_json()); return; diff --git a/src/librustdoc/passes/collect_trait_impls.rs b/src/librustdoc/passes/collect_trait_impls.rs index 0e84a51017761..685451b87eda9 100644 --- a/src/librustdoc/passes/collect_trait_impls.rs +++ b/src/librustdoc/passes/collect_trait_impls.rs @@ -47,7 +47,7 @@ crate fn collect_trait_impls(krate: Crate, cx: &mut DocContext<'_>) -> Crate { // FIXME(eddyb) is this `doc(hidden)` check needed? if !cx.tcx.get_attrs(def_id).lists(sym::doc).has_word(sym::hidden) { let impls = get_auto_trait_and_blanket_impls(cx, def_id); - new_items.extend(impls.filter(|i| cx.renderinfo.inlined.insert(i.def_id))); + new_items.extend(impls.filter(|i| cx.inlined.insert(i.def_id))); } }); } diff --git a/src/librustdoc/passes/doc_test_lints.rs b/src/librustdoc/passes/doc_test_lints.rs index e8e1bead84fb6..3b1508c134857 100644 --- a/src/librustdoc/passes/doc_test_lints.rs +++ b/src/librustdoc/passes/doc_test_lints.rs @@ -97,7 +97,7 @@ crate fn look_for_tests<'tcx>(cx: &DocContext<'tcx>, dox: &str, item: &Item) { |lint| lint.build("missing code example in this documentation").emit(), ); } - } else if tests.found_tests > 0 && !cx.renderinfo.access_levels.is_public(item.def_id) { + } else if tests.found_tests > 0 && !cx.cache.access_levels.is_public(item.def_id) { cx.tcx.struct_span_lint_hir( lint::builtin::PRIVATE_DOC_TESTS, hir_id, diff --git a/src/librustdoc/passes/strip_private.rs b/src/librustdoc/passes/strip_private.rs index f83eab6799ee6..fc8bbc9715029 100644 --- a/src/librustdoc/passes/strip_private.rs +++ b/src/librustdoc/passes/strip_private.rs @@ -17,13 +17,12 @@ crate const STRIP_PRIVATE: Pass = Pass { crate fn strip_private(mut krate: clean::Crate, cx: &mut DocContext<'_>) -> clean::Crate { // This stripper collects all *retained* nodes. let mut retained = DefIdSet::default(); - let access_levels = cx.renderinfo.access_levels.clone(); // strip all private items { let mut stripper = Stripper { retained: &mut retained, - access_levels: &access_levels, + access_levels: &cx.cache.access_levels, update_retained: true, }; krate = ImportStripper.fold_crate(stripper.fold_crate(krate)); diff --git a/src/librustdoc/visit_ast.rs b/src/librustdoc/visit_ast.rs index 4d42c181d8cf2..5da7d2f1e9b84 100644 --- a/src/librustdoc/visit_ast.rs +++ b/src/librustdoc/visit_ast.rs @@ -113,7 +113,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { assert_eq!(cur_mod_def_id, macro_parent_def_id); cur_mod.macros.push((def, None)); } - self.cx.renderinfo.exact_paths = self.exact_paths; + self.cx.cache.exact_paths = self.exact_paths; top_level_module } @@ -199,7 +199,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { } else { // All items need to be handled here in case someone wishes to link // to them with intra-doc links - self.cx.renderinfo.access_levels.map.insert(did, AccessLevel::Public); + self.cx.cache.access_levels.map.insert(did, AccessLevel::Public); } } } @@ -211,7 +211,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { None => return false, }; - let is_private = !self.cx.renderinfo.access_levels.is_public(res_did); + let is_private = !self.cx.cache.access_levels.is_public(res_did); let is_hidden = inherits_doc_hidden(self.cx, res_hir_id); // Only inline if requested or if the item would otherwise be stripped. diff --git a/src/librustdoc/visit_lib.rs b/src/librustdoc/visit_lib.rs index daed5bd107db1..3e06b4173144c 100644 --- a/src/librustdoc/visit_lib.rs +++ b/src/librustdoc/visit_lib.rs @@ -25,7 +25,7 @@ impl<'a, 'tcx> LibEmbargoVisitor<'a, 'tcx> { crate fn new(cx: &'a mut crate::core::DocContext<'tcx>) -> LibEmbargoVisitor<'a, 'tcx> { LibEmbargoVisitor { tcx: cx.tcx, - access_levels: &mut cx.renderinfo.access_levels, + access_levels: &mut cx.cache.access_levels, prev_level: Some(AccessLevel::Public), visited_mods: FxHashSet::default(), } From 163b01aa140299ca5934031e5edf17cb23184941 Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Fri, 12 Feb 2021 00:03:24 -0500 Subject: [PATCH 09/16] Remove unused `RenderInfo` struct --- src/librustdoc/config.rs | 18 +----------------- src/librustdoc/core.rs | 11 ++--------- src/librustdoc/formats/cache.rs | 30 +++--------------------------- 3 files changed, 6 insertions(+), 53 deletions(-) diff --git a/src/librustdoc/config.rs b/src/librustdoc/config.rs index 1478437cefaa3..d9f5b5bfa3ae2 100644 --- a/src/librustdoc/config.rs +++ b/src/librustdoc/config.rs @@ -4,9 +4,7 @@ use std::ffi::OsStr; use std::fmt; use std::path::PathBuf; -use rustc_data_structures::fx::{FxHashMap, FxHashSet}; -use rustc_hir::def_id::DefId; -use rustc_middle::middle::privacy::AccessLevels; +use rustc_data_structures::fx::FxHashMap; use rustc_session::config::{self, parse_crate_types_from_list, parse_externs, CrateType}; use rustc_session::config::{ build_codegen_options, build_debugging_options, get_cmd_lint_options, host_triple, @@ -268,20 +266,6 @@ crate struct RenderOptions { crate unstable_features: rustc_feature::UnstableFeatures, } -/// Temporary storage for data obtained during `RustdocVisitor::clean()`. -/// Later on moved into `cache`. -#[derive(Default, Clone)] -crate struct RenderInfo { - crate inlined: FxHashSet, - crate external_paths: crate::core::ExternalPaths, - crate exact_paths: FxHashMap>, - crate access_levels: AccessLevels, - crate deref_trait_did: Option, - crate deref_mut_trait_did: Option, - crate owned_box_did: Option, - crate output_format: OutputFormat, -} - impl Options { /// Parses the given command-line for options. If an error message or other early-return has /// been printed, returns `Err` with the exit code. diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs index 727b79d4e3b5a..1d55fa42a3a9b 100644 --- a/src/librustdoc/core.rs +++ b/src/librustdoc/core.rs @@ -31,15 +31,12 @@ use std::{cell::RefCell, collections::hash_map::Entry}; use crate::clean; use crate::clean::inline::build_external_trait; use crate::clean::{AttributesExt, TraitWithExtraInfo, MAX_DEF_IDX}; -use crate::config::{Options as RustdocOptions, RenderOptions}; -use crate::config::{OutputFormat, RenderInfo}; +use crate::config::{Options as RustdocOptions, OutputFormat, RenderOptions}; use crate::formats::cache::Cache; use crate::passes::{self, Condition::*, ConditionalPass}; crate use rustc_session::config::{DebuggingOptions, Input, Options}; -crate type ExternalPaths = FxHashMap, clean::TypeKind)>; - crate struct DocContext<'tcx> { crate tcx: TyCtxt<'tcx>, /// Name resolver. Used for intra-doc links. @@ -506,10 +503,6 @@ crate fn run_global_ctxt( .collect(), }; - let mut renderinfo = RenderInfo::default(); - renderinfo.access_levels = access_levels; - renderinfo.output_format = output_format; - let mut ctxt = DocContext { tcx, resolver, @@ -529,7 +522,7 @@ crate fn run_global_ctxt( .filter(|trait_def_id| tcx.trait_is_auto(*trait_def_id)) .collect(), module_trait_cache: RefCell::new(FxHashMap::default()), - cache: Cache::new(renderinfo, render_options.document_private), + cache: Cache::new(access_levels, render_options.document_private), inlined: FxHashSet::default(), output_format, render_options, diff --git a/src/librustdoc/formats/cache.rs b/src/librustdoc/formats/cache.rs index 3b2ede577aa3e..1636af70a9ae5 100644 --- a/src/librustdoc/formats/cache.rs +++ b/src/librustdoc/formats/cache.rs @@ -11,7 +11,6 @@ use rustc_span::symbol::sym; use rustc_span::Symbol; use crate::clean::{self, GetDefId}; -use crate::config::RenderInfo; use crate::fold::DocFolder; use crate::formats::item_type::ItemType; use crate::formats::Impl; @@ -131,32 +130,8 @@ struct CacheBuilder<'a, 'tcx> { } impl Cache { - crate fn new(render_info: RenderInfo, document_private: bool) -> Self { - // Crawl the crate to build various caches used for the output - let RenderInfo { - inlined: _, - external_paths, - exact_paths, - access_levels, - deref_trait_did, - deref_mut_trait_did, - owned_box_did, - .. - } = render_info; - - let external_paths = - external_paths.into_iter().map(|(k, (v, t))| (k, (v, ItemType::from(t)))).collect(); - - Cache { - external_paths, - exact_paths, - access_levels, - document_private, - deref_trait_did, - deref_mut_trait_did, - owned_box_did, - ..Cache::default() - } + crate fn new(access_levels: AccessLevels, document_private: bool) -> Self { + Cache { access_levels, document_private, ..Cache::default() } } /// Populates the `Cache` with more data. The returned `Crate` will be missing some data that was @@ -168,6 +143,7 @@ impl Cache { extern_html_root_urls: &BTreeMap, dst: &Path, ) -> clean::Crate { + // Crawl the crate to build various caches used for the output self.crate_version = krate.version.take(); debug!(?self.crate_version); self.traits = krate.external_traits.take(); From be069a687a4e1c231b8ae8c68ac0444fa6fee249 Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Thu, 25 Feb 2021 00:16:47 -0500 Subject: [PATCH 10/16] Remove `krate.version`; fix `crate_version` in JSON Previously, `JsonRenderer::after_krate` called `krate.version.clone()`. The problem was it did that after the version was already moved into the cache, so it would always be None. The fix was to get the version from the cache instead. --- src/librustdoc/clean/types.rs | 1 - src/librustdoc/clean/utils.rs | 1 - src/librustdoc/formats/cache.rs | 1 - src/librustdoc/json/mod.rs | 4 ++-- src/test/rustdoc-json/nested.rs | 4 +++- 5 files changed, 5 insertions(+), 6 deletions(-) diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs index 7fc48cd5f0b38..09ba0e2740f1b 100644 --- a/src/librustdoc/clean/types.rs +++ b/src/librustdoc/clean/types.rs @@ -50,7 +50,6 @@ thread_local!(crate static MAX_DEF_IDX: RefCell> = #[derive(Clone, Debug)] crate struct Crate { crate name: Symbol, - crate version: Option, crate src: FileName, crate module: Option, crate externs: Vec<(CrateNum, ExternalCrate)>, diff --git a/src/librustdoc/clean/utils.rs b/src/librustdoc/clean/utils.rs index 40f6c084a7178..a64e8c21c462e 100644 --- a/src/librustdoc/clean/utils.rs +++ b/src/librustdoc/clean/utils.rs @@ -77,7 +77,6 @@ crate fn krate(cx: &mut DocContext<'_>) -> Crate { Crate { name, - version: None, src, module: Some(module), externs, diff --git a/src/librustdoc/formats/cache.rs b/src/librustdoc/formats/cache.rs index 1636af70a9ae5..f20296f4fe148 100644 --- a/src/librustdoc/formats/cache.rs +++ b/src/librustdoc/formats/cache.rs @@ -144,7 +144,6 @@ impl Cache { dst: &Path, ) -> clean::Crate { // Crawl the crate to build various caches used for the output - self.crate_version = krate.version.take(); debug!(?self.crate_version); self.traits = krate.external_traits.take(); self.masked_crates = mem::take(&mut krate.masked_crates); diff --git a/src/librustdoc/json/mod.rs b/src/librustdoc/json/mod.rs index bd5802a99dda2..e6edf33d23c8d 100644 --- a/src/librustdoc/json/mod.rs +++ b/src/librustdoc/json/mod.rs @@ -199,7 +199,7 @@ impl<'tcx> FormatRenderer<'tcx> for JsonRenderer<'tcx> { fn after_krate( &mut self, - krate: &clean::Crate, + _krate: &clean::Crate, _diag: &rustc_errors::Handler, ) -> Result<(), Error> { debug!("Done with crate"); @@ -210,7 +210,7 @@ impl<'tcx> FormatRenderer<'tcx> for JsonRenderer<'tcx> { #[allow(rustc::default_hash_types)] let output = types::Crate { root: types::Id(String::from("0:0")), - crate_version: krate.version.clone(), + crate_version: self.cache.crate_version.clone(), includes_private: self.cache.document_private, index: index.into_iter().collect(), paths: self diff --git a/src/test/rustdoc-json/nested.rs b/src/test/rustdoc-json/nested.rs index a3d4935f49614..5bb66f7f6fd7c 100644 --- a/src/test/rustdoc-json/nested.rs +++ b/src/test/rustdoc-json/nested.rs @@ -1,6 +1,8 @@ // edition:2018 +// compile-flags: --crate-version 1.0.0 -// @is nested.json "$.index[*][?(@.name=='nested')].kind" \"module\" +// @is nested.json "$.crate_version" \"1.0.0\" +// @is - "$.index[*][?(@.name=='nested')].kind" \"module\" // @is - "$.index[*][?(@.name=='nested')].inner.is_crate" true // @count - "$.index[*][?(@.name=='nested')].inner.items[*]" 1 From 3c63f67802c728bd84953c19735fabd8f071c326 Mon Sep 17 00:00:00 2001 From: Giacomo Stevanato Date: Sun, 28 Feb 2021 21:03:44 +0100 Subject: [PATCH 11/16] Add regression test --- .../lint/issue-81314-unused-span-ident.fixed | 12 +++++++++++ .../ui/lint/issue-81314-unused-span-ident.rs | 12 +++++++++++ .../lint/issue-81314-unused-span-ident.stderr | 21 +++++++++++++++++++ 3 files changed, 45 insertions(+) create mode 100644 src/test/ui/lint/issue-81314-unused-span-ident.fixed create mode 100644 src/test/ui/lint/issue-81314-unused-span-ident.rs create mode 100644 src/test/ui/lint/issue-81314-unused-span-ident.stderr diff --git a/src/test/ui/lint/issue-81314-unused-span-ident.fixed b/src/test/ui/lint/issue-81314-unused-span-ident.fixed new file mode 100644 index 0000000000000..aac918f2bc817 --- /dev/null +++ b/src/test/ui/lint/issue-81314-unused-span-ident.fixed @@ -0,0 +1,12 @@ +// run-rustfix +// Regression test for #81314: Unused variable lint should +// span only the identifier and not the rest of the pattern + +#![deny(unused)] + +fn main() { + let [_rest @ ..] = [1, 2, 3]; //~ ERROR unused variable +} + +pub fn foo([_rest @ ..]: &[i32]) { //~ ERROR unused variable +} diff --git a/src/test/ui/lint/issue-81314-unused-span-ident.rs b/src/test/ui/lint/issue-81314-unused-span-ident.rs new file mode 100644 index 0000000000000..78296f4258d73 --- /dev/null +++ b/src/test/ui/lint/issue-81314-unused-span-ident.rs @@ -0,0 +1,12 @@ +// run-rustfix +// Regression test for #81314: Unused variable lint should +// span only the identifier and not the rest of the pattern + +#![deny(unused)] + +fn main() { + let [rest @ ..] = [1, 2, 3]; //~ ERROR unused variable +} + +pub fn foo([rest @ ..]: &[i32]) { //~ ERROR unused variable +} diff --git a/src/test/ui/lint/issue-81314-unused-span-ident.stderr b/src/test/ui/lint/issue-81314-unused-span-ident.stderr new file mode 100644 index 0000000000000..519c71e941311 --- /dev/null +++ b/src/test/ui/lint/issue-81314-unused-span-ident.stderr @@ -0,0 +1,21 @@ +error: unused variable: `rest` + --> $DIR/issue-81314-unused-span-ident.rs:8:10 + | +LL | let [rest @ ..] = [1, 2, 3]; + | ^^^^ help: if this is intentional, prefix it with an underscore: `_rest` + | +note: the lint level is defined here + --> $DIR/issue-81314-unused-span-ident.rs:5:9 + | +LL | #![deny(unused)] + | ^^^^^^ + = note: `#[deny(unused_variables)]` implied by `#[deny(unused)]` + +error: unused variable: `rest` + --> $DIR/issue-81314-unused-span-ident.rs:11:13 + | +LL | pub fn foo([rest @ ..]: &[i32]) { + | ^^^^ help: if this is intentional, prefix it with an underscore: `_rest` + +error: aborting due to 2 previous errors + From 5a33f531cd87988e95a8e811d71b653a7ff9ffca Mon Sep 17 00:00:00 2001 From: Austin Bonander Date: Tue, 5 Jan 2021 13:54:28 -0800 Subject: [PATCH 12/16] check that first arg to `panic!()` in const is `&str` --- .../src/transform/check_consts/ops.rs | 12 +++++++++ .../src/transform/check_consts/validation.rs | 12 +++++++-- .../consts/issue-66693-panic-in-array-len.rs | 17 ++++++++++++ .../issue-66693-panic-in-array-len.stderr | 19 ++++++++++++++ src/test/ui/consts/issue-66693.rs | 24 +++++++++++++++++ src/test/ui/consts/issue-66693.stderr | 26 +++++++++++++++++++ src/test/ui/consts/issue-76064.rs | 4 ++- src/test/ui/consts/issue-76064.stderr | 6 ++--- 8 files changed, 114 insertions(+), 6 deletions(-) create mode 100644 src/test/ui/consts/issue-66693-panic-in-array-len.rs create mode 100644 src/test/ui/consts/issue-66693-panic-in-array-len.stderr create mode 100644 src/test/ui/consts/issue-66693.rs create mode 100644 src/test/ui/consts/issue-66693.stderr diff --git a/compiler/rustc_mir/src/transform/check_consts/ops.rs b/compiler/rustc_mir/src/transform/check_consts/ops.rs index 9e90a7519cf2c..134b6d6fe075b 100644 --- a/compiler/rustc_mir/src/transform/check_consts/ops.rs +++ b/compiler/rustc_mir/src/transform/check_consts/ops.rs @@ -360,6 +360,18 @@ impl NonConstOp for Panic { } } +/// A call to a `panic()` lang item where the first argument is _not_ a `&str`. +#[derive(Debug)] +pub struct PanicNonStr; +impl NonConstOp for PanicNonStr { + fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> DiagnosticBuilder<'tcx> { + ccx.tcx.sess.struct_span_err( + span, + "argument to `panic!()` in a const context must have type `&str`", + ) + } +} + #[derive(Debug)] pub struct RawPtrComparison; impl NonConstOp for RawPtrComparison { diff --git a/compiler/rustc_mir/src/transform/check_consts/validation.rs b/compiler/rustc_mir/src/transform/check_consts/validation.rs index d1c07d1051d2f..fea5dd3554fb0 100644 --- a/compiler/rustc_mir/src/transform/check_consts/validation.rs +++ b/compiler/rustc_mir/src/transform/check_consts/validation.rs @@ -796,7 +796,7 @@ impl Visitor<'tcx> for Validator<'mir, 'tcx> { self.super_terminator(terminator, location); match &terminator.kind { - TerminatorKind::Call { func, .. } => { + TerminatorKind::Call { func, args, .. } => { let ConstCx { tcx, body, param_env, .. } = *self.ccx; let caller = self.def_id().to_def_id(); @@ -857,9 +857,17 @@ impl Visitor<'tcx> for Validator<'mir, 'tcx> { } // At this point, we are calling a function, `callee`, whose `DefId` is known... - if is_lang_panic_fn(tcx, callee) { self.check_op(ops::Panic); + + // const-eval of the `begin_panic` fn assumes the argument is `&str` + if Some(callee) == tcx.lang_items().begin_panic_fn() { + match args[0].ty(&self.ccx.body.local_decls, tcx).kind() { + ty::Ref(_, ty, _) if ty.is_str() => (), + _ => self.check_op(ops::PanicNonStr), + } + } + return; } diff --git a/src/test/ui/consts/issue-66693-panic-in-array-len.rs b/src/test/ui/consts/issue-66693-panic-in-array-len.rs new file mode 100644 index 0000000000000..718a19067a6ac --- /dev/null +++ b/src/test/ui/consts/issue-66693-panic-in-array-len.rs @@ -0,0 +1,17 @@ +// This is a separate test from `issue-66693.rs` because array lengths are evaluated +// in a separate stage before `const`s and `statics` and so the error below is hit and +// the compiler exits before generating errors for the others. + +#![feature(const_panic)] + +fn main() { + let _ = [0i32; panic!(2f32)]; + //~^ ERROR: argument to `panic!()` in a const context must have type `&str` + + // ensure that conforming panics are handled correctly + let _ = [false; panic!()]; + //~^ ERROR: evaluation of constant value failed + + // typechecking halts before getting to this one + let _ = ['a', panic!("panic in array len")]; +} diff --git a/src/test/ui/consts/issue-66693-panic-in-array-len.stderr b/src/test/ui/consts/issue-66693-panic-in-array-len.stderr new file mode 100644 index 0000000000000..e0ca9dfde0bf9 --- /dev/null +++ b/src/test/ui/consts/issue-66693-panic-in-array-len.stderr @@ -0,0 +1,19 @@ +error: argument to `panic!()` in a const context must have type `&str` + --> $DIR/issue-66693-panic-in-array-len.rs:8:20 + | +LL | let _ = [0i32; panic!(2f32)]; + | ^^^^^^^^^^^^ + | + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) + +error[E0080]: evaluation of constant value failed + --> $DIR/issue-66693-panic-in-array-len.rs:12:21 + | +LL | let _ = [false; panic!()]; + | ^^^^^^^^ the evaluated program panicked at 'explicit panic', $DIR/issue-66693-panic-in-array-len.rs:12:21 + | + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0080`. diff --git a/src/test/ui/consts/issue-66693.rs b/src/test/ui/consts/issue-66693.rs new file mode 100644 index 0000000000000..77fe4417d5b10 --- /dev/null +++ b/src/test/ui/consts/issue-66693.rs @@ -0,0 +1,24 @@ +// Tests that the compiler does not ICE when const-evaluating a `panic!()` invocation with a +// non-`&str` argument. + +#![feature(const_panic)] + +const _: () = panic!(1); +//~^ ERROR: argument to `panic!()` in a const context must have type `&str` + +static _FOO: () = panic!(true); +//~^ ERROR: argument to `panic!()` in a const context must have type `&str` + +const fn _foo() { + panic!(&1); //~ ERROR: argument to `panic!()` in a const context must have type `&str` +} + +// ensure that conforming panics don't cause an error +const _: () = panic!(); +static _BAR: () = panic!("panic in static"); + +const fn _bar() { + panic!("panic in const fn"); +} + +fn main() {} diff --git a/src/test/ui/consts/issue-66693.stderr b/src/test/ui/consts/issue-66693.stderr new file mode 100644 index 0000000000000..6bbde057ead7f --- /dev/null +++ b/src/test/ui/consts/issue-66693.stderr @@ -0,0 +1,26 @@ +error: argument to `panic!()` in a const context must have type `&str` + --> $DIR/issue-66693.rs:13:5 + | +LL | panic!(&1); + | ^^^^^^^^^^^ + | + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) + +error: argument to `panic!()` in a const context must have type `&str` + --> $DIR/issue-66693.rs:6:15 + | +LL | const _: () = panic!(1); + | ^^^^^^^^^ + | + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) + +error: argument to `panic!()` in a const context must have type `&str` + --> $DIR/issue-66693.rs:9:19 + | +LL | static _FOO: () = panic!(true); + | ^^^^^^^^^^^^ + | + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) + +error: aborting due to 3 previous errors + diff --git a/src/test/ui/consts/issue-76064.rs b/src/test/ui/consts/issue-76064.rs index 2da764b47c0c4..d511f75df8129 100644 --- a/src/test/ui/consts/issue-76064.rs +++ b/src/test/ui/consts/issue-76064.rs @@ -1,3 +1,5 @@ -struct Bug([u8; panic!(1)]); //~ ERROR panicking in constants is unstable +// Note: non-`&str` panic arguments gained a separate error in PR #80734 +// which is why this doesn't match the issue +struct Bug([u8; panic!("panic")]); //~ ERROR panicking in constants is unstable fn main() {} diff --git a/src/test/ui/consts/issue-76064.stderr b/src/test/ui/consts/issue-76064.stderr index f939ff3397504..9bda1b7570d56 100644 --- a/src/test/ui/consts/issue-76064.stderr +++ b/src/test/ui/consts/issue-76064.stderr @@ -1,8 +1,8 @@ error[E0658]: panicking in constants is unstable - --> $DIR/issue-76064.rs:1:17 + --> $DIR/issue-76064.rs:3:17 | -LL | struct Bug([u8; panic!(1)]); - | ^^^^^^^^^ +LL | struct Bug([u8; panic!("panic")]); + | ^^^^^^^^^^^^^^^ | = note: see issue #51999 for more information = help: add `#![feature(const_panic)]` to the crate attributes to enable From bd51dea6934d5c583fe9c8bc806e6287cac43f90 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Sun, 28 Feb 2021 23:51:30 -0800 Subject: [PATCH 13/16] Change twice used large const table to static This table is used twice in core::num::dec2flt::algorithm::power_of_ten. According to the semantics of const, a separate huge definition of the table is inlined at both places. fn power_of_ten(e: i16) -> Fp { assert!(e >= table::MIN_E); let i = e - table::MIN_E; let sig = table::POWERS.0[i as usize]; let exp = table::POWERS.1[i as usize]; Fp { f: sig, e: exp } } Theoretically this gets cleaned up by optimization passes, but in practice I am experiencing a miscompile from LTO on this code. Making the table a static, which would only be defined a single time and not require attention from LTO, eliminates the miscompile and seems semantically more appropriate anyway. A separate bug report on the LTO bug is forthcoming. --- library/core/src/num/dec2flt/table.rs | 2 +- src/etc/dec2flt_table.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/library/core/src/num/dec2flt/table.rs b/library/core/src/num/dec2flt/table.rs index 1bd94ffa04e0e..97b497e81e070 100644 --- a/library/core/src/num/dec2flt/table.rs +++ b/library/core/src/num/dec2flt/table.rs @@ -5,7 +5,7 @@ pub const MIN_E: i16 = -305; pub const MAX_E: i16 = 305; #[rustfmt::skip] -pub const POWERS: ([u64; 611], [i16; 611]) = ( +pub static POWERS: ([u64; 611], [i16; 611]) = ( [ 0xe0b62e2929aba83c, 0x8c71dcd9ba0b4926, diff --git a/src/etc/dec2flt_table.py b/src/etc/dec2flt_table.py index 9bbcaf7c4cc49..ad2292e857186 100755 --- a/src/etc/dec2flt_table.py +++ b/src/etc/dec2flt_table.py @@ -113,7 +113,7 @@ def print_proper_powers(): print() print("#[rustfmt::skip]") typ = "([u64; {0}], [i16; {0}])".format(len(powers)) - print("pub const POWERS: ", typ, " = (", sep='') + print("pub static POWERS: ", typ, " = (", sep='') print(" [") for z in powers: print(" 0x{:x},".format(z.sig)) From b0b330f143ba0d6769b0d7da6d9302eef33fca44 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Mon, 1 Mar 2021 17:12:39 +0100 Subject: [PATCH 14/16] Validate meta items used in \#\[doc(...)\] --- compiler/rustc_passes/src/check_attr.rs | 35 +++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index cf08881cd473d..afd1642bbd57c 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -544,6 +544,41 @@ impl CheckAttrVisitor<'tcx> { { return false; } + } else if let Some(i_meta) = meta.meta_item() { + if ![ + sym::cfg, + sym::hidden, + sym::html_favicon_url, + sym::html_logo_url, + sym::html_no_source, + sym::html_playground_url, + sym::html_root_url, + sym::include, + sym::inline, + sym::issue_tracker_base_url, + sym::masked, + sym::no_default_passes, // deprecated + sym::no_inline, + sym::passes, // deprecated + sym::primitive, + sym::spotlight, + sym::test, + ] + .iter() + .any(|m| i_meta.has_name(*m)) + { + self.tcx + .sess + .struct_span_err( + meta.span(), + &format!( + "unknown `doc` attribute `{}`", + i_meta.name_or_empty(), + ), + ) + .emit(); + return false; + } } } } From f6de1300b499c669a1a7865cb9860c27cebe5ac1 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Mon, 1 Mar 2021 17:13:06 +0100 Subject: [PATCH 15/16] Add tests for doc attribute check --- src/test/rustdoc-ui/doc-attr.rs | 5 +++++ src/test/rustdoc-ui/doc-attr.stderr | 14 ++++++++++++++ src/test/ui/attributes/doc-attr.rs | 5 +++++ src/test/ui/attributes/doc-attr.stderr | 14 ++++++++++++++ 4 files changed, 38 insertions(+) create mode 100644 src/test/rustdoc-ui/doc-attr.rs create mode 100644 src/test/rustdoc-ui/doc-attr.stderr create mode 100644 src/test/ui/attributes/doc-attr.rs create mode 100644 src/test/ui/attributes/doc-attr.stderr diff --git a/src/test/rustdoc-ui/doc-attr.rs b/src/test/rustdoc-ui/doc-attr.rs new file mode 100644 index 0000000000000..37c69a214b8ed --- /dev/null +++ b/src/test/rustdoc-ui/doc-attr.rs @@ -0,0 +1,5 @@ +#![crate_type = "lib"] +#![doc(as_ptr)] //~ ERROR + +#[doc(as_ptr)] //~ ERROR +pub fn foo() {} diff --git a/src/test/rustdoc-ui/doc-attr.stderr b/src/test/rustdoc-ui/doc-attr.stderr new file mode 100644 index 0000000000000..17bc3d6a45a05 --- /dev/null +++ b/src/test/rustdoc-ui/doc-attr.stderr @@ -0,0 +1,14 @@ +error: unknown `doc` attribute `as_ptr` + --> $DIR/doc-attr.rs:4:7 + | +LL | #[doc(as_ptr)] + | ^^^^^^ + +error: unknown `doc` attribute `as_ptr` + --> $DIR/doc-attr.rs:2:8 + | +LL | #![doc(as_ptr)] + | ^^^^^^ + +error: aborting due to 2 previous errors + diff --git a/src/test/ui/attributes/doc-attr.rs b/src/test/ui/attributes/doc-attr.rs new file mode 100644 index 0000000000000..37c69a214b8ed --- /dev/null +++ b/src/test/ui/attributes/doc-attr.rs @@ -0,0 +1,5 @@ +#![crate_type = "lib"] +#![doc(as_ptr)] //~ ERROR + +#[doc(as_ptr)] //~ ERROR +pub fn foo() {} diff --git a/src/test/ui/attributes/doc-attr.stderr b/src/test/ui/attributes/doc-attr.stderr new file mode 100644 index 0000000000000..17bc3d6a45a05 --- /dev/null +++ b/src/test/ui/attributes/doc-attr.stderr @@ -0,0 +1,14 @@ +error: unknown `doc` attribute `as_ptr` + --> $DIR/doc-attr.rs:4:7 + | +LL | #[doc(as_ptr)] + | ^^^^^^ + +error: unknown `doc` attribute `as_ptr` + --> $DIR/doc-attr.rs:2:8 + | +LL | #![doc(as_ptr)] + | ^^^^^^ + +error: aborting due to 2 previous errors + From d20fd62d7020162623c89b0ae984b8ad58c59a46 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Sun, 28 Feb 2021 00:48:22 +0100 Subject: [PATCH 16/16] Add missing stability attributes in libstd --- library/std/src/os/mod.rs | 1 + library/std/src/sys/mod.rs | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/library/std/src/os/mod.rs b/library/std/src/os/mod.rs index 500e8267cf821..31e39b5ad0421 100644 --- a/library/std/src/os/mod.rs +++ b/library/std/src/os/mod.rs @@ -23,6 +23,7 @@ pub use crate::sys::windows_ext as windows; pub mod linux; #[cfg(doc)] +#[stable(feature = "wasi_ext_doc", since = "1.35.0")] pub use crate::sys::wasi_ext as wasi; // If we're not documenting libstd then we just expose the main modules as we otherwise would. diff --git a/library/std/src/sys/mod.rs b/library/std/src/sys/mod.rs index d3f53801d2d0f..1e79a5c3f9bd5 100644 --- a/library/std/src/sys/mod.rs +++ b/library/std/src/sys/mod.rs @@ -111,7 +111,7 @@ cfg_if::cfg_if! { cfg_if::cfg_if! { if #[cfg(target_os = "wasi")] { // On WASI we'll document what's already available - #[stable(feature = "rust1", since = "1.0.0")] + #[stable(feature = "wasi_ext_doc", since = "1.35.0")] pub use self::ext as wasi_ext; } else if #[cfg(any(target_os = "hermit", target_arch = "wasm32", @@ -125,6 +125,7 @@ cfg_if::cfg_if! { } else { // On other platforms like Windows document the bare bones of WASI #[path = "wasi/ext/mod.rs"] + #[stable(feature = "wasi_ext_doc", since = "1.35.0")] pub mod wasi_ext; } }