diff --git a/Cargo.lock b/Cargo.lock index 505263c645..215dd627cc 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1158,6 +1158,15 @@ dependencies = [ [[package]] name = "proc_macro_test" version = "0.0.0" +dependencies = [ + "cargo_metadata", + "proc_macro_test_impl", + "toolchain", +] + +[[package]] +name = "proc_macro_test_impl" +version = "0.0.0" [[package]] name = "profile" diff --git a/Cargo.toml b/Cargo.toml index 32ba3923bb..4d6908fa93 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,7 @@ [workspace] resolver = "2" members = ["xtask/", "lib/*", "crates/*"] +exclude = ["crates/proc_macro_test/imp"] [profile.dev] # Disabling debug info speeds up builds a bunch, diff --git a/crates/proc_macro_srv/src/tests/utils.rs b/crates/proc_macro_srv/src/tests/utils.rs index 2e950c1132..2c093aa0ad 100644 --- a/crates/proc_macro_srv/src/tests/utils.rs +++ b/crates/proc_macro_srv/src/tests/utils.rs @@ -7,35 +7,8 @@ use proc_macro_api::ListMacrosTask; use std::str::FromStr; pub mod fixtures { - use cargo_metadata::Message; - use std::path::PathBuf; - use std::process::Command; - - // Use current project metadata to get the proc-macro dylib path pub fn proc_macro_test_dylib_path() -> std::path::PathBuf { - let name = "proc_macro_test"; - let version = "0.0.0"; - let command = Command::new(toolchain::cargo()) - .args(&["check", "--tests", "--message-format", "json"]) - .output() - .unwrap() - .stdout; - - for message in Message::parse_stream(command.as_slice()) { - match message.unwrap() { - Message::CompilerArtifact(artifact) => { - if artifact.target.kind.contains(&"proc-macro".to_string()) { - let repr = format!("{} {}", name, version); - if artifact.package_id.repr.starts_with(&repr) { - return PathBuf::from(&artifact.filenames[0]); - } - } - } - _ => (), // Unknown message - } - } - - panic!("No proc-macro dylib for {} found!", name); + proc_macro_test::PROC_MACRO_TEST_LOCATION.into() } } diff --git a/crates/proc_macro_test/Cargo.toml b/crates/proc_macro_test/Cargo.toml index 753443be29..1a88e361e8 100644 --- a/crates/proc_macro_test/Cargo.toml +++ b/crates/proc_macro_test/Cargo.toml @@ -8,4 +8,8 @@ publish = false [lib] doctest = false -proc-macro = true + +[build-dependencies] +proc_macro_test_impl = { path = "imp", version = "0.0.0" } +toolchain = { path = "../toolchain", version = "0.0.0" } +cargo_metadata = "0.13" diff --git a/crates/proc_macro_test/build.rs b/crates/proc_macro_test/build.rs new file mode 100644 index 0000000000..4653a93dde --- /dev/null +++ b/crates/proc_macro_test/build.rs @@ -0,0 +1,48 @@ +//! This will build the proc macro in `imp`, and copy the resulting dylib artifact into the +//! `OUT_DIR`. +//! +//! `proc_macro_test` itself contains only a path to that artifact. + +use std::{ + env, fs, + path::{Path, PathBuf}, + process::Command, +}; + +use cargo_metadata::Message; + +fn main() { + let out_dir = env::var_os("OUT_DIR").unwrap(); + let out_dir = Path::new(&out_dir); + + let name = "proc_macro_test_impl"; + let version = "0.0.0"; + let output = Command::new(toolchain::cargo()) + .current_dir("imp") + .args(&["build", "-p", "proc_macro_test_impl", "--message-format", "json"]) + .output() + .unwrap(); + assert!(output.status.success()); + + let mut artifact_path = None; + for message in Message::parse_stream(output.stdout.as_slice()) { + match message.unwrap() { + Message::CompilerArtifact(artifact) => { + if artifact.target.kind.contains(&"proc-macro".to_string()) { + let repr = format!("{} {}", name, version); + if artifact.package_id.repr.starts_with(&repr) { + artifact_path = Some(PathBuf::from(&artifact.filenames[0])); + } + } + } + _ => (), // Unknown message + } + } + + let src_path = artifact_path.expect("no dylib for proc_macro_test_impl found"); + let dest_path = out_dir.join(src_path.file_name().unwrap()); + fs::copy(src_path, &dest_path).unwrap(); + + let info_path = out_dir.join("proc_macro_test_location.txt"); + fs::write(info_path, dest_path.to_str().unwrap()).unwrap(); +} diff --git a/crates/proc_macro_test/imp/.gitignore b/crates/proc_macro_test/imp/.gitignore new file mode 100644 index 0000000000..2c96eb1b65 --- /dev/null +++ b/crates/proc_macro_test/imp/.gitignore @@ -0,0 +1,2 @@ +target/ +Cargo.lock diff --git a/crates/proc_macro_test/imp/Cargo.toml b/crates/proc_macro_test/imp/Cargo.toml new file mode 100644 index 0000000000..1c2e754017 --- /dev/null +++ b/crates/proc_macro_test/imp/Cargo.toml @@ -0,0 +1,17 @@ +[package] +name = "proc_macro_test_impl" +version = "0.0.0" +license = "MIT OR Apache-2.0" +authors = ["rust-analyzer developers"] +edition = "2018" +publish = false + +[lib] +doctest = false +proc-macro = true + +[workspace] + +[dependencies] +# this crate should not have any dependencies, since it uses its own workspace, +# and its own `Cargo.lock` diff --git a/crates/proc_macro_test/imp/src/lib.rs b/crates/proc_macro_test/imp/src/lib.rs new file mode 100644 index 0000000000..4b26d24721 --- /dev/null +++ b/crates/proc_macro_test/imp/src/lib.rs @@ -0,0 +1,48 @@ +//! Exports a few trivial procedural macros for testing. + +use proc_macro::TokenStream; + +#[proc_macro] +pub fn fn_like_noop(args: TokenStream) -> TokenStream { + args +} + +#[proc_macro] +pub fn fn_like_panic(args: TokenStream) -> TokenStream { + panic!("fn_like_panic!({})", args); +} + +#[proc_macro] +pub fn fn_like_error(args: TokenStream) -> TokenStream { + format!("compile_error!(\"fn_like_error!({})\");", args).parse().unwrap() +} + +#[proc_macro_attribute] +pub fn attr_noop(_args: TokenStream, item: TokenStream) -> TokenStream { + item +} + +#[proc_macro_attribute] +pub fn attr_panic(args: TokenStream, item: TokenStream) -> TokenStream { + panic!("#[attr_panic {}] {}", args, item); +} + +#[proc_macro_attribute] +pub fn attr_error(args: TokenStream, item: TokenStream) -> TokenStream { + format!("compile_error!(\"#[attr_error({})] {}\");", args, item).parse().unwrap() +} + +#[proc_macro_derive(DeriveEmpty)] +pub fn derive_empty(_item: TokenStream) -> TokenStream { + TokenStream::new() +} + +#[proc_macro_derive(DerivePanic)] +pub fn derive_panic(item: TokenStream) -> TokenStream { + panic!("#[derive(DerivePanic)] {}", item); +} + +#[proc_macro_derive(DeriveError)] +pub fn derive_error(item: TokenStream) -> TokenStream { + format!("compile_error!(\"#[derive(DeriveError)] {}\");", item).parse().unwrap() +} diff --git a/crates/proc_macro_test/src/lib.rs b/crates/proc_macro_test/src/lib.rs index 4b26d24721..2edf23a634 100644 --- a/crates/proc_macro_test/src/lib.rs +++ b/crates/proc_macro_test/src/lib.rs @@ -1,48 +1,4 @@ //! Exports a few trivial procedural macros for testing. -use proc_macro::TokenStream; - -#[proc_macro] -pub fn fn_like_noop(args: TokenStream) -> TokenStream { - args -} - -#[proc_macro] -pub fn fn_like_panic(args: TokenStream) -> TokenStream { - panic!("fn_like_panic!({})", args); -} - -#[proc_macro] -pub fn fn_like_error(args: TokenStream) -> TokenStream { - format!("compile_error!(\"fn_like_error!({})\");", args).parse().unwrap() -} - -#[proc_macro_attribute] -pub fn attr_noop(_args: TokenStream, item: TokenStream) -> TokenStream { - item -} - -#[proc_macro_attribute] -pub fn attr_panic(args: TokenStream, item: TokenStream) -> TokenStream { - panic!("#[attr_panic {}] {}", args, item); -} - -#[proc_macro_attribute] -pub fn attr_error(args: TokenStream, item: TokenStream) -> TokenStream { - format!("compile_error!(\"#[attr_error({})] {}\");", args, item).parse().unwrap() -} - -#[proc_macro_derive(DeriveEmpty)] -pub fn derive_empty(_item: TokenStream) -> TokenStream { - TokenStream::new() -} - -#[proc_macro_derive(DerivePanic)] -pub fn derive_panic(item: TokenStream) -> TokenStream { - panic!("#[derive(DerivePanic)] {}", item); -} - -#[proc_macro_derive(DeriveError)] -pub fn derive_error(item: TokenStream) -> TokenStream { - format!("compile_error!(\"#[derive(DeriveError)] {}\");", item).parse().unwrap() -} +pub static PROC_MACRO_TEST_LOCATION: &str = + include_str!(concat!(env!("OUT_DIR"), "/proc_macro_test_location.txt"));