Skip to content

Commit 96d47dc

Browse files
authored
Merge pull request #252 from Alexendoo/crate-type-re
Fix `#[proc_macros::...]` being detected as a proc macro crate
2 parents e86b241 + 9c926fc commit 96d47dc

File tree

4 files changed

+43
-15
lines changed

4 files changed

+43
-15
lines changed

src/core.rs

Lines changed: 23 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,18 @@
11
//! Basic operations useful for building a testsuite
22
33
use crate::test_result::Errored;
4-
use bstr::ByteSlice as _;
54
use color_eyre::eyre::Result;
65
use crossbeam_channel::unbounded;
76
use crossbeam_channel::Receiver;
87
use crossbeam_channel::Sender;
8+
use regex::bytes::RegexSet;
99
use std::num::NonZeroUsize;
1010
use std::path::Component;
1111
use std::path::Path;
1212
use std::path::Prefix;
1313
use std::process::Command;
1414
use std::process::Output;
15+
use std::sync::OnceLock;
1516
use std::thread;
1617

1718
pub(crate) fn run_command(cmd: &mut Command) -> Result<Output, Errored> {
@@ -53,20 +54,28 @@ pub(crate) fn strip_path_prefix<'a>(
5354

5455
impl CrateType {
5556
/// Heuristic:
56-
/// * if the file contains `#[test]`, automatically pass `--cfg test`.
57-
/// * if the file does not contain `fn main()` or `#[start]`, automatically pass `--crate-type=lib`.
58-
/// This avoids having to spam `fn main() {}` in almost every test.
57+
/// * [`CrateType::ProcMacro`] if the file contains a [proc macro attribute]
58+
/// * [`CrateType::Test`] if the file contains `#[test]`
59+
/// * [`CrateType::Bin`] if the file contains `fn main()` or `#[start]`
60+
/// * otherwise [`CrateType::Lib`]
61+
///
62+
/// [proc macro attribute]: https://doc.rust-lang.org/reference/procedural-macros.html
5963
pub fn from_file_contents(file_contents: &[u8]) -> CrateType {
60-
if file_contents.find(b"#[proc_macro").is_some() {
61-
CrateType::ProcMacro
62-
} else if file_contents.find(b"#[test]").is_some() {
63-
CrateType::Test
64-
} else if file_contents.find(b"fn main()").is_none()
65-
&& file_contents.find(b"#[start]").is_none()
66-
{
67-
CrateType::Lib
68-
} else {
69-
CrateType::Bin
64+
static RE: OnceLock<RegexSet> = OnceLock::new();
65+
let re = RE.get_or_init(|| {
66+
RegexSet::new([
67+
r"#\[proc_macro(_derive|_attribute)?[\](]",
68+
r"#\[test\]",
69+
r"fn main()|#\[start\]",
70+
])
71+
.unwrap()
72+
});
73+
74+
match re.matches(file_contents).iter().next() {
75+
Some(0) => CrateType::ProcMacro,
76+
Some(1) => CrateType::Test,
77+
Some(2) => CrateType::Bin,
78+
_ => CrateType::Lib,
7079
}
7180
}
7281
}

tests/integrations/basic/Cargo.stdout

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ running 3 tests
99
test result: ok. 3 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished
1010

1111
Building dependencies ... ok
12+
Building aux file tests/actual_tests/auxiliary/proc_macro_attr.rs ... ok
13+
tests/actual_tests/aux_attr_proc_macro.rs ... ok
1214
Building aux file tests/actual_tests/auxiliary/derive_proc_macro.rs ... ok
1315
tests/actual_tests/aux_derive.fixed ... ok
1416
tests/actual_tests/aux_derive.rs ... ok
@@ -42,7 +44,7 @@ tests/actual_tests/unicode.rs ... ok
4244
tests/actual_tests/windows_paths.rs ... ok
4345
tests/actual_tests/subdir/aux_proc_macro.rs ... ok
4446

45-
test result: ok. 30 passed;
47+
test result: ok. 31 passed;
4648

4749

4850
running 0 tests
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
//@aux-build:proc_macro_attr.rs
2+
//@check-pass
3+
4+
extern crate proc_macro_attr;
5+
6+
#[proc_macro_attr::passthrough]
7+
pub fn f() {}
8+
9+
pub fn g() {}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
extern crate proc_macro;
2+
3+
use proc_macro::TokenStream;
4+
5+
#[proc_macro_attribute]
6+
pub fn passthrough(_: TokenStream, item: TokenStream) -> TokenStream {
7+
item
8+
}

0 commit comments

Comments
 (0)