about summary refs log tree commit diff
path: root/src/libsyntax/ext
diff options
context:
space:
mode:
authorZack M. Davis <code@zackmdavis.net>2017-09-21 20:29:29 -0700
committerZack M. Davis <code@zackmdavis.net>2017-09-21 21:20:31 -0700
commit083f053294b062e12bacfea17a07f83e1b4c3732 (patch)
treee6a5bee5c9d9085fd2638dcab4e01907a8695ada /src/libsyntax/ext
parent35176867f62f76b9bc27267878f2d74d9c776221 (diff)
downloadrust-083f053294b062e12bacfea17a07f83e1b4c3732.tar.gz
rust-083f053294b062e12bacfea17a07f83e1b4c3732.zip
suggest an outer attribute when `#![derive(...)]` (predictably) fails
Diffstat (limited to 'src/libsyntax/ext')
-rw-r--r--src/libsyntax/ext/base.rs4
-rw-r--r--src/libsyntax/ext/expand.rs18
2 files changed, 17 insertions, 5 deletions
diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs
index c139cfeaebf..0e05cce35e2 100644
--- a/src/libsyntax/ext/base.rs
+++ b/src/libsyntax/ext/base.rs
@@ -783,6 +783,10 @@ impl<'a> ExtCtxt<'a> {
     pub fn span_err(&self, sp: Span, msg: &str) {
         self.parse_sess.span_diagnostic.span_err(sp, msg);
     }
+    pub fn mut_span_err(&self, sp: Span, msg: &str)
+                        -> DiagnosticBuilder<'a> {
+        self.parse_sess.span_diagnostic.mut_span_err(sp, msg)
+    }
     pub fn span_warn(&self, sp: Span, msg: &str) {
         self.parse_sess.span_diagnostic.span_warn(sp, msg);
     }
diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs
index 3a1b9342530..5deb4c3cc00 100644
--- a/src/libsyntax/ext/expand.rs
+++ b/src/libsyntax/ext/expand.rs
@@ -292,12 +292,20 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
                         _ => false,
                     };
                     if !derive_allowed {
-                        let span = item.attrs().iter()
+                        let attr = 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");
+                            .expect("`derive` attribute should exist");
+                        let span = attr.span;
+                        let mut err = self.cx.mut_span_err(span,
+                                                           "`derive` may only be applied to \
+                                                            structs, enums and unions");
+                        if let ast::AttrStyle::Inner = attr.style {
+                            let trait_list = traits.iter()
+                                .map(|t| format!("{}", t)).collect::<Vec<_>>();
+                            let suggestion = format!("#[derive({})]", trait_list.join(", "));
+                            err.span_suggestion(span, "try an outer attribute", suggestion);
+                        }
+                        err.emit();
                     }
 
                     let item = item