diff options
| author | Eric Huss <eric@huss.org> | 2024-11-24 09:08:07 -0800 |
|---|---|---|
| committer | Eric Huss <eric@huss.org> | 2024-11-27 06:01:46 -0800 |
| commit | f592dd95dbfc892c1153af67e0ab5b4e593d33e7 (patch) | |
| tree | 75ac3f2405ef41a8033d1a9cdb1374f1a0b08c75 | |
| parent | 39cb3386ddc6c71657418be28dbb3987eea4aa4b (diff) | |
| download | rust-f592dd95dbfc892c1153af67e0ab5b4e593d33e7.tar.gz rust-f592dd95dbfc892c1153af67e0ab5b4e593d33e7.zip | |
Compiletest: Add proc-macro header
This adds a proc-macro header to make it easier to depend on a proc-macro, and remove some of the boilerplate necessary.
| -rw-r--r-- | src/tools/compiletest/src/directive-list.rs | 1 | ||||
| -rw-r--r-- | src/tools/compiletest/src/header.rs | 1 | ||||
| -rw-r--r-- | src/tools/compiletest/src/header/auxiliary.rs | 11 | ||||
| -rw-r--r-- | src/tools/compiletest/src/runtest.rs | 76 |
4 files changed, 66 insertions, 23 deletions
diff --git a/src/tools/compiletest/src/directive-list.rs b/src/tools/compiletest/src/directive-list.rs index 0c47ef871d2..952533e904c 100644 --- a/src/tools/compiletest/src/directive-list.rs +++ b/src/tools/compiletest/src/directive-list.rs @@ -215,6 +215,7 @@ const KNOWN_DIRECTIVE_NAMES: &[&str] = &[ "pp-exact", "pretty-compare-only", "pretty-mode", + "proc-macro", "reference", "regex-error-pattern", "remap-src-base", diff --git a/src/tools/compiletest/src/header.rs b/src/tools/compiletest/src/header.rs index e945797647e..fe4c5fdd8b5 100644 --- a/src/tools/compiletest/src/header.rs +++ b/src/tools/compiletest/src/header.rs @@ -221,6 +221,7 @@ mod directives { pub const AUX_BIN: &'static str = "aux-bin"; pub const AUX_BUILD: &'static str = "aux-build"; pub const AUX_CRATE: &'static str = "aux-crate"; + pub const PROC_MACRO: &'static str = "proc-macro"; pub const AUX_CODEGEN_BACKEND: &'static str = "aux-codegen-backend"; pub const EXEC_ENV: &'static str = "exec-env"; pub const RUSTC_ENV: &'static str = "rustc-env"; diff --git a/src/tools/compiletest/src/header/auxiliary.rs b/src/tools/compiletest/src/header/auxiliary.rs index 6f6538ce196..0e1f3a785f8 100644 --- a/src/tools/compiletest/src/header/auxiliary.rs +++ b/src/tools/compiletest/src/header/auxiliary.rs @@ -4,7 +4,7 @@ use std::iter; use crate::common::Config; -use crate::header::directives::{AUX_BIN, AUX_BUILD, AUX_CODEGEN_BACKEND, AUX_CRATE}; +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)] @@ -17,6 +17,8 @@ pub(crate) struct AuxProps { /// Similar to `builds`, but a list of NAME=somelib.rs of dependencies /// to build and pass with the `--extern` flag. pub(crate) crates: Vec<(String, String)>, + /// Same as `builds`, but for proc-macros. + pub(crate) proc_macros: Vec<String>, /// Similar to `builds`, but also uses the resulting dylib as a /// `-Zcodegen-backend` when compiling the test file. pub(crate) codegen_backend: Option<String>, @@ -26,12 +28,13 @@ impl AuxProps { /// Yields all of the paths (relative to `./auxiliary/`) that have been /// specified in `aux-*` directives for this test. pub(crate) fn all_aux_path_strings(&self) -> impl Iterator<Item = &str> { - let Self { builds, bins, crates, codegen_backend } = self; + let Self { builds, bins, crates, proc_macros, codegen_backend } = self; iter::empty() .chain(builds.iter().map(String::as_str)) .chain(bins.iter().map(String::as_str)) .chain(crates.iter().map(|(_, path)| path.as_str())) + .chain(proc_macros.iter().map(String::as_str)) .chain(codegen_backend.iter().map(String::as_str)) } } @@ -39,13 +42,15 @@ impl AuxProps { /// If the given test directive line contains an `aux-*` directive, parse it /// and update [`AuxProps`] accordingly. pub(super) fn parse_and_update_aux(config: &Config, ln: &str, aux: &mut AuxProps) { - if !ln.starts_with("aux-") { + if !(ln.starts_with("aux-") || ln.starts_with("proc-macro")) { return; } config.push_name_value_directive(ln, AUX_BUILD, &mut aux.builds, |r| r.trim().to_string()); config.push_name_value_directive(ln, AUX_BIN, &mut aux.bins, |r| r.trim().to_string()); config.push_name_value_directive(ln, AUX_CRATE, &mut aux.crates, parse_aux_crate); + config + .push_name_value_directive(ln, PROC_MACRO, &mut aux.proc_macros, |r| r.trim().to_string()); if let Some(r) = config.parse_name_value_directive(ln, AUX_CODEGEN_BACKEND) { aux.codegen_backend = Some(r.trim().to_owned()); } diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs index bc80c8246ad..93e5980f1f5 100644 --- a/src/tools/compiletest/src/runtest.rs +++ b/src/tools/compiletest/src/runtest.rs @@ -102,7 +102,7 @@ fn get_lib_name(name: &str, aux_type: AuxType) -> Option<String> { // In this case, the only path we can pass // with '--extern-meta' is the '.rlib' file AuxType::Lib => Some(format!("lib{name}.rlib")), - AuxType::Dylib => Some(dylib_name(name)), + AuxType::Dylib | AuxType::ProcMacro => Some(dylib_name(name)), } } @@ -1097,7 +1097,9 @@ impl<'test> TestCx<'test> { } fn has_aux_dir(&self) -> bool { - !self.props.aux.builds.is_empty() || !self.props.aux.crates.is_empty() + !self.props.aux.builds.is_empty() + || !self.props.aux.crates.is_empty() + || !self.props.aux.proc_macros.is_empty() } fn aux_output_dir(&self) -> PathBuf { @@ -1118,31 +1120,48 @@ impl<'test> TestCx<'test> { fn build_all_auxiliary(&self, of: &TestPaths, aux_dir: &Path, rustc: &mut Command) { for rel_ab in &self.props.aux.builds { - self.build_auxiliary(of, rel_ab, &aux_dir, false /* is_bin */); + self.build_auxiliary(of, rel_ab, &aux_dir, None); } for rel_ab in &self.props.aux.bins { - self.build_auxiliary(of, rel_ab, &aux_dir, true /* is_bin */); + self.build_auxiliary(of, rel_ab, &aux_dir, Some(AuxType::Bin)); } + let path_to_crate_name = |path: &str| -> String { + path.rsplit_once('/') + .map_or(path, |(_, tail)| tail) + .trim_end_matches(".rs") + .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.display(), + lib_name + )); + } + }; + for (aux_name, aux_path) in &self.props.aux.crates { - let aux_type = self.build_auxiliary(of, &aux_path, &aux_dir, false /* is_bin */); - let lib_name = - get_lib_name(&aux_path.trim_end_matches(".rs").replace('-', "_"), aux_type); - if let Some(lib_name) = lib_name { - rustc.arg("--extern").arg(format!( - "{}={}/{}", - aux_name, - aux_dir.display(), - lib_name - )); - } + let aux_type = self.build_auxiliary(of, &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)); + let crate_name = path_to_crate_name(proc_macro); + add_extern(rustc, &crate_name, proc_macro, AuxType::ProcMacro); } // 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, false); + let aux_type = self.build_auxiliary(of, 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.display())); @@ -1209,17 +1228,23 @@ impl<'test> TestCx<'test> { } /// Builds an aux dependency. + /// + /// If `aux_type` is `None`, then this will determine the aux-type automatically. fn build_auxiliary( &self, of: &TestPaths, source_path: &str, aux_dir: &Path, - is_bin: bool, + aux_type: Option<AuxType>, ) -> AuxType { let aux_testpaths = self.compute_aux_test_paths(of, source_path); - let aux_props = self.props.from_aux_file(&aux_testpaths.file, self.revision, self.config); + let mut aux_props = + self.props.from_aux_file(&aux_testpaths.file, self.revision, self.config); + if aux_type == Some(AuxType::ProcMacro) { + aux_props.force_host = true; + } let mut aux_dir = aux_dir.to_path_buf(); - if is_bin { + if aux_type == Some(AuxType::Bin) { // On unix, the binary of `auxiliary/foo.rs` will be named // `auxiliary/foo` which clashes with the _dir_ `auxiliary/foo`, so // put bins in a `bin` subfolder. @@ -1250,8 +1275,12 @@ impl<'test> TestCx<'test> { aux_rustc.env_remove(key); } - let (aux_type, crate_type) = if is_bin { + let (aux_type, crate_type) = if aux_type == Some(AuxType::Bin) { (AuxType::Bin, Some("bin")) + } else if aux_type == Some(AuxType::ProcMacro) { + (AuxType::ProcMacro, Some("proc-macro")) + } else if aux_type.is_some() { + panic!("aux_type {aux_type:?} not expected"); } else if aux_props.no_prefer_dynamic { (AuxType::Dylib, None) } else if self.config.target.contains("emscripten") @@ -1287,6 +1316,11 @@ impl<'test> TestCx<'test> { aux_rustc.args(&["--crate-type", crate_type]); } + if aux_type == AuxType::ProcMacro { + // For convenience, but this only works on 2018. + aux_rustc.args(&["--extern", "proc_macro"]); + } + aux_rustc.arg("-L").arg(&aux_dir); let auxres = aux_cx.compose_and_run( @@ -2768,8 +2802,10 @@ enum LinkToAux { No, } +#[derive(Debug, PartialEq)] enum AuxType { Bin, Lib, Dylib, + ProcMacro, } |
