From 7fb34c99e32c01082110dc7281049e26622f924d Mon Sep 17 00:00:00 2001 From: Dante Broggi <34220985+Dante-Broggi@users.noreply.github.com> Date: Mon, 13 Mar 2023 15:52:32 -0400 Subject: [PATCH 1/9] add `#[doc(alias="flatmap")]` to `Option::and_then` I keep forgetting that rust calls this `and_then` and trying to search for `flatmap`. `and_then`'s docs even mention "Some languages call this operation flatmap", but it doesn't show up as a result in the search at `https://doc.rust-lang.org/std/?search=flatmap` --- library/core/src/option.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/library/core/src/option.rs b/library/core/src/option.rs index 0f2475a8bdea6..b5ea891627532 100644 --- a/library/core/src/option.rs +++ b/library/core/src/option.rs @@ -1464,6 +1464,7 @@ impl Option { /// let item_2_0 = arr_2d.get(2).and_then(|row| row.get(0)); /// assert_eq!(item_2_0, None); /// ``` + #[doc(alias = "flatmap")] #[inline] #[stable(feature = "rust1", since = "1.0.0")] #[rustc_const_unstable(feature = "const_option_ext", issue = "91930")] From b42ff20c560fb53982b3f77d3fed5c459a01b545 Mon Sep 17 00:00:00 2001 From: jyn Date: Thu, 25 May 2023 23:56:15 -0500 Subject: [PATCH 2/9] Revert "Enable incremental independent of stage" This reverts commit 827f656ebb1230f31af6d968c4bfe69a79914ffc. Incremental is not sound to use across stages. Arbitrary changes to the compiler can invalidate the incremental cache - even changes to normal queries, not incremental itself! - and we do not currently enable `incremental-verify-ich` in bootstrap. Since 2018, we highly recommend and nudge users towards stage 1 builds instead of stage 2, and using `keep-stage` for anything other than libstd is very rare. I don't think the risk of unsoundness is worth the very minor speedup when building libstd. Disable incremental to avoid spurious panics and miscompilations when building with the stage 1 and 2 sysroot. --- src/bootstrap/builder.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/bootstrap/builder.rs b/src/bootstrap/builder.rs index cf7c6596c0238..685824278ff25 100644 --- a/src/bootstrap/builder.rs +++ b/src/bootstrap/builder.rs @@ -1783,7 +1783,10 @@ impl<'a> Builder<'a> { cargo.env("RUSTC_TLS_MODEL_INITIAL_EXEC", "1"); } - if self.config.incremental { + // Ignore incremental modes except for stage0, since we're + // not guaranteeing correctness across builds if the compiler + // is changing under your feet. + if self.config.incremental && compiler.stage == 0 { cargo.env("CARGO_INCREMENTAL", "1"); } else { // Don't rely on any default setting for incr. comp. in Cargo From 2f0a26607f324ad2d630c39e718e55725f8b108d Mon Sep 17 00:00:00 2001 From: jyn Date: Sat, 20 May 2023 10:40:30 -0500 Subject: [PATCH 3/9] Make `x test --dry-run` less verbose Previously, this would print a message for each doctest, which was quite verbose: ``` doc tests for: /home/jyn/src/rust/src/doc/rustc/src/exploit-mitigations.md doc tests for: /home/jyn/src/rust/src/doc/rustc/src/instrument-coverage.md doc tests for: /home/jyn/src/rust/src/doc/rustc/src/json.md doc tests for: /home/jyn/src/rust/src/doc/rustc/src/linker-plugin-lto.md doc tests for: /home/jyn/src/rust/src/doc/rustc/src/lints/groups.md doc tests for: /home/jyn/src/rust/src/doc/rustc/src/lints/index.md doc tests for: /home/jyn/src/rust/src/doc/rustc/src/lints/levels.md doc tests for: /home/jyn/src/rust/src/doc/rustc/src/platform-support/aarch64-apple-ios-sim.md doc tests for: /home/jyn/src/rust/src/doc/rustc/src/platform-support/aarch64-nintendo-switch-freestanding.md doc tests for: /home/jyn/src/rust/src/doc/rustc/src/platform-support/apple-watchos.md doc tests for: /home/jyn/src/rust/src/doc/rustc/src/platform-support/armeb-unknown-linux-gnueabi.md doc tests for: /home/jyn/src/rust/src/doc/rustc/src/platform-support/armv4t-none-eabi.md doc tests for: /home/jyn/src/rust/src/doc/rustc/src/platform-support/armv5te-none-eabi.md doc tests for: /home/jyn/src/rust/src/doc/rustc/src/platform-support/armv6k-nintendo-3ds.md doc tests for: /home/jyn/src/rust/src/doc/rustc/src/platform-support/armv7-sony-vita-newlibeabihf.md doc tests for: /home/jyn/src/rust/src/doc/rustc/src/platform-support/armv7-unknown-linux-uclibceabi.md doc tests for: /home/jyn/src/rust/src/doc/rustc/src/platform-support/armv7-unknown-linux-uclibceabihf.md doc tests for: /home/jyn/src/rust/src/doc/rustc/src/platform-support/esp-idf.md doc tests for: /home/jyn/src/rust/src/doc/rustc/src/platform-support/fuchsia.md doc tests for: /home/jyn/src/rust/src/doc/rustc/src/platform-support/kmc-solid.md doc tests for: /home/jyn/src/rust/src/doc/rustc/src/platform-support/loongarch-linux.md doc tests for: /home/jyn/src/rust/src/doc/rustc/src/platform-support/m68k-unknown-linux-gnu.md doc tests for: /home/jyn/src/rust/src/doc/rustc/src/platform-support/mipsel-sony-psx.md doc tests for: /home/jyn/src/rust/src/doc/rustc/src/platform-support/nto-qnx.md doc tests for: /home/jyn/src/rust/src/doc/rustc/src/platform-support/openbsd.md doc tests for: /home/jyn/src/rust/src/doc/rustc/src/platform-support/openharmony.md doc tests for: /home/jyn/src/rust/src/doc/rustc/src/platform-support/riscv32imac-unknown-xous-elf.md doc tests for: /home/jyn/src/rust/src/doc/rustc/src/platform-support/unknown-uefi.md doc tests for: /home/jyn/src/rust/src/doc/rustc/src/platform-support/wasm64-unknown-unknown.md doc tests for: /home/jyn/src/rust/src/doc/rustc/src/platform-support/x86_64-fortanix-unknown-sgx.md doc tests for: /home/jyn/src/rust/src/doc/rustc/src/platform-support/x86_64-unknown-none.md doc tests for: /home/jyn/src/rust/src/doc/rustc/src/profile-guided-optimization.md doc tests for: /home/jyn/src/rust/src/doc/rustc/src/target-tier-policy.md doc tests for: /home/jyn/src/rust/src/doc/rustc/src/targets/custom.md doc tests for: /home/jyn/src/rust/src/doc/rustc/src/targets/index.md doc tests for: /home/jyn/src/rust/src/doc/rustc/src/tests/index.md doc tests for: /home/jyn/src/rust/src/doc/rustc/src/what-is-rustc.md ``` --- src/bootstrap/test.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/bootstrap/test.rs b/src/bootstrap/test.rs index 960abb31b2016..9f365474a70c8 100644 --- a/src/bootstrap/test.rs +++ b/src/bootstrap/test.rs @@ -1776,6 +1776,8 @@ impl Step for BookTest { /// /// This uses the `rustdoc` that sits next to `compiler`. fn run(self, builder: &Builder<'_>) { + let host = self.compiler.host; + let _guard = builder.msg(Kind::Test, self.compiler.stage, &format!("book {}", self.name), host, host); // External docs are different from local because: // - Some books need pre-processing by mdbook before being tested. // - They need to save their state to toolstate. @@ -1967,7 +1969,7 @@ fn markdown_test(builder: &Builder<'_>, compiler: Compiler, markdown: &Path) -> } } - builder.info(&format!("doc tests for: {}", markdown.display())); + builder.verbose(&format!("doc tests for: {}", markdown.display())); let mut cmd = builder.rustdoc_cmd(compiler); builder.add_rust_test_threads(&mut cmd); // allow for unstable options such as new editions From a80d69a6ac996616937fb41357f10db036f85f73 Mon Sep 17 00:00:00 2001 From: jyn Date: Sat, 22 Apr 2023 09:53:22 -0500 Subject: [PATCH 4/9] Fix `x test --stage 2 core` when download-rustc is enabled This works by building std from source unconditionally instead of downloading it, for library tests only. This was somewhat complicated because of the following requirements: 1. Unconditionally downloading libstd breaks `x test std`, because `coretests` requires the std loaded from the sysroot to match the std that's currently being tested. 2. Unconditionally rebuilding libstd breaks `x test ui-fulldeps librustdoc`, because anything loading `rustc_private` needs to use the same libstd that rustc was built with. Break the knot by introducing a new `stage2-test-sysroot`, used only for testing `std` itself. This holds a freshly compiled std, while `stage2` and `ci-rustc-sysroot` still hold the downloaded std. This also extends the existing `cp_filtered` in Sysroot to apply to the `rust-std` component, not just the `rustc-dev` component. --- src/bootstrap/builder.rs | 2 +- src/bootstrap/compile.rs | 120 +++++++++++++++++++++++++++++--------- src/bootstrap/download.rs | 33 ++++++++--- src/bootstrap/test.rs | 34 ++++++++++- 4 files changed, 149 insertions(+), 40 deletions(-) diff --git a/src/bootstrap/builder.rs b/src/bootstrap/builder.rs index 30359e47e73be..b69f99c5e7806 100644 --- a/src/bootstrap/builder.rs +++ b/src/bootstrap/builder.rs @@ -992,7 +992,7 @@ impl<'a> Builder<'a> { } pub fn sysroot(&self, compiler: Compiler) -> Interned { - self.ensure(compile::Sysroot { compiler }) + self.ensure(compile::Sysroot::new(compiler)) } /// Returns the libdir where the standard library and other artifacts are diff --git a/src/bootstrap/compile.rs b/src/bootstrap/compile.rs index a7ebd018a8791..7c09d2043f116 100644 --- a/src/bootstrap/compile.rs +++ b/src/bootstrap/compile.rs @@ -40,11 +40,18 @@ pub struct Std { /// /// This shouldn't be used from other steps; see the comment on [`Rustc`]. crates: Interned>, + /// When using download-rustc, we need to use a new build of `std` for running unit tests of Std itself, + /// but we need to use the downloaded copy of std for linking to rustdoc. Allow this to be overriden by `builder.ensure` from other steps. + force_recompile: bool, } impl Std { pub fn new(compiler: Compiler, target: TargetSelection) -> Self { - Self { target, compiler, crates: Default::default() } + Self { target, compiler, crates: Default::default(), force_recompile: false } + } + + pub fn force_recompile(compiler: Compiler, target: TargetSelection) -> Self { + Self { target, compiler, crates: Default::default(), force_recompile: true } } } @@ -77,6 +84,7 @@ impl Step for Std { compiler: run.builder.compiler(run.builder.top_stage, run.build_triple()), target: run.target, crates: make_run_crates(&run, "library"), + force_recompile: false, }); } @@ -89,11 +97,20 @@ impl Step for Std { let target = self.target; let compiler = self.compiler; - // When using `download-rustc`, we already have artifacts for the host available - // (they were copied in `impl Step for Sysroot`). Don't recompile them. - // NOTE: the ABI of the beta compiler is different from the ABI of the downloaded compiler, - // so its artifacts can't be reused. - if builder.download_rustc() && compiler.stage != 0 && target == builder.build.build { + // When using `download-rustc`, we already have artifacts for the host available. Don't + // recompile them. + if builder.download_rustc() && target == builder.build.build + // NOTE: the beta compiler may generate different artifacts than the downloaded compiler, so + // its artifacts can't be reused. + && compiler.stage != 0 + // This check is specific to testing std itself; see `test::Std` for more details. + && !self.force_recompile + { + cp_rustc_component_to_ci_sysroot( + builder, + compiler, + builder.config.ci_rust_std_contents(), + ); return; } @@ -428,6 +445,8 @@ struct StdLink { pub target: TargetSelection, /// Not actually used; only present to make sure the cache invalidation is correct. crates: Interned>, + /// See [`Std::force_recompile`]. + force_recompile: bool, } impl StdLink { @@ -437,6 +456,7 @@ impl StdLink { target_compiler: std.compiler, target: std.target, crates: std.crates, + force_recompile: std.force_recompile, } } } @@ -460,8 +480,24 @@ impl Step for StdLink { let compiler = self.compiler; let target_compiler = self.target_compiler; let target = self.target; - let libdir = builder.sysroot_libdir(target_compiler, target); - let hostdir = builder.sysroot_libdir(target_compiler, compiler.host); + + // NOTE: intentionally does *not* check `target == builder.build` to avoid having to add the same check in `test::Crate`. + let (libdir, hostdir) = if self.force_recompile && builder.download_rustc() { + // NOTE: copies part of `sysroot_libdir` to avoid having to add a new `force_recompile` argument there too + let lib = builder.sysroot_libdir_relative(self.compiler); + let sysroot = builder.ensure(crate::compile::Sysroot { + compiler: self.compiler, + force_recompile: self.force_recompile, + }); + let libdir = sysroot.join(lib).join("rustlib").join(target.triple).join("lib"); + let hostdir = sysroot.join(lib).join("rustlib").join(compiler.host.triple).join("lib"); + (INTERNER.intern_path(libdir), INTERNER.intern_path(hostdir)) + } else { + let libdir = builder.sysroot_libdir(target_compiler, target); + let hostdir = builder.sysroot_libdir(target_compiler, compiler.host); + (libdir, hostdir) + }; + add_to_sysroot(builder, &libdir, &hostdir, &libstd_stamp(builder, compiler, target)); } } @@ -594,6 +630,25 @@ impl Step for StartupObjects { } } +fn cp_rustc_component_to_ci_sysroot( + builder: &Builder<'_>, + compiler: Compiler, + contents: Vec, +) { + let sysroot = builder.ensure(Sysroot { compiler, force_recompile: false }); + + let ci_rustc_dir = builder.out.join(&*builder.build.build.triple).join("ci-rustc"); + for file in contents { + let src = ci_rustc_dir.join(&file); + let dst = sysroot.join(file); + if src.is_dir() { + t!(fs::create_dir_all(dst)); + } else { + builder.copy(&src, &dst); + } + } +} + #[derive(Debug, PartialOrd, Ord, Copy, Clone, PartialEq, Eq, Hash)] pub struct Rustc { pub target: TargetSelection, @@ -653,18 +708,11 @@ impl Step for Rustc { if builder.download_rustc() && compiler.stage != 0 { // Copy the existing artifacts instead of rebuilding them. // NOTE: this path is only taken for tools linking to rustc-dev (including ui-fulldeps tests). - let sysroot = builder.ensure(Sysroot { compiler }); - - let ci_rustc_dir = builder.out.join(&*builder.build.build.triple).join("ci-rustc"); - for file in builder.config.rustc_dev_contents() { - let src = ci_rustc_dir.join(&file); - let dst = sysroot.join(file); - if src.is_dir() { - t!(fs::create_dir_all(dst)); - } else { - builder.copy(&src, &dst); - } - } + cp_rustc_component_to_ci_sysroot( + builder, + compiler, + builder.config.ci_rustc_dev_contents(), + ); return; } @@ -1225,6 +1273,14 @@ pub fn compiler_file( #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] pub struct Sysroot { pub compiler: Compiler, + /// See [`Std::force_recompile`]. + force_recompile: bool, +} + +impl Sysroot { + pub(crate) fn new(compiler: Compiler) -> Self { + Sysroot { compiler, force_recompile: false } + } } impl Step for Sysroot { @@ -1247,6 +1303,8 @@ impl Step for Sysroot { let sysroot_dir = |stage| { if stage == 0 { host_dir.join("stage0-sysroot") + } else if self.force_recompile && stage == compiler.stage { + host_dir.join(format!("stage{stage}-test-sysroot")) } else if builder.download_rustc() && compiler.stage != builder.top_stage { host_dir.join("ci-rustc-sysroot") } else { @@ -1286,14 +1344,19 @@ impl Step for Sysroot { // 2. The sysroot is deleted and recreated between each invocation, so running `x test // ui-fulldeps && x test ui` can't cause failures. let mut filtered_files = Vec::new(); - // Don't trim directories or files that aren't loaded per-target; they can't cause conflicts. - let suffix = format!("lib/rustlib/{}/lib", compiler.host); - for path in builder.config.rustc_dev_contents() { - let path = Path::new(&path); - if path.parent().map_or(false, |parent| parent.ends_with(&suffix)) { - filtered_files.push(path.file_name().unwrap().to_owned()); + let mut add_filtered_files = |suffix, contents| { + for path in contents { + let path = Path::new(&path); + if path.parent().map_or(false, |parent| parent.ends_with(&suffix)) { + filtered_files.push(path.file_name().unwrap().to_owned()); + } } - } + }; + let suffix = format!("lib/rustlib/{}/lib", compiler.host); + add_filtered_files(suffix.as_str(), builder.config.ci_rustc_dev_contents()); + // NOTE: we can't copy std eagerly because `stage2-test-sysroot` needs to have only the + // newly compiled std, not the downloaded std. + add_filtered_files("lib", builder.config.ci_rust_std_contents()); let filtered_extensions = [OsStr::new("rmeta"), OsStr::new("rlib"), OsStr::new("so")]; let ci_rustc_dir = builder.ci_rustc_dir(builder.config.build); @@ -1411,7 +1474,8 @@ impl Step for Assemble { // If we're downloading a compiler from CI, we can use the same compiler for all stages other than 0. if builder.download_rustc() { - let sysroot = builder.ensure(Sysroot { compiler: target_compiler }); + let sysroot = + builder.ensure(Sysroot { compiler: target_compiler, force_recompile: false }); // Ensure that `libLLVM.so` ends up in the newly created target directory, // so that tools using `rustc_private` can use it. dist::maybe_install_llvm_target(builder, target_compiler.host, &sysroot); diff --git a/src/bootstrap/download.rs b/src/bootstrap/download.rs index c7969d2a2c7be..c18e7ed5a56c9 100644 --- a/src/bootstrap/download.rs +++ b/src/bootstrap/download.rs @@ -270,11 +270,8 @@ impl Config { // `compile::Sysroot` needs to know the contents of the `rustc-dev` tarball to avoid adding // it to the sysroot unless it was explicitly requested. But parsing the 100 MB tarball is slow. // Cache the entries when we extract it so we only have to read it once. - let mut recorded_entries = if dst.ends_with("ci-rustc") && pattern == "rustc-dev" { - Some(BufWriter::new(t!(File::create(dst.join(".rustc-dev-contents"))))) - } else { - None - }; + let mut recorded_entries = + if dst.ends_with("ci-rustc") { recorded_entries(dst, pattern) } else { None }; for member in t!(tar.entries()) { let mut member = t!(member); @@ -331,6 +328,17 @@ impl Config { } } +fn recorded_entries(dst: &Path, pattern: &str) -> Option> { + let name = if pattern == "rustc-dev" { + ".rustc-dev-contents" + } else if pattern.starts_with("rust-std") { + ".rust-std-contents" + } else { + return None; + }; + Some(BufWriter::new(t!(File::create(dst.join(name))))) +} + enum DownloadSource { CI, Dist, @@ -381,11 +389,20 @@ impl Config { Some(rustfmt_path) } - pub(crate) fn rustc_dev_contents(&self) -> Vec { + pub(crate) fn ci_rust_std_contents(&self) -> Vec { + self.ci_component_contents(".rust-std-contents") + } + + pub(crate) fn ci_rustc_dev_contents(&self) -> Vec { + self.ci_component_contents(".rustc-dev-contents") + } + + fn ci_component_contents(&self, stamp_file: &str) -> Vec { assert!(self.download_rustc()); let ci_rustc_dir = self.out.join(&*self.build.triple).join("ci-rustc"); - let rustc_dev_contents_file = t!(File::open(ci_rustc_dir.join(".rustc-dev-contents"))); - t!(BufReader::new(rustc_dev_contents_file).lines().collect()) + let stamp_file = ci_rustc_dir.join(stamp_file); + let contents_file = t!(File::open(&stamp_file), stamp_file.display().to_string()); + t!(BufReader::new(contents_file).lines().collect()) } pub(crate) fn download_ci_rustc(&self, commit: &str) { diff --git a/src/bootstrap/test.rs b/src/bootstrap/test.rs index 9f365474a70c8..ed524a2c4b1b4 100644 --- a/src/bootstrap/test.rs +++ b/src/bootstrap/test.rs @@ -1777,7 +1777,13 @@ impl Step for BookTest { /// This uses the `rustdoc` that sits next to `compiler`. fn run(self, builder: &Builder<'_>) { let host = self.compiler.host; - let _guard = builder.msg(Kind::Test, self.compiler.stage, &format!("book {}", self.name), host, host); + let _guard = builder.msg( + Kind::Test, + self.compiler.stage, + &format!("book {}", self.name), + host, + host, + ); // External docs are different from local because: // - Some books need pre-processing by mdbook before being tested. // - They need to save their state to toolstate. @@ -2202,7 +2208,8 @@ impl Step for Crate { let target = self.target; let mode = self.mode; - builder.ensure(compile::Std::new(compiler, target)); + // See [field@compile::Std::force_recompile]. + builder.ensure(compile::Std::force_recompile(compiler, target)); builder.ensure(RemoteCopyLibs { compiler, target }); // If we're not doing a full bootstrap but we're testing a stage2 @@ -2216,6 +2223,16 @@ impl Step for Crate { match mode { Mode::Std => { compile::std_cargo(builder, target, compiler.stage, &mut cargo); + // `std_cargo` actually does the wrong thing: it passes `--sysroot build/host/stage2`, + // but we want to use the force-recompile std we just built in `build/host/stage2-test-sysroot`. + // Override it. + if builder.download_rustc() { + let sysroot = builder + .out + .join(compiler.host.triple) + .join(format!("stage{}-test-sysroot", compiler.stage)); + cargo.env("RUSTC_SYSROOT", sysroot); + } } Mode::Rustc => { compile::rustc_cargo(builder, &mut cargo, target, compiler.stage); @@ -2267,6 +2284,11 @@ impl Step for CrateRustdoc { // isn't really necessary. builder.compiler_for(builder.top_stage, target, target) }; + // NOTE: normally `ensure(Rustc)` automatically runs `ensure(Std)` for us. However, when + // using `download-rustc`, the rustc_private artifacts may be in a *different sysroot* from + // the target rustdoc (`ci-rustc-sysroot` vs `stage2`). In that case, we need to ensure this + // explicitly to make sure it ends up in the stage2 sysroot. + builder.ensure(compile::Std::new(compiler, target)); builder.ensure(compile::Rustc::new(compiler, target)); let mut cargo = tool::prepare_tool_cargo( @@ -2318,7 +2340,13 @@ impl Step for CrateRustdoc { dylib_path.insert(0, PathBuf::from(&*libdir)); cargo.env(dylib_path_var(), env::join_paths(&dylib_path).unwrap()); - let _guard = builder.msg(builder.kind, compiler.stage, "rustdoc", compiler.host, target); + let _guard = builder.msg_sysroot_tool( + builder.kind, + compiler.stage, + "rustdoc", + compiler.host, + target, + ); run_cargo_test( cargo, &[], From 8abb80326adfe676f418c7bf162d979c9f99d224 Mon Sep 17 00:00:00 2001 From: Caleb Zulawski Date: Wed, 31 May 2023 22:54:01 -0400 Subject: [PATCH 5/9] Add portable-simd mention --- triagebot.toml | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/triagebot.toml b/triagebot.toml index c160c83cc9590..2758f1d1458b7 100644 --- a/triagebot.toml +++ b/triagebot.toml @@ -372,6 +372,14 @@ cc = ["@GuillaumeGomez"] message = "Some changes might have occurred in exhaustiveness checking" cc = ["@Nadrieril"] +[mentions."library/portable-simd"] +message = """ +Portable SIMD is developed in its own repository. If possible, consider \ +making this change to [rust-lang/portable-simd](https://github.com/rust-lang/portable-simd) \ +instead. +""" +cc = ["@calebzulawski"] + [mentions."src/librustdoc/clean/types.rs"] cc = ["@camelid"] From 793fa8d7c5535867510de90b945f1e01d0eca496 Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Thu, 1 Jun 2023 12:55:58 +0200 Subject: [PATCH 6/9] doc: improve explanation --- library/std/src/sync/once.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/std/src/sync/once.rs b/library/std/src/sync/once.rs index 1b17c31089ff2..8c46080e43b38 100644 --- a/library/std/src/sync/once.rs +++ b/library/std/src/sync/once.rs @@ -91,7 +91,7 @@ impl Once { /// return). /// /// If the given closure recursively invokes `call_once` on the same [`Once`] - /// instance the exact behavior is not specified, allowed outcomes are + /// instance, the exact behavior is not specified: allowed outcomes are /// a panic or a deadlock. /// /// # Examples From 96892a52edc4ae063a1cd2ab5b92be1df2fc65ea Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Thu, 1 Jun 2023 18:29:18 +0200 Subject: [PATCH 7/9] Fix bug where private item with intermediate doc hidden re-export was not inlined --- src/librustdoc/clean/mod.rs | 3 ++- src/librustdoc/visit_ast.rs | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 5fd867189fd71..60da1d6577490 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -2180,7 +2180,8 @@ fn get_all_import_attributes<'hir>( // This is the "original" reexport so we get all its attributes without filtering them. attrs = import_attrs.iter().map(|attr| (Cow::Borrowed(attr), Some(def_id))).collect(); first = false; - } else { + // We don't add attributes of an intermediate re-export if it has `#[doc(hidden)]`. + } else if !cx.tcx.is_doc_hidden(def_id) { add_without_unwanted_attributes(&mut attrs, import_attrs, is_inline, Some(def_id)); } } diff --git a/src/librustdoc/visit_ast.rs b/src/librustdoc/visit_ast.rs index abb9229fbd51a..1689445b9ef7c 100644 --- a/src/librustdoc/visit_ast.rs +++ b/src/librustdoc/visit_ast.rs @@ -246,7 +246,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { glob: bool, please_inline: bool, ) -> bool { - debug!("maybe_inline_local res: {:?}", res); + debug!("maybe_inline_local (renamed: {renamed:?}) res: {res:?}"); if renamed == Some(kw::Underscore) { // We never inline `_` reexports. @@ -308,6 +308,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { .cache .effective_visibilities .is_directly_public(tcx, item_def_id.to_def_id()) && + !tcx.is_doc_hidden(item_def_id) && !inherits_doc_hidden(tcx, item_def_id, None) { // The imported item is public and not `doc(hidden)` so no need to inline it. From a825b1e5da8bce093abf77559cf6b82b590a254e Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Thu, 1 Jun 2023 18:35:00 +0200 Subject: [PATCH 8/9] Add regression test where private item with intermediate doc hidden re-export was not inlined --- ...ne-private-with-intermediate-doc-hidden.rs | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 tests/rustdoc/inline-private-with-intermediate-doc-hidden.rs diff --git a/tests/rustdoc/inline-private-with-intermediate-doc-hidden.rs b/tests/rustdoc/inline-private-with-intermediate-doc-hidden.rs new file mode 100644 index 0000000000000..e382940a47eb8 --- /dev/null +++ b/tests/rustdoc/inline-private-with-intermediate-doc-hidden.rs @@ -0,0 +1,23 @@ +// This test ensures that if a private item is re-exported with an intermediate +// `#[doc(hidden)]` re-export, it'll still be inlined (and not include any attribute +// from the doc hidden re-export. + +#![crate_name = "foo"] + +// @has 'foo/index.html' +// There should only be one struct displayed. +// @count - '//*[@id="main-content"]/*[@class="small-section-header"]' 1 +// @has - '//*[@id="main-content"]/*[@class="small-section-header"]' 'Structs' +// @has - '//*[@id="main-content"]//a[@href="struct.Reexport.html"]' 'Reexport' +// @has - '//*[@id="main-content"]//*[@class="desc docblock-short"]' 'Visible. Original.' + +mod private { + /// Original. + pub struct Bar3; +} + +/// Hidden. +#[doc(hidden)] +pub use crate::private::Bar3; +/// Visible. +pub use self::Bar3 as Reexport; From d0298009924a3d37ddba89b346d1e419c9f1def3 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Thu, 1 Jun 2023 20:10:39 +0200 Subject: [PATCH 9/9] Update reexport-attr-merge rustdoc test --- tests/rustdoc/reexport-attr-merge.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/rustdoc/reexport-attr-merge.rs b/tests/rustdoc/reexport-attr-merge.rs index f6c23a1365f46..6cc054e7a8b2c 100644 --- a/tests/rustdoc/reexport-attr-merge.rs +++ b/tests/rustdoc/reexport-attr-merge.rs @@ -19,9 +19,9 @@ pub use Foo1 as Foo2; // First we ensure that only the reexport `Bar2` and the inlined struct `Bar` // are inlined. // @count - '//a[@class="struct"]' 2 -// Then we check that both `cfg` are displayed. +// Then we check that `cfg` is displayed for base item, but not for intermediate re-exports. // @has - '//*[@class="stab portability"]' 'foo' -// @has - '//*[@class="stab portability"]' 'bar' +// @!has - '//*[@class="stab portability"]' 'bar' // And finally we check that the only element displayed is `Bar`. // @has - '//a[@class="struct"]' 'Bar' #[doc(inline)]