diff --git a/compiler/rustc_expand/src/base.rs b/compiler/rustc_expand/src/base.rs index 35ddb1fb9bc..196a774355e 100644 --- a/compiler/rustc_expand/src/base.rs +++ b/compiler/rustc_expand/src/base.rs @@ -141,6 +141,9 @@ impl Annotatable { } crate fn into_tokens(self, sess: &ParseSess) -> TokenStream { + // Tokens of an attribute target may be invalidated by some outer `#[derive]` performing + // "full configuration" (attributes following derives on the same item should be the most + // common case), that's why synthesizing tokens is allowed. nt_to_tokenstream(&self.into_nonterminal(), sess, CanSynthesizeMissingTokens::Yes) } diff --git a/src/test/ui/derives/derive-renamed.rs b/src/test/ui/derives/derive-renamed.rs new file mode 100644 index 00000000000..d310e5806c5 --- /dev/null +++ b/src/test/ui/derives/derive-renamed.rs @@ -0,0 +1,11 @@ +// check-pass +// edition:2018 + +use derive as my_derive; + +#[my_derive(Debug)] +struct S; + +fn main() { + println!("{:?}", S); // OK +} diff --git a/src/test/ui/proc-macro/attribute-after-derive-feature-gate.rs b/src/test/ui/proc-macro/attribute-after-derive-feature-gate.rs index 74751a23d79..f0fec678242 100644 --- a/src/test/ui/proc-macro/attribute-after-derive-feature-gate.rs +++ b/src/test/ui/proc-macro/attribute-after-derive-feature-gate.rs @@ -25,4 +25,13 @@ struct S3 { field: [u8; #[identity_attr] 10], //~ ERROR macro attributes in `#[derive]` output are unstable } +#[derive(Empty)] +struct S4 { + field: [u8; { + #[derive(Empty)] // OK, not gated + struct Inner; + 10 + }] +} + fn main() {} diff --git a/src/test/ui/proc-macro/derive-helper-legacy-limits.rs b/src/test/ui/proc-macro/derive-helper-legacy-limits.rs new file mode 100644 index 00000000000..ca904900da0 --- /dev/null +++ b/src/test/ui/proc-macro/derive-helper-legacy-limits.rs @@ -0,0 +1,21 @@ +// Support for legacy derive helpers is limited and heuristic-based +// (that's exactly the reason why they are deprecated). + +// edition:2018 +// aux-build:test-macros.rs + +#[macro_use] +extern crate test_macros; + +use derive as my_derive; + +#[my_derive(Empty)] +#[empty_helper] // OK +struct S1; + +// Legacy helper detection doesn't see through `derive` renaming. +#[empty_helper] //~ ERROR cannot find attribute `empty_helper` in this scope +#[my_derive(Empty)] +struct S2; + +fn main() {} diff --git a/src/test/ui/proc-macro/derive-helper-legacy-limits.stderr b/src/test/ui/proc-macro/derive-helper-legacy-limits.stderr new file mode 100644 index 00000000000..186f38a00f9 --- /dev/null +++ b/src/test/ui/proc-macro/derive-helper-legacy-limits.stderr @@ -0,0 +1,8 @@ +error: cannot find attribute `empty_helper` in this scope + --> $DIR/derive-helper-legacy-limits.rs:17:3 + | +LL | #[empty_helper] + | ^^^^^^^^^^^^ + +error: aborting due to previous error +