diff options
46 files changed, 765 insertions, 793 deletions
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 0cfbb4e77c4..a91598586b9 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -182,6 +182,13 @@ jobs: - name: show the current environment run: src/ci/scripts/dump-environment.sh + # Pre-build citool before the following step uninstalls rustup + # Build is into the build directory, to avoid modifying sources + - name: build citool + run: | + cd src/ci/citool + CARGO_TARGET_DIR=../../../build/citool cargo build + - name: run the build # Redirect stderr to stdout to avoid reordering the two streams in the GHA logs. run: src/ci/scripts/run-build-from-ci.sh 2>&1 @@ -218,6 +225,16 @@ jobs: # erroring about invalid credentials instead. if: github.event_name == 'push' || env.DEPLOY == '1' || env.DEPLOY_ALT == '1' + - name: postprocess metrics into the summary + run: | + if [ -f build/metrics.json ]; then + ./build/citool/debug/citool postprocess-metrics build/metrics.json ${GITHUB_STEP_SUMMARY} + elif [ -f obj/build/metrics.json ]; then + ./build/citool/debug/citool postprocess-metrics obj/build/metrics.json ${GITHUB_STEP_SUMMARY} + else + echo "No metrics.json found" + fi + - name: upload job metrics to DataDog if: needs.calculate_matrix.outputs.run_type != 'pr' env: diff --git a/compiler/rustc_codegen_cranelift/patches/0029-stdlib-Disable-f16-and-f128-in-compiler-builtins.patch b/compiler/rustc_codegen_cranelift/patches/0029-stdlib-Disable-f16-and-f128-in-compiler-builtins.patch index bedc6ca11b3..d8db7d63f2d 100644 --- a/compiler/rustc_codegen_cranelift/patches/0029-stdlib-Disable-f16-and-f128-in-compiler-builtins.patch +++ b/compiler/rustc_codegen_cranelift/patches/0029-stdlib-Disable-f16-and-f128-in-compiler-builtins.patch @@ -16,8 +16,8 @@ index 7165c3e48af..968552ad435 100644 [dependencies] core = { path = "../core", public = true } --compiler_builtins = { version = "=0.1.148", features = ['rustc-dep-of-std'] } -+compiler_builtins = { version = "=0.1.148", features = ['rustc-dep-of-std', 'no-f16-f128'] } +-compiler_builtins = { version = "=0.1.150", features = ['rustc-dep-of-std'] } ++compiler_builtins = { version = "=0.1.150", features = ['rustc-dep-of-std', 'no-f16-f128'] } [dev-dependencies] rand = { version = "0.8.5", default-features = false, features = ["alloc"] } diff --git a/compiler/rustc_data_structures/src/captures.rs b/compiler/rustc_data_structures/src/captures.rs deleted file mode 100644 index 677ccb31454..00000000000 --- a/compiler/rustc_data_structures/src/captures.rs +++ /dev/null @@ -1,8 +0,0 @@ -/// "Signaling" trait used in impl trait to tag lifetimes that you may -/// need to capture but don't really need for other reasons. -/// Basically a workaround; see [this comment] for details. -/// -/// [this comment]: https://github.com/rust-lang/rust/issues/34511#issuecomment-373423999 -pub trait Captures<'a> {} - -impl<'a, T: ?Sized> Captures<'a> for T {} diff --git a/compiler/rustc_data_structures/src/lib.rs b/compiler/rustc_data_structures/src/lib.rs index 66d3834d857..a3b62b46919 100644 --- a/compiler/rustc_data_structures/src/lib.rs +++ b/compiler/rustc_data_structures/src/lib.rs @@ -48,7 +48,6 @@ pub use rustc_index::static_assert_size; pub mod aligned; pub mod base_n; pub mod binary_search_util; -pub mod captures; pub mod fingerprint; pub mod flat_map_in_place; pub mod flock; diff --git a/library/Cargo.lock b/library/Cargo.lock index de9685742f5..37b10649ced 100644 --- a/library/Cargo.lock +++ b/library/Cargo.lock @@ -61,9 +61,9 @@ dependencies = [ [[package]] name = "compiler_builtins" -version = "0.1.148" +version = "0.1.150" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26137996631d90d2727b905b480fdcf8c4479fdbce7afd7f8e3796d689b33cc2" +checksum = "5c42734e0ccf0d9f953165770593a75306f0b24dda1aa03f115c70748726dbca" dependencies = [ "cc", "rustc-std-workspace-core", diff --git a/library/alloc/Cargo.toml b/library/alloc/Cargo.toml index 9e80f3579e8..9cf9e98e89e 100644 --- a/library/alloc/Cargo.toml +++ b/library/alloc/Cargo.toml @@ -12,7 +12,7 @@ edition = "2021" [dependencies] core = { path = "../core", public = true } -compiler_builtins = { version = "=0.1.148", features = ['rustc-dep-of-std'] } +compiler_builtins = { version = "=0.1.150", features = ['rustc-dep-of-std'] } [dev-dependencies] rand = { version = "0.9.0", default-features = false, features = ["alloc"] } diff --git a/library/std/Cargo.toml b/library/std/Cargo.toml index f4d4894c1bb..8e4dd0f2bf4 100644 --- a/library/std/Cargo.toml +++ b/library/std/Cargo.toml @@ -18,7 +18,7 @@ cfg-if = { version = "1.0", features = ['rustc-dep-of-std'] } panic_unwind = { path = "../panic_unwind", optional = true } panic_abort = { path = "../panic_abort" } core = { path = "../core", public = true } -compiler_builtins = { version = "=0.1.148" } +compiler_builtins = { version = "=0.1.150" } unwind = { path = "../unwind" } hashbrown = { version = "0.15", default-features = false, features = [ 'rustc-dep-of-std', diff --git a/src/bootstrap/src/core/build_steps/dist.rs b/src/bootstrap/src/core/build_steps/dist.rs index 26b3e0b701c..e0ad6856dc7 100644 --- a/src/bootstrap/src/core/build_steps/dist.rs +++ b/src/bootstrap/src/core/build_steps/dist.rs @@ -2464,3 +2464,30 @@ impl Step for ReproducibleArtifacts { if added_anything { Some(tarball.generate()) } else { None } } } + +/// Tarball containing a prebuilt version of the libgccjit library, +/// needed as a dependency for the GCC codegen backend (similarly to the LLVM +/// backend needing a prebuilt libLLVM). +#[derive(Clone, Debug, Eq, Hash, PartialEq)] +pub struct Gcc { + pub target: TargetSelection, +} + +impl Step for Gcc { + type Output = GeneratedTarball; + + fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> { + run.alias("gcc") + } + + fn make_run(run: RunConfig<'_>) { + run.builder.ensure(Gcc { target: run.target }); + } + + fn run(self, builder: &Builder<'_>) -> Self::Output { + let tarball = Tarball::new(builder, "gcc", &self.target.triple); + let output = builder.ensure(super::gcc::Gcc { target: self.target }); + tarball.add_file(output.libgccjit, ".", 0o644); + tarball.generate() + } +} diff --git a/src/bootstrap/src/core/build_steps/test.rs b/src/bootstrap/src/core/build_steps/test.rs index c9fa2e9ba96..d84ade21caf 100644 --- a/src/bootstrap/src/core/build_steps/test.rs +++ b/src/bootstrap/src/core/build_steps/test.rs @@ -1242,59 +1242,6 @@ macro_rules! test { }; } -#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq, Ord, PartialOrd)] -pub struct RunMakeSupport { - pub compiler: Compiler, - pub target: TargetSelection, -} - -impl Step for RunMakeSupport { - type Output = PathBuf; - const DEFAULT: bool = true; - - fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> { - run.never() - } - - fn make_run(run: RunConfig<'_>) { - let compiler = run.builder.compiler(run.builder.top_stage, run.build_triple()); - run.builder.ensure(RunMakeSupport { compiler, target: run.build_triple() }); - } - - /// Builds run-make-support and returns the path to the resulting rlib. - fn run(self, builder: &Builder<'_>) -> PathBuf { - builder.ensure(compile::Std::new(self.compiler, self.target)); - - let cargo = tool::prepare_tool_cargo( - builder, - self.compiler, - Mode::ToolStd, - self.target, - Kind::Build, - "src/tools/run-make-support", - SourceType::InTree, - &[], - ); - - let _guard = builder.msg_tool( - Kind::Build, - Mode::ToolStd, - "run-make-support", - self.compiler.stage, - &self.compiler.host, - &self.target, - ); - cargo.into_cmd().run(builder); - - let lib_name = "librun_make_support.rlib"; - let lib = builder.tools_dir(self.compiler).join(lib_name); - - let cargo_out = builder.cargo_out(self.compiler, Mode::ToolStd, self.target).join(lib_name); - builder.copy_link(&cargo_out, &lib); - lib - } -} - /// Runs `cargo test` on the `src/tools/run-make-support` crate. /// That crate is used by run-make tests. #[derive(Debug, Clone, PartialEq, Eq, Hash)] @@ -1446,40 +1393,7 @@ test!(Pretty { only_hosts: true, }); -/// Special-handling is needed for `run-make`, so don't use `test!` for defining `RunMake` -/// tests. -#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] -pub struct RunMake { - pub compiler: Compiler, - pub target: TargetSelection, -} - -impl Step for RunMake { - type Output = (); - const DEFAULT: bool = true; - const ONLY_HOSTS: bool = false; - - fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> { - run.suite_path("tests/run-make") - } - - fn make_run(run: RunConfig<'_>) { - let compiler = run.builder.compiler(run.builder.top_stage, run.build_triple()); - run.builder.ensure(RunMakeSupport { compiler, target: run.build_triple() }); - run.builder.ensure(RunMake { compiler, target: run.target }); - } - - fn run(self, builder: &Builder<'_>) { - builder.ensure(Compiletest { - compiler: self.compiler, - target: self.target, - mode: "run-make", - suite: "run-make", - path: "tests/run-make", - compare_mode: None, - }); - } -} +test!(RunMake { path: "tests/run-make", mode: "run-make", suite: "run-make", default: true }); test!(Assembly { path: "tests/assembly", mode: "assembly", suite: "assembly", default: true }); @@ -1722,6 +1636,9 @@ NOTE: if you're sure you want to do this, please open an issue as to why. In the host: target, }); } + if suite == "run-make" { + builder.tool_exe(Tool::RunMakeSupport); + } // Also provide `rust_test_helpers` for the host. builder.ensure(TestHelpers { target: compiler.host }); @@ -1774,6 +1691,11 @@ NOTE: if you're sure you want to do this, please open an issue as to why. In the }; cmd.arg("--cargo-path").arg(cargo_path); + + // We need to pass the compiler that was used to compile run-make-support, + // because we have to use the same compiler to compile rmake.rs recipes. + let stage0_rustc_path = builder.compiler(0, compiler.host); + cmd.arg("--stage0-rustc-path").arg(builder.rustc(stage0_rustc_path)); } // Avoid depending on rustdoc when we don't need it. diff --git a/src/bootstrap/src/core/build_steps/tool.rs b/src/bootstrap/src/core/build_steps/tool.rs index 39acb646dff..0149709f5c5 100644 --- a/src/bootstrap/src/core/build_steps/tool.rs +++ b/src/bootstrap/src/core/build_steps/tool.rs @@ -35,6 +35,12 @@ pub enum SourceType { } #[derive(Debug, Clone, Hash, PartialEq, Eq)] +pub enum ToolArtifactKind { + Binary, + Library, +} + +#[derive(Debug, Clone, Hash, PartialEq, Eq)] struct ToolBuild { compiler: Compiler, target: TargetSelection, @@ -47,6 +53,8 @@ struct ToolBuild { allow_features: &'static str, /// Additional arguments to pass to the `cargo` invocation. cargo_args: Vec<String>, + /// Whether the tool builds a binary or a library. + artifact_kind: ToolArtifactKind, } impl Builder<'_> { @@ -79,7 +87,7 @@ impl Builder<'_> { /// for using this type as `type Output = ToolBuildResult;` #[derive(Clone)] pub struct ToolBuildResult { - /// Executable path of the corresponding tool that was built. + /// Artifact path of the corresponding tool that was built. pub tool_path: PathBuf, /// Compiler used to build the tool. For non-`ToolRustc` tools this is equal to `target_compiler`. /// For `ToolRustc` this is one stage before of the `target_compiler`. @@ -179,8 +187,14 @@ impl Step for ToolBuild { if tool == "tidy" { tool = "rust-tidy"; } - let tool_path = - copy_link_tool_bin(builder, self.compiler, self.target, self.mode, tool); + let tool_path = match self.artifact_kind { + ToolArtifactKind::Binary => { + copy_link_tool_bin(builder, self.compiler, self.target, self.mode, tool) + } + ToolArtifactKind::Library => builder + .cargo_out(self.compiler, self.mode, self.target) + .join(format!("lib{tool}.rlib")), + }; ToolBuildResult { tool_path, build_compiler: self.compiler, target_compiler } } @@ -330,6 +344,7 @@ macro_rules! bootstrap_tool { $(,is_unstable_tool = $unstable:expr)* $(,allow_features = $allow_features:expr)? $(,submodules = $submodules:expr)? + $(,artifact_kind = $artifact_kind:expr)? ; )+) => { #[derive(PartialEq, Eq, Clone)] @@ -389,6 +404,7 @@ macro_rules! bootstrap_tool { builder.require_submodule(submodule, None); } )* + builder.ensure(ToolBuild { compiler: self.compiler, target: self.target, @@ -407,7 +423,12 @@ macro_rules! bootstrap_tool { }, extra_features: vec![], allow_features: concat!($($allow_features)*), - cargo_args: vec![] + cargo_args: vec![], + artifact_kind: if false $(|| $artifact_kind == ToolArtifactKind::Library)* { + ToolArtifactKind::Library + } else { + ToolArtifactKind::Binary + } }) } } @@ -445,51 +466,14 @@ bootstrap_tool!( WasmComponentLd, "src/tools/wasm-component-ld", "wasm-component-ld", is_unstable_tool = true, allow_features = "min_specialization"; UnicodeTableGenerator, "src/tools/unicode-table-generator", "unicode-table-generator"; FeaturesStatusDump, "src/tools/features-status-dump", "features-status-dump"; + OptimizedDist, "src/tools/opt-dist", "opt-dist", submodules = &["src/tools/rustc-perf"]; + RunMakeSupport, "src/tools/run-make-support", "run_make_support", artifact_kind = ToolArtifactKind::Library; ); /// These are the submodules that are required for rustbook to work due to /// depending on mdbook plugins. pub static SUBMODULES_FOR_RUSTBOOK: &[&str] = &["src/doc/book", "src/doc/reference"]; -#[derive(Debug, Clone, Hash, PartialEq, Eq)] -pub struct OptimizedDist { - pub compiler: Compiler, - pub target: TargetSelection, -} - -impl Step for OptimizedDist { - type Output = ToolBuildResult; - - fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> { - run.path("src/tools/opt-dist") - } - - fn make_run(run: RunConfig<'_>) { - run.builder.ensure(OptimizedDist { - compiler: run.builder.compiler(0, run.builder.config.build), - target: run.target, - }); - } - - fn run(self, builder: &Builder<'_>) -> ToolBuildResult { - // We need to ensure the rustc-perf submodule is initialized when building opt-dist since - // the tool requires it to be in place to run. - builder.require_submodule("src/tools/rustc-perf", None); - - builder.ensure(ToolBuild { - compiler: self.compiler, - target: self.target, - tool: "opt-dist", - mode: Mode::ToolBootstrap, - path: "src/tools/opt-dist", - source_type: SourceType::InTree, - extra_features: Vec::new(), - allow_features: "", - cargo_args: Vec::new(), - }) - } -} - /// The [rustc-perf](https://github.com/rust-lang/rustc-perf) benchmark suite, which is added /// as a submodule at `src/tools/rustc-perf`. #[derive(Debug, Clone, Hash, PartialEq, Eq)] @@ -529,6 +513,7 @@ impl Step for RustcPerf { // Only build the collector package, which is used for benchmarking through // a CLI. cargo_args: vec!["-p".to_string(), "collector".to_string()], + artifact_kind: ToolArtifactKind::Binary, }; let res = builder.ensure(tool.clone()); // We also need to symlink the `rustc-fake` binary to the corresponding directory, @@ -586,6 +571,7 @@ impl Step for ErrorIndex { extra_features: Vec::new(), allow_features: "", cargo_args: Vec::new(), + artifact_kind: ToolArtifactKind::Binary, }) } } @@ -621,6 +607,7 @@ impl Step for RemoteTestServer { extra_features: Vec::new(), allow_features: "", cargo_args: Vec::new(), + artifact_kind: ToolArtifactKind::Binary, }) } } @@ -725,6 +712,7 @@ impl Step for Rustdoc { extra_features, allow_features: "", cargo_args: Vec::new(), + artifact_kind: ToolArtifactKind::Binary, }); // don't create a stage0-sysroot/bin directory. @@ -779,6 +767,7 @@ impl Step for Cargo { extra_features: Vec::new(), allow_features: "", cargo_args: Vec::new(), + artifact_kind: ToolArtifactKind::Binary, }) } } @@ -827,6 +816,7 @@ impl Step for LldWrapper { extra_features: Vec::new(), allow_features: "", cargo_args: Vec::new(), + artifact_kind: ToolArtifactKind::Binary, }); let libdir_bin = builder.sysroot_target_bindir(self.target_compiler, target); @@ -887,6 +877,7 @@ impl Step for RustAnalyzer { source_type: SourceType::InTree, allow_features: RustAnalyzer::ALLOW_FEATURES, cargo_args: Vec::new(), + artifact_kind: ToolArtifactKind::Binary, }) } } @@ -931,6 +922,7 @@ impl Step for RustAnalyzerProcMacroSrv { source_type: SourceType::InTree, allow_features: RustAnalyzer::ALLOW_FEATURES, cargo_args: Vec::new(), + artifact_kind: ToolArtifactKind::Binary, }); // Copy `rust-analyzer-proc-macro-srv` to `<sysroot>/libexec/` @@ -985,6 +977,7 @@ impl Step for LlvmBitcodeLinker { extra_features: self.extra_features, allow_features: "", cargo_args: Vec::new(), + artifact_kind: ToolArtifactKind::Binary, }); if tool_result.target_compiler.stage > 0 { @@ -1164,6 +1157,7 @@ fn run_tool_build_step( source_type: SourceType::InTree, allow_features: "", cargo_args: vec![], + artifact_kind: ToolArtifactKind::Binary, }); // FIXME: This should just be an if-let-chain, but those are unstable. @@ -1242,6 +1236,7 @@ impl Step for TestFloatParse { extra_features: Vec::new(), allow_features: "", cargo_args: Vec::new(), + artifact_kind: ToolArtifactKind::Binary, }) } } diff --git a/src/bootstrap/src/core/builder/mod.rs b/src/bootstrap/src/core/builder/mod.rs index c8e2856bdc8..7d404a4f7ff 100644 --- a/src/bootstrap/src/core/builder/mod.rs +++ b/src/bootstrap/src/core/builder/mod.rs @@ -1072,6 +1072,7 @@ impl<'a> Builder<'a> { dist::PlainSourceTarball, dist::BuildManifest, dist::ReproducibleArtifacts, + dist::Gcc ), Kind::Install => describe!( install::Docs, diff --git a/src/bootstrap/src/utils/metrics.rs b/src/bootstrap/src/utils/metrics.rs index b51fd490535..57766fd63fb 100644 --- a/src/bootstrap/src/utils/metrics.rs +++ b/src/bootstrap/src/utils/metrics.rs @@ -200,6 +200,14 @@ impl BuildMetrics { } }; invocations.push(JsonInvocation { + // The command-line invocation with which bootstrap was invoked. + // Skip the first argument, as it is a potentially long absolute + // path that is not interesting. + cmdline: std::env::args_os() + .skip(1) + .map(|arg| arg.to_string_lossy().to_string()) + .collect::<Vec<_>>() + .join(" "), start_time: state .invocation_start .duration_since(SystemTime::UNIX_EPOCH) diff --git a/src/build_helper/src/metrics.rs b/src/build_helper/src/metrics.rs index 538c33e9b15..eb306550fc4 100644 --- a/src/build_helper/src/metrics.rs +++ b/src/build_helper/src/metrics.rs @@ -1,3 +1,5 @@ +use std::time::Duration; + use serde_derive::{Deserialize, Serialize}; #[derive(Serialize, Deserialize)] @@ -12,6 +14,8 @@ pub struct JsonRoot { #[derive(Serialize, Deserialize)] #[serde(rename_all = "snake_case")] pub struct JsonInvocation { + // Remembers the command-line invocation with which bootstrap was invoked. + pub cmdline: String, // Unix timestamp in seconds // // This is necessary to easily correlate this invocation with logs or other data. @@ -98,3 +102,87 @@ fn null_as_f64_nan<'de, D: serde::Deserializer<'de>>(d: D) -> Result<f64, D::Err use serde::Deserialize as _; Option::<f64>::deserialize(d).map(|f| f.unwrap_or(f64::NAN)) } + +/// Represents a single bootstrap step, with the accumulated duration of all its children. +#[derive(Clone, Debug)] +pub struct BuildStep { + pub r#type: String, + pub children: Vec<BuildStep>, + pub duration: Duration, +} + +impl BuildStep { + /// Create a `BuildStep` representing a single invocation of bootstrap. + /// The most important thing is that the build step aggregates the + /// durations of all children, so that it can be easily accessed. + pub fn from_invocation(invocation: &JsonInvocation) -> Self { + fn parse(node: &JsonNode) -> Option<BuildStep> { + match node { + JsonNode::RustbuildStep { + type_: kind, + children, + duration_excluding_children_sec, + .. + } => { + let children: Vec<_> = children.into_iter().filter_map(parse).collect(); + let children_duration = children.iter().map(|c| c.duration).sum::<Duration>(); + Some(BuildStep { + r#type: kind.to_string(), + children, + duration: children_duration + + Duration::from_secs_f64(*duration_excluding_children_sec), + }) + } + JsonNode::TestSuite(_) => None, + } + } + + let duration = Duration::from_secs_f64(invocation.duration_including_children_sec); + let children: Vec<_> = invocation.children.iter().filter_map(parse).collect(); + Self { r#type: "total".to_string(), children, duration } + } + + pub fn find_all_by_type(&self, r#type: &str) -> Vec<&Self> { + let mut result = Vec::new(); + self.find_by_type(r#type, &mut result); + result + } + + fn find_by_type<'a>(&'a self, r#type: &str, result: &mut Vec<&'a Self>) { + if self.r#type == r#type { + result.push(self); + } + for child in &self.children { + child.find_by_type(r#type, result); + } + } +} + +/// Writes build steps into a nice indented table. +pub fn format_build_steps(root: &BuildStep) -> String { + use std::fmt::Write; + + let mut substeps: Vec<(u32, &BuildStep)> = Vec::new(); + + fn visit<'a>(step: &'a BuildStep, level: u32, substeps: &mut Vec<(u32, &'a BuildStep)>) { + substeps.push((level, step)); + for child in &step.children { + visit(child, level + 1, substeps); + } + } + + visit(root, 0, &mut substeps); + + let mut output = String::new(); + for (level, step) in substeps { + let label = format!( + "{}{}", + ".".repeat(level as usize), + // Bootstrap steps can be generic and thus contain angle brackets (<...>). + // However, Markdown interprets these as HTML, so we need to escap ethem. + step.r#type.replace('<', "<").replace('>', ">") + ); + writeln!(output, "{label:.<65}{:>8.2}s", step.duration.as_secs_f64()).unwrap(); + } + output +} diff --git a/src/ci/citool/Cargo.lock b/src/ci/citool/Cargo.lock index 39b6b44da64..e5be2d42472 100644 --- a/src/ci/citool/Cargo.lock +++ b/src/ci/citool/Cargo.lock @@ -59,10 +59,19 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "34ac096ce696dc2fcabef30516bb13c0a68a11d30131d3df6f04711467681b04" [[package]] +name = "build_helper" +version = "0.1.0" +dependencies = [ + "serde", + "serde_derive", +] + +[[package]] name = "citool" version = "0.1.0" dependencies = [ "anyhow", + "build_helper", "clap", "insta", "serde", diff --git a/src/ci/citool/Cargo.toml b/src/ci/citool/Cargo.toml index e77c67c7147..11172832cb8 100644 --- a/src/ci/citool/Cargo.toml +++ b/src/ci/citool/Cargo.toml @@ -10,6 +10,8 @@ serde = { version = "1", features = ["derive"] } serde_yaml = "0.9" serde_json = "1" +build_helper = { path = "../../build_helper" } + [dev-dependencies] insta = "1" diff --git a/src/ci/citool/src/main.rs b/src/ci/citool/src/main.rs index ad9cc8b82a6..cef92e998da 100644 --- a/src/ci/citool/src/main.rs +++ b/src/ci/citool/src/main.rs @@ -1,3 +1,5 @@ +mod metrics; + use std::collections::BTreeMap; use std::path::{Path, PathBuf}; use std::process::Command; @@ -6,6 +8,8 @@ use anyhow::Context; use clap::Parser; use serde_yaml::Value; +use crate::metrics::postprocess_metrics; + const CI_DIRECTORY: &str = concat!(env!("CARGO_MANIFEST_DIR"), "/.."); const DOCKER_DIRECTORY: &str = concat!(env!("CARGO_MANIFEST_DIR"), "/../docker"); const JOBS_YML_PATH: &str = concat!(env!("CARGO_MANIFEST_DIR"), "/../github-actions/jobs.yml"); @@ -338,6 +342,14 @@ enum Args { #[clap(long = "type", default_value = "auto")] job_type: JobType, }, + /// Postprocess the metrics.json file generated by bootstrap. + PostprocessMetrics { + /// Path to the metrics.json file + metrics_path: PathBuf, + /// Path to a file where the postprocessed metrics summary will be stored. + /// Usually, this will be GITHUB_STEP_SUMMARY on CI. + summary_path: PathBuf, + }, } #[derive(clap::ValueEnum, Clone)] @@ -369,6 +381,9 @@ fn main() -> anyhow::Result<()> { Args::RunJobLocally { job_type, name } => { run_workflow_locally(load_db(default_jobs_file)?, job_type, name)? } + Args::PostprocessMetrics { metrics_path, summary_path } => { + postprocess_metrics(&metrics_path, &summary_path)?; + } } Ok(()) diff --git a/src/ci/citool/src/metrics.rs b/src/ci/citool/src/metrics.rs new file mode 100644 index 00000000000..2386413ed6b --- /dev/null +++ b/src/ci/citool/src/metrics.rs @@ -0,0 +1,164 @@ +use std::collections::BTreeMap; +use std::fs::File; +use std::io::Write; +use std::path::Path; + +use anyhow::Context; +use build_helper::metrics::{ + BuildStep, JsonNode, JsonRoot, TestOutcome, TestSuite, TestSuiteMetadata, format_build_steps, +}; + +pub fn postprocess_metrics(metrics_path: &Path, summary_path: &Path) -> anyhow::Result<()> { + let metrics = load_metrics(metrics_path)?; + + let mut file = File::options() + .append(true) + .create(true) + .open(summary_path) + .with_context(|| format!("Cannot open summary file at {summary_path:?}"))?; + + if !metrics.invocations.is_empty() { + writeln!(file, "# Bootstrap steps")?; + record_bootstrap_step_durations(&metrics, &mut file)?; + record_test_suites(&metrics, &mut file)?; + } + + Ok(()) +} + +fn record_bootstrap_step_durations(metrics: &JsonRoot, file: &mut File) -> anyhow::Result<()> { + for invocation in &metrics.invocations { + let step = BuildStep::from_invocation(invocation); + let table = format_build_steps(&step); + eprintln!("Step `{}`\n{table}\n", invocation.cmdline); + writeln!( + file, + r"<details> +<summary>{}</summary> +<pre><code>{table}</code></pre> +</details> +", + invocation.cmdline + )?; + } + eprintln!("Recorded {} bootstrap invocation(s)", metrics.invocations.len()); + + Ok(()) +} + +fn record_test_suites(metrics: &JsonRoot, file: &mut File) -> anyhow::Result<()> { + let suites = get_test_suites(&metrics); + + if !suites.is_empty() { + let aggregated = aggregate_test_suites(&suites); + let table = render_table(aggregated); + writeln!(file, "\n# Test results\n")?; + writeln!(file, "{table}")?; + } else { + eprintln!("No test suites found in metrics"); + } + + Ok(()) +} + +fn render_table(suites: BTreeMap<String, TestSuiteRecord>) -> String { + use std::fmt::Write; + + let mut table = "| Test suite | Passed ✅ | Ignored 🚫 | Failed ❌ |\n".to_string(); + writeln!(table, "|:------|------:|------:|------:|").unwrap(); + + fn write_row( + buffer: &mut String, + name: &str, + record: &TestSuiteRecord, + surround: &str, + ) -> std::fmt::Result { + let TestSuiteRecord { passed, ignored, failed } = record; + let total = (record.passed + record.ignored + record.failed) as f64; + let passed_pct = ((*passed as f64) / total) * 100.0; + let ignored_pct = ((*ignored as f64) / total) * 100.0; + let failed_pct = ((*failed as f64) / total) * 100.0; + + write!(buffer, "| {surround}{name}{surround} |")?; + write!(buffer, " {surround}{passed} ({passed_pct:.0}%){surround} |")?; + write!(buffer, " {surround}{ignored} ({ignored_pct:.0}%){surround} |")?; + writeln!(buffer, " {surround}{failed} ({failed_pct:.0}%){surround} |")?; + + Ok(()) + } + + let mut total = TestSuiteRecord::default(); + for (name, record) in suites { + write_row(&mut table, &name, &record, "").unwrap(); + total.passed += record.passed; + total.ignored += record.ignored; + total.failed += record.failed; + } + write_row(&mut table, "Total", &total, "**").unwrap(); + table +} + +#[derive(Default)] +struct TestSuiteRecord { + passed: u64, + ignored: u64, + failed: u64, +} + +fn aggregate_test_suites(suites: &[&TestSuite]) -> BTreeMap<String, TestSuiteRecord> { + let mut records: BTreeMap<String, TestSuiteRecord> = BTreeMap::new(); + for suite in suites { + let name = match &suite.metadata { + TestSuiteMetadata::CargoPackage { crates, stage, .. } => { + format!("{} (stage {stage})", crates.join(", ")) + } + TestSuiteMetadata::Compiletest { suite, stage, .. } => { + format!("{suite} (stage {stage})") + } + }; + let record = records.entry(name).or_default(); + for test in &suite.tests { + match test.outcome { + TestOutcome::Passed => { + record.passed += 1; + } + TestOutcome::Failed => { + record.failed += 1; + } + TestOutcome::Ignored { .. } => { + record.ignored += 1; + } + } + } + } + records +} + +fn get_test_suites(metrics: &JsonRoot) -> Vec<&TestSuite> { + fn visit_test_suites<'a>(nodes: &'a [JsonNode], suites: &mut Vec<&'a TestSuite>) { + for node in nodes { + match node { + JsonNode::RustbuildStep { children, .. } => { + visit_test_suites(&children, suites); + } + JsonNode::TestSuite(suite) => { + suites.push(&suite); + } + } + } + } + + let mut suites = vec![]; + for invocation in &metrics.invocations { + visit_test_suites(&invocation.children, &mut suites); + } + suites +} + +fn load_metrics(path: &Path) -> anyhow::Result<JsonRoot> { + let metrics = std::fs::read_to_string(path) + .with_context(|| format!("Cannot read JSON metrics from {path:?}"))?; + let metrics: JsonRoot = serde_json::from_str(&metrics) + .with_context(|| format!("Cannot deserialize JSON metrics from {path:?}"))?; + Ok(metrics) +} diff --git a/src/ci/docker/host-x86_64/dist-x86_64-linux/Dockerfile b/src/ci/docker/host-x86_64/dist-x86_64-linux/Dockerfile index 0b4682ac32b..f54ecef1e30 100644 --- a/src/ci/docker/host-x86_64/dist-x86_64-linux/Dockerfile +++ b/src/ci/docker/host-x86_64/dist-x86_64-linux/Dockerfile @@ -101,7 +101,7 @@ ENV SCRIPT python3 ../x.py build --set rust.debug=true opt-dist && \ ./build/$HOSTS/stage0-tools-bin/opt-dist linux-ci -- python3 ../x.py dist \ --host $HOSTS --target $HOSTS \ --include-default-paths \ - build-manifest bootstrap + build-manifest bootstrap gcc ENV CARGO_TARGET_X86_64_UNKNOWN_LINUX_GNU_LINKER=clang # This is the only builder which will create source tarballs diff --git a/src/ci/docker/scripts/rfl-build.sh b/src/ci/docker/scripts/rfl-build.sh index 573821c3e59..ea8066d95e0 100755 --- a/src/ci/docker/scripts/rfl-build.sh +++ b/src/ci/docker/scripts/rfl-build.sh @@ -8,16 +8,10 @@ LINUX_VERSION=v6.14-rc3 ../x.py build --stage 2 library rustdoc clippy rustfmt ../x.py build --stage 0 cargo -# Install rustup so that we can use the built toolchain easily, and also -# install bindgen in an easy way. -curl --proto '=https' --tlsv1.2 -sSf -o rustup.sh https://sh.rustup.rs -sh rustup.sh -y --default-toolchain none +BUILD_DIR=$(realpath ./build/x86_64-unknown-linux-gnu) -source /cargo/env - -BUILD_DIR=$(realpath ./build) -rustup toolchain link local "${BUILD_DIR}"/x86_64-unknown-linux-gnu/stage2 -rustup default local +# Provide path to rustc, rustdoc, clippy-driver and rustfmt to RfL +export PATH=${PATH}:${BUILD_DIR}/stage2/bin mkdir -p rfl cd rfl @@ -33,10 +27,14 @@ git -C linux fetch --depth 1 origin ${LINUX_VERSION} git -C linux checkout FETCH_HEAD # Install bindgen -"${BUILD_DIR}"/x86_64-unknown-linux-gnu/stage0/bin/cargo install \ +"${BUILD_DIR}"/stage0/bin/cargo install \ --version $(linux/scripts/min-tool-version.sh bindgen) \ + --root ${BUILD_DIR}/bindgen \ bindgen-cli +# Provide path to bindgen to RfL +export PATH=${PATH}:${BUILD_DIR}/bindgen/bin + # Configure Rust for Linux cat <<EOF > linux/kernel/configs/rfl-for-rust-ci.config # CONFIG_WERROR is not set diff --git a/src/ci/github-actions/jobs.yml b/src/ci/github-actions/jobs.yml index 1504e5c60ce..bbcc01a0c29 100644 --- a/src/ci/github-actions/jobs.yml +++ b/src/ci/github-actions/jobs.yml @@ -271,9 +271,8 @@ auto: # Tests integration with Rust for Linux. # Builds stage 1 compiler and tries to compile a few RfL examples with it. - # FIXME: fix rustup 1.28 issue - # - name: x86_64-rust-for-linux - # <<: *job-linux-4c + - name: x86_64-rust-for-linux + <<: *job-linux-4c - name: x86_64-gnu <<: *job-linux-4c diff --git a/src/librustdoc/Cargo.toml b/src/librustdoc/Cargo.toml index 91cc4088788..909b81a723b 100644 --- a/src/librustdoc/Cargo.toml +++ b/src/librustdoc/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "rustdoc" version = "0.0.0" -edition = "2021" +edition = "2024" build = "build.rs" [lib] diff --git a/src/librustdoc/clean/cfg.rs b/src/librustdoc/clean/cfg.rs index bec7fbe8f52..ab169f3c2a4 100644 --- a/src/librustdoc/clean/cfg.rs +++ b/src/librustdoc/clean/cfg.rs @@ -48,12 +48,12 @@ impl Cfg { exclude: &FxHashSet<Cfg>, ) -> Result<Option<Cfg>, InvalidCfgError> { match nested_cfg { - MetaItemInner::MetaItem(ref cfg) => Cfg::parse_without(cfg, exclude), + MetaItemInner::MetaItem(cfg) => Cfg::parse_without(cfg, exclude), MetaItemInner::Lit(MetaItemLit { kind: LitKind::Bool(b), .. }) => match *b { true => Ok(Some(Cfg::True)), false => Ok(Some(Cfg::False)), }, - MetaItemInner::Lit(ref lit) => { + MetaItemInner::Lit(lit) => { Err(InvalidCfgError { msg: "unexpected literal", span: lit.span }) } } diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index ceffe5e5ce0..bb12e4a706e 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -741,7 +741,7 @@ pub(crate) fn clean_generics<'tcx>( for p in gens.params.iter().filter(|p| !is_impl_trait(p) && !is_elided_lifetime(p)) { let mut p = clean_generic_param(cx, Some(gens), p); match &mut p.kind { - GenericParamDefKind::Lifetime { ref mut outlives } => { + GenericParamDefKind::Lifetime { outlives } => { if let Some(region_pred) = region_predicates.get_mut(&Lifetime(p.name)) { // We merge bounds in the `where` clause. for outlive in outlives.drain(..) { @@ -2688,7 +2688,7 @@ fn filter_doc_attr_ident(ident: Symbol, is_inline: bool) -> bool { /// Before calling this function, make sure `normal` is a `#[doc]` attribute. fn filter_doc_attr(args: &mut hir::AttrArgs, is_inline: bool) { match args { - hir::AttrArgs::Delimited(ref mut args) => { + hir::AttrArgs::Delimited(args) => { let tokens = filter_tokens_from_list(&args.tokens, |token| { !matches!( token, diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs index 178b6a60b41..5906a720e0f 100644 --- a/src/librustdoc/clean/types.rs +++ b/src/librustdoc/clean/types.rs @@ -502,7 +502,7 @@ impl Item { let Some(links) = cx.cache().intra_doc_links.get(&self.item_id) else { return vec![] }; links .iter() - .filter_map(|ItemLink { link: s, link_text, page_id: id, ref fragment }| { + .filter_map(|ItemLink { link: s, link_text, page_id: id, fragment }| { debug!(?id); if let Ok((mut href, ..)) = href(*id, cx) { debug!(?href); @@ -1150,7 +1150,7 @@ pub(crate) struct Attributes { } impl Attributes { - pub(crate) fn lists(&self, name: Symbol) -> impl Iterator<Item = ast::MetaItemInner> + '_ { + pub(crate) fn lists(&self, name: Symbol) -> impl Iterator<Item = ast::MetaItemInner> { hir_attr_lists(&self.other_attrs[..], name) } @@ -1864,7 +1864,7 @@ impl PrimitiveType { .copied() } - pub(crate) fn all_impls(tcx: TyCtxt<'_>) -> impl Iterator<Item = DefId> + '_ { + pub(crate) fn all_impls(tcx: TyCtxt<'_>) -> impl Iterator<Item = DefId> { Self::simplified_types() .values() .flatten() @@ -2259,7 +2259,7 @@ impl GenericArgs { GenericArgs::Parenthesized { inputs, output } => inputs.is_empty() && output.is_none(), } } - pub(crate) fn constraints<'a>(&'a self) -> Box<dyn Iterator<Item = AssocItemConstraint> + 'a> { + pub(crate) fn constraints(&self) -> Box<dyn Iterator<Item = AssocItemConstraint> + '_> { match self { GenericArgs::AngleBracketed { constraints, .. } => { Box::new(constraints.iter().cloned()) diff --git a/src/librustdoc/clean/utils.rs b/src/librustdoc/clean/utils.rs index 34656b26ce2..a284de5229a 100644 --- a/src/librustdoc/clean/utils.rs +++ b/src/librustdoc/clean/utils.rs @@ -60,7 +60,7 @@ pub(crate) fn krate(cx: &mut DocContext<'_>) -> Crate { let primitives = local_crate.primitives(cx.tcx); let keywords = local_crate.keywords(cx.tcx); { - let ItemKind::ModuleItem(ref mut m) = &mut module.inner.kind else { unreachable!() }; + let ItemKind::ModuleItem(m) = &mut module.inner.kind else { unreachable!() }; m.items.extend(primitives.iter().map(|&(def_id, prim)| { Item::from_def_id_and_parts( def_id, @@ -302,7 +302,7 @@ pub(crate) fn name_from_pat(p: &hir::Pat<'_>) -> Symbol { use rustc_hir::*; debug!("trying to get a name from pattern: {p:?}"); - Symbol::intern(&match p.kind { + Symbol::intern(&match &p.kind { // FIXME(never_patterns): does this make sense? PatKind::Wild | PatKind::Err(_) @@ -313,8 +313,9 @@ pub(crate) fn name_from_pat(p: &hir::Pat<'_>) -> Symbol { } PatKind::Binding(_, _, ident, _) => return ident.name, PatKind::Box(p) | PatKind::Ref(p, _) | PatKind::Guard(p, _) => return name_from_pat(p), - PatKind::TupleStruct(ref p, ..) - | PatKind::Expr(PatExpr { kind: PatExprKind::Path(ref p), .. }) => qpath_to_string(p), + PatKind::TupleStruct(p, ..) | PatKind::Expr(PatExpr { kind: PatExprKind::Path(p), .. }) => { + qpath_to_string(p) + } PatKind::Or(pats) => { fmt::from_fn(|f| pats.iter().map(|p| name_from_pat(p)).joined(" | ", f)).to_string() } @@ -329,7 +330,7 @@ pub(crate) fn name_from_pat(p: &hir::Pat<'_>) -> Symbol { return Symbol::intern("()"); } PatKind::Slice(begin, mid, end) => { - fn print_pat<'a>(pat: &'a Pat<'a>, wild: bool) -> impl Display + 'a { + fn print_pat(pat: &Pat<'_>, wild: bool) -> impl Display { fmt::from_fn(move |f| { if wild { f.write_str("..")?; @@ -493,7 +494,7 @@ pub(crate) fn resolve_type(cx: &mut DocContext<'_>, path: Path) -> Type { pub(crate) fn synthesize_auto_trait_and_blanket_impls( cx: &mut DocContext<'_>, item_def_id: DefId, -) -> impl Iterator<Item = Item> { +) -> impl Iterator<Item = Item> + use<> { let auto_impls = cx .sess() .prof diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs index 522ef1af376..ea740508c58 100644 --- a/src/librustdoc/html/format.rs +++ b/src/librustdoc/html/format.rs @@ -15,7 +15,6 @@ use std::iter::{self, once}; use itertools::Either; use rustc_abi::ExternAbi; use rustc_attr_parsing::{ConstStability, StabilityLevel, StableSince}; -use rustc_data_structures::captures::Captures; use rustc_data_structures::fx::FxHashSet; use rustc_hir as hir; use rustc_hir::def::DefKind; @@ -41,10 +40,10 @@ pub(crate) fn write_str(s: &mut String, f: fmt::Arguments<'_>) { s.write_fmt(f).unwrap(); } -pub(crate) fn print_generic_bounds<'a, 'tcx: 'a>( - bounds: &'a [clean::GenericBound], - cx: &'a Context<'tcx>, -) -> impl Display + 'a + Captures<'tcx> { +pub(crate) fn print_generic_bounds( + bounds: &[clean::GenericBound], + cx: &Context<'_>, +) -> impl Display { fmt::from_fn(move |f| { let mut bounds_dup = FxHashSet::default(); @@ -57,10 +56,7 @@ pub(crate) fn print_generic_bounds<'a, 'tcx: 'a>( } impl clean::GenericParamDef { - pub(crate) fn print<'a, 'tcx: 'a>( - &'a self, - cx: &'a Context<'tcx>, - ) -> impl Display + 'a + Captures<'tcx> { + pub(crate) fn print(&self, cx: &Context<'_>) -> impl Display { fmt::from_fn(move |f| match &self.kind { clean::GenericParamDefKind::Lifetime { outlives } => { write!(f, "{}", self.name)?; @@ -80,7 +76,7 @@ impl clean::GenericParamDef { print_generic_bounds(bounds, cx).fmt(f)?; } - if let Some(ref ty) = default { + if let Some(ty) = default { f.write_str(" = ")?; ty.print(cx).fmt(f)?; } @@ -107,10 +103,7 @@ impl clean::GenericParamDef { } impl clean::Generics { - pub(crate) fn print<'a, 'tcx: 'a>( - &'a self, - cx: &'a Context<'tcx>, - ) -> impl Display + 'a + Captures<'tcx> { + pub(crate) fn print(&self, cx: &Context<'_>) -> impl Display { fmt::from_fn(move |f| { let mut real_params = self.params.iter().filter(|p| !p.is_synthetic_param()).peekable(); if real_params.peek().is_none() { @@ -134,10 +127,7 @@ pub(crate) enum Ending { NoNewline, } -fn print_where_predicate<'a, 'tcx: 'a>( - predicate: &'a clean::WherePredicate, - cx: &'a Context<'tcx>, -) -> impl Display + 'a + Captures<'tcx> { +fn print_where_predicate(predicate: &clean::WherePredicate, cx: &Context<'_>) -> impl Display { fmt::from_fn(move |f| { match predicate { clean::WherePredicate::BoundPredicate { ty, bounds, bound_params } => { @@ -173,12 +163,12 @@ fn print_where_predicate<'a, 'tcx: 'a>( /// * The Generics from which to emit a where-clause. /// * The number of spaces to indent each line with. /// * Whether the where-clause needs to add a comma and newline after the last bound. -pub(crate) fn print_where_clause<'a, 'tcx: 'a>( - gens: &'a clean::Generics, - cx: &'a Context<'tcx>, +pub(crate) fn print_where_clause( + gens: &clean::Generics, + cx: &Context<'_>, indent: usize, ending: Ending, -) -> Option<impl Display + 'a + Captures<'tcx>> { +) -> Option<impl Display> { if gens.where_predicates.is_empty() { return None; } @@ -250,13 +240,13 @@ pub(crate) fn print_where_clause<'a, 'tcx: 'a>( } impl clean::Lifetime { - pub(crate) fn print(&self) -> impl Display + '_ { + pub(crate) fn print(&self) -> impl Display { self.0.as_str() } } impl clean::ConstantKind { - pub(crate) fn print(&self, tcx: TyCtxt<'_>) -> impl Display + '_ { + pub(crate) fn print(&self, tcx: TyCtxt<'_>) -> impl Display { let expr = self.expr(tcx); fmt::from_fn(move |f| { if f.alternate() { f.write_str(&expr) } else { write!(f, "{}", Escape(&expr)) } @@ -265,7 +255,7 @@ impl clean::ConstantKind { } impl clean::PolyTrait { - fn print<'a, 'tcx: 'a>(&'a self, cx: &'a Context<'tcx>) -> impl Display + 'a + Captures<'tcx> { + fn print(&self, cx: &Context<'_>) -> impl Display { fmt::from_fn(move |f| { print_higher_ranked_params_with_space(&self.generic_params, cx, "for").fmt(f)?; self.trait_.print(cx).fmt(f) @@ -274,10 +264,7 @@ impl clean::PolyTrait { } impl clean::GenericBound { - pub(crate) fn print<'a, 'tcx: 'a>( - &'a self, - cx: &'a Context<'tcx>, - ) -> impl Display + 'a + Captures<'tcx> { + pub(crate) fn print(&self, cx: &Context<'_>) -> impl Display { fmt::from_fn(move |f| match self { clean::GenericBound::Outlives(lt) => write!(f, "{}", lt.print()), clean::GenericBound::TraitBound(ty, modifiers) => { @@ -304,7 +291,7 @@ impl clean::GenericBound { } impl clean::GenericArgs { - fn print<'a, 'tcx: 'a>(&'a self, cx: &'a Context<'tcx>) -> impl Display + 'a + Captures<'tcx> { + fn print(&self, cx: &Context<'_>) -> impl Display { fmt::from_fn(move |f| { match self { clean::GenericArgs::AngleBracketed { args, constraints } => { @@ -809,11 +796,11 @@ fn primitive_link_fragment( Ok(()) } -fn tybounds<'a, 'tcx: 'a>( - bounds: &'a [clean::PolyTrait], - lt: &'a Option<clean::Lifetime>, - cx: &'a Context<'tcx>, -) -> impl Display + 'a + Captures<'tcx> { +fn tybounds( + bounds: &[clean::PolyTrait], + lt: &Option<clean::Lifetime>, + cx: &Context<'_>, +) -> impl Display { fmt::from_fn(move |f| { bounds.iter().map(|bound| bound.print(cx)).joined(" + ", f)?; if let Some(lt) = lt { @@ -825,11 +812,11 @@ fn tybounds<'a, 'tcx: 'a>( }) } -fn print_higher_ranked_params_with_space<'a, 'tcx: 'a>( - params: &'a [clean::GenericParamDef], - cx: &'a Context<'tcx>, +fn print_higher_ranked_params_with_space( + params: &[clean::GenericParamDef], + cx: &Context<'_>, keyword: &'static str, -) -> impl Display + 'a + Captures<'tcx> { +) -> impl Display { fmt::from_fn(move |f| { if !params.is_empty() { f.write_str(keyword)?; @@ -841,11 +828,7 @@ fn print_higher_ranked_params_with_space<'a, 'tcx: 'a>( }) } -pub(crate) fn anchor<'a: 'cx, 'cx>( - did: DefId, - text: Symbol, - cx: &'cx Context<'a>, -) -> impl Display + Captures<'a> + 'cx { +pub(crate) fn anchor(did: DefId, text: Symbol, cx: &Context<'_>) -> impl Display { fmt::from_fn(move |f| { let parts = href(did, cx); if let Ok((url, short_ty, fqp)) = parts { @@ -1121,29 +1104,19 @@ fn fmt_type( } impl clean::Type { - pub(crate) fn print<'b, 'a: 'b, 'tcx: 'a>( - &'a self, - cx: &'a Context<'tcx>, - ) -> impl Display + 'b + Captures<'tcx> { + pub(crate) fn print(&self, cx: &Context<'_>) -> impl Display { fmt::from_fn(move |f| fmt_type(self, f, false, cx)) } } impl clean::Path { - pub(crate) fn print<'b, 'a: 'b, 'tcx: 'a>( - &'a self, - cx: &'a Context<'tcx>, - ) -> impl Display + 'b + Captures<'tcx> { + pub(crate) fn print(&self, cx: &Context<'_>) -> impl Display { fmt::from_fn(move |f| resolved_path(f, self.def_id(), self, false, false, cx)) } } impl clean::Impl { - pub(crate) fn print<'a, 'tcx: 'a>( - &'a self, - use_absolute: bool, - cx: &'a Context<'tcx>, - ) -> impl Display + 'a + Captures<'tcx> { + pub(crate) fn print(&self, use_absolute: bool, cx: &Context<'_>) -> impl Display { fmt::from_fn(move |f| { f.write_str("impl")?; self.generics.print(cx).fmt(f)?; @@ -1182,12 +1155,12 @@ impl clean::Impl { print_where_clause(&self.generics, cx, 0, Ending::Newline).maybe_display().fmt(f) }) } - fn print_type<'a, 'tcx: 'a>( + fn print_type( &self, type_: &clean::Type, f: &mut fmt::Formatter<'_>, use_absolute: bool, - cx: &'a Context<'tcx>, + cx: &Context<'_>, ) -> Result<(), fmt::Error> { if let clean::Type::Tuple(types) = type_ && let [clean::Type::Generic(name)] = &types[..] @@ -1258,10 +1231,7 @@ impl clean::Impl { } impl clean::Arguments { - pub(crate) fn print<'a, 'tcx: 'a>( - &'a self, - cx: &'a Context<'tcx>, - ) -> impl Display + 'a + Captures<'tcx> { + pub(crate) fn print(&self, cx: &Context<'_>) -> impl Display { fmt::from_fn(move |f| { self.values .iter() @@ -1301,10 +1271,7 @@ impl Display for Indent { } impl clean::FnDecl { - pub(crate) fn print<'b, 'a: 'b, 'tcx: 'a>( - &'a self, - cx: &'a Context<'tcx>, - ) -> impl Display + 'b + Captures<'tcx> { + pub(crate) fn print(&self, cx: &Context<'_>) -> impl Display { fmt::from_fn(move |f| { let ellipsis = if self.c_variadic { ", ..." } else { "" }; if f.alternate() { @@ -1333,12 +1300,12 @@ impl clean::FnDecl { /// are preserved. /// * `indent`: The number of spaces to indent each successive line with, if line-wrapping is /// necessary. - pub(crate) fn full_print<'a, 'tcx: 'a>( - &'a self, + pub(crate) fn full_print( + &self, header_len: usize, indent: usize, - cx: &'a Context<'tcx>, - ) -> impl Display + 'a + Captures<'tcx> { + cx: &Context<'_>, + ) -> impl Display { fmt::from_fn(move |f| { // First, generate the text form of the declaration, with no line wrapping, and count the bytes. let mut counter = WriteCounter(0); @@ -1420,10 +1387,7 @@ impl clean::FnDecl { self.print_output(cx).fmt(f) } - fn print_output<'a, 'tcx: 'a>( - &'a self, - cx: &'a Context<'tcx>, - ) -> impl Display + 'a + Captures<'tcx> { + fn print_output(&self, cx: &Context<'_>) -> impl Display { fmt::from_fn(move |f| match &self.output { clean::Tuple(tys) if tys.is_empty() => Ok(()), ty if f.alternate() => { @@ -1434,10 +1398,7 @@ impl clean::FnDecl { } } -pub(crate) fn visibility_print_with_space<'a, 'tcx: 'a>( - item: &clean::Item, - cx: &'a Context<'tcx>, -) -> impl Display + 'a + Captures<'tcx> { +pub(crate) fn visibility_print_with_space(item: &clean::Item, cx: &Context<'_>) -> impl Display { use std::fmt::Write as _; let vis: Cow<'static, str> = match item.visibility(cx.tcx()) { None => "".into(), @@ -1546,10 +1507,7 @@ pub(crate) fn print_constness_with_space( } impl clean::Import { - pub(crate) fn print<'a, 'tcx: 'a>( - &'a self, - cx: &'a Context<'tcx>, - ) -> impl Display + 'a + Captures<'tcx> { + pub(crate) fn print(&self, cx: &Context<'_>) -> impl Display { fmt::from_fn(move |f| match self.kind { clean::ImportKind::Simple(name) => { if name == self.source.path.last() { @@ -1570,10 +1528,7 @@ impl clean::Import { } impl clean::ImportSource { - pub(crate) fn print<'a, 'tcx: 'a>( - &'a self, - cx: &'a Context<'tcx>, - ) -> impl Display + 'a + Captures<'tcx> { + pub(crate) fn print(&self, cx: &Context<'_>) -> impl Display { fmt::from_fn(move |f| match self.did { Some(did) => resolved_path(f, did, &self.path, true, false, cx), _ => { @@ -1593,10 +1548,7 @@ impl clean::ImportSource { } impl clean::AssocItemConstraint { - pub(crate) fn print<'a, 'tcx: 'a>( - &'a self, - cx: &'a Context<'tcx>, - ) -> impl Display + 'a + Captures<'tcx> { + pub(crate) fn print(&self, cx: &Context<'_>) -> impl Display { fmt::from_fn(move |f| { f.write_str(self.assoc.name.as_str())?; self.assoc.args.print(cx).fmt(f)?; @@ -1627,15 +1579,12 @@ pub(crate) fn print_abi_with_space(abi: ExternAbi) -> impl Display { }) } -pub(crate) fn print_default_space<'a>(v: bool) -> &'a str { +pub(crate) fn print_default_space(v: bool) -> &'static str { if v { "default " } else { "" } } impl clean::GenericArg { - pub(crate) fn print<'a, 'tcx: 'a>( - &'a self, - cx: &'a Context<'tcx>, - ) -> impl Display + 'a + Captures<'tcx> { + pub(crate) fn print(&self, cx: &Context<'_>) -> impl Display { fmt::from_fn(move |f| match self { clean::GenericArg::Lifetime(lt) => lt.print().fmt(f), clean::GenericArg::Type(ty) => ty.print(cx).fmt(f), @@ -1646,10 +1595,7 @@ impl clean::GenericArg { } impl clean::Term { - pub(crate) fn print<'a, 'tcx: 'a>( - &'a self, - cx: &'a Context<'tcx>, - ) -> impl Display + 'a + Captures<'tcx> { + pub(crate) fn print(&self, cx: &Context<'_>) -> impl Display { fmt::from_fn(move |f| match self { clean::Term::Type(ty) => ty.print(cx).fmt(f), clean::Term::Constant(ct) => ct.print(cx.tcx()).fmt(f), diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs index bd4af359404..b2ad2fa773a 100644 --- a/src/librustdoc/html/render/mod.rs +++ b/src/librustdoc/html/render/mod.rs @@ -47,7 +47,6 @@ use rinja::Template; use rustc_attr_parsing::{ ConstStability, DeprecatedSince, Deprecation, RustcVersion, StabilityLevel, StableSince, }; -use rustc_data_structures::captures::Captures; use rustc_data_structures::fx::{FxHashSet, FxIndexMap, FxIndexSet}; use rustc_hir::Mutability; use rustc_hir::def_id::{DefId, DefIdSet}; @@ -82,7 +81,7 @@ use crate::html::{highlight, sources}; use crate::scrape_examples::{CallData, CallLocation}; use crate::{DOC_RUST_LANG_ORG_VERSION, try_none}; -pub(crate) fn ensure_trailing_slash(v: &str) -> impl fmt::Display + '_ { +pub(crate) fn ensure_trailing_slash(v: &str) -> impl fmt::Display { fmt::from_fn(move |f| { if !v.ends_with('/') && !v.is_empty() { write!(f, "{v}/") } else { f.write_str(v) } }) @@ -310,7 +309,7 @@ impl ItemEntry { } impl ItemEntry { - pub(crate) fn print(&self) -> impl fmt::Display + '_ { + pub(crate) fn print(&self) -> impl fmt::Display { fmt::from_fn(move |f| write!(f, "<a href=\"{}\">{}</a>", self.url, Escape(&self.name))) } } @@ -505,12 +504,12 @@ fn scrape_examples_help(shared: &SharedContext<'_>) -> String { ) } -fn document<'a, 'cx: 'a>( - cx: &'a Context<'cx>, - item: &'a clean::Item, - parent: Option<&'a clean::Item>, +fn document( + cx: &Context<'_>, + item: &clean::Item, + parent: Option<&clean::Item>, heading_offset: HeadingOffset, -) -> impl fmt::Display + 'a + Captures<'cx> { +) -> impl fmt::Display { if let Some(ref name) = item.name { info!("Documenting {name}"); } @@ -526,12 +525,12 @@ fn document<'a, 'cx: 'a>( } /// Render md_text as markdown. -fn render_markdown<'a, 'cx: 'a>( - cx: &'a Context<'cx>, - md_text: &'a str, +fn render_markdown( + cx: &Context<'_>, + md_text: &str, links: Vec<RenderedLink>, heading_offset: HeadingOffset, -) -> impl fmt::Display + 'a + Captures<'cx> { +) -> impl fmt::Display { fmt::from_fn(move |f| { write!( f, @@ -552,13 +551,13 @@ fn render_markdown<'a, 'cx: 'a>( /// Writes a documentation block containing only the first paragraph of the documentation. If the /// docs are longer, a "Read more" link is appended to the end. -fn document_short<'a, 'cx: 'a>( - item: &'a clean::Item, - cx: &'a Context<'cx>, - link: AssocItemLink<'a>, - parent: &'a clean::Item, +fn document_short( + item: &clean::Item, + cx: &Context<'_>, + link: AssocItemLink<'_>, + parent: &clean::Item, show_def_docs: bool, -) -> impl fmt::Display + 'a + Captures<'cx> { +) -> impl fmt::Display { fmt::from_fn(move |f| { document_item_info(cx, item, Some(parent)).render_into(f).unwrap(); if !show_def_docs { @@ -595,28 +594,28 @@ fn document_short<'a, 'cx: 'a>( }) } -fn document_full_collapsible<'a, 'cx: 'a>( - item: &'a clean::Item, - cx: &'a Context<'cx>, +fn document_full_collapsible( + item: &clean::Item, + cx: &Context<'_>, heading_offset: HeadingOffset, -) -> impl fmt::Display + 'a + Captures<'cx> { +) -> impl fmt::Display { document_full_inner(item, cx, true, heading_offset) } -fn document_full<'a, 'cx: 'a>( - item: &'a clean::Item, - cx: &'a Context<'cx>, +fn document_full( + item: &clean::Item, + cx: &Context<'_>, heading_offset: HeadingOffset, -) -> impl fmt::Display + 'a + Captures<'cx> { +) -> impl fmt::Display { document_full_inner(item, cx, false, heading_offset) } -fn document_full_inner<'a, 'cx: 'a>( - item: &'a clean::Item, - cx: &'a Context<'cx>, +fn document_full_inner( + item: &clean::Item, + cx: &Context<'_>, is_collapsible: bool, heading_offset: HeadingOffset, -) -> impl fmt::Display + 'a + Captures<'cx> { +) -> impl fmt::Display { fmt::from_fn(move |f| { if let Some(s) = item.opt_doc_value() { debug!("Doc block: =====\n{s}\n====="); @@ -797,11 +796,11 @@ pub(crate) fn render_impls( } /// Build a (possibly empty) `href` attribute (a key-value pair) for the given associated item. -fn assoc_href_attr<'a, 'tcx>( +fn assoc_href_attr( it: &clean::Item, - link: AssocItemLink<'a>, - cx: &Context<'tcx>, -) -> Option<impl fmt::Display + 'a + Captures<'tcx>> { + link: AssocItemLink<'_>, + cx: &Context<'_>, +) -> Option<impl fmt::Display> { let name = it.name.unwrap(); let item_type = it.type_(); @@ -812,7 +811,7 @@ fn assoc_href_attr<'a, 'tcx>( } let href = match link { - AssocItemLink::Anchor(Some(ref id)) => Href::AnchorId(id), + AssocItemLink::Anchor(Some(id)) => Href::AnchorId(id), AssocItemLink::Anchor(None) => Href::Anchor(item_type), AssocItemLink::GotoSource(did, provided_methods) => { // We're creating a link from the implementation of an associated item to its @@ -877,15 +876,15 @@ enum AssocConstValue<'a> { None, } -fn assoc_const<'a, 'tcx>( - it: &'a clean::Item, - generics: &'a clean::Generics, - ty: &'a clean::Type, - value: AssocConstValue<'a>, - link: AssocItemLink<'a>, +fn assoc_const( + it: &clean::Item, + generics: &clean::Generics, + ty: &clean::Type, + value: AssocConstValue<'_>, + link: AssocItemLink<'_>, indent: usize, - cx: &'a Context<'tcx>, -) -> impl fmt::Display + 'a + Captures<'tcx> { + cx: &Context<'_>, +) -> impl fmt::Display { let tcx = cx.tcx(); fmt::from_fn(move |w| { write!( @@ -917,15 +916,15 @@ fn assoc_const<'a, 'tcx>( }) } -fn assoc_type<'a, 'tcx>( - it: &'a clean::Item, - generics: &'a clean::Generics, - bounds: &'a [clean::GenericBound], - default: Option<&'a clean::Type>, - link: AssocItemLink<'a>, +fn assoc_type( + it: &clean::Item, + generics: &clean::Generics, + bounds: &[clean::GenericBound], + default: Option<&clean::Type>, + link: AssocItemLink<'_>, indent: usize, - cx: &'a Context<'tcx>, -) -> impl fmt::Display + 'a + Captures<'tcx> { + cx: &Context<'_>, +) -> impl fmt::Display { fmt::from_fn(move |w| { write!( w, @@ -947,15 +946,15 @@ fn assoc_type<'a, 'tcx>( }) } -fn assoc_method<'a, 'tcx>( - meth: &'a clean::Item, - g: &'a clean::Generics, - d: &'a clean::FnDecl, - link: AssocItemLink<'a>, +fn assoc_method( + meth: &clean::Item, + g: &clean::Generics, + d: &clean::FnDecl, + link: AssocItemLink<'_>, parent: ItemType, - cx: &'a Context<'tcx>, + cx: &Context<'_>, render_mode: RenderMode, -) -> impl fmt::Display + 'a + Captures<'tcx> { +) -> impl fmt::Display { let tcx = cx.tcx(); let header = meth.fn_header(tcx).expect("Trying to get header from a non-function item"); let name = meth.name.as_ref().unwrap(); @@ -1031,7 +1030,7 @@ fn render_stability_since_raw_with_extra( stable_version: Option<StableSince>, const_stability: Option<ConstStability>, extra_class: &str, -) -> Option<impl fmt::Display + '_> { +) -> Option<impl fmt::Display> { let mut title = String::new(); let mut stability = String::new(); @@ -1102,13 +1101,13 @@ fn render_stability_since_raw( render_stability_since_raw_with_extra(ver, const_stability, "") } -fn render_assoc_item<'a, 'tcx>( - item: &'a clean::Item, - link: AssocItemLink<'a>, +fn render_assoc_item( + item: &clean::Item, + link: AssocItemLink<'_>, parent: ItemType, - cx: &'a Context<'tcx>, + cx: &Context<'_>, render_mode: RenderMode, -) -> impl fmt::Display + 'a + Captures<'tcx> { +) -> impl fmt::Display { fmt::from_fn(move |f| match &item.kind { clean::StrippedItem(..) => Ok(()), clean::RequiredMethodItem(m) | clean::MethodItem(m, _) => { @@ -1144,7 +1143,7 @@ fn render_assoc_item<'a, 'tcx>( cx, ) .fmt(f), - clean::RequiredAssocTypeItem(ref generics, ref bounds) => assoc_type( + clean::RequiredAssocTypeItem(generics, bounds) => assoc_type( item, generics, bounds, @@ -1154,7 +1153,7 @@ fn render_assoc_item<'a, 'tcx>( cx, ) .fmt(f), - clean::AssocTypeItem(ref ty, ref bounds) => assoc_type( + clean::AssocTypeItem(ty, bounds) => assoc_type( item, &ty.generics, bounds, @@ -1170,11 +1169,7 @@ fn render_assoc_item<'a, 'tcx>( // When an attribute is rendered inside a `<pre>` tag, it is formatted using // a whitespace prefix and newline. -fn render_attributes_in_pre<'a, 'tcx: 'a>( - it: &'a clean::Item, - prefix: &'a str, - cx: &'a Context<'tcx>, -) -> impl fmt::Display + Captures<'a> + Captures<'tcx> { +fn render_attributes_in_pre(it: &clean::Item, prefix: &str, cx: &Context<'_>) -> impl fmt::Display { fmt::from_fn(move |f| { for a in it.attributes(cx.tcx(), cx.cache(), false) { writeln!(f, "{prefix}{a}")?; @@ -1206,12 +1201,12 @@ impl<'a> AssocItemLink<'a> { } } -pub fn write_section_heading<'a>( - title: &'a str, - id: &'a str, - extra_class: Option<&'a str>, - extra: impl fmt::Display + 'a, -) -> impl fmt::Display + 'a { +pub fn write_section_heading( + title: &str, + id: &str, + extra_class: Option<&str>, + extra: impl fmt::Display, +) -> impl fmt::Display { fmt::from_fn(move |w| { let (extra_class, whitespace) = match extra_class { Some(extra) => (extra, " "), @@ -1227,7 +1222,7 @@ pub fn write_section_heading<'a>( }) } -fn write_impl_section_heading<'a>(title: &'a str, id: &'a str) -> impl fmt::Display + 'a { +fn write_impl_section_heading(title: &str, id: &str) -> impl fmt::Display { write_section_heading(title, id, None, "") } @@ -1276,12 +1271,12 @@ pub(crate) fn render_all_impls( } } -fn render_assoc_items<'a, 'cx: 'a>( - cx: &'a Context<'cx>, - containing_item: &'a clean::Item, +fn render_assoc_items( + cx: &Context<'_>, + containing_item: &clean::Item, it: DefId, - what: AssocItemRender<'a>, -) -> impl fmt::Display + 'a + Captures<'cx> { + what: AssocItemRender<'_>, +) -> impl fmt::Display { fmt::from_fn(move |f| { let mut derefs = DefIdSet::default(); derefs.insert(it); @@ -1466,10 +1461,10 @@ fn should_render_item(item: &clean::Item, deref_mut_: bool, tcx: TyCtxt<'_>) -> } } -pub(crate) fn notable_traits_button<'a, 'tcx>( - ty: &'a clean::Type, - cx: &'a Context<'tcx>, -) -> Option<impl fmt::Display + 'a + Captures<'tcx>> { +pub(crate) fn notable_traits_button( + ty: &clean::Type, + cx: &Context<'_>, +) -> Option<impl fmt::Display> { let mut has_notable_trait = false; if ty.is_unit() { @@ -1623,16 +1618,16 @@ struct ImplRenderingParameters { toggle_open_by_default: bool, } -fn render_impl<'a, 'tcx>( - cx: &'a Context<'tcx>, - i: &'a Impl, - parent: &'a clean::Item, - link: AssocItemLink<'a>, +fn render_impl( + cx: &Context<'_>, + i: &Impl, + parent: &clean::Item, + link: AssocItemLink<'_>, render_mode: RenderMode, use_absolute: Option<bool>, - aliases: &'a [String], + aliases: &[String], rendering_params: ImplRenderingParameters, -) -> impl fmt::Display + 'a + Captures<'tcx> { +) -> impl fmt::Display { fmt::from_fn(move |w| { let cache = &cx.shared.cache; let traits = &cache.traits; @@ -1780,7 +1775,7 @@ fn render_impl<'a, 'tcx>( ); } } - clean::RequiredAssocConstItem(ref generics, ref ty) => { + clean::RequiredAssocConstItem(generics, ty) => { let source_id = format!("{item_type}.{name}"); let id = cx.derive_id(&source_id); write_str( @@ -1847,7 +1842,7 @@ fn render_impl<'a, 'tcx>( ), ); } - clean::RequiredAssocTypeItem(ref generics, ref bounds) => { + clean::RequiredAssocTypeItem(generics, bounds) => { let source_id = format!("{item_type}.{name}"); let id = cx.derive_id(&source_id); write_str( @@ -2135,11 +2130,11 @@ fn render_impl<'a, 'tcx>( // Render the items that appear on the right side of methods, impls, and // associated types. For example "1.0.0 (const: 1.39.0) · source". -fn render_rightside<'a, 'tcx>( - cx: &'a Context<'tcx>, - item: &'a clean::Item, +fn render_rightside( + cx: &Context<'_>, + item: &clean::Item, render_mode: RenderMode, -) -> impl fmt::Display + 'a + Captures<'tcx> { +) -> impl fmt::Display { let tcx = cx.tcx(); fmt::from_fn(move |w| { @@ -2174,17 +2169,17 @@ fn render_rightside<'a, 'tcx>( }) } -pub(crate) fn render_impl_summary<'a, 'tcx>( - cx: &'a Context<'tcx>, - i: &'a Impl, - parent: &'a clean::Item, +pub(crate) fn render_impl_summary( + cx: &Context<'_>, + i: &Impl, + parent: &clean::Item, show_def_docs: bool, use_absolute: Option<bool>, // This argument is used to reference same type with different paths to avoid duplication // in documentation pages for trait with automatic implementations like "Send" and "Sync". - aliases: &'a [String], - doc: Option<&'a str>, -) -> impl fmt::Display + 'a + Captures<'tcx> { + aliases: &[String], + doc: Option<&str>, +) -> impl fmt::Display { fmt::from_fn(move |w| { let inner_impl = i.inner_impl(); let id = cx.derive_id(get_id_for_impl(cx.tcx(), i.impl_item.item_id)); diff --git a/src/librustdoc/html/render/print_item.rs b/src/librustdoc/html/render/print_item.rs index b647b2aad75..c599a84ee44 100644 --- a/src/librustdoc/html/render/print_item.rs +++ b/src/librustdoc/html/render/print_item.rs @@ -4,7 +4,6 @@ use std::fmt::{Display, Write as _}; use rinja::Template; use rustc_abi::VariantIdx; -use rustc_data_structures::captures::Captures; use rustc_data_structures::fx::{FxHashMap, FxIndexSet}; use rustc_hir as hir; use rustc_hir::def::CtorKind; @@ -92,44 +91,32 @@ macro_rules! item_template { macro_rules! item_template_methods { () => {}; (document $($rest:tt)*) => { - fn document<'b>(&'b self) -> impl fmt::Display + Captures<'a> + 'b + Captures<'cx> { - fmt::from_fn(move |f| { - let (item, cx) = self.item_and_cx(); - let v = document(cx, item, None, HeadingOffset::H2); - write!(f, "{v}") - }) + fn document(&self) -> impl fmt::Display { + let (item, cx) = self.item_and_cx(); + document(cx, item, None, HeadingOffset::H2) } item_template_methods!($($rest)*); }; (document_type_layout $($rest:tt)*) => { - fn document_type_layout<'b>(&'b self) -> impl fmt::Display + Captures<'a> + 'b + Captures<'cx> { - fmt::from_fn(move |f| { - let (item, cx) = self.item_and_cx(); - let def_id = item.item_id.expect_def_id(); - let v = document_type_layout(cx, def_id); - write!(f, "{v}") - }) + fn document_type_layout(&self) -> impl fmt::Display { + let (item, cx) = self.item_and_cx(); + let def_id = item.item_id.expect_def_id(); + document_type_layout(cx, def_id) } item_template_methods!($($rest)*); }; (render_attributes_in_pre $($rest:tt)*) => { - fn render_attributes_in_pre<'b>(&'b self) -> impl fmt::Display + Captures<'a> + 'b + Captures<'cx> { - fmt::from_fn(move |f| { - let (item, cx) = self.item_and_cx(); - let v = render_attributes_in_pre(item, "", cx); - write!(f, "{v}") - }) + fn render_attributes_in_pre(&self) -> impl fmt::Display { + let (item, cx) = self.item_and_cx(); + render_attributes_in_pre(item, "", cx) } item_template_methods!($($rest)*); }; (render_assoc_items $($rest:tt)*) => { - fn render_assoc_items<'b>(&'b self) -> impl fmt::Display + Captures<'a> + 'b + Captures<'cx> { - fmt::from_fn(move |f| { - let (item, cx) = self.item_and_cx(); - let def_id = item.item_id.expect_def_id(); - let v = render_assoc_items(cx, item, def_id, AssocItemRender::All); - write!(f, "{v}") - }) + fn render_assoc_items(&self) -> impl fmt::Display { + let (item, cx) = self.item_and_cx(); + let def_id = item.item_id.expect_def_id(); + render_assoc_items(cx, item, def_id, AssocItemRender::All) } item_template_methods!($($rest)*); }; @@ -162,10 +149,7 @@ struct ItemVars<'a> { src_href: Option<&'a str>, } -pub(super) fn print_item<'a, 'tcx>( - cx: &'a Context<'tcx>, - item: &'a clean::Item, -) -> impl fmt::Display + 'a + Captures<'tcx> { +pub(super) fn print_item(cx: &Context<'_>, item: &clean::Item) -> impl fmt::Display { debug_assert!(!item.is_stripped()); fmt::from_fn(|buf| { @@ -241,30 +225,30 @@ pub(super) fn print_item<'a, 'tcx>( item_vars.render_into(buf).unwrap(); match &item.kind { - clean::ModuleItem(ref m) => { + clean::ModuleItem(m) => { write!(buf, "{}", item_module(cx, item, &m.items)) } - clean::FunctionItem(ref f) | clean::ForeignFunctionItem(ref f, _) => { + clean::FunctionItem(f) | clean::ForeignFunctionItem(f, _) => { write!(buf, "{}", item_function(cx, item, f)) } - clean::TraitItem(ref t) => write!(buf, "{}", item_trait(cx, item, t)), - clean::StructItem(ref s) => { + clean::TraitItem(t) => write!(buf, "{}", item_trait(cx, item, t)), + clean::StructItem(s) => { write!(buf, "{}", item_struct(cx, item, s)) } - clean::UnionItem(ref s) => write!(buf, "{}", item_union(cx, item, s)), - clean::EnumItem(ref e) => write!(buf, "{}", item_enum(cx, item, e)), - clean::TypeAliasItem(ref t) => { + clean::UnionItem(s) => write!(buf, "{}", item_union(cx, item, s)), + clean::EnumItem(e) => write!(buf, "{}", item_enum(cx, item, e)), + clean::TypeAliasItem(t) => { write!(buf, "{}", item_type_alias(cx, item, t)) } - clean::MacroItem(ref m) => write!(buf, "{}", item_macro(cx, item, m)), - clean::ProcMacroItem(ref m) => { + clean::MacroItem(m) => write!(buf, "{}", item_macro(cx, item, m)), + clean::ProcMacroItem(m) => { write!(buf, "{}", item_proc_macro(cx, item, m)) } clean::PrimitiveItem(_) => write!(buf, "{}", item_primitive(cx, item)), - clean::StaticItem(ref i) => { + clean::StaticItem(i) => { write!(buf, "{}", item_static(cx, item, i, None)) } - clean::ForeignStaticItem(ref i, safety) => { + clean::ForeignStaticItem(i, safety) => { write!(buf, "{}", item_static(cx, item, i, Some(*safety))) } clean::ConstantItem(ci) => { @@ -274,7 +258,7 @@ pub(super) fn print_item<'a, 'tcx>( write!(buf, "{}", item_foreign_type(cx, item)) } clean::KeywordItem => write!(buf, "{}", item_keyword(cx, item)), - clean::TraitAliasItem(ref ta) => { + clean::TraitAliasItem(ta) => { write!(buf, "{}", item_trait_alias(cx, item, ta)) } _ => { @@ -321,11 +305,7 @@ trait ItemTemplate<'a, 'cx: 'a>: rinja::Template + Display { fn item_and_cx(&self) -> (&'a clean::Item, &'a Context<'cx>); } -fn item_module<'a, 'tcx>( - cx: &'a Context<'tcx>, - item: &'a clean::Item, - items: &'a [clean::Item], -) -> impl fmt::Display + 'a + Captures<'tcx> { +fn item_module(cx: &Context<'_>, item: &clean::Item, items: &[clean::Item]) -> impl fmt::Display { fmt::from_fn(|w| { write!(w, "{}", document(cx, item, None, HeadingOffset::H2))?; @@ -541,14 +521,14 @@ fn item_module<'a, 'tcx>( /// Render the stability, deprecation and portability tags that are displayed in the item's summary /// at the module level. -fn extra_info_tags<'a, 'tcx: 'a>( - tcx: TyCtxt<'tcx>, - item: &'a clean::Item, - parent: &'a clean::Item, +fn extra_info_tags( + tcx: TyCtxt<'_>, + item: &clean::Item, + parent: &clean::Item, import_def_id: Option<DefId>, -) -> impl Display + 'a + Captures<'tcx> { +) -> impl Display { fmt::from_fn(move |f| { - fn tag_html<'a>(class: &'a str, title: &'a str, contents: &'a str) -> impl Display + 'a { + fn tag_html(class: &str, title: &str, contents: &str) -> impl Display { fmt::from_fn(move |f| { write!( f, @@ -597,11 +577,7 @@ fn extra_info_tags<'a, 'tcx: 'a>( }) } -fn item_function<'a, 'tcx>( - cx: &'a Context<'tcx>, - it: &'a clean::Item, - f: &'a clean::Function, -) -> impl fmt::Display + 'a + Captures<'tcx> { +fn item_function(cx: &Context<'_>, it: &clean::Item, f: &clean::Function) -> impl fmt::Display { fmt::from_fn(|w| { let tcx = cx.tcx(); let header = it.fn_header(tcx).expect("printing a function which isn't a function"); @@ -657,11 +633,7 @@ fn item_function<'a, 'tcx>( }) } -fn item_trait<'a, 'tcx>( - cx: &'a Context<'tcx>, - it: &'a clean::Item, - t: &'a clean::Trait, -) -> impl fmt::Display + 'a + Captures<'tcx> { +fn item_trait(cx: &Context<'_>, it: &clean::Item, t: &clean::Trait) -> impl fmt::Display { fmt::from_fn(|w| { let tcx = cx.tcx(); let bounds = bounds(&t.bounds, false, cx); @@ -831,11 +803,7 @@ fn item_trait<'a, 'tcx>( // Trait documentation write!(w, "{}", document(cx, it, None, HeadingOffset::H2))?; - fn trait_item<'a, 'tcx>( - cx: &'a Context<'tcx>, - m: &'a clean::Item, - t: &'a clean::Item, - ) -> impl fmt::Display + 'a + Captures<'tcx> { + fn trait_item(cx: &Context<'_>, m: &clean::Item, t: &clean::Item) -> impl fmt::Display { fmt::from_fn(|w| { let name = m.name.unwrap(); info!("Documenting {name} on {ty_name:?}", ty_name = t.name); @@ -1021,7 +989,7 @@ fn item_trait<'a, 'tcx>( extern_crates.insert(did.krate); } match implementor.inner_impl().for_.without_borrowed_ref() { - clean::Type::Path { ref path } if !path.is_assoc_ty() => { + clean::Type::Path { path } if !path.is_assoc_ty() => { let did = path.def_id(); let &mut (prev_did, ref mut has_duplicates) = implementor_dups.entry(path.last()).or_insert((did, false)); @@ -1254,11 +1222,11 @@ fn item_trait<'a, 'tcx>( }) } -fn item_trait_alias<'a, 'tcx>( - cx: &'a Context<'tcx>, - it: &'a clean::Item, - t: &'a clean::TraitAlias, -) -> impl fmt::Display + 'a + Captures<'tcx> { +fn item_trait_alias( + cx: &Context<'_>, + it: &clean::Item, + t: &clean::TraitAlias, +) -> impl fmt::Display { fmt::from_fn(|w| { wrap_item(w, |w| { write!( @@ -1285,11 +1253,7 @@ fn item_trait_alias<'a, 'tcx>( }) } -fn item_type_alias<'a, 'tcx>( - cx: &'a Context<'tcx>, - it: &'a clean::Item, - t: &'a clean::TypeAlias, -) -> impl fmt::Display + 'a + Captures<'tcx> { +fn item_type_alias(cx: &Context<'_>, it: &clean::Item, t: &clean::TypeAlias) -> impl fmt::Display { fmt::from_fn(|w| { wrap_item(w, |w| { write!( @@ -1499,11 +1463,7 @@ fn item_type_alias<'a, 'tcx>( }) } -fn item_union<'a, 'tcx>( - cx: &'a Context<'tcx>, - it: &'a clean::Item, - s: &'a clean::Union, -) -> impl fmt::Display + 'a + Captures<'tcx> { +fn item_union(cx: &Context<'_>, it: &clean::Item, s: &clean::Union) -> impl fmt::Display { item_template!( #[template(path = "item_union.html")] struct ItemUnion<'a, 'cx> { @@ -1515,35 +1475,20 @@ fn item_union<'a, 'tcx>( ); impl<'a, 'cx: 'a> ItemUnion<'a, 'cx> { - fn render_union<'b>(&'b self) -> impl Display + Captures<'a> + 'b + Captures<'cx> { - fmt::from_fn(move |f| { - let v = render_union(self.it, Some(&self.s.generics), &self.s.fields, self.cx); - write!(f, "{v}") - }) + fn render_union(&self) -> impl Display { + render_union(self.it, Some(&self.s.generics), &self.s.fields, self.cx) } - fn document_field<'b>( - &'b self, - field: &'a clean::Item, - ) -> impl Display + Captures<'a> + 'b + Captures<'cx> { - fmt::from_fn(move |f| { - let v = document(self.cx, field, Some(self.it), HeadingOffset::H3); - write!(f, "{v}") - }) + fn document_field(&self, field: &'a clean::Item) -> impl Display { + document(self.cx, field, Some(self.it), HeadingOffset::H3) } fn stability_field(&self, field: &clean::Item) -> Option<String> { field.stability_class(self.cx.tcx()) } - fn print_ty<'b>( - &'b self, - ty: &'a clean::Type, - ) -> impl Display + Captures<'a> + 'b + Captures<'cx> { - fmt::from_fn(move |f| { - let v = ty.print(self.cx); - write!(f, "{v}") - }) + fn print_ty(&self, ty: &'a clean::Type) -> impl Display { + ty.print(self.cx) } fn fields_iter( @@ -1566,10 +1511,7 @@ fn item_union<'a, 'tcx>( }) } -fn print_tuple_struct_fields<'a, 'cx: 'a>( - cx: &'a Context<'cx>, - s: &'a [clean::Item], -) -> impl Display + 'a + Captures<'cx> { +fn print_tuple_struct_fields(cx: &Context<'_>, s: &[clean::Item]) -> impl Display { fmt::from_fn(|f| { if !s.is_empty() && s.iter().all(|field| { @@ -1591,11 +1533,7 @@ fn print_tuple_struct_fields<'a, 'cx: 'a>( }) } -fn item_enum<'a, 'tcx>( - cx: &'a Context<'tcx>, - it: &'a clean::Item, - e: &'a clean::Enum, -) -> impl fmt::Display + 'a + Captures<'tcx> { +fn item_enum(cx: &Context<'_>, it: &clean::Item, e: &clean::Enum) -> impl fmt::Display { fmt::from_fn(|w| { let count_variants = e.variants().count(); wrap_item(w, |w| { @@ -1658,14 +1596,14 @@ fn should_show_enum_discriminant( repr.c() || repr.int.is_some() } -fn display_c_like_variant<'a, 'tcx>( - cx: &'a Context<'tcx>, - item: &'a clean::Item, - variant: &'a clean::Variant, +fn display_c_like_variant( + cx: &Context<'_>, + item: &clean::Item, + variant: &clean::Variant, index: VariantIdx, should_show_enum_discriminant: bool, enum_def_id: DefId, -) -> impl fmt::Display + 'a + Captures<'tcx> { +) -> impl fmt::Display { fmt::from_fn(move |w| { let name = item.name.unwrap(); if let Some(ref value) = variant.discriminant { @@ -1685,15 +1623,15 @@ fn display_c_like_variant<'a, 'tcx>( }) } -fn render_enum_fields<'a, 'tcx>( - cx: &'a Context<'tcx>, - g: Option<&'a clean::Generics>, - variants: &'a IndexVec<VariantIdx, clean::Item>, +fn render_enum_fields( + cx: &Context<'_>, + g: Option<&clean::Generics>, + variants: &IndexVec<VariantIdx, clean::Item>, count_variants: usize, has_stripped_entries: bool, is_non_exhaustive: bool, enum_def_id: DefId, -) -> impl fmt::Display + 'a + Captures<'tcx> { +) -> impl fmt::Display { fmt::from_fn(move |w| { let should_show_enum_discriminant = should_show_enum_discriminant(cx, enum_def_id, variants); @@ -1764,12 +1702,12 @@ fn render_enum_fields<'a, 'tcx>( }) } -fn item_variants<'a, 'tcx>( - cx: &'a Context<'tcx>, - it: &'a clean::Item, - variants: &'a IndexVec<VariantIdx, clean::Item>, +fn item_variants( + cx: &Context<'_>, + it: &clean::Item, + variants: &IndexVec<VariantIdx, clean::Item>, enum_def_id: DefId, -) -> impl fmt::Display + 'a + Captures<'tcx> { +) -> impl fmt::Display { fmt::from_fn(move |w| { let tcx = cx.tcx(); write!( @@ -1895,11 +1833,7 @@ fn item_variants<'a, 'tcx>( }) } -fn item_macro<'a, 'tcx>( - cx: &'a Context<'tcx>, - it: &'a clean::Item, - t: &'a clean::Macro, -) -> impl fmt::Display + 'a + Captures<'tcx> { +fn item_macro(cx: &Context<'_>, it: &clean::Item, t: &clean::Macro) -> impl fmt::Display { fmt::from_fn(|w| { wrap_item(w, |w| { // FIXME: Also print `#[doc(hidden)]` for `macro_rules!` if it `is_doc_hidden`. @@ -1912,11 +1846,7 @@ fn item_macro<'a, 'tcx>( }) } -fn item_proc_macro<'a, 'tcx>( - cx: &'a Context<'tcx>, - it: &'a clean::Item, - m: &'a clean::ProcMacro, -) -> impl fmt::Display + 'a + Captures<'tcx> { +fn item_proc_macro(cx: &Context<'_>, it: &clean::Item, m: &clean::ProcMacro) -> impl fmt::Display { fmt::from_fn(|w| { wrap_item(w, |w| { let name = it.name.expect("proc-macros always have names"); @@ -1947,10 +1877,7 @@ fn item_proc_macro<'a, 'tcx>( }) } -fn item_primitive<'a, 'tcx>( - cx: &'a Context<'tcx>, - it: &'a clean::Item, -) -> impl fmt::Display + 'a + Captures<'tcx> { +fn item_primitive(cx: &Context<'_>, it: &clean::Item) -> impl fmt::Display { fmt::from_fn(|w| { let def_id = it.item_id.expect_def_id(); write!(w, "{}", document(cx, it, None, HeadingOffset::H2))?; @@ -1968,13 +1895,13 @@ fn item_primitive<'a, 'tcx>( }) } -fn item_constant<'a, 'tcx>( - cx: &'a Context<'tcx>, - it: &'a clean::Item, - generics: &'a clean::Generics, - ty: &'a clean::Type, - c: &'a clean::ConstantKind, -) -> impl fmt::Display + 'a + Captures<'tcx> { +fn item_constant( + cx: &Context<'_>, + it: &clean::Item, + generics: &clean::Generics, + ty: &clean::Type, + c: &clean::ConstantKind, +) -> impl fmt::Display { fmt::from_fn(|w| { wrap_item(w, |w| { let tcx = cx.tcx(); @@ -2028,11 +1955,7 @@ fn item_constant<'a, 'tcx>( }) } -fn item_struct<'a, 'tcx>( - cx: &'a Context<'tcx>, - it: &'a clean::Item, - s: &'a clean::Struct, -) -> impl fmt::Display + 'a + Captures<'tcx> { +fn item_struct(cx: &Context<'_>, it: &clean::Item, s: &clean::Struct) -> impl fmt::Display { fmt::from_fn(|w| { wrap_item(w, |w| { render_attributes_in_code(w, it, cx); @@ -2056,12 +1979,12 @@ fn item_struct<'a, 'tcx>( }) } -fn item_fields<'a, 'tcx>( - cx: &'a Context<'tcx>, - it: &'a clean::Item, - fields: &'a [clean::Item], +fn item_fields( + cx: &Context<'_>, + it: &clean::Item, + fields: &[clean::Item], ctor_kind: Option<CtorKind>, -) -> impl fmt::Display + 'a + Captures<'tcx> { +) -> impl fmt::Display { fmt::from_fn(move |w| { let mut fields = fields .iter() @@ -2111,12 +2034,12 @@ fn item_fields<'a, 'tcx>( }) } -fn item_static<'a, 'tcx>( - cx: &'a Context<'tcx>, - it: &'a clean::Item, - s: &'a clean::Static, +fn item_static( + cx: &Context<'_>, + it: &clean::Item, + s: &clean::Static, safety: Option<hir::Safety>, -) -> impl fmt::Display + 'a + Captures<'tcx> { +) -> impl fmt::Display { fmt::from_fn(move |w| { wrap_item(w, |w| { render_attributes_in_code(w, it, cx); @@ -2135,10 +2058,7 @@ fn item_static<'a, 'tcx>( }) } -fn item_foreign_type<'a, 'tcx>( - cx: &'a Context<'tcx>, - it: &'a clean::Item, -) -> impl fmt::Display + 'a + Captures<'tcx> { +fn item_foreign_type(cx: &Context<'_>, it: &clean::Item) -> impl fmt::Display { fmt::from_fn(|w| { wrap_item(w, |w| { w.write_str("extern {\n")?; @@ -2155,10 +2075,7 @@ fn item_foreign_type<'a, 'tcx>( }) } -fn item_keyword<'a, 'tcx>( - cx: &'a Context<'tcx>, - it: &'a clean::Item, -) -> impl fmt::Display + 'a + Captures<'tcx> { +fn item_keyword(cx: &Context<'_>, it: &clean::Item) -> impl fmt::Display { document(cx, it, None, HeadingOffset::H2) } @@ -2268,18 +2185,14 @@ pub(super) fn full_path(cx: &Context<'_>, item: &clean::Item) -> String { s } -pub(super) fn item_path(ty: ItemType, name: &str) -> impl Display + '_ { +pub(super) fn item_path(ty: ItemType, name: &str) -> impl Display { fmt::from_fn(move |f| match ty { ItemType::Module => write!(f, "{}index.html", ensure_trailing_slash(name)), _ => write!(f, "{ty}.{name}.html"), }) } -fn bounds<'a, 'tcx>( - bounds: &'a [clean::GenericBound], - trait_alias: bool, - cx: &'a Context<'tcx>, -) -> impl Display + 'a + Captures<'tcx> { +fn bounds(bounds: &[clean::GenericBound], trait_alias: bool, cx: &Context<'_>) -> impl Display { (!bounds.is_empty()) .then_some(fmt::from_fn(move |f| { let has_lots_of_bounds = bounds.len() > 2; @@ -2329,13 +2242,13 @@ impl Ord for ImplString { } } -fn render_implementor<'a, 'tcx>( - cx: &'a Context<'tcx>, - implementor: &'a Impl, - trait_: &'a clean::Item, - implementor_dups: &'a FxHashMap<Symbol, (DefId, bool)>, - aliases: &'a [String], -) -> impl fmt::Display + 'a + Captures<'tcx> { +fn render_implementor( + cx: &Context<'_>, + implementor: &Impl, + trait_: &clean::Item, + implementor_dups: &FxHashMap<Symbol, (DefId, bool)>, + aliases: &[String], +) -> impl fmt::Display { // If there's already another implementor that has the same abridged name, use the // full path, for example in `std::iter::ExactSizeIterator` let use_absolute = match implementor.inner_impl().for_ { @@ -2364,12 +2277,12 @@ fn render_implementor<'a, 'tcx>( ) } -fn render_union<'a, 'cx: 'a>( - it: &'a clean::Item, - g: Option<&'a clean::Generics>, - fields: &'a [clean::Item], - cx: &'a Context<'cx>, -) -> impl Display + 'a + Captures<'cx> { +fn render_union( + it: &clean::Item, + g: Option<&clean::Generics>, + fields: &[clean::Item], + cx: &Context<'_>, +) -> impl Display { fmt::from_fn(move |mut f| { write!(f, "{}union {}", visibility_print_with_space(it, cx), it.name.unwrap(),)?; @@ -2421,15 +2334,15 @@ fn render_union<'a, 'cx: 'a>( }) } -fn render_struct<'a, 'tcx>( - it: &'a clean::Item, - g: Option<&'a clean::Generics>, +fn render_struct( + it: &clean::Item, + g: Option<&clean::Generics>, ty: Option<CtorKind>, - fields: &'a [clean::Item], - tab: &'a str, + fields: &[clean::Item], + tab: &str, structhead: bool, - cx: &'a Context<'tcx>, -) -> impl fmt::Display + 'a + Captures<'tcx> { + cx: &Context<'_>, +) -> impl fmt::Display { fmt::from_fn(move |w| { write!( w, @@ -2457,15 +2370,15 @@ fn render_struct<'a, 'tcx>( }) } -fn render_struct_fields<'a, 'tcx>( - g: Option<&'a clean::Generics>, +fn render_struct_fields( + g: Option<&clean::Generics>, ty: Option<CtorKind>, - fields: &'a [clean::Item], - tab: &'a str, + fields: &[clean::Item], + tab: &str, structhead: bool, has_stripped_entries: bool, - cx: &'a Context<'tcx>, -) -> impl fmt::Display + 'a + Captures<'tcx> { + cx: &Context<'_>, +) -> impl fmt::Display { fmt::from_fn(move |w| { match ty { None => { @@ -2581,7 +2494,7 @@ fn document_non_exhaustive_header(item: &clean::Item) -> &str { if item.is_non_exhaustive() { " (Non-exhaustive)" } else { "" } } -fn document_non_exhaustive(item: &clean::Item) -> impl Display + '_ { +fn document_non_exhaustive(item: &clean::Item) -> impl Display { fmt::from_fn(|f| { if item.is_non_exhaustive() { write!( diff --git a/src/librustdoc/html/render/type_layout.rs b/src/librustdoc/html/render/type_layout.rs index 0f01db5f6bc..a1ee5c8c548 100644 --- a/src/librustdoc/html/render/type_layout.rs +++ b/src/librustdoc/html/render/type_layout.rs @@ -2,7 +2,6 @@ use std::fmt; use rinja::Template; use rustc_abi::{Primitive, TagEncoding, Variants}; -use rustc_data_structures::captures::Captures; use rustc_hir::def_id::DefId; use rustc_middle::span_bug; use rustc_middle::ty::layout::LayoutError; @@ -26,10 +25,7 @@ struct TypeLayoutSize { size: u64, } -pub(crate) fn document_type_layout<'a, 'cx: 'a>( - cx: &'a Context<'cx>, - ty_def_id: DefId, -) -> impl fmt::Display + 'a + Captures<'cx> { +pub(crate) fn document_type_layout(cx: &Context<'_>, ty_def_id: DefId) -> impl fmt::Display { fmt::from_fn(move |f| { if !cx.shared.show_type_layout { return Ok(()); diff --git a/src/librustdoc/html/sources.rs b/src/librustdoc/html/sources.rs index 78c86a27632..cbbd4b01d83 100644 --- a/src/librustdoc/html/sources.rs +++ b/src/librustdoc/html/sources.rs @@ -333,7 +333,7 @@ pub(crate) fn print_src( source_context: &SourceContext<'_>, ) { let mut lines = s.lines().count(); - let line_info = if let SourceContext::Embedded(ref info) = source_context { + let line_info = if let SourceContext::Embedded(info) = source_context { highlight::LineInfo::new_scraped(lines as u32, info.offset as u32) } else { highlight::LineInfo::new(lines as u32) diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs index c1e6d324d5a..4fe5e13c3af 100644 --- a/src/librustdoc/lib.rs +++ b/src/librustdoc/lib.rs @@ -147,7 +147,7 @@ pub fn main() { #[cfg(target_os = "macos")] { - extern "C" { + unsafe extern "C" { fn _rjem_je_zone_register(); } diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs index 97e6d314642..440d6331457 100644 --- a/src/librustdoc/passes/collect_intra_doc_links.rs +++ b/src/librustdoc/passes/collect_intra_doc_links.rs @@ -58,7 +58,7 @@ fn filter_assoc_items_by_name_and_namespace( assoc_items_of: DefId, ident: Ident, ns: Namespace, -) -> impl Iterator<Item = &ty::AssocItem> + '_ { +) -> impl Iterator<Item = &ty::AssocItem> { tcx.associated_items(assoc_items_of).filter_by_name_unhygienic(ident.name).filter(move |item| { item.kind.namespace() == ns && tcx.hygienic_eq(ident, item.ident(tcx), assoc_items_of) }) diff --git a/src/tools/compiletest/src/common.rs b/src/tools/compiletest/src/common.rs index b302c6a49f5..978836cb663 100644 --- a/src/tools/compiletest/src/common.rs +++ b/src/tools/compiletest/src/common.rs @@ -190,6 +190,9 @@ pub struct Config { /// The cargo executable. pub cargo_path: Option<PathBuf>, + /// Rustc executable used to compile run-make recipes. + pub stage0_rustc_path: Option<PathBuf>, + /// The rustdoc executable. pub rustdoc_path: Option<PathBuf>, diff --git a/src/tools/compiletest/src/lib.rs b/src/tools/compiletest/src/lib.rs index 9dff7047bc4..e93f32c86bc 100644 --- a/src/tools/compiletest/src/lib.rs +++ b/src/tools/compiletest/src/lib.rs @@ -54,6 +54,12 @@ pub fn parse_config(args: Vec<String>) -> Config { .reqopt("", "run-lib-path", "path to target shared libraries", "PATH") .reqopt("", "rustc-path", "path to rustc to use for compiling", "PATH") .optopt("", "cargo-path", "path to cargo to use for compiling", "PATH") + .optopt( + "", + "stage0-rustc-path", + "path to rustc to use for compiling run-make recipes", + "PATH", + ) .optopt("", "rustdoc-path", "path to rustdoc to use for compiling", "PATH") .optopt("", "coverage-dump-path", "path to coverage-dump to use in tests", "PATH") .reqopt("", "python", "path to python to use for doc tests", "PATH") @@ -320,6 +326,7 @@ pub fn parse_config(args: Vec<String>) -> Config { run_lib_path: make_absolute(opt_path(matches, "run-lib-path")), rustc_path: opt_path(matches, "rustc-path"), cargo_path: matches.opt_str("cargo-path").map(PathBuf::from), + stage0_rustc_path: matches.opt_str("stage0-rustc-path").map(PathBuf::from), rustdoc_path: matches.opt_str("rustdoc-path").map(PathBuf::from), coverage_dump_path: matches.opt_str("coverage-dump-path").map(PathBuf::from), python: matches.opt_str("python").unwrap(), diff --git a/src/tools/compiletest/src/runtest/run_make.rs b/src/tools/compiletest/src/runtest/run_make.rs index 9bb3993223e..07f4d7c4942 100644 --- a/src/tools/compiletest/src/runtest/run_make.rs +++ b/src/tools/compiletest/src/runtest/run_make.rs @@ -173,7 +173,8 @@ impl TestCx<'_> { fn run_rmake_v2_test(&self) { // For `run-make` V2, we need to perform 2 steps to build and run a `run-make` V2 recipe // (`rmake.rs`) to run the actual tests. The support library is already built as a tool rust - // library and is available under `build/$TARGET/stageN-tools-bin/librun_make_support.rlib`. + // library and is available under + // `build/$HOST/stage0-bootstrap-tools/$TARGET/release/librun_make_support.rlib`. // // 1. We need to build the recipe `rmake.rs` as a binary and link in the `run_make_support` // library. @@ -224,25 +225,21 @@ impl TestCx<'_> { // // ``` // build/<target_triple>/ - // ├── stageN-tools-bin/ - // │ └── librun_make_support.rlib // <- support rlib itself - // ├── stageN-tools/ - // │ ├── release/deps/ // <- deps of deps - // │ └── <host_triple>/release/deps/ // <- deps + // ├── stage0-bootstrap-tools/ + // │ ├── <host_triple>/release/librun_make_support.rlib // <- support rlib itself + // │ ├── <host_triple>/release/deps/ // <- deps + // │ └── release/deps/ // <- deps of deps // ``` // // FIXME(jieyouxu): there almost certainly is a better way to do this (specifically how the - // support lib and its deps are organized, can't we copy them to the tools-bin dir as - // well?), but this seems to work for now. + // support lib and its deps are organized), but this seems to work for now. - let stage_number = self.config.stage; + let tools_bin = host_build_root.join("stage0-bootstrap-tools"); + let support_host_path = tools_bin.join(&self.config.host).join("release"); + let support_lib_path = support_host_path.join("librun_make_support.rlib"); - let stage_tools_bin = host_build_root.join(format!("stage{stage_number}-tools-bin")); - let support_lib_path = stage_tools_bin.join("librun_make_support.rlib"); - - let stage_tools = host_build_root.join(format!("stage{stage_number}-tools")); - let support_lib_deps = stage_tools.join(&self.config.host).join("release").join("deps"); - let support_lib_deps_deps = stage_tools.join("release").join("deps"); + let support_lib_deps = support_host_path.join("deps"); + let support_lib_deps_deps = tools_bin.join("release").join("deps"); // To compile the recipe with rustc, we need to provide suitable dynamic library search // paths to rustc. This includes both: @@ -253,12 +250,6 @@ impl TestCx<'_> { let base_dylib_search_paths = Vec::from_iter(env::split_paths(&env::var(dylib_env_var()).unwrap())); - let host_dylib_search_paths = { - let mut paths = vec![self.config.compile_lib_path.clone()]; - paths.extend(base_dylib_search_paths.iter().cloned()); - paths - }; - // Calculate the paths of the recipe binary. As previously discussed, this is placed at // `<base_dir>/<bin_name>` with `bin_name` being `rmake` or `rmake.exe` depending on // platform. @@ -268,7 +259,15 @@ impl TestCx<'_> { p }; - let mut rustc = Command::new(&self.config.rustc_path); + // run-make-support and run-make tests are compiled using the stage0 compiler + // If the stage is 0, then the compiler that we test (either bootstrap or an explicitly + // set compiler) is the one that actually compiled run-make-support. + let stage0_rustc = self + .config + .stage0_rustc_path + .as_ref() + .expect("stage0 rustc is required to run run-make tests"); + let mut rustc = Command::new(&stage0_rustc); rustc .arg("-o") .arg(&recipe_bin) @@ -282,35 +281,12 @@ impl TestCx<'_> { .arg(format!("run_make_support={}", &support_lib_path.to_string_lossy())) .arg("--edition=2021") .arg(&self.testpaths.file.join("rmake.rs")) - .arg("-Cprefer-dynamic") - // Provide necessary library search paths for rustc. - .env(dylib_env_var(), &env::join_paths(host_dylib_search_paths).unwrap()); + .arg("-Cprefer-dynamic"); // In test code we want to be very pedantic about values being silently discarded that are // annotated with `#[must_use]`. rustc.arg("-Dunused_must_use"); - // > `cg_clif` uses `COMPILETEST_FORCE_STAGE0=1 ./x.py test --stage 0` for running the rustc - // > test suite. With the introduction of rmake.rs this broke. `librun_make_support.rlib` is - // > compiled using the bootstrap rustc wrapper which sets `--sysroot - // > build/aarch64-unknown-linux-gnu/stage0-sysroot`, but then compiletest will compile - // > `rmake.rs` using the sysroot of the bootstrap compiler causing it to not find the - // > `libstd.rlib` against which `librun_make_support.rlib` is compiled. - // - // The gist here is that we have to pass the proper stage0 sysroot if we want - // - // ``` - // $ COMPILETEST_FORCE_STAGE0=1 ./x test run-make --stage 0 - // ``` - // - // to work correctly. - // - // See <https://github.com/rust-lang/rust/pull/122248> for more background. - let stage0_sysroot = host_build_root.join("stage0-sysroot"); - if std::env::var_os("COMPILETEST_FORCE_STAGE0").is_some() { - rustc.arg("--sysroot").arg(&stage0_sysroot); - } - // Now run rustc to build the recipe. let res = self.run_command_to_procres(&mut rustc); if !res.status.success() { @@ -320,35 +296,24 @@ impl TestCx<'_> { // To actually run the recipe, we have to provide the recipe with a bunch of information // provided through env vars. - // Compute stage-specific standard library paths. - let stage_std_path = host_build_root.join(format!("stage{stage_number}")).join("lib"); - // Compute dynamic library search paths for recipes. + // These dylib directories are needed to **execute the recipe**. let recipe_dylib_search_paths = { let mut paths = base_dylib_search_paths.clone(); - - // For stage 0, we need to explicitly include the stage0-sysroot libstd dylib. - // See <https://github.com/rust-lang/rust/issues/135373>. - if std::env::var_os("COMPILETEST_FORCE_STAGE0").is_some() { - paths.push( - stage0_sysroot.join("lib").join("rustlib").join(&self.config.host).join("lib"), - ); - } - - paths.push(support_lib_path.parent().unwrap().to_path_buf()); - paths.push(stage_std_path.join("rustlib").join(&self.config.host).join("lib")); - paths - }; - - // Compute runtime library search paths for recipes. This is target-specific. - let target_runtime_dylib_search_paths = { - let mut paths = vec![rmake_out_dir.clone()]; - paths.extend(base_dylib_search_paths.iter().cloned()); + paths.push( + stage0_rustc + .parent() + .unwrap() + .parent() + .unwrap() + .join("lib") + .join("rustlib") + .join(&self.config.host) + .join("lib"), + ); paths }; - // FIXME(jieyouxu): please rename `TARGET_RPATH_ENV`, `HOST_RPATH_DIR` and - // `TARGET_RPATH_DIR`, it is **extremely** confusing! let mut cmd = Command::new(&recipe_bin); cmd.current_dir(&rmake_out_dir) .stdout(Stdio::piped()) @@ -357,9 +322,14 @@ impl TestCx<'_> { // example, this could be `LD_LIBRARY_PATH` on some linux distros but `PATH` on Windows. .env("LD_LIB_PATH_ENVVAR", dylib_env_var()) // Provide the dylib search paths. + // This is required to run the **recipe** itself. .env(dylib_env_var(), &env::join_paths(recipe_dylib_search_paths).unwrap()) - // Provide runtime dylib search paths. - .env("TARGET_RPATH_ENV", &env::join_paths(target_runtime_dylib_search_paths).unwrap()) + // Provide the directory to libraries that are needed to run the *compiler* invoked + // by the recipe. + .env("HOST_RUSTC_DYLIB_PATH", &self.config.compile_lib_path) + // Provide the directory to libraries that might be needed to run binaries created + // by a compiler invoked by the recipe. + .env("TARGET_EXE_DYLIB_PATH", &self.config.run_lib_path) // Provide the target. .env("TARGET", &self.config.target) // Some tests unfortunately still need Python, so provide path to a Python interpreter. @@ -370,13 +340,6 @@ impl TestCx<'_> { .env("BUILD_ROOT", &host_build_root) // Provide path to stage-corresponding rustc. .env("RUSTC", &self.config.rustc_path) - // Provide the directory to libraries that are needed to run the *compiler*. This is not - // to be confused with `TARGET_RPATH_ENV` or `TARGET_RPATH_DIR`. This is needed if the - // recipe wants to invoke rustc. - .env("HOST_RPATH_DIR", &self.config.compile_lib_path) - // Provide the directory to libraries that might be needed to run compiled binaries - // (further compiled by the recipe!). - .env("TARGET_RPATH_DIR", &self.config.run_lib_path) // Provide which LLVM components are available (e.g. which LLVM components are provided // through a specific CI runner). .env("LLVM_COMPONENTS", &self.config.llvm_components); diff --git a/src/tools/opt-dist/src/main.rs b/src/tools/opt-dist/src/main.rs index 565721a9093..3111149f2ae 100644 --- a/src/tools/opt-dist/src/main.rs +++ b/src/tools/opt-dist/src/main.rs @@ -389,6 +389,7 @@ fn main() -> anyhow::Result<()> { "clippy", "miri", "rustfmt", + "gcc", ] { build_args.extend(["--skip".to_string(), target.to_string()]); } diff --git a/src/tools/opt-dist/src/metrics.rs b/src/tools/opt-dist/src/metrics.rs index 89c4cb12d4c..0a745566eb5 100644 --- a/src/tools/opt-dist/src/metrics.rs +++ b/src/tools/opt-dist/src/metrics.rs @@ -1,33 +1,10 @@ use std::time::Duration; -use build_helper::metrics::{JsonNode, JsonRoot}; +use build_helper::metrics::{BuildStep, JsonRoot, format_build_steps}; use camino::Utf8Path; use crate::timer::TimerSection; -#[derive(Clone, Debug)] -pub struct BuildStep { - r#type: String, - children: Vec<BuildStep>, - duration: Duration, -} - -impl BuildStep { - pub fn find_all_by_type(&self, r#type: &str) -> Vec<&BuildStep> { - let mut result = Vec::new(); - self.find_by_type(r#type, &mut result); - result - } - fn find_by_type<'a>(&'a self, r#type: &str, result: &mut Vec<&'a BuildStep>) { - if self.r#type == r#type { - result.push(self); - } - for child in &self.children { - child.find_by_type(r#type, result); - } - } -} - /// Loads the metrics of the most recent bootstrap execution from a metrics.json file. pub fn load_metrics(path: &Utf8Path) -> anyhow::Result<BuildStep> { let content = std::fs::read(path.as_std_path())?; @@ -37,30 +14,7 @@ pub fn load_metrics(path: &Utf8Path) -> anyhow::Result<BuildStep> { .pop() .ok_or_else(|| anyhow::anyhow!("No bootstrap invocation found in metrics file"))?; - fn parse(node: JsonNode) -> Option<BuildStep> { - match node { - JsonNode::RustbuildStep { - type_: kind, - children, - duration_excluding_children_sec, - .. - } => { - let children: Vec<_> = children.into_iter().filter_map(parse).collect(); - let children_duration = children.iter().map(|c| c.duration).sum::<Duration>(); - Some(BuildStep { - r#type: kind.to_string(), - children, - duration: children_duration - + Duration::from_secs_f64(duration_excluding_children_sec), - }) - } - JsonNode::TestSuite(_) => None, - } - } - - let duration = Duration::from_secs_f64(invocation.duration_including_children_sec); - let children: Vec<_> = invocation.children.into_iter().filter_map(parse).collect(); - Ok(BuildStep { r#type: "root".to_string(), children, duration }) + Ok(BuildStep::from_invocation(&invocation)) } /// Logs the individual metrics in a table and add Rustc and LLVM durations to the passed @@ -82,27 +36,6 @@ pub fn record_metrics(metrics: &BuildStep, timer: &mut TimerSection) { timer.add_duration("Rustc", rustc_duration); } - log_metrics(metrics); -} - -fn log_metrics(metrics: &BuildStep) { - use std::fmt::Write; - - let mut substeps: Vec<(u32, &BuildStep)> = Vec::new(); - - fn visit<'a>(step: &'a BuildStep, level: u32, substeps: &mut Vec<(u32, &'a BuildStep)>) { - substeps.push((level, step)); - for child in &step.children { - visit(child, level + 1, substeps); - } - } - - visit(metrics, 0, &mut substeps); - - let mut output = String::new(); - for (level, step) in substeps { - let label = format!("{}{}", ".".repeat(level as usize), step.r#type); - writeln!(output, "{label:<65}{:>8.2}s", step.duration.as_secs_f64()).unwrap(); - } + let output = format_build_steps(metrics); log::info!("Build step durations\n{output}"); } diff --git a/src/tools/run-make-support/src/external_deps/rustc.rs b/src/tools/run-make-support/src/external_deps/rustc.rs index 710ba025830..cb2bd83815a 100644 --- a/src/tools/run-make-support/src/external_deps/rustc.rs +++ b/src/tools/run-make-support/src/external_deps/rustc.rs @@ -5,7 +5,7 @@ use std::str::FromStr as _; use crate::command::Command; use crate::env::env_var; use crate::path_helpers::cwd; -use crate::util::set_host_rpath; +use crate::util::set_host_compiler_dylib_path; use crate::{is_aix, is_darwin, is_msvc, is_windows, uname}; /// Construct a new `rustc` invocation. This will automatically set the library @@ -15,8 +15,8 @@ pub fn rustc() -> Rustc { Rustc::new() } -/// Construct a plain `rustc` invocation with no flags set. Note that [`set_host_rpath`] -/// still presets the environment variable `HOST_RPATH_DIR` by default. +/// Construct a plain `rustc` invocation with no flags set. Note that [`set_host_compiler_dylib_path`] +/// still presets the environment variable `HOST_RUSTC_DYLIB_PATH` by default. #[track_caller] pub fn bare_rustc() -> Rustc { Rustc::bare() @@ -44,7 +44,7 @@ pub fn rustc_path() -> String { #[track_caller] fn setup_common() -> Command { let mut cmd = Command::new(rustc_path()); - set_host_rpath(&mut cmd); + set_host_compiler_dylib_path(&mut cmd); cmd } diff --git a/src/tools/run-make-support/src/external_deps/rustdoc.rs b/src/tools/run-make-support/src/external_deps/rustdoc.rs index 8a659cd3d8a..433a57cd9fa 100644 --- a/src/tools/run-make-support/src/external_deps/rustdoc.rs +++ b/src/tools/run-make-support/src/external_deps/rustdoc.rs @@ -2,16 +2,10 @@ use std::ffi::OsStr; use std::path::Path; use crate::command::Command; -use crate::env::{env_var, env_var_os}; -use crate::util::set_host_rpath; +use crate::env::env_var; +use crate::util::set_host_compiler_dylib_path; -/// Construct a plain `rustdoc` invocation with no flags set. -#[track_caller] -pub fn bare_rustdoc() -> Rustdoc { - Rustdoc::bare() -} - -/// Construct a new `rustdoc` invocation with `-L $(TARGET_RPATH_DIR)` set. +/// Construct a new `rustdoc` invocation. #[track_caller] pub fn rustdoc() -> Rustdoc { Rustdoc::new() @@ -29,23 +23,15 @@ crate::macros::impl_common_helpers!(Rustdoc); fn setup_common() -> Command { let rustdoc = env_var("RUSTDOC"); let mut cmd = Command::new(rustdoc); - set_host_rpath(&mut cmd); + set_host_compiler_dylib_path(&mut cmd); cmd } impl Rustdoc { /// Construct a bare `rustdoc` invocation. #[track_caller] - pub fn bare() -> Self { - let cmd = setup_common(); - Self { cmd } - } - - /// Construct a `rustdoc` invocation with `-L $(TARGET_RPATH_DIR)` set. - #[track_caller] pub fn new() -> Self { - let mut cmd = setup_common(); - cmd.arg("-L").arg(env_var_os("TARGET_RPATH_DIR")); + let cmd = setup_common(); Self { cmd } } diff --git a/src/tools/run-make-support/src/lib.rs b/src/tools/run-make-support/src/lib.rs index 7e63ab3159a..d40ec9c4116 100644 --- a/src/tools/run-make-support/src/lib.rs +++ b/src/tools/run-make-support/src/lib.rs @@ -67,7 +67,7 @@ pub use llvm::{ }; pub use python::python_command; pub use rustc::{aux_build, bare_rustc, rustc, rustc_path, Rustc}; -pub use rustdoc::{bare_rustdoc, rustdoc, Rustdoc}; +pub use rustdoc::{rustdoc, Rustdoc}; /// [`diff`][mod@diff] is implemented in terms of the [similar] library. /// diff --git a/src/tools/run-make-support/src/run.rs b/src/tools/run-make-support/src/run.rs index 3eeba6fd526..7812863ccc2 100644 --- a/src/tools/run-make-support/src/run.rs +++ b/src/tools/run-make-support/src/run.rs @@ -1,10 +1,10 @@ use std::ffi::OsStr; -use std::path::{Path, PathBuf}; +use std::path::PathBuf; use std::{env, panic}; use crate::command::{Command, CompletedProcess}; -use crate::util::{handle_failed_output, set_host_rpath}; -use crate::{cwd, env_var, is_windows}; +use crate::util::handle_failed_output; +use crate::{cwd, env_var}; #[track_caller] fn run_common(name: &str, args: Option<&[&str]>) -> Command { @@ -18,10 +18,11 @@ fn run_common(name: &str, args: Option<&[&str]>) -> Command { cmd.arg(arg); } } + cmd.env(&ld_lib_path_envvar, { let mut paths = vec![]; paths.push(cwd()); - for p in env::split_paths(&env_var("TARGET_RPATH_ENV")) { + for p in env::split_paths(&env_var("TARGET_EXE_DYLIB_PATH")) { paths.push(p.to_path_buf()); } for p in env::split_paths(&env_var(&ld_lib_path_envvar)) { @@ -31,15 +32,6 @@ fn run_common(name: &str, args: Option<&[&str]>) -> Command { }); cmd.env("LC_ALL", "C"); // force english locale - if is_windows() { - let mut paths = vec![]; - for p in env::split_paths(&std::env::var("PATH").unwrap_or(String::new())) { - paths.push(p.to_path_buf()); - } - paths.push(Path::new(&env_var("TARGET_RPATH_DIR")).to_path_buf()); - cmd.env("PATH", env::join_paths(paths.iter()).unwrap()); - } - cmd } @@ -84,7 +76,6 @@ pub fn run_fail(name: &str) -> CompletedProcess { #[track_caller] pub fn cmd<S: AsRef<OsStr>>(program: S) -> Command { let mut command = Command::new(program); - set_host_rpath(&mut command); command.env("LC_ALL", "C"); // force english locale command } diff --git a/src/tools/run-make-support/src/util.rs b/src/tools/run-make-support/src/util.rs index 703e3ad1c6c..af01758447b 100644 --- a/src/tools/run-make-support/src/util.rs +++ b/src/tools/run-make-support/src/util.rs @@ -24,13 +24,13 @@ pub(crate) fn handle_failed_output( std::process::exit(1) } -/// Set the runtime library path as needed for running the host rustc/rustdoc/etc. -pub(crate) fn set_host_rpath(cmd: &mut Command) { +/// Set the runtime library paths as needed for running the host compilers (rustc/rustdoc/etc). +pub(crate) fn set_host_compiler_dylib_path(cmd: &mut Command) { let ld_lib_path_envvar = env_var("LD_LIB_PATH_ENVVAR"); cmd.env(&ld_lib_path_envvar, { let mut paths = vec![]; paths.push(cwd()); - paths.push(PathBuf::from(env_var("HOST_RPATH_DIR"))); + paths.push(PathBuf::from(env_var("HOST_RUSTC_DYLIB_PATH"))); for p in std::env::split_paths(&env_var(&ld_lib_path_envvar)) { paths.push(p.to_path_buf()); } diff --git a/src/tools/rustdoc/Cargo.toml b/src/tools/rustdoc/Cargo.toml index c4101f72cc2..d1682758d36 100644 --- a/src/tools/rustdoc/Cargo.toml +++ b/src/tools/rustdoc/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "rustdoc-tool" version = "0.0.0" -edition = "2021" +edition = "2024" # Cargo adds a number of paths to the dylib search path on windows, which results in # the wrong rustdoc being executed. To avoid the conflicting rustdocs, we name the "tool" diff --git a/tests/run-make/a-b-a-linker-guard/rmake.rs b/tests/run-make/a-b-a-linker-guard/rmake.rs index ee6d655bc76..4428685a6cf 100644 --- a/tests/run-make/a-b-a-linker-guard/rmake.rs +++ b/tests/run-make/a-b-a-linker-guard/rmake.rs @@ -1,7 +1,8 @@ -// ignore-tidy-linelength +// Test that if we build `b` against a version of `a` that has +// one set of types, it will not run with a dylib that has a different set of types. -// Test that if we build `b` against a version of `a` that has one set of types, it will not run -// with a dylib that has a different set of types. +//@ ignore-cross-compile +// Reason: the compiled binary is executed use run_make_support::{run, run_fail, rustc}; diff --git a/tests/run-make/rustdoc-default-output/rmake.rs b/tests/run-make/rustdoc-default-output/rmake.rs index 06720445a35..5f9c501e528 100644 --- a/tests/run-make/rustdoc-default-output/rmake.rs +++ b/tests/run-make/rustdoc-default-output/rmake.rs @@ -3,10 +3,10 @@ // ensures the output of rustdoc's help menu is as expected. // See https://github.com/rust-lang/rust/issues/88756 -use run_make_support::{bare_rustdoc, diff}; +use run_make_support::{diff, rustdoc}; fn main() { - let out = bare_rustdoc().run().stdout_utf8(); + let out = rustdoc().run().stdout_utf8(); diff() .expected_file("output-default.stdout") .actual_text("actual", out) diff --git a/tests/run-make/version-verbose-commit-hash/rmake.rs b/tests/run-make/version-verbose-commit-hash/rmake.rs index 733c0e2cdb1..ae8dda38ab4 100644 --- a/tests/run-make/version-verbose-commit-hash/rmake.rs +++ b/tests/run-make/version-verbose-commit-hash/rmake.rs @@ -5,13 +5,13 @@ //@ needs-git-hash -use run_make_support::{bare_rustc, bare_rustdoc, regex}; +use run_make_support::{bare_rustc, regex, rustdoc}; fn main() { let out_rustc = bare_rustc().arg("--version").arg("--verbose").run().stdout_utf8().to_lowercase(); let out_rustdoc = - bare_rustdoc().arg("--version").arg("--verbose").run().stdout_utf8().to_lowercase(); + rustdoc().arg("--version").arg("--verbose").run().stdout_utf8().to_lowercase(); let re = regex::Regex::new(r#"commit-hash: [0-9a-f]{40}\ncommit-date: [0-9]{4}-[0-9]{2}-[0-9]{2}"#) .unwrap(); |
