From 083f053294b062e12bacfea17a07f83e1b4c3732 Mon Sep 17 00:00:00 2001 From: "Zack M. Davis" Date: Thu, 21 Sep 2017 20:29:29 -0700 Subject: suggest an outer attribute when `#![derive(...)]` (predictably) fails --- src/libsyntax/ext/base.rs | 4 ++++ src/libsyntax/ext/expand.rs | 18 +++++++++++++----- 2 files changed, 17 insertions(+), 5 deletions(-) (limited to 'src/libsyntax/ext') 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::>(); + let suggestion = format!("#[derive({})]", trait_list.join(", ")); + err.span_suggestion(span, "try an outer attribute", suggestion); + } + err.emit(); } let item = item -- cgit 1.4.1-3-g733a5