Skip to content

Commit 083f053

Browse files
committed
suggest an outer attribute when #![derive(...)] (predictably) fails
1 parent 3517686 commit 083f053

File tree

3 files changed

+18
-6
lines changed

3 files changed

+18
-6
lines changed

src/libsyntax/ext/base.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -783,6 +783,10 @@ impl<'a> ExtCtxt<'a> {
783783
pub fn span_err(&self, sp: Span, msg: &str) {
784784
self.parse_sess.span_diagnostic.span_err(sp, msg);
785785
}
786+
pub fn mut_span_err(&self, sp: Span, msg: &str)
787+
-> DiagnosticBuilder<'a> {
788+
self.parse_sess.span_diagnostic.mut_span_err(sp, msg)
789+
}
786790
pub fn span_warn(&self, sp: Span, msg: &str) {
787791
self.parse_sess.span_diagnostic.span_warn(sp, msg);
788792
}

src/libsyntax/ext/expand.rs

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -292,12 +292,20 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
292292
_ => false,
293293
};
294294
if !derive_allowed {
295-
let span = item.attrs().iter()
295+
let attr = item.attrs().iter()
296296
.find(|attr| attr.check_name("derive"))
297-
.expect("`derive` attribute should exist").span;
298-
self.cx.span_err(span,
299-
"`derive` may only be applied to structs, enums \
300-
and unions");
297+
.expect("`derive` attribute should exist");
298+
let span = attr.span;
299+
let mut err = self.cx.mut_span_err(span,
300+
"`derive` may only be applied to \
301+
structs, enums and unions");
302+
if let ast::AttrStyle::Inner = attr.style {
303+
let trait_list = traits.iter()
304+
.map(|t| format!("{}", t)).collect::<Vec<_>>();
305+
let suggestion = format!("#[derive({})]", trait_list.join(", "));
306+
err.span_suggestion(span, "try an outer attribute", suggestion);
307+
}
308+
err.emit();
301309
}
302310

303311
let item = item

src/test/ui/span/issue-43927-non-ADT-derive.stderr

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ error: `derive` may only be applied to structs, enums and unions
22
--> $DIR/issue-43927-non-ADT-derive.rs:13:1
33
|
44
13 | #![derive(Debug, PartialEq, Eq)] // should be an outer attribute!
5-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
5+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try an outer attribute: `#[derive(Debug, PartialEq, Eq)]`
66

77
error: aborting due to previous error
88

0 commit comments

Comments
 (0)