diff --git a/Cargo.lock b/Cargo.lock index 358b2f2e924c3..da2e483fe61b2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3181,7 +3181,6 @@ dependencies = [ "rustc_index", "rustc_macros", "rustc_serialize", - "serde_json", "smallvec", "stable_deref_trait", "stacker", diff --git a/compiler/rustc_ast_lowering/src/item.rs b/compiler/rustc_ast_lowering/src/item.rs index f89e254a2f54d..7b94f6edf7039 100644 --- a/compiler/rustc_ast_lowering/src/item.rs +++ b/compiler/rustc_ast_lowering/src/item.rs @@ -138,12 +138,10 @@ impl<'a, 'hir> ItemLowerer<'a, 'hir> { // Evaluate with the lifetimes in `params` in-scope. // This is used to track which lifetimes have already been defined, // and which need to be replicated when lowering an async fn. - match parent_hir.node().expect_item().kind { - hir::ItemKind::Impl(hir::Impl { of_trait, .. }) => { - lctx.is_in_trait_impl = of_trait.is_some(); - } - _ => {} - }; + + if let hir::ItemKind::Impl(impl_) = parent_hir.node().expect_item().kind { + lctx.is_in_trait_impl = impl_.of_trait.is_some(); + } match ctxt { AssocCtxt::Trait => hir::OwnerNode::TraitItem(lctx.lower_trait_item(item)), diff --git a/compiler/rustc_data_structures/Cargo.toml b/compiler/rustc_data_structures/Cargo.toml index 2102f09c56a03..39f4bc63c88d1 100644 --- a/compiler/rustc_data_structures/Cargo.toml +++ b/compiler/rustc_data_structures/Cargo.toml @@ -21,7 +21,6 @@ rustc-hash = "1.1.0" rustc_index = { path = "../rustc_index", package = "rustc_index" } rustc_macros = { path = "../rustc_macros" } rustc_serialize = { path = "../rustc_serialize" } -serde_json = "1.0.59" smallvec = { version = "1.8.1", features = [ "const_generics", "union", diff --git a/compiler/rustc_data_structures/src/profiling.rs b/compiler/rustc_data_structures/src/profiling.rs index 1ed584eafad30..8fa1ac70a78c0 100644 --- a/compiler/rustc_data_structures/src/profiling.rs +++ b/compiler/rustc_data_structures/src/profiling.rs @@ -87,6 +87,7 @@ use crate::fx::FxHashMap; use std::borrow::Borrow; use std::collections::hash_map::Entry; use std::error::Error; +use std::fmt::Display; use std::fs; use std::intrinsics::unlikely; use std::path::Path; @@ -97,7 +98,6 @@ use std::time::{Duration, Instant}; pub use measureme::EventId; use measureme::{EventIdBuilder, Profiler, SerializableString, StringId}; use parking_lot::RwLock; -use serde_json::json; use smallvec::SmallVec; bitflags::bitflags! { @@ -763,6 +763,31 @@ impl Drop for VerboseTimingGuard<'_> { } } +struct JsonTimePassesEntry<'a> { + pass: &'a str, + time: f64, + start_rss: Option, + end_rss: Option, +} + +impl Display for JsonTimePassesEntry<'_> { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + let Self { pass: what, time, start_rss, end_rss } = self; + write!(f, r#"{{"pass":"{what}","time":{time},"rss_start":"#).unwrap(); + match start_rss { + Some(rss) => write!(f, "{rss}")?, + None => write!(f, "null")?, + } + write!(f, r#","rss_end":"#)?; + match end_rss { + Some(rss) => write!(f, "{rss}")?, + None => write!(f, "null")?, + } + write!(f, "}}")?; + Ok(()) + } +} + pub fn print_time_passes_entry( what: &str, dur: Duration, @@ -772,13 +797,10 @@ pub fn print_time_passes_entry( ) { match format { TimePassesFormat::Json => { - let json = json!({ - "pass": what, - "time": dur.as_secs_f64(), - "rss_start": start_rss, - "rss_end": end_rss, - }); - eprintln!("time: {json}"); + let entry = + JsonTimePassesEntry { pass: what, time: dur.as_secs_f64(), start_rss, end_rss }; + + eprintln!(r#"time: {entry}"#); return; } TimePassesFormat::Text => (), @@ -894,3 +916,6 @@ cfg_if! { } } } + +#[cfg(test)] +mod tests; diff --git a/compiler/rustc_data_structures/src/profiling/tests.rs b/compiler/rustc_data_structures/src/profiling/tests.rs new file mode 100644 index 0000000000000..2b09de085da06 --- /dev/null +++ b/compiler/rustc_data_structures/src/profiling/tests.rs @@ -0,0 +1,19 @@ +use super::JsonTimePassesEntry; + +#[test] +fn with_rss() { + let entry = + JsonTimePassesEntry { pass: "typeck", time: 56.1, start_rss: Some(10), end_rss: Some(20) }; + + assert_eq!(entry.to_string(), r#"{"pass":"typeck","time":56.1,"rss_start":10,"rss_end":20}"#) +} + +#[test] +fn no_rss() { + let entry = JsonTimePassesEntry { pass: "typeck", time: 56.1, start_rss: None, end_rss: None }; + + assert_eq!( + entry.to_string(), + r#"{"pass":"typeck","time":56.1,"rss_start":null,"rss_end":null}"# + ) +} diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index b274e62807988..fb0c087bfb471 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -3146,7 +3146,6 @@ impl<'hir> Item<'hir> { (ty, gen) } - /// An opaque `impl Trait` type alias, e.g., `type Foo = impl Bar;`. /// Expect an [`ItemKind::OpaqueTy`] or panic. #[track_caller] pub fn expect_opaque_ty(&self) -> &OpaqueTy<'hir> { @@ -3168,7 +3167,6 @@ impl<'hir> Item<'hir> { (data, gen) } - /// A union definition, e.g., `union Foo {x: A, y: B}`. /// Expect an [`ItemKind::Union`] or panic. #[track_caller] pub fn expect_union(&self) -> (&VariantData<'hir>, &'hir Generics<'hir>) { diff --git a/compiler/rustc_hir_analysis/src/coherence/builtin.rs b/compiler/rustc_hir_analysis/src/coherence/builtin.rs index 0f40cca9427b4..c2dc2a0f058f3 100644 --- a/compiler/rustc_hir_analysis/src/coherence/builtin.rs +++ b/compiler/rustc_hir_analysis/src/coherence/builtin.rs @@ -74,10 +74,9 @@ fn visit_implementation_of_copy(tcx: TyCtxt<'_>, impl_did: LocalDefId) { debug!("visit_implementation_of_copy: self_type={:?} (free)", self_type); - let span = match tcx.hir().expect_item(impl_did).kind { - ItemKind::Impl(hir::Impl { polarity: hir::ImplPolarity::Negative(_), .. }) => return, - ItemKind::Impl(impl_) => impl_.self_ty.span, - _ => bug!("expected Copy impl item"), + let span = match tcx.hir().expect_item(impl_did).expect_impl() { + hir::Impl { polarity: hir::ImplPolarity::Negative(_), .. } => return, + hir::Impl { self_ty, .. } => self_ty.span, }; let cause = traits::ObligationCause::misc(span, impl_did); diff --git a/compiler/rustc_infer/src/infer/error_reporting/note_and_explain.rs b/compiler/rustc_infer/src/infer/error_reporting/note_and_explain.rs index b38bbdfe7bb8b..e410172c8c8d1 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/note_and_explain.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/note_and_explain.rs @@ -462,10 +462,7 @@ fn foo(&self) -> Self::T { String::new() } if let ty::Alias(ty::Opaque, ty::AliasTy { def_id, .. }) = *proj_ty.self_ty().kind() { let opaque_local_def_id = def_id.as_local(); let opaque_hir_ty = if let Some(opaque_local_def_id) = opaque_local_def_id { - match &tcx.hir().expect_item(opaque_local_def_id).kind { - hir::ItemKind::OpaqueTy(opaque_hir_ty) => opaque_hir_ty, - _ => bug!("The HirId comes from a `ty::Opaque`"), - } + tcx.hir().expect_item(opaque_local_def_id).expect_opaque_ty() } else { return false; }; diff --git a/compiler/rustc_infer/src/infer/opaque_types.rs b/compiler/rustc_infer/src/infer/opaque_types.rs index 3a0a0494a7ed3..680465bdab690 100644 --- a/compiler/rustc_infer/src/infer/opaque_types.rs +++ b/compiler/rustc_infer/src/infer/opaque_types.rs @@ -392,12 +392,7 @@ impl<'tcx> InferCtxt<'tcx> { /// defining scope. #[instrument(skip(self), level = "trace", ret)] fn opaque_type_origin_unchecked(&self, def_id: LocalDefId) -> OpaqueTyOrigin { - match self.tcx.hir().expect_item(def_id).kind { - hir::ItemKind::OpaqueTy(hir::OpaqueTy { origin, .. }) => origin, - ref itemkind => { - bug!("weird opaque type: {:?}, {:#?}", def_id, itemkind) - } - } + self.tcx.hir().expect_item(def_id).expect_opaque_ty().origin } } diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs index 1109e308cf0bf..e7c3cf779d3d0 100644 --- a/compiler/rustc_metadata/src/rmeta/encoder.rs +++ b/compiler/rustc_metadata/src/rmeta/encoder.rs @@ -1469,8 +1469,8 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { match impl_item.kind { ty::AssocKind::Fn => { - let ast_item = self.tcx.hir().expect_impl_item(def_id.expect_local()); - let hir::ImplItemKind::Fn(ref sig, body) = ast_item.kind else { bug!() }; + let (sig, body) = + self.tcx.hir().expect_impl_item(def_id.expect_local()).expect_fn(); self.tables.asyncness.set_some(def_id.index, sig.header.asyncness); record_array!(self.tables.fn_arg_names[def_id] <- self.tcx.hir().body_param_names(body)); // Can be inside `impl const Trait`, so using sig.header.constness is not reliable diff --git a/compiler/rustc_middle/src/ty/visit.rs b/compiler/rustc_middle/src/ty/visit.rs index 24a1f04c7e388..1b07f52afca92 100644 --- a/compiler/rustc_middle/src/ty/visit.rs +++ b/compiler/rustc_middle/src/ty/visit.rs @@ -33,6 +33,14 @@ pub trait TypeVisitableExt<'tcx>: TypeVisitable> { } fn has_type_flags(&self, flags: TypeFlags) -> bool { + // N.B. Even though this uses a visitor, the visitor does not actually + // recurse through the whole `TypeVisitable` implementor type. + // + // Instead it stops on the first "level", visiting types, regions, + // consts and predicates just fetches their type flags. + // + // Thus this is a lot faster than it might seem and should be + // optimized to a simple field access. let res = self.visit_with(&mut HasTypeFlagsVisitor { flags }).break_value() == Some(FoundFlags); trace!(?self, ?flags, ?res, "has_type_flags"); diff --git a/src/bootstrap/builder.rs b/src/bootstrap/builder.rs index e959ea06f8b69..4977ce22724f1 100644 --- a/src/bootstrap/builder.rs +++ b/src/bootstrap/builder.rs @@ -2030,7 +2030,7 @@ impl<'a> Builder<'a> { } #[cfg(feature = "build-metrics")] - self.metrics.enter_step(&step); + self.metrics.enter_step(&step, self); let (out, dur) = { let start = Instant::now(); @@ -2056,7 +2056,7 @@ impl<'a> Builder<'a> { } #[cfg(feature = "build-metrics")] - self.metrics.exit_step(); + self.metrics.exit_step(self); { let mut stack = self.stack.borrow_mut(); diff --git a/src/bootstrap/metrics.rs b/src/bootstrap/metrics.rs index 82b123ec8a5e1..e19d56ccd6adc 100644 --- a/src/bootstrap/metrics.rs +++ b/src/bootstrap/metrics.rs @@ -4,7 +4,7 @@ //! As this module requires additional dependencies not present during local builds, it's cfg'd //! away whenever the `build.metrics` config option is not set to `true`. -use crate::builder::Step; +use crate::builder::{Builder, Step}; use crate::util::t; use crate::Build; use serde_derive::{Deserialize, Serialize}; @@ -33,7 +33,12 @@ impl BuildMetrics { BuildMetrics { state } } - pub(crate) fn enter_step(&self, step: &S) { + pub(crate) fn enter_step(&self, step: &S, builder: &Builder<'_>) { + // Do not record dry runs, as they'd be duplicates of the actual steps. + if builder.config.dry_run() { + return; + } + let mut state = self.state.borrow_mut(); // Consider all the stats gathered so far as the parent's. @@ -56,7 +61,12 @@ impl BuildMetrics { }); } - pub(crate) fn exit_step(&self) { + pub(crate) fn exit_step(&self, builder: &Builder<'_>) { + // Do not record dry runs, as they'd be duplicates of the actual steps. + if builder.config.dry_run() { + return; + } + let mut state = self.state.borrow_mut(); self.collect_stats(&mut *state); @@ -74,7 +84,12 @@ impl BuildMetrics { } } - pub(crate) fn record_test(&self, name: &str, outcome: TestOutcome) { + pub(crate) fn record_test(&self, name: &str, outcome: TestOutcome, builder: &Builder<'_>) { + // Do not record dry runs, as they'd be duplicates of the actual steps. + if builder.config.dry_run() { + return; + } + let mut state = self.state.borrow_mut(); state .running_steps diff --git a/src/bootstrap/render_tests.rs b/src/bootstrap/render_tests.rs index 19019ad2c089d..a56db9cccfe5b 100644 --- a/src/bootstrap/render_tests.rs +++ b/src/bootstrap/render_tests.rs @@ -124,6 +124,7 @@ impl<'a> Renderer<'a> { ignore_reason: reason.map(|s| s.to_string()), }, }, + self.builder, ); if self.builder.config.verbose_tests { diff --git a/src/bootstrap/test.rs b/src/bootstrap/test.rs index aedf1ecab13c4..3814dc63ed4dc 100644 --- a/src/bootstrap/test.rs +++ b/src/bootstrap/test.rs @@ -1804,6 +1804,10 @@ note: if you're sure you want to do this, please open an issue as to why. In the cmd.arg("--channel").arg(&builder.config.channel); + if !builder.config.omit_git_hash { + cmd.arg("--git-hash"); + } + if let Some(commit) = builder.config.download_rustc_commit() { cmd.env("FAKE_DOWNLOAD_RUSTC_PREFIX", format!("/rustc/{commit}")); } diff --git a/src/bootstrap/tool.rs b/src/bootstrap/tool.rs index c732fd7e8335e..79fab00efe703 100644 --- a/src/bootstrap/tool.rs +++ b/src/bootstrap/tool.rs @@ -194,6 +194,12 @@ pub fn prepare_tool_cargo( cargo.env("CFG_VERSION", builder.rust_version()); cargo.env("CFG_RELEASE_NUM", &builder.version); cargo.env("DOC_RUST_LANG_ORG_CHANNEL", builder.doc_rust_lang_org_channel()); + if let Some(ref ver_date) = builder.rust_info().commit_date() { + cargo.env("CFG_VER_DATE", ver_date); + } + if let Some(ref ver_hash) = builder.rust_info().sha() { + cargo.env("CFG_VER_HASH", ver_hash); + } let info = GitInfo::new(builder.config.omit_git_hash, &dir); if let Some(sha) = info.sha() { diff --git a/src/doc/rustdoc/src/write-documentation/linking-to-items-by-name.md b/src/doc/rustdoc/src/write-documentation/linking-to-items-by-name.md index eb2285ef90646..72157b5cd9bce 100644 --- a/src/doc/rustdoc/src/write-documentation/linking-to-items-by-name.md +++ b/src/doc/rustdoc/src/write-documentation/linking-to-items-by-name.md @@ -88,13 +88,16 @@ fn Foo() {} ``` These prefixes will be stripped when displayed in the documentation, so `[struct@Foo]` will be -rendered as `Foo`. +rendered as `Foo`. The following prefixes are available: `struct`, `enum`, `trait`, `union`, +`mod`, `module`, `const`, `constant`, `fn`, `function`, `method`, `derive`, `type`, `value`, +`macro`, `prim` or `primitive`. You can also disambiguate for functions by adding `()` after the function name, -or for macros by adding `!` after the macro name: +or for macros by adding `!` after the macro name. The macro `!` can be followed by `()`, `{}`, +or `[]`. Example: ```rust -/// This is different from [`foo!`] +/// This is different from [`foo!()`]. fn foo() {} /// This is different from [`foo()`] diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs index a835bd2de3b14..33e80df9ed77b 100644 --- a/src/librustdoc/passes/collect_intra_doc_links.rs +++ b/src/librustdoc/passes/collect_intra_doc_links.rs @@ -1419,6 +1419,7 @@ impl Disambiguator { if let Some(idx) = link.find('@') { let (prefix, rest) = link.split_at(idx); let d = match prefix { + // If you update this list, please also update the relevant rustdoc book section! "struct" => Kind(DefKind::Struct), "enum" => Kind(DefKind::Enum), "trait" => Kind(DefKind::Trait), @@ -1437,6 +1438,7 @@ impl Disambiguator { Ok(Some((d, &rest[1..], &rest[1..]))) } else { let suffixes = [ + // If you update this list, please also update the relevant rustdoc book section! ("!()", DefKind::Macro(MacroKind::Bang)), ("!{}", DefKind::Macro(MacroKind::Bang)), ("![]", DefKind::Macro(MacroKind::Bang)), diff --git a/src/librustdoc/visit_ast.rs b/src/librustdoc/visit_ast.rs index f54b70b417d77..a6089680fae9d 100644 --- a/src/librustdoc/visit_ast.rs +++ b/src/librustdoc/visit_ast.rs @@ -10,6 +10,7 @@ use rustc_hir::{Node, CRATE_HIR_ID}; use rustc_middle::hir::nested_filter; use rustc_middle::ty::TyCtxt; use rustc_span::def_id::{CRATE_DEF_ID, LOCAL_CRATE}; +use rustc_span::hygiene::MacroKind; use rustc_span::symbol::{kw, sym, Symbol}; use rustc_span::Span; @@ -87,6 +88,7 @@ pub(crate) struct RustdocVisitor<'a, 'tcx> { inside_public_path: bool, exact_paths: DefIdMap>, modules: Vec>, + is_importable_from_parent: bool, } impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { @@ -107,6 +109,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { inside_public_path: true, exact_paths: Default::default(), modules: vec![om], + is_importable_from_parent: true, } } @@ -319,11 +322,23 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { renamed: Option, parent_id: Option, ) { - self.modules - .last_mut() - .unwrap() - .items - .insert((item.owner_id.def_id, renamed), (item, renamed, parent_id)); + if self.is_importable_from_parent + // If we're inside an item, only impl blocks and `macro_rules!` with the `macro_export` + // attribute can still be visible. + || match item.kind { + hir::ItemKind::Impl(..) => true, + hir::ItemKind::Macro(_, MacroKind::Bang) => { + self.cx.tcx.has_attr(item.owner_id.def_id, sym::macro_export) + } + _ => false, + } + { + self.modules + .last_mut() + .unwrap() + .items + .insert((item.owner_id.def_id, renamed), (item, renamed, parent_id)); + } } fn visit_item_inner( @@ -331,7 +346,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { item: &'tcx hir::Item<'_>, renamed: Option, import_id: Option, - ) -> bool { + ) { debug!("visiting item {:?}", item); let name = renamed.unwrap_or(item.ident.name); let tcx = self.cx.tcx; @@ -448,7 +463,6 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { } } } - true } fn visit_foreign_item_inner( @@ -485,9 +499,23 @@ impl<'a, 'tcx> Visitor<'tcx> for RustdocVisitor<'a, 'tcx> { } fn visit_item(&mut self, i: &'tcx hir::Item<'tcx>) { - if self.visit_item_inner(i, None, None) { - walk_item(self, i); - } + self.visit_item_inner(i, None, None); + let new_value = if self.is_importable_from_parent { + matches!( + i.kind, + hir::ItemKind::Mod(..) + | hir::ItemKind::ForeignMod { .. } + | hir::ItemKind::Impl(..) + | hir::ItemKind::Trait(..) + ) + } else { + // Whatever the context, if it's an impl block, the items inside it can be used so they + // should be visible. + matches!(i.kind, hir::ItemKind::Impl(..)) + }; + let prev = mem::replace(&mut self.is_importable_from_parent, new_value); + walk_item(self, i); + self.is_importable_from_parent = prev; } fn visit_mod(&mut self, _: &hir::Mod<'tcx>, _: Span, _: hir::HirId) { diff --git a/src/tools/compiletest/src/common.rs b/src/tools/compiletest/src/common.rs index d2f494942cf9b..3f36cc5bbcc91 100644 --- a/src/tools/compiletest/src/common.rs +++ b/src/tools/compiletest/src/common.rs @@ -303,6 +303,9 @@ pub struct Config { /// The current Rust channel pub channel: String, + /// Whether adding git commit information such as the commit hash has been enabled for building + pub git_hash: bool, + /// The default Rust edition pub edition: Option, diff --git a/src/tools/compiletest/src/header/needs.rs b/src/tools/compiletest/src/header/needs.rs index 35d6179abaa6b..81179480ed810 100644 --- a/src/tools/compiletest/src/header/needs.rs +++ b/src/tools/compiletest/src/header/needs.rs @@ -115,6 +115,11 @@ pub(super) fn handle_needs( condition: cache.x86_64_dlltool, ignore_reason: "ignored when dlltool for x86_64 is not present", }, + Need { + name: "needs-git-hash", + condition: config.git_hash, + ignore_reason: "ignored when git hashes have been omitted for building", + }, ]; let (name, comment) = match ln.split_once([':', ' ']) { diff --git a/src/tools/compiletest/src/header/tests.rs b/src/tools/compiletest/src/header/tests.rs index 9af7bd5e20145..362fba11697be 100644 --- a/src/tools/compiletest/src/header/tests.rs +++ b/src/tools/compiletest/src/header/tests.rs @@ -251,6 +251,16 @@ fn debugger() { assert!(check_ignore(&config, "// ignore-lldb")); } +#[test] +fn git_hash() { + let mut config = config(); + config.git_hash = false; + assert!(check_ignore(&config, "// needs-git-hash")); + + config.git_hash = true; + assert!(!check_ignore(&config, "// needs-git-hash")); +} + #[test] fn sanitizers() { let mut config = config(); diff --git a/src/tools/compiletest/src/main.rs b/src/tools/compiletest/src/main.rs index 4a2b9de8aee6b..c4bef998f3171 100644 --- a/src/tools/compiletest/src/main.rs +++ b/src/tools/compiletest/src/main.rs @@ -159,6 +159,7 @@ pub fn parse_config(args: Vec) -> Config { .optflag("", "nocapture", "") .optflag("h", "help", "show this message") .reqopt("", "channel", "current Rust channel", "CHANNEL") + .optflag("", "git-hash", "run tests which rely on commit version being compiled into the binaries") .optopt("", "edition", "default Rust edition", "EDITION"); let (argv0, args_) = args.split_first().unwrap(); @@ -302,6 +303,7 @@ pub fn parse_config(args: Vec) -> Config { rustfix_coverage: matches.opt_present("rustfix-coverage"), has_tidy, channel: matches.opt_str("channel").unwrap(), + git_hash: matches.opt_present("git-hash"), edition: matches.opt_str("edition"), cc: matches.opt_str("cc").unwrap(), diff --git a/tests/run-make/issue-107094/Makefile b/tests/run-make/issue-107094/Makefile new file mode 100644 index 0000000000000..d614e3e1055c0 --- /dev/null +++ b/tests/run-make/issue-107094/Makefile @@ -0,0 +1,7 @@ +# needs-git-hash + +include ../tools.mk + +all: + $(BARE_RUSTC) --version --verbose | $(CGREP) -i -e "commit-hash: [0-9a-f]{40}" "commit-date: [0-9]{4}-[0-9]{2}-[0-9]{2}" + $(BARE_RUSTDOC) --version --verbose | $(CGREP) -i -e "commit-hash: [0-9a-f]{40}" "commit-date: [0-9]{4}-[0-9]{2}-[0-9]{2}" diff --git a/tests/rustdoc-ui/infinite-recursive-type-impl-trait.rs b/tests/rustdoc-ui/infinite-recursive-type-impl-trait.rs index ac51725749867..096130d776828 100644 --- a/tests/rustdoc-ui/infinite-recursive-type-impl-trait.rs +++ b/tests/rustdoc-ui/infinite-recursive-type-impl-trait.rs @@ -1,6 +1,9 @@ +// check-pass + fn f() -> impl Sized { - enum E { //~ ERROR + enum E { V(E), } + unimplemented!() } diff --git a/tests/rustdoc-ui/infinite-recursive-type-impl-trait.stderr b/tests/rustdoc-ui/infinite-recursive-type-impl-trait.stderr deleted file mode 100644 index a61577bd14afc..0000000000000 --- a/tests/rustdoc-ui/infinite-recursive-type-impl-trait.stderr +++ /dev/null @@ -1,16 +0,0 @@ -error[E0072]: recursive type `f::E` has infinite size - --> $DIR/infinite-recursive-type-impl-trait.rs:2:5 - | -LL | enum E { - | ^^^^^^ -LL | V(E), - | - recursive without indirection - | -help: insert some indirection (e.g., a `Box`, `Rc`, or `&`) to break the cycle - | -LL | V(Box), - | ++++ + - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0072`. diff --git a/tests/rustdoc/issue-110422-inner-private.rs b/tests/rustdoc/issue-110422-inner-private.rs new file mode 100644 index 0000000000000..ee8ed5cc6e17f --- /dev/null +++ b/tests/rustdoc/issue-110422-inner-private.rs @@ -0,0 +1,64 @@ +// Regression test for . +// This test ensures that inner items (except for implementations and macros) +// don't appear in documentation. + +// compile-flags: --document-private-items + +#![crate_name = "foo"] + +// @has 'foo/index.html' +// Checking there is no "trait" entry. +// @count - '//*[@id="main-content"]/*[@class="small-section-header"]' 4 +// @has - '//*[@id="main-content"]/*[@class="small-section-header"]' 'Structs' +// @has - '//*[@id="main-content"]/*[@class="small-section-header"]' 'Constants' +// @has - '//*[@id="main-content"]/*[@class="small-section-header"]' 'Functions' +// @has - '//*[@id="main-content"]/*[@class="small-section-header"]' 'Macros' + +// @has - '//a[@href="fn.foo.html"]' 'foo' +fn foo() { + fn bar() {} + + // @has - '//a[@class="macro"]' 'visible_macro' + // @!has - '//a[@class="macro"]' 'non_visible_macro' + // @has 'foo/macro.visible_macro.html' + // @!has 'foo/macro.non_visible_macro.html' + #[macro_export] + macro_rules! visible_macro { + () => {} + } + + macro_rules! non_visible_macro { + () => {} + } +} + +// @has 'foo/index.html' +// @has - '//a[@href="struct.Bar.html"]' 'Bar' +struct Bar; + +const BAR: i32 = { + // @!has - '//a[@href="fn.yo.html"]' 'yo' + // @!has 'foo/fn.yo.html' + fn yo() {} + + // @!has 'foo/index.html' '//a[@href="trait.Foo.html"]' 'Foo' + // @!has 'foo/trait.Foo.html' + trait Foo { + fn babar() {} + } + impl Foo for Bar {} + + // @has 'foo/struct.Bar.html' + // @has - '//*[@id="method.foo"]/*[@class="code-header"]' 'pub(crate) fn foo()' + // @count - '//*[@id="main-content"]/*[@class="small-section-header"]' 3 + // We now check that the `Foo` trait is not documented nor visible on `Bar` page. + // @has - '//*[@id="main-content"]/*[@class="small-section-header"]' 'Implementations' + // @has - '//*[@id="main-content"]/*[@class="small-section-header"]' 'Auto Trait Implementations' + // @has - '//*[@id="main-content"]/*[@class="small-section-header"]' 'Blanket Implementations' + // @!has - '//*[@href="trait.Foo.html#method.babar"]/*[@class="code-header"]' 'fn babar()' + impl Bar { + fn foo() {} + } + + 1 +};