diff options
| author | Ralf Jung <post@ralfj.de> | 2025-07-03 08:56:11 +0000 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-07-03 08:56:11 +0000 |
| commit | 3c3f1e461cc6009e1dc025205e984a932bc0ab62 (patch) | |
| tree | 898ca56d1d20ea1fe27732f5f9087bdfc9235f65 /src | |
| parent | 4be7583545cdb7535f5a2f6f7adad154b4321a5c (diff) | |
| parent | 484c64b161e7387d10d94be23382decb6f9da6ba (diff) | |
Merge pull request #4440 from RalfJung/rustup
Rustup
Diffstat (limited to 'src')
52 files changed, 668 insertions, 311 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/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/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/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..4041e6dd545 100644 --- a/src/bootstrap/src/utils/change_tracker.rs +++ b/src/bootstrap/src/utils/change_tracker.rs @@ -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/ci/citool/src/jobs.rs b/src/ci/citool/src/jobs.rs index 81e002edb15..31c761d1670 100644 --- a/src/ci/citool/src/jobs.rs +++ b/src/ci/citool/src/jobs.rs @@ -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/test-jobs.yml b/src/ci/citool/tests/test-jobs.yml index d262da11102..7b349ceba3f 100644 --- a/src/ci/citool/tests/test-jobs.yml +++ b/src/ci/citool/tests/test-jobs.yml @@ -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/github-actions/jobs.yml b/src/ci/github-actions/jobs.yml index 3aa435003d3..1e253131c1a 100644 --- a/src/ci/github-actions/jobs.yml +++ b/src/ci/github-actions/jobs.yml @@ -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. 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/tools/clippy/clippy_utils/src/ast_utils/mod.rs b/src/tools/clippy/clippy_utils/src/ast_utils/mod.rs index e65914b9b5e..e6396987cc6 100644 --- a/src/tools/clippy/clippy_utils/src/ast_utils/mod.rs +++ b/src/tools/clippy/clippy_utils/src/ast_utils/mod.rs @@ -886,13 +886,13 @@ pub fn eq_generic_param(l: &GenericParam, r: &GenericParam) -> bool { ( Const { ty: lt, - kw_span: _, default: ld, + span: _, }, Const { ty: rt, - kw_span: _, default: rd, + span: _, }, ) => eq_ty(lt, rt) && both(ld.as_ref(), rd.as_ref(), eq_anon_const), _ => false, 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/rust-version b/src/tools/miri/rust-version index 18ebea64301..38f228aa8f6 100644 --- a/src/tools/miri/rust-version +++ b/src/tools/miri/rust-version @@ -1 +1 @@ -f51c9870bab634afb9e7a262b6ca7816bb9e940d +6268d0aa34b46981533b09827c1454b8cf27e032 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/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/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/rustfmt/src/spanned.rs b/src/tools/rustfmt/src/spanned.rs index 507647566d4..ac132999b62 100644 --- a/src/tools/rustfmt/src/spanned.rs +++ b/src/tools/rustfmt/src/spanned.rs @@ -122,7 +122,7 @@ impl Spanned for ast::GenericParam { fn span(&self) -> Span { let lo = match self.kind { _ if !self.attrs.is_empty() => self.attrs[0].span.lo(), - ast::GenericParamKind::Const { kw_span, .. } => kw_span.lo(), + ast::GenericParamKind::Const { span, .. } => span.lo(), _ => self.ident.span.lo(), }; let hi = if self.bounds.is_empty() { diff --git a/src/tools/rustfmt/src/types.rs b/src/tools/rustfmt/src/types.rs index dd1515805e5..c0df01edd6d 100644 --- a/src/tools/rustfmt/src/types.rs +++ b/src/tools/rustfmt/src/types.rs @@ -689,7 +689,7 @@ impl Rewrite for ast::GenericParam { let param_start = if let ast::GenericParamKind::Const { ref ty, - kw_span, + span, default, } = &self.kind { @@ -711,7 +711,7 @@ impl Rewrite for ast::GenericParam { default.rewrite_result(context, Shape::legacy(budget, shape.indent))?; param.push_str(&rewrite); } - kw_span.lo() + span.lo() } else { param.push_str(rewrite_ident(context, self.ident)); self.ident.span.lo() |
