compiletest: Make aux-crate directive explicitly handle --extern modifiers

To make it clearer what happens. In other words, do not silently keep
modifiers as part of `AuxCrate::name`.
This commit is contained in:
Martin Nordholts 2026-01-19 05:25:31 +01:00
parent 9aaa581fe8
commit 6f767b6860
3 changed files with 76 additions and 17 deletions

View file

@ -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: <https://github.com/rust-lang/rust/issues/98405>
/// With `aux-crate: noprelude:foo=bar.rs` this will be `noprelude`.
pub extern_modifiers: Option<String>,
/// 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"^(?:(?<modifiers>[^=]*?):)?(?<name>[^=]*)=(?<path>.*)$")
.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 }
}

View file

@ -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());
}

View file

@ -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