about summary refs log tree commit diff
path: root/src/libsyntax/ext
diff options
context:
space:
mode:
authorZack M. Davis <code@zackmdavis.net>2017-08-22 19:22:52 -0700
committerZack M. Davis <code@zackmdavis.net>2017-09-21 21:20:23 -0700
commit35176867f62f76b9bc27267878f2d74d9c776221 (patch)
tree95f178900cce7fab2c22b61a830aa05a2faf569b /src/libsyntax/ext
parent17f56c549c35bb2cb316e5abff116e65277c7bb1 (diff)
downloadrust-35176867f62f76b9bc27267878f2d74d9c776221.tar.gz
rust-35176867f62f76b9bc27267878f2d74d9c776221.zip
only set non-ADT derive error once per attribute, not per trait
A slight eccentricity of this change is that now non-ADT-derive errors prevent
derive-macro-not-found errors from surfacing (see changes to the
gating-of-derive compile-fail tests).

Resolves #43927.
Diffstat (limited to 'src/libsyntax/ext')
-rw-r--r--src/libsyntax/ext/expand.rs18
1 files changed, 18 insertions, 0 deletions
diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs
index de9c085cc78..3a1b9342530 100644
--- a/src/libsyntax/ext/expand.rs
+++ b/src/libsyntax/ext/expand.rs
@@ -282,6 +282,24 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
                     let expansion = self.expand_invoc(invoc, ext);
                     self.collect_invocations(expansion, &[])
                 } else if let InvocationKind::Attr { attr: None, traits, item } = invoc.kind {
+                    let derive_allowed = match item {
+                        Annotatable::Item(ref item) => match item.node {
+                            ast::ItemKind::Struct(..) |
+                            ast::ItemKind::Enum(..) |
+                            ast::ItemKind::Union(..) => true,
+                            _ => false,
+                        },
+                        _ => false,
+                    };
+                    if !derive_allowed {
+                        let span = item.attrs().iter()
+                            .find(|attr| attr.check_name("derive"))
+                            .expect("`derive` attribute should exist").span;
+                        self.cx.span_err(span,
+                                         "`derive` may only be applied to structs, enums \
+                                          and unions");
+                    }
+
                     let item = item
                         .map_attrs(|mut attrs| { attrs.retain(|a| a.path != "derive"); attrs });
                     let item_with_markers =