diff --git a/src/doc/rustc-dev-guide/src/tests/compiletest.md b/src/doc/rustc-dev-guide/src/tests/compiletest.md index d69e0a5ce988a..b212675d3fcfc 100644 --- a/src/doc/rustc-dev-guide/src/tests/compiletest.md +++ b/src/doc/rustc-dev-guide/src/tests/compiletest.md @@ -655,7 +655,9 @@ to link to the extern crate to make the crate be available as an extern prelude. That allows you to specify the additional syntax of the `--extern` flag, such as renaming a dependency. For example, `//@ aux-crate:foo=bar.rs` will compile `auxiliary/bar.rs` and make it available under then name `foo` within the test. -This is similar to how Cargo does dependency renaming. +This is similar to how Cargo does dependency renaming. It is also possible to +specify [`--extern` modifiers](https://github.com/rust-lang/rust/issues/98405). +For example, `//@ aux-crate:noprelude:foo=bar.rs`. `aux-bin` is similar to `aux-build` but will build a binary instead of a library. The binary will be available in `auxiliary/bin` relative to the working diff --git a/src/doc/rustc-dev-guide/src/tests/directives.md b/src/doc/rustc-dev-guide/src/tests/directives.md index ae341599f15ad..81c421bc92c44 100644 --- a/src/doc/rustc-dev-guide/src/tests/directives.md +++ b/src/doc/rustc-dev-guide/src/tests/directives.md @@ -53,14 +53,14 @@ Directives can generally be found by browsing the See [Building auxiliary crates](compiletest.html#building-auxiliary-crates) -| Directive | Explanation | Supported test suites | Possible values | -|-----------------------|-------------------------------------------------------------------------------------------------------|----------------------------------------|-----------------------------------------------| -| `aux-bin` | Build a aux binary, made available in `auxiliary/bin` relative to test directory | All except `run-make`/`run-make-cargo` | Path to auxiliary `.rs` file | -| `aux-build` | Build a separate crate from the named source file | All except `run-make`/`run-make-cargo` | Path to auxiliary `.rs` file | -| `aux-crate` | Like `aux-build` but makes available as extern prelude | All except `run-make`/`run-make-cargo` | `=` | -| `aux-codegen-backend` | Similar to `aux-build` but pass the compiled dylib to `-Zcodegen-backend` when building the main file | `ui-fulldeps` | Path to codegen backend file | -| `proc-macro` | Similar to `aux-build`, but for aux forces host and don't use `-Cprefer-dynamic`[^pm]. | All except `run-make`/`run-make-cargo` | Path to auxiliary proc-macro `.rs` file | -| `build-aux-docs` | Build docs for auxiliaries as well. Note that this only works with `aux-build`, not `aux-crate`. | All except `run-make`/`run-make-cargo` | N/A | +| Directive | Explanation | Supported test suites | Possible values | +|-----------------------|-------------------------------------------------------------------------------------------------------|----------------------------------------|--------------------------------------------------------------------| +| `aux-bin` | Build a aux binary, made available in `auxiliary/bin` relative to test directory | All except `run-make`/`run-make-cargo` | Path to auxiliary `.rs` file | +| `aux-build` | Build a separate crate from the named source file | All except `run-make`/`run-make-cargo` | Path to auxiliary `.rs` file | +| `aux-crate` | Like `aux-build` but makes available as extern prelude | All except `run-make`/`run-make-cargo` | `[:]=` | +| `aux-codegen-backend` | Similar to `aux-build` but pass the compiled dylib to `-Zcodegen-backend` when building the main file | `ui-fulldeps` | Path to codegen backend file | +| `proc-macro` | Similar to `aux-build`, but for aux forces host and don't use `-Cprefer-dynamic`[^pm]. | All except `run-make`/`run-make-cargo` | Path to auxiliary proc-macro `.rs` file | +| `build-aux-docs` | Build docs for auxiliaries as well. Note that this only works with `aux-build`, not `aux-crate`. | All except `run-make`/`run-make-cargo` | N/A | [^pm]: please see the [Auxiliary proc-macro section](compiletest.html#auxiliary-proc-macro) in the compiletest chapter for specifics. diff --git a/src/tools/compiletest/src/directives/auxiliary.rs b/src/tools/compiletest/src/directives/auxiliary.rs index 1b72931949c54..1d5b7926a8e34 100644 --- a/src/tools/compiletest/src/directives/auxiliary.rs +++ b/src/tools/compiletest/src/directives/auxiliary.rs @@ -6,12 +6,20 @@ use std::iter; use super::directives::{AUX_BIN, AUX_BUILD, AUX_CODEGEN_BACKEND, AUX_CRATE, PROC_MACRO}; use crate::common::Config; use crate::directives::DirectiveLine; +use crate::util::static_regex; + +#[cfg(test)] +mod tests; /// The value of an `aux-crate` directive. -#[derive(Clone, Debug, Default)] +#[derive(Clone, Debug, Default, PartialEq, Eq)] pub struct AuxCrate { + /// Contains `--extern` modifiers, if any. See the tracking issue for more + /// info: + /// With `aux-crate: noprelude:foo=bar.rs` this will be `noprelude`. + pub extern_modifiers: Option, /// With `aux-crate: foo=bar.rs` this will be `foo`. - /// With `aux-crate: noprelude:foo=bar.rs` this will be `noprelude:foo`. + /// With `aux-crate: noprelude:foo=bar.rs` this will be `foo`. pub name: String, /// With `aux-crate: foo=bar.rs` this will be `bar.rs`. pub path: String, @@ -74,9 +82,20 @@ pub(super) fn parse_and_update_aux( } fn parse_aux_crate(r: String) -> AuxCrate { - let mut parts = r.trim().splitn(2, '='); - AuxCrate { - name: parts.next().expect("missing aux-crate name (e.g. log=log.rs)").to_string(), - path: parts.next().expect("missing aux-crate value (e.g. log=log.rs)").to_string(), - } + let r = r.trim(); + + // Matches: + // name=path + // modifiers:name=path + let caps = static_regex!(r"^(?:(?[^=]*?):)?(?[^=]*)=(?.*)$") + .captures(r) + .unwrap_or_else(|| { + panic!("couldn't parse aux-crate value `{r}` (should be e.g. `log=log.rs`)") + }); + + let modifiers = caps.name("modifiers").map(|m| m.as_str().to_string()); + let name = caps["name"].to_string(); + let path = caps["path"].to_string(); + + AuxCrate { extern_modifiers: modifiers, name, path } } diff --git a/src/tools/compiletest/src/directives/auxiliary/tests.rs b/src/tools/compiletest/src/directives/auxiliary/tests.rs new file mode 100644 index 0000000000000..ad205eaabfda2 --- /dev/null +++ b/src/tools/compiletest/src/directives/auxiliary/tests.rs @@ -0,0 +1,27 @@ +use super::*; + +#[test] +fn test_aux_crate_value_no_modifiers() { + assert_eq!( + AuxCrate { extern_modifiers: None, name: "foo".to_string(), path: "foo.rs".to_string() }, + parse_aux_crate("foo=foo.rs".to_string()) + ); +} + +#[test] +fn test_aux_crate_value_with_modifiers() { + assert_eq!( + AuxCrate { + extern_modifiers: Some("noprelude".to_string()), + name: "foo".to_string(), + path: "foo.rs".to_string() + }, + parse_aux_crate("noprelude:foo=foo.rs".to_string()) + ); +} + +#[test] +#[should_panic(expected = "couldn't parse aux-crate value `foo.rs` (should be e.g. `log=log.rs`)")] +fn test_aux_crate_value_invalid() { + parse_aux_crate("foo.rs".to_string()); +} diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs index 901ce8421ebf4..dfbe84d5da721 100644 --- a/src/tools/compiletest/src/runtest.rs +++ b/src/tools/compiletest/src/runtest.rs @@ -1277,23 +1277,36 @@ impl<'test> TestCx<'test> { .replace('-', "_") }; - let add_extern = - |rustc: &mut Command, aux_name: &str, aux_path: &str, aux_type: AuxType| { - let lib_name = get_lib_name(&path_to_crate_name(aux_path), aux_type); - if let Some(lib_name) = lib_name { - rustc.arg("--extern").arg(format!("{}={}/{}", aux_name, aux_dir, lib_name)); - } - }; + let add_extern = |rustc: &mut Command, + extern_modifiers: Option<&str>, + aux_name: &str, + aux_path: &str, + aux_type: AuxType| { + let lib_name = get_lib_name(&path_to_crate_name(aux_path), aux_type); + if let Some(lib_name) = lib_name { + let modifiers_and_name = match extern_modifiers { + Some(modifiers) => format!("{modifiers}:{aux_name}"), + None => aux_name.to_string(), + }; + rustc.arg("--extern").arg(format!("{modifiers_and_name}={aux_dir}/{lib_name}")); + } + }; - for AuxCrate { name, path } in &self.props.aux.crates { + for AuxCrate { extern_modifiers, name, path } in &self.props.aux.crates { let aux_type = self.build_auxiliary(&path, &aux_dir, None); - add_extern(rustc, name, path, aux_type); + add_extern(rustc, extern_modifiers.as_deref(), name, path, aux_type); } for proc_macro in &self.props.aux.proc_macros { 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); + add_extern( + rustc, + None, // `extern_modifiers` + &crate_name, + proc_macro, + AuxType::ProcMacro, + ); } // Build any `//@ aux-codegen-backend`, and pass the resulting library