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 =
if self.cx.current_expansion.depth > self.cx.ecfg.recursion_limit {
let info = self.cx.current_expansion.mark.expn_info().unwrap();
let suggested_limit = self.cx.ecfg.recursion_limit * 2;
- let mut err = self.cx.struct_span_fatal(info.call_site,
+ let mut err = self.cx.struct_span_err(info.call_site,
&format!("recursion limit reached while expanding the macro `{}`",
info.callee.name()));
err.help(&format!(
match *ext {
ProcMacroDerive(ref ext, _) => {
invoc.expansion_data.mark.set_expn_info(expn_info);
- let span = Span { ctxt: self.cx.backtrace(), ..span };
+ let span = span.with_ctxt(self.cx.backtrace());
let dummy = ast::MetaItem { // FIXME(jseyfried) avoid this
name: keywords::Invalid.name(),
span: DUMMY_SP,
BuiltinDerive(func) => {
expn_info.callee.allow_internal_unstable = true;
invoc.expansion_data.mark.set_expn_info(expn_info);
- let span = Span { ctxt: self.cx.backtrace(), ..span };
+ let span = span.with_ctxt(self.cx.backtrace());
let mut items = Vec::new();
func(self.cx, span, &attr.meta().unwrap(), &item, &mut |a| items.push(a));
kind.expect_from_annotatables(items)
Ok(expansion) => expansion,
Err(mut err) => {
err.emit();
+ self.cx.trace_macros_diag();
return kind.dummy(span);
}
};
if self.token != token::Eof {
let msg = format!("macro expansion ignores token `{}` and any following",
self.this_token_to_string());
- let mut def_site_span = self.span;
- def_site_span.ctxt = SyntaxContext::empty(); // Avoid emitting backtrace info twice.
+ // Avoid emitting backtrace info twice.
+ let def_site_span = self.span.with_ctxt(SyntaxContext::empty());
let mut err = self.diagnostic().struct_span_err(def_site_span, &msg);
let msg = format!("caused by the macro expansion here; the usage \
of `{}!` is likely invalid in {} context",
macro_path, kind_name);
err.span_note(span, &msg).emit();
- self.cx.trace_macros_diag();
}
}
}
ident
}
- fn new_span(&mut self, mut span: Span) -> Span {
- span.ctxt = span.ctxt.apply_mark(self.0);
- span
+ fn new_span(&mut self, span: Span) -> Span {
+ span.with_ctxt(span.ctxt().apply_mark(self.0))
}
fn fold_mac(&mut self, mac: ast::Mac) -> ast::Mac {