From 21143a2c12f692f7f04ec31ef8ad66b86df86646 Mon Sep 17 00:00:00 2001 From: Zalathar Date: Mon, 27 Oct 2025 18:19:36 +1100 Subject: [PATCH 1/3] Test that auxiliaries are built against their own directives --- tests/ui/compiletest-self-test/aux-has-props.rs | 14 ++++++++++++++ .../auxiliary/aux_with_props.rs | 6 ++++++ 2 files changed, 20 insertions(+) create mode 100644 tests/ui/compiletest-self-test/aux-has-props.rs create mode 100644 tests/ui/compiletest-self-test/auxiliary/aux_with_props.rs diff --git a/tests/ui/compiletest-self-test/aux-has-props.rs b/tests/ui/compiletest-self-test/aux-has-props.rs new file mode 100644 index 0000000000000..73ec2e169f4fe --- /dev/null +++ b/tests/ui/compiletest-self-test/aux-has-props.rs @@ -0,0 +1,14 @@ +//@ edition: 2024 +//@ aux-build: aux_with_props.rs +//@ compile-flags: --check-cfg=cfg(this_is_aux) +//@ run-pass + +// Test that auxiliaries are built using the directives in the auxiliary file, +// and don't just accidentally use the directives of the main test file. + +extern crate aux_with_props; + +fn main() { + assert!(!cfg!(this_is_aux)); + assert!(aux_with_props::aux_directives_are_respected()); +} diff --git a/tests/ui/compiletest-self-test/auxiliary/aux_with_props.rs b/tests/ui/compiletest-self-test/auxiliary/aux_with_props.rs new file mode 100644 index 0000000000000..31a5a05a7144f --- /dev/null +++ b/tests/ui/compiletest-self-test/auxiliary/aux_with_props.rs @@ -0,0 +1,6 @@ +//@ edition: 2024 +//@ compile-flags: --cfg=this_is_aux + +pub fn aux_directives_are_respected() -> bool { + cfg!(this_is_aux) +} From 379f3a53a520ec1eca3750098a5ef079423a0570 Mon Sep 17 00:00:00 2001 From: Zalathar Date: Mon, 27 Oct 2025 18:50:02 +1100 Subject: [PATCH 2/3] Don't modify `testpaths` when creating aux contexts --- src/tools/compiletest/src/runtest.rs | 55 ++++++++++++---------------- 1 file changed, 23 insertions(+), 32 deletions(-) diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs index 16b604e9df821..39a8bef9b1313 100644 --- a/src/tools/compiletest/src/runtest.rs +++ b/src/tools/compiletest/src/runtest.rs @@ -18,7 +18,6 @@ use crate::common::{ CompareMode, Config, Debugger, FailMode, PassMode, RunFailMode, RunResult, TestMode, TestPaths, TestSuite, UI_EXTENSIONS, UI_FIXED, UI_RUN_STDERR, UI_RUN_STDOUT, UI_STDERR, UI_STDOUT, UI_SVG, UI_WINDOWS_SVG, expected_output_path, incremental_dir, output_base_dir, output_base_name, - output_testname_unique, }; use crate::directives::TestProps; use crate::errors::{Error, ErrorKind, load_errors}; @@ -1004,27 +1003,36 @@ impl<'test> TestCx<'test> { root_out_dir: &Utf8Path, root_testpaths: &TestPaths, kind: DocKind, + ) -> ProcRes { + self.document_inner(&self.testpaths.file, root_out_dir, root_testpaths, kind) + } + + fn document_inner( + &self, + file_to_doc: &Utf8Path, + root_out_dir: &Utf8Path, + root_testpaths: &TestPaths, + kind: DocKind, ) -> ProcRes { if self.props.build_aux_docs { assert_eq!(kind, DocKind::Html, "build-aux-docs only make sense for html output"); for rel_ab in &self.props.aux.builds { - let aux_testpaths = self.compute_aux_test_paths(root_testpaths, rel_ab); - let props_for_aux = - self.props.from_aux_file(&aux_testpaths.file, self.revision, self.config); + let aux_path = self.compute_aux_test_paths(root_testpaths, rel_ab); + let props_for_aux = self.props.from_aux_file(&aux_path, self.revision, self.config); let aux_cx = TestCx { config: self.config, stdout: self.stdout, stderr: self.stderr, props: &props_for_aux, - testpaths: &aux_testpaths, + testpaths: self.testpaths, revision: self.revision, }; // Create the directory for the stdout/stderr files. create_dir_all(aux_cx.output_base_dir()).unwrap(); // use root_testpaths here, because aux-builds should have the // same --out-dir and auxiliary directory. - let auxres = aux_cx.document(&root_out_dir, root_testpaths, kind); + let auxres = aux_cx.document_inner(&aux_path, &root_out_dir, root_testpaths, kind); if !auxres.status.success() { return auxres; } @@ -1038,7 +1046,7 @@ impl<'test> TestCx<'test> { // actual --out-dir given to the auxiliary or test, as opposed to the root out dir for the entire // test let out_dir: Cow<'_, Utf8Path> = if self.props.unique_doc_out_dir { - let file_name = self.testpaths.file.file_stem().expect("file name should not be empty"); + let file_name = file_to_doc.file_stem().expect("file name should not be empty"); let out_dir = Utf8PathBuf::from_iter([ root_out_dir, Utf8Path::new("docs"), @@ -1063,7 +1071,7 @@ impl<'test> TestCx<'test> { .arg(out_dir.as_ref()) .arg("--deny") .arg("warnings") - .arg(&self.testpaths.file) + .arg(file_to_doc) .arg("-A") .arg("internal_features") .args(&self.props.compile_flags) @@ -1195,24 +1203,14 @@ impl<'test> TestCx<'test> { /// For each `aux-build: foo/bar` annotation, we check to find the file in an `auxiliary` /// directory relative to the test itself (not any intermediate auxiliaries). - fn compute_aux_test_paths(&self, of: &TestPaths, rel_ab: &str) -> TestPaths { + fn compute_aux_test_paths(&self, of: &TestPaths, rel_ab: &str) -> Utf8PathBuf { let test_ab = of.file.parent().expect("test file path has no parent").join("auxiliary").join(rel_ab); if !test_ab.exists() { self.fatal(&format!("aux-build `{}` source not found", test_ab)) } - TestPaths { - file: test_ab, - relative_dir: of - .relative_dir - .join(self.output_testname_unique()) - .join("auxiliary") - .join(rel_ab) - .parent() - .expect("aux-build path has no parent") - .to_path_buf(), - } + test_ab } fn is_vxworks_pure_static(&self) -> bool { @@ -1369,9 +1367,8 @@ impl<'test> TestCx<'test> { aux_dir: &Utf8Path, aux_type: Option, ) -> AuxType { - let aux_testpaths = self.compute_aux_test_paths(of, source_path); - let mut aux_props = - self.props.from_aux_file(&aux_testpaths.file, self.revision, self.config); + let aux_path = self.compute_aux_test_paths(of, source_path); + let mut aux_props = self.props.from_aux_file(&aux_path, self.revision, self.config); if aux_type == Some(AuxType::ProcMacro) { aux_props.force_host = true; } @@ -1388,14 +1385,13 @@ impl<'test> TestCx<'test> { stdout: self.stdout, stderr: self.stderr, props: &aux_props, - testpaths: &aux_testpaths, + testpaths: self.testpaths, revision: self.revision, }; // Create the directory for the stdout/stderr files. create_dir_all(aux_cx.output_base_dir()).unwrap(); - let input_file = &aux_testpaths.file; let mut aux_rustc = aux_cx.make_compile_args( - input_file, + &aux_path, aux_output, Emit::None, AllowUnused::No, @@ -1471,7 +1467,7 @@ impl<'test> TestCx<'test> { ); if !auxres.status.success() { self.fatal_proc_rec( - &format!("auxiliary build of {} failed to compile: ", aux_testpaths.file), + &format!("auxiliary build of {aux_path} failed to compile: "), &auxres, ); } @@ -2033,11 +2029,6 @@ impl<'test> TestCx<'test> { self.aux_output_dir_name().join("bin") } - /// Generates a unique name for the test, such as `testname.revision.mode`. - fn output_testname_unique(&self) -> Utf8PathBuf { - output_testname_unique(self.config, self.testpaths, self.safe_revision()) - } - /// The revision, ignored for incremental compilation since it wants all revisions in /// the same directory. fn safe_revision(&self) -> Option<&str> { From a0d516a5559cff1337a624274e61f900f414f823 Mon Sep 17 00:00:00 2001 From: Zalathar Date: Mon, 27 Oct 2025 21:29:13 +1100 Subject: [PATCH 3/3] Remove some parameters that are always `self.testpaths` --- src/tools/compiletest/src/runtest.rs | 67 ++++++++----------- src/tools/compiletest/src/runtest/assembly.rs | 2 +- src/tools/compiletest/src/runtest/coverage.rs | 2 +- src/tools/compiletest/src/runtest/js_doc.rs | 2 +- src/tools/compiletest/src/runtest/rustdoc.rs | 2 +- .../compiletest/src/runtest/rustdoc_json.rs | 2 +- src/tools/compiletest/src/runtest/ui.rs | 2 +- 7 files changed, 35 insertions(+), 44 deletions(-) diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs index 39a8bef9b1313..937e886b74f0b 100644 --- a/src/tools/compiletest/src/runtest.rs +++ b/src/tools/compiletest/src/runtest.rs @@ -562,7 +562,7 @@ impl<'test> TestCx<'test> { self.maybe_add_external_args(&mut rustc, &self.config.target_rustcflags); rustc.args(&self.props.compile_flags); - self.compose_and_run_compiler(rustc, Some(src), self.testpaths) + self.compose_and_run_compiler(rustc, Some(src)) } fn maybe_add_external_args(&self, cmd: &mut Command, args: &Vec) { @@ -993,32 +993,26 @@ impl<'test> TestCx<'test> { passes, ); - self.compose_and_run_compiler(rustc, None, self.testpaths) + self.compose_and_run_compiler(rustc, None) } /// `root_out_dir` and `root_testpaths` refer to the parameters of the actual test being run. /// Auxiliaries, no matter how deep, have the same root_out_dir and root_testpaths. - fn document( - &self, - root_out_dir: &Utf8Path, - root_testpaths: &TestPaths, - kind: DocKind, - ) -> ProcRes { - self.document_inner(&self.testpaths.file, root_out_dir, root_testpaths, kind) + fn document(&self, root_out_dir: &Utf8Path, kind: DocKind) -> ProcRes { + self.document_inner(&self.testpaths.file, root_out_dir, kind) } fn document_inner( &self, file_to_doc: &Utf8Path, root_out_dir: &Utf8Path, - root_testpaths: &TestPaths, kind: DocKind, ) -> ProcRes { if self.props.build_aux_docs { assert_eq!(kind, DocKind::Html, "build-aux-docs only make sense for html output"); for rel_ab in &self.props.aux.builds { - let aux_path = self.compute_aux_test_paths(root_testpaths, rel_ab); + let aux_path = self.compute_aux_test_paths(rel_ab); let props_for_aux = self.props.from_aux_file(&aux_path, self.revision, self.config); let aux_cx = TestCx { config: self.config, @@ -1030,9 +1024,7 @@ impl<'test> TestCx<'test> { }; // Create the directory for the stdout/stderr files. create_dir_all(aux_cx.output_base_dir()).unwrap(); - // use root_testpaths here, because aux-builds should have the - // same --out-dir and auxiliary directory. - let auxres = aux_cx.document_inner(&aux_path, &root_out_dir, root_testpaths, kind); + let auxres = aux_cx.document_inner(&aux_path, &root_out_dir, kind); if !auxres.status.success() { return auxres; } @@ -1060,7 +1052,7 @@ impl<'test> TestCx<'test> { }; let mut rustdoc = Command::new(rustdoc_path); - let current_dir = output_base_dir(self.config, root_testpaths, self.safe_revision()); + let current_dir = self.output_base_dir(); rustdoc.current_dir(current_dir); rustdoc .arg("-L") @@ -1088,7 +1080,7 @@ impl<'test> TestCx<'test> { rustdoc.arg(format!("-Clinker={}", linker)); } - self.compose_and_run_compiler(rustdoc, None, root_testpaths) + self.compose_and_run_compiler(rustdoc, None) } fn exec_compiled_test(&self) -> ProcRes { @@ -1203,9 +1195,14 @@ impl<'test> TestCx<'test> { /// For each `aux-build: foo/bar` annotation, we check to find the file in an `auxiliary` /// directory relative to the test itself (not any intermediate auxiliaries). - fn compute_aux_test_paths(&self, of: &TestPaths, rel_ab: &str) -> Utf8PathBuf { - let test_ab = - of.file.parent().expect("test file path has no parent").join("auxiliary").join(rel_ab); + fn compute_aux_test_paths(&self, rel_ab: &str) -> Utf8PathBuf { + let test_ab = self + .testpaths + .file + .parent() + .expect("test file path has no parent") + .join("auxiliary") + .join(rel_ab); if !test_ab.exists() { self.fatal(&format!("aux-build `{}` source not found", test_ab)) } @@ -1256,13 +1253,13 @@ impl<'test> TestCx<'test> { aux_dir } - fn build_all_auxiliary(&self, of: &TestPaths, aux_dir: &Utf8Path, rustc: &mut Command) { + fn build_all_auxiliary(&self, aux_dir: &Utf8Path, rustc: &mut Command) { for rel_ab in &self.props.aux.builds { - self.build_auxiliary(of, rel_ab, &aux_dir, None); + self.build_auxiliary(rel_ab, &aux_dir, None); } for rel_ab in &self.props.aux.bins { - self.build_auxiliary(of, rel_ab, &aux_dir, Some(AuxType::Bin)); + self.build_auxiliary(rel_ab, &aux_dir, Some(AuxType::Bin)); } let path_to_crate_name = |path: &str| -> String { @@ -1281,12 +1278,12 @@ impl<'test> TestCx<'test> { }; for (aux_name, aux_path) in &self.props.aux.crates { - let aux_type = self.build_auxiliary(of, &aux_path, &aux_dir, None); + let aux_type = self.build_auxiliary(&aux_path, &aux_dir, None); add_extern(rustc, aux_name, aux_path, aux_type); } for proc_macro in &self.props.aux.proc_macros { - self.build_auxiliary(of, proc_macro, &aux_dir, Some(AuxType::ProcMacro)); + self.build_auxiliary(proc_macro, &aux_dir, Some(AuxType::ProcMacro)); let crate_name = path_to_crate_name(proc_macro); add_extern(rustc, &crate_name, proc_macro, AuxType::ProcMacro); } @@ -1294,7 +1291,7 @@ impl<'test> TestCx<'test> { // Build any `//@ aux-codegen-backend`, and pass the resulting library // to `-Zcodegen-backend` when compiling the test file. if let Some(aux_file) = &self.props.aux.codegen_backend { - let aux_type = self.build_auxiliary(of, aux_file, aux_dir, None); + let aux_type = self.build_auxiliary(aux_file, aux_dir, None); if let Some(lib_name) = get_lib_name(aux_file.trim_end_matches(".rs"), aux_type) { let lib_path = aux_dir.join(&lib_name); rustc.arg(format!("-Zcodegen-backend={}", lib_path)); @@ -1304,12 +1301,7 @@ impl<'test> TestCx<'test> { /// `root_testpaths` refers to the path of the original test. the auxiliary and the test with an /// aux-build have the same `root_testpaths`. - fn compose_and_run_compiler( - &self, - mut rustc: Command, - input: Option, - root_testpaths: &TestPaths, - ) -> ProcRes { + fn compose_and_run_compiler(&self, mut rustc: Command, input: Option) -> ProcRes { if self.props.add_core_stubs { let minicore_path = self.build_minicore(); rustc.arg("--extern"); @@ -1317,7 +1309,7 @@ impl<'test> TestCx<'test> { } let aux_dir = self.aux_output_dir(); - self.build_all_auxiliary(root_testpaths, &aux_dir, &mut rustc); + self.build_all_auxiliary(&aux_dir, &mut rustc); rustc.envs(self.props.rustc_env.clone()); self.props.unset_rustc_env.iter().fold(&mut rustc, Command::env_remove); @@ -1362,12 +1354,11 @@ impl<'test> TestCx<'test> { /// If `aux_type` is `None`, then this will determine the aux-type automatically. fn build_auxiliary( &self, - of: &TestPaths, source_path: &str, aux_dir: &Utf8Path, aux_type: Option, ) -> AuxType { - let aux_path = self.compute_aux_test_paths(of, source_path); + let aux_path = self.compute_aux_test_paths(source_path); let mut aux_props = self.props.from_aux_file(&aux_path, self.revision, self.config); if aux_type == Some(AuxType::ProcMacro) { aux_props.force_host = true; @@ -1398,7 +1389,7 @@ impl<'test> TestCx<'test> { LinkToAux::No, Vec::new(), ); - aux_cx.build_all_auxiliary(of, &aux_dir, &mut aux_rustc); + aux_cx.build_all_auxiliary(&aux_dir, &mut aux_rustc); aux_rustc.envs(aux_props.rustc_env.clone()); for key in &aux_props.unset_rustc_env { @@ -2123,7 +2114,7 @@ impl<'test> TestCx<'test> { Vec::new(), ); - let proc_res = self.compose_and_run_compiler(rustc, None, self.testpaths); + let proc_res = self.compose_and_run_compiler(rustc, None); (proc_res, output_path) } @@ -2201,9 +2192,9 @@ impl<'test> TestCx<'test> { Vec::new(), ); let aux_dir = new_rustdoc.aux_output_dir(); - new_rustdoc.build_all_auxiliary(&new_rustdoc.testpaths, &aux_dir, &mut rustc); + new_rustdoc.build_all_auxiliary(&aux_dir, &mut rustc); - let proc_res = new_rustdoc.document(&compare_dir, &new_rustdoc.testpaths, DocKind::Html); + let proc_res = new_rustdoc.document(&compare_dir, DocKind::Html); if !proc_res.status.success() { writeln!(self.stderr, "failed to run nightly rustdoc"); return; diff --git a/src/tools/compiletest/src/runtest/assembly.rs b/src/tools/compiletest/src/runtest/assembly.rs index 91d4f620f7194..c805b4c7a59e0 100644 --- a/src/tools/compiletest/src/runtest/assembly.rs +++ b/src/tools/compiletest/src/runtest/assembly.rs @@ -43,7 +43,7 @@ impl TestCx<'_> { Vec::new(), ); - let proc_res = self.compose_and_run_compiler(rustc, None, self.testpaths); + let proc_res = self.compose_and_run_compiler(rustc, None); (proc_res, output_path) } } diff --git a/src/tools/compiletest/src/runtest/coverage.rs b/src/tools/compiletest/src/runtest/coverage.rs index d0a0c960b4512..5b94d9567d8fc 100644 --- a/src/tools/compiletest/src/runtest/coverage.rs +++ b/src/tools/compiletest/src/runtest/coverage.rs @@ -197,7 +197,7 @@ impl<'test> TestCx<'test> { rustdoc_cmd.arg(&self.testpaths.file); - let proc_res = self.compose_and_run_compiler(rustdoc_cmd, None, self.testpaths); + let proc_res = self.compose_and_run_compiler(rustdoc_cmd, None); if !proc_res.status.success() { self.fatal_proc_rec("rustdoc --test failed!", &proc_res) } diff --git a/src/tools/compiletest/src/runtest/js_doc.rs b/src/tools/compiletest/src/runtest/js_doc.rs index 93b05617e6f8c..e7e078ff27d9e 100644 --- a/src/tools/compiletest/src/runtest/js_doc.rs +++ b/src/tools/compiletest/src/runtest/js_doc.rs @@ -7,7 +7,7 @@ impl TestCx<'_> { if let Some(nodejs) = &self.config.nodejs { let out_dir = self.output_base_dir(); - self.document(&out_dir, &self.testpaths, DocKind::Html); + self.document(&out_dir, DocKind::Html); let file_stem = self.testpaths.file.file_stem().expect("no file stem"); let res = self.run_command_to_procres( diff --git a/src/tools/compiletest/src/runtest/rustdoc.rs b/src/tools/compiletest/src/runtest/rustdoc.rs index 32b1823961bea..a4558de5f1c0c 100644 --- a/src/tools/compiletest/src/runtest/rustdoc.rs +++ b/src/tools/compiletest/src/runtest/rustdoc.rs @@ -11,7 +11,7 @@ impl TestCx<'_> { panic!("failed to remove and recreate output directory `{out_dir}`: {e}") }); - let proc_res = self.document(&out_dir, &self.testpaths, DocKind::Html); + let proc_res = self.document(&out_dir, DocKind::Html); if !proc_res.status.success() { self.fatal_proc_rec("rustdoc failed!", &proc_res); } diff --git a/src/tools/compiletest/src/runtest/rustdoc_json.rs b/src/tools/compiletest/src/runtest/rustdoc_json.rs index dd7ebe9efaeef..6cb0c2a040535 100644 --- a/src/tools/compiletest/src/runtest/rustdoc_json.rs +++ b/src/tools/compiletest/src/runtest/rustdoc_json.rs @@ -13,7 +13,7 @@ impl TestCx<'_> { panic!("failed to remove and recreate output directory `{out_dir}`: {e}") }); - let proc_res = self.document(&out_dir, &self.testpaths, DocKind::Json); + let proc_res = self.document(&out_dir, DocKind::Json); if !proc_res.status.success() { self.fatal_proc_rec("rustdoc failed!", &proc_res); } diff --git a/src/tools/compiletest/src/runtest/ui.rs b/src/tools/compiletest/src/runtest/ui.rs index d683a325c8666..2bbde95dba54c 100644 --- a/src/tools/compiletest/src/runtest/ui.rs +++ b/src/tools/compiletest/src/runtest/ui.rs @@ -249,7 +249,7 @@ impl TestCx<'_> { rustc.arg(crate_name); } - let res = self.compose_and_run_compiler(rustc, None, self.testpaths); + let res = self.compose_and_run_compiler(rustc, None); if !res.status.success() { self.fatal_proc_rec("failed to compile fixed code", &res); }