diff options
Diffstat (limited to 'src')
95 files changed, 1078 insertions, 565 deletions
diff --git a/src/bootstrap/src/core/build_steps/check.rs b/src/bootstrap/src/core/build_steps/check.rs index 567416d079b..6c5f70b2f43 100644 --- a/src/bootstrap/src/core/build_steps/check.rs +++ b/src/bootstrap/src/core/build_steps/check.rs @@ -5,7 +5,7 @@ use crate::core::build_steps::compile::{ }; use crate::core::build_steps::tool::{COMPILETEST_ALLOW_FEATURES, SourceType, prepare_tool_cargo}; use crate::core::builder::{ - self, Alias, Builder, Kind, RunConfig, ShouldRun, Step, crate_description, + self, Alias, Builder, Kind, RunConfig, ShouldRun, Step, StepMetadata, crate_description, }; use crate::core::config::TargetSelection; use crate::utils::build_stamp::{self, BuildStamp}; @@ -167,6 +167,10 @@ impl Step for Std { let _guard = builder.msg_check("library test/bench/example targets", target, Some(stage)); run_cargo(builder, cargo, builder.config.free_args.clone(), &stamp, vec![], true, false); } + + fn metadata(&self) -> Option<StepMetadata> { + Some(StepMetadata::check("std", self.target)) + } } #[derive(Debug, Clone, PartialEq, Eq, Hash)] @@ -258,6 +262,10 @@ impl Step for Rustc { let hostdir = builder.sysroot_target_libdir(compiler, compiler.host); add_to_sysroot(builder, &libdir, &hostdir, &stamp); } + + fn metadata(&self) -> Option<StepMetadata> { + Some(StepMetadata::check("rustc", self.target)) + } } #[derive(Debug, Clone, PartialEq, Eq, Hash)] @@ -315,6 +323,10 @@ impl Step for CodegenBackend { run_cargo(builder, cargo, builder.config.free_args.clone(), &stamp, vec![], true, false); } + + fn metadata(&self) -> Option<StepMetadata> { + Some(StepMetadata::check(self.backend, self.target)) + } } #[derive(Debug, Clone, PartialEq, Eq, Hash)] @@ -373,6 +385,10 @@ impl Step for RustAnalyzer { let _guard = builder.msg_check("rust-analyzer artifacts", target, None); run_cargo(builder, cargo, builder.config.free_args.clone(), &stamp, vec![], true, false); } + + fn metadata(&self) -> Option<StepMetadata> { + Some(StepMetadata::check("rust-analyzer", self.target)) + } } /// Compiletest is implicitly "checked" when it gets built in order to run tests, @@ -432,6 +448,10 @@ impl Step for Compiletest { let _guard = builder.msg_check("compiletest artifacts", self.target, None); run_cargo(builder, cargo, builder.config.free_args.clone(), &stamp, vec![], true, false); } + + fn metadata(&self) -> Option<StepMetadata> { + Some(StepMetadata::check("compiletest", self.target)) + } } macro_rules! tool_check_step { @@ -467,6 +487,10 @@ macro_rules! tool_check_step { let Self { target } = self; run_tool_check_step(builder, target, stringify!($name), $path); } + + fn metadata(&self) -> Option<StepMetadata> { + Some(StepMetadata::check(stringify!($name), self.target)) + } } } } diff --git a/src/bootstrap/src/core/build_steps/clean.rs b/src/bootstrap/src/core/build_steps/clean.rs index 882fcd08780..f67569d1486 100644 --- a/src/bootstrap/src/core/build_steps/clean.rs +++ b/src/bootstrap/src/core/build_steps/clean.rs @@ -181,7 +181,7 @@ fn rm_rf(path: &Path) { panic!("failed to get metadata for file {}: {}", path.display(), e); } Ok(metadata) => { - if metadata.file_type().is_file() || metadata.file_type().is_symlink() { + if !metadata.file_type().is_dir() { do_op(path, "remove file", |p| match fs::remove_file(p) { #[cfg(windows)] Err(e) diff --git a/src/bootstrap/src/core/build_steps/compile.rs b/src/bootstrap/src/core/build_steps/compile.rs index 84064150738..c3a3eddd161 100644 --- a/src/bootstrap/src/core/build_steps/compile.rs +++ b/src/bootstrap/src/core/build_steps/compile.rs @@ -306,11 +306,7 @@ impl Step for Std { } fn metadata(&self) -> Option<StepMetadata> { - Some( - StepMetadata::build("std", self.target) - .built_by(self.compiler) - .stage(self.compiler.stage), - ) + Some(StepMetadata::build("std", self.target).built_by(self.compiler)) } } @@ -1186,11 +1182,7 @@ impl Step for Rustc { } fn metadata(&self) -> Option<StepMetadata> { - Some( - StepMetadata::build("rustc", self.target) - .built_by(self.build_compiler) - .stage(self.build_compiler.stage + 1), - ) + Some(StepMetadata::build("rustc", self.target).built_by(self.build_compiler)) } } diff --git a/src/bootstrap/src/core/build_steps/format.rs b/src/bootstrap/src/core/build_steps/format.rs index 61268df7336..d487995e98a 100644 --- a/src/bootstrap/src/core/build_steps/format.rs +++ b/src/bootstrap/src/core/build_steps/format.rs @@ -346,6 +346,6 @@ pub fn format(build: &Builder<'_>, check: bool, all: bool, paths: &[PathBuf]) { // since last merge. // // NOTE: Because of the exit above, this is only reachable if formatting / format checking - // succeeded. So we are not commiting the version if formatting was not good. + // succeeded. So we are not committing the version if formatting was not good. update_rustfmt_version(build); } diff --git a/src/bootstrap/src/core/build_steps/test.rs b/src/bootstrap/src/core/build_steps/test.rs index 01b181f55de..2d4d9e53598 100644 --- a/src/bootstrap/src/core/build_steps/test.rs +++ b/src/bootstrap/src/core/build_steps/test.rs @@ -1108,7 +1108,9 @@ impl Step for Tidy { if builder.config.cmd.bless() { cmd.arg("--bless"); } - if let Some(s) = builder.config.cmd.extra_checks() { + if let Some(s) = + builder.config.cmd.extra_checks().or(builder.config.tidy_extra_checks.as_deref()) + { cmd.arg(format!("--extra-checks={s}")); } let mut args = std::env::args_os(); diff --git a/src/bootstrap/src/core/build_steps/tool.rs b/src/bootstrap/src/core/build_steps/tool.rs index a7220515ca0..ad3f8d89767 100644 --- a/src/bootstrap/src/core/build_steps/tool.rs +++ b/src/bootstrap/src/core/build_steps/tool.rs @@ -1195,7 +1195,6 @@ macro_rules! tool_extended { Some( StepMetadata::build($tool_name, self.target) .built_by(self.compiler.with_stage(self.compiler.stage.saturating_sub(1))) - .stage(self.compiler.stage) ) } } diff --git a/src/bootstrap/src/core/builder/mod.rs b/src/bootstrap/src/core/builder/mod.rs index 8e9e8b496de..b96a988cde3 100644 --- a/src/bootstrap/src/core/builder/mod.rs +++ b/src/bootstrap/src/core/builder/mod.rs @@ -153,6 +153,10 @@ impl StepMetadata { Self::new(name, target, Kind::Build) } + pub fn check(name: &'static str, target: TargetSelection) -> Self { + Self::new(name, target, Kind::Check) + } + pub fn doc(name: &'static str, target: TargetSelection) -> Self { Self::new(name, target, Kind::Doc) } @@ -178,6 +182,14 @@ impl StepMetadata { self.stage = Some(stage); self } + + pub fn get_stage(&self) -> Option<u32> { + self.stage.or(self + .built_by + // For std, its stage corresponds to the stage of the compiler that builds it. + // For everything else, a stage N things gets built by a stage N-1 compiler. + .map(|compiler| if self.name == "std" { compiler.stage } else { compiler.stage + 1 })) + } } pub struct RunConfig<'a> { diff --git a/src/bootstrap/src/core/builder/tests.rs b/src/bootstrap/src/core/builder/tests.rs index 8adf93ea528..1c5267cb75e 100644 --- a/src/bootstrap/src/core/builder/tests.rs +++ b/src/bootstrap/src/core/builder/tests.rs @@ -863,7 +863,7 @@ mod snapshot { insta::assert_snapshot!( ctx.config("build") .path("opt-dist") - .render_steps(), @"[build] rustc 0 <host> -> OptimizedDist <host>"); + .render_steps(), @"[build] rustc 0 <host> -> OptimizedDist 1 <host>"); } #[test] @@ -880,7 +880,7 @@ mod snapshot { ctx.config("build") .path("opt-dist") .stage(1) - .render_steps(), @"[build] rustc 0 <host> -> OptimizedDist <host>"); + .render_steps(), @"[build] rustc 0 <host> -> OptimizedDist 1 <host>"); } #[test] @@ -890,7 +890,7 @@ mod snapshot { ctx.config("build") .path("opt-dist") .stage(2) - .render_steps(), @"[build] rustc 0 <host> -> OptimizedDist <host>"); + .render_steps(), @"[build] rustc 0 <host> -> OptimizedDist 1 <host>"); } #[test] @@ -984,8 +984,8 @@ mod snapshot { ctx .config("dist") .render_steps(), @r" - [build] rustc 0 <host> -> UnstableBookGen <host> - [build] rustc 0 <host> -> Rustbook <host> + [build] rustc 0 <host> -> UnstableBookGen 1 <host> + [build] rustc 0 <host> -> Rustbook 1 <host> [build] llvm <host> [build] rustc 0 <host> -> rustc 1 <host> [build] rustc 1 <host> -> std 1 <host> @@ -993,14 +993,14 @@ mod snapshot { [build] rustdoc 1 <host> [doc] std 2 <host> [build] rustc 2 <host> -> std 2 <host> - [build] rustc 0 <host> -> LintDocs <host> - [build] rustc 0 <host> -> RustInstaller <host> + [build] rustc 0 <host> -> LintDocs 1 <host> + [build] rustc 0 <host> -> RustInstaller 1 <host> [dist] docs <host> [doc] std 2 <host> [dist] mingw <host> - [build] rustc 0 <host> -> GenerateCopyright <host> + [build] rustc 0 <host> -> GenerateCopyright 1 <host> [dist] rustc <host> - [dist] rustc 1 <host> -> std <host> + [dist] rustc 1 <host> -> std 1 <host> [dist] src <> " ); @@ -1014,25 +1014,25 @@ mod snapshot { .config("dist") .args(&["--set", "build.extended=true"]) .render_steps(), @r" - [build] rustc 0 <host> -> UnstableBookGen <host> - [build] rustc 0 <host> -> Rustbook <host> + [build] rustc 0 <host> -> UnstableBookGen 1 <host> + [build] rustc 0 <host> -> Rustbook 1 <host> [build] llvm <host> [build] rustc 0 <host> -> rustc 1 <host> - [build] rustc 0 <host> -> WasmComponentLd <host> + [build] rustc 0 <host> -> WasmComponentLd 1 <host> [build] rustc 1 <host> -> std 1 <host> [build] rustc 1 <host> -> rustc 2 <host> - [build] rustc 1 <host> -> WasmComponentLd <host> + [build] rustc 1 <host> -> WasmComponentLd 2 <host> [build] rustdoc 1 <host> [doc] std 2 <host> [build] rustc 2 <host> -> std 2 <host> - [build] rustc 0 <host> -> LintDocs <host> - [build] rustc 0 <host> -> RustInstaller <host> + [build] rustc 0 <host> -> LintDocs 1 <host> + [build] rustc 0 <host> -> RustInstaller 1 <host> [dist] docs <host> [doc] std 2 <host> [dist] mingw <host> - [build] rustc 0 <host> -> GenerateCopyright <host> + [build] rustc 0 <host> -> GenerateCopyright 1 <host> [dist] rustc <host> - [dist] rustc 1 <host> -> std <host> + [dist] rustc 1 <host> -> std 1 <host> [dist] src <> [build] rustc 0 <host> -> rustfmt 1 <host> [build] rustc 0 <host> -> cargo-fmt 1 <host> @@ -1052,8 +1052,8 @@ mod snapshot { .hosts(&[&host_target()]) .targets(&[&host_target(), TEST_TRIPLE_1]) .render_steps(), @r" - [build] rustc 0 <host> -> UnstableBookGen <host> - [build] rustc 0 <host> -> Rustbook <host> + [build] rustc 0 <host> -> UnstableBookGen 1 <host> + [build] rustc 0 <host> -> Rustbook 1 <host> [build] llvm <host> [build] rustc 0 <host> -> rustc 1 <host> [build] rustc 1 <host> -> std 1 <host> @@ -1062,19 +1062,19 @@ mod snapshot { [doc] std 2 <host> [doc] std 2 <target1> [build] rustc 2 <host> -> std 2 <host> - [build] rustc 0 <host> -> LintDocs <host> - [build] rustc 0 <host> -> RustInstaller <host> + [build] rustc 0 <host> -> LintDocs 1 <host> + [build] rustc 0 <host> -> RustInstaller 1 <host> [dist] docs <host> [dist] docs <target1> [doc] std 2 <host> [doc] std 2 <target1> [dist] mingw <host> [dist] mingw <target1> - [build] rustc 0 <host> -> GenerateCopyright <host> + [build] rustc 0 <host> -> GenerateCopyright 1 <host> [dist] rustc <host> - [dist] rustc 1 <host> -> std <host> + [dist] rustc 1 <host> -> std 1 <host> [build] rustc 2 <host> -> std 2 <target1> - [dist] rustc 2 <host> -> std <target1> + [dist] rustc 2 <host> -> std 2 <target1> [dist] src <> " ); @@ -1089,8 +1089,8 @@ mod snapshot { .hosts(&[&host_target(), TEST_TRIPLE_1]) .targets(&[&host_target()]) .render_steps(), @r" - [build] rustc 0 <host> -> UnstableBookGen <host> - [build] rustc 0 <host> -> Rustbook <host> + [build] rustc 0 <host> -> UnstableBookGen 1 <host> + [build] rustc 0 <host> -> Rustbook 1 <host> [build] llvm <host> [build] rustc 0 <host> -> rustc 1 <host> [build] rustc 1 <host> -> std 1 <host> @@ -1098,20 +1098,20 @@ mod snapshot { [build] rustdoc 1 <host> [doc] std 2 <host> [build] rustc 2 <host> -> std 2 <host> - [build] rustc 0 <host> -> LintDocs <host> + [build] rustc 0 <host> -> LintDocs 1 <host> [build] rustc 1 <host> -> std 1 <target1> [build] rustc 2 <host> -> std 2 <target1> - [build] rustc 0 <host> -> RustInstaller <host> + [build] rustc 0 <host> -> RustInstaller 1 <host> [dist] docs <host> [doc] std 2 <host> [dist] mingw <host> - [build] rustc 0 <host> -> GenerateCopyright <host> + [build] rustc 0 <host> -> GenerateCopyright 1 <host> [dist] rustc <host> [build] llvm <target1> [build] rustc 1 <host> -> rustc 2 <target1> [build] rustdoc 1 <target1> [dist] rustc <target1> - [dist] rustc 1 <host> -> std <host> + [dist] rustc 1 <host> -> std 1 <host> [dist] src <> " ); @@ -1126,8 +1126,8 @@ mod snapshot { .hosts(&[&host_target(), TEST_TRIPLE_1]) .targets(&[&host_target(), TEST_TRIPLE_1]) .render_steps(), @r" - [build] rustc 0 <host> -> UnstableBookGen <host> - [build] rustc 0 <host> -> Rustbook <host> + [build] rustc 0 <host> -> UnstableBookGen 1 <host> + [build] rustc 0 <host> -> Rustbook 1 <host> [build] llvm <host> [build] rustc 0 <host> -> rustc 1 <host> [build] rustc 1 <host> -> std 1 <host> @@ -1136,24 +1136,24 @@ mod snapshot { [doc] std 2 <host> [doc] std 2 <target1> [build] rustc 2 <host> -> std 2 <host> - [build] rustc 0 <host> -> LintDocs <host> + [build] rustc 0 <host> -> LintDocs 1 <host> [build] rustc 1 <host> -> std 1 <target1> [build] rustc 2 <host> -> std 2 <target1> - [build] rustc 0 <host> -> RustInstaller <host> + [build] rustc 0 <host> -> RustInstaller 1 <host> [dist] docs <host> [dist] docs <target1> [doc] std 2 <host> [doc] std 2 <target1> [dist] mingw <host> [dist] mingw <target1> - [build] rustc 0 <host> -> GenerateCopyright <host> + [build] rustc 0 <host> -> GenerateCopyright 1 <host> [dist] rustc <host> [build] llvm <target1> [build] rustc 1 <host> -> rustc 2 <target1> [build] rustdoc 1 <target1> [dist] rustc <target1> - [dist] rustc 1 <host> -> std <host> - [dist] rustc 1 <host> -> std <target1> + [dist] rustc 1 <host> -> std 1 <host> + [dist] rustc 1 <host> -> std 1 <target1> [dist] src <> " ); @@ -1168,8 +1168,8 @@ mod snapshot { .hosts(&[]) .targets(&[TEST_TRIPLE_1]) .render_steps(), @r" - [build] rustc 0 <host> -> UnstableBookGen <host> - [build] rustc 0 <host> -> Rustbook <host> + [build] rustc 0 <host> -> UnstableBookGen 1 <host> + [build] rustc 0 <host> -> Rustbook 1 <host> [build] llvm <host> [build] rustc 0 <host> -> rustc 1 <host> [build] rustc 1 <host> -> std 1 <host> @@ -1177,12 +1177,12 @@ mod snapshot { [build] rustdoc 1 <host> [doc] std 2 <target1> [build] rustc 2 <host> -> std 2 <host> - [build] rustc 0 <host> -> RustInstaller <host> + [build] rustc 0 <host> -> RustInstaller 1 <host> [dist] docs <target1> [doc] std 2 <target1> [dist] mingw <target1> [build] rustc 2 <host> -> std 2 <target1> - [dist] rustc 2 <host> -> std <target1> + [dist] rustc 2 <host> -> std 2 <target1> "); } @@ -1198,31 +1198,31 @@ mod snapshot { .targets(&[TEST_TRIPLE_1]) .args(&["--set", "rust.channel=nightly", "--set", "build.extended=true"]) .render_steps(), @r" - [build] rustc 0 <host> -> UnstableBookGen <host> - [build] rustc 0 <host> -> Rustbook <host> + [build] rustc 0 <host> -> UnstableBookGen 1 <host> + [build] rustc 0 <host> -> Rustbook 1 <host> [build] llvm <host> [build] rustc 0 <host> -> rustc 1 <host> - [build] rustc 0 <host> -> WasmComponentLd <host> + [build] rustc 0 <host> -> WasmComponentLd 1 <host> [build] rustc 1 <host> -> std 1 <host> [build] rustc 1 <host> -> rustc 2 <host> - [build] rustc 1 <host> -> WasmComponentLd <host> + [build] rustc 1 <host> -> WasmComponentLd 2 <host> [build] rustdoc 1 <host> [doc] std 2 <target1> [build] rustc 2 <host> -> std 2 <host> [build] rustc 1 <host> -> std 1 <target1> [build] rustc 2 <host> -> std 2 <target1> - [build] rustc 0 <host> -> LintDocs <host> - [build] rustc 0 <host> -> RustInstaller <host> + [build] rustc 0 <host> -> LintDocs 1 <host> + [build] rustc 0 <host> -> RustInstaller 1 <host> [dist] docs <target1> [doc] std 2 <target1> [dist] mingw <target1> [build] llvm <target1> [build] rustc 1 <host> -> rustc 2 <target1> - [build] rustc 1 <host> -> WasmComponentLd <target1> + [build] rustc 1 <host> -> WasmComponentLd 2 <target1> [build] rustdoc 1 <target1> - [build] rustc 0 <host> -> GenerateCopyright <host> + [build] rustc 0 <host> -> GenerateCopyright 1 <host> [dist] rustc <target1> - [dist] rustc 1 <host> -> std <target1> + [dist] rustc 1 <host> -> std 1 <target1> [dist] src <> [build] rustc 0 <host> -> rustfmt 1 <target1> [build] rustc 0 <host> -> cargo-fmt 1 <target1> @@ -1234,6 +1234,289 @@ mod snapshot { } #[test] + fn check_compiler_no_explicit_stage() { + let ctx = TestCtx::new(); + insta::assert_snapshot!( + ctx.config("check") + .path("compiler") + .render_steps(), @r" + [check] std <host> + [build] llvm <host> + [check] rustc <host> + [check] cranelift <host> + [check] gcc <host> + "); + + insta::assert_snapshot!( + ctx.config("check") + .path("rustc") + .render_steps(), @r" + [check] std <host> + [build] llvm <host> + [check] rustc <host> + "); + } + + #[test] + fn check_compiler_stage_0() { + let ctx = TestCtx::new(); + ctx.config("check").path("compiler").stage(0).run(); + } + + #[test] + fn check_compiler_stage_1() { + let ctx = TestCtx::new(); + insta::assert_snapshot!( + ctx.config("check") + .path("compiler") + .stage(1) + .render_steps(), @r" + [build] llvm <host> + [build] rustc 0 <host> -> rustc 1 <host> + [build] rustc 1 <host> -> std 1 <host> + [check] rustc <host> + [check] cranelift <host> + [check] gcc <host> + "); + } + + #[test] + fn check_compiler_stage_2() { + let ctx = TestCtx::new(); + insta::assert_snapshot!( + ctx.config("check") + .path("compiler") + .stage(2) + .render_steps(), @r" + [build] llvm <host> + [build] rustc 0 <host> -> rustc 1 <host> + [build] rustc 1 <host> -> std 1 <host> + [build] rustc 1 <host> -> rustc 2 <host> + [build] rustc 2 <host> -> std 2 <host> + [check] rustc <host> + [check] cranelift <host> + [check] gcc <host> + "); + } + + #[test] + fn check_cross_compile() { + let ctx = TestCtx::new(); + insta::assert_snapshot!( + ctx.config("check") + .stage(2) + .targets(&[TEST_TRIPLE_1]) + .hosts(&[TEST_TRIPLE_1]) + .render_steps(), @r" + [build] llvm <host> + [build] rustc 0 <host> -> rustc 1 <host> + [build] rustc 1 <host> -> std 1 <host> + [build] rustc 1 <host> -> rustc 2 <host> + [build] rustc 2 <host> -> std 2 <host> + [build] rustc 1 <host> -> std 1 <target1> + [build] rustc 2 <host> -> std 2 <target1> + [check] rustc <target1> + [check] Rustdoc <target1> + [check] cranelift <target1> + [check] gcc <target1> + [check] Clippy <target1> + [check] Miri <target1> + [check] CargoMiri <target1> + [check] MiroptTestTools <target1> + [check] Rustfmt <target1> + [check] rust-analyzer <target1> + [check] TestFloatParse <target1> + [check] FeaturesStatusDump <target1> + [check] std <target1> + "); + } + + #[test] + fn check_library_no_explicit_stage() { + let ctx = TestCtx::new(); + insta::assert_snapshot!( + ctx.config("check") + .path("library") + .render_steps(), @r" + [build] llvm <host> + [build] rustc 0 <host> -> rustc 1 <host> + [check] std <host> + "); + } + + #[test] + fn check_library_stage_0() { + let ctx = TestCtx::new(); + ctx.config("check").path("library").stage(0).run(); + } + + #[test] + fn check_library_stage_1() { + let ctx = TestCtx::new(); + insta::assert_snapshot!( + ctx.config("check") + .path("library") + .stage(1) + .render_steps(), @r" + [build] llvm <host> + [build] rustc 0 <host> -> rustc 1 <host> + [check] std <host> + "); + } + + #[test] + fn check_library_stage_2() { + let ctx = TestCtx::new(); + insta::assert_snapshot!( + ctx.config("check") + .path("library") + .stage(2) + .render_steps(), @r" + [build] llvm <host> + [build] rustc 0 <host> -> rustc 1 <host> + [build] rustc 1 <host> -> std 1 <host> + [build] rustc 1 <host> -> rustc 2 <host> + [check] std <host> + "); + } + + #[test] + fn check_library_cross_compile() { + let ctx = TestCtx::new(); + insta::assert_snapshot!( + ctx.config("check") + .paths(&["core", "alloc", "std"]) + .targets(&[TEST_TRIPLE_1, TEST_TRIPLE_2]) + .render_steps(), @r" + [build] llvm <host> + [build] rustc 0 <host> -> rustc 1 <host> + [check] std <target1> + [check] std <target2> + "); + } + + #[test] + fn check_miri_no_explicit_stage() { + let ctx = TestCtx::new(); + insta::assert_snapshot!( + ctx.config("check") + .path("miri") + .render_steps(), @r" + [check] std <host> + [build] llvm <host> + [check] rustc <host> + [check] Miri <host> + "); + } + + #[test] + fn check_miri_stage_0() { + let ctx = TestCtx::new(); + ctx.config("check").path("miri").stage(0).run(); + } + + #[test] + fn check_miri_stage_1() { + let ctx = TestCtx::new(); + insta::assert_snapshot!( + ctx.config("check") + .path("miri") + .stage(1) + .render_steps(), @r" + [build] llvm <host> + [build] rustc 0 <host> -> rustc 1 <host> + [build] rustc 1 <host> -> std 1 <host> + [check] rustc <host> + [check] Miri <host> + "); + } + + #[test] + fn check_miri_stage_2() { + let ctx = TestCtx::new(); + insta::assert_snapshot!( + ctx.config("check") + .path("miri") + .stage(2) + .render_steps(), @r" + [build] llvm <host> + [build] rustc 0 <host> -> rustc 1 <host> + [build] rustc 1 <host> -> std 1 <host> + [build] rustc 1 <host> -> rustc 2 <host> + [build] rustc 2 <host> -> std 2 <host> + [check] rustc <host> + [check] Miri <host> + "); + } + + #[test] + fn check_compiletest() { + let ctx = TestCtx::new(); + insta::assert_snapshot!( + ctx.config("check") + .path("compiletest") + .render_steps(), @"[check] compiletest <host>"); + } + + #[test] + fn check_compiletest_stage1_libtest() { + let ctx = TestCtx::new(); + insta::assert_snapshot!( + ctx.config("check") + .path("compiletest") + .args(&["--set", "build.compiletest-use-stage0-libtest=false"]) + .render_steps(), @r" + [check] std <host> + [build] llvm <host> + [check] rustc <host> + [check] compiletest <host> + "); + } + + #[test] + fn check_codegen() { + let ctx = TestCtx::new(); + insta::assert_snapshot!( + ctx.config("check") + .path("rustc_codegen_cranelift") + .render_steps(), @r" + [check] std <host> + [build] llvm <host> + [check] rustc <host> + [check] cranelift <host> + [check] gcc <host> + "); + } + + #[test] + fn check_rust_analyzer() { + let ctx = TestCtx::new(); + insta::assert_snapshot!( + ctx.config("check") + .path("rust-analyzer") + .render_steps(), @r" + [check] std <host> + [build] llvm <host> + [check] rustc <host> + [check] rust-analyzer <host> + "); + } + + #[test] + fn check_bootstrap_tool() { + let ctx = TestCtx::new(); + insta::assert_snapshot!( + ctx.config("check") + .path("run-make-support") + .render_steps(), @r" + [check] std <host> + [build] llvm <host> + [check] rustc <host> + [check] RunMakeSupport <host> + "); + } + + #[test] fn test_exclude() { let ctx = TestCtx::new(); let steps = ctx.config("test").args(&["--skip", "src/tools/tidy"]).get_steps(); @@ -1384,7 +1667,7 @@ fn render_metadata(metadata: &StepMetadata) -> String { if let Some(compiler) = metadata.built_by { write!(record, "{} -> ", render_compiler(compiler)); } - let stage = if let Some(stage) = metadata.stage { format!("{stage} ") } else { "".to_string() }; + let stage = metadata.get_stage().map(|stage| format!("{stage} ")).unwrap_or_default(); write!(record, "{} {stage}<{}>", metadata.name, normalize_target(metadata.target)); record } diff --git a/src/bootstrap/src/core/config/config.rs b/src/bootstrap/src/core/config/config.rs index 0cdfbbdaf75..49b3fec4c35 100644 --- a/src/bootstrap/src/core/config/config.rs +++ b/src/bootstrap/src/core/config/config.rs @@ -297,7 +297,8 @@ pub struct Config { /// Whether to use the precompiled stage0 libtest with compiletest. pub compiletest_use_stage0_libtest: bool, - + /// Default value for `--extra-checks` + pub tidy_extra_checks: Option<String>, pub is_running_on_ci: bool, /// Cache for determining path modifications @@ -744,6 +745,7 @@ impl Config { jobs, compiletest_diff_tool, compiletest_use_stage0_libtest, + tidy_extra_checks, mut ccache, exclude, } = toml.build.unwrap_or_default(); @@ -1010,6 +1012,7 @@ impl Config { optimized_compiler_builtins.unwrap_or(config.channel != "dev"); config.compiletest_diff_tool = compiletest_diff_tool; config.compiletest_use_stage0_libtest = compiletest_use_stage0_libtest.unwrap_or(true); + config.tidy_extra_checks = tidy_extra_checks; let download_rustc = config.download_rustc_commit.is_some(); config.explicit_stage_from_cli = flags_stage.is_some(); diff --git a/src/bootstrap/src/core/config/flags.rs b/src/bootstrap/src/core/config/flags.rs index bb21d033458..79275db6486 100644 --- a/src/bootstrap/src/core/config/flags.rs +++ b/src/bootstrap/src/core/config/flags.rs @@ -382,7 +382,7 @@ pub enum Subcommand { bless: bool, #[arg(long)] /// comma-separated list of other files types to check (accepts py, py:lint, - /// py:fmt, shell) + /// py:fmt, shell, shell:lint, cpp, cpp:fmt, spellcheck, spellcheck:fix) extra_checks: Option<String>, #[arg(long)] /// rerun tests even if the inputs are unchanged diff --git a/src/bootstrap/src/core/config/toml/build.rs b/src/bootstrap/src/core/config/toml/build.rs index 98e1194de72..4d29691f38b 100644 --- a/src/bootstrap/src/core/config/toml/build.rs +++ b/src/bootstrap/src/core/config/toml/build.rs @@ -69,6 +69,7 @@ define_config! { jobs: Option<u32> = "jobs", compiletest_diff_tool: Option<String> = "compiletest-diff-tool", compiletest_use_stage0_libtest: Option<bool> = "compiletest-use-stage0-libtest", + tidy_extra_checks: Option<String> = "tidy-extra-checks", ccache: Option<StringOrBool> = "ccache", exclude: Option<Vec<PathBuf>> = "exclude", } diff --git a/src/bootstrap/src/core/config/toml/rust.rs b/src/bootstrap/src/core/config/toml/rust.rs index 642f2f2271d..ac5eaea3bcb 100644 --- a/src/bootstrap/src/core/config/toml/rust.rs +++ b/src/bootstrap/src/core/config/toml/rust.rs @@ -393,6 +393,27 @@ pub fn check_incompatible_options_for_ci_rustc( Ok(()) } +pub(crate) const VALID_CODEGEN_BACKENDS: &[&str] = &["llvm", "cranelift", "gcc"]; + +pub(crate) fn validate_codegen_backends(backends: Vec<String>, section: &str) -> Vec<String> { + for backend in &backends { + if let Some(stripped) = backend.strip_prefix(CODEGEN_BACKEND_PREFIX) { + panic!( + "Invalid value '{backend}' for '{section}.codegen-backends'. \ + Codegen backends are defined without the '{CODEGEN_BACKEND_PREFIX}' prefix. \ + Please, use '{stripped}' instead." + ) + } + if !VALID_CODEGEN_BACKENDS.contains(&backend.as_str()) { + println!( + "HELP: '{backend}' for '{section}.codegen-backends' might fail. \ + List of known good values: {VALID_CODEGEN_BACKENDS:?}" + ); + } + } + backends +} + impl Config { pub fn apply_rust_config( &mut self, @@ -571,24 +592,10 @@ impl Config { set(&mut self.ehcont_guard, ehcont_guard); self.llvm_libunwind_default = llvm_libunwind.map(|v| v.parse().expect("failed to parse rust.llvm-libunwind")); - - if let Some(ref backends) = codegen_backends { - let available_backends = ["llvm", "cranelift", "gcc"]; - - self.rust_codegen_backends = backends.iter().map(|s| { - if let Some(backend) = s.strip_prefix(CODEGEN_BACKEND_PREFIX) { - if available_backends.contains(&backend) { - panic!("Invalid value '{s}' for 'rust.codegen-backends'. Instead, please use '{backend}'."); - } else { - println!("HELP: '{s}' for 'rust.codegen-backends' might fail. \ - Codegen backends are mostly defined without the '{CODEGEN_BACKEND_PREFIX}' prefix. \ - In this case, it would be referred to as '{backend}'."); - } - } - - s.clone() - }).collect(); - } + set( + &mut self.rust_codegen_backends, + codegen_backends.map(|backends| validate_codegen_backends(backends, "rust")), + ); self.rust_codegen_units = codegen_units.map(threads_from_config); self.rust_codegen_units_std = codegen_units_std.map(threads_from_config); diff --git a/src/bootstrap/src/core/config/toml/target.rs b/src/bootstrap/src/core/config/toml/target.rs index b9f6780ca3f..337276948b3 100644 --- a/src/bootstrap/src/core/config/toml/target.rs +++ b/src/bootstrap/src/core/config/toml/target.rs @@ -16,7 +16,7 @@ use std::collections::HashMap; use serde::{Deserialize, Deserializer}; -use crate::core::build_steps::compile::CODEGEN_BACKEND_PREFIX; +use crate::core::config::toml::rust::validate_codegen_backends; use crate::core::config::{LlvmLibunwind, Merge, ReplaceOpt, SplitDebuginfo, StringOrBool}; use crate::{Config, HashSet, PathBuf, TargetSelection, define_config, exit}; @@ -142,23 +142,9 @@ impl Config { target.rpath = cfg.rpath; target.optimized_compiler_builtins = cfg.optimized_compiler_builtins; target.jemalloc = cfg.jemalloc; - - if let Some(ref backends) = cfg.codegen_backends { - let available_backends = ["llvm", "cranelift", "gcc"]; - - target.codegen_backends = Some(backends.iter().map(|s| { - if let Some(backend) = s.strip_prefix(CODEGEN_BACKEND_PREFIX) { - if available_backends.contains(&backend) { - panic!("Invalid value '{s}' for 'target.{triple}.codegen-backends'. Instead, please use '{backend}'."); - } else { - println!("HELP: '{s}' for 'target.{triple}.codegen-backends' might fail. \ - Codegen backends are mostly defined without the '{CODEGEN_BACKEND_PREFIX}' prefix. \ - In this case, it would be referred to as '{backend}'."); - } - } - - s.clone() - }).collect()); + if let Some(backends) = cfg.codegen_backends { + target.codegen_backends = + Some(validate_codegen_backends(backends, &format!("target.{triple}"))) } target.split_debuginfo = cfg.split_debuginfo.as_ref().map(|v| { diff --git a/src/bootstrap/src/utils/cache/tests.rs b/src/bootstrap/src/utils/cache/tests.rs index 8562a35b3e0..fd0a7cccd60 100644 --- a/src/bootstrap/src/utils/cache/tests.rs +++ b/src/bootstrap/src/utils/cache/tests.rs @@ -1,12 +1,13 @@ use std::path::PathBuf; -use crate::utils::cache::{INTERNER, Internable, TyIntern}; +use crate::utils::cache::{INTERNER, Internable, Interner, TyIntern}; #[test] fn test_string_interning() { - let s1 = INTERNER.intern_str("Hello"); - let s2 = INTERNER.intern_str("Hello"); - let s3 = INTERNER.intern_str("world"); + let interner = Interner::default(); + let s1 = interner.intern_str("Hello"); + let s2 = interner.intern_str("Hello"); + let s3 = interner.intern_str("world"); assert_eq!(s1, s2, "Same strings should be interned to the same instance"); assert_ne!(s1, s3, "Different strings should have different interned values"); @@ -14,6 +15,8 @@ fn test_string_interning() { #[test] fn test_interned_equality() { + // Because we compare with &str, and the Deref impl accesses the global + // INTERNER variable, we cannot use a local Interner variable here. let s1 = INTERNER.intern_str("test"); let s2 = INTERNER.intern_str("test"); diff --git a/src/bootstrap/src/utils/change_tracker.rs b/src/bootstrap/src/utils/change_tracker.rs index f873c62588b..68312a503ee 100644 --- a/src/bootstrap/src/utils/change_tracker.rs +++ b/src/bootstrap/src/utils/change_tracker.rs @@ -149,7 +149,7 @@ pub const CONFIG_CHANGE_HISTORY: &[ChangeInfo] = &[ ChangeInfo { change_id: 121976, severity: ChangeSeverity::Info, - summary: "A new `boostrap-cache-path` option has been introduced which can be utilized to modify the cache path for bootstrap.", + summary: "A new `bootstrap-cache-path` option has been introduced which can be utilized to modify the cache path for bootstrap.", }, ChangeInfo { change_id: 122108, @@ -404,7 +404,7 @@ pub const CONFIG_CHANGE_HISTORY: &[ChangeInfo] = &[ ChangeInfo { change_id: 140438, severity: ChangeSeverity::Info, - summary: "Added a new option `rust.debug-assertions-tools` to control debug asssertions for tools.", + summary: "Added a new option `rust.debug-assertions-tools` to control debug assertions for tools.", }, ChangeInfo { change_id: 140732, @@ -441,4 +441,9 @@ pub const CONFIG_CHANGE_HISTORY: &[ChangeInfo] = &[ severity: ChangeSeverity::Warning, summary: "`llvm.lld` is no longer enabled by default for the dist profile.", }, + ChangeInfo { + change_id: 143251, + severity: ChangeSeverity::Info, + summary: "Added new option `build.tidy-extra-checks` to specify a default value for the --extra-checks cli flag.", + }, ]; diff --git a/src/bootstrap/src/utils/proc_macro_deps.rs b/src/bootstrap/src/utils/proc_macro_deps.rs index b61fa3bb8d6..21c7fc89d7d 100644 --- a/src/bootstrap/src/utils/proc_macro_deps.rs +++ b/src/bootstrap/src/utils/proc_macro_deps.rs @@ -30,7 +30,6 @@ pub static CRATES: &[&str] = &[ "memchr", "minimal-lexical", "nom", - "once_cell", "pest", "pest_generator", "pest_meta", diff --git a/src/ci/citool/src/jobs.rs b/src/ci/citool/src/jobs.rs index 81e002edb15..410274227e4 100644 --- a/src/ci/citool/src/jobs.rs +++ b/src/ci/citool/src/jobs.rs @@ -13,7 +13,7 @@ use crate::utils::load_env_var; #[derive(serde::Deserialize, Debug, Clone)] #[serde(deny_unknown_fields)] pub struct Job { - /// Name of the job, e.g. mingw-check-1 + /// Name of the job, e.g. pr-check-1 pub name: String, /// GitHub runner on which the job should be executed pub os: String, @@ -66,6 +66,8 @@ pub struct JobDatabase { pub try_jobs: Vec<Job>, #[serde(rename = "auto")] pub auto_jobs: Vec<Job>, + #[serde(rename = "optional")] + pub optional_jobs: Vec<Job>, /// Shared environments for the individual run types. envs: JobEnvironments, @@ -75,9 +77,10 @@ impl JobDatabase { /// Find `auto` jobs that correspond to the passed `pattern`. /// Patterns are matched using the glob syntax. /// For example `dist-*` matches all jobs starting with `dist-`. - fn find_auto_jobs_by_pattern(&self, pattern: &str) -> Vec<Job> { + fn find_auto_or_optional_jobs_by_pattern(&self, pattern: &str) -> Vec<Job> { self.auto_jobs .iter() + .chain(self.optional_jobs.iter()) .filter(|j| glob_match::glob_match(pattern, &j.name)) .cloned() .collect() @@ -181,7 +184,7 @@ fn calculate_jobs( let mut jobs: Vec<Job> = vec![]; let mut unknown_patterns = vec![]; for pattern in patterns { - let matched_jobs = db.find_auto_jobs_by_pattern(pattern); + let matched_jobs = db.find_auto_or_optional_jobs_by_pattern(pattern); if matched_jobs.is_empty() { unknown_patterns.push(pattern.clone()); } else { diff --git a/src/ci/citool/src/jobs/tests.rs b/src/ci/citool/src/jobs/tests.rs index ed5444d4333..63ac508b632 100644 --- a/src/ci/citool/src/jobs/tests.rs +++ b/src/ci/citool/src/jobs/tests.rs @@ -46,6 +46,13 @@ auto: - name: test-msvc-i686-2 os: ubuntu env: {} +optional: + - name: optional-job-1 + os: ubuntu + env: {} + - name: optional-dist-x86_64 + os: ubuntu + env: {} "#, ) .unwrap(); @@ -57,12 +64,18 @@ auto: "*i686*", &["test-i686", "dist-i686", "test-msvc-i686-1", "test-msvc-i686-2"], ); + // Test that optional jobs are found + check_pattern(&db, "optional-*", &["optional-job-1", "optional-dist-x86_64"]); + check_pattern(&db, "*optional*", &["optional-job-1", "optional-dist-x86_64"]); } #[track_caller] fn check_pattern(db: &JobDatabase, pattern: &str, expected: &[&str]) { - let jobs = - db.find_auto_jobs_by_pattern(pattern).into_iter().map(|j| j.name).collect::<Vec<_>>(); + let jobs = db + .find_auto_or_optional_jobs_by_pattern(pattern) + .into_iter() + .map(|j| j.name) + .collect::<Vec<_>>(); assert_eq!(jobs, expected); } @@ -116,8 +129,13 @@ fn validate_jobs() { load_job_db(&db_str).expect("Failed to load job database") }; - let all_jobs = - db.pr_jobs.iter().chain(db.try_jobs.iter()).chain(db.auto_jobs.iter()).collect::<Vec<_>>(); + let all_jobs = db + .pr_jobs + .iter() + .chain(db.try_jobs.iter()) + .chain(db.auto_jobs.iter()) + .chain(db.optional_jobs.iter()) + .collect::<Vec<_>>(); let errors: Vec<anyhow::Error> = all_jobs.into_iter().filter_map(|job| validate_codebuild_image(job).err()).collect(); diff --git a/src/ci/citool/tests/jobs.rs b/src/ci/citool/tests/jobs.rs index 83f2fc0ed1f..dbaf13d4f42 100644 --- a/src/ci/citool/tests/jobs.rs +++ b/src/ci/citool/tests/jobs.rs @@ -40,7 +40,7 @@ try-job: dist-i686-msvc"#, fn pr_jobs() { let stdout = get_matrix("pull_request", "commit", "refs/heads/pr/1234"); insta::assert_snapshot!(stdout, @r#" - jobs=[{"name":"mingw-check-1","full_name":"PR - mingw-check-1","os":"ubuntu-24.04","env":{"PR_CI_JOB":1},"free_disk":true},{"name":"mingw-check-2","full_name":"PR - mingw-check-2","os":"ubuntu-24.04","env":{"PR_CI_JOB":1},"free_disk":true},{"name":"mingw-check-tidy","full_name":"PR - mingw-check-tidy","os":"ubuntu-24.04","env":{"PR_CI_JOB":1},"continue_on_error":true,"free_disk":true,"doc_url":"https://foo.bar"}] + jobs=[{"name":"pr-check-1","full_name":"PR - pr-check-1","os":"ubuntu-24.04","env":{"PR_CI_JOB":1},"free_disk":true},{"name":"pr-check-2","full_name":"PR - pr-check-2","os":"ubuntu-24.04","env":{"PR_CI_JOB":1},"free_disk":true},{"name":"tidy","full_name":"PR - tidy","os":"ubuntu-24.04","env":{"PR_CI_JOB":1},"continue_on_error":true,"free_disk":true,"doc_url":"https://foo.bar"}] run_type=pr "#); } diff --git a/src/ci/citool/tests/test-jobs.yml b/src/ci/citool/tests/test-jobs.yml index d262da11102..d82b3e7648e 100644 --- a/src/ci/citool/tests/test-jobs.yml +++ b/src/ci/citool/tests/test-jobs.yml @@ -64,11 +64,11 @@ envs: # These jobs automatically inherit envs.pr, to avoid repeating # it in each job definition. pr: - - name: mingw-check-1 + - name: pr-check-1 <<: *job-linux-4c - - name: mingw-check-2 + - name: pr-check-2 <<: *job-linux-4c - - name: mingw-check-tidy + - name: tidy continue_on_error: true doc_url: https://foo.bar <<: *job-linux-4c @@ -139,3 +139,8 @@ auto: DIST_REQUIRE_ALL_TOOLS: 1 CODEGEN_BACKENDS: llvm,cranelift <<: *job-windows + +# Jobs that only run when explicitly invoked via `@bors try`. +optional: + - name: test-optional-job + <<: *job-linux-4c diff --git a/src/ci/docker/host-aarch64/aarch64-gnu/Dockerfile b/src/ci/docker/host-aarch64/aarch64-gnu/Dockerfile index d5027589e0b..e6133fce83e 100644 --- a/src/ci/docker/host-aarch64/aarch64-gnu/Dockerfile +++ b/src/ci/docker/host-aarch64/aarch64-gnu/Dockerfile @@ -26,6 +26,5 @@ ENV RUST_CONFIGURE_ARGS \ --enable-sanitizers \ --enable-profiler \ --enable-compiler-docs -# FIXME: Skipping cargo panic_abort_doc_tests due to https://github.com/rust-lang/rust/issues/123733 ENV SCRIPT python3 ../x.py --stage 2 test && \ - python3 ../x.py --stage 2 test src/tools/cargo --test-args \"--skip panic_abort_doc_tests\" + python3 ../x.py --stage 2 test src/tools/cargo diff --git a/src/ci/docker/host-x86_64/mingw-check-1/Dockerfile b/src/ci/docker/host-x86_64/mingw-check-1/Dockerfile deleted file mode 100644 index c46a2471e75..00000000000 --- a/src/ci/docker/host-x86_64/mingw-check-1/Dockerfile +++ /dev/null @@ -1,58 +0,0 @@ -FROM ubuntu:22.04 - -ARG DEBIAN_FRONTEND=noninteractive -RUN apt-get update && apt-get install -y --no-install-recommends \ - g++ \ - make \ - ninja-build \ - file \ - curl \ - ca-certificates \ - python3 \ - python3-pip \ - python3-pkg-resources \ - git \ - cmake \ - sudo \ - gdb \ - xz-utils \ - libssl-dev \ - pkg-config \ - mingw-w64 \ - && rm -rf /var/lib/apt/lists/* - -ENV RUST_CONFIGURE_ARGS="--set rust.validate-mir-opts=3" - -COPY scripts/nodejs.sh /scripts/ -RUN sh /scripts/nodejs.sh /node -ENV PATH="/node/bin:${PATH}" - -# Install es-check -# Pin its version to prevent unrelated CI failures due to future es-check versions. -RUN npm install es-check@6.1.1 eslint@8.6.0 typescript@5.7.3 -g - -COPY scripts/sccache.sh /scripts/ -RUN sh /scripts/sccache.sh - -COPY host-x86_64/mingw-check-1/reuse-requirements.txt /tmp/ -RUN pip3 install --no-deps --no-cache-dir --require-hashes -r /tmp/reuse-requirements.txt - -COPY host-x86_64/mingw-check-1/check-default-config-profiles.sh /scripts/ -COPY host-x86_64/mingw-check-1/validate-toolstate.sh /scripts/ - -# Check library crates on all tier 1 targets. -# We disable optimized compiler built-ins because that requires a C toolchain for the target. -# We also skip the x86_64-unknown-linux-gnu target as it is well-tested by other jobs. -ENV SCRIPT \ - /scripts/check-default-config-profiles.sh && \ - python3 ../x.py build --stage 1 src/tools/build-manifest && \ - python3 ../x.py test --stage 0 src/tools/compiletest && \ - python3 ../x.py check compiletest --set build.compiletest-use-stage0-libtest=true && \ - python3 ../x.py check --stage 1 --target=i686-pc-windows-gnu --host=i686-pc-windows-gnu && \ - python3 ../x.py check --stage 1 --set build.optimized-compiler-builtins=false core alloc std --target=aarch64-unknown-linux-gnu,i686-pc-windows-msvc,i686-unknown-linux-gnu,x86_64-apple-darwin,x86_64-pc-windows-gnu,x86_64-pc-windows-msvc && \ - /scripts/validate-toolstate.sh && \ - reuse --include-submodules lint && \ - python3 ../x.py test collect-license-metadata && \ - # Runs checks to ensure that there are no issues in our JS code. - es-check es2019 ../src/librustdoc/html/static/js/*.js && \ - tsc --project ../src/librustdoc/html/static/js/tsconfig.json diff --git a/src/ci/docker/host-x86_64/pr-check-1/Dockerfile b/src/ci/docker/host-x86_64/pr-check-1/Dockerfile new file mode 100644 index 00000000000..7a8056b70dc --- /dev/null +++ b/src/ci/docker/host-x86_64/pr-check-1/Dockerfile @@ -0,0 +1,58 @@ +FROM ubuntu:22.04 + +ARG DEBIAN_FRONTEND=noninteractive +RUN apt-get update && apt-get install -y --no-install-recommends \ + g++ \ + make \ + ninja-build \ + file \ + curl \ + ca-certificates \ + python3 \ + python3-pip \ + python3-pkg-resources \ + git \ + cmake \ + sudo \ + gdb \ + xz-utils \ + libssl-dev \ + pkg-config \ + mingw-w64 \ + && rm -rf /var/lib/apt/lists/* + +ENV RUST_CONFIGURE_ARGS="--set rust.validate-mir-opts=3" + +COPY scripts/nodejs.sh /scripts/ +RUN sh /scripts/nodejs.sh /node +ENV PATH="/node/bin:${PATH}" + +# Install es-check +# Pin its version to prevent unrelated CI failures due to future es-check versions. +RUN npm install es-check@6.1.1 eslint@8.6.0 typescript@5.7.3 -g + +COPY scripts/sccache.sh /scripts/ +RUN sh /scripts/sccache.sh + +COPY host-x86_64/pr-check-1/reuse-requirements.txt /tmp/ +RUN pip3 install --no-deps --no-cache-dir --require-hashes -r /tmp/reuse-requirements.txt + +COPY host-x86_64/pr-check-1/check-default-config-profiles.sh /scripts/ +COPY host-x86_64/pr-check-1/validate-toolstate.sh /scripts/ + +# Check library crates on all tier 1 targets. +# We disable optimized compiler built-ins because that requires a C toolchain for the target. +# We also skip the x86_64-unknown-linux-gnu target as it is well-tested by other jobs. +ENV SCRIPT \ + /scripts/check-default-config-profiles.sh && \ + python3 ../x.py build --stage 1 src/tools/build-manifest && \ + python3 ../x.py test --stage 0 src/tools/compiletest && \ + python3 ../x.py check compiletest --set build.compiletest-use-stage0-libtest=true && \ + python3 ../x.py check --stage 1 --target=i686-pc-windows-gnu --host=i686-pc-windows-gnu && \ + python3 ../x.py check --stage 1 --set build.optimized-compiler-builtins=false core alloc std --target=aarch64-unknown-linux-gnu,i686-pc-windows-msvc,i686-unknown-linux-gnu,x86_64-apple-darwin,x86_64-pc-windows-gnu,x86_64-pc-windows-msvc && \ + /scripts/validate-toolstate.sh && \ + reuse --include-submodules lint && \ + python3 ../x.py test collect-license-metadata && \ + # Runs checks to ensure that there are no issues in our JS code. + es-check es2019 ../src/librustdoc/html/static/js/*.js && \ + tsc --project ../src/librustdoc/html/static/js/tsconfig.json diff --git a/src/ci/docker/host-x86_64/mingw-check-1/check-default-config-profiles.sh b/src/ci/docker/host-x86_64/pr-check-1/check-default-config-profiles.sh index 0c85d4b449d..0c85d4b449d 100755 --- a/src/ci/docker/host-x86_64/mingw-check-1/check-default-config-profiles.sh +++ b/src/ci/docker/host-x86_64/pr-check-1/check-default-config-profiles.sh diff --git a/src/ci/docker/host-x86_64/mingw-check-1/reuse-requirements.in b/src/ci/docker/host-x86_64/pr-check-1/reuse-requirements.in index d7c2d3fde5b..d7c2d3fde5b 100644 --- a/src/ci/docker/host-x86_64/mingw-check-1/reuse-requirements.in +++ b/src/ci/docker/host-x86_64/pr-check-1/reuse-requirements.in diff --git a/src/ci/docker/host-x86_64/mingw-check-1/reuse-requirements.txt b/src/ci/docker/host-x86_64/pr-check-1/reuse-requirements.txt index 8784e18864b..8784e18864b 100644 --- a/src/ci/docker/host-x86_64/mingw-check-1/reuse-requirements.txt +++ b/src/ci/docker/host-x86_64/pr-check-1/reuse-requirements.txt diff --git a/src/ci/docker/host-x86_64/mingw-check-1/validate-toolstate.sh b/src/ci/docker/host-x86_64/pr-check-1/validate-toolstate.sh index a5691da8cda..a5691da8cda 100755 --- a/src/ci/docker/host-x86_64/mingw-check-1/validate-toolstate.sh +++ b/src/ci/docker/host-x86_64/pr-check-1/validate-toolstate.sh diff --git a/src/ci/docker/host-x86_64/mingw-check-2/Dockerfile b/src/ci/docker/host-x86_64/pr-check-2/Dockerfile index ce18a181d31..ce18a181d31 100644 --- a/src/ci/docker/host-x86_64/mingw-check-2/Dockerfile +++ b/src/ci/docker/host-x86_64/pr-check-2/Dockerfile diff --git a/src/ci/docker/host-x86_64/mingw-check-tidy/Dockerfile b/src/ci/docker/host-x86_64/tidy/Dockerfile index 62cd8a31212..dbb950cbe0c 100644 --- a/src/ci/docker/host-x86_64/mingw-check-tidy/Dockerfile +++ b/src/ci/docker/host-x86_64/tidy/Dockerfile @@ -1,5 +1,5 @@ # We use the ghcr base image because ghcr doesn't have a rate limit -# and the mingw-check-tidy job doesn't cache docker images in CI. +# and the tidy job doesn't cache docker images in CI. FROM ghcr.io/rust-lang/ubuntu:22.04 ARG DEBIAN_FRONTEND=noninteractive @@ -29,20 +29,20 @@ RUN sh /scripts/nodejs.sh /node ENV PATH="/node/bin:${PATH}" # Install eslint -COPY host-x86_64/mingw-check-tidy/eslint.version /tmp/ +COPY host-x86_64/tidy/eslint.version /tmp/ COPY scripts/sccache.sh /scripts/ RUN sh /scripts/sccache.sh -COPY host-x86_64/mingw-check-1/reuse-requirements.txt /tmp/ +COPY host-x86_64/pr-check-1/reuse-requirements.txt /tmp/ RUN pip3 install --no-deps --no-cache-dir --require-hashes -r /tmp/reuse-requirements.txt \ - && pip3 install virtualenv + && pip3 install virtualenv -COPY host-x86_64/mingw-check-1/validate-toolstate.sh /scripts/ +COPY host-x86_64/pr-check-1/validate-toolstate.sh /scripts/ RUN bash -c 'npm install -g eslint@$(cat /tmp/eslint.version)' # NOTE: intentionally uses python2 for x.py so we can test it still works. # validate-toolstate only runs in our CI, so it's ok for it to only support python3. ENV SCRIPT TIDY_PRINT_DIFF=1 python2.7 ../x.py test --stage 0 \ - src/tools/tidy tidyselftest --extra-checks=py,cpp + src/tools/tidy tidyselftest --extra-checks=py,cpp diff --git a/src/ci/docker/host-x86_64/mingw-check-tidy/eslint.version b/src/ci/docker/host-x86_64/tidy/eslint.version index 1acea15afd6..1acea15afd6 100644 --- a/src/ci/docker/host-x86_64/mingw-check-tidy/eslint.version +++ b/src/ci/docker/host-x86_64/tidy/eslint.version diff --git a/src/ci/docker/host-x86_64/x86_64-gnu-tools/browser-ui-test.version b/src/ci/docker/host-x86_64/x86_64-gnu-tools/browser-ui-test.version index f8d54d44557..b9f8e558df4 100644 --- a/src/ci/docker/host-x86_64/x86_64-gnu-tools/browser-ui-test.version +++ b/src/ci/docker/host-x86_64/x86_64-gnu-tools/browser-ui-test.version @@ -1 +1 @@ -0.20.7 \ No newline at end of file +0.21.1 \ No newline at end of file diff --git a/src/ci/github-actions/jobs.yml b/src/ci/github-actions/jobs.yml index 3aa435003d3..01993ad28aa 100644 --- a/src/ci/github-actions/jobs.yml +++ b/src/ci/github-actions/jobs.yml @@ -122,11 +122,11 @@ jobs: # These jobs automatically inherit envs.pr, to avoid repeating # it in each job definition. pr: - - name: mingw-check-1 + - name: pr-check-1 <<: *job-linux-4c - - name: mingw-check-2 + - name: pr-check-2 <<: *job-linux-4c - - name: mingw-check-tidy + - name: tidy continue_on_error: true free_disk: false env: @@ -160,6 +160,17 @@ pr: try: - <<: *job-dist-x86_64-linux +# Jobs that only run when explicitly invoked in one of the following ways: +# - comment `@bors2 try jobs=<job-name>` +# - `try-job: <job-name>` in the PR description and comment `@bors try` or `@bors2 try`. +optional: + # This job is used just to test optional jobs. + # It will be replaced by tier 2 and tier 3 jobs in the future. + - name: optional-mingw-check-1 + env: + IMAGE: mingw-check-1 + <<: *job-linux-4c + # Main CI jobs that have to be green to merge a commit into master # These jobs automatically inherit envs.auto, to avoid repeating # it in each job definition. @@ -312,13 +323,13 @@ auto: /scripts/stage_2_test_set2.sh <<: *job-linux-4c - - name: mingw-check-1 + - name: pr-check-1 <<: *job-linux-4c - - name: mingw-check-2 + - name: pr-check-2 <<: *job-linux-4c - - name: mingw-check-tidy + - name: tidy free_disk: false <<: *job-linux-4c diff --git a/src/doc/rustc-dev-guide/src/solve/opaque-types.md b/src/doc/rustc-dev-guide/src/solve/opaque-types.md index 6898ef3aa78..8880962d621 100644 --- a/src/doc/rustc-dev-guide/src/solve/opaque-types.md +++ b/src/doc/rustc-dev-guide/src/solve/opaque-types.md @@ -56,7 +56,7 @@ Finally, we check whether the item bounds of the opaque hold for the expected ty [source][item-bounds-ck]. [norm]: https://github.com/rust-lang/rust/blob/384d26fc7e3bdd7687cc17b2662b091f6017ec2a/compiler/rustc_trait_selection/src/solve/normalizes_to/opaque_types.rs#L13 -[coherence-example]: https://github.com/rust-lang/rust/blob/master/tests/ui/type-alias-impl-trait/coherence_different_hidden_ty.rs +[coherence-example]: https://github.com/rust-lang/rust/blob/master/tests/ui/type-alias-impl-trait/coherence/coherence_different_hidden_ty.rs [placeholder-ck]: https://github.com/rust-lang/rust/blob/384d26fc7e3bdd7687cc17b2662b091f6017ec2a/compiler/rustc_trait_selection/src/solve/normalizes_to/opaque_types.rs#L33 [check-storage]: https://github.com/rust-lang/rust/blob/384d26fc7e3bdd7687cc17b2662b091f6017ec2a/compiler/rustc_trait_selection/src/solve/normalizes_to/opaque_types.rs#L51-L52 [eq-prev]: https://github.com/rust-lang/rust/blob/384d26fc7e3bdd7687cc17b2662b091f6017ec2a/compiler/rustc_trait_selection/src/solve/normalizes_to/opaque_types.rs#L51-L59 diff --git a/src/doc/rustc-dev-guide/src/tests/ci.md b/src/doc/rustc-dev-guide/src/tests/ci.md index 96e4edc17a5..750e4fa1a0f 100644 --- a/src/doc/rustc-dev-guide/src/tests/ci.md +++ b/src/doc/rustc-dev-guide/src/tests/ci.md @@ -66,8 +66,8 @@ kinds of builds (sets of jobs). ### Pull Request builds After each push to a pull request, a set of `pr` jobs are executed. Currently, -these execute the `x86_64-gnu-llvm-X`, `x86_64-gnu-tools`, `mingw-check-1`, `mingw-check-2` -and `mingw-check-tidy` jobs, all running on Linux. These execute a relatively short +these execute the `x86_64-gnu-llvm-X`, `x86_64-gnu-tools`, `pr-check-1`, `pr-check-2` +and `tidy` jobs, all running on Linux. These execute a relatively short (~40 minutes) and lightweight test suite that should catch common issues. More specifically, they run a set of lints, they try to perform a cross-compile check build to Windows mingw (without producing any artifacts) and they test the @@ -148,6 +148,13 @@ for example `*msvc*` or `*-alt`. You can start at most 20 jobs in a single try b glob patterns, you might want to wrap them in backticks (`` ` ``) to avoid GitHub rendering the pattern as Markdown. +The job pattern needs to match one or more jobs defined in the `auto` or `optional` sections +of [`jobs.yml`]: + +- `auto` jobs are executed before a commit is merged into the `master` branch. +- `optional` jobs are executed only when explicitly requested via a try build. + They are typically used for tier 2 and tier 3 targets. + > **Using `try-job` PR description directives** > > 1. Identify which set of try-jobs you would like to exercise. You can diff --git a/src/doc/rustc-dev-guide/src/tests/minicore.md b/src/doc/rustc-dev-guide/src/tests/minicore.md index def9aaf8733..23b77279011 100644 --- a/src/doc/rustc-dev-guide/src/tests/minicore.md +++ b/src/doc/rustc-dev-guide/src/tests/minicore.md @@ -39,6 +39,12 @@ If you find a `core` item to be missing from the [`minicore`] stub, consider adding it to the test auxiliary if it's likely to be used or is already needed by more than one test. +## Staying in sync with `core` + +The `minicore` items must be kept up to date with `core`. For consistent +diagnostic output between using `core` and `minicore`, any `diagnostic` +attributes (e.g. `on_unimplemented`) should be replicated exactly in `minicore`. + ## Example codegen test that uses `minicore` ```rust,no_run diff --git a/src/doc/rustc/src/SUMMARY.md b/src/doc/rustc/src/SUMMARY.md index 201a5503079..9fe4c218121 100644 --- a/src/doc/rustc/src/SUMMARY.md +++ b/src/doc/rustc/src/SUMMARY.md @@ -130,7 +130,7 @@ - [\*-win7-windows-msvc](platform-support/win7-windows-msvc.md) - [x86_64-fortanix-unknown-sgx](platform-support/x86_64-fortanix-unknown-sgx.md) - [x86_64-pc-cygwin](platform-support/x86_64-pc-cygwin.md) - - [x86_64-unknown-linux-none.md](platform-support/x86_64-unknown-linux-none.md) + - [x86_64-unknown-linux-none](platform-support/x86_64-unknown-linux-none.md) - [x86_64-unknown-none](platform-support/x86_64-unknown-none.md) - [xtensa-\*-none-elf](platform-support/xtensa.md) - [\*-nuttx-\*](platform-support/nuttx.md) diff --git a/src/etc/completions/x.py.fish b/src/etc/completions/x.py.fish index 64734d5bcaa..e982cde634f 100644 --- a/src/etc/completions/x.py.fish +++ b/src/etc/completions/x.py.fish @@ -293,7 +293,7 @@ complete -c x.py -n "__fish_x.py_using_subcommand doc" -l skip-std-check-if-no-d complete -c x.py -n "__fish_x.py_using_subcommand doc" -s h -l help -d 'Print help (see more with \'--help\')' complete -c x.py -n "__fish_x.py_using_subcommand test" -l test-args -d 'extra arguments to be passed for the test tool being used (e.g. libtest, compiletest or rustdoc)' -r complete -c x.py -n "__fish_x.py_using_subcommand test" -l compiletest-rustc-args -d 'extra options to pass the compiler when running compiletest tests' -r -complete -c x.py -n "__fish_x.py_using_subcommand test" -l extra-checks -d 'comma-separated list of other files types to check (accepts py, py:lint, py:fmt, shell)' -r +complete -c x.py -n "__fish_x.py_using_subcommand test" -l extra-checks -d 'comma-separated list of other files types to check (accepts py, py:lint, py:fmt, shell, shell:lint, cpp, cpp:fmt, spellcheck, spellcheck:fix)' -r complete -c x.py -n "__fish_x.py_using_subcommand test" -l compare-mode -d 'mode describing what file the actual ui output will be compared to' -r complete -c x.py -n "__fish_x.py_using_subcommand test" -l pass -d 'force {check,build,run}-pass tests to this mode' -r complete -c x.py -n "__fish_x.py_using_subcommand test" -l run -d 'whether to execute run-* tests' -r diff --git a/src/etc/completions/x.py.ps1 b/src/etc/completions/x.py.ps1 index 154f4f95eb5..f4b26fac0bc 100644 --- a/src/etc/completions/x.py.ps1 +++ b/src/etc/completions/x.py.ps1 @@ -339,7 +339,7 @@ Register-ArgumentCompleter -Native -CommandName 'x.py' -ScriptBlock { 'x.py;test' { [CompletionResult]::new('--test-args', '--test-args', [CompletionResultType]::ParameterName, 'extra arguments to be passed for the test tool being used (e.g. libtest, compiletest or rustdoc)') [CompletionResult]::new('--compiletest-rustc-args', '--compiletest-rustc-args', [CompletionResultType]::ParameterName, 'extra options to pass the compiler when running compiletest tests') - [CompletionResult]::new('--extra-checks', '--extra-checks', [CompletionResultType]::ParameterName, 'comma-separated list of other files types to check (accepts py, py:lint, py:fmt, shell)') + [CompletionResult]::new('--extra-checks', '--extra-checks', [CompletionResultType]::ParameterName, 'comma-separated list of other files types to check (accepts py, py:lint, py:fmt, shell, shell:lint, cpp, cpp:fmt, spellcheck, spellcheck:fix)') [CompletionResult]::new('--compare-mode', '--compare-mode', [CompletionResultType]::ParameterName, 'mode describing what file the actual ui output will be compared to') [CompletionResult]::new('--pass', '--pass', [CompletionResultType]::ParameterName, 'force {check,build,run}-pass tests to this mode') [CompletionResult]::new('--run', '--run', [CompletionResultType]::ParameterName, 'whether to execute run-* tests') diff --git a/src/etc/completions/x.py.zsh b/src/etc/completions/x.py.zsh index 177d60f9738..8fc4f052252 100644 --- a/src/etc/completions/x.py.zsh +++ b/src/etc/completions/x.py.zsh @@ -338,7 +338,7 @@ _arguments "${_arguments_options[@]}" : \ _arguments "${_arguments_options[@]}" : \ '*--test-args=[extra arguments to be passed for the test tool being used (e.g. libtest, compiletest or rustdoc)]:ARGS:_default' \ '*--compiletest-rustc-args=[extra options to pass the compiler when running compiletest tests]:ARGS:_default' \ -'--extra-checks=[comma-separated list of other files types to check (accepts py, py\:lint, py\:fmt, shell)]:EXTRA_CHECKS:_default' \ +'--extra-checks=[comma-separated list of other files types to check (accepts py, py\:lint, py\:fmt, shell, shell\:lint, cpp, cpp\:fmt, spellcheck, spellcheck\:fix)]:EXTRA_CHECKS:_default' \ '--compare-mode=[mode describing what file the actual ui output will be compared to]:COMPARE MODE:_default' \ '--pass=[force {check,build,run}-pass tests to this mode]:check | build | run:_default' \ '--run=[whether to execute run-* tests]:auto | always | never:_default' \ diff --git a/src/librustdoc/clean/blanket_impl.rs b/src/librustdoc/clean/blanket_impl.rs index c889f52b789..11d5b472d73 100644 --- a/src/librustdoc/clean/blanket_impl.rs +++ b/src/librustdoc/clean/blanket_impl.rs @@ -23,7 +23,7 @@ pub(crate) fn synthesize_blanket_impls( let ty = tcx.type_of(item_def_id); let mut blanket_impls = Vec::new(); - for trait_def_id in tcx.all_traits() { + for trait_def_id in tcx.visible_traits() { if !cx.cache.effective_visibilities.is_reachable(tcx, trait_def_id) || cx.generated_synthetics.contains(&(ty.skip_binder(), trait_def_id)) { diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 3d027db2622..2ab827b3ace 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -66,8 +66,8 @@ use crate::visit_ast::Module as DocModule; pub(crate) fn clean_doc_module<'tcx>(doc: &DocModule<'tcx>, cx: &mut DocContext<'tcx>) -> Item { let mut items: Vec<Item> = vec![]; let mut inserted = FxHashSet::default(); - items.extend(doc.foreigns.iter().map(|(item, renamed)| { - let item = clean_maybe_renamed_foreign_item(cx, item, *renamed); + items.extend(doc.foreigns.iter().map(|(item, renamed, import_id)| { + let item = clean_maybe_renamed_foreign_item(cx, item, *renamed, *import_id); if let Some(name) = item.name && (cx.render_options.document_hidden || !item.is_doc_hidden()) { @@ -89,7 +89,7 @@ pub(crate) fn clean_doc_module<'tcx>(doc: &DocModule<'tcx>, cx: &mut DocContext< Some(item) })); - // Split up imports from all other items. + // Split up glob imports from all other items. // // This covers the case where somebody does an import which should pull in an item, // but there's already an item with the same namespace and same name. Rust gives @@ -1171,7 +1171,7 @@ fn clean_poly_fn_sig<'tcx>( // If this comes from a fn item, let's not perpetuate anon params from Rust 2015; use `_` for them. // If this comes from a fn ptr ty, we just keep params unnamed since it's more conventional stylistically. // Since the param name is not part of the semantic type, these params never bear a name unlike - // in the HIR case, thus we can't peform any fancy fallback logic unlike `clean_bare_fn_ty`. + // in the HIR case, thus we can't perform any fancy fallback logic unlike `clean_bare_fn_ty`. let fallback = did.map(|_| kw::Underscore); let params = sig @@ -2746,7 +2746,8 @@ fn add_without_unwanted_attributes<'hir>( attrs.push((Cow::Owned(attr), import_parent)); } } - hir::Attribute::Parsed(..) if is_inline => { + // FIXME: make sure to exclude `#[cfg_trace]` here when it is ported to the new parsers + hir::Attribute::Parsed(..) => { attrs.push((Cow::Owned(attr), import_parent)); } _ => {} @@ -2761,7 +2762,6 @@ fn clean_maybe_renamed_item<'tcx>( import_id: Option<LocalDefId>, ) -> Vec<Item> { use hir::ItemKind; - fn get_name( cx: &DocContext<'_>, item: &hir::Item<'_>, @@ -2973,6 +2973,7 @@ fn clean_extern_crate<'tcx>( && !cx.is_json_output(); let krate_owner_def_id = krate.owner_id.def_id; + if please_inline && let Some(items) = inline::try_inline( cx, @@ -3134,6 +3135,7 @@ fn clean_maybe_renamed_foreign_item<'tcx>( cx: &mut DocContext<'tcx>, item: &hir::ForeignItem<'tcx>, renamed: Option<Symbol>, + import_id: Option<LocalDefId>, ) -> Item { let def_id = item.owner_id.to_def_id(); cx.with_param_env(def_id, |cx| { @@ -3149,11 +3151,13 @@ fn clean_maybe_renamed_foreign_item<'tcx>( hir::ForeignItemKind::Type => ForeignTypeItem, }; - Item::from_def_id_and_parts( - item.owner_id.def_id.to_def_id(), - Some(renamed.unwrap_or(item.ident.name)), - kind, + generate_item_with_correct_attrs( cx, + kind, + item.owner_id.def_id.to_def_id(), + item.ident.name, + import_id, + renamed, ) }) } diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs index 600c564d714..c9530216968 100644 --- a/src/librustdoc/clean/types.rs +++ b/src/librustdoc/clean/types.rs @@ -7,7 +7,7 @@ use arrayvec::ArrayVec; use itertools::Either; use rustc_abi::{ExternAbi, VariantIdx}; use rustc_attr_data_structures::{ - AttributeKind, ConstStability, Deprecation, Stability, StableSince, + AttributeKind, ConstStability, Deprecation, Stability, StableSince, find_attr, }; use rustc_data_structures::fx::{FxHashSet, FxIndexMap, FxIndexSet}; use rustc_hir::def::{CtorKind, DefKind, Res}; @@ -24,7 +24,7 @@ use rustc_resolve::rustdoc::{ }; use rustc_session::Session; use rustc_span::hygiene::MacroKind; -use rustc_span::symbol::{Ident, Symbol, kw, sym}; +use rustc_span::symbol::{Symbol, kw, sym}; use rustc_span::{DUMMY_SP, FileName, Loc}; use thin_vec::ThinVec; use tracing::{debug, trace}; @@ -770,6 +770,17 @@ impl Item { hir::Attribute::Parsed(AttributeKind::Deprecation { .. }) => None, // We have separate pretty-printing logic for `#[repr(..)]` attributes. hir::Attribute::Parsed(AttributeKind::Repr(..)) => None, + // target_feature is special-cased because cargo-semver-checks uses it + hir::Attribute::Parsed(AttributeKind::TargetFeature(features, _)) => { + let mut output = String::new(); + for (i, (feature, _)) in features.iter().enumerate() { + if i != 0 { + output.push_str(", "); + } + output.push_str(&format!("enable=\"{}\"", feature.as_str())); + } + Some(format!("#[target_feature({output})]")) + } _ => Some({ let mut s = rustc_hir_pretty::attribute_to_string(&tcx, attr); assert_eq!(s.pop(), Some('\n')); @@ -1075,16 +1086,10 @@ pub(crate) fn extract_cfg_from_attrs<'a, I: Iterator<Item = &'a hir::Attribute> // treat #[target_feature(enable = "feat")] attributes as if they were // #[doc(cfg(target_feature = "feat"))] attributes as well - for attr in hir_attr_lists(attrs, sym::target_feature) { - if attr.has_name(sym::enable) && attr.value_str().is_some() { - // Clone `enable = "feat"`, change to `target_feature = "feat"`. - // Unwrap is safe because `value_str` succeeded above. - let mut meta = attr.meta_item().unwrap().clone(); - meta.path = ast::Path::from_ident(Ident::with_dummy_span(sym::target_feature)); - - if let Ok(feat_cfg) = Cfg::parse(&ast::MetaItemInner::MetaItem(meta)) { - cfg &= feat_cfg; - } + if let Some(features) = find_attr!(attrs, AttributeKind::TargetFeature(features, _) => features) + { + for (feature, _) in features { + cfg &= Cfg::Cfg(sym::target_feature, Some(*feature)); } } diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs index cf3c4ac97af..bd57bb21e63 100644 --- a/src/librustdoc/core.rs +++ b/src/librustdoc/core.rs @@ -353,7 +353,7 @@ pub(crate) fn run_global_ctxt( rustc_passes::stability::check_unused_or_stable_features(tcx); let auto_traits = - tcx.all_traits().filter(|&trait_def_id| tcx.trait_is_auto(trait_def_id)).collect(); + tcx.visible_traits().filter(|&trait_def_id| tcx.trait_is_auto(trait_def_id)).collect(); let mut ctxt = DocContext { tcx, diff --git a/src/librustdoc/doctest.rs b/src/librustdoc/doctest.rs index 1b5c9fd4664..9b4d2533954 100644 --- a/src/librustdoc/doctest.rs +++ b/src/librustdoc/doctest.rs @@ -858,7 +858,7 @@ impl ScrapedDocTest { item_path.push(' '); } let name = - format!("{} - {item_path}(line {line})", filename.prefer_remapped_unconditionaly()); + format!("{} - {item_path}(line {line})", filename.prefer_remapped_unconditionally()); Self { filename, line, langstr, text, name, span, global_crate_attrs } } diff --git a/src/librustdoc/doctest/extracted.rs b/src/librustdoc/doctest/extracted.rs index 925fb6fee2c..3d046ec1835 100644 --- a/src/librustdoc/doctest/extracted.rs +++ b/src/librustdoc/doctest/extracted.rs @@ -62,7 +62,7 @@ impl ExtractedDocTests { Some(&opts.crate_name), ); self.doctests.push(ExtractedDocTest { - file: filename.prefer_remapped_unconditionaly().to_string(), + file: filename.prefer_remapped_unconditionally().to_string(), line, doctest_attributes: langstr.into(), doctest_code: match wrapped { diff --git a/src/librustdoc/externalfiles.rs b/src/librustdoc/externalfiles.rs index b81fc5a0a71..ea2aa963edd 100644 --- a/src/librustdoc/externalfiles.rs +++ b/src/librustdoc/externalfiles.rs @@ -35,10 +35,9 @@ impl ExternalHtml { ) -> Option<ExternalHtml> { let codes = ErrorCodes::from(nightly_build); let ih = load_external_files(in_header, dcx)?; - let bc = load_external_files(before_content, dcx)?; - let m_bc = load_external_files(md_before_content, dcx)?; - let bc = format!( - "{bc}{}", + let bc = { + let mut bc = load_external_files(before_content, dcx)?; + let m_bc = load_external_files(md_before_content, dcx)?; Markdown { content: &m_bc, links: &[], @@ -48,12 +47,13 @@ impl ExternalHtml { playground, heading_offset: HeadingOffset::H2, } - .into_string() - ); - let ac = load_external_files(after_content, dcx)?; - let m_ac = load_external_files(md_after_content, dcx)?; - let ac = format!( - "{ac}{}", + .write_into(&mut bc) + .unwrap(); + bc + }; + let ac = { + let mut ac = load_external_files(after_content, dcx)?; + let m_ac = load_external_files(md_after_content, dcx)?; Markdown { content: &m_ac, links: &[], @@ -63,8 +63,10 @@ impl ExternalHtml { playground, heading_offset: HeadingOffset::H2, } - .into_string() - ); + .write_into(&mut ac) + .unwrap(); + ac + }; Some(ExternalHtml { in_header: ih, before_content: bc, after_content: ac }) } } diff --git a/src/librustdoc/html/markdown.rs b/src/librustdoc/html/markdown.rs index f626e07b000..e41435de29c 100644 --- a/src/librustdoc/html/markdown.rs +++ b/src/librustdoc/html/markdown.rs @@ -21,13 +21,14 @@ //! playground: &None, //! heading_offset: HeadingOffset::H2, //! }; -//! let html = md.into_string(); +//! let mut html = String::new(); +//! md.write_into(&mut html).unwrap(); //! // ... something using html //! ``` use std::borrow::Cow; use std::collections::VecDeque; -use std::fmt::Write; +use std::fmt::{self, Write}; use std::iter::Peekable; use std::ops::{ControlFlow, Range}; use std::path::PathBuf; @@ -1328,16 +1329,13 @@ impl LangString { } impl<'a> Markdown<'a> { - pub fn into_string(self) -> String { + pub fn write_into(self, f: impl fmt::Write) -> fmt::Result { // This is actually common enough to special-case if self.content.is_empty() { - return String::new(); + return Ok(()); } - let mut s = String::with_capacity(self.content.len() * 3 / 2); - html::push_html(&mut s, self.into_iter()); - - s + html::write_html_fmt(f, self.into_iter()) } fn into_iter(self) -> CodeBlocks<'a, 'a, impl Iterator<Item = Event<'a>>> { @@ -1453,19 +1451,20 @@ impl MarkdownWithToc<'_> { (toc.into_toc(), s) } - pub(crate) fn into_string(self) -> String { + + pub(crate) fn write_into(self, mut f: impl fmt::Write) -> fmt::Result { let (toc, s) = self.into_parts(); - format!("<nav id=\"rustdoc\">{toc}</nav>{s}", toc = toc.print()) + write!(f, "<nav id=\"rustdoc\">{toc}</nav>{s}", toc = toc.print()) } } impl MarkdownItemInfo<'_> { - pub(crate) fn into_string(self) -> String { + pub(crate) fn write_into(self, mut f: impl fmt::Write) -> fmt::Result { let MarkdownItemInfo(md, ids) = self; // This is actually common enough to special-case if md.is_empty() { - return String::new(); + return Ok(()); } let p = Parser::new_ext(md, main_body_opts()).into_offset_iter(); @@ -1475,8 +1474,6 @@ impl MarkdownItemInfo<'_> { _ => event, }); - let mut s = String::with_capacity(md.len() * 3 / 2); - ids.handle_footnotes(|ids, existing_footnotes| { let p = HeadingLinks::new(p, None, ids, HeadingOffset::H1); let p = footnotes::Footnotes::new(p, existing_footnotes); @@ -1484,10 +1481,8 @@ impl MarkdownItemInfo<'_> { let p = p.filter(|event| { !matches!(event, Event::Start(Tag::Paragraph) | Event::End(TagEnd::Paragraph)) }); - html::push_html(&mut s, p); - }); - - s + html::write_html_fmt(&mut f, p) + }) } } diff --git a/src/librustdoc/html/markdown/footnotes.rs b/src/librustdoc/html/markdown/footnotes.rs index ded0585ddcc..7ee012c4da2 100644 --- a/src/librustdoc/html/markdown/footnotes.rs +++ b/src/librustdoc/html/markdown/footnotes.rs @@ -38,7 +38,7 @@ impl<'a, I: Iterator<Item = SpannedEvent<'a>>> Footnotes<'a, I> { let key = key.to_owned(); let FootnoteDef { content, id } = self.footnotes.entry(key).or_insert(FootnoteDef { content: Vec::new(), id: new_id }); - // Don't allow changing the ID of existing entrys, but allow changing the contents. + // Don't allow changing the ID of existing entries, but allow changing the contents. (content, *id) } @@ -82,7 +82,7 @@ impl<'a, I: Iterator<Item = SpannedEvent<'a>>> Iterator for Footnotes<'a, I> { return Some((self.handle_footnote_reference(reference), range)); } Some((Event::Start(Tag::FootnoteDefinition(def)), _)) => { - // When we see a footnote definition, collect the assocated content, and store + // When we see a footnote definition, collect the associated content, and store // that for rendering later. let content = self.collect_footnote_def(); let (entry_content, _) = self.get_entry(&def); diff --git a/src/librustdoc/html/markdown/tests.rs b/src/librustdoc/html/markdown/tests.rs index 784d0c5d21e..61fd4287463 100644 --- a/src/librustdoc/html/markdown/tests.rs +++ b/src/librustdoc/html/markdown/tests.rs @@ -297,7 +297,8 @@ fn test_lang_string_tokenizer() { fn test_header() { fn t(input: &str, expect: &str) { let mut map = IdMap::new(); - let output = Markdown { + let mut output = String::new(); + Markdown { content: input, links: &[], ids: &mut map, @@ -306,7 +307,8 @@ fn test_header() { playground: &None, heading_offset: HeadingOffset::H2, } - .into_string(); + .write_into(&mut output) + .unwrap(); assert_eq!(output, expect, "original: {}", input); } @@ -348,7 +350,8 @@ fn test_header() { fn test_header_ids_multiple_blocks() { let mut map = IdMap::new(); fn t(map: &mut IdMap, input: &str, expect: &str) { - let output = Markdown { + let mut output = String::new(); + Markdown { content: input, links: &[], ids: map, @@ -357,7 +360,8 @@ fn test_header_ids_multiple_blocks() { playground: &None, heading_offset: HeadingOffset::H2, } - .into_string(); + .write_into(&mut output) + .unwrap(); assert_eq!(output, expect, "original: {}", input); } @@ -466,7 +470,8 @@ fn test_plain_text_summary() { fn test_markdown_html_escape() { fn t(input: &str, expect: &str) { let mut idmap = IdMap::new(); - let output = MarkdownItemInfo(input, &mut idmap).into_string(); + let mut output = String::new(); + MarkdownItemInfo(input, &mut idmap).write_into(&mut output).unwrap(); assert_eq!(output, expect, "original: {}", input); } @@ -496,7 +501,8 @@ fn test_find_testable_code_line() { fn test_ascii_with_prepending_hashtag() { fn t(input: &str, expect: &str) { let mut map = IdMap::new(); - let output = Markdown { + let mut output = String::new(); + Markdown { content: input, links: &[], ids: &mut map, @@ -505,7 +511,8 @@ fn test_ascii_with_prepending_hashtag() { playground: &None, heading_offset: HeadingOffset::H2, } - .into_string(); + .write_into(&mut output) + .unwrap(); assert_eq!(output, expect, "original: {}", input); } diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs index ed58bae70bd..6a1fad06ae3 100644 --- a/src/librustdoc/html/render/mod.rs +++ b/src/librustdoc/html/render/mod.rs @@ -508,22 +508,21 @@ fn scrape_examples_help(shared: &SharedContext<'_>) -> String { the Rustdoc book]({DOC_RUST_LANG_ORG_VERSION}/rustdoc/scraped-examples.html)." )); - let mut ids = IdMap::default(); format!( "<div class=\"main-heading\">\ <h1>About scraped examples</h1>\ </div>\ <div>{}</div>", - Markdown { + fmt::from_fn(|f| Markdown { content: &content, links: &[], - ids: &mut ids, + ids: &mut IdMap::default(), error_codes: shared.codes, edition: shared.edition(), playground: &shared.playground, heading_offset: HeadingOffset::H1, } - .into_string() + .write_into(f)) ) } @@ -555,20 +554,18 @@ fn render_markdown( heading_offset: HeadingOffset, ) -> impl fmt::Display { fmt::from_fn(move |f| { - write!( - f, - "<div class=\"docblock\">{}</div>", - Markdown { - content: md_text, - links: &links, - ids: &mut cx.id_map.borrow_mut(), - error_codes: cx.shared.codes, - edition: cx.shared.edition(), - playground: &cx.shared.playground, - heading_offset, - } - .into_string() - ) + f.write_str("<div class=\"docblock\">")?; + Markdown { + content: md_text, + links: &links, + ids: &mut cx.id_map.borrow_mut(), + error_codes: cx.shared.codes, + edition: cx.shared.edition(), + playground: &cx.shared.playground, + heading_offset, + } + .write_into(&mut *f)?; + f.write_str("</div>") }) } @@ -752,7 +749,7 @@ fn short_item_info( let mut id_map = cx.id_map.borrow_mut(); let html = MarkdownItemInfo(note, &mut id_map); message.push_str(": "); - message.push_str(&html.into_string()); + html.write_into(&mut message).unwrap(); } extra_info.push(ShortItemInfo::Deprecation { message }); } @@ -1947,7 +1944,7 @@ fn render_impl( // 3. Functions // // This order is because you can have associated constants used in associated types (like array - // length), and both in associcated functions. So with this order, when reading from top to + // length), and both in associated functions. So with this order, when reading from top to // bottom, you should see items definitions before they're actually used most of the time. let mut assoc_types = Vec::new(); let mut methods = Vec::new(); diff --git a/src/librustdoc/html/render/write_shared.rs b/src/librustdoc/html/render/write_shared.rs index 606a9113908..41c3f03b91b 100644 --- a/src/librustdoc/html/render/write_shared.rs +++ b/src/librustdoc/html/render/write_shared.rs @@ -443,7 +443,7 @@ impl CratesIndexPart { .expect("Object Replacement Character (U+FFFC) should not appear in the --index-page") } - /// Might return parts that are duplicate with ones in prexisting index.html + /// Might return parts that are duplicate with ones in preexisting index.html fn get(crate_name: &str, external_crates: &[String]) -> Result<PartsAndLocations<Self>, Error> { let mut ret = PartsAndLocations::default(); let path = Path::new("index.html"); diff --git a/src/librustdoc/html/static/css/rustdoc.css b/src/librustdoc/html/static/css/rustdoc.css index 7be83b65fbf..99b3da8b2cd 100644 --- a/src/librustdoc/html/static/css/rustdoc.css +++ b/src/librustdoc/html/static/css/rustdoc.css @@ -8,6 +8,8 @@ 3. Copy the filenames with updated suffixes from the directory. */ +/* ignore-tidy-filelength */ + :root { --nav-sub-mobile-padding: 8px; --search-typename-width: 6.75rem; @@ -915,32 +917,30 @@ ul.block, .block li, .block ul { overflow: auto; } -.example-wrap.digits-1:not(.hide-lines) [data-nosnippet] { - width: calc(1ch + var(--line-number-padding) * 2); -} -.example-wrap.digits-2:not(.hide-lines) [data-nosnippet] { - width: calc(2ch + var(--line-number-padding) * 2); -} -.example-wrap.digits-3:not(.hide-lines) [data-nosnippet] { - width: calc(3ch + var(--line-number-padding) * 2); -} -.example-wrap.digits-4:not(.hide-lines) [data-nosnippet] { - width: calc(4ch + var(--line-number-padding) * 2); -} -.example-wrap.digits-5:not(.hide-lines) [data-nosnippet] { - width: calc(5ch + var(--line-number-padding) * 2); -} -.example-wrap.digits-6:not(.hide-lines) [data-nosnippet] { - width: calc(6ch + var(--line-number-padding) * 2); +.example-wrap code { + position: relative; } -.example-wrap.digits-7:not(.hide-lines) [data-nosnippet] { - width: calc(7ch + var(--line-number-padding) * 2); +.example-wrap pre code span { + display: inline; } -.example-wrap.digits-8:not(.hide-lines) [data-nosnippet] { - width: calc(8ch + var(--line-number-padding) * 2); + +.example-wrap.digits-1 { --example-wrap-digits-count: 1ch; } +.example-wrap.digits-2 { --example-wrap-digits-count: 2ch; } +.example-wrap.digits-3 { --example-wrap-digits-count: 3ch; } +.example-wrap.digits-4 { --example-wrap-digits-count: 4ch; } +.example-wrap.digits-5 { --example-wrap-digits-count: 5ch; } +.example-wrap.digits-6 { --example-wrap-digits-count: 6ch; } +.example-wrap.digits-7 { --example-wrap-digits-count: 7ch; } +.example-wrap.digits-8 { --example-wrap-digits-count: 8ch; } +.example-wrap.digits-9 { --example-wrap-digits-count: 9ch; } + +.example-wrap [data-nosnippet] { + width: calc(var(--example-wrap-digits-count) + var(--line-number-padding) * 2); } -.example-wrap.digits-9:not(.hide-lines) [data-nosnippet] { - width: calc(9ch + var(--line-number-padding) * 2); +.example-wrap pre > code { + padding-left: calc( + var(--example-wrap-digits-count) + var(--line-number-padding) * 2 + + var(--line-number-right-margin)); } .example-wrap [data-nosnippet] { @@ -953,63 +953,25 @@ ul.block, .block li, .block ul { -ms-user-select: none; user-select: none; padding: 0 var(--line-number-padding); -} -.example-wrap [data-nosnippet]:target { - border-right: none; + position: absolute; + left: 0; } .example-wrap .line-highlighted[data-nosnippet] { background-color: var(--src-line-number-highlighted-background-color); } -:root.word-wrap-source-code .example-wrap [data-nosnippet] { - position: absolute; - left: 0; -} -.word-wrap-source-code .example-wrap pre > code { +.example-wrap pre > code { position: relative; - word-break: break-all; + display: block; } :root.word-wrap-source-code .example-wrap pre > code { - display: block; + word-break: break-all; white-space: pre-wrap; } :root.word-wrap-source-code .example-wrap pre > code * { word-break: break-all; } -:root.word-wrap-source-code .example-wrap.digits-1 pre > code { - padding-left: calc( - 1ch + var(--line-number-padding) * 2 + var(--line-number-right-margin)); -} -:root.word-wrap-source-code .example-wrap.digits-2 pre > code { - padding-left: calc( - 2ch + var(--line-number-padding) * 2 + var(--line-number-right-margin)); -} -:root.word-wrap-source-code .example-wrap.digits-3 pre > code { - padding-left: calc( - 3ch + var(--line-number-padding) * 2 + var(--line-number-right-margin)); -} -:root.word-wrap-source-code .example-wrap.digits-4 pre > code { - padding-left: calc( - 4ch + var(--line-number-padding) * 2 + var(--line-number-right-margin)); -} -:root.word-wrap-source-code .example-wrap.digits-5 pre > code { - padding-left: calc( - 5ch + var(--line-number-padding) * 2 + var(--line-number-right-margin)); -} -:root.word-wrap-source-code .example-wrap.digits-6 pre > code { - padding-left: calc( - 6ch + var(--line-number-padding) * 2 + var(--line-number-right-margin)); -} -:root.word-wrap-source-code .example-wrap.digits-7 pre > code { - padding-left: calc( - 7ch + var(--line-number-padding) * 2 + var(--line-number-right-margin)); -} -:root.word-wrap-source-code .example-wrap.digits-8 pre > code { - padding-left: calc( - 8ch + var(--line-number-padding) * 2 + var(--line-number-right-margin)); -} -:root.word-wrap-source-code .example-wrap.digits-9 pre > code { - padding-left: calc( - 9ch + var(--line-number-padding) * 2 + var(--line-number-right-margin)); +.example-wrap [data-nosnippet]:target { + border-right: none; } .example-wrap.hide-lines [data-nosnippet] { display: none; diff --git a/src/librustdoc/html/static/js/main.js b/src/librustdoc/html/static/js/main.js index 2de8f836da3..3c4af0dc612 100644 --- a/src/librustdoc/html/static/js/main.js +++ b/src/librustdoc/html/static/js/main.js @@ -1719,7 +1719,7 @@ function preLoadCss(cssUrl) { // 300px, and the RUSTDOC_MOBILE_BREAKPOINT is 700px, so BODY_MIN must be // at most 400px. Otherwise, it would start out at the default size, then // grabbing the resize handle would suddenly cause it to jank to - // its contraint-generated maximum. + // its constraint-generated maximum. const RUSTDOC_MOBILE_BREAKPOINT = 700; const BODY_MIN = 400; // At half-way past the minimum size, vanish the sidebar entirely diff --git a/src/librustdoc/html/static/js/rustdoc.d.ts b/src/librustdoc/html/static/js/rustdoc.d.ts index bbcd96040be..ca2512e5ab6 100644 --- a/src/librustdoc/html/static/js/rustdoc.d.ts +++ b/src/librustdoc/html/static/js/rustdoc.d.ts @@ -464,7 +464,7 @@ declare namespace rustdoc { /** * Maps from crate names to trait implementation data. - * Provied by generated `trait.impl` files. + * Provided by generated `trait.impl` files. */ type Implementors = { [key: string]: Array<[string, number, Array<string>]> diff --git a/src/librustdoc/markdown.rs b/src/librustdoc/markdown.rs index 76eac084907..4ca2c104888 100644 --- a/src/librustdoc/markdown.rs +++ b/src/librustdoc/markdown.rs @@ -8,7 +8,7 @@ //! //! [docs]: https://doc.rust-lang.org/stable/rustdoc/#using-standalone-markdown-files -use std::fmt::Write as _; +use std::fmt::{self, Write as _}; use std::fs::{File, create_dir_all, read_to_string}; use std::io::prelude::*; use std::path::Path; @@ -77,32 +77,33 @@ pub(crate) fn render_and_write<P: AsRef<Path>>( } let title = metadata[0]; - let mut ids = IdMap::new(); let error_codes = ErrorCodes::from(options.unstable_features.is_nightly_build()); - let text = if !options.markdown_no_toc { - MarkdownWithToc { - content: text, - links: &[], - ids: &mut ids, - error_codes, - edition, - playground: &playground, - } - .into_string() - } else { - Markdown { - content: text, - links: &[], - ids: &mut ids, - error_codes, - edition, - playground: &playground, - heading_offset: HeadingOffset::H1, + let text = fmt::from_fn(|f| { + if !options.markdown_no_toc { + MarkdownWithToc { + content: text, + links: &[], + ids: &mut IdMap::new(), + error_codes, + edition, + playground: &playground, + } + .write_into(f) + } else { + Markdown { + content: text, + links: &[], + ids: &mut IdMap::new(), + error_codes, + edition, + playground: &playground, + heading_offset: HeadingOffset::H1, + } + .write_into(f) } - .into_string() - }; + }); - let err = write!( + let res = write!( &mut out, r#"<!DOCTYPE html> <html lang="en"> @@ -130,15 +131,10 @@ pub(crate) fn render_and_write<P: AsRef<Path>>( </body> </html>"#, title = Escape(title), - css = css, in_header = options.external_html.in_header, before_content = options.external_html.before_content, - text = text, after_content = options.external_html.after_content, ); - match err { - Err(e) => Err(format!("cannot write to `{output}`: {e}", output = output.display())), - Ok(_) => Ok(()), - } + res.map_err(|e| format!("cannot write to `{output}`: {e}", output = output.display())) } diff --git a/src/librustdoc/passes/strip_aliased_non_local.rs b/src/librustdoc/passes/strip_aliased_non_local.rs index 7f5c7da3634..b53e3b4e3d7 100644 --- a/src/librustdoc/passes/strip_aliased_non_local.rs +++ b/src/librustdoc/passes/strip_aliased_non_local.rs @@ -42,7 +42,7 @@ struct NonLocalStripper<'tcx> { impl DocFolder for NonLocalStripper<'_> { fn fold_item(&mut self, i: Item) -> Option<Item> { // If not local, we want to respect the original visibility of - // the field and not the one given by the user for the currrent crate. + // the field and not the one given by the user for the current crate. // // FIXME(#125009): Not-local should probably consider same Cargo workspace if let Some(def_id) = i.def_id() diff --git a/src/librustdoc/passes/strip_hidden.rs b/src/librustdoc/passes/strip_hidden.rs index 692ce21d6cf..3388ae46f05 100644 --- a/src/librustdoc/passes/strip_hidden.rs +++ b/src/librustdoc/passes/strip_hidden.rs @@ -168,7 +168,7 @@ impl DocFolder for Stripper<'_, '_> { self.update_retained = old; if ret.item_id == clean::ItemId::DefId(CRATE_DEF_ID.into()) { // We don't strip the current crate, even if it has `#[doc(hidden)]`. - debug!("strip_hidden: Not strippping local crate"); + debug!("strip_hidden: Not stripping local crate"); Some(ret) } else { Some(strip_item(ret)) diff --git a/src/librustdoc/visit_ast.rs b/src/librustdoc/visit_ast.rs index 5b52e785b8f..2889bfae7b0 100644 --- a/src/librustdoc/visit_ast.rs +++ b/src/librustdoc/visit_ast.rs @@ -38,9 +38,18 @@ pub(crate) struct Module<'hir> { (LocalDefId, Option<Symbol>), (&'hir hir::Item<'hir>, Option<Symbol>, Option<LocalDefId>), >, - /// Same as for `items`. + + /// (def_id, renamed) -> (res, local_import_id) + /// + /// `inlined_foreigns` only contains `extern` items + /// that are cross-crate inlined. + /// + /// Locally inlined `extern` items are + /// stored in `foreigns` with the `import_id` set, + /// analogous to how `items` is. pub(crate) inlined_foreigns: FxIndexMap<(DefId, Option<Symbol>), (Res, LocalDefId)>, - pub(crate) foreigns: Vec<(&'hir hir::ForeignItem<'hir>, Option<Symbol>)>, + /// (item, renamed, import_id) + pub(crate) foreigns: Vec<(&'hir hir::ForeignItem<'hir>, Option<Symbol>, Option<LocalDefId>)>, } impl Module<'_> { @@ -327,7 +336,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { } Node::ForeignItem(it) if !glob => { let prev = mem::replace(&mut self.inlining, true); - self.visit_foreign_item_inner(it, renamed); + self.visit_foreign_item_inner(it, renamed, Some(def_id)); self.inlining = prev; true } @@ -432,7 +441,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { hir::ItemKind::ForeignMod { items, .. } => { for item in items { let item = tcx.hir_foreign_item(item.id); - self.visit_foreign_item_inner(item, None); + self.visit_foreign_item_inner(item, None, None); } } // If we're inlining, skip private items. @@ -527,10 +536,11 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { &mut self, item: &'tcx hir::ForeignItem<'_>, renamed: Option<Symbol>, + import_id: Option<LocalDefId>, ) { // If inlining we only want to include public functions. if !self.inlining || self.cx.tcx.visibility(item.owner_id).is_public() { - self.modules.last_mut().unwrap().foreigns.push((item, renamed)); + self.modules.last_mut().unwrap().foreigns.push((item, renamed, import_id)); } } diff --git a/src/tools/clippy/clippy_utils/src/diagnostics.rs b/src/tools/clippy/clippy_utils/src/diagnostics.rs index dc240dd067b..8453165818b 100644 --- a/src/tools/clippy/clippy_utils/src/diagnostics.rs +++ b/src/tools/clippy/clippy_utils/src/diagnostics.rs @@ -98,6 +98,7 @@ fn validate_diag(diag: &Diag<'_, impl EmissionGuarantee>) { /// 17 | std::mem::forget(seven); /// | ^^^^^^^^^^^^^^^^^^^^^^^ /// ``` +#[track_caller] pub fn span_lint<T: LintContext>(cx: &T, lint: &'static Lint, sp: impl Into<MultiSpan>, msg: impl Into<DiagMessage>) { #[expect(clippy::disallowed_methods)] cx.span_lint(lint, sp, |diag| { @@ -143,6 +144,7 @@ pub fn span_lint<T: LintContext>(cx: &T, lint: &'static Lint, sp: impl Into<Mult /// | /// = help: consider using `f64::NAN` if you would like a constant representing NaN /// ``` +#[track_caller] pub fn span_lint_and_help<T: LintContext>( cx: &T, lint: &'static Lint, @@ -203,6 +205,7 @@ pub fn span_lint_and_help<T: LintContext>( /// 10 | forget(&SomeStruct); /// | ^^^^^^^^^^^ /// ``` +#[track_caller] pub fn span_lint_and_note<T: LintContext>( cx: &T, lint: &'static Lint, @@ -244,6 +247,7 @@ pub fn span_lint_and_note<T: LintContext>( /// If you're unsure which function you should use, you can test if the `#[expect]` attribute works /// where you would expect it to. /// If it doesn't, you likely need to use [`span_lint_hir_and_then`] instead. +#[track_caller] pub fn span_lint_and_then<C, S, M, F>(cx: &C, lint: &'static Lint, sp: S, msg: M, f: F) where C: LintContext, @@ -286,6 +290,7 @@ where /// Instead, use this function and also pass the `HirId` of `<expr_1>`, which will let /// the compiler check lint level attributes at the place of the expression and /// the `#[allow]` will work. +#[track_caller] pub fn span_lint_hir(cx: &LateContext<'_>, lint: &'static Lint, hir_id: HirId, sp: Span, msg: impl Into<DiagMessage>) { #[expect(clippy::disallowed_methods)] cx.tcx.node_span_lint(lint, hir_id, sp, |diag| { @@ -321,6 +326,7 @@ pub fn span_lint_hir(cx: &LateContext<'_>, lint: &'static Lint, hir_id: HirId, s /// Instead, use this function and also pass the `HirId` of `<expr_1>`, which will let /// the compiler check lint level attributes at the place of the expression and /// the `#[allow]` will work. +#[track_caller] pub fn span_lint_hir_and_then( cx: &LateContext<'_>, lint: &'static Lint, @@ -374,6 +380,7 @@ pub fn span_lint_hir_and_then( /// = note: `-D fold-any` implied by `-D warnings` /// ``` #[cfg_attr(not(debug_assertions), expect(clippy::collapsible_span_lint_calls))] +#[track_caller] pub fn span_lint_and_sugg<T: LintContext>( cx: &T, lint: &'static Lint, diff --git a/src/tools/clippy/tests/ui/track-diagnostics-clippy.rs b/src/tools/clippy/tests/ui/track-diagnostics-clippy.rs new file mode 100644 index 00000000000..2e67fb65efc --- /dev/null +++ b/src/tools/clippy/tests/ui/track-diagnostics-clippy.rs @@ -0,0 +1,22 @@ +//@compile-flags: -Z track-diagnostics +//@no-rustfix + +// Normalize the emitted location so this doesn't need +// updating everytime someone adds or removes a line. +//@normalize-stderr-test: ".rs:\d+:\d+" -> ".rs:LL:CC" + +#![warn(clippy::let_and_return, clippy::unnecessary_cast)] + +fn main() { + // Check the provenance of a lint sent through `LintContext::span_lint()` + let a = 3u32; + let b = a as u32; + //~^ unnecessary_cast + + // Check the provenance of a lint sent through `TyCtxt::node_span_lint()` + let c = { + let d = 42; + d + //~^ let_and_return + }; +} diff --git a/src/tools/clippy/tests/ui/track-diagnostics-clippy.stderr b/src/tools/clippy/tests/ui/track-diagnostics-clippy.stderr new file mode 100644 index 00000000000..f3aca685417 --- /dev/null +++ b/src/tools/clippy/tests/ui/track-diagnostics-clippy.stderr @@ -0,0 +1,29 @@ +error: casting to the same type is unnecessary (`u32` -> `u32`) + --> tests/ui/track-diagnostics-clippy.rs:LL:CC + | +LL | let b = a as u32; + | ^^^^^^^^ help: try: `a` +-Ztrack-diagnostics: created at src/tools/clippy/clippy_lints/src/casts/unnecessary_cast.rs:LL:CC + | + = note: `-D clippy::unnecessary-cast` implied by `-D warnings` + = help: to override `-D warnings` add `#[allow(clippy::unnecessary_cast)]` + +error: returning the result of a `let` binding from a block + --> tests/ui/track-diagnostics-clippy.rs:LL:CC + | +LL | let d = 42; + | ----------- unnecessary `let` binding +LL | d + | ^ +-Ztrack-diagnostics: created at src/tools/clippy/clippy_lints/src/returns.rs:LL:CC + | + = note: `-D clippy::let-and-return` implied by `-D warnings` + = help: to override `-D warnings` add `#[allow(clippy::let_and_return)]` +help: return the expression directly + | +LL ~ +LL ~ 42 + | + +error: aborting due to 2 previous errors + diff --git a/src/tools/compiletest/src/directive-list.rs b/src/tools/compiletest/src/directive-list.rs index 2ecb4fc8652..adf2a7bffef 100644 --- a/src/tools/compiletest/src/directive-list.rs +++ b/src/tools/compiletest/src/directive-list.rs @@ -1,6 +1,6 @@ /// This was originally generated by collecting directives from ui tests and then extracting their /// directive names. This is **not** an exhaustive list of all possible directives. Instead, this is -/// a best-effort approximation for diagnostics. Add new headers to this list when needed. +/// a best-effort approximation for diagnostics. Add new directives to this list when needed. const KNOWN_DIRECTIVE_NAMES: &[&str] = &[ // tidy-alphabetical-start "add-core-stubs", diff --git a/src/tools/compiletest/src/header.rs b/src/tools/compiletest/src/directives.rs index 5636a146b0f..a6242cf0c22 100644 --- a/src/tools/compiletest/src/header.rs +++ b/src/tools/compiletest/src/directives.rs @@ -11,10 +11,10 @@ use tracing::*; use crate::common::{Config, Debugger, FailMode, Mode, PassMode}; use crate::debuggers::{extract_cdb_version, extract_gdb_version}; +use crate::directives::auxiliary::{AuxProps, parse_and_update_aux}; +use crate::directives::needs::CachedNeedsConditions; use crate::errors::ErrorKind; use crate::executor::{CollectedTestDesc, ShouldPanic}; -use crate::header::auxiliary::{AuxProps, parse_and_update_aux}; -use crate::header::needs::CachedNeedsConditions; use crate::help; use crate::util::static_regex; @@ -24,11 +24,11 @@ mod needs; #[cfg(test)] mod tests; -pub struct HeadersCache { +pub struct DirectivesCache { needs: CachedNeedsConditions, } -impl HeadersCache { +impl DirectivesCache { pub fn load(config: &Config) -> Self { Self { needs: CachedNeedsConditions::load(config) } } @@ -54,7 +54,7 @@ impl EarlyProps { pub fn from_reader<R: Read>(config: &Config, testfile: &Utf8Path, rdr: R) -> Self { let mut props = EarlyProps::default(); let mut poisoned = false; - iter_header( + iter_directives( config.mode, &config.suite, &mut poisoned, @@ -138,12 +138,12 @@ pub struct TestProps { pub incremental_dir: Option<Utf8PathBuf>, // If `true`, this test will use incremental compilation. // - // This can be set manually with the `incremental` header, or implicitly + // This can be set manually with the `incremental` directive, or implicitly // by being a part of an incremental mode test. Using the `incremental` - // header should be avoided if possible; using an incremental mode test is + // directive should be avoided if possible; using an incremental mode test is // preferred. Incremental mode tests support multiple passes, which can // verify that the incremental cache can be loaded properly after being - // created. Just setting the header will only verify the behavior with + // created. Just setting the directive will only verify the behavior with // creating an incremental cache, but doesn't check that it is created // correctly. // @@ -347,7 +347,7 @@ impl TestProps { let mut poisoned = false; - iter_header( + iter_directives( config.mode, &config.suite, &mut poisoned, @@ -642,11 +642,11 @@ impl TestProps { let check_ui = |mode: &str| { // Mode::Crashes may need build-fail in order to trigger llvm errors or stack overflows if config.mode != Mode::Ui && config.mode != Mode::Crashes { - panic!("`{}-fail` header is only supported in UI tests", mode); + panic!("`{}-fail` directive is only supported in UI tests", mode); } }; if config.mode == Mode::Ui && config.parse_name_directive(ln, "compile-fail") { - panic!("`compile-fail` header is useless in UI tests"); + panic!("`compile-fail` directive is useless in UI tests"); } let fail_mode = if config.parse_name_directive(ln, "check-fail") { check_ui("check"); @@ -662,7 +662,7 @@ impl TestProps { }; match (self.fail_mode, fail_mode) { (None, Some(_)) => self.fail_mode = fail_mode, - (Some(_), Some(_)) => panic!("multiple `*-fail` headers in a single test"), + (Some(_), Some(_)) => panic!("multiple `*-fail` directives in a single test"), (_, None) => {} } } @@ -674,10 +674,10 @@ impl TestProps { (Mode::Codegen, "build-pass") => (), (Mode::Incremental, _) => { if revision.is_some() && !self.revisions.iter().all(|r| r.starts_with("cfail")) { - panic!("`{s}` header is only supported in `cfail` incremental tests") + panic!("`{s}` directive is only supported in `cfail` incremental tests") } } - (mode, _) => panic!("`{s}` header is not supported in `{mode}` tests"), + (mode, _) => panic!("`{s}` directive is not supported in `{mode}` tests"), }; let pass_mode = if config.parse_name_directive(ln, "check-pass") { check_no_run("check-pass"); @@ -693,7 +693,7 @@ impl TestProps { }; match (self.pass_mode, pass_mode) { (None, Some(_)) => self.pass_mode = pass_mode, - (Some(_), Some(_)) => panic!("multiple `*-pass` headers in a single test"), + (Some(_), Some(_)) => panic!("multiple `*-pass` directives in a single test"), (_, None) => {} } } @@ -794,7 +794,7 @@ const KNOWN_JSONDOCCK_DIRECTIVE_NAMES: &[&str] = &["count", "!count", "has", "!has", "is", "!is", "ismany", "!ismany", "set", "!set"]; /// The (partly) broken-down contents of a line containing a test directive, -/// which [`iter_header`] passes to its callback function. +/// which [`iter_directives`] passes to its callback function. /// /// For example: /// @@ -867,7 +867,7 @@ pub(crate) fn check_directive<'a>( const COMPILETEST_DIRECTIVE_PREFIX: &str = "//@"; -fn iter_header( +fn iter_directives( mode: Mode, _suite: &str, poisoned: &mut bool, @@ -1163,8 +1163,7 @@ enum NormalizeKind { Stderr64bit, } -/// Parses the regex and replacement values of a `//@ normalize-*` header, -/// in the format: +/// Parses the regex and replacement values of a `//@ normalize-*` directive, in the format: /// ```text /// "REGEX" -> "REPLACEMENT" /// ``` @@ -1373,7 +1372,7 @@ where pub(crate) fn make_test_description<R: Read>( config: &Config, - cache: &HeadersCache, + cache: &DirectivesCache, name: String, path: &Utf8Path, src: R, @@ -1387,7 +1386,7 @@ pub(crate) fn make_test_description<R: Read>( let mut local_poisoned = false; // Scan through the test file to handle `ignore-*`, `only-*`, and `needs-*` directives. - iter_header( + iter_directives( config.mode, &config.suite, &mut local_poisoned, diff --git a/src/tools/compiletest/src/header/auxiliary.rs b/src/tools/compiletest/src/directives/auxiliary.rs index 0e1f3a785f8..cdb75f6ffa9 100644 --- a/src/tools/compiletest/src/header/auxiliary.rs +++ b/src/tools/compiletest/src/directives/auxiliary.rs @@ -3,8 +3,8 @@ use std::iter; +use super::directives::{AUX_BIN, AUX_BUILD, AUX_CODEGEN_BACKEND, AUX_CRATE, PROC_MACRO}; use crate::common::Config; -use crate::header::directives::{AUX_BIN, AUX_BUILD, AUX_CODEGEN_BACKEND, AUX_CRATE, PROC_MACRO}; /// Properties parsed from `aux-*` test directives. #[derive(Clone, Debug, Default)] diff --git a/src/tools/compiletest/src/header/cfg.rs b/src/tools/compiletest/src/directives/cfg.rs index f1f1384afb9..35f6a9e1644 100644 --- a/src/tools/compiletest/src/header/cfg.rs +++ b/src/tools/compiletest/src/directives/cfg.rs @@ -1,7 +1,7 @@ use std::collections::HashSet; use crate::common::{CompareMode, Config, Debugger}; -use crate::header::IgnoreDecision; +use crate::directives::IgnoreDecision; const EXTRA_ARCHS: &[&str] = &["spirv"]; diff --git a/src/tools/compiletest/src/header/needs.rs b/src/tools/compiletest/src/directives/needs.rs index b1165f4bb18..ee46f4c70cb 100644 --- a/src/tools/compiletest/src/header/needs.rs +++ b/src/tools/compiletest/src/directives/needs.rs @@ -1,5 +1,5 @@ use crate::common::{Config, KNOWN_CRATE_TYPES, KNOWN_TARGET_HAS_ATOMIC_WIDTHS, Sanitizer}; -use crate::header::{IgnoreDecision, llvm_has_libzstd}; +use crate::directives::{IgnoreDecision, llvm_has_libzstd}; pub(super) fn handle_needs( cache: &CachedNeedsConditions, diff --git a/src/tools/compiletest/src/header/test-auxillary/error_annotation.rs b/src/tools/compiletest/src/directives/test-auxillary/error_annotation.rs index fea66a5e07b..fea66a5e07b 100644 --- a/src/tools/compiletest/src/header/test-auxillary/error_annotation.rs +++ b/src/tools/compiletest/src/directives/test-auxillary/error_annotation.rs diff --git a/src/tools/compiletest/src/header/test-auxillary/known_directive.rs b/src/tools/compiletest/src/directives/test-auxillary/known_directive.rs index 99834b14c1e..99834b14c1e 100644 --- a/src/tools/compiletest/src/header/test-auxillary/known_directive.rs +++ b/src/tools/compiletest/src/directives/test-auxillary/known_directive.rs diff --git a/src/tools/compiletest/src/header/test-auxillary/not_rs.Makefile b/src/tools/compiletest/src/directives/test-auxillary/not_rs.Makefile index 4b565e0e6df..4b565e0e6df 100644 --- a/src/tools/compiletest/src/header/test-auxillary/not_rs.Makefile +++ b/src/tools/compiletest/src/directives/test-auxillary/not_rs.Makefile diff --git a/src/tools/compiletest/src/header/test-auxillary/unknown_directive.rs b/src/tools/compiletest/src/directives/test-auxillary/unknown_directive.rs index d4406031043..d4406031043 100644 --- a/src/tools/compiletest/src/header/test-auxillary/unknown_directive.rs +++ b/src/tools/compiletest/src/directives/test-auxillary/unknown_directive.rs diff --git a/src/tools/compiletest/src/header/tests.rs b/src/tools/compiletest/src/directives/tests.rs index 31b49b09bcd..d4570f82677 100644 --- a/src/tools/compiletest/src/header/tests.rs +++ b/src/tools/compiletest/src/directives/tests.rs @@ -4,7 +4,7 @@ use camino::Utf8Path; use semver::Version; use super::{ - EarlyProps, HeadersCache, extract_llvm_version, extract_version_range, iter_header, + DirectivesCache, EarlyProps, extract_llvm_version, extract_version_range, iter_directives, parse_normalize_rule, }; use crate::common::{Config, Debugger, Mode}; @@ -17,9 +17,9 @@ fn make_test_description<R: Read>( src: R, revision: Option<&str>, ) -> CollectedTestDesc { - let cache = HeadersCache::load(config); + let cache = DirectivesCache::load(config); let mut poisoned = false; - let test = crate::header::make_test_description( + let test = crate::directives::make_test_description( config, &cache, name, @@ -785,7 +785,7 @@ fn threads_support() { fn run_path(poisoned: &mut bool, path: &Utf8Path, buf: &[u8]) { let rdr = std::io::Cursor::new(&buf); - iter_header(Mode::Ui, "ui", poisoned, path, rdr, &mut |_| {}); + iter_directives(Mode::Ui, "ui", poisoned, path, rdr, &mut |_| {}); } #[test] diff --git a/src/tools/compiletest/src/lib.rs b/src/tools/compiletest/src/lib.rs index 09de3eb4c70..dfce4b8b408 100644 --- a/src/tools/compiletest/src/lib.rs +++ b/src/tools/compiletest/src/lib.rs @@ -12,9 +12,9 @@ pub mod common; pub mod compute_diff; mod debuggers; pub mod diagnostics; +pub mod directives; pub mod errors; mod executor; -pub mod header; mod json; mod raise_fd_limit; mod read2; @@ -37,13 +37,13 @@ use rayon::iter::{ParallelBridge, ParallelIterator}; use tracing::debug; use walkdir::WalkDir; -use self::header::{EarlyProps, make_test_description}; +use self::directives::{EarlyProps, make_test_description}; use crate::common::{ CompareMode, Config, Debugger, Mode, PassMode, TestPaths, UI_EXTENSIONS, expected_output_path, output_base_dir, output_relative_path, }; +use crate::directives::DirectivesCache; use crate::executor::{CollectedTest, ColorConfig, OutputFormat}; -use crate::header::HeadersCache; use crate::util::logv; /// Creates the `Config` instance for this invocation of compiletest. @@ -254,8 +254,8 @@ pub fn parse_config(args: Vec<String>) -> Config { Some(x) => panic!("argument for --color must be auto, always, or never, but found `{}`", x), }; let llvm_version = - matches.opt_str("llvm-version").as_deref().map(header::extract_llvm_version).or_else( - || header::extract_llvm_version_from_binary(&matches.opt_str("llvm-filecheck")?), + matches.opt_str("llvm-version").as_deref().map(directives::extract_llvm_version).or_else( + || directives::extract_llvm_version_from_binary(&matches.opt_str("llvm-filecheck")?), ); let run_ignored = matches.opt_present("ignored"); @@ -618,7 +618,7 @@ pub fn run_tests(config: Arc<Config>) { /// Read-only context data used during test collection. struct TestCollectorCx { config: Arc<Config>, - cache: HeadersCache, + cache: DirectivesCache, common_inputs_stamp: Stamp, modified_tests: Vec<Utf8PathBuf>, } @@ -654,7 +654,7 @@ pub(crate) fn collect_and_make_tests(config: Arc<Config>) -> Vec<CollectedTest> modified_tests(&config, &config.src_test_suite_root).unwrap_or_else(|err| { fatal!("modified_tests: {}: {err}", config.src_test_suite_root); }); - let cache = HeadersCache::load(&config); + let cache = DirectivesCache::load(&config); let cx = TestCollectorCx { config, cache, common_inputs_stamp, modified_tests }; let collector = collect_tests_from_dir(&cx, &cx.config.src_test_suite_root, Utf8Path::new("")) diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs index 53b5990d3cd..f8bf4ee3022 100644 --- a/src/tools/compiletest/src/runtest.rs +++ b/src/tools/compiletest/src/runtest.rs @@ -23,8 +23,8 @@ use crate::common::{ output_base_dir, output_base_name, output_testname_unique, }; use crate::compute_diff::{DiffLine, make_diff, write_diff, write_filtered_diff}; +use crate::directives::TestProps; use crate::errors::{Error, ErrorKind, load_errors}; -use crate::header::TestProps; use crate::read2::{Truncated, read2_abbreviated}; use crate::util::{Utf8PathBufExt, add_dylib_path, logv, static_regex}; use crate::{ColorConfig, help, json, stamp_file_path, warning}; @@ -2039,7 +2039,7 @@ impl<'test> TestCx<'test> { // Provide more context on failures. filecheck.args(&["--dump-input-context", "100"]); - // Add custom flags supplied by the `filecheck-flags:` test header. + // Add custom flags supplied by the `filecheck-flags:` test directive. filecheck.args(&self.props.filecheck_flags); // FIXME(jieyouxu): don't pass an empty Path diff --git a/src/tools/compiletest/src/runtest/debuginfo.rs b/src/tools/compiletest/src/runtest/debuginfo.rs index 31240dff9a1..d9e1e4dfc8d 100644 --- a/src/tools/compiletest/src/runtest/debuginfo.rs +++ b/src/tools/compiletest/src/runtest/debuginfo.rs @@ -49,7 +49,7 @@ impl TestCx<'_> { std::fs::remove_file(pdb_file).unwrap(); } - // compile test file (it should have 'compile-flags:-g' in the header) + // compile test file (it should have 'compile-flags:-g' in the directive) let should_run = self.run_if_enabled(); let compile_result = self.compile_test(should_run, Emit::None); if !compile_result.status.success() { @@ -135,7 +135,7 @@ impl TestCx<'_> { .unwrap_or_else(|e| self.fatal(&e)); let mut cmds = dbg_cmds.commands.join("\n"); - // compile test file (it should have 'compile-flags:-g' in the header) + // compile test file (it should have 'compile-flags:-g' in the directive) let should_run = self.run_if_enabled(); let compiler_run_result = self.compile_test(should_run, Emit::None); if !compiler_run_result.status.success() { @@ -359,7 +359,7 @@ impl TestCx<'_> { } fn run_debuginfo_lldb_test_no_opt(&self) { - // compile test file (it should have 'compile-flags:-g' in the header) + // compile test file (it should have 'compile-flags:-g' in the directive) let should_run = self.run_if_enabled(); let compile_result = self.compile_test(should_run, Emit::None); if !compile_result.status.success() { diff --git a/src/tools/compiletest/src/runtest/ui.rs b/src/tools/compiletest/src/runtest/ui.rs index cc50a918f75..f6bc85cd051 100644 --- a/src/tools/compiletest/src/runtest/ui.rs +++ b/src/tools/compiletest/src/runtest/ui.rs @@ -52,10 +52,10 @@ impl TestCx<'_> { // don't test rustfix with nll right now } else if self.config.rustfix_coverage { // Find out which tests have `MachineApplicable` suggestions but are missing - // `run-rustfix` or `run-rustfix-only-machine-applicable` headers. + // `run-rustfix` or `run-rustfix-only-machine-applicable` directives. // // This will return an empty `Vec` in case the executed test file has a - // `compile-flags: --error-format=xxxx` header with a value other than `json`. + // `compile-flags: --error-format=xxxx` directive with a value other than `json`. let suggestions = get_suggestions_from_json( &rustfix_input, &HashSet::new(), diff --git a/src/tools/miri/src/alloc_addresses/mod.rs b/src/tools/miri/src/alloc_addresses/mod.rs index 1796120cf8a..3cc38fa087c 100644 --- a/src/tools/miri/src/alloc_addresses/mod.rs +++ b/src/tools/miri/src/alloc_addresses/mod.rs @@ -466,17 +466,10 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { Some((alloc_id, Size::from_bytes(rel_offset))) } - /// Prepare all exposed memory for a native call. - /// This overapproximates the modifications which external code might make to memory: - /// We set all reachable allocations as initialized, mark all reachable provenances as exposed - /// and overwrite them with `Provenance::WILDCARD`. - fn prepare_exposed_for_native_call(&mut self) -> InterpResult<'tcx> { - let this = self.eval_context_mut(); - // We need to make a deep copy of this list, but it's fine; it also serves as scratch space - // for the search within `prepare_for_native_call`. - let exposed: Vec<AllocId> = - this.machine.alloc_addresses.get_mut().exposed.iter().copied().collect(); - this.prepare_for_native_call(exposed) + /// Return a list of all exposed allocations. + fn exposed_allocs(&self) -> Vec<AllocId> { + let this = self.eval_context_ref(); + this.machine.alloc_addresses.borrow().exposed.iter().copied().collect() } } diff --git a/src/tools/miri/src/intrinsics/mod.rs b/src/tools/miri/src/intrinsics/mod.rs index ed1851a19ae..4efa7dd4dcf 100644 --- a/src/tools/miri/src/intrinsics/mod.rs +++ b/src/tools/miri/src/intrinsics/mod.rs @@ -457,6 +457,10 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { throw_machine_stop!(TerminationInfo::Abort(format!("trace/breakpoint trap"))) } + "assert_inhabited" | "assert_zero_valid" | "assert_mem_uninitialized_valid" => { + // Make these a NOP, so we get the better Miri-native error messages. + } + _ => return interp_ok(EmulateItemResult::NotSupported), } diff --git a/src/tools/miri/src/shims/backtrace.rs b/src/tools/miri/src/shims/backtrace.rs index dd00b270b38..18d60915d20 100644 --- a/src/tools/miri/src/shims/backtrace.rs +++ b/src/tools/miri/src/shims/backtrace.rs @@ -104,7 +104,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { this.tcx.sess.source_map().lookup_char_pos(BytePos(offset.bytes().try_into().unwrap())); let name = fn_instance.to_string(); - let filename = lo.file.name.prefer_remapped_unconditionaly().to_string(); + let filename = lo.file.name.prefer_remapped_unconditionally().to_string(); interp_ok((fn_instance, lo, name, filename)) } diff --git a/src/tools/miri/src/shims/native_lib/mod.rs b/src/tools/miri/src/shims/native_lib/mod.rs index 9c659f65e50..9b30d8ce78b 100644 --- a/src/tools/miri/src/shims/native_lib/mod.rs +++ b/src/tools/miri/src/shims/native_lib/mod.rs @@ -198,7 +198,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { let mut libffi_args = Vec::<CArg>::with_capacity(args.len()); for arg in args.iter() { if !matches!(arg.layout.backend_repr, BackendRepr::Scalar(_)) { - throw_unsup_format!("only scalar argument types are support for native calls") + throw_unsup_format!("only scalar argument types are supported for native calls") } let imm = this.read_immediate(arg)?; libffi_args.push(imm_to_carg(&imm, this)?); @@ -224,16 +224,42 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { this.expose_provenance(prov)?; } } - - // Prepare all exposed memory. - this.prepare_exposed_for_native_call()?; - - // Convert them to `libffi::high::Arg` type. + // Convert arguments to `libffi::high::Arg` type. let libffi_args = libffi_args .iter() .map(|arg| arg.arg_downcast()) .collect::<Vec<libffi::high::Arg<'_>>>(); + // Prepare all exposed memory (both previously exposed, and just newly exposed since a + // pointer was passed as argument). + this.visit_reachable_allocs(this.exposed_allocs(), |this, alloc_id, info| { + // If there is no data behind this pointer, skip this. + if !matches!(info.kind, AllocKind::LiveData) { + return interp_ok(()); + } + // It's okay to get raw access, what we do does not correspond to any actual + // AM operation, it just approximates the state to account for the native call. + let alloc = this.get_alloc_raw(alloc_id)?; + // Also expose the provenance of the interpreter-level allocation, so it can + // be read by FFI. The `black_box` is defensive programming as LLVM likes + // to (incorrectly) optimize away ptr2int casts whose result is unused. + std::hint::black_box(alloc.get_bytes_unchecked_raw().expose_provenance()); + // Expose all provenances in this allocation, since the native code can do $whatever. + for prov in alloc.provenance().provenances() { + this.expose_provenance(prov)?; + } + + // Prepare for possible write from native code if mutable. + if info.mutbl.is_mut() { + let alloc = &mut this.get_alloc_raw_mut(alloc_id)?.0; + alloc.prepare_for_native_access(); + // Also expose *mutable* provenance for the interpreter-level allocation. + std::hint::black_box(alloc.get_bytes_unchecked_raw_mut().expose_provenance()); + } + + interp_ok(()) + })?; + // Call the function and store output, depending on return type in the function signature. let (ret, maybe_memevents) = this.call_native_with_args(link_name, dest, code_ptr, libffi_args)?; @@ -321,7 +347,8 @@ fn imm_to_carg<'tcx>(v: &ImmTy<'tcx>, cx: &impl HasDataLayout) -> InterpResult<' CArg::USize(v.to_scalar().to_target_usize(cx)?.try_into().unwrap()), ty::RawPtr(..) => { let s = v.to_scalar().to_pointer(cx)?.addr(); - // This relies on the `expose_provenance` in `prepare_for_native_call`. + // This relies on the `expose_provenance` in the `visit_reachable_allocs` callback + // above. CArg::RawPtr(std::ptr::with_exposed_provenance_mut(s.bytes_usize())) } _ => throw_unsup_format!("unsupported argument type for native call: {}", v.layout.ty), diff --git a/src/tools/miri/tests/fail-dep/libc/libc-read-and-uninit-premature-eof.rs b/src/tools/miri/tests/fail-dep/libc/libc-read-and-uninit-premature-eof.rs index dd2dd346231..1dc334486c3 100644 --- a/src/tools/miri/tests/fail-dep/libc/libc-read-and-uninit-premature-eof.rs +++ b/src/tools/miri/tests/fail-dep/libc/libc-read-and-uninit-premature-eof.rs @@ -20,7 +20,7 @@ fn main() { let mut buf: MaybeUninit<[u8; 4]> = std::mem::MaybeUninit::uninit(); // Read 4 bytes from a 3-byte file. assert_eq!(libc::read(fd, buf.as_mut_ptr().cast::<std::ffi::c_void>(), 4), 3); - buf.assume_init(); //~ERROR: Undefined Behavior: constructing invalid value at .value[3]: encountered uninitialized memory, but expected an integer + buf.assume_init(); //~ERROR: encountered uninitialized memory, but expected an integer assert_eq!(libc::close(fd), 0); } remove_file(&path).unwrap(); diff --git a/src/tools/miri/tests/fail-dep/libc/libc-read-and-uninit-premature-eof.stderr b/src/tools/miri/tests/fail-dep/libc/libc-read-and-uninit-premature-eof.stderr index fadb31e3a8f..83119f087ff 100644 --- a/src/tools/miri/tests/fail-dep/libc/libc-read-and-uninit-premature-eof.stderr +++ b/src/tools/miri/tests/fail-dep/libc/libc-read-and-uninit-premature-eof.stderr @@ -1,8 +1,8 @@ -error: Undefined Behavior: constructing invalid value at .value[3]: encountered uninitialized memory, but expected an integer +error: Undefined Behavior: constructing invalid value at [3]: encountered uninitialized memory, but expected an integer --> tests/fail-dep/libc/libc-read-and-uninit-premature-eof.rs:LL:CC | -LL | ... buf.assume_init(); - | ^^^^^^^^^^^^^^^^^ Undefined Behavior occurred here +LL | buf.assume_init(); + | ^^^^^^^^^^^^^^^^^ Undefined Behavior occurred here | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information diff --git a/src/tools/miri/tests/fail/intrinsics/uninit_uninhabited_type.rs b/src/tools/miri/tests/fail/intrinsics/uninit_uninhabited_type.rs index dd3246d8120..34fef6b9ee5 100644 --- a/src/tools/miri/tests/fail/intrinsics/uninit_uninhabited_type.rs +++ b/src/tools/miri/tests/fail/intrinsics/uninit_uninhabited_type.rs @@ -1,11 +1,6 @@ -//@normalize-stderr-test: "\|.*::abort\(\).*" -> "| ABORT()" -//@normalize-stderr-test: "\| +\^+" -> "| ^" -//@normalize-stderr-test: "\n +[0-9]+:[^\n]+" -> "" -//@normalize-stderr-test: "\n +at [^\n]+" -> "" -//@error-in-other-file: aborted execution #![feature(never_type)] #[allow(deprecated, invalid_value)] fn main() { - let _ = unsafe { std::mem::uninitialized::<!>() }; + let _ = unsafe { std::mem::uninitialized::<!>() }; //~ERROR: constructing invalid value } diff --git a/src/tools/miri/tests/fail/intrinsics/uninit_uninhabited_type.stderr b/src/tools/miri/tests/fail/intrinsics/uninit_uninhabited_type.stderr index 3db8a5be205..36642208afe 100644 --- a/src/tools/miri/tests/fail/intrinsics/uninit_uninhabited_type.stderr +++ b/src/tools/miri/tests/fail/intrinsics/uninit_uninhabited_type.stderr @@ -1,27 +1,13 @@ - -thread 'main' panicked at RUSTLIB/core/src/panicking.rs:LL:CC: -aborted execution: attempted to instantiate uninhabited type `!` -note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace -note: in Miri, you may have to set `MIRIFLAGS=-Zmiri-env-forward=RUST_BACKTRACE` for the environment variable to have an effect -thread caused non-unwinding panic. aborting. -error: abnormal termination: the program aborted execution - --> RUSTLIB/std/src/sys/pal/PLATFORM/mod.rs:LL:CC - | -LL | ABORT() - | ^ abnormal termination occurred here - | - = note: BACKTRACE: - = note: inside `std::sys::pal::PLATFORM::abort_internal` at RUSTLIB/std/src/sys/pal/PLATFORM/mod.rs:LL:CC - = note: inside `std::panicking::rust_panic_with_hook` at RUSTLIB/std/src/panicking.rs:LL:CC - = note: inside closure at RUSTLIB/std/src/panicking.rs:LL:CC - = note: inside `std::sys::backtrace::__rust_end_short_backtrace::<{closure@std::panicking::begin_panic_handler::{closure#0}}, !>` at RUSTLIB/std/src/sys/backtrace.rs:LL:CC - = note: inside `std::panicking::begin_panic_handler` at RUSTLIB/std/src/panicking.rs:LL:CC - = note: inside `core::panicking::panic_nounwind` at RUSTLIB/core/src/panicking.rs:LL:CC -note: inside `main` +error: Undefined Behavior: constructing invalid value: encountered a value of the never type `!` --> tests/fail/intrinsics/uninit_uninhabited_type.rs:LL:CC | LL | let _ = unsafe { std::mem::uninitialized::<!>() }; - | ^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Undefined Behavior occurred here + | + = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior + = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information + = note: BACKTRACE: + = note: inside `main` at tests/fail/intrinsics/uninit_uninhabited_type.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/intrinsics/zero_fn_ptr.rs b/src/tools/miri/tests/fail/intrinsics/zero_fn_ptr.rs index 3d355bad626..cca2c5ae984 100644 --- a/src/tools/miri/tests/fail/intrinsics/zero_fn_ptr.rs +++ b/src/tools/miri/tests/fail/intrinsics/zero_fn_ptr.rs @@ -1,10 +1,4 @@ -//@normalize-stderr-test: "\|.*::abort\(\).*" -> "| ABORT()" -//@normalize-stderr-test: "\| +\^+" -> "| ^" -//@normalize-stderr-test: "\n +[0-9]+:[^\n]+" -> "" -//@normalize-stderr-test: "\n +at [^\n]+" -> "" -//@error-in-other-file: aborted execution - #[allow(deprecated, invalid_value)] fn main() { - let _ = unsafe { std::mem::zeroed::<fn()>() }; + let _ = unsafe { std::mem::zeroed::<fn()>() }; //~ERROR: constructing invalid value } diff --git a/src/tools/miri/tests/fail/intrinsics/zero_fn_ptr.stderr b/src/tools/miri/tests/fail/intrinsics/zero_fn_ptr.stderr index a1e476328b0..53f3f8d1404 100644 --- a/src/tools/miri/tests/fail/intrinsics/zero_fn_ptr.stderr +++ b/src/tools/miri/tests/fail/intrinsics/zero_fn_ptr.stderr @@ -1,27 +1,13 @@ - -thread 'main' panicked at RUSTLIB/core/src/panicking.rs:LL:CC: -aborted execution: attempted to zero-initialize type `fn()`, which is invalid -note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace -note: in Miri, you may have to set `MIRIFLAGS=-Zmiri-env-forward=RUST_BACKTRACE` for the environment variable to have an effect -thread caused non-unwinding panic. aborting. -error: abnormal termination: the program aborted execution - --> RUSTLIB/std/src/sys/pal/PLATFORM/mod.rs:LL:CC - | -LL | ABORT() - | ^ abnormal termination occurred here - | - = note: BACKTRACE: - = note: inside `std::sys::pal::PLATFORM::abort_internal` at RUSTLIB/std/src/sys/pal/PLATFORM/mod.rs:LL:CC - = note: inside `std::panicking::rust_panic_with_hook` at RUSTLIB/std/src/panicking.rs:LL:CC - = note: inside closure at RUSTLIB/std/src/panicking.rs:LL:CC - = note: inside `std::sys::backtrace::__rust_end_short_backtrace::<{closure@std::panicking::begin_panic_handler::{closure#0}}, !>` at RUSTLIB/std/src/sys/backtrace.rs:LL:CC - = note: inside `std::panicking::begin_panic_handler` at RUSTLIB/std/src/panicking.rs:LL:CC - = note: inside `core::panicking::panic_nounwind` at RUSTLIB/core/src/panicking.rs:LL:CC -note: inside `main` +error: Undefined Behavior: constructing invalid value: encountered a null function pointer --> tests/fail/intrinsics/zero_fn_ptr.rs:LL:CC | LL | let _ = unsafe { std::mem::zeroed::<fn()>() }; - | ^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ Undefined Behavior occurred here + | + = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior + = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information + = note: BACKTRACE: + = note: inside `main` at tests/fail/intrinsics/zero_fn_ptr.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/validity/uninit_float.stderr b/src/tools/miri/tests/fail/validity/uninit_float.stderr index 1b948b062e1..0c859d72764 100644 --- a/src/tools/miri/tests/fail/validity/uninit_float.stderr +++ b/src/tools/miri/tests/fail/validity/uninit_float.stderr @@ -1,4 +1,4 @@ -error: Undefined Behavior: constructing invalid value at .value[0]: encountered uninitialized memory, but expected a floating point number +error: Undefined Behavior: constructing invalid value at [0]: encountered uninitialized memory, but expected a floating point number --> tests/fail/validity/uninit_float.rs:LL:CC | LL | let _val: [f32; 1] = unsafe { std::mem::uninitialized() }; diff --git a/src/tools/miri/tests/fail/validity/uninit_integer.stderr b/src/tools/miri/tests/fail/validity/uninit_integer.stderr index b17bdee65da..5d31e2659ee 100644 --- a/src/tools/miri/tests/fail/validity/uninit_integer.stderr +++ b/src/tools/miri/tests/fail/validity/uninit_integer.stderr @@ -1,4 +1,4 @@ -error: Undefined Behavior: constructing invalid value at .value[0]: encountered uninitialized memory, but expected an integer +error: Undefined Behavior: constructing invalid value at [0]: encountered uninitialized memory, but expected an integer --> tests/fail/validity/uninit_integer.rs:LL:CC | LL | let _val = unsafe { std::mem::MaybeUninit::<[usize; 1]>::uninit().assume_init() }; diff --git a/src/tools/miri/tests/fail/validity/uninit_raw_ptr.stderr b/src/tools/miri/tests/fail/validity/uninit_raw_ptr.stderr index 269af6061c2..d2e9408adbe 100644 --- a/src/tools/miri/tests/fail/validity/uninit_raw_ptr.stderr +++ b/src/tools/miri/tests/fail/validity/uninit_raw_ptr.stderr @@ -1,4 +1,4 @@ -error: Undefined Behavior: constructing invalid value at .value[0]: encountered uninitialized memory, but expected a raw pointer +error: Undefined Behavior: constructing invalid value at [0]: encountered uninitialized memory, but expected a raw pointer --> tests/fail/validity/uninit_raw_ptr.rs:LL:CC | LL | let _val = unsafe { std::mem::MaybeUninit::<[*const u8; 1]>::uninit().assume_init() }; diff --git a/src/tools/rustbook/Cargo.lock b/src/tools/rustbook/Cargo.lock index 7bf3bb195ee..aeae5b61b95 100644 --- a/src/tools/rustbook/Cargo.lock +++ b/src/tools/rustbook/Cargo.lock @@ -81,7 +81,7 @@ version = "1.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6c8bdeb6047d8983be085bab0ba1472e6dc604e7041dbf6fcd5e71523014fae9" dependencies = [ - "windows-sys", + "windows-sys 0.59.0", ] [[package]] @@ -92,7 +92,7 @@ checksum = "403f75924867bb1033c59fbf0797484329750cfbe3c4325cd33127941fabc882" dependencies = [ "anstyle", "once_cell_polyfill", - "windows-sys", + "windows-sys 0.59.0", ] [[package]] @@ -103,9 +103,9 @@ checksum = "e16d2d3311acee920a9eb8d33b8cbc1787ce4a264e85f964c2404b969bdcd487" [[package]] name = "autocfg" -version = "1.4.0" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" +checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" [[package]] name = "bincode" @@ -150,9 +150,9 @@ dependencies = [ [[package]] name = "bumpalo" -version = "3.18.1" +version = "3.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "793db76d6187cd04dff33004d8e6c9cc4e05cd330500379d2394209271b4aeee" +checksum = "46c5e41b57b8bba42a04676d81cb89e9ee8e859a1a66f80a5a72e1cb76b34d43" [[package]] name = "cc" @@ -459,12 +459,12 @@ checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" [[package]] name = "errno" -version = "0.3.12" +version = "0.3.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cea14ef9355e3beab063703aa9dab15afd25f0667c341310c1e5274bb1d0da18" +checksum = "778e2ac28f6c47af28e4907f13ffd1e1ddbd400980a9abd7c8df189bf578a5ad" dependencies = [ "libc", - "windows-sys", + "windows-sys 0.60.2", ] [[package]] @@ -746,9 +746,9 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.9.0" +version = "2.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cea70ddb795996207ad57735b50c5982d8844f38ba9ee5f1aedcfb708a2aa11e" +checksum = "fe4cd85333e22411419a0bcae1297d25e58c9443848b11dc6a86fefe8c78a661" dependencies = [ "equivalent", "hashbrown", @@ -863,9 +863,9 @@ checksum = "3e2e65a1a2e43cfcb47a895c4c8b10d1f4a61097f9f254f183aee60cad9c651d" [[package]] name = "markup5ever" -version = "0.16.1" +version = "0.16.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0a8096766c229e8c88a3900c9b44b7e06aa7f7343cc229158c3e58ef8f9973a" +checksum = "2e4cd8c02f18a011991a039855480c64d74291c5792fcc160d55d77dc4de4a39" dependencies = [ "log", "tendril", @@ -991,7 +991,7 @@ version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c8911957c4b1549ac0dc74e30db9c8b0e66ddcd6d7acc33098f4c63a64a6d7ed" dependencies = [ - "windows-sys", + "windows-sys 0.59.0", ] [[package]] @@ -1060,7 +1060,7 @@ checksum = "771b9704f8cd8b424ec747a320b30b47517a6966ba2c7da90047c16f4a962223" dependencies = [ "bstr", "normpath", - "windows-sys", + "windows-sys 0.59.0", ] [[package]] @@ -1083,7 +1083,7 @@ dependencies = [ "libc", "redox_syscall", "smallvec", - "windows-targets", + "windows-targets 0.52.6", ] [[package]] @@ -1100,9 +1100,9 @@ checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" [[package]] name = "pest" -version = "2.8.0" +version = "2.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "198db74531d58c70a361c42201efde7e2591e976d518caf7662a47dc5720e7b6" +checksum = "1db05f56d34358a8b1066f67cbb203ee3e7ed2ba674a6263a1d5ec6db2204323" dependencies = [ "memchr", "thiserror 2.0.12", @@ -1111,9 +1111,9 @@ dependencies = [ [[package]] name = "pest_derive" -version = "2.8.0" +version = "2.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d725d9cfd79e87dccc9341a2ef39d1b6f6353d68c4b33c177febbe1a402c97c5" +checksum = "bb056d9e8ea77922845ec74a1c4e8fb17e7c218cc4fc11a15c5d25e189aa40bc" dependencies = [ "pest", "pest_generator", @@ -1121,9 +1121,9 @@ dependencies = [ [[package]] name = "pest_generator" -version = "2.8.0" +version = "2.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db7d01726be8ab66ab32f9df467ae8b1148906685bbe75c82d1e65d7f5b3f841" +checksum = "87e404e638f781eb3202dc82db6760c8ae8a1eeef7fb3fa8264b2ef280504966" dependencies = [ "pest", "pest_meta", @@ -1134,11 +1134,10 @@ dependencies = [ [[package]] name = "pest_meta" -version = "2.8.0" +version = "2.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f9f832470494906d1fca5329f8ab5791cc60beb230c74815dff541cbd2b5ca0" +checksum = "edd1101f170f5903fde0914f899bb503d9ff5271d7ba76bbb70bea63690cc0d5" dependencies = [ - "once_cell", "pest", "sha2", ] @@ -1315,9 +1314,9 @@ dependencies = [ [[package]] name = "r-efi" -version = "5.2.0" +version = "5.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74765f6d916ee2faa39bc8e68e4f3ed8949b48cccdac59983d287a7cb71ce9c5" +checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f" [[package]] name = "railroad" @@ -1403,7 +1402,7 @@ dependencies = [ "errno", "libc", "linux-raw-sys", - "windows-sys", + "windows-sys 0.59.0", ] [[package]] @@ -1548,9 +1547,9 @@ checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" [[package]] name = "syn" -version = "2.0.103" +version = "2.0.104" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e4307e30089d6fd6aff212f2da3a1f9e32f3223b1f010fb09b7c95f90f3ca1e8" +checksum = "17b6f705963418cdb9927482fa304bc562ece2fdd4f616084c50b7023b435a40" dependencies = [ "proc-macro2", "quote", @@ -1598,7 +1597,7 @@ dependencies = [ "getrandom", "once_cell", "rustix", - "windows-sys", + "windows-sys 0.59.0", ] [[package]] @@ -1619,7 +1618,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "45c6481c4829e4cc63825e62c49186a34538b7b2750b73b266581ffb612fb5ed" dependencies = [ "rustix", - "windows-sys", + "windows-sys 0.59.0", ] [[package]] @@ -1894,7 +1893,7 @@ version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb" dependencies = [ - "windows-sys", + "windows-sys 0.59.0", ] [[package]] @@ -1962,7 +1961,16 @@ version = "0.59.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" dependencies = [ - "windows-targets", + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-sys" +version = "0.60.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2f500e4d28234f72040990ec9d39e3a6b950f9f22d3dba18416c35882612bcb" +dependencies = [ + "windows-targets 0.53.2", ] [[package]] @@ -1971,14 +1979,30 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" dependencies = [ - "windows_aarch64_gnullvm", - "windows_aarch64_msvc", - "windows_i686_gnu", - "windows_i686_gnullvm", - "windows_i686_msvc", - "windows_x86_64_gnu", - "windows_x86_64_gnullvm", - "windows_x86_64_msvc", + "windows_aarch64_gnullvm 0.52.6", + "windows_aarch64_msvc 0.52.6", + "windows_i686_gnu 0.52.6", + "windows_i686_gnullvm 0.52.6", + "windows_i686_msvc 0.52.6", + "windows_x86_64_gnu 0.52.6", + "windows_x86_64_gnullvm 0.52.6", + "windows_x86_64_msvc 0.52.6", +] + +[[package]] +name = "windows-targets" +version = "0.53.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c66f69fcc9ce11da9966ddb31a40968cad001c5bedeb5c2b82ede4253ab48aef" +dependencies = [ + "windows_aarch64_gnullvm 0.53.0", + "windows_aarch64_msvc 0.53.0", + "windows_i686_gnu 0.53.0", + "windows_i686_gnullvm 0.53.0", + "windows_i686_msvc 0.53.0", + "windows_x86_64_gnu 0.53.0", + "windows_x86_64_gnullvm 0.53.0", + "windows_x86_64_msvc 0.53.0", ] [[package]] @@ -1988,48 +2012,96 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" [[package]] +name = "windows_aarch64_gnullvm" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "86b8d5f90ddd19cb4a147a5fa63ca848db3df085e25fee3cc10b39b6eebae764" + +[[package]] name = "windows_aarch64_msvc" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" [[package]] +name = "windows_aarch64_msvc" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7651a1f62a11b8cbd5e0d42526e55f2c99886c77e007179efff86c2b137e66c" + +[[package]] name = "windows_i686_gnu" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" [[package]] +name = "windows_i686_gnu" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1dc67659d35f387f5f6c479dc4e28f1d4bb90ddd1a5d3da2e5d97b42d6272c3" + +[[package]] name = "windows_i686_gnullvm" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" [[package]] +name = "windows_i686_gnullvm" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ce6ccbdedbf6d6354471319e781c0dfef054c81fbc7cf83f338a4296c0cae11" + +[[package]] name = "windows_i686_msvc" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" [[package]] +name = "windows_i686_msvc" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "581fee95406bb13382d2f65cd4a908ca7b1e4c2f1917f143ba16efe98a589b5d" + +[[package]] name = "windows_x86_64_gnu" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" [[package]] +name = "windows_x86_64_gnu" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2e55b5ac9ea33f2fc1716d1742db15574fd6fc8dadc51caab1c16a3d3b4190ba" + +[[package]] name = "windows_x86_64_gnullvm" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" [[package]] +name = "windows_x86_64_gnullvm" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0a6e035dd0599267ce1ee132e51c27dd29437f63325753051e71dd9e42406c57" + +[[package]] name = "windows_x86_64_msvc" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" [[package]] +name = "windows_x86_64_msvc" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "271414315aff87387382ec3d271b52d7ae78726f5d44ac98b4f4030c91880486" + +[[package]] name = "winnow" version = "0.7.11" source = "registry+https://github.com/rust-lang/crates.io-index" diff --git a/src/tools/rustdoc-gui-test/src/main.rs b/src/tools/rustdoc-gui-test/src/main.rs index addb0af4a54..6461f38f527 100644 --- a/src/tools/rustdoc-gui-test/src/main.rs +++ b/src/tools/rustdoc-gui-test/src/main.rs @@ -4,7 +4,7 @@ use std::sync::Arc; use std::{env, fs}; use build_helper::util::try_run; -use compiletest::header::TestProps; +use compiletest::directives::TestProps; use config::Config; mod config; diff --git a/src/tools/rustdoc-gui/tester.js b/src/tools/rustdoc-gui/tester.js index ff87b76aa45..9dc32f335a8 100644 --- a/src/tools/rustdoc-gui/tester.js +++ b/src/tools/rustdoc-gui/tester.js @@ -196,7 +196,7 @@ async function main(argv) { // This is more convenient that setting fields one by one. const args = [ "--variable", "DOC_PATH", opts["doc_folder"].split("\\").join("/"), - "--enable-fail-on-js-error", "--allow-file-access-from-files", + "--allow-file-access-from-files", ]; if (opts["debug"]) { debug = true; diff --git a/src/tools/rustfmt/tests/source/let_chains.rs b/src/tools/rustfmt/tests/source/let_chains.rs index 0c4d8aa85ea..fc2a9310569 100644 --- a/src/tools/rustfmt/tests/source/let_chains.rs +++ b/src/tools/rustfmt/tests/source/let_chains.rs @@ -1,3 +1,5 @@ +// rustfmt-edition: 2024 + fn main() { if let x = x && x {} diff --git a/src/tools/rustfmt/tests/target/let_chains.rs b/src/tools/rustfmt/tests/target/let_chains.rs index 204937b4cac..4fd6048d914 100644 --- a/src/tools/rustfmt/tests/target/let_chains.rs +++ b/src/tools/rustfmt/tests/target/let_chains.rs @@ -1,3 +1,5 @@ +// rustfmt-edition: 2024 + fn main() { if let x = x && x diff --git a/src/tools/tidy/src/ext_tool_checks.rs b/src/tools/tidy/src/ext_tool_checks.rs index 4f9a20fa9e2..2904908fd43 100644 --- a/src/tools/tidy/src/ext_tool_checks.rs +++ b/src/tools/tidy/src/ext_tool_checks.rs @@ -72,6 +72,8 @@ fn check_impl( let shell_lint = lint_args.contains(&"shell:lint") || shell_all; let cpp_all = lint_args.contains(&"cpp"); let cpp_fmt = lint_args.contains(&"cpp:fmt") || cpp_all; + let spellcheck_all = lint_args.contains(&"spellcheck"); + let spellcheck_fix = lint_args.contains(&"spellcheck:fix"); let mut py_path = None; @@ -224,6 +226,27 @@ fn check_impl( shellcheck_runner(&merge_args(&cfg_args, &file_args_shc))?; } + if spellcheck_all || spellcheck_fix { + let config_path = root_path.join("typos.toml"); + // sync target files with .github/workflows/spellcheck.yml + let mut args = vec![ + "-c", + config_path.as_os_str().to_str().unwrap(), + "./compiler", + "./library", + "./src/bootstrap", + "./src/librustdoc", + ]; + + if spellcheck_all { + eprintln!("spellcheck files"); + } else if spellcheck_fix { + eprintln!("spellcheck files and fix"); + args.push("--write-changes"); + } + spellcheck_runner(&args)?; + } + Ok(()) } @@ -491,6 +514,36 @@ fn shellcheck_runner(args: &[&OsStr]) -> Result<(), Error> { if status.success() { Ok(()) } else { Err(Error::FailedCheck("shellcheck")) } } +/// Check that spellchecker is installed then run it at the given path +fn spellcheck_runner(args: &[&str]) -> Result<(), Error> { + // sync version with .github/workflows/spellcheck.yml + let expected_version = "typos-cli 1.34.0"; + match Command::new("typos").arg("--version").output() { + Ok(o) => { + let stdout = String::from_utf8_lossy(&o.stdout); + if stdout.trim() != expected_version { + return Err(Error::Version { + program: "typos", + required: expected_version, + installed: stdout.trim().to_string(), + }); + } + } + Err(e) if e.kind() == io::ErrorKind::NotFound => { + return Err(Error::MissingReq( + "typos", + "spellcheck file checks", + // sync version with .github/workflows/spellcheck.yml + Some("install tool via `cargo install typos-cli@1.34.0`".to_owned()), + )); + } + Err(e) => return Err(e.into()), + } + + let status = Command::new("typos").args(args).status()?; + if status.success() { Ok(()) } else { Err(Error::FailedCheck("typos")) } +} + /// Check git for tracked files matching an extension fn find_with_extension( root_path: &Path, diff --git a/src/tools/tidy/src/rustdoc_js.rs b/src/tools/tidy/src/rustdoc_js.rs index 720f0712ee0..5e924544f0d 100644 --- a/src/tools/tidy/src/rustdoc_js.rs +++ b/src/tools/tidy/src/rustdoc_js.rs @@ -52,8 +52,7 @@ fn get_eslint_version() -> Option<String> { } pub fn check(librustdoc_path: &Path, tools_path: &Path, src_path: &Path, bad: &mut bool) { - let eslint_version_path = - src_path.join("ci/docker/host-x86_64/mingw-check-tidy/eslint.version"); + let eslint_version_path = src_path.join("ci/docker/host-x86_64/tidy/eslint.version"); let eslint_version = match std::fs::read_to_string(&eslint_version_path) { Ok(version) => version.trim().to_string(), Err(error) => { |
