Skip to content

Commit 787bee6

Browse files
committed
Auto merge of #6256 - ehuss:proc-macro-crate-type, r=alexcrichton
Treat "proc-macro" crate type the same as `proc-macro = true` Effectively closes #5310 since they are now identical.
2 parents 0eee76e + b0e767f commit 787bee6

File tree

3 files changed

+167
-1
lines changed

3 files changed

+167
-1
lines changed

src/cargo/util/toml/mod.rs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1474,7 +1474,14 @@ impl TomlTarget {
14741474
}
14751475

14761476
fn proc_macro(&self) -> Option<bool> {
1477-
self.proc_macro.or(self.proc_macro2)
1477+
self.proc_macro.or(self.proc_macro2).or_else(|| {
1478+
if let Some(types) = self.crate_types() {
1479+
if types.contains(&"proc-macro".to_string()) {
1480+
return Some(true);
1481+
}
1482+
}
1483+
None
1484+
})
14781485
}
14791486

14801487
fn crate_types(&self) -> Option<&Vec<String>> {

src/cargo/util/toml/targets.rs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -206,6 +206,23 @@ fn clean_lib(
206206
// A plugin requires exporting plugin_registrar so a crate cannot be
207207
// both at once.
208208
let crate_types = match (lib.crate_types(), lib.plugin, lib.proc_macro()) {
209+
(Some(kinds), _, _) if kinds.contains(&"proc-macro".to_string()) => {
210+
if let Some(true) = lib.plugin {
211+
// This is a warning to retain backwards compatibility.
212+
warnings.push(format!(
213+
"proc-macro library `{}` should not specify `plugin = true`",
214+
lib.name()
215+
));
216+
}
217+
warnings.push(format!(
218+
"library `{}` should only specify `proc-macro = true` instead of setting `crate-type`",
219+
lib.name()
220+
));
221+
if kinds.len() > 1 {
222+
bail!("cannot mix `proc-macro` crate type with others");
223+
}
224+
vec![LibKind::ProcMacro]
225+
}
209226
(_, Some(true), Some(true)) => bail!("lib.plugin and lib.proc-macro cannot both be true"),
210227
(Some(kinds), _, _) => kinds.iter().map(|s| s.into()).collect(),
211228
(None, Some(true), _) => vec![LibKind::Dylib],

tests/testsuite/proc_macro.rs

Lines changed: 142 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -279,3 +279,145 @@ fn a() {
279279
.with_stdout_contains_n("test [..] ... ok", 2)
280280
.run();
281281
}
282+
283+
#[test]
284+
fn proc_macro_crate_type() {
285+
// Verify that `crate-type = ["proc-macro"]` is the same as `proc-macro = true`
286+
// and that everything, including rustdoc, works correctly.
287+
let foo = project()
288+
.file(
289+
"Cargo.toml",
290+
r#"
291+
[package]
292+
name = "foo"
293+
version = "0.1.0"
294+
[dependencies]
295+
pm = { path = "pm" }
296+
"#,
297+
)
298+
.file(
299+
"src/lib.rs",
300+
r#"
301+
//! ```
302+
//! use foo::THING;
303+
//! assert_eq!(THING, 123);
304+
//! ```
305+
#[macro_use]
306+
extern crate pm;
307+
#[derive(MkItem)]
308+
pub struct S;
309+
#[cfg(test)]
310+
mod tests {
311+
use super::THING;
312+
#[test]
313+
fn it_works() {
314+
assert_eq!(THING, 123);
315+
}
316+
}
317+
"#,
318+
)
319+
.file(
320+
"pm/Cargo.toml",
321+
r#"
322+
[package]
323+
name = "pm"
324+
version = "0.1.0"
325+
[lib]
326+
crate-type = ["proc-macro"]
327+
"#,
328+
)
329+
.file(
330+
"pm/src/lib.rs",
331+
r#"
332+
extern crate proc_macro;
333+
use proc_macro::TokenStream;
334+
335+
#[proc_macro_derive(MkItem)]
336+
pub fn mk_item(_input: TokenStream) -> TokenStream {
337+
"pub const THING: i32 = 123;".parse().unwrap()
338+
}
339+
"#,
340+
)
341+
.build();
342+
343+
foo.cargo("test")
344+
.with_stdout_contains("test tests::it_works ... ok")
345+
.with_stdout_contains_n("test [..] ... ok", 2)
346+
.run();
347+
}
348+
349+
#[test]
350+
fn proc_macro_crate_type_warning() {
351+
let foo = project()
352+
.file(
353+
"Cargo.toml",
354+
r#"
355+
[package]
356+
name = "foo"
357+
version = "0.1.0"
358+
[lib]
359+
crate-type = ["proc-macro"]
360+
"#,
361+
)
362+
.file("src/lib.rs", "")
363+
.build();
364+
365+
foo.cargo("build")
366+
.with_stderr_contains(
367+
"[WARNING] library `foo` should only specify `proc-macro = true` instead of setting `crate-type`")
368+
.run();
369+
}
370+
371+
#[test]
372+
fn proc_macro_crate_type_warning_plugin() {
373+
let foo = project()
374+
.file(
375+
"Cargo.toml",
376+
r#"
377+
[package]
378+
name = "foo"
379+
version = "0.1.0"
380+
[lib]
381+
crate-type = ["proc-macro"]
382+
plugin = true
383+
"#,
384+
)
385+
.file("src/lib.rs", "")
386+
.build();
387+
388+
foo.cargo("build")
389+
.with_stderr_contains(
390+
"[WARNING] proc-macro library `foo` should not specify `plugin = true`")
391+
.with_stderr_contains(
392+
"[WARNING] library `foo` should only specify `proc-macro = true` instead of setting `crate-type`")
393+
.run();
394+
}
395+
396+
#[test]
397+
fn proc_macro_crate_type_multiple() {
398+
let foo = project()
399+
.file(
400+
"Cargo.toml",
401+
r#"
402+
[package]
403+
name = "foo"
404+
version = "0.1.0"
405+
[lib]
406+
crate-type = ["proc-macro", "rlib"]
407+
"#,
408+
)
409+
.file("src/lib.rs", "")
410+
.build();
411+
412+
foo.cargo("build")
413+
.with_stderr(
414+
"\
415+
[ERROR] failed to parse manifest at `[..]/foo/Cargo.toml`
416+
417+
Caused by:
418+
cannot mix `proc-macro` crate type with others
419+
",
420+
)
421+
.with_status(101)
422+
.run();
423+
}

0 commit comments

Comments
 (0)