| author | bors <bors@rust-lang.org> 2025-03-05 02:43:15 UTC |
| committer | bors <bors@rust-lang.org> 2025-03-05 02:43:15 UTC |
| log | ac951d379913c667a1fb73a0830e81d65d2007cf |
| tree | 0e95d4d9055ab7295908f998b9d5efb7890b4988 |
| parent | 08db600e8e276b548e986abe7239c2a85d2f425f |
| parent | 7ba7cc835ec18876b8133c4f051abfd5bfebb0aa |
Rollup of 6 pull requests
Successful merges:
- #137077 (Postprocess bootstrap metrics into GitHub job summary)
- #137373 (Compile run-make-support and run-make tests with the bootstrap compiler)
- #137634 (Update `compiler-builtins` to 0.1.149)
- #137667 (Add `dist::Gcc` build step)
- #137722 (`librustdoc`: 2024 edition! 🎊)
- #137947 (Do not install rustup on Rust for Linux job)
r? `@ghost`
`@rustbot` modify labels: rollup46 files changed, 765 insertions(+), 793 deletions(-)
.github/workflows/ci.yml+17| ... | ... | @@ -182,6 +182,13 @@ jobs: |
| 182 | 182 | - name: show the current environment |
| 183 | 183 | run: src/ci/scripts/dump-environment.sh |
| 184 | 184 | |
| 185 | # Pre-build citool before the following step uninstalls rustup | |
| 186 | # Build is into the build directory, to avoid modifying sources | |
| 187 | - name: build citool | |
| 188 | run: | | |
| 189 | cd src/ci/citool | |
| 190 | CARGO_TARGET_DIR=../../../build/citool cargo build | |
| 191 | ||
| 185 | 192 | - name: run the build |
| 186 | 193 | # Redirect stderr to stdout to avoid reordering the two streams in the GHA logs. |
| 187 | 194 | run: src/ci/scripts/run-build-from-ci.sh 2>&1 |
| ... | ... | @@ -218,6 +225,16 @@ jobs: |
| 218 | 225 | # erroring about invalid credentials instead. |
| 219 | 226 | if: github.event_name == 'push' || env.DEPLOY == '1' || env.DEPLOY_ALT == '1' |
| 220 | 227 | |
| 228 | - name: postprocess metrics into the summary | |
| 229 | run: | | |
| 230 | if [ -f build/metrics.json ]; then | |
| 231 | ./build/citool/debug/citool postprocess-metrics build/metrics.json ${GITHUB_STEP_SUMMARY} | |
| 232 | elif [ -f obj/build/metrics.json ]; then | |
| 233 | ./build/citool/debug/citool postprocess-metrics obj/build/metrics.json ${GITHUB_STEP_SUMMARY} | |
| 234 | else | |
| 235 | echo "No metrics.json found" | |
| 236 | fi | |
| 237 | ||
| 221 | 238 | - name: upload job metrics to DataDog |
| 222 | 239 | if: needs.calculate_matrix.outputs.run_type != 'pr' |
| 223 | 240 | env: |
compiler/rustc_codegen_cranelift/patches/0029-stdlib-Disable-f16-and-f128-in-compiler-builtins.patch+2-2| ... | ... | @@ -16,8 +16,8 @@ index 7165c3e48af..968552ad435 100644 |
| 16 | 16 | |
| 17 | 17 | [dependencies] |
| 18 | 18 | core = { path = "../core", public = true } |
| 19 | -compiler_builtins = { version = "=0.1.148", features = ['rustc-dep-of-std'] } | |
| 20 | +compiler_builtins = { version = "=0.1.148", features = ['rustc-dep-of-std', 'no-f16-f128'] } | |
| 19 | -compiler_builtins = { version = "=0.1.150", features = ['rustc-dep-of-std'] } | |
| 20 | +compiler_builtins = { version = "=0.1.150", features = ['rustc-dep-of-std', 'no-f16-f128'] } | |
| 21 | 21 | |
| 22 | 22 | [dev-dependencies] |
| 23 | 23 | rand = { version = "0.8.5", default-features = false, features = ["alloc"] } |
compiler/rustc_data_structures/src/captures.rs deleted-8| ... | ... | @@ -1,8 +0,0 @@ |
| 1 | /// "Signaling" trait used in impl trait to tag lifetimes that you may | |
| 2 | /// need to capture but don't really need for other reasons. | |
| 3 | /// Basically a workaround; see [this comment] for details. | |
| 4 | /// | |
| 5 | /// [this comment]: https://github.com/rust-lang/rust/issues/34511#issuecomment-373423999 | |
| 6 | pub trait Captures<'a> {} | |
| 7 | ||
| 8 | impl<'a, T: ?Sized> Captures<'a> for T {} |
compiler/rustc_data_structures/src/lib.rs-1| ... | ... | @@ -48,7 +48,6 @@ pub use rustc_index::static_assert_size; |
| 48 | 48 | pub mod aligned; |
| 49 | 49 | pub mod base_n; |
| 50 | 50 | pub mod binary_search_util; |
| 51 | pub mod captures; | |
| 52 | 51 | pub mod fingerprint; |
| 53 | 52 | pub mod flat_map_in_place; |
| 54 | 53 | pub mod flock; |
library/Cargo.lock+2-2| ... | ... | @@ -61,9 +61,9 @@ dependencies = [ |
| 61 | 61 | |
| 62 | 62 | [[package]] |
| 63 | 63 | name = "compiler_builtins" |
| 64 | version = "0.1.148" | |
| 64 | version = "0.1.150" | |
| 65 | 65 | source = "registry+https://github.com/rust-lang/crates.io-index" |
| 66 | checksum = "26137996631d90d2727b905b480fdcf8c4479fdbce7afd7f8e3796d689b33cc2" | |
| 66 | checksum = "5c42734e0ccf0d9f953165770593a75306f0b24dda1aa03f115c70748726dbca" | |
| 67 | 67 | dependencies = [ |
| 68 | 68 | "cc", |
| 69 | 69 | "rustc-std-workspace-core", |
library/alloc/Cargo.toml+1-1| ... | ... | @@ -12,7 +12,7 @@ edition = "2021" |
| 12 | 12 | |
| 13 | 13 | [dependencies] |
| 14 | 14 | core = { path = "../core", public = true } |
| 15 | compiler_builtins = { version = "=0.1.148", features = ['rustc-dep-of-std'] } | |
| 15 | compiler_builtins = { version = "=0.1.150", features = ['rustc-dep-of-std'] } | |
| 16 | 16 | |
| 17 | 17 | [dev-dependencies] |
| 18 | 18 | rand = { version = "0.9.0", default-features = false, features = ["alloc"] } |
library/std/Cargo.toml+1-1| ... | ... | @@ -18,7 +18,7 @@ cfg-if = { version = "1.0", features = ['rustc-dep-of-std'] } |
| 18 | 18 | panic_unwind = { path = "../panic_unwind", optional = true } |
| 19 | 19 | panic_abort = { path = "../panic_abort" } |
| 20 | 20 | core = { path = "../core", public = true } |
| 21 | compiler_builtins = { version = "=0.1.148" } | |
| 21 | compiler_builtins = { version = "=0.1.150" } | |
| 22 | 22 | unwind = { path = "../unwind" } |
| 23 | 23 | hashbrown = { version = "0.15", default-features = false, features = [ |
| 24 | 24 | 'rustc-dep-of-std', |
src/bootstrap/src/core/build_steps/dist.rs+27| ... | ... | @@ -2464,3 +2464,30 @@ impl Step for ReproducibleArtifacts { |
| 2464 | 2464 | if added_anything { Some(tarball.generate()) } else { None } |
| 2465 | 2465 | } |
| 2466 | 2466 | } |
| 2467 | ||
| 2468 | /// Tarball containing a prebuilt version of the libgccjit library, | |
| 2469 | /// needed as a dependency for the GCC codegen backend (similarly to the LLVM | |
| 2470 | /// backend needing a prebuilt libLLVM). | |
| 2471 | #[derive(Clone, Debug, Eq, Hash, PartialEq)] | |
| 2472 | pub struct Gcc { | |
| 2473 | pub target: TargetSelection, | |
| 2474 | } | |
| 2475 | ||
| 2476 | impl Step for Gcc { | |
| 2477 | type Output = GeneratedTarball; | |
| 2478 | ||
| 2479 | fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> { | |
| 2480 | run.alias("gcc") | |
| 2481 | } | |
| 2482 | ||
| 2483 | fn make_run(run: RunConfig<'_>) { | |
| 2484 | run.builder.ensure(Gcc { target: run.target }); | |
| 2485 | } | |
| 2486 | ||
| 2487 | fn run(self, builder: &Builder<'_>) -> Self::Output { | |
| 2488 | let tarball = Tarball::new(builder, "gcc", &self.target.triple); | |
| 2489 | let output = builder.ensure(super::gcc::Gcc { target: self.target }); | |
| 2490 | tarball.add_file(output.libgccjit, ".", 0o644); | |
| 2491 | tarball.generate() | |
| 2492 | } | |
| 2493 | } |
src/bootstrap/src/core/build_steps/test.rs+9-87| ... | ... | @@ -1242,59 +1242,6 @@ macro_rules! test { |
| 1242 | 1242 | }; |
| 1243 | 1243 | } |
| 1244 | 1244 | |
| 1245 | #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq, Ord, PartialOrd)] | |
| 1246 | pub struct RunMakeSupport { | |
| 1247 | pub compiler: Compiler, | |
| 1248 | pub target: TargetSelection, | |
| 1249 | } | |
| 1250 | ||
| 1251 | impl Step for RunMakeSupport { | |
| 1252 | type Output = PathBuf; | |
| 1253 | const DEFAULT: bool = true; | |
| 1254 | ||
| 1255 | fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> { | |
| 1256 | run.never() | |
| 1257 | } | |
| 1258 | ||
| 1259 | fn make_run(run: RunConfig<'_>) { | |
| 1260 | let compiler = run.builder.compiler(run.builder.top_stage, run.build_triple()); | |
| 1261 | run.builder.ensure(RunMakeSupport { compiler, target: run.build_triple() }); | |
| 1262 | } | |
| 1263 | ||
| 1264 | /// Builds run-make-support and returns the path to the resulting rlib. | |
| 1265 | fn run(self, builder: &Builder<'_>) -> PathBuf { | |
| 1266 | builder.ensure(compile::Std::new(self.compiler, self.target)); | |
| 1267 | ||
| 1268 | let cargo = tool::prepare_tool_cargo( | |
| 1269 | builder, | |
| 1270 | self.compiler, | |
| 1271 | Mode::ToolStd, | |
| 1272 | self.target, | |
| 1273 | Kind::Build, | |
| 1274 | "src/tools/run-make-support", | |
| 1275 | SourceType::InTree, | |
| 1276 | &[], | |
| 1277 | ); | |
| 1278 | ||
| 1279 | let _guard = builder.msg_tool( | |
| 1280 | Kind::Build, | |
| 1281 | Mode::ToolStd, | |
| 1282 | "run-make-support", | |
| 1283 | self.compiler.stage, | |
| 1284 | &self.compiler.host, | |
| 1285 | &self.target, | |
| 1286 | ); | |
| 1287 | cargo.into_cmd().run(builder); | |
| 1288 | ||
| 1289 | let lib_name = "librun_make_support.rlib"; | |
| 1290 | let lib = builder.tools_dir(self.compiler).join(lib_name); | |
| 1291 | ||
| 1292 | let cargo_out = builder.cargo_out(self.compiler, Mode::ToolStd, self.target).join(lib_name); | |
| 1293 | builder.copy_link(&cargo_out, &lib); | |
| 1294 | lib | |
| 1295 | } | |
| 1296 | } | |
| 1297 | ||
| 1298 | 1245 | /// Runs `cargo test` on the `src/tools/run-make-support` crate. |
| 1299 | 1246 | /// That crate is used by run-make tests. |
| 1300 | 1247 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] |
| ... | ... | @@ -1446,40 +1393,7 @@ test!(Pretty { |
| 1446 | 1393 | only_hosts: true, |
| 1447 | 1394 | }); |
| 1448 | 1395 | |
| 1449 | /// Special-handling is needed for `run-make`, so don't use `test!` for defining `RunMake` | |
| 1450 | /// tests. | |
| 1451 | #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] | |
| 1452 | pub struct RunMake { | |
| 1453 | pub compiler: Compiler, | |
| 1454 | pub target: TargetSelection, | |
| 1455 | } | |
| 1456 | ||
| 1457 | impl Step for RunMake { | |
| 1458 | type Output = (); | |
| 1459 | const DEFAULT: bool = true; | |
| 1460 | const ONLY_HOSTS: bool = false; | |
| 1461 | ||
| 1462 | fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> { | |
| 1463 | run.suite_path("tests/run-make") | |
| 1464 | } | |
| 1465 | ||
| 1466 | fn make_run(run: RunConfig<'_>) { | |
| 1467 | let compiler = run.builder.compiler(run.builder.top_stage, run.build_triple()); | |
| 1468 | run.builder.ensure(RunMakeSupport { compiler, target: run.build_triple() }); | |
| 1469 | run.builder.ensure(RunMake { compiler, target: run.target }); | |
| 1470 | } | |
| 1471 | ||
| 1472 | fn run(self, builder: &Builder<'_>) { | |
| 1473 | builder.ensure(Compiletest { | |
| 1474 | compiler: self.compiler, | |
| 1475 | target: self.target, | |
| 1476 | mode: "run-make", | |
| 1477 | suite: "run-make", | |
| 1478 | path: "tests/run-make", | |
| 1479 | compare_mode: None, | |
| 1480 | }); | |
| 1481 | } | |
| 1482 | } | |
| 1396 | test!(RunMake { path: "tests/run-make", mode: "run-make", suite: "run-make", default: true }); | |
| 1483 | 1397 | |
| 1484 | 1398 | test!(Assembly { path: "tests/assembly", mode: "assembly", suite: "assembly", default: true }); |
| 1485 | 1399 | |
| ... | ... | @@ -1722,6 +1636,9 @@ NOTE: if you're sure you want to do this, please open an issue as to why. In the |
| 1722 | 1636 | host: target, |
| 1723 | 1637 | }); |
| 1724 | 1638 | } |
| 1639 | if suite == "run-make" { | |
| 1640 | builder.tool_exe(Tool::RunMakeSupport); | |
| 1641 | } | |
| 1725 | 1642 | |
| 1726 | 1643 | // Also provide `rust_test_helpers` for the host. |
| 1727 | 1644 | 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 |
| 1774 | 1691 | }; |
| 1775 | 1692 | |
| 1776 | 1693 | cmd.arg("--cargo-path").arg(cargo_path); |
| 1694 | ||
| 1695 | // We need to pass the compiler that was used to compile run-make-support, | |
| 1696 | // because we have to use the same compiler to compile rmake.rs recipes. | |
| 1697 | let stage0_rustc_path = builder.compiler(0, compiler.host); | |
| 1698 | cmd.arg("--stage0-rustc-path").arg(builder.rustc(stage0_rustc_path)); | |
| 1777 | 1699 | } |
| 1778 | 1700 | |
| 1779 | 1701 | // Avoid depending on rustdoc when we don't need it. |
src/bootstrap/src/core/build_steps/tool.rs+38-43| ... | ... | @@ -34,6 +34,12 @@ pub enum SourceType { |
| 34 | 34 | Submodule, |
| 35 | 35 | } |
| 36 | 36 | |
| 37 | #[derive(Debug, Clone, Hash, PartialEq, Eq)] | |
| 38 | pub enum ToolArtifactKind { | |
| 39 | Binary, | |
| 40 | Library, | |
| 41 | } | |
| 42 | ||
| 37 | 43 | #[derive(Debug, Clone, Hash, PartialEq, Eq)] |
| 38 | 44 | struct ToolBuild { |
| 39 | 45 | compiler: Compiler, |
| ... | ... | @@ -47,6 +53,8 @@ struct ToolBuild { |
| 47 | 53 | allow_features: &'static str, |
| 48 | 54 | /// Additional arguments to pass to the `cargo` invocation. |
| 49 | 55 | cargo_args: Vec<String>, |
| 56 | /// Whether the tool builds a binary or a library. | |
| 57 | artifact_kind: ToolArtifactKind, | |
| 50 | 58 | } |
| 51 | 59 | |
| 52 | 60 | impl Builder<'_> { |
| ... | ... | @@ -79,7 +87,7 @@ impl Builder<'_> { |
| 79 | 87 | /// for using this type as `type Output = ToolBuildResult;` |
| 80 | 88 | #[derive(Clone)] |
| 81 | 89 | pub struct ToolBuildResult { |
| 82 | /// Executable path of the corresponding tool that was built. | |
| 90 | /// Artifact path of the corresponding tool that was built. | |
| 83 | 91 | pub tool_path: PathBuf, |
| 84 | 92 | /// Compiler used to build the tool. For non-`ToolRustc` tools this is equal to `target_compiler`. |
| 85 | 93 | /// For `ToolRustc` this is one stage before of the `target_compiler`. |
| ... | ... | @@ -179,8 +187,14 @@ impl Step for ToolBuild { |
| 179 | 187 | if tool == "tidy" { |
| 180 | 188 | tool = "rust-tidy"; |
| 181 | 189 | } |
| 182 | let tool_path = | |
| 183 | copy_link_tool_bin(builder, self.compiler, self.target, self.mode, tool); | |
| 190 | let tool_path = match self.artifact_kind { | |
| 191 | ToolArtifactKind::Binary => { | |
| 192 | copy_link_tool_bin(builder, self.compiler, self.target, self.mode, tool) | |
| 193 | } | |
| 194 | ToolArtifactKind::Library => builder | |
| 195 | .cargo_out(self.compiler, self.mode, self.target) | |
| 196 | .join(format!("lib{tool}.rlib")), | |
| 197 | }; | |
| 184 | 198 | |
| 185 | 199 | ToolBuildResult { tool_path, build_compiler: self.compiler, target_compiler } |
| 186 | 200 | } |
| ... | ... | @@ -330,6 +344,7 @@ macro_rules! bootstrap_tool { |
| 330 | 344 | $(,is_unstable_tool = $unstable:expr)* |
| 331 | 345 | $(,allow_features = $allow_features:expr)? |
| 332 | 346 | $(,submodules = $submodules:expr)? |
| 347 | $(,artifact_kind = $artifact_kind:expr)? | |
| 333 | 348 | ; |
| 334 | 349 | )+) => { |
| 335 | 350 | #[derive(PartialEq, Eq, Clone)] |
| ... | ... | @@ -389,6 +404,7 @@ macro_rules! bootstrap_tool { |
| 389 | 404 | builder.require_submodule(submodule, None); |
| 390 | 405 | } |
| 391 | 406 | )* |
| 407 | ||
| 392 | 408 | builder.ensure(ToolBuild { |
| 393 | 409 | compiler: self.compiler, |
| 394 | 410 | target: self.target, |
| ... | ... | @@ -407,7 +423,12 @@ macro_rules! bootstrap_tool { |
| 407 | 423 | }, |
| 408 | 424 | extra_features: vec![], |
| 409 | 425 | allow_features: concat!($($allow_features)*), |
| 410 | cargo_args: vec![] | |
| 426 | cargo_args: vec![], | |
| 427 | artifact_kind: if false $(|| $artifact_kind == ToolArtifactKind::Library)* { | |
| 428 | ToolArtifactKind::Library | |
| 429 | } else { | |
| 430 | ToolArtifactKind::Binary | |
| 431 | } | |
| 411 | 432 | }) |
| 412 | 433 | } |
| 413 | 434 | } |
| ... | ... | @@ -445,51 +466,14 @@ bootstrap_tool!( |
| 445 | 466 | WasmComponentLd, "src/tools/wasm-component-ld", "wasm-component-ld", is_unstable_tool = true, allow_features = "min_specialization"; |
| 446 | 467 | UnicodeTableGenerator, "src/tools/unicode-table-generator", "unicode-table-generator"; |
| 447 | 468 | FeaturesStatusDump, "src/tools/features-status-dump", "features-status-dump"; |
| 469 | OptimizedDist, "src/tools/opt-dist", "opt-dist", submodules = &["src/tools/rustc-perf"]; | |
| 470 | RunMakeSupport, "src/tools/run-make-support", "run_make_support", artifact_kind = ToolArtifactKind::Library; | |
| 448 | 471 | ); |
| 449 | 472 | |
| 450 | 473 | /// These are the submodules that are required for rustbook to work due to |
| 451 | 474 | /// depending on mdbook plugins. |
| 452 | 475 | pub static SUBMODULES_FOR_RUSTBOOK: &[&str] = &["src/doc/book", "src/doc/reference"]; |
| 453 | 476 | |
| 454 | #[derive(Debug, Clone, Hash, PartialEq, Eq)] | |
| 455 | pub struct OptimizedDist { | |
| 456 | pub compiler: Compiler, | |
| 457 | pub target: TargetSelection, | |
| 458 | } | |
| 459 | ||
| 460 | impl Step for OptimizedDist { | |
| 461 | type Output = ToolBuildResult; | |
| 462 | ||
| 463 | fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> { | |
| 464 | run.path("src/tools/opt-dist") | |
| 465 | } | |
| 466 | ||
| 467 | fn make_run(run: RunConfig<'_>) { | |
| 468 | run.builder.ensure(OptimizedDist { | |
| 469 | compiler: run.builder.compiler(0, run.builder.config.build), | |
| 470 | target: run.target, | |
| 471 | }); | |
| 472 | } | |
| 473 | ||
| 474 | fn run(self, builder: &Builder<'_>) -> ToolBuildResult { | |
| 475 | // We need to ensure the rustc-perf submodule is initialized when building opt-dist since | |
| 476 | // the tool requires it to be in place to run. | |
| 477 | builder.require_submodule("src/tools/rustc-perf", None); | |
| 478 | ||
| 479 | builder.ensure(ToolBuild { | |
| 480 | compiler: self.compiler, | |
| 481 | target: self.target, | |
| 482 | tool: "opt-dist", | |
| 483 | mode: Mode::ToolBootstrap, | |
| 484 | path: "src/tools/opt-dist", | |
| 485 | source_type: SourceType::InTree, | |
| 486 | extra_features: Vec::new(), | |
| 487 | allow_features: "", | |
| 488 | cargo_args: Vec::new(), | |
| 489 | }) | |
| 490 | } | |
| 491 | } | |
| 492 | ||
| 493 | 477 | /// The [rustc-perf](https://github.com/rust-lang/rustc-perf) benchmark suite, which is added |
| 494 | 478 | /// as a submodule at `src/tools/rustc-perf`. |
| 495 | 479 | #[derive(Debug, Clone, Hash, PartialEq, Eq)] |
| ... | ... | @@ -529,6 +513,7 @@ impl Step for RustcPerf { |
| 529 | 513 | // Only build the collector package, which is used for benchmarking through |
| 530 | 514 | // a CLI. |
| 531 | 515 | cargo_args: vec!["-p".to_string(), "collector".to_string()], |
| 516 | artifact_kind: ToolArtifactKind::Binary, | |
| 532 | 517 | }; |
| 533 | 518 | let res = builder.ensure(tool.clone()); |
| 534 | 519 | // We also need to symlink the `rustc-fake` binary to the corresponding directory, |
| ... | ... | @@ -586,6 +571,7 @@ impl Step for ErrorIndex { |
| 586 | 571 | extra_features: Vec::new(), |
| 587 | 572 | allow_features: "", |
| 588 | 573 | cargo_args: Vec::new(), |
| 574 | artifact_kind: ToolArtifactKind::Binary, | |
| 589 | 575 | }) |
| 590 | 576 | } |
| 591 | 577 | } |
| ... | ... | @@ -621,6 +607,7 @@ impl Step for RemoteTestServer { |
| 621 | 607 | extra_features: Vec::new(), |
| 622 | 608 | allow_features: "", |
| 623 | 609 | cargo_args: Vec::new(), |
| 610 | artifact_kind: ToolArtifactKind::Binary, | |
| 624 | 611 | }) |
| 625 | 612 | } |
| 626 | 613 | } |
| ... | ... | @@ -725,6 +712,7 @@ impl Step for Rustdoc { |
| 725 | 712 | extra_features, |
| 726 | 713 | allow_features: "", |
| 727 | 714 | cargo_args: Vec::new(), |
| 715 | artifact_kind: ToolArtifactKind::Binary, | |
| 728 | 716 | }); |
| 729 | 717 | |
| 730 | 718 | // don't create a stage0-sysroot/bin directory. |
| ... | ... | @@ -779,6 +767,7 @@ impl Step for Cargo { |
| 779 | 767 | extra_features: Vec::new(), |
| 780 | 768 | allow_features: "", |
| 781 | 769 | cargo_args: Vec::new(), |
| 770 | artifact_kind: ToolArtifactKind::Binary, | |
| 782 | 771 | }) |
| 783 | 772 | } |
| 784 | 773 | } |
| ... | ... | @@ -827,6 +816,7 @@ impl Step for LldWrapper { |
| 827 | 816 | extra_features: Vec::new(), |
| 828 | 817 | allow_features: "", |
| 829 | 818 | cargo_args: Vec::new(), |
| 819 | artifact_kind: ToolArtifactKind::Binary, | |
| 830 | 820 | }); |
| 831 | 821 | |
| 832 | 822 | let libdir_bin = builder.sysroot_target_bindir(self.target_compiler, target); |
| ... | ... | @@ -887,6 +877,7 @@ impl Step for RustAnalyzer { |
| 887 | 877 | source_type: SourceType::InTree, |
| 888 | 878 | allow_features: RustAnalyzer::ALLOW_FEATURES, |
| 889 | 879 | cargo_args: Vec::new(), |
| 880 | artifact_kind: ToolArtifactKind::Binary, | |
| 890 | 881 | }) |
| 891 | 882 | } |
| 892 | 883 | } |
| ... | ... | @@ -931,6 +922,7 @@ impl Step for RustAnalyzerProcMacroSrv { |
| 931 | 922 | source_type: SourceType::InTree, |
| 932 | 923 | allow_features: RustAnalyzer::ALLOW_FEATURES, |
| 933 | 924 | cargo_args: Vec::new(), |
| 925 | artifact_kind: ToolArtifactKind::Binary, | |
| 934 | 926 | }); |
| 935 | 927 | |
| 936 | 928 | // Copy `rust-analyzer-proc-macro-srv` to `<sysroot>/libexec/` |
| ... | ... | @@ -985,6 +977,7 @@ impl Step for LlvmBitcodeLinker { |
| 985 | 977 | extra_features: self.extra_features, |
| 986 | 978 | allow_features: "", |
| 987 | 979 | cargo_args: Vec::new(), |
| 980 | artifact_kind: ToolArtifactKind::Binary, | |
| 988 | 981 | }); |
| 989 | 982 | |
| 990 | 983 | if tool_result.target_compiler.stage > 0 { |
| ... | ... | @@ -1164,6 +1157,7 @@ fn run_tool_build_step( |
| 1164 | 1157 | source_type: SourceType::InTree, |
| 1165 | 1158 | allow_features: "", |
| 1166 | 1159 | cargo_args: vec![], |
| 1160 | artifact_kind: ToolArtifactKind::Binary, | |
| 1167 | 1161 | }); |
| 1168 | 1162 | |
| 1169 | 1163 | // FIXME: This should just be an if-let-chain, but those are unstable. |
| ... | ... | @@ -1242,6 +1236,7 @@ impl Step for TestFloatParse { |
| 1242 | 1236 | extra_features: Vec::new(), |
| 1243 | 1237 | allow_features: "", |
| 1244 | 1238 | cargo_args: Vec::new(), |
| 1239 | artifact_kind: ToolArtifactKind::Binary, | |
| 1245 | 1240 | }) |
| 1246 | 1241 | } |
| 1247 | 1242 | } |
src/bootstrap/src/core/builder/mod.rs+1| ... | ... | @@ -1072,6 +1072,7 @@ impl<'a> Builder<'a> { |
| 1072 | 1072 | dist::PlainSourceTarball, |
| 1073 | 1073 | dist::BuildManifest, |
| 1074 | 1074 | dist::ReproducibleArtifacts, |
| 1075 | dist::Gcc | |
| 1075 | 1076 | ), |
| 1076 | 1077 | Kind::Install => describe!( |
| 1077 | 1078 | install::Docs, |
src/bootstrap/src/utils/metrics.rs+8| ... | ... | @@ -200,6 +200,14 @@ impl BuildMetrics { |
| 200 | 200 | } |
| 201 | 201 | }; |
| 202 | 202 | invocations.push(JsonInvocation { |
| 203 | // The command-line invocation with which bootstrap was invoked. | |
| 204 | // Skip the first argument, as it is a potentially long absolute | |
| 205 | // path that is not interesting. | |
| 206 | cmdline: std::env::args_os() | |
| 207 | .skip(1) | |
| 208 | .map(|arg| arg.to_string_lossy().to_string()) | |
| 209 | .collect::<Vec<_>>() | |
| 210 | .join(" "), | |
| 203 | 211 | start_time: state |
| 204 | 212 | .invocation_start |
| 205 | 213 | .duration_since(SystemTime::UNIX_EPOCH) |
src/build_helper/src/metrics.rs+88| ... | ... | @@ -1,3 +1,5 @@ |
| 1 | use std::time::Duration; | |
| 2 | ||
| 1 | 3 | use serde_derive::{Deserialize, Serialize}; |
| 2 | 4 | |
| 3 | 5 | #[derive(Serialize, Deserialize)] |
| ... | ... | @@ -12,6 +14,8 @@ pub struct JsonRoot { |
| 12 | 14 | #[derive(Serialize, Deserialize)] |
| 13 | 15 | #[serde(rename_all = "snake_case")] |
| 14 | 16 | pub struct JsonInvocation { |
| 17 | // Remembers the command-line invocation with which bootstrap was invoked. | |
| 18 | pub cmdline: String, | |
| 15 | 19 | // Unix timestamp in seconds |
| 16 | 20 | // |
| 17 | 21 | // 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 |
| 98 | 102 | use serde::Deserialize as _; |
| 99 | 103 | Option::<f64>::deserialize(d).map(|f| f.unwrap_or(f64::NAN)) |
| 100 | 104 | } |
| 105 | ||
| 106 | /// Represents a single bootstrap step, with the accumulated duration of all its children. | |
| 107 | #[derive(Clone, Debug)] | |
| 108 | pub struct BuildStep { | |
| 109 | pub r#type: String, | |
| 110 | pub children: Vec<BuildStep>, | |
| 111 | pub duration: Duration, | |
| 112 | } | |
| 113 | ||
| 114 | impl BuildStep { | |
| 115 | /// Create a `BuildStep` representing a single invocation of bootstrap. | |
| 116 | /// The most important thing is that the build step aggregates the | |
| 117 | /// durations of all children, so that it can be easily accessed. | |
| 118 | pub fn from_invocation(invocation: &JsonInvocation) -> Self { | |
| 119 | fn parse(node: &JsonNode) -> Option<BuildStep> { | |
| 120 | match node { | |
| 121 | JsonNode::RustbuildStep { | |
| 122 | type_: kind, | |
| 123 | children, | |
| 124 | duration_excluding_children_sec, | |
| 125 | .. | |
| 126 | } => { | |
| 127 | let children: Vec<_> = children.into_iter().filter_map(parse).collect(); | |
| 128 | let children_duration = children.iter().map(|c| c.duration).sum::<Duration>(); | |
| 129 | Some(BuildStep { | |
| 130 | r#type: kind.to_string(), | |
| 131 | children, | |
| 132 | duration: children_duration | |
| 133 | + Duration::from_secs_f64(*duration_excluding_children_sec), | |
| 134 | }) | |
| 135 | } | |
| 136 | JsonNode::TestSuite(_) => None, | |
| 137 | } | |
| 138 | } | |
| 139 | ||
| 140 | let duration = Duration::from_secs_f64(invocation.duration_including_children_sec); | |
| 141 | let children: Vec<_> = invocation.children.iter().filter_map(parse).collect(); | |
| 142 | Self { r#type: "total".to_string(), children, duration } | |
| 143 | } | |
| 144 | ||
| 145 | pub fn find_all_by_type(&self, r#type: &str) -> Vec<&Self> { | |
| 146 | let mut result = Vec::new(); | |
| 147 | self.find_by_type(r#type, &mut result); | |
| 148 | result | |
| 149 | } | |
| 150 | ||
| 151 | fn find_by_type<'a>(&'a self, r#type: &str, result: &mut Vec<&'a Self>) { | |
| 152 | if self.r#type == r#type { | |
| 153 | result.push(self); | |
| 154 | } | |
| 155 | for child in &self.children { | |
| 156 | child.find_by_type(r#type, result); | |
| 157 | } | |
| 158 | } | |
| 159 | } | |
| 160 | ||
| 161 | /// Writes build steps into a nice indented table. | |
| 162 | pub fn format_build_steps(root: &BuildStep) -> String { | |
| 163 | use std::fmt::Write; | |
| 164 | ||
| 165 | let mut substeps: Vec<(u32, &BuildStep)> = Vec::new(); | |
| 166 | ||
| 167 | fn visit<'a>(step: &'a BuildStep, level: u32, substeps: &mut Vec<(u32, &'a BuildStep)>) { | |
| 168 | substeps.push((level, step)); | |
| 169 | for child in &step.children { | |
| 170 | visit(child, level + 1, substeps); | |
| 171 | } | |
| 172 | } | |
| 173 | ||
| 174 | visit(root, 0, &mut substeps); | |
| 175 | ||
| 176 | let mut output = String::new(); | |
| 177 | for (level, step) in substeps { | |
| 178 | let label = format!( | |
| 179 | "{}{}", | |
| 180 | ".".repeat(level as usize), | |
| 181 | // Bootstrap steps can be generic and thus contain angle brackets (<...>). | |
| 182 | // However, Markdown interprets these as HTML, so we need to escap ethem. | |
| 183 | step.r#type.replace('<', "&lt;").replace('>', "&gt;") | |
| 184 | ); | |
| 185 | writeln!(output, "{label:.<65}{:>8.2}s", step.duration.as_secs_f64()).unwrap(); | |
| 186 | } | |
| 187 | output | |
| 188 | } |
src/ci/citool/Cargo.lock+9| ... | ... | @@ -58,11 +58,20 @@ version = "1.0.95" |
| 58 | 58 | source = "registry+https://github.com/rust-lang/crates.io-index" |
| 59 | 59 | checksum = "34ac096ce696dc2fcabef30516bb13c0a68a11d30131d3df6f04711467681b04" |
| 60 | 60 | |
| 61 | [[package]] | |
| 62 | name = "build_helper" | |
| 63 | version = "0.1.0" | |
| 64 | dependencies = [ | |
| 65 | "serde", | |
| 66 | "serde_derive", | |
| 67 | ] | |
| 68 | ||
| 61 | 69 | [[package]] |
| 62 | 70 | name = "citool" |
| 63 | 71 | version = "0.1.0" |
| 64 | 72 | dependencies = [ |
| 65 | 73 | "anyhow", |
| 74 | "build_helper", | |
| 66 | 75 | "clap", |
| 67 | 76 | "insta", |
| 68 | 77 | "serde", |
src/ci/citool/Cargo.toml+2| ... | ... | @@ -10,6 +10,8 @@ serde = { version = "1", features = ["derive"] } |
| 10 | 10 | serde_yaml = "0.9" |
| 11 | 11 | serde_json = "1" |
| 12 | 12 | |
| 13 | build_helper = { path = "../../build_helper" } | |
| 14 | ||
| 13 | 15 | [dev-dependencies] |
| 14 | 16 | insta = "1" |
| 15 | 17 |
src/ci/citool/src/main.rs+15| ... | ... | @@ -1,3 +1,5 @@ |
| 1 | mod metrics; | |
| 2 | ||
| 1 | 3 | use std::collections::BTreeMap; |
| 2 | 4 | use std::path::{Path, PathBuf}; |
| 3 | 5 | use std::process::Command; |
| ... | ... | @@ -6,6 +8,8 @@ use anyhow::Context; |
| 6 | 8 | use clap::Parser; |
| 7 | 9 | use serde_yaml::Value; |
| 8 | 10 | |
| 11 | use crate::metrics::postprocess_metrics; | |
| 12 | ||
| 9 | 13 | const CI_DIRECTORY: &str = concat!(env!("CARGO_MANIFEST_DIR"), "/.."); |
| 10 | 14 | const DOCKER_DIRECTORY: &str = concat!(env!("CARGO_MANIFEST_DIR"), "/../docker"); |
| 11 | 15 | const JOBS_YML_PATH: &str = concat!(env!("CARGO_MANIFEST_DIR"), "/../github-actions/jobs.yml"); |
| ... | ... | @@ -338,6 +342,14 @@ enum Args { |
| 338 | 342 | #[clap(long = "type", default_value = "auto")] |
| 339 | 343 | job_type: JobType, |
| 340 | 344 | }, |
| 345 | /// Postprocess the metrics.json file generated by bootstrap. | |
| 346 | PostprocessMetrics { | |
| 347 | /// Path to the metrics.json file | |
| 348 | metrics_path: PathBuf, | |
| 349 | /// Path to a file where the postprocessed metrics summary will be stored. | |
| 350 | /// Usually, this will be GITHUB_STEP_SUMMARY on CI. | |
| 351 | summary_path: PathBuf, | |
| 352 | }, | |
| 341 | 353 | } |
| 342 | 354 | |
| 343 | 355 | #[derive(clap::ValueEnum, Clone)] |
| ... | ... | @@ -369,6 +381,9 @@ fn main() -> anyhow::Result<()> { |
| 369 | 381 | Args::RunJobLocally { job_type, name } => { |
| 370 | 382 | run_workflow_locally(load_db(default_jobs_file)?, job_type, name)? |
| 371 | 383 | } |
| 384 | Args::PostprocessMetrics { metrics_path, summary_path } => { | |
| 385 | postprocess_metrics(&metrics_path, &summary_path)?; | |
| 386 | } | |
| 372 | 387 | } |
| 373 | 388 | |
| 374 | 389 | Ok(()) |
src/ci/citool/src/metrics.rs created+164| ... | ... | @@ -0,0 +1,164 @@ |
| 1 | use std::collections::BTreeMap; | |
| 2 | use std::fs::File; | |
| 3 | use std::io::Write; | |
| 4 | use std::path::Path; | |
| 5 | ||
| 6 | use anyhow::Context; | |
| 7 | use build_helper::metrics::{ | |
| 8 | BuildStep, JsonNode, JsonRoot, TestOutcome, TestSuite, TestSuiteMetadata, format_build_steps, | |
| 9 | }; | |
| 10 | ||
| 11 | pub fn postprocess_metrics(metrics_path: &Path, summary_path: &Path) -> anyhow::Result<()> { | |
| 12 | let metrics = load_metrics(metrics_path)?; | |
| 13 | ||
| 14 | let mut file = File::options() | |
| 15 | .append(true) | |
| 16 | .create(true) | |
| 17 | .open(summary_path) | |
| 18 | .with_context(|| format!("Cannot open summary file at {summary_path:?}"))?; | |
| 19 | ||
| 20 | if !metrics.invocations.is_empty() { | |
| 21 | writeln!(file, "# Bootstrap steps")?; | |
| 22 | record_bootstrap_step_durations(&metrics, &mut file)?; | |
| 23 | record_test_suites(&metrics, &mut file)?; | |
| 24 | } | |
| 25 | ||
| 26 | Ok(()) | |
| 27 | } | |
| 28 | ||
| 29 | fn record_bootstrap_step_durations(metrics: &JsonRoot, file: &mut File) -> anyhow::Result<()> { | |
| 30 | for invocation in &metrics.invocations { | |
| 31 | let step = BuildStep::from_invocation(invocation); | |
| 32 | let table = format_build_steps(&step); | |
| 33 | eprintln!("Step `{}`\n{table}\n", invocation.cmdline); | |
| 34 | writeln!( | |
| 35 | file, | |
| 36 | r"<details> | |
| 37 | <summary>{}</summary> | |
| 38 | <pre><code>{table}</code></pre> | |
| 39 | </details> | |
| 40 | ", | |
| 41 | invocation.cmdline | |
| 42 | )?; | |
| 43 | } | |
| 44 | eprintln!("Recorded {} bootstrap invocation(s)", metrics.invocations.len()); | |
| 45 | ||
| 46 | Ok(()) | |
| 47 | } | |
| 48 | ||
| 49 | fn record_test_suites(metrics: &JsonRoot, file: &mut File) -> anyhow::Result<()> { | |
| 50 | let suites = get_test_suites(&metrics); | |
| 51 | ||
| 52 | if !suites.is_empty() { | |
| 53 | let aggregated = aggregate_test_suites(&suites); | |
| 54 | let table = render_table(aggregated); | |
| 55 | writeln!(file, "\n# Test results\n")?; | |
| 56 | writeln!(file, "{table}")?; | |
| 57 | } else { | |
| 58 | eprintln!("No test suites found in metrics"); | |
| 59 | } | |
| 60 | ||
| 61 | Ok(()) | |
| 62 | } | |
| 63 | ||
| 64 | fn render_table(suites: BTreeMap<String, TestSuiteRecord>) -> String { | |
| 65 | use std::fmt::Write; | |
| 66 | ||
| 67 | let mut table = "| Test suite | Passed ✅ | Ignored 🚫 | Failed ❌ |\n".to_string(); | |
| 68 | writeln!(table, "|:------|------:|------:|------:|").unwrap(); | |
| 69 | ||
| 70 | fn write_row( | |
| 71 | buffer: &mut String, | |
| 72 | name: &str, | |
| 73 | record: &TestSuiteRecord, | |
| 74 | surround: &str, | |
| 75 | ) -> std::fmt::Result { | |
| 76 | let TestSuiteRecord { passed, ignored, failed } = record; | |
| 77 | let total = (record.passed + record.ignored + record.failed) as f64; | |
| 78 | let passed_pct = ((*passed as f64) / total) * 100.0; | |
| 79 | let ignored_pct = ((*ignored as f64) / total) * 100.0; | |
| 80 | let failed_pct = ((*failed as f64) / total) * 100.0; | |
| 81 | ||
| 82 | write!(buffer, "| {surround}{name}{surround} |")?; | |
| 83 | write!(buffer, " {surround}{passed} ({passed_pct:.0}%){surround} |")?; | |
| 84 | write!(buffer, " {surround}{ignored} ({ignored_pct:.0}%){surround} |")?; | |
| 85 | writeln!(buffer, " {surround}{failed} ({failed_pct:.0}%){surround} |")?; | |
| 86 | ||
| 87 | Ok(()) | |
| 88 | } | |
| 89 | ||
| 90 | let mut total = TestSuiteRecord::default(); | |
| 91 | for (name, record) in suites { | |
| 92 | write_row(&mut table, &name, &record, "").unwrap(); | |
| 93 | total.passed += record.passed; | |
| 94 | total.ignored += record.ignored; | |
| 95 | total.failed += record.failed; | |
| 96 | } | |
| 97 | write_row(&mut table, "Total", &total, "**").unwrap(); | |
| 98 | table | |
| 99 | } | |
| 100 | ||
| 101 | #[derive(Default)] | |
| 102 | struct TestSuiteRecord { | |
| 103 | passed: u64, | |
| 104 | ignored: u64, | |
| 105 | failed: u64, | |
| 106 | } | |
| 107 | ||
| 108 | fn aggregate_test_suites(suites: &[&TestSuite]) -> BTreeMap<String, TestSuiteRecord> { | |
| 109 | let mut records: BTreeMap<String, TestSuiteRecord> = BTreeMap::new(); | |
| 110 | for suite in suites { | |
| 111 | let name = match &suite.metadata { | |
| 112 | TestSuiteMetadata::CargoPackage { crates, stage, .. } => { | |
| 113 | format!("{} (stage {stage})", crates.join(", ")) | |
| 114 | } | |
| 115 | TestSuiteMetadata::Compiletest { suite, stage, .. } => { | |
| 116 | format!("{suite} (stage {stage})") | |
| 117 | } | |
| 118 | }; | |
| 119 | let record = records.entry(name).or_default(); | |
| 120 | for test in &suite.tests { | |
| 121 | match test.outcome { | |
| 122 | TestOutcome::Passed => { | |
| 123 | record.passed += 1; | |
| 124 | } | |
| 125 | TestOutcome::Failed => { | |
| 126 | record.failed += 1; | |
| 127 | } | |
| 128 | TestOutcome::Ignored { .. } => { | |
| 129 | record.ignored += 1; | |
| 130 | } | |
| 131 | } | |
| 132 | } | |
| 133 | } | |
| 134 | records | |
| 135 | } | |
| 136 | ||
| 137 | fn get_test_suites(metrics: &JsonRoot) -> Vec<&TestSuite> { | |
| 138 | fn visit_test_suites<'a>(nodes: &'a [JsonNode], suites: &mut Vec<&'a TestSuite>) { | |
| 139 | for node in nodes { | |
| 140 | match node { | |
| 141 | JsonNode::RustbuildStep { children, .. } => { | |
| 142 | visit_test_suites(&children, suites); | |
| 143 | } | |
| 144 | JsonNode::TestSuite(suite) => { | |
| 145 | suites.push(&suite); | |
| 146 | } | |
| 147 | } | |
| 148 | } | |
| 149 | } | |
| 150 | ||
| 151 | let mut suites = vec![]; | |
| 152 | for invocation in &metrics.invocations { | |
| 153 | visit_test_suites(&invocation.children, &mut suites); | |
| 154 | } | |
| 155 | suites | |
| 156 | } | |
| 157 | ||
| 158 | fn load_metrics(path: &Path) -> anyhow::Result<JsonRoot> { | |
| 159 | let metrics = std::fs::read_to_string(path) | |
| 160 | .with_context(|| format!("Cannot read JSON metrics from {path:?}"))?; | |
| 161 | let metrics: JsonRoot = serde_json::from_str(&metrics) | |
| 162 | .with_context(|| format!("Cannot deserialize JSON metrics from {path:?}"))?; | |
| 163 | Ok(metrics) | |
| 164 | } |
src/ci/docker/host-x86_64/dist-x86_64-linux/Dockerfile+1-1| ... | ... | @@ -101,7 +101,7 @@ ENV SCRIPT python3 ../x.py build --set rust.debug=true opt-dist && \ |
| 101 | 101 | ./build/$HOSTS/stage0-tools-bin/opt-dist linux-ci -- python3 ../x.py dist \ |
| 102 | 102 | --host $HOSTS --target $HOSTS \ |
| 103 | 103 | --include-default-paths \ |
| 104 | build-manifest bootstrap | |
| 104 | build-manifest bootstrap gcc | |
| 105 | 105 | ENV CARGO_TARGET_X86_64_UNKNOWN_LINUX_GNU_LINKER=clang |
| 106 | 106 | |
| 107 | 107 | # This is the only builder which will create source tarballs |
src/ci/docker/scripts/rfl-build.sh+8-10| ... | ... | @@ -8,16 +8,10 @@ LINUX_VERSION=v6.14-rc3 |
| 8 | 8 | ../x.py build --stage 2 library rustdoc clippy rustfmt |
| 9 | 9 | ../x.py build --stage 0 cargo |
| 10 | 10 | |
| 11 | # Install rustup so that we can use the built toolchain easily, and also | |
| 12 | # install bindgen in an easy way. | |
| 13 | curl --proto '=https' --tlsv1.2 -sSf -o rustup.sh https://sh.rustup.rs | |
| 14 | sh rustup.sh -y --default-toolchain none | |
| 11 | BUILD_DIR=$(realpath ./build/x86_64-unknown-linux-gnu) | |
| 15 | 12 | |
| 16 | source /cargo/env | |
| 17 | ||
| 18 | BUILD_DIR=$(realpath ./build) | |
| 19 | rustup toolchain link local "${BUILD_DIR}"/x86_64-unknown-linux-gnu/stage2 | |
| 20 | rustup default local | |
| 13 | # Provide path to rustc, rustdoc, clippy-driver and rustfmt to RfL | |
| 14 | export PATH=${PATH}:${BUILD_DIR}/stage2/bin | |
| 21 | 15 | |
| 22 | 16 | mkdir -p rfl |
| 23 | 17 | cd rfl |
| ... | ... | @@ -33,10 +27,14 @@ git -C linux fetch --depth 1 origin ${LINUX_VERSION} |
| 33 | 27 | git -C linux checkout FETCH_HEAD |
| 34 | 28 | |
| 35 | 29 | # Install bindgen |
| 36 | "${BUILD_DIR}"/x86_64-unknown-linux-gnu/stage0/bin/cargo install \ | |
| 30 | "${BUILD_DIR}"/stage0/bin/cargo install \ | |
| 37 | 31 | --version $(linux/scripts/min-tool-version.sh bindgen) \ |
| 32 | --root ${BUILD_DIR}/bindgen \ | |
| 38 | 33 | bindgen-cli |
| 39 | 34 | |
| 35 | # Provide path to bindgen to RfL | |
| 36 | export PATH=${PATH}:${BUILD_DIR}/bindgen/bin | |
| 37 | ||
| 40 | 38 | # Configure Rust for Linux |
| 41 | 39 | cat <<EOF > linux/kernel/configs/rfl-for-rust-ci.config |
| 42 | 40 | # CONFIG_WERROR is not set |
src/ci/github-actions/jobs.yml+2-3| ... | ... | @@ -271,9 +271,8 @@ auto: |
| 271 | 271 | |
| 272 | 272 | # Tests integration with Rust for Linux. |
| 273 | 273 | # Builds stage 1 compiler and tries to compile a few RfL examples with it. |
| 274 | # FIXME: fix rustup 1.28 issue | |
| 275 | # - name: x86_64-rust-for-linux | |
| 276 | # <<: *job-linux-4c | |
| 274 | - name: x86_64-rust-for-linux | |
| 275 | <<: *job-linux-4c | |
| 277 | 276 | |
| 278 | 277 | - name: x86_64-gnu |
| 279 | 278 | <<: *job-linux-4c |
src/librustdoc/Cargo.toml+1-1| ... | ... | @@ -1,7 +1,7 @@ |
| 1 | 1 | [package] |
| 2 | 2 | name = "rustdoc" |
| 3 | 3 | version = "0.0.0" |
| 4 | edition = "2021" | |
| 4 | edition = "2024" | |
| 5 | 5 | build = "build.rs" |
| 6 | 6 | |
| 7 | 7 | [lib] |
src/librustdoc/clean/cfg.rs+2-2| ... | ... | @@ -48,12 +48,12 @@ impl Cfg { |
| 48 | 48 | exclude: &FxHashSet<Cfg>, |
| 49 | 49 | ) -> Result<Option<Cfg>, InvalidCfgError> { |
| 50 | 50 | match nested_cfg { |
| 51 | MetaItemInner::MetaItem(ref cfg) => Cfg::parse_without(cfg, exclude), | |
| 51 | MetaItemInner::MetaItem(cfg) => Cfg::parse_without(cfg, exclude), | |
| 52 | 52 | MetaItemInner::Lit(MetaItemLit { kind: LitKind::Bool(b), .. }) => match *b { |
| 53 | 53 | true => Ok(Some(Cfg::True)), |
| 54 | 54 | false => Ok(Some(Cfg::False)), |
| 55 | 55 | }, |
| 56 | MetaItemInner::Lit(ref lit) => { | |
| 56 | MetaItemInner::Lit(lit) => { | |
| 57 | 57 | Err(InvalidCfgError { msg: "unexpected literal", span: lit.span }) |
| 58 | 58 | } |
| 59 | 59 | } |
src/librustdoc/clean/mod.rs+2-2| ... | ... | @@ -741,7 +741,7 @@ pub(crate) fn clean_generics<'tcx>( |
| 741 | 741 | for p in gens.params.iter().filter(|p| !is_impl_trait(p) && !is_elided_lifetime(p)) { |
| 742 | 742 | let mut p = clean_generic_param(cx, Some(gens), p); |
| 743 | 743 | match &mut p.kind { |
| 744 | GenericParamDefKind::Lifetime { ref mut outlives } => { | |
| 744 | GenericParamDefKind::Lifetime { outlives } => { | |
| 745 | 745 | if let Some(region_pred) = region_predicates.get_mut(&Lifetime(p.name)) { |
| 746 | 746 | // We merge bounds in the `where` clause. |
| 747 | 747 | for outlive in outlives.drain(..) { |
| ... | ... | @@ -2688,7 +2688,7 @@ fn filter_doc_attr_ident(ident: Symbol, is_inline: bool) -> bool { |
| 2688 | 2688 | /// Before calling this function, make sure `normal` is a `#[doc]` attribute. |
| 2689 | 2689 | fn filter_doc_attr(args: &mut hir::AttrArgs, is_inline: bool) { |
| 2690 | 2690 | match args { |
| 2691 | hir::AttrArgs::Delimited(ref mut args) => { | |
| 2691 | hir::AttrArgs::Delimited(args) => { | |
| 2692 | 2692 | let tokens = filter_tokens_from_list(&args.tokens, |token| { |
| 2693 | 2693 | !matches!( |
| 2694 | 2694 | token, |
src/librustdoc/clean/types.rs+4-4| ... | ... | @@ -502,7 +502,7 @@ impl Item { |
| 502 | 502 | let Some(links) = cx.cache().intra_doc_links.get(&self.item_id) else { return vec![] }; |
| 503 | 503 | links |
| 504 | 504 | .iter() |
| 505 | .filter_map(|ItemLink { link: s, link_text, page_id: id, ref fragment }| { | |
| 505 | .filter_map(|ItemLink { link: s, link_text, page_id: id, fragment }| { | |
| 506 | 506 | debug!(?id); |
| 507 | 507 | if let Ok((mut href, ..)) = href(*id, cx) { |
| 508 | 508 | debug!(?href); |
| ... | ... | @@ -1150,7 +1150,7 @@ pub(crate) struct Attributes { |
| 1150 | 1150 | } |
| 1151 | 1151 | |
| 1152 | 1152 | impl Attributes { |
| 1153 | pub(crate) fn lists(&self, name: Symbol) -> impl Iterator<Item = ast::MetaItemInner> + '_ { | |
| 1153 | pub(crate) fn lists(&self, name: Symbol) -> impl Iterator<Item = ast::MetaItemInner> { | |
| 1154 | 1154 | hir_attr_lists(&self.other_attrs[..], name) |
| 1155 | 1155 | } |
| 1156 | 1156 | |
| ... | ... | @@ -1864,7 +1864,7 @@ impl PrimitiveType { |
| 1864 | 1864 | .copied() |
| 1865 | 1865 | } |
| 1866 | 1866 | |
| 1867 | pub(crate) fn all_impls(tcx: TyCtxt<'_>) -> impl Iterator<Item = DefId> + '_ { | |
| 1867 | pub(crate) fn all_impls(tcx: TyCtxt<'_>) -> impl Iterator<Item = DefId> { | |
| 1868 | 1868 | Self::simplified_types() |
| 1869 | 1869 | .values() |
| 1870 | 1870 | .flatten() |
| ... | ... | @@ -2259,7 +2259,7 @@ impl GenericArgs { |
| 2259 | 2259 | GenericArgs::Parenthesized { inputs, output } => inputs.is_empty() && output.is_none(), |
| 2260 | 2260 | } |
| 2261 | 2261 | } |
| 2262 | pub(crate) fn constraints<'a>(&'a self) -> Box<dyn Iterator<Item = AssocItemConstraint> + 'a> { | |
| 2262 | pub(crate) fn constraints(&self) -> Box<dyn Iterator<Item = AssocItemConstraint> + '_> { | |
| 2263 | 2263 | match self { |
| 2264 | 2264 | GenericArgs::AngleBracketed { constraints, .. } => { |
| 2265 | 2265 | Box::new(constraints.iter().cloned()) |
src/librustdoc/clean/utils.rs+7-6| ... | ... | @@ -60,7 +60,7 @@ pub(crate) fn krate(cx: &mut DocContext<'_>) -> Crate { |
| 60 | 60 | let primitives = local_crate.primitives(cx.tcx); |
| 61 | 61 | let keywords = local_crate.keywords(cx.tcx); |
| 62 | 62 | { |
| 63 | let ItemKind::ModuleItem(ref mut m) = &mut module.inner.kind else { unreachable!() }; | |
| 63 | let ItemKind::ModuleItem(m) = &mut module.inner.kind else { unreachable!() }; | |
| 64 | 64 | m.items.extend(primitives.iter().map(|&(def_id, prim)| { |
| 65 | 65 | Item::from_def_id_and_parts( |
| 66 | 66 | def_id, |
| ... | ... | @@ -302,7 +302,7 @@ pub(crate) fn name_from_pat(p: &hir::Pat<'_>) -> Symbol { |
| 302 | 302 | use rustc_hir::*; |
| 303 | 303 | debug!("trying to get a name from pattern: {p:?}"); |
| 304 | 304 | |
| 305 | Symbol::intern(&match p.kind { | |
| 305 | Symbol::intern(&match &p.kind { | |
| 306 | 306 | // FIXME(never_patterns): does this make sense? |
| 307 | 307 | PatKind::Wild |
| 308 | 308 | | PatKind::Err(_) |
| ... | ... | @@ -313,8 +313,9 @@ pub(crate) fn name_from_pat(p: &hir::Pat<'_>) -> Symbol { |
| 313 | 313 | } |
| 314 | 314 | PatKind::Binding(_, _, ident, _) => return ident.name, |
| 315 | 315 | PatKind::Box(p) | PatKind::Ref(p, _) | PatKind::Guard(p, _) => return name_from_pat(p), |
| 316 | PatKind::TupleStruct(ref p, ..) | |
| 317 | | PatKind::Expr(PatExpr { kind: PatExprKind::Path(ref p), .. }) => qpath_to_string(p), | |
| 316 | PatKind::TupleStruct(p, ..) | PatKind::Expr(PatExpr { kind: PatExprKind::Path(p), .. }) => { | |
| 317 | qpath_to_string(p) | |
| 318 | } | |
| 318 | 319 | PatKind::Or(pats) => { |
| 319 | 320 | fmt::from_fn(|f| pats.iter().map(|p| name_from_pat(p)).joined(" | ", f)).to_string() |
| 320 | 321 | } |
| ... | ... | @@ -329,7 +330,7 @@ pub(crate) fn name_from_pat(p: &hir::Pat<'_>) -> Symbol { |
| 329 | 330 | return Symbol::intern("()"); |
| 330 | 331 | } |
| 331 | 332 | PatKind::Slice(begin, mid, end) => { |
| 332 | fn print_pat<'a>(pat: &'a Pat<'a>, wild: bool) -> impl Display + 'a { | |
| 333 | fn print_pat(pat: &Pat<'_>, wild: bool) -> impl Display { | |
| 333 | 334 | fmt::from_fn(move |f| { |
| 334 | 335 | if wild { |
| 335 | 336 | f.write_str("..")?; |
| ... | ... | @@ -493,7 +494,7 @@ pub(crate) fn resolve_type(cx: &mut DocContext<'_>, path: Path) -> Type { |
| 493 | 494 | pub(crate) fn synthesize_auto_trait_and_blanket_impls( |
| 494 | 495 | cx: &mut DocContext<'_>, |
| 495 | 496 | item_def_id: DefId, |
| 496 | ) -> impl Iterator<Item = Item> { | |
| 497 | ) -> impl Iterator<Item = Item> + use<> { | |
| 497 | 498 | let auto_impls = cx |
| 498 | 499 | .sess() |
| 499 | 500 | .prof |
src/librustdoc/html/format.rs+46-100| ... | ... | @@ -15,7 +15,6 @@ use std::iter::{self, once}; |
| 15 | 15 | use itertools::Either; |
| 16 | 16 | use rustc_abi::ExternAbi; |
| 17 | 17 | use rustc_attr_parsing::{ConstStability, StabilityLevel, StableSince}; |
| 18 | use rustc_data_structures::captures::Captures; | |
| 19 | 18 | use rustc_data_structures::fx::FxHashSet; |
| 20 | 19 | use rustc_hir as hir; |
| 21 | 20 | use rustc_hir::def::DefKind; |
| ... | ... | @@ -41,10 +40,10 @@ pub(crate) fn write_str(s: &mut String, f: fmt::Arguments<'_>) { |
| 41 | 40 | s.write_fmt(f).unwrap(); |
| 42 | 41 | } |
| 43 | 42 | |
| 44 | pub(crate) fn print_generic_bounds<'a, 'tcx: 'a>( | |
| 45 | bounds: &'a [clean::GenericBound], | |
| 46 | cx: &'a Context<'tcx>, | |
| 47 | ) -> impl Display + 'a + Captures<'tcx> { | |
| 43 | pub(crate) fn print_generic_bounds( | |
| 44 | bounds: &[clean::GenericBound], | |
| 45 | cx: &Context<'_>, | |
| 46 | ) -> impl Display { | |
| 48 | 47 | fmt::from_fn(move |f| { |
| 49 | 48 | let mut bounds_dup = FxHashSet::default(); |
| 50 | 49 | |
| ... | ... | @@ -57,10 +56,7 @@ pub(crate) fn print_generic_bounds<'a, 'tcx: 'a>( |
| 57 | 56 | } |
| 58 | 57 | |
| 59 | 58 | impl clean::GenericParamDef { |
| 60 | pub(crate) fn print<'a, 'tcx: 'a>( | |
| 61 | &'a self, | |
| 62 | cx: &'a Context<'tcx>, | |
| 63 | ) -> impl Display + 'a + Captures<'tcx> { | |
| 59 | pub(crate) fn print(&self, cx: &Context<'_>) -> impl Display { | |
| 64 | 60 | fmt::from_fn(move |f| match &self.kind { |
| 65 | 61 | clean::GenericParamDefKind::Lifetime { outlives } => { |
| 66 | 62 | write!(f, "{}", self.name)?; |
| ... | ... | @@ -80,7 +76,7 @@ impl clean::GenericParamDef { |
| 80 | 76 | print_generic_bounds(bounds, cx).fmt(f)?; |
| 81 | 77 | } |
| 82 | 78 | |
| 83 | if let Some(ref ty) = default { | |
| 79 | if let Some(ty) = default { | |
| 84 | 80 | f.write_str(" = ")?; |
| 85 | 81 | ty.print(cx).fmt(f)?; |
| 86 | 82 | } |
| ... | ... | @@ -107,10 +103,7 @@ impl clean::GenericParamDef { |
| 107 | 103 | } |
| 108 | 104 | |
| 109 | 105 | impl clean::Generics { |
| 110 | pub(crate) fn print<'a, 'tcx: 'a>( | |
| 111 | &'a self, | |
| 112 | cx: &'a Context<'tcx>, | |
| 113 | ) -> impl Display + 'a + Captures<'tcx> { | |
| 106 | pub(crate) fn print(&self, cx: &Context<'_>) -> impl Display { | |
| 114 | 107 | fmt::from_fn(move |f| { |
| 115 | 108 | let mut real_params = self.params.iter().filter(|p| !p.is_synthetic_param()).peekable(); |
| 116 | 109 | if real_params.peek().is_none() { |
| ... | ... | @@ -134,10 +127,7 @@ pub(crate) enum Ending { |
| 134 | 127 | NoNewline, |
| 135 | 128 | } |
| 136 | 129 | |
| 137 | fn print_where_predicate<'a, 'tcx: 'a>( | |
| 138 | predicate: &'a clean::WherePredicate, | |
| 139 | cx: &'a Context<'tcx>, | |
| 140 | ) -> impl Display + 'a + Captures<'tcx> { | |
| 130 | fn print_where_predicate(predicate: &clean::WherePredicate, cx: &Context<'_>) -> impl Display { | |
| 141 | 131 | fmt::from_fn(move |f| { |
| 142 | 132 | match predicate { |
| 143 | 133 | clean::WherePredicate::BoundPredicate { ty, bounds, bound_params } => { |
| ... | ... | @@ -173,12 +163,12 @@ fn print_where_predicate<'a, 'tcx: 'a>( |
| 173 | 163 | /// * The Generics from which to emit a where-clause. |
| 174 | 164 | /// * The number of spaces to indent each line with. |
| 175 | 165 | /// * Whether the where-clause needs to add a comma and newline after the last bound. |
| 176 | pub(crate) fn print_where_clause<'a, 'tcx: 'a>( | |
| 177 | gens: &'a clean::Generics, | |
| 178 | cx: &'a Context<'tcx>, | |
| 166 | pub(crate) fn print_where_clause( | |
| 167 | gens: &clean::Generics, | |
| 168 | cx: &Context<'_>, | |
| 179 | 169 | indent: usize, |
| 180 | 170 | ending: Ending, |
| 181 | ) -> Option<impl Display + 'a + Captures<'tcx>> { | |
| 171 | ) -> Option<impl Display> { | |
| 182 | 172 | if gens.where_predicates.is_empty() { |
| 183 | 173 | return None; |
| 184 | 174 | } |
| ... | ... | @@ -250,13 +240,13 @@ pub(crate) fn print_where_clause<'a, 'tcx: 'a>( |
| 250 | 240 | } |
| 251 | 241 | |
| 252 | 242 | impl clean::Lifetime { |
| 253 | pub(crate) fn print(&self) -> impl Display + '_ { | |
| 243 | pub(crate) fn print(&self) -> impl Display { | |
| 254 | 244 | self.0.as_str() |
| 255 | 245 | } |
| 256 | 246 | } |
| 257 | 247 | |
| 258 | 248 | impl clean::ConstantKind { |
| 259 | pub(crate) fn print(&self, tcx: TyCtxt<'_>) -> impl Display + '_ { | |
| 249 | pub(crate) fn print(&self, tcx: TyCtxt<'_>) -> impl Display { | |
| 260 | 250 | let expr = self.expr(tcx); |
| 261 | 251 | fmt::from_fn(move |f| { |
| 262 | 252 | if f.alternate() { f.write_str(&expr) } else { write!(f, "{}", Escape(&expr)) } |
| ... | ... | @@ -265,7 +255,7 @@ impl clean::ConstantKind { |
| 265 | 255 | } |
| 266 | 256 | |
| 267 | 257 | impl clean::PolyTrait { |
| 268 | fn print<'a, 'tcx: 'a>(&'a self, cx: &'a Context<'tcx>) -> impl Display + 'a + Captures<'tcx> { | |
| 258 | fn print(&self, cx: &Context<'_>) -> impl Display { | |
| 269 | 259 | fmt::from_fn(move |f| { |
| 270 | 260 | print_higher_ranked_params_with_space(&self.generic_params, cx, "for").fmt(f)?; |
| 271 | 261 | self.trait_.print(cx).fmt(f) |
| ... | ... | @@ -274,10 +264,7 @@ impl clean::PolyTrait { |
| 274 | 264 | } |
| 275 | 265 | |
| 276 | 266 | impl clean::GenericBound { |
| 277 | pub(crate) fn print<'a, 'tcx: 'a>( | |
| 278 | &'a self, | |
| 279 | cx: &'a Context<'tcx>, | |
| 280 | ) -> impl Display + 'a + Captures<'tcx> { | |
| 267 | pub(crate) fn print(&self, cx: &Context<'_>) -> impl Display { | |
| 281 | 268 | fmt::from_fn(move |f| match self { |
| 282 | 269 | clean::GenericBound::Outlives(lt) => write!(f, "{}", lt.print()), |
| 283 | 270 | clean::GenericBound::TraitBound(ty, modifiers) => { |
| ... | ... | @@ -304,7 +291,7 @@ impl clean::GenericBound { |
| 304 | 291 | } |
| 305 | 292 | |
| 306 | 293 | impl clean::GenericArgs { |
| 307 | fn print<'a, 'tcx: 'a>(&'a self, cx: &'a Context<'tcx>) -> impl Display + 'a + Captures<'tcx> { | |
| 294 | fn print(&self, cx: &Context<'_>) -> impl Display { | |
| 308 | 295 | fmt::from_fn(move |f| { |
| 309 | 296 | match self { |
| 310 | 297 | clean::GenericArgs::AngleBracketed { args, constraints } => { |
| ... | ... | @@ -809,11 +796,11 @@ fn primitive_link_fragment( |
| 809 | 796 | Ok(()) |
| 810 | 797 | } |
| 811 | 798 | |
| 812 | fn tybounds<'a, 'tcx: 'a>( | |
| 813 | bounds: &'a [clean::PolyTrait], | |
| 814 | lt: &'a Option<clean::Lifetime>, | |
| 815 | cx: &'a Context<'tcx>, | |
| 816 | ) -> impl Display + 'a + Captures<'tcx> { | |
| 799 | fn tybounds( | |
| 800 | bounds: &[clean::PolyTrait], | |
| 801 | lt: &Option<clean::Lifetime>, | |
| 802 | cx: &Context<'_>, | |
| 803 | ) -> impl Display { | |
| 817 | 804 | fmt::from_fn(move |f| { |
| 818 | 805 | bounds.iter().map(|bound| bound.print(cx)).joined(" + ", f)?; |
| 819 | 806 | if let Some(lt) = lt { |
| ... | ... | @@ -825,11 +812,11 @@ fn tybounds<'a, 'tcx: 'a>( |
| 825 | 812 | }) |
| 826 | 813 | } |
| 827 | 814 | |
| 828 | fn print_higher_ranked_params_with_space<'a, 'tcx: 'a>( | |
| 829 | params: &'a [clean::GenericParamDef], | |
| 830 | cx: &'a Context<'tcx>, | |
| 815 | fn print_higher_ranked_params_with_space( | |
| 816 | params: &[clean::GenericParamDef], | |
| 817 | cx: &Context<'_>, | |
| 831 | 818 | keyword: &'static str, |
| 832 | ) -> impl Display + 'a + Captures<'tcx> { | |
| 819 | ) -> impl Display { | |
| 833 | 820 | fmt::from_fn(move |f| { |
| 834 | 821 | if !params.is_empty() { |
| 835 | 822 | f.write_str(keyword)?; |
| ... | ... | @@ -841,11 +828,7 @@ fn print_higher_ranked_params_with_space<'a, 'tcx: 'a>( |
| 841 | 828 | }) |
| 842 | 829 | } |
| 843 | 830 | |
| 844 | pub(crate) fn anchor<'a: 'cx, 'cx>( | |
| 845 | did: DefId, | |
| 846 | text: Symbol, | |
| 847 | cx: &'cx Context<'a>, | |
| 848 | ) -> impl Display + Captures<'a> + 'cx { | |
| 831 | pub(crate) fn anchor(did: DefId, text: Symbol, cx: &Context<'_>) -> impl Display { | |
| 849 | 832 | fmt::from_fn(move |f| { |
| 850 | 833 | let parts = href(did, cx); |
| 851 | 834 | if let Ok((url, short_ty, fqp)) = parts { |
| ... | ... | @@ -1121,29 +1104,19 @@ fn fmt_type( |
| 1121 | 1104 | } |
| 1122 | 1105 | |
| 1123 | 1106 | impl clean::Type { |
| 1124 | pub(crate) fn print<'b, 'a: 'b, 'tcx: 'a>( | |
| 1125 | &'a self, | |
| 1126 | cx: &'a Context<'tcx>, | |
| 1127 | ) -> impl Display + 'b + Captures<'tcx> { | |
| 1107 | pub(crate) fn print(&self, cx: &Context<'_>) -> impl Display { | |
| 1128 | 1108 | fmt::from_fn(move |f| fmt_type(self, f, false, cx)) |
| 1129 | 1109 | } |
| 1130 | 1110 | } |
| 1131 | 1111 | |
| 1132 | 1112 | impl clean::Path { |
| 1133 | pub(crate) fn print<'b, 'a: 'b, 'tcx: 'a>( | |
| 1134 | &'a self, | |
| 1135 | cx: &'a Context<'tcx>, | |
| 1136 | ) -> impl Display + 'b + Captures<'tcx> { | |
| 1113 | pub(crate) fn print(&self, cx: &Context<'_>) -> impl Display { | |
| 1137 | 1114 | fmt::from_fn(move |f| resolved_path(f, self.def_id(), self, false, false, cx)) |
| 1138 | 1115 | } |
| 1139 | 1116 | } |
| 1140 | 1117 | |
| 1141 | 1118 | impl clean::Impl { |
| 1142 | pub(crate) fn print<'a, 'tcx: 'a>( | |
| 1143 | &'a self, | |
| 1144 | use_absolute: bool, | |
| 1145 | cx: &'a Context<'tcx>, | |
| 1146 | ) -> impl Display + 'a + Captures<'tcx> { | |
| 1119 | pub(crate) fn print(&self, use_absolute: bool, cx: &Context<'_>) -> impl Display { | |
| 1147 | 1120 | fmt::from_fn(move |f| { |
| 1148 | 1121 | f.write_str("impl")?; |
| 1149 | 1122 | self.generics.print(cx).fmt(f)?; |
| ... | ... | @@ -1182,12 +1155,12 @@ impl clean::Impl { |
| 1182 | 1155 | print_where_clause(&self.generics, cx, 0, Ending::Newline).maybe_display().fmt(f) |
| 1183 | 1156 | }) |
| 1184 | 1157 | } |
| 1185 | fn print_type<'a, 'tcx: 'a>( | |
| 1158 | fn print_type( | |
| 1186 | 1159 | &self, |
| 1187 | 1160 | type_: &clean::Type, |
| 1188 | 1161 | f: &mut fmt::Formatter<'_>, |
| 1189 | 1162 | use_absolute: bool, |
| 1190 | cx: &'a Context<'tcx>, | |
| 1163 | cx: &Context<'_>, | |
| 1191 | 1164 | ) -> Result<(), fmt::Error> { |
| 1192 | 1165 | if let clean::Type::Tuple(types) = type_ |
| 1193 | 1166 | && let [clean::Type::Generic(name)] = &types[..] |
| ... | ... | @@ -1258,10 +1231,7 @@ impl clean::Impl { |
| 1258 | 1231 | } |
| 1259 | 1232 | |
| 1260 | 1233 | impl clean::Arguments { |
| 1261 | pub(crate) fn print<'a, 'tcx: 'a>( | |
| 1262 | &'a self, | |
| 1263 | cx: &'a Context<'tcx>, | |
| 1264 | ) -> impl Display + 'a + Captures<'tcx> { | |
| 1234 | pub(crate) fn print(&self, cx: &Context<'_>) -> impl Display { | |
| 1265 | 1235 | fmt::from_fn(move |f| { |
| 1266 | 1236 | self.values |
| 1267 | 1237 | .iter() |
| ... | ... | @@ -1301,10 +1271,7 @@ impl Display for Indent { |
| 1301 | 1271 | } |
| 1302 | 1272 | |
| 1303 | 1273 | impl clean::FnDecl { |
| 1304 | pub(crate) fn print<'b, 'a: 'b, 'tcx: 'a>( | |
| 1305 | &'a self, | |
| 1306 | cx: &'a Context<'tcx>, | |
| 1307 | ) -> impl Display + 'b + Captures<'tcx> { | |
| 1274 | pub(crate) fn print(&self, cx: &Context<'_>) -> impl Display { | |
| 1308 | 1275 | fmt::from_fn(move |f| { |
| 1309 | 1276 | let ellipsis = if self.c_variadic { ", ..." } else { "" }; |
| 1310 | 1277 | if f.alternate() { |
| ... | ... | @@ -1333,12 +1300,12 @@ impl clean::FnDecl { |
| 1333 | 1300 | /// are preserved. |
| 1334 | 1301 | /// * `indent`: The number of spaces to indent each successive line with, if line-wrapping is |
| 1335 | 1302 | /// necessary. |
| 1336 | pub(crate) fn full_print<'a, 'tcx: 'a>( | |
| 1337 | &'a self, | |
| 1303 | pub(crate) fn full_print( | |
| 1304 | &self, | |
| 1338 | 1305 | header_len: usize, |
| 1339 | 1306 | indent: usize, |
| 1340 | cx: &'a Context<'tcx>, | |
| 1341 | ) -> impl Display + 'a + Captures<'tcx> { | |
| 1307 | cx: &Context<'_>, | |
| 1308 | ) -> impl Display { | |
| 1342 | 1309 | fmt::from_fn(move |f| { |
| 1343 | 1310 | // First, generate the text form of the declaration, with no line wrapping, and count the bytes. |
| 1344 | 1311 | let mut counter = WriteCounter(0); |
| ... | ... | @@ -1420,10 +1387,7 @@ impl clean::FnDecl { |
| 1420 | 1387 | self.print_output(cx).fmt(f) |
| 1421 | 1388 | } |
| 1422 | 1389 | |
| 1423 | fn print_output<'a, 'tcx: 'a>( | |
| 1424 | &'a self, | |
| 1425 | cx: &'a Context<'tcx>, | |
| 1426 | ) -> impl Display + 'a + Captures<'tcx> { | |
| 1390 | fn print_output(&self, cx: &Context<'_>) -> impl Display { | |
| 1427 | 1391 | fmt::from_fn(move |f| match &self.output { |
| 1428 | 1392 | clean::Tuple(tys) if tys.is_empty() => Ok(()), |
| 1429 | 1393 | ty if f.alternate() => { |
| ... | ... | @@ -1434,10 +1398,7 @@ impl clean::FnDecl { |
| 1434 | 1398 | } |
| 1435 | 1399 | } |
| 1436 | 1400 | |
| 1437 | pub(crate) fn visibility_print_with_space<'a, 'tcx: 'a>( | |
| 1438 | item: &clean::Item, | |
| 1439 | cx: &'a Context<'tcx>, | |
| 1440 | ) -> impl Display + 'a + Captures<'tcx> { | |
| 1401 | pub(crate) fn visibility_print_with_space(item: &clean::Item, cx: &Context<'_>) -> impl Display { | |
| 1441 | 1402 | use std::fmt::Write as _; |
| 1442 | 1403 | let vis: Cow<'static, str> = match item.visibility(cx.tcx()) { |
| 1443 | 1404 | None => "".into(), |
| ... | ... | @@ -1546,10 +1507,7 @@ pub(crate) fn print_constness_with_space( |
| 1546 | 1507 | } |
| 1547 | 1508 | |
| 1548 | 1509 | impl clean::Import { |
| 1549 | pub(crate) fn print<'a, 'tcx: 'a>( | |
| 1550 | &'a self, | |
| 1551 | cx: &'a Context<'tcx>, | |
| 1552 | ) -> impl Display + 'a + Captures<'tcx> { | |
| 1510 | pub(crate) fn print(&self, cx: &Context<'_>) -> impl Display { | |
| 1553 | 1511 | fmt::from_fn(move |f| match self.kind { |
| 1554 | 1512 | clean::ImportKind::Simple(name) => { |
| 1555 | 1513 | if name == self.source.path.last() { |
| ... | ... | @@ -1570,10 +1528,7 @@ impl clean::Import { |
| 1570 | 1528 | } |
| 1571 | 1529 | |
| 1572 | 1530 | impl clean::ImportSource { |
| 1573 | pub(crate) fn print<'a, 'tcx: 'a>( | |
| 1574 | &'a self, | |
| 1575 | cx: &'a Context<'tcx>, | |
| 1576 | ) -> impl Display + 'a + Captures<'tcx> { | |
| 1531 | pub(crate) fn print(&self, cx: &Context<'_>) -> impl Display { | |
| 1577 | 1532 | fmt::from_fn(move |f| match self.did { |
| 1578 | 1533 | Some(did) => resolved_path(f, did, &self.path, true, false, cx), |
| 1579 | 1534 | _ => { |
| ... | ... | @@ -1593,10 +1548,7 @@ impl clean::ImportSource { |
| 1593 | 1548 | } |
| 1594 | 1549 | |
| 1595 | 1550 | impl clean::AssocItemConstraint { |
| 1596 | pub(crate) fn print<'a, 'tcx: 'a>( | |
| 1597 | &'a self, | |
| 1598 | cx: &'a Context<'tcx>, | |
| 1599 | ) -> impl Display + 'a + Captures<'tcx> { | |
| 1551 | pub(crate) fn print(&self, cx: &Context<'_>) -> impl Display { | |
| 1600 | 1552 | fmt::from_fn(move |f| { |
| 1601 | 1553 | f.write_str(self.assoc.name.as_str())?; |
| 1602 | 1554 | self.assoc.args.print(cx).fmt(f)?; |
| ... | ... | @@ -1627,15 +1579,12 @@ pub(crate) fn print_abi_with_space(abi: ExternAbi) -> impl Display { |
| 1627 | 1579 | }) |
| 1628 | 1580 | } |
| 1629 | 1581 | |
| 1630 | pub(crate) fn print_default_space<'a>(v: bool) -> &'a str { | |
| 1582 | pub(crate) fn print_default_space(v: bool) -> &'static str { | |
| 1631 | 1583 | if v { "default " } else { "" } |
| 1632 | 1584 | } |
| 1633 | 1585 | |
| 1634 | 1586 | impl clean::GenericArg { |
| 1635 | pub(crate) fn print<'a, 'tcx: 'a>( | |
| 1636 | &'a self, | |
| 1637 | cx: &'a Context<'tcx>, | |
| 1638 | ) -> impl Display + 'a + Captures<'tcx> { | |
| 1587 | pub(crate) fn print(&self, cx: &Context<'_>) -> impl Display { | |
| 1639 | 1588 | fmt::from_fn(move |f| match self { |
| 1640 | 1589 | clean::GenericArg::Lifetime(lt) => lt.print().fmt(f), |
| 1641 | 1590 | clean::GenericArg::Type(ty) => ty.print(cx).fmt(f), |
| ... | ... | @@ -1646,10 +1595,7 @@ impl clean::GenericArg { |
| 1646 | 1595 | } |
| 1647 | 1596 | |
| 1648 | 1597 | impl clean::Term { |
| 1649 | pub(crate) fn print<'a, 'tcx: 'a>( | |
| 1650 | &'a self, | |
| 1651 | cx: &'a Context<'tcx>, | |
| 1652 | ) -> impl Display + 'a + Captures<'tcx> { | |
| 1598 | pub(crate) fn print(&self, cx: &Context<'_>) -> impl Display { | |
| 1653 | 1599 | fmt::from_fn(move |f| match self { |
| 1654 | 1600 | clean::Term::Type(ty) => ty.print(cx).fmt(f), |
| 1655 | 1601 | clean::Term::Constant(ct) => ct.print(cx.tcx()).fmt(f), |
src/librustdoc/html/render/mod.rs+102-107| ... | ... | @@ -47,7 +47,6 @@ use rinja::Template; |
| 47 | 47 | use rustc_attr_parsing::{ |
| 48 | 48 | ConstStability, DeprecatedSince, Deprecation, RustcVersion, StabilityLevel, StableSince, |
| 49 | 49 | }; |
| 50 | use rustc_data_structures::captures::Captures; | |
| 51 | 50 | use rustc_data_structures::fx::{FxHashSet, FxIndexMap, FxIndexSet}; |
| 52 | 51 | use rustc_hir::Mutability; |
| 53 | 52 | use rustc_hir::def_id::{DefId, DefIdSet}; |
| ... | ... | @@ -82,7 +81,7 @@ use crate::html::{highlight, sources}; |
| 82 | 81 | use crate::scrape_examples::{CallData, CallLocation}; |
| 83 | 82 | use crate::{DOC_RUST_LANG_ORG_VERSION, try_none}; |
| 84 | 83 | |
| 85 | pub(crate) fn ensure_trailing_slash(v: &str) -> impl fmt::Display + '_ { | |
| 84 | pub(crate) fn ensure_trailing_slash(v: &str) -> impl fmt::Display { | |
| 86 | 85 | fmt::from_fn(move |f| { |
| 87 | 86 | if !v.ends_with('/') && !v.is_empty() { write!(f, "{v}/") } else { f.write_str(v) } |
| 88 | 87 | }) |
| ... | ... | @@ -310,7 +309,7 @@ impl ItemEntry { |
| 310 | 309 | } |
| 311 | 310 | |
| 312 | 311 | impl ItemEntry { |
| 313 | pub(crate) fn print(&self) -> impl fmt::Display + '_ { | |
| 312 | pub(crate) fn print(&self) -> impl fmt::Display { | |
| 314 | 313 | fmt::from_fn(move |f| write!(f, "<a href=\"{}\">{}</a>", self.url, Escape(&self.name))) |
| 315 | 314 | } |
| 316 | 315 | } |
| ... | ... | @@ -505,12 +504,12 @@ fn scrape_examples_help(shared: &SharedContext<'_>) -> String { |
| 505 | 504 | ) |
| 506 | 505 | } |
| 507 | 506 | |
| 508 | fn document<'a, 'cx: 'a>( | |
| 509 | cx: &'a Context<'cx>, | |
| 510 | item: &'a clean::Item, | |
| 511 | parent: Option<&'a clean::Item>, | |
| 507 | fn document( | |
| 508 | cx: &Context<'_>, | |
| 509 | item: &clean::Item, | |
| 510 | parent: Option<&clean::Item>, | |
| 512 | 511 | heading_offset: HeadingOffset, |
| 513 | ) -> impl fmt::Display + 'a + Captures<'cx> { | |
| 512 | ) -> impl fmt::Display { | |
| 514 | 513 | if let Some(ref name) = item.name { |
| 515 | 514 | info!("Documenting {name}"); |
| 516 | 515 | } |
| ... | ... | @@ -526,12 +525,12 @@ fn document<'a, 'cx: 'a>( |
| 526 | 525 | } |
| 527 | 526 | |
| 528 | 527 | /// Render md_text as markdown. |
| 529 | fn render_markdown<'a, 'cx: 'a>( | |
| 530 | cx: &'a Context<'cx>, | |
| 531 | md_text: &'a str, | |
| 528 | fn render_markdown( | |
| 529 | cx: &Context<'_>, | |
| 530 | md_text: &str, | |
| 532 | 531 | links: Vec<RenderedLink>, |
| 533 | 532 | heading_offset: HeadingOffset, |
| 534 | ) -> impl fmt::Display + 'a + Captures<'cx> { | |
| 533 | ) -> impl fmt::Display { | |
| 535 | 534 | fmt::from_fn(move |f| { |
| 536 | 535 | write!( |
| 537 | 536 | f, |
| ... | ... | @@ -552,13 +551,13 @@ fn render_markdown<'a, 'cx: 'a>( |
| 552 | 551 | |
| 553 | 552 | /// Writes a documentation block containing only the first paragraph of the documentation. If the |
| 554 | 553 | /// docs are longer, a "Read more" link is appended to the end. |
| 555 | fn document_short<'a, 'cx: 'a>( | |
| 556 | item: &'a clean::Item, | |
| 557 | cx: &'a Context<'cx>, | |
| 558 | link: AssocItemLink<'a>, | |
| 559 | parent: &'a clean::Item, | |
| 554 | fn document_short( | |
| 555 | item: &clean::Item, | |
| 556 | cx: &Context<'_>, | |
| 557 | link: AssocItemLink<'_>, | |
| 558 | parent: &clean::Item, | |
| 560 | 559 | show_def_docs: bool, |
| 561 | ) -> impl fmt::Display + 'a + Captures<'cx> { | |
| 560 | ) -> impl fmt::Display { | |
| 562 | 561 | fmt::from_fn(move |f| { |
| 563 | 562 | document_item_info(cx, item, Some(parent)).render_into(f).unwrap(); |
| 564 | 563 | if !show_def_docs { |
| ... | ... | @@ -595,28 +594,28 @@ fn document_short<'a, 'cx: 'a>( |
| 595 | 594 | }) |
| 596 | 595 | } |
| 597 | 596 | |
| 598 | fn document_full_collapsible<'a, 'cx: 'a>( | |
| 599 | item: &'a clean::Item, | |
| 600 | cx: &'a Context<'cx>, | |
| 597 | fn document_full_collapsible( | |
| 598 | item: &clean::Item, | |
| 599 | cx: &Context<'_>, | |
| 601 | 600 | heading_offset: HeadingOffset, |
| 602 | ) -> impl fmt::Display + 'a + Captures<'cx> { | |
| 601 | ) -> impl fmt::Display { | |
| 603 | 602 | document_full_inner(item, cx, true, heading_offset) |
| 604 | 603 | } |
| 605 | 604 | |
| 606 | fn document_full<'a, 'cx: 'a>( | |
| 607 | item: &'a clean::Item, | |
| 608 | cx: &'a Context<'cx>, | |
| 605 | fn document_full( | |
| 606 | item: &clean::Item, | |
| 607 | cx: &Context<'_>, | |
| 609 | 608 | heading_offset: HeadingOffset, |
| 610 | ) -> impl fmt::Display + 'a + Captures<'cx> { | |
| 609 | ) -> impl fmt::Display { | |
| 611 | 610 | document_full_inner(item, cx, false, heading_offset) |
| 612 | 611 | } |
| 613 | 612 | |
| 614 | fn document_full_inner<'a, 'cx: 'a>( | |
| 615 | item: &'a clean::Item, | |
| 616 | cx: &'a Context<'cx>, | |
| 613 | fn document_full_inner( | |
| 614 | item: &clean::Item, | |
| 615 | cx: &Context<'_>, | |
| 617 | 616 | is_collapsible: bool, |
| 618 | 617 | heading_offset: HeadingOffset, |
| 619 | ) -> impl fmt::Display + 'a + Captures<'cx> { | |
| 618 | ) -> impl fmt::Display { | |
| 620 | 619 | fmt::from_fn(move |f| { |
| 621 | 620 | if let Some(s) = item.opt_doc_value() { |
| 622 | 621 | debug!("Doc block: =====\n{s}\n====="); |
| ... | ... | @@ -797,11 +796,11 @@ pub(crate) fn render_impls( |
| 797 | 796 | } |
| 798 | 797 | |
| 799 | 798 | /// Build a (possibly empty) `href` attribute (a key-value pair) for the given associated item. |
| 800 | fn assoc_href_attr<'a, 'tcx>( | |
| 799 | fn assoc_href_attr( | |
| 801 | 800 | it: &clean::Item, |
| 802 | link: AssocItemLink<'a>, | |
| 803 | cx: &Context<'tcx>, | |
| 804 | ) -> Option<impl fmt::Display + 'a + Captures<'tcx>> { | |
| 801 | link: AssocItemLink<'_>, | |
| 802 | cx: &Context<'_>, | |
| 803 | ) -> Option<impl fmt::Display> { | |
| 805 | 804 | let name = it.name.unwrap(); |
| 806 | 805 | let item_type = it.type_(); |
| 807 | 806 | |
| ... | ... | @@ -812,7 +811,7 @@ fn assoc_href_attr<'a, 'tcx>( |
| 812 | 811 | } |
| 813 | 812 | |
| 814 | 813 | let href = match link { |
| 815 | AssocItemLink::Anchor(Some(ref id)) => Href::AnchorId(id), | |
| 814 | AssocItemLink::Anchor(Some(id)) => Href::AnchorId(id), | |
| 816 | 815 | AssocItemLink::Anchor(None) => Href::Anchor(item_type), |
| 817 | 816 | AssocItemLink::GotoSource(did, provided_methods) => { |
| 818 | 817 | // We're creating a link from the implementation of an associated item to its |
| ... | ... | @@ -877,15 +876,15 @@ enum AssocConstValue<'a> { |
| 877 | 876 | None, |
| 878 | 877 | } |
| 879 | 878 | |
| 880 | fn assoc_const<'a, 'tcx>( | |
| 881 | it: &'a clean::Item, | |
| 882 | generics: &'a clean::Generics, | |
| 883 | ty: &'a clean::Type, | |
| 884 | value: AssocConstValue<'a>, | |
| 885 | link: AssocItemLink<'a>, | |
| 879 | fn assoc_const( | |
| 880 | it: &clean::Item, | |
| 881 | generics: &clean::Generics, | |
| 882 | ty: &clean::Type, | |
| 883 | value: AssocConstValue<'_>, | |
| 884 | link: AssocItemLink<'_>, | |
| 886 | 885 | indent: usize, |
| 887 | cx: &'a Context<'tcx>, | |
| 888 | ) -> impl fmt::Display + 'a + Captures<'tcx> { | |
| 886 | cx: &Context<'_>, | |
| 887 | ) -> impl fmt::Display { | |
| 889 | 888 | let tcx = cx.tcx(); |
| 890 | 889 | fmt::from_fn(move |w| { |
| 891 | 890 | write!( |
| ... | ... | @@ -917,15 +916,15 @@ fn assoc_const<'a, 'tcx>( |
| 917 | 916 | }) |
| 918 | 917 | } |
| 919 | 918 | |
| 920 | fn assoc_type<'a, 'tcx>( | |
| 921 | it: &'a clean::Item, | |
| 922 | generics: &'a clean::Generics, | |
| 923 | bounds: &'a [clean::GenericBound], | |
| 924 | default: Option<&'a clean::Type>, | |
| 925 | link: AssocItemLink<'a>, | |
| 919 | fn assoc_type( | |
| 920 | it: &clean::Item, | |
| 921 | generics: &clean::Generics, | |
| 922 | bounds: &[clean::GenericBound], | |
| 923 | default: Option<&clean::Type>, | |
| 924 | link: AssocItemLink<'_>, | |
| 926 | 925 | indent: usize, |
| 927 | cx: &'a Context<'tcx>, | |
| 928 | ) -> impl fmt::Display + 'a + Captures<'tcx> { | |
| 926 | cx: &Context<'_>, | |
| 927 | ) -> impl fmt::Display { | |
| 929 | 928 | fmt::from_fn(move |w| { |
| 930 | 929 | write!( |
| 931 | 930 | w, |
| ... | ... | @@ -947,15 +946,15 @@ fn assoc_type<'a, 'tcx>( |
| 947 | 946 | }) |
| 948 | 947 | } |
| 949 | 948 | |
| 950 | fn assoc_method<'a, 'tcx>( | |
| 951 | meth: &'a clean::Item, | |
| 952 | g: &'a clean::Generics, | |
| 953 | d: &'a clean::FnDecl, | |
| 954 | link: AssocItemLink<'a>, | |
| 949 | fn assoc_method( | |
| 950 | meth: &clean::Item, | |
| 951 | g: &clean::Generics, | |
| 952 | d: &clean::FnDecl, | |
| 953 | link: AssocItemLink<'_>, | |
| 955 | 954 | parent: ItemType, |
| 956 | cx: &'a Context<'tcx>, | |
| 955 | cx: &Context<'_>, | |
| 957 | 956 | render_mode: RenderMode, |
| 958 | ) -> impl fmt::Display + 'a + Captures<'tcx> { | |
| 957 | ) -> impl fmt::Display { | |
| 959 | 958 | let tcx = cx.tcx(); |
| 960 | 959 | let header = meth.fn_header(tcx).expect("Trying to get header from a non-function item"); |
| 961 | 960 | let name = meth.name.as_ref().unwrap(); |
| ... | ... | @@ -1031,7 +1030,7 @@ fn render_stability_since_raw_with_extra( |
| 1031 | 1030 | stable_version: Option<StableSince>, |
| 1032 | 1031 | const_stability: Option<ConstStability>, |
| 1033 | 1032 | extra_class: &str, |
| 1034 | ) -> Option<impl fmt::Display + '_> { | |
| 1033 | ) -> Option<impl fmt::Display> { | |
| 1035 | 1034 | let mut title = String::new(); |
| 1036 | 1035 | let mut stability = String::new(); |
| 1037 | 1036 | |
| ... | ... | @@ -1102,13 +1101,13 @@ fn render_stability_since_raw( |
| 1102 | 1101 | render_stability_since_raw_with_extra(ver, const_stability, "") |
| 1103 | 1102 | } |
| 1104 | 1103 | |
| 1105 | fn render_assoc_item<'a, 'tcx>( | |
| 1106 | item: &'a clean::Item, | |
| 1107 | link: AssocItemLink<'a>, | |
| 1104 | fn render_assoc_item( | |
| 1105 | item: &clean::Item, | |
| 1106 | link: AssocItemLink<'_>, | |
| 1108 | 1107 | parent: ItemType, |
| 1109 | cx: &'a Context<'tcx>, | |
| 1108 | cx: &Context<'_>, | |
| 1110 | 1109 | render_mode: RenderMode, |
| 1111 | ) -> impl fmt::Display + 'a + Captures<'tcx> { | |
| 1110 | ) -> impl fmt::Display { | |
| 1112 | 1111 | fmt::from_fn(move |f| match &item.kind { |
| 1113 | 1112 | clean::StrippedItem(..) => Ok(()), |
| 1114 | 1113 | clean::RequiredMethodItem(m) | clean::MethodItem(m, _) => { |
| ... | ... | @@ -1144,7 +1143,7 @@ fn render_assoc_item<'a, 'tcx>( |
| 1144 | 1143 | cx, |
| 1145 | 1144 | ) |
| 1146 | 1145 | .fmt(f), |
| 1147 | clean::RequiredAssocTypeItem(ref generics, ref bounds) => assoc_type( | |
| 1146 | clean::RequiredAssocTypeItem(generics, bounds) => assoc_type( | |
| 1148 | 1147 | item, |
| 1149 | 1148 | generics, |
| 1150 | 1149 | bounds, |
| ... | ... | @@ -1154,7 +1153,7 @@ fn render_assoc_item<'a, 'tcx>( |
| 1154 | 1153 | cx, |
| 1155 | 1154 | ) |
| 1156 | 1155 | .fmt(f), |
| 1157 | clean::AssocTypeItem(ref ty, ref bounds) => assoc_type( | |
| 1156 | clean::AssocTypeItem(ty, bounds) => assoc_type( | |
| 1158 | 1157 | item, |
| 1159 | 1158 | &ty.generics, |
| 1160 | 1159 | bounds, |
| ... | ... | @@ -1170,11 +1169,7 @@ fn render_assoc_item<'a, 'tcx>( |
| 1170 | 1169 | |
| 1171 | 1170 | // When an attribute is rendered inside a `<pre>` tag, it is formatted using |
| 1172 | 1171 | // a whitespace prefix and newline. |
| 1173 | fn render_attributes_in_pre<'a, 'tcx: 'a>( | |
| 1174 | it: &'a clean::Item, | |
| 1175 | prefix: &'a str, | |
| 1176 | cx: &'a Context<'tcx>, | |
| 1177 | ) -> impl fmt::Display + Captures<'a> + Captures<'tcx> { | |
| 1172 | fn render_attributes_in_pre(it: &clean::Item, prefix: &str, cx: &Context<'_>) -> impl fmt::Display { | |
| 1178 | 1173 | fmt::from_fn(move |f| { |
| 1179 | 1174 | for a in it.attributes(cx.tcx(), cx.cache(), false) { |
| 1180 | 1175 | writeln!(f, "{prefix}{a}")?; |
| ... | ... | @@ -1206,12 +1201,12 @@ impl<'a> AssocItemLink<'a> { |
| 1206 | 1201 | } |
| 1207 | 1202 | } |
| 1208 | 1203 | |
| 1209 | pub fn write_section_heading<'a>( | |
| 1210 | title: &'a str, | |
| 1211 | id: &'a str, | |
| 1212 | extra_class: Option<&'a str>, | |
| 1213 | extra: impl fmt::Display + 'a, | |
| 1214 | ) -> impl fmt::Display + 'a { | |
| 1204 | pub fn write_section_heading( | |
| 1205 | title: &str, | |
| 1206 | id: &str, | |
| 1207 | extra_class: Option<&str>, | |
| 1208 | extra: impl fmt::Display, | |
| 1209 | ) -> impl fmt::Display { | |
| 1215 | 1210 | fmt::from_fn(move |w| { |
| 1216 | 1211 | let (extra_class, whitespace) = match extra_class { |
| 1217 | 1212 | Some(extra) => (extra, " "), |
| ... | ... | @@ -1227,7 +1222,7 @@ pub fn write_section_heading<'a>( |
| 1227 | 1222 | }) |
| 1228 | 1223 | } |
| 1229 | 1224 | |
| 1230 | fn write_impl_section_heading<'a>(title: &'a str, id: &'a str) -> impl fmt::Display + 'a { | |
| 1225 | fn write_impl_section_heading(title: &str, id: &str) -> impl fmt::Display { | |
| 1231 | 1226 | write_section_heading(title, id, None, "") |
| 1232 | 1227 | } |
| 1233 | 1228 | |
| ... | ... | @@ -1276,12 +1271,12 @@ pub(crate) fn render_all_impls( |
| 1276 | 1271 | } |
| 1277 | 1272 | } |
| 1278 | 1273 | |
| 1279 | fn render_assoc_items<'a, 'cx: 'a>( | |
| 1280 | cx: &'a Context<'cx>, | |
| 1281 | containing_item: &'a clean::Item, | |
| 1274 | fn render_assoc_items( | |
| 1275 | cx: &Context<'_>, | |
| 1276 | containing_item: &clean::Item, | |
| 1282 | 1277 | it: DefId, |
| 1283 | what: AssocItemRender<'a>, | |
| 1284 | ) -> impl fmt::Display + 'a + Captures<'cx> { | |
| 1278 | what: AssocItemRender<'_>, | |
| 1279 | ) -> impl fmt::Display { | |
| 1285 | 1280 | fmt::from_fn(move |f| { |
| 1286 | 1281 | let mut derefs = DefIdSet::default(); |
| 1287 | 1282 | derefs.insert(it); |
| ... | ... | @@ -1466,10 +1461,10 @@ fn should_render_item(item: &clean::Item, deref_mut_: bool, tcx: TyCtxt<'_>) -> |
| 1466 | 1461 | } |
| 1467 | 1462 | } |
| 1468 | 1463 | |
| 1469 | pub(crate) fn notable_traits_button<'a, 'tcx>( | |
| 1470 | ty: &'a clean::Type, | |
| 1471 | cx: &'a Context<'tcx>, | |
| 1472 | ) -> Option<impl fmt::Display + 'a + Captures<'tcx>> { | |
| 1464 | pub(crate) fn notable_traits_button( | |
| 1465 | ty: &clean::Type, | |
| 1466 | cx: &Context<'_>, | |
| 1467 | ) -> Option<impl fmt::Display> { | |
| 1473 | 1468 | let mut has_notable_trait = false; |
| 1474 | 1469 | |
| 1475 | 1470 | if ty.is_unit() { |
| ... | ... | @@ -1623,16 +1618,16 @@ struct ImplRenderingParameters { |
| 1623 | 1618 | toggle_open_by_default: bool, |
| 1624 | 1619 | } |
| 1625 | 1620 | |
| 1626 | fn render_impl<'a, 'tcx>( | |
| 1627 | cx: &'a Context<'tcx>, | |
| 1628 | i: &'a Impl, | |
| 1629 | parent: &'a clean::Item, | |
| 1630 | link: AssocItemLink<'a>, | |
| 1621 | fn render_impl( | |
| 1622 | cx: &Context<'_>, | |
| 1623 | i: &Impl, | |
| 1624 | parent: &clean::Item, | |
| 1625 | link: AssocItemLink<'_>, | |
| 1631 | 1626 | render_mode: RenderMode, |
| 1632 | 1627 | use_absolute: Option<bool>, |
| 1633 | aliases: &'a [String], | |
| 1628 | aliases: &[String], | |
| 1634 | 1629 | rendering_params: ImplRenderingParameters, |
| 1635 | ) -> impl fmt::Display + 'a + Captures<'tcx> { | |
| 1630 | ) -> impl fmt::Display { | |
| 1636 | 1631 | fmt::from_fn(move |w| { |
| 1637 | 1632 | let cache = &cx.shared.cache; |
| 1638 | 1633 | let traits = &cache.traits; |
| ... | ... | @@ -1780,7 +1775,7 @@ fn render_impl<'a, 'tcx>( |
| 1780 | 1775 | ); |
| 1781 | 1776 | } |
| 1782 | 1777 | } |
| 1783 | clean::RequiredAssocConstItem(ref generics, ref ty) => { | |
| 1778 | clean::RequiredAssocConstItem(generics, ty) => { | |
| 1784 | 1779 | let source_id = format!("{item_type}.{name}"); |
| 1785 | 1780 | let id = cx.derive_id(&source_id); |
| 1786 | 1781 | write_str( |
| ... | ... | @@ -1847,7 +1842,7 @@ fn render_impl<'a, 'tcx>( |
| 1847 | 1842 | ), |
| 1848 | 1843 | ); |
| 1849 | 1844 | } |
| 1850 | clean::RequiredAssocTypeItem(ref generics, ref bounds) => { | |
| 1845 | clean::RequiredAssocTypeItem(generics, bounds) => { | |
| 1851 | 1846 | let source_id = format!("{item_type}.{name}"); |
| 1852 | 1847 | let id = cx.derive_id(&source_id); |
| 1853 | 1848 | write_str( |
| ... | ... | @@ -2135,11 +2130,11 @@ fn render_impl<'a, 'tcx>( |
| 2135 | 2130 | |
| 2136 | 2131 | // Render the items that appear on the right side of methods, impls, and |
| 2137 | 2132 | // associated types. For example "1.0.0 (const: 1.39.0) · source". |
| 2138 | fn render_rightside<'a, 'tcx>( | |
| 2139 | cx: &'a Context<'tcx>, | |
| 2140 | item: &'a clean::Item, | |
| 2133 | fn render_rightside( | |
| 2134 | cx: &Context<'_>, | |
| 2135 | item: &clean::Item, | |
| 2141 | 2136 | render_mode: RenderMode, |
| 2142 | ) -> impl fmt::Display + 'a + Captures<'tcx> { | |
| 2137 | ) -> impl fmt::Display { | |
| 2143 | 2138 | let tcx = cx.tcx(); |
| 2144 | 2139 | |
| 2145 | 2140 | fmt::from_fn(move |w| { |
| ... | ... | @@ -2174,17 +2169,17 @@ fn render_rightside<'a, 'tcx>( |
| 2174 | 2169 | }) |
| 2175 | 2170 | } |
| 2176 | 2171 | |
| 2177 | pub(crate) fn render_impl_summary<'a, 'tcx>( | |
| 2178 | cx: &'a Context<'tcx>, | |
| 2179 | i: &'a Impl, | |
| 2180 | parent: &'a clean::Item, | |
| 2172 | pub(crate) fn render_impl_summary( | |
| 2173 | cx: &Context<'_>, | |
| 2174 | i: &Impl, | |
| 2175 | parent: &clean::Item, | |
| 2181 | 2176 | show_def_docs: bool, |
| 2182 | 2177 | use_absolute: Option<bool>, |
| 2183 | 2178 | // This argument is used to reference same type with different paths to avoid duplication |
| 2184 | 2179 | // in documentation pages for trait with automatic implementations like "Send" and "Sync". |
| 2185 | aliases: &'a [String], | |
| 2186 | doc: Option<&'a str>, | |
| 2187 | ) -> impl fmt::Display + 'a + Captures<'tcx> { | |
| 2180 | aliases: &[String], | |
| 2181 | doc: Option<&str>, | |
| 2182 | ) -> impl fmt::Display { | |
| 2188 | 2183 | fmt::from_fn(move |w| { |
| 2189 | 2184 | let inner_impl = i.inner_impl(); |
| 2190 | 2185 | let id = cx.derive_id(get_id_for_impl(cx.tcx(), i.impl_item.item_id)); |
src/librustdoc/html/render/print_item.rs+120-207| ... | ... | @@ -4,7 +4,6 @@ use std::fmt::{Display, Write as _}; |
| 4 | 4 | |
| 5 | 5 | use rinja::Template; |
| 6 | 6 | use rustc_abi::VariantIdx; |
| 7 | use rustc_data_structures::captures::Captures; | |
| 8 | 7 | use rustc_data_structures::fx::{FxHashMap, FxIndexSet}; |
| 9 | 8 | use rustc_hir as hir; |
| 10 | 9 | use rustc_hir::def::CtorKind; |
| ... | ... | @@ -92,44 +91,32 @@ macro_rules! item_template { |
| 92 | 91 | macro_rules! item_template_methods { |
| 93 | 92 | () => {}; |
| 94 | 93 | (document $($rest:tt)*) => { |
| 95 | fn document<'b>(&'b self) -> impl fmt::Display + Captures<'a> + 'b + Captures<'cx> { | |
| 96 | fmt::from_fn(move |f| { | |
| 97 | let (item, cx) = self.item_and_cx(); | |
| 98 | let v = document(cx, item, None, HeadingOffset::H2); | |
| 99 | write!(f, "{v}") | |
| 100 | }) | |
| 94 | fn document(&self) -> impl fmt::Display { | |
| 95 | let (item, cx) = self.item_and_cx(); | |
| 96 | document(cx, item, None, HeadingOffset::H2) | |
| 101 | 97 | } |
| 102 | 98 | item_template_methods!($($rest)*); |
| 103 | 99 | }; |
| 104 | 100 | (document_type_layout $($rest:tt)*) => { |
| 105 | fn document_type_layout<'b>(&'b self) -> impl fmt::Display + Captures<'a> + 'b + Captures<'cx> { | |
| 106 | fmt::from_fn(move |f| { | |
| 107 | let (item, cx) = self.item_and_cx(); | |
| 108 | let def_id = item.item_id.expect_def_id(); | |
| 109 | let v = document_type_layout(cx, def_id); | |
| 110 | write!(f, "{v}") | |
| 111 | }) | |
| 101 | fn document_type_layout(&self) -> impl fmt::Display { | |
| 102 | let (item, cx) = self.item_and_cx(); | |
| 103 | let def_id = item.item_id.expect_def_id(); | |
| 104 | document_type_layout(cx, def_id) | |
| 112 | 105 | } |
| 113 | 106 | item_template_methods!($($rest)*); |
| 114 | 107 | }; |
| 115 | 108 | (render_attributes_in_pre $($rest:tt)*) => { |
| 116 | fn render_attributes_in_pre<'b>(&'b self) -> impl fmt::Display + Captures<'a> + 'b + Captures<'cx> { | |
| 117 | fmt::from_fn(move |f| { | |
| 118 | let (item, cx) = self.item_and_cx(); | |
| 119 | let v = render_attributes_in_pre(item, "", cx); | |
| 120 | write!(f, "{v}") | |
| 121 | }) | |
| 109 | fn render_attributes_in_pre(&self) -> impl fmt::Display { | |
| 110 | let (item, cx) = self.item_and_cx(); | |
| 111 | render_attributes_in_pre(item, "", cx) | |
| 122 | 112 | } |
| 123 | 113 | item_template_methods!($($rest)*); |
| 124 | 114 | }; |
| 125 | 115 | (render_assoc_items $($rest:tt)*) => { |
| 126 | fn render_assoc_items<'b>(&'b self) -> impl fmt::Display + Captures<'a> + 'b + Captures<'cx> { | |
| 127 | fmt::from_fn(move |f| { | |
| 128 | let (item, cx) = self.item_and_cx(); | |
| 129 | let def_id = item.item_id.expect_def_id(); | |
| 130 | let v = render_assoc_items(cx, item, def_id, AssocItemRender::All); | |
| 131 | write!(f, "{v}") | |
| 132 | }) | |
| 116 | fn render_assoc_items(&self) -> impl fmt::Display { | |
| 117 | let (item, cx) = self.item_and_cx(); | |
| 118 | let def_id = item.item_id.expect_def_id(); | |
| 119 | render_assoc_items(cx, item, def_id, AssocItemRender::All) | |
| 133 | 120 | } |
| 134 | 121 | item_template_methods!($($rest)*); |
| 135 | 122 | }; |
| ... | ... | @@ -162,10 +149,7 @@ struct ItemVars<'a> { |
| 162 | 149 | src_href: Option<&'a str>, |
| 163 | 150 | } |
| 164 | 151 | |
| 165 | pub(super) fn print_item<'a, 'tcx>( | |
| 166 | cx: &'a Context<'tcx>, | |
| 167 | item: &'a clean::Item, | |
| 168 | ) -> impl fmt::Display + 'a + Captures<'tcx> { | |
| 152 | pub(super) fn print_item(cx: &Context<'_>, item: &clean::Item) -> impl fmt::Display { | |
| 169 | 153 | debug_assert!(!item.is_stripped()); |
| 170 | 154 | |
| 171 | 155 | fmt::from_fn(|buf| { |
| ... | ... | @@ -241,30 +225,30 @@ pub(super) fn print_item<'a, 'tcx>( |
| 241 | 225 | item_vars.render_into(buf).unwrap(); |
| 242 | 226 | |
| 243 | 227 | match &item.kind { |
| 244 | clean::ModuleItem(ref m) => { | |
| 228 | clean::ModuleItem(m) => { | |
| 245 | 229 | write!(buf, "{}", item_module(cx, item, &m.items)) |
| 246 | 230 | } |
| 247 | clean::FunctionItem(ref f) | clean::ForeignFunctionItem(ref f, _) => { | |
| 231 | clean::FunctionItem(f) | clean::ForeignFunctionItem(f, _) => { | |
| 248 | 232 | write!(buf, "{}", item_function(cx, item, f)) |
| 249 | 233 | } |
| 250 | clean::TraitItem(ref t) => write!(buf, "{}", item_trait(cx, item, t)), | |
| 251 | clean::StructItem(ref s) => { | |
| 234 | clean::TraitItem(t) => write!(buf, "{}", item_trait(cx, item, t)), | |
| 235 | clean::StructItem(s) => { | |
| 252 | 236 | write!(buf, "{}", item_struct(cx, item, s)) |
| 253 | 237 | } |
| 254 | clean::UnionItem(ref s) => write!(buf, "{}", item_union(cx, item, s)), | |
| 255 | clean::EnumItem(ref e) => write!(buf, "{}", item_enum(cx, item, e)), | |
| 256 | clean::TypeAliasItem(ref t) => { | |
| 238 | clean::UnionItem(s) => write!(buf, "{}", item_union(cx, item, s)), | |
| 239 | clean::EnumItem(e) => write!(buf, "{}", item_enum(cx, item, e)), | |
| 240 | clean::TypeAliasItem(t) => { | |
| 257 | 241 | write!(buf, "{}", item_type_alias(cx, item, t)) |
| 258 | 242 | } |
| 259 | clean::MacroItem(ref m) => write!(buf, "{}", item_macro(cx, item, m)), | |
| 260 | clean::ProcMacroItem(ref m) => { | |
| 243 | clean::MacroItem(m) => write!(buf, "{}", item_macro(cx, item, m)), | |
| 244 | clean::ProcMacroItem(m) => { | |
| 261 | 245 | write!(buf, "{}", item_proc_macro(cx, item, m)) |
| 262 | 246 | } |
| 263 | 247 | clean::PrimitiveItem(_) => write!(buf, "{}", item_primitive(cx, item)), |
| 264 | clean::StaticItem(ref i) => { | |
| 248 | clean::StaticItem(i) => { | |
| 265 | 249 | write!(buf, "{}", item_static(cx, item, i, None)) |
| 266 | 250 | } |
| 267 | clean::ForeignStaticItem(ref i, safety) => { | |
| 251 | clean::ForeignStaticItem(i, safety) => { | |
| 268 | 252 | write!(buf, "{}", item_static(cx, item, i, Some(*safety))) |
| 269 | 253 | } |
| 270 | 254 | clean::ConstantItem(ci) => { |
| ... | ... | @@ -274,7 +258,7 @@ pub(super) fn print_item<'a, 'tcx>( |
| 274 | 258 | write!(buf, "{}", item_foreign_type(cx, item)) |
| 275 | 259 | } |
| 276 | 260 | clean::KeywordItem => write!(buf, "{}", item_keyword(cx, item)), |
| 277 | clean::TraitAliasItem(ref ta) => { | |
| 261 | clean::TraitAliasItem(ta) => { | |
| 278 | 262 | write!(buf, "{}", item_trait_alias(cx, item, ta)) |
| 279 | 263 | } |
| 280 | 264 | _ => { |
| ... | ... | @@ -321,11 +305,7 @@ trait ItemTemplate<'a, 'cx: 'a>: rinja::Template + Display { |
| 321 | 305 | fn item_and_cx(&self) -> (&'a clean::Item, &'a Context<'cx>); |
| 322 | 306 | } |
| 323 | 307 | |
| 324 | fn item_module<'a, 'tcx>( | |
| 325 | cx: &'a Context<'tcx>, | |
| 326 | item: &'a clean::Item, | |
| 327 | items: &'a [clean::Item], | |
| 328 | ) -> impl fmt::Display + 'a + Captures<'tcx> { | |
| 308 | fn item_module(cx: &Context<'_>, item: &clean::Item, items: &[clean::Item]) -> impl fmt::Display { | |
| 329 | 309 | fmt::from_fn(|w| { |
| 330 | 310 | write!(w, "{}", document(cx, item, None, HeadingOffset::H2))?; |
| 331 | 311 | |
| ... | ... | @@ -541,14 +521,14 @@ fn item_module<'a, 'tcx>( |
| 541 | 521 | |
| 542 | 522 | /// Render the stability, deprecation and portability tags that are displayed in the item's summary |
| 543 | 523 | /// at the module level. |
| 544 | fn extra_info_tags<'a, 'tcx: 'a>( | |
| 545 | tcx: TyCtxt<'tcx>, | |
| 546 | item: &'a clean::Item, | |
| 547 | parent: &'a clean::Item, | |
| 524 | fn extra_info_tags( | |
| 525 | tcx: TyCtxt<'_>, | |
| 526 | item: &clean::Item, | |
| 527 | parent: &clean::Item, | |
| 548 | 528 | import_def_id: Option<DefId>, |
| 549 | ) -> impl Display + 'a + Captures<'tcx> { | |
| 529 | ) -> impl Display { | |
| 550 | 530 | fmt::from_fn(move |f| { |
| 551 | fn tag_html<'a>(class: &'a str, title: &'a str, contents: &'a str) -> impl Display + 'a { | |
| 531 | fn tag_html(class: &str, title: &str, contents: &str) -> impl Display { | |
| 552 | 532 | fmt::from_fn(move |f| { |
| 553 | 533 | write!( |
| 554 | 534 | f, |
| ... | ... | @@ -597,11 +577,7 @@ fn extra_info_tags<'a, 'tcx: 'a>( |
| 597 | 577 | }) |
| 598 | 578 | } |
| 599 | 579 | |
| 600 | fn item_function<'a, 'tcx>( | |
| 601 | cx: &'a Context<'tcx>, | |
| 602 | it: &'a clean::Item, | |
| 603 | f: &'a clean::Function, | |
| 604 | ) -> impl fmt::Display + 'a + Captures<'tcx> { | |
| 580 | fn item_function(cx: &Context<'_>, it: &clean::Item, f: &clean::Function) -> impl fmt::Display { | |
| 605 | 581 | fmt::from_fn(|w| { |
| 606 | 582 | let tcx = cx.tcx(); |
| 607 | 583 | let header = it.fn_header(tcx).expect("printing a function which isn't a function"); |
| ... | ... | @@ -657,11 +633,7 @@ fn item_function<'a, 'tcx>( |
| 657 | 633 | }) |
| 658 | 634 | } |
| 659 | 635 | |
| 660 | fn item_trait<'a, 'tcx>( | |
| 661 | cx: &'a Context<'tcx>, | |
| 662 | it: &'a clean::Item, | |
| 663 | t: &'a clean::Trait, | |
| 664 | ) -> impl fmt::Display + 'a + Captures<'tcx> { | |
| 636 | fn item_trait(cx: &Context<'_>, it: &clean::Item, t: &clean::Trait) -> impl fmt::Display { | |
| 665 | 637 | fmt::from_fn(|w| { |
| 666 | 638 | let tcx = cx.tcx(); |
| 667 | 639 | let bounds = bounds(&t.bounds, false, cx); |
| ... | ... | @@ -831,11 +803,7 @@ fn item_trait<'a, 'tcx>( |
| 831 | 803 | // Trait documentation |
| 832 | 804 | write!(w, "{}", document(cx, it, None, HeadingOffset::H2))?; |
| 833 | 805 | |
| 834 | fn trait_item<'a, 'tcx>( | |
| 835 | cx: &'a Context<'tcx>, | |
| 836 | m: &'a clean::Item, | |
| 837 | t: &'a clean::Item, | |
| 838 | ) -> impl fmt::Display + 'a + Captures<'tcx> { | |
| 806 | fn trait_item(cx: &Context<'_>, m: &clean::Item, t: &clean::Item) -> impl fmt::Display { | |
| 839 | 807 | fmt::from_fn(|w| { |
| 840 | 808 | let name = m.name.unwrap(); |
| 841 | 809 | info!("Documenting {name} on {ty_name:?}", ty_name = t.name); |
| ... | ... | @@ -1021,7 +989,7 @@ fn item_trait<'a, 'tcx>( |
| 1021 | 989 | extern_crates.insert(did.krate); |
| 1022 | 990 | } |
| 1023 | 991 | match implementor.inner_impl().for_.without_borrowed_ref() { |
| 1024 | clean::Type::Path { ref path } if !path.is_assoc_ty() => { | |
| 992 | clean::Type::Path { path } if !path.is_assoc_ty() => { | |
| 1025 | 993 | let did = path.def_id(); |
| 1026 | 994 | let &mut (prev_did, ref mut has_duplicates) = |
| 1027 | 995 | implementor_dups.entry(path.last()).or_insert((did, false)); |
| ... | ... | @@ -1254,11 +1222,11 @@ fn item_trait<'a, 'tcx>( |
| 1254 | 1222 | }) |
| 1255 | 1223 | } |
| 1256 | 1224 | |
| 1257 | fn item_trait_alias<'a, 'tcx>( | |
| 1258 | cx: &'a Context<'tcx>, | |
| 1259 | it: &'a clean::Item, | |
| 1260 | t: &'a clean::TraitAlias, | |
| 1261 | ) -> impl fmt::Display + 'a + Captures<'tcx> { | |
| 1225 | fn item_trait_alias( | |
| 1226 | cx: &Context<'_>, | |
| 1227 | it: &clean::Item, | |
| 1228 | t: &clean::TraitAlias, | |
| 1229 | ) -> impl fmt::Display { | |
| 1262 | 1230 | fmt::from_fn(|w| { |
| 1263 | 1231 | wrap_item(w, |w| { |
| 1264 | 1232 | write!( |
| ... | ... | @@ -1285,11 +1253,7 @@ fn item_trait_alias<'a, 'tcx>( |
| 1285 | 1253 | }) |
| 1286 | 1254 | } |
| 1287 | 1255 | |
| 1288 | fn item_type_alias<'a, 'tcx>( | |
| 1289 | cx: &'a Context<'tcx>, | |
| 1290 | it: &'a clean::Item, | |
| 1291 | t: &'a clean::TypeAlias, | |
| 1292 | ) -> impl fmt::Display + 'a + Captures<'tcx> { | |
| 1256 | fn item_type_alias(cx: &Context<'_>, it: &clean::Item, t: &clean::TypeAlias) -> impl fmt::Display { | |
| 1293 | 1257 | fmt::from_fn(|w| { |
| 1294 | 1258 | wrap_item(w, |w| { |
| 1295 | 1259 | write!( |
| ... | ... | @@ -1499,11 +1463,7 @@ fn item_type_alias<'a, 'tcx>( |
| 1499 | 1463 | }) |
| 1500 | 1464 | } |
| 1501 | 1465 | |
| 1502 | fn item_union<'a, 'tcx>( | |
| 1503 | cx: &'a Context<'tcx>, | |
| 1504 | it: &'a clean::Item, | |
| 1505 | s: &'a clean::Union, | |
| 1506 | ) -> impl fmt::Display + 'a + Captures<'tcx> { | |
| 1466 | fn item_union(cx: &Context<'_>, it: &clean::Item, s: &clean::Union) -> impl fmt::Display { | |
| 1507 | 1467 | item_template!( |
| 1508 | 1468 | #[template(path = "item_union.html")] |
| 1509 | 1469 | struct ItemUnion<'a, 'cx> { |
| ... | ... | @@ -1515,35 +1475,20 @@ fn item_union<'a, 'tcx>( |
| 1515 | 1475 | ); |
| 1516 | 1476 | |
| 1517 | 1477 | impl<'a, 'cx: 'a> ItemUnion<'a, 'cx> { |
| 1518 | fn render_union<'b>(&'b self) -> impl Display + Captures<'a> + 'b + Captures<'cx> { | |
| 1519 | fmt::from_fn(move |f| { | |
| 1520 | let v = render_union(self.it, Some(&self.s.generics), &self.s.fields, self.cx); | |
| 1521 | write!(f, "{v}") | |
| 1522 | }) | |
| 1478 | fn render_union(&self) -> impl Display { | |
| 1479 | render_union(self.it, Some(&self.s.generics), &self.s.fields, self.cx) | |
| 1523 | 1480 | } |
| 1524 | 1481 | |
| 1525 | fn document_field<'b>( | |
| 1526 | &'b self, | |
| 1527 | field: &'a clean::Item, | |
| 1528 | ) -> impl Display + Captures<'a> + 'b + Captures<'cx> { | |
| 1529 | fmt::from_fn(move |f| { | |
| 1530 | let v = document(self.cx, field, Some(self.it), HeadingOffset::H3); | |
| 1531 | write!(f, "{v}") | |
| 1532 | }) | |
| 1482 | fn document_field(&self, field: &'a clean::Item) -> impl Display { | |
| 1483 | document(self.cx, field, Some(self.it), HeadingOffset::H3) | |
| 1533 | 1484 | } |
| 1534 | 1485 | |
| 1535 | 1486 | fn stability_field(&self, field: &clean::Item) -> Option<String> { |
| 1536 | 1487 | field.stability_class(self.cx.tcx()) |
| 1537 | 1488 | } |
| 1538 | 1489 | |
| 1539 | fn print_ty<'b>( | |
| 1540 | &'b self, | |
| 1541 | ty: &'a clean::Type, | |
| 1542 | ) -> impl Display + Captures<'a> + 'b + Captures<'cx> { | |
| 1543 | fmt::from_fn(move |f| { | |
| 1544 | let v = ty.print(self.cx); | |
| 1545 | write!(f, "{v}") | |
| 1546 | }) | |
| 1490 | fn print_ty(&self, ty: &'a clean::Type) -> impl Display { | |
| 1491 | ty.print(self.cx) | |
| 1547 | 1492 | } |
| 1548 | 1493 | |
| 1549 | 1494 | fn fields_iter( |
| ... | ... | @@ -1566,10 +1511,7 @@ fn item_union<'a, 'tcx>( |
| 1566 | 1511 | }) |
| 1567 | 1512 | } |
| 1568 | 1513 | |
| 1569 | fn print_tuple_struct_fields<'a, 'cx: 'a>( | |
| 1570 | cx: &'a Context<'cx>, | |
| 1571 | s: &'a [clean::Item], | |
| 1572 | ) -> impl Display + 'a + Captures<'cx> { | |
| 1514 | fn print_tuple_struct_fields(cx: &Context<'_>, s: &[clean::Item]) -> impl Display { | |
| 1573 | 1515 | fmt::from_fn(|f| { |
| 1574 | 1516 | if !s.is_empty() |
| 1575 | 1517 | && s.iter().all(|field| { |
| ... | ... | @@ -1591,11 +1533,7 @@ fn print_tuple_struct_fields<'a, 'cx: 'a>( |
| 1591 | 1533 | }) |
| 1592 | 1534 | } |
| 1593 | 1535 | |
| 1594 | fn item_enum<'a, 'tcx>( | |
| 1595 | cx: &'a Context<'tcx>, | |
| 1596 | it: &'a clean::Item, | |
| 1597 | e: &'a clean::Enum, | |
| 1598 | ) -> impl fmt::Display + 'a + Captures<'tcx> { | |
| 1536 | fn item_enum(cx: &Context<'_>, it: &clean::Item, e: &clean::Enum) -> impl fmt::Display { | |
| 1599 | 1537 | fmt::from_fn(|w| { |
| 1600 | 1538 | let count_variants = e.variants().count(); |
| 1601 | 1539 | wrap_item(w, |w| { |
| ... | ... | @@ -1658,14 +1596,14 @@ fn should_show_enum_discriminant( |
| 1658 | 1596 | repr.c() || repr.int.is_some() |
| 1659 | 1597 | } |
| 1660 | 1598 | |
| 1661 | fn display_c_like_variant<'a, 'tcx>( | |
| 1662 | cx: &'a Context<'tcx>, | |
| 1663 | item: &'a clean::Item, | |
| 1664 | variant: &'a clean::Variant, | |
| 1599 | fn display_c_like_variant( | |
| 1600 | cx: &Context<'_>, | |
| 1601 | item: &clean::Item, | |
| 1602 | variant: &clean::Variant, | |
| 1665 | 1603 | index: VariantIdx, |
| 1666 | 1604 | should_show_enum_discriminant: bool, |
| 1667 | 1605 | enum_def_id: DefId, |
| 1668 | ) -> impl fmt::Display + 'a + Captures<'tcx> { | |
| 1606 | ) -> impl fmt::Display { | |
| 1669 | 1607 | fmt::from_fn(move |w| { |
| 1670 | 1608 | let name = item.name.unwrap(); |
| 1671 | 1609 | if let Some(ref value) = variant.discriminant { |
| ... | ... | @@ -1685,15 +1623,15 @@ fn display_c_like_variant<'a, 'tcx>( |
| 1685 | 1623 | }) |
| 1686 | 1624 | } |
| 1687 | 1625 | |
| 1688 | fn render_enum_fields<'a, 'tcx>( | |
| 1689 | cx: &'a Context<'tcx>, | |
| 1690 | g: Option<&'a clean::Generics>, | |
| 1691 | variants: &'a IndexVec<VariantIdx, clean::Item>, | |
| 1626 | fn render_enum_fields( | |
| 1627 | cx: &Context<'_>, | |
| 1628 | g: Option<&clean::Generics>, | |
| 1629 | variants: &IndexVec<VariantIdx, clean::Item>, | |
| 1692 | 1630 | count_variants: usize, |
| 1693 | 1631 | has_stripped_entries: bool, |
| 1694 | 1632 | is_non_exhaustive: bool, |
| 1695 | 1633 | enum_def_id: DefId, |
| 1696 | ) -> impl fmt::Display + 'a + Captures<'tcx> { | |
| 1634 | ) -> impl fmt::Display { | |
| 1697 | 1635 | fmt::from_fn(move |w| { |
| 1698 | 1636 | let should_show_enum_discriminant = |
| 1699 | 1637 | should_show_enum_discriminant(cx, enum_def_id, variants); |
| ... | ... | @@ -1764,12 +1702,12 @@ fn render_enum_fields<'a, 'tcx>( |
| 1764 | 1702 | }) |
| 1765 | 1703 | } |
| 1766 | 1704 | |
| 1767 | fn item_variants<'a, 'tcx>( | |
| 1768 | cx: &'a Context<'tcx>, | |
| 1769 | it: &'a clean::Item, | |
| 1770 | variants: &'a IndexVec<VariantIdx, clean::Item>, | |
| 1705 | fn item_variants( | |
| 1706 | cx: &Context<'_>, | |
| 1707 | it: &clean::Item, | |
| 1708 | variants: &IndexVec<VariantIdx, clean::Item>, | |
| 1771 | 1709 | enum_def_id: DefId, |
| 1772 | ) -> impl fmt::Display + 'a + Captures<'tcx> { | |
| 1710 | ) -> impl fmt::Display { | |
| 1773 | 1711 | fmt::from_fn(move |w| { |
| 1774 | 1712 | let tcx = cx.tcx(); |
| 1775 | 1713 | write!( |
| ... | ... | @@ -1895,11 +1833,7 @@ fn item_variants<'a, 'tcx>( |
| 1895 | 1833 | }) |
| 1896 | 1834 | } |
| 1897 | 1835 | |
| 1898 | fn item_macro<'a, 'tcx>( | |
| 1899 | cx: &'a Context<'tcx>, | |
| 1900 | it: &'a clean::Item, | |
| 1901 | t: &'a clean::Macro, | |
| 1902 | ) -> impl fmt::Display + 'a + Captures<'tcx> { | |
| 1836 | fn item_macro(cx: &Context<'_>, it: &clean::Item, t: &clean::Macro) -> impl fmt::Display { | |
| 1903 | 1837 | fmt::from_fn(|w| { |
| 1904 | 1838 | wrap_item(w, |w| { |
| 1905 | 1839 | // FIXME: Also print `#[doc(hidden)]` for `macro_rules!` if it `is_doc_hidden`. |
| ... | ... | @@ -1912,11 +1846,7 @@ fn item_macro<'a, 'tcx>( |
| 1912 | 1846 | }) |
| 1913 | 1847 | } |
| 1914 | 1848 | |
| 1915 | fn item_proc_macro<'a, 'tcx>( | |
| 1916 | cx: &'a Context<'tcx>, | |
| 1917 | it: &'a clean::Item, | |
| 1918 | m: &'a clean::ProcMacro, | |
| 1919 | ) -> impl fmt::Display + 'a + Captures<'tcx> { | |
| 1849 | fn item_proc_macro(cx: &Context<'_>, it: &clean::Item, m: &clean::ProcMacro) -> impl fmt::Display { | |
| 1920 | 1850 | fmt::from_fn(|w| { |
| 1921 | 1851 | wrap_item(w, |w| { |
| 1922 | 1852 | let name = it.name.expect("proc-macros always have names"); |
| ... | ... | @@ -1947,10 +1877,7 @@ fn item_proc_macro<'a, 'tcx>( |
| 1947 | 1877 | }) |
| 1948 | 1878 | } |
| 1949 | 1879 | |
| 1950 | fn item_primitive<'a, 'tcx>( | |
| 1951 | cx: &'a Context<'tcx>, | |
| 1952 | it: &'a clean::Item, | |
| 1953 | ) -> impl fmt::Display + 'a + Captures<'tcx> { | |
| 1880 | fn item_primitive(cx: &Context<'_>, it: &clean::Item) -> impl fmt::Display { | |
| 1954 | 1881 | fmt::from_fn(|w| { |
| 1955 | 1882 | let def_id = it.item_id.expect_def_id(); |
| 1956 | 1883 | write!(w, "{}", document(cx, it, None, HeadingOffset::H2))?; |
| ... | ... | @@ -1968,13 +1895,13 @@ fn item_primitive<'a, 'tcx>( |
| 1968 | 1895 | }) |
| 1969 | 1896 | } |
| 1970 | 1897 | |
| 1971 | fn item_constant<'a, 'tcx>( | |
| 1972 | cx: &'a Context<'tcx>, | |
| 1973 | it: &'a clean::Item, | |
| 1974 | generics: &'a clean::Generics, | |
| 1975 | ty: &'a clean::Type, | |
| 1976 | c: &'a clean::ConstantKind, | |
| 1977 | ) -> impl fmt::Display + 'a + Captures<'tcx> { | |
| 1898 | fn item_constant( | |
| 1899 | cx: &Context<'_>, | |
| 1900 | it: &clean::Item, | |
| 1901 | generics: &clean::Generics, | |
| 1902 | ty: &clean::Type, | |
| 1903 | c: &clean::ConstantKind, | |
| 1904 | ) -> impl fmt::Display { | |
| 1978 | 1905 | fmt::from_fn(|w| { |
| 1979 | 1906 | wrap_item(w, |w| { |
| 1980 | 1907 | let tcx = cx.tcx(); |
| ... | ... | @@ -2028,11 +1955,7 @@ fn item_constant<'a, 'tcx>( |
| 2028 | 1955 | }) |
| 2029 | 1956 | } |
| 2030 | 1957 | |
| 2031 | fn item_struct<'a, 'tcx>( | |
| 2032 | cx: &'a Context<'tcx>, | |
| 2033 | it: &'a clean::Item, | |
| 2034 | s: &'a clean::Struct, | |
| 2035 | ) -> impl fmt::Display + 'a + Captures<'tcx> { | |
| 1958 | fn item_struct(cx: &Context<'_>, it: &clean::Item, s: &clean::Struct) -> impl fmt::Display { | |
| 2036 | 1959 | fmt::from_fn(|w| { |
| 2037 | 1960 | wrap_item(w, |w| { |
| 2038 | 1961 | render_attributes_in_code(w, it, cx); |
| ... | ... | @@ -2056,12 +1979,12 @@ fn item_struct<'a, 'tcx>( |
| 2056 | 1979 | }) |
| 2057 | 1980 | } |
| 2058 | 1981 | |
| 2059 | fn item_fields<'a, 'tcx>( | |
| 2060 | cx: &'a Context<'tcx>, | |
| 2061 | it: &'a clean::Item, | |
| 2062 | fields: &'a [clean::Item], | |
| 1982 | fn item_fields( | |
| 1983 | cx: &Context<'_>, | |
| 1984 | it: &clean::Item, | |
| 1985 | fields: &[clean::Item], | |
| 2063 | 1986 | ctor_kind: Option<CtorKind>, |
| 2064 | ) -> impl fmt::Display + 'a + Captures<'tcx> { | |
| 1987 | ) -> impl fmt::Display { | |
| 2065 | 1988 | fmt::from_fn(move |w| { |
| 2066 | 1989 | let mut fields = fields |
| 2067 | 1990 | .iter() |
| ... | ... | @@ -2111,12 +2034,12 @@ fn item_fields<'a, 'tcx>( |
| 2111 | 2034 | }) |
| 2112 | 2035 | } |
| 2113 | 2036 | |
| 2114 | fn item_static<'a, 'tcx>( | |
| 2115 | cx: &'a Context<'tcx>, | |
| 2116 | it: &'a clean::Item, | |
| 2117 | s: &'a clean::Static, | |
| 2037 | fn item_static( | |
| 2038 | cx: &Context<'_>, | |
| 2039 | it: &clean::Item, | |
| 2040 | s: &clean::Static, | |
| 2118 | 2041 | safety: Option<hir::Safety>, |
| 2119 | ) -> impl fmt::Display + 'a + Captures<'tcx> { | |
| 2042 | ) -> impl fmt::Display { | |
| 2120 | 2043 | fmt::from_fn(move |w| { |
| 2121 | 2044 | wrap_item(w, |w| { |
| 2122 | 2045 | render_attributes_in_code(w, it, cx); |
| ... | ... | @@ -2135,10 +2058,7 @@ fn item_static<'a, 'tcx>( |
| 2135 | 2058 | }) |
| 2136 | 2059 | } |
| 2137 | 2060 | |
| 2138 | fn item_foreign_type<'a, 'tcx>( | |
| 2139 | cx: &'a Context<'tcx>, | |
| 2140 | it: &'a clean::Item, | |
| 2141 | ) -> impl fmt::Display + 'a + Captures<'tcx> { | |
| 2061 | fn item_foreign_type(cx: &Context<'_>, it: &clean::Item) -> impl fmt::Display { | |
| 2142 | 2062 | fmt::from_fn(|w| { |
| 2143 | 2063 | wrap_item(w, |w| { |
| 2144 | 2064 | w.write_str("extern {\n")?; |
| ... | ... | @@ -2155,10 +2075,7 @@ fn item_foreign_type<'a, 'tcx>( |
| 2155 | 2075 | }) |
| 2156 | 2076 | } |
| 2157 | 2077 | |
| 2158 | fn item_keyword<'a, 'tcx>( | |
| 2159 | cx: &'a Context<'tcx>, | |
| 2160 | it: &'a clean::Item, | |
| 2161 | ) -> impl fmt::Display + 'a + Captures<'tcx> { | |
| 2078 | fn item_keyword(cx: &Context<'_>, it: &clean::Item) -> impl fmt::Display { | |
| 2162 | 2079 | document(cx, it, None, HeadingOffset::H2) |
| 2163 | 2080 | } |
| 2164 | 2081 | |
| ... | ... | @@ -2268,18 +2185,14 @@ pub(super) fn full_path(cx: &Context<'_>, item: &clean::Item) -> String { |
| 2268 | 2185 | s |
| 2269 | 2186 | } |
| 2270 | 2187 | |
| 2271 | pub(super) fn item_path(ty: ItemType, name: &str) -> impl Display + '_ { | |
| 2188 | pub(super) fn item_path(ty: ItemType, name: &str) -> impl Display { | |
| 2272 | 2189 | fmt::from_fn(move |f| match ty { |
| 2273 | 2190 | ItemType::Module => write!(f, "{}index.html", ensure_trailing_slash(name)), |
| 2274 | 2191 | _ => write!(f, "{ty}.{name}.html"), |
| 2275 | 2192 | }) |
| 2276 | 2193 | } |
| 2277 | 2194 | |
| 2278 | fn bounds<'a, 'tcx>( | |
| 2279 | bounds: &'a [clean::GenericBound], | |
| 2280 | trait_alias: bool, | |
| 2281 | cx: &'a Context<'tcx>, | |
| 2282 | ) -> impl Display + 'a + Captures<'tcx> { | |
| 2195 | fn bounds(bounds: &[clean::GenericBound], trait_alias: bool, cx: &Context<'_>) -> impl Display { | |
| 2283 | 2196 | (!bounds.is_empty()) |
| 2284 | 2197 | .then_some(fmt::from_fn(move |f| { |
| 2285 | 2198 | let has_lots_of_bounds = bounds.len() > 2; |
| ... | ... | @@ -2329,13 +2242,13 @@ impl Ord for ImplString { |
| 2329 | 2242 | } |
| 2330 | 2243 | } |
| 2331 | 2244 | |
| 2332 | fn render_implementor<'a, 'tcx>( | |
| 2333 | cx: &'a Context<'tcx>, | |
| 2334 | implementor: &'a Impl, | |
| 2335 | trait_: &'a clean::Item, | |
| 2336 | implementor_dups: &'a FxHashMap<Symbol, (DefId, bool)>, | |
| 2337 | aliases: &'a [String], | |
| 2338 | ) -> impl fmt::Display + 'a + Captures<'tcx> { | |
| 2245 | fn render_implementor( | |
| 2246 | cx: &Context<'_>, | |
| 2247 | implementor: &Impl, | |
| 2248 | trait_: &clean::Item, | |
| 2249 | implementor_dups: &FxHashMap<Symbol, (DefId, bool)>, | |
| 2250 | aliases: &[String], | |
| 2251 | ) -> impl fmt::Display { | |
| 2339 | 2252 | // If there's already another implementor that has the same abridged name, use the |
| 2340 | 2253 | // full path, for example in `std::iter::ExactSizeIterator` |
| 2341 | 2254 | let use_absolute = match implementor.inner_impl().for_ { |
| ... | ... | @@ -2364,12 +2277,12 @@ fn render_implementor<'a, 'tcx>( |
| 2364 | 2277 | ) |
| 2365 | 2278 | } |
| 2366 | 2279 | |
| 2367 | fn render_union<'a, 'cx: 'a>( | |
| 2368 | it: &'a clean::Item, | |
| 2369 | g: Option<&'a clean::Generics>, | |
| 2370 | fields: &'a [clean::Item], | |
| 2371 | cx: &'a Context<'cx>, | |
| 2372 | ) -> impl Display + 'a + Captures<'cx> { | |
| 2280 | fn render_union( | |
| 2281 | it: &clean::Item, | |
| 2282 | g: Option<&clean::Generics>, | |
| 2283 | fields: &[clean::Item], | |
| 2284 | cx: &Context<'_>, | |
| 2285 | ) -> impl Display { | |
| 2373 | 2286 | fmt::from_fn(move |mut f| { |
| 2374 | 2287 | write!(f, "{}union {}", visibility_print_with_space(it, cx), it.name.unwrap(),)?; |
| 2375 | 2288 | |
| ... | ... | @@ -2421,15 +2334,15 @@ fn render_union<'a, 'cx: 'a>( |
| 2421 | 2334 | }) |
| 2422 | 2335 | } |
| 2423 | 2336 | |
| 2424 | fn render_struct<'a, 'tcx>( | |
| 2425 | it: &'a clean::Item, | |
| 2426 | g: Option<&'a clean::Generics>, | |
| 2337 | fn render_struct( | |
| 2338 | it: &clean::Item, | |
| 2339 | g: Option<&clean::Generics>, | |
| 2427 | 2340 | ty: Option<CtorKind>, |
| 2428 | fields: &'a [clean::Item], | |
| 2429 | tab: &'a str, | |
| 2341 | fields: &[clean::Item], | |
| 2342 | tab: &str, | |
| 2430 | 2343 | structhead: bool, |
| 2431 | cx: &'a Context<'tcx>, | |
| 2432 | ) -> impl fmt::Display + 'a + Captures<'tcx> { | |
| 2344 | cx: &Context<'_>, | |
| 2345 | ) -> impl fmt::Display { | |
| 2433 | 2346 | fmt::from_fn(move |w| { |
| 2434 | 2347 | write!( |
| 2435 | 2348 | w, |
| ... | ... | @@ -2457,15 +2370,15 @@ fn render_struct<'a, 'tcx>( |
| 2457 | 2370 | }) |
| 2458 | 2371 | } |
| 2459 | 2372 | |
| 2460 | fn render_struct_fields<'a, 'tcx>( | |
| 2461 | g: Option<&'a clean::Generics>, | |
| 2373 | fn render_struct_fields( | |
| 2374 | g: Option<&clean::Generics>, | |
| 2462 | 2375 | ty: Option<CtorKind>, |
| 2463 | fields: &'a [clean::Item], | |
| 2464 | tab: &'a str, | |
| 2376 | fields: &[clean::Item], | |
| 2377 | tab: &str, | |
| 2465 | 2378 | structhead: bool, |
| 2466 | 2379 | has_stripped_entries: bool, |
| 2467 | cx: &'a Context<'tcx>, | |
| 2468 | ) -> impl fmt::Display + 'a + Captures<'tcx> { | |
| 2380 | cx: &Context<'_>, | |
| 2381 | ) -> impl fmt::Display { | |
| 2469 | 2382 | fmt::from_fn(move |w| { |
| 2470 | 2383 | match ty { |
| 2471 | 2384 | None => { |
| ... | ... | @@ -2581,7 +2494,7 @@ fn document_non_exhaustive_header(item: &clean::Item) -> &str { |
| 2581 | 2494 | if item.is_non_exhaustive() { " (Non-exhaustive)" } else { "" } |
| 2582 | 2495 | } |
| 2583 | 2496 | |
| 2584 | fn document_non_exhaustive(item: &clean::Item) -> impl Display + '_ { | |
| 2497 | fn document_non_exhaustive(item: &clean::Item) -> impl Display { | |
| 2585 | 2498 | fmt::from_fn(|f| { |
| 2586 | 2499 | if item.is_non_exhaustive() { |
| 2587 | 2500 | write!( |
src/librustdoc/html/render/type_layout.rs+1-5| ... | ... | @@ -2,7 +2,6 @@ use std::fmt; |
| 2 | 2 | |
| 3 | 3 | use rinja::Template; |
| 4 | 4 | use rustc_abi::{Primitive, TagEncoding, Variants}; |
| 5 | use rustc_data_structures::captures::Captures; | |
| 6 | 5 | use rustc_hir::def_id::DefId; |
| 7 | 6 | use rustc_middle::span_bug; |
| 8 | 7 | use rustc_middle::ty::layout::LayoutError; |
| ... | ... | @@ -26,10 +25,7 @@ struct TypeLayoutSize { |
| 26 | 25 | size: u64, |
| 27 | 26 | } |
| 28 | 27 | |
| 29 | pub(crate) fn document_type_layout<'a, 'cx: 'a>( | |
| 30 | cx: &'a Context<'cx>, | |
| 31 | ty_def_id: DefId, | |
| 32 | ) -> impl fmt::Display + 'a + Captures<'cx> { | |
| 28 | pub(crate) fn document_type_layout(cx: &Context<'_>, ty_def_id: DefId) -> impl fmt::Display { | |
| 33 | 29 | fmt::from_fn(move |f| { |
| 34 | 30 | if !cx.shared.show_type_layout { |
| 35 | 31 | return Ok(()); |
src/librustdoc/html/sources.rs+1-1| ... | ... | @@ -333,7 +333,7 @@ pub(crate) fn print_src( |
| 333 | 333 | source_context: &SourceContext<'_>, |
| 334 | 334 | ) { |
| 335 | 335 | let mut lines = s.lines().count(); |
| 336 | let line_info = if let SourceContext::Embedded(ref info) = source_context { | |
| 336 | let line_info = if let SourceContext::Embedded(info) = source_context { | |
| 337 | 337 | highlight::LineInfo::new_scraped(lines as u32, info.offset as u32) |
| 338 | 338 | } else { |
| 339 | 339 | highlight::LineInfo::new(lines as u32) |
src/librustdoc/lib.rs+1-1| ... | ... | @@ -147,7 +147,7 @@ pub fn main() { |
| 147 | 147 | |
| 148 | 148 | #[cfg(target_os = "macos")] |
| 149 | 149 | { |
| 150 | extern "C" { | |
| 150 | unsafe extern "C" { | |
| 151 | 151 | fn _rjem_je_zone_register(); |
| 152 | 152 | } |
| 153 | 153 |
src/librustdoc/passes/collect_intra_doc_links.rs+1-1| ... | ... | @@ -58,7 +58,7 @@ fn filter_assoc_items_by_name_and_namespace( |
| 58 | 58 | assoc_items_of: DefId, |
| 59 | 59 | ident: Ident, |
| 60 | 60 | ns: Namespace, |
| 61 | ) -> impl Iterator<Item = &ty::AssocItem> + '_ { | |
| 61 | ) -> impl Iterator<Item = &ty::AssocItem> { | |
| 62 | 62 | tcx.associated_items(assoc_items_of).filter_by_name_unhygienic(ident.name).filter(move |item| { |
| 63 | 63 | item.kind.namespace() == ns && tcx.hygienic_eq(ident, item.ident(tcx), assoc_items_of) |
| 64 | 64 | }) |
src/tools/compiletest/src/common.rs+3| ... | ... | @@ -190,6 +190,9 @@ pub struct Config { |
| 190 | 190 | /// The cargo executable. |
| 191 | 191 | pub cargo_path: Option<PathBuf>, |
| 192 | 192 | |
| 193 | /// Rustc executable used to compile run-make recipes. | |
| 194 | pub stage0_rustc_path: Option<PathBuf>, | |
| 195 | ||
| 193 | 196 | /// The rustdoc executable. |
| 194 | 197 | pub rustdoc_path: Option<PathBuf>, |
| 195 | 198 |
src/tools/compiletest/src/lib.rs+7| ... | ... | @@ -54,6 +54,12 @@ pub fn parse_config(args: Vec<String>) -> Config { |
| 54 | 54 | .reqopt("", "run-lib-path", "path to target shared libraries", "PATH") |
| 55 | 55 | .reqopt("", "rustc-path", "path to rustc to use for compiling", "PATH") |
| 56 | 56 | .optopt("", "cargo-path", "path to cargo to use for compiling", "PATH") |
| 57 | .optopt( | |
| 58 | "", | |
| 59 | "stage0-rustc-path", | |
| 60 | "path to rustc to use for compiling run-make recipes", | |
| 61 | "PATH", | |
| 62 | ) | |
| 57 | 63 | .optopt("", "rustdoc-path", "path to rustdoc to use for compiling", "PATH") |
| 58 | 64 | .optopt("", "coverage-dump-path", "path to coverage-dump to use in tests", "PATH") |
| 59 | 65 | .reqopt("", "python", "path to python to use for doc tests", "PATH") |
| ... | ... | @@ -320,6 +326,7 @@ pub fn parse_config(args: Vec<String>) -> Config { |
| 320 | 326 | run_lib_path: make_absolute(opt_path(matches, "run-lib-path")), |
| 321 | 327 | rustc_path: opt_path(matches, "rustc-path"), |
| 322 | 328 | cargo_path: matches.opt_str("cargo-path").map(PathBuf::from), |
| 329 | stage0_rustc_path: matches.opt_str("stage0-rustc-path").map(PathBuf::from), | |
| 323 | 330 | rustdoc_path: matches.opt_str("rustdoc-path").map(PathBuf::from), |
| 324 | 331 | coverage_dump_path: matches.opt_str("coverage-dump-path").map(PathBuf::from), |
| 325 | 332 | python: matches.opt_str("python").unwrap(), |
src/tools/compiletest/src/runtest/run_make.rs+41-78| ... | ... | @@ -173,7 +173,8 @@ impl TestCx<'_> { |
| 173 | 173 | fn run_rmake_v2_test(&self) { |
| 174 | 174 | // For `run-make` V2, we need to perform 2 steps to build and run a `run-make` V2 recipe |
| 175 | 175 | // (`rmake.rs`) to run the actual tests. The support library is already built as a tool rust |
| 176 | // library and is available under `build/$TARGET/stageN-tools-bin/librun_make_support.rlib`. | |
| 176 | // library and is available under | |
| 177 | // `build/$HOST/stage0-bootstrap-tools/$TARGET/release/librun_make_support.rlib`. | |
| 177 | 178 | // |
| 178 | 179 | // 1. We need to build the recipe `rmake.rs` as a binary and link in the `run_make_support` |
| 179 | 180 | // library. |
| ... | ... | @@ -224,25 +225,21 @@ impl TestCx<'_> { |
| 224 | 225 | // |
| 225 | 226 | // ``` |
| 226 | 227 | // build/<target_triple>/ |
| 227 | // ├── stageN-tools-bin/ | |
| 228 | // │ └── librun_make_support.rlib // <- support rlib itself | |
| 229 | // ├── stageN-tools/ | |
| 230 | // │ ├── release/deps/ // <- deps of deps | |
| 231 | // │ └── <host_triple>/release/deps/ // <- deps | |
| 228 | // ├── stage0-bootstrap-tools/ | |
| 229 | // │ ├── <host_triple>/release/librun_make_support.rlib // <- support rlib itself | |
| 230 | // │ ├── <host_triple>/release/deps/ // <- deps | |
| 231 | // │ └── release/deps/ // <- deps of deps | |
| 232 | 232 | // ``` |
| 233 | 233 | // |
| 234 | 234 | // FIXME(jieyouxu): there almost certainly is a better way to do this (specifically how the |
| 235 | // support lib and its deps are organized, can't we copy them to the tools-bin dir as | |
| 236 | // well?), but this seems to work for now. | |
| 235 | // support lib and its deps are organized), but this seems to work for now. | |
| 237 | 236 | |
| 238 | let stage_number = self.config.stage; | |
| 237 | let tools_bin = host_build_root.join("stage0-bootstrap-tools"); | |
| 238 | let support_host_path = tools_bin.join(&self.config.host).join("release"); | |
| 239 | let support_lib_path = support_host_path.join("librun_make_support.rlib"); | |
| 239 | 240 | |
| 240 | let stage_tools_bin = host_build_root.join(format!("stage{stage_number}-tools-bin")); | |
| 241 | let support_lib_path = stage_tools_bin.join("librun_make_support.rlib"); | |
| 242 | ||
| 243 | let stage_tools = host_build_root.join(format!("stage{stage_number}-tools")); | |
| 244 | let support_lib_deps = stage_tools.join(&self.config.host).join("release").join("deps"); | |
| 245 | let support_lib_deps_deps = stage_tools.join("release").join("deps"); | |
| 241 | let support_lib_deps = support_host_path.join("deps"); | |
| 242 | let support_lib_deps_deps = tools_bin.join("release").join("deps"); | |
| 246 | 243 | |
| 247 | 244 | // To compile the recipe with rustc, we need to provide suitable dynamic library search |
| 248 | 245 | // paths to rustc. This includes both: |
| ... | ... | @@ -253,12 +250,6 @@ impl TestCx<'_> { |
| 253 | 250 | let base_dylib_search_paths = |
| 254 | 251 | Vec::from_iter(env::split_paths(&env::var(dylib_env_var()).unwrap())); |
| 255 | 252 | |
| 256 | let host_dylib_search_paths = { | |
| 257 | let mut paths = vec![self.config.compile_lib_path.clone()]; | |
| 258 | paths.extend(base_dylib_search_paths.iter().cloned()); | |
| 259 | paths | |
| 260 | }; | |
| 261 | ||
| 262 | 253 | // Calculate the paths of the recipe binary. As previously discussed, this is placed at |
| 263 | 254 | // `<base_dir>/<bin_name>` with `bin_name` being `rmake` or `rmake.exe` depending on |
| 264 | 255 | // platform. |
| ... | ... | @@ -268,7 +259,15 @@ impl TestCx<'_> { |
| 268 | 259 | p |
| 269 | 260 | }; |
| 270 | 261 | |
| 271 | let mut rustc = Command::new(&self.config.rustc_path); | |
| 262 | // run-make-support and run-make tests are compiled using the stage0 compiler | |
| 263 | // If the stage is 0, then the compiler that we test (either bootstrap or an explicitly | |
| 264 | // set compiler) is the one that actually compiled run-make-support. | |
| 265 | let stage0_rustc = self | |
| 266 | .config | |
| 267 | .stage0_rustc_path | |
| 268 | .as_ref() | |
| 269 | .expect("stage0 rustc is required to run run-make tests"); | |
| 270 | let mut rustc = Command::new(&stage0_rustc); | |
| 272 | 271 | rustc |
| 273 | 272 | .arg("-o") |
| 274 | 273 | .arg(&recipe_bin) |
| ... | ... | @@ -282,35 +281,12 @@ impl TestCx<'_> { |
| 282 | 281 | .arg(format!("run_make_support={}", &support_lib_path.to_string_lossy())) |
| 283 | 282 | .arg("--edition=2021") |
| 284 | 283 | .arg(&self.testpaths.file.join("rmake.rs")) |
| 285 | .arg("-Cprefer-dynamic") | |
| 286 | // Provide necessary library search paths for rustc. | |
| 287 | .env(dylib_env_var(), &env::join_paths(host_dylib_search_paths).unwrap()); | |
| 284 | .arg("-Cprefer-dynamic"); | |
| 288 | 285 | |
| 289 | 286 | // In test code we want to be very pedantic about values being silently discarded that are |
| 290 | 287 | // annotated with `#[must_use]`. |
| 291 | 288 | rustc.arg("-Dunused_must_use"); |
| 292 | 289 | |
| 293 | // > `cg_clif` uses `COMPILETEST_FORCE_STAGE0=1 ./x.py test --stage 0` for running the rustc | |
| 294 | // > test suite. With the introduction of rmake.rs this broke. `librun_make_support.rlib` is | |
| 295 | // > compiled using the bootstrap rustc wrapper which sets `--sysroot | |
| 296 | // > build/aarch64-unknown-linux-gnu/stage0-sysroot`, but then compiletest will compile | |
| 297 | // > `rmake.rs` using the sysroot of the bootstrap compiler causing it to not find the | |
| 298 | // > `libstd.rlib` against which `librun_make_support.rlib` is compiled. | |
| 299 | // | |
| 300 | // The gist here is that we have to pass the proper stage0 sysroot if we want | |
| 301 | // | |
| 302 | // ``` | |
| 303 | // $ COMPILETEST_FORCE_STAGE0=1 ./x test run-make --stage 0 | |
| 304 | // ``` | |
| 305 | // | |
| 306 | // to work correctly. | |
| 307 | // | |
| 308 | // See <https://github.com/rust-lang/rust/pull/122248> for more background. | |
| 309 | let stage0_sysroot = host_build_root.join("stage0-sysroot"); | |
| 310 | if std::env::var_os("COMPILETEST_FORCE_STAGE0").is_some() { | |
| 311 | rustc.arg("--sysroot").arg(&stage0_sysroot); | |
| 312 | } | |
| 313 | ||
| 314 | 290 | // Now run rustc to build the recipe. |
| 315 | 291 | let res = self.run_command_to_procres(&mut rustc); |
| 316 | 292 | if !res.status.success() { |
| ... | ... | @@ -320,35 +296,24 @@ impl TestCx<'_> { |
| 320 | 296 | // To actually run the recipe, we have to provide the recipe with a bunch of information |
| 321 | 297 | // provided through env vars. |
| 322 | 298 | |
| 323 | // Compute stage-specific standard library paths. | |
| 324 | let stage_std_path = host_build_root.join(format!("stage{stage_number}")).join("lib"); | |
| 325 | ||
| 326 | 299 | // Compute dynamic library search paths for recipes. |
| 300 | // These dylib directories are needed to **execute the recipe**. | |
| 327 | 301 | let recipe_dylib_search_paths = { |
| 328 | 302 | let mut paths = base_dylib_search_paths.clone(); |
| 329 | ||
| 330 | // For stage 0, we need to explicitly include the stage0-sysroot libstd dylib. | |
| 331 | // See <https://github.com/rust-lang/rust/issues/135373>. | |
| 332 | if std::env::var_os("COMPILETEST_FORCE_STAGE0").is_some() { | |
| 333 | paths.push( | |
| 334 | stage0_sysroot.join("lib").join("rustlib").join(&self.config.host).join("lib"), | |
| 335 | ); | |
| 336 | } | |
| 337 | ||
| 338 | paths.push(support_lib_path.parent().unwrap().to_path_buf()); | |
| 339 | paths.push(stage_std_path.join("rustlib").join(&self.config.host).join("lib")); | |
| 340 | paths | |
| 341 | }; | |
| 342 | ||
| 343 | // Compute runtime library search paths for recipes. This is target-specific. | |
| 344 | let target_runtime_dylib_search_paths = { | |
| 345 | let mut paths = vec![rmake_out_dir.clone()]; | |
| 346 | paths.extend(base_dylib_search_paths.iter().cloned()); | |
| 303 | paths.push( | |
| 304 | stage0_rustc | |
| 305 | .parent() | |
| 306 | .unwrap() | |
| 307 | .parent() | |
| 308 | .unwrap() | |
| 309 | .join("lib") | |
| 310 | .join("rustlib") | |
| 311 | .join(&self.config.host) | |
| 312 | .join("lib"), | |
| 313 | ); | |
| 347 | 314 | paths |
| 348 | 315 | }; |
| 349 | 316 | |
| 350 | // FIXME(jieyouxu): please rename `TARGET_RPATH_ENV`, `HOST_RPATH_DIR` and | |
| 351 | // `TARGET_RPATH_DIR`, it is **extremely** confusing! | |
| 352 | 317 | let mut cmd = Command::new(&recipe_bin); |
| 353 | 318 | cmd.current_dir(&rmake_out_dir) |
| 354 | 319 | .stdout(Stdio::piped()) |
| ... | ... | @@ -357,9 +322,14 @@ impl TestCx<'_> { |
| 357 | 322 | // example, this could be `LD_LIBRARY_PATH` on some linux distros but `PATH` on Windows. |
| 358 | 323 | .env("LD_LIB_PATH_ENVVAR", dylib_env_var()) |
| 359 | 324 | // Provide the dylib search paths. |
| 325 | // This is required to run the **recipe** itself. | |
| 360 | 326 | .env(dylib_env_var(), &env::join_paths(recipe_dylib_search_paths).unwrap()) |
| 361 | // Provide runtime dylib search paths. | |
| 362 | .env("TARGET_RPATH_ENV", &env::join_paths(target_runtime_dylib_search_paths).unwrap()) | |
| 327 | // Provide the directory to libraries that are needed to run the *compiler* invoked | |
| 328 | // by the recipe. | |
| 329 | .env("HOST_RUSTC_DYLIB_PATH", &self.config.compile_lib_path) | |
| 330 | // Provide the directory to libraries that might be needed to run binaries created | |
| 331 | // by a compiler invoked by the recipe. | |
| 332 | .env("TARGET_EXE_DYLIB_PATH", &self.config.run_lib_path) | |
| 363 | 333 | // Provide the target. |
| 364 | 334 | .env("TARGET", &self.config.target) |
| 365 | 335 | // Some tests unfortunately still need Python, so provide path to a Python interpreter. |
| ... | ... | @@ -370,13 +340,6 @@ impl TestCx<'_> { |
| 370 | 340 | .env("BUILD_ROOT", &host_build_root) |
| 371 | 341 | // Provide path to stage-corresponding rustc. |
| 372 | 342 | .env("RUSTC", &self.config.rustc_path) |
| 373 | // Provide the directory to libraries that are needed to run the *compiler*. This is not | |
| 374 | // to be confused with `TARGET_RPATH_ENV` or `TARGET_RPATH_DIR`. This is needed if the | |
| 375 | // recipe wants to invoke rustc. | |
| 376 | .env("HOST_RPATH_DIR", &self.config.compile_lib_path) | |
| 377 | // Provide the directory to libraries that might be needed to run compiled binaries | |
| 378 | // (further compiled by the recipe!). | |
| 379 | .env("TARGET_RPATH_DIR", &self.config.run_lib_path) | |
| 380 | 343 | // Provide which LLVM components are available (e.g. which LLVM components are provided |
| 381 | 344 | // through a specific CI runner). |
| 382 | 345 | .env("LLVM_COMPONENTS", &self.config.llvm_components); |
src/tools/opt-dist/src/main.rs+1| ... | ... | @@ -389,6 +389,7 @@ fn main() -> anyhow::Result<()> { |
| 389 | 389 | "clippy", |
| 390 | 390 | "miri", |
| 391 | 391 | "rustfmt", |
| 392 | "gcc", | |
| 392 | 393 | ] { |
| 393 | 394 | build_args.extend(["--skip".to_string(), target.to_string()]); |
| 394 | 395 | } |
src/tools/opt-dist/src/metrics.rs+3-70| ... | ... | @@ -1,33 +1,10 @@ |
| 1 | 1 | use std::time::Duration; |
| 2 | 2 | |
| 3 | use build_helper::metrics::{JsonNode, JsonRoot}; | |
| 3 | use build_helper::metrics::{BuildStep, JsonRoot, format_build_steps}; | |
| 4 | 4 | use camino::Utf8Path; |
| 5 | 5 | |
| 6 | 6 | use crate::timer::TimerSection; |
| 7 | 7 | |
| 8 | #[derive(Clone, Debug)] | |
| 9 | pub struct BuildStep { | |
| 10 | r#type: String, | |
| 11 | children: Vec<BuildStep>, | |
| 12 | duration: Duration, | |
| 13 | } | |
| 14 | ||
| 15 | impl BuildStep { | |
| 16 | pub fn find_all_by_type(&self, r#type: &str) -> Vec<&BuildStep> { | |
| 17 | let mut result = Vec::new(); | |
| 18 | self.find_by_type(r#type, &mut result); | |
| 19 | result | |
| 20 | } | |
| 21 | fn find_by_type<'a>(&'a self, r#type: &str, result: &mut Vec<&'a BuildStep>) { | |
| 22 | if self.r#type == r#type { | |
| 23 | result.push(self); | |
| 24 | } | |
| 25 | for child in &self.children { | |
| 26 | child.find_by_type(r#type, result); | |
| 27 | } | |
| 28 | } | |
| 29 | } | |
| 30 | ||
| 31 | 8 | /// Loads the metrics of the most recent bootstrap execution from a metrics.json file. |
| 32 | 9 | pub fn load_metrics(path: &Utf8Path) -> anyhow::Result<BuildStep> { |
| 33 | 10 | let content = std::fs::read(path.as_std_path())?; |
| ... | ... | @@ -37,30 +14,7 @@ pub fn load_metrics(path: &Utf8Path) -> anyhow::Result<BuildStep> { |
| 37 | 14 | .pop() |
| 38 | 15 | .ok_or_else(|| anyhow::anyhow!("No bootstrap invocation found in metrics file"))?; |
| 39 | 16 | |
| 40 | fn parse(node: JsonNode) -> Option<BuildStep> { | |
| 41 | match node { | |
| 42 | JsonNode::RustbuildStep { | |
| 43 | type_: kind, | |
| 44 | children, | |
| 45 | duration_excluding_children_sec, | |
| 46 | .. | |
| 47 | } => { | |
| 48 | let children: Vec<_> = children.into_iter().filter_map(parse).collect(); | |
| 49 | let children_duration = children.iter().map(|c| c.duration).sum::<Duration>(); | |
| 50 | Some(BuildStep { | |
| 51 | r#type: kind.to_string(), | |
| 52 | children, | |
| 53 | duration: children_duration | |
| 54 | + Duration::from_secs_f64(duration_excluding_children_sec), | |
| 55 | }) | |
| 56 | } | |
| 57 | JsonNode::TestSuite(_) => None, | |
| 58 | } | |
| 59 | } | |
| 60 | ||
| 61 | let duration = Duration::from_secs_f64(invocation.duration_including_children_sec); | |
| 62 | let children: Vec<_> = invocation.children.into_iter().filter_map(parse).collect(); | |
| 63 | Ok(BuildStep { r#type: "root".to_string(), children, duration }) | |
| 17 | Ok(BuildStep::from_invocation(&invocation)) | |
| 64 | 18 | } |
| 65 | 19 | |
| 66 | 20 | /// 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) { |
| 82 | 36 | timer.add_duration("Rustc", rustc_duration); |
| 83 | 37 | } |
| 84 | 38 | |
| 85 | log_metrics(metrics); | |
| 86 | } | |
| 87 | ||
| 88 | fn log_metrics(metrics: &BuildStep) { | |
| 89 | use std::fmt::Write; | |
| 90 | ||
| 91 | let mut substeps: Vec<(u32, &BuildStep)> = Vec::new(); | |
| 92 | ||
| 93 | fn visit<'a>(step: &'a BuildStep, level: u32, substeps: &mut Vec<(u32, &'a BuildStep)>) { | |
| 94 | substeps.push((level, step)); | |
| 95 | for child in &step.children { | |
| 96 | visit(child, level + 1, substeps); | |
| 97 | } | |
| 98 | } | |
| 99 | ||
| 100 | visit(metrics, 0, &mut substeps); | |
| 101 | ||
| 102 | let mut output = String::new(); | |
| 103 | for (level, step) in substeps { | |
| 104 | let label = format!("{}{}", ".".repeat(level as usize), step.r#type); | |
| 105 | writeln!(output, "{label:<65}{:>8.2}s", step.duration.as_secs_f64()).unwrap(); | |
| 106 | } | |
| 39 | let output = format_build_steps(metrics); | |
| 107 | 40 | log::info!("Build step durations\n{output}"); |
| 108 | 41 | } |
src/tools/run-make-support/src/external_deps/rustc.rs+4-4| ... | ... | @@ -5,7 +5,7 @@ use std::str::FromStr as _; |
| 5 | 5 | use crate::command::Command; |
| 6 | 6 | use crate::env::env_var; |
| 7 | 7 | use crate::path_helpers::cwd; |
| 8 | use crate::util::set_host_rpath; | |
| 8 | use crate::util::set_host_compiler_dylib_path; | |
| 9 | 9 | use crate::{is_aix, is_darwin, is_msvc, is_windows, uname}; |
| 10 | 10 | |
| 11 | 11 | /// Construct a new `rustc` invocation. This will automatically set the library |
| ... | ... | @@ -15,8 +15,8 @@ pub fn rustc() -> Rustc { |
| 15 | 15 | Rustc::new() |
| 16 | 16 | } |
| 17 | 17 | |
| 18 | /// Construct a plain `rustc` invocation with no flags set. Note that [`set_host_rpath`] | |
| 19 | /// still presets the environment variable `HOST_RPATH_DIR` by default. | |
| 18 | /// Construct a plain `rustc` invocation with no flags set. Note that [`set_host_compiler_dylib_path`] | |
| 19 | /// still presets the environment variable `HOST_RUSTC_DYLIB_PATH` by default. | |
| 20 | 20 | #[track_caller] |
| 21 | 21 | pub fn bare_rustc() -> Rustc { |
| 22 | 22 | Rustc::bare() |
| ... | ... | @@ -44,7 +44,7 @@ pub fn rustc_path() -> String { |
| 44 | 44 | #[track_caller] |
| 45 | 45 | fn setup_common() -> Command { |
| 46 | 46 | let mut cmd = Command::new(rustc_path()); |
| 47 | set_host_rpath(&mut cmd); | |
| 47 | set_host_compiler_dylib_path(&mut cmd); | |
| 48 | 48 | cmd |
| 49 | 49 | } |
| 50 | 50 |
src/tools/run-make-support/src/external_deps/rustdoc.rs+5-19| ... | ... | @@ -2,16 +2,10 @@ use std::ffi::OsStr; |
| 2 | 2 | use std::path::Path; |
| 3 | 3 | |
| 4 | 4 | use crate::command::Command; |
| 5 | use crate::env::{env_var, env_var_os}; | |
| 6 | use crate::util::set_host_rpath; | |
| 5 | use crate::env::env_var; | |
| 6 | use crate::util::set_host_compiler_dylib_path; | |
| 7 | 7 | |
| 8 | /// Construct a plain `rustdoc` invocation with no flags set. | |
| 9 | #[track_caller] | |
| 10 | pub fn bare_rustdoc() -> Rustdoc { | |
| 11 | Rustdoc::bare() | |
| 12 | } | |
| 13 | ||
| 14 | /// Construct a new `rustdoc` invocation with `-L $(TARGET_RPATH_DIR)` set. | |
| 8 | /// Construct a new `rustdoc` invocation. | |
| 15 | 9 | #[track_caller] |
| 16 | 10 | pub fn rustdoc() -> Rustdoc { |
| 17 | 11 | Rustdoc::new() |
| ... | ... | @@ -29,23 +23,15 @@ crate::macros::impl_common_helpers!(Rustdoc); |
| 29 | 23 | fn setup_common() -> Command { |
| 30 | 24 | let rustdoc = env_var("RUSTDOC"); |
| 31 | 25 | let mut cmd = Command::new(rustdoc); |
| 32 | set_host_rpath(&mut cmd); | |
| 26 | set_host_compiler_dylib_path(&mut cmd); | |
| 33 | 27 | cmd |
| 34 | 28 | } |
| 35 | 29 | |
| 36 | 30 | impl Rustdoc { |
| 37 | 31 | /// Construct a bare `rustdoc` invocation. |
| 38 | 32 | #[track_caller] |
| 39 | pub fn bare() -> Self { | |
| 40 | let cmd = setup_common(); | |
| 41 | Self { cmd } | |
| 42 | } | |
| 43 | ||
| 44 | /// Construct a `rustdoc` invocation with `-L $(TARGET_RPATH_DIR)` set. | |
| 45 | #[track_caller] | |
| 46 | 33 | pub fn new() -> Self { |
| 47 | let mut cmd = setup_common(); | |
| 48 | cmd.arg("-L").arg(env_var_os("TARGET_RPATH_DIR")); | |
| 34 | let cmd = setup_common(); | |
| 49 | 35 | Self { cmd } |
| 50 | 36 | } |
| 51 | 37 |
src/tools/run-make-support/src/lib.rs+1-1| ... | ... | @@ -67,7 +67,7 @@ pub use llvm::{ |
| 67 | 67 | }; |
| 68 | 68 | pub use python::python_command; |
| 69 | 69 | pub use rustc::{aux_build, bare_rustc, rustc, rustc_path, Rustc}; |
| 70 | pub use rustdoc::{bare_rustdoc, rustdoc, Rustdoc}; | |
| 70 | pub use rustdoc::{rustdoc, Rustdoc}; | |
| 71 | 71 | |
| 72 | 72 | /// [`diff`][mod@diff] is implemented in terms of the [similar] library. |
| 73 | 73 | /// |
src/tools/run-make-support/src/run.rs+5-14| ... | ... | @@ -1,10 +1,10 @@ |
| 1 | 1 | use std::ffi::OsStr; |
| 2 | use std::path::{Path, PathBuf}; | |
| 2 | use std::path::PathBuf; | |
| 3 | 3 | use std::{env, panic}; |
| 4 | 4 | |
| 5 | 5 | use crate::command::{Command, CompletedProcess}; |
| 6 | use crate::util::{handle_failed_output, set_host_rpath}; | |
| 7 | use crate::{cwd, env_var, is_windows}; | |
| 6 | use crate::util::handle_failed_output; | |
| 7 | use crate::{cwd, env_var}; | |
| 8 | 8 | |
| 9 | 9 | #[track_caller] |
| 10 | 10 | fn run_common(name: &str, args: Option<&[&str]>) -> Command { |
| ... | ... | @@ -18,10 +18,11 @@ fn run_common(name: &str, args: Option<&[&str]>) -> Command { |
| 18 | 18 | cmd.arg(arg); |
| 19 | 19 | } |
| 20 | 20 | } |
| 21 | ||
| 21 | 22 | cmd.env(&ld_lib_path_envvar, { |
| 22 | 23 | let mut paths = vec![]; |
| 23 | 24 | paths.push(cwd()); |
| 24 | for p in env::split_paths(&env_var("TARGET_RPATH_ENV")) { | |
| 25 | for p in env::split_paths(&env_var("TARGET_EXE_DYLIB_PATH")) { | |
| 25 | 26 | paths.push(p.to_path_buf()); |
| 26 | 27 | } |
| 27 | 28 | 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 { |
| 31 | 32 | }); |
| 32 | 33 | cmd.env("LC_ALL", "C"); // force english locale |
| 33 | 34 | |
| 34 | if is_windows() { | |
| 35 | let mut paths = vec![]; | |
| 36 | for p in env::split_paths(&std::env::var("PATH").unwrap_or(String::new())) { | |
| 37 | paths.push(p.to_path_buf()); | |
| 38 | } | |
| 39 | paths.push(Path::new(&env_var("TARGET_RPATH_DIR")).to_path_buf()); | |
| 40 | cmd.env("PATH", env::join_paths(paths.iter()).unwrap()); | |
| 41 | } | |
| 42 | ||
| 43 | 35 | cmd |
| 44 | 36 | } |
| 45 | 37 | |
| ... | ... | @@ -84,7 +76,6 @@ pub fn run_fail(name: &str) -> CompletedProcess { |
| 84 | 76 | #[track_caller] |
| 85 | 77 | pub fn cmd<S: AsRef<OsStr>>(program: S) -> Command { |
| 86 | 78 | let mut command = Command::new(program); |
| 87 | set_host_rpath(&mut command); | |
| 88 | 79 | command.env("LC_ALL", "C"); // force english locale |
| 89 | 80 | command |
| 90 | 81 | } |
src/tools/run-make-support/src/util.rs+3-3| ... | ... | @@ -24,13 +24,13 @@ pub(crate) fn handle_failed_output( |
| 24 | 24 | std::process::exit(1) |
| 25 | 25 | } |
| 26 | 26 | |
| 27 | /// Set the runtime library path as needed for running the host rustc/rustdoc/etc. | |
| 28 | pub(crate) fn set_host_rpath(cmd: &mut Command) { | |
| 27 | /// Set the runtime library paths as needed for running the host compilers (rustc/rustdoc/etc). | |
| 28 | pub(crate) fn set_host_compiler_dylib_path(cmd: &mut Command) { | |
| 29 | 29 | let ld_lib_path_envvar = env_var("LD_LIB_PATH_ENVVAR"); |
| 30 | 30 | cmd.env(&ld_lib_path_envvar, { |
| 31 | 31 | let mut paths = vec![]; |
| 32 | 32 | paths.push(cwd()); |
| 33 | paths.push(PathBuf::from(env_var("HOST_RPATH_DIR"))); | |
| 33 | paths.push(PathBuf::from(env_var("HOST_RUSTC_DYLIB_PATH"))); | |
| 34 | 34 | for p in std::env::split_paths(&env_var(&ld_lib_path_envvar)) { |
| 35 | 35 | paths.push(p.to_path_buf()); |
| 36 | 36 | } |
src/tools/rustdoc/Cargo.toml+1-1| ... | ... | @@ -1,7 +1,7 @@ |
| 1 | 1 | [package] |
| 2 | 2 | name = "rustdoc-tool" |
| 3 | 3 | version = "0.0.0" |
| 4 | edition = "2021" | |
| 4 | edition = "2024" | |
| 5 | 5 | |
| 6 | 6 | # Cargo adds a number of paths to the dylib search path on windows, which results in |
| 7 | 7 | # the wrong rustdoc being executed. To avoid the conflicting rustdocs, we name the "tool" |
tests/run-make/a-b-a-linker-guard/rmake.rs+4-3| ... | ... | @@ -1,7 +1,8 @@ |
| 1 | // ignore-tidy-linelength | |
| 1 | // Test that if we build `b` against a version of `a` that has | |
| 2 | // one set of types, it will not run with a dylib that has a different set of types. | |
| 2 | 3 | |
| 3 | // Test that if we build `b` against a version of `a` that has one set of types, it will not run | |
| 4 | // with a dylib that has a different set of types. | |
| 4 | //@ ignore-cross-compile | |
| 5 | // Reason: the compiled binary is executed | |
| 5 | 6 | |
| 6 | 7 | use run_make_support::{run, run_fail, rustc}; |
| 7 | 8 |
tests/run-make/rustdoc-default-output/rmake.rs+2-2| ... | ... | @@ -3,10 +3,10 @@ |
| 3 | 3 | // ensures the output of rustdoc's help menu is as expected. |
| 4 | 4 | // See https://github.com/rust-lang/rust/issues/88756 |
| 5 | 5 | |
| 6 | use run_make_support::{bare_rustdoc, diff}; | |
| 6 | use run_make_support::{diff, rustdoc}; | |
| 7 | 7 | |
| 8 | 8 | fn main() { |
| 9 | let out = bare_rustdoc().run().stdout_utf8(); | |
| 9 | let out = rustdoc().run().stdout_utf8(); | |
| 10 | 10 | diff() |
| 11 | 11 | .expected_file("output-default.stdout") |
| 12 | 12 | .actual_text("actual", out) |
tests/run-make/version-verbose-commit-hash/rmake.rs+2-2| ... | ... | @@ -5,13 +5,13 @@ |
| 5 | 5 | |
| 6 | 6 | //@ needs-git-hash |
| 7 | 7 | |
| 8 | use run_make_support::{bare_rustc, bare_rustdoc, regex}; | |
| 8 | use run_make_support::{bare_rustc, regex, rustdoc}; | |
| 9 | 9 | |
| 10 | 10 | fn main() { |
| 11 | 11 | let out_rustc = |
| 12 | 12 | bare_rustc().arg("--version").arg("--verbose").run().stdout_utf8().to_lowercase(); |
| 13 | 13 | let out_rustdoc = |
| 14 | bare_rustdoc().arg("--version").arg("--verbose").run().stdout_utf8().to_lowercase(); | |
| 14 | rustdoc().arg("--version").arg("--verbose").run().stdout_utf8().to_lowercase(); | |
| 15 | 15 | let re = |
| 16 | 16 | regex::Regex::new(r#"commit-hash: [0-9a-f]{40}\ncommit-date: [0-9]{4}-[0-9]{2}-[0-9]{2}"#) |
| 17 | 17 | .unwrap(); |