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!(
"consider adding a `#![recursion_limit=\"{}\"]` attribute to your crate",
suggested_limit));
err.emit();
+ self.cx.trace_macros_diag();
panic!(FatalError);
}
}
ProcMacroDerive(..) | BuiltinDerive(..) => {
self.cx.span_err(attr.span, &format!("`{}` is a derive mode", attr.path));
+ self.cx.trace_macros_diag();
kind.dummy(attr.span)
}
_ => {
let msg = &format!("macro `{}` may not be used in attributes", attr.path);
self.cx.span_err(attr.span, msg);
+ self.cx.trace_macros_diag();
kind.dummy(attr.span)
}
}
if let Err(msg) = validate_and_set_expn_info(def_span.map(|(_, s)| s),
false, false) {
self.cx.span_err(path.span, &msg);
+ self.cx.trace_macros_diag();
return kind.dummy(span);
}
kind.make_from(expand.expand(self.cx, span, mac.node.stream()))
allow_internal_unstable,
allow_internal_unsafe) {
self.cx.span_err(path.span, &msg);
+ self.cx.trace_macros_diag();
return kind.dummy(span);
}
kind.make_from(expander.expand(self.cx, span, mac.node.stream()))
if ident.name == keywords::Invalid.name() {
self.cx.span_err(path.span,
&format!("macro {}! expects an ident argument", path));
+ self.cx.trace_macros_diag();
return kind.dummy(span);
};
MultiDecorator(..) | MultiModifier(..) | AttrProcMacro(..) => {
self.cx.span_err(path.span,
&format!("`{}` can only be used in attributes", path));
+ self.cx.trace_macros_diag();
return kind.dummy(span);
}
ProcMacroDerive(..) | BuiltinDerive(..) => {
self.cx.span_err(path.span, &format!("`{}` is a derive mode", path));
+ self.cx.trace_macros_diag();
return kind.dummy(span);
}
let msg =
format!("macro {}! expects no ident argument, given '{}'", path, ident);
self.cx.span_err(path.span, &msg);
+ self.cx.trace_macros_diag();
return kind.dummy(span);
}
let msg = format!("non-{kind} macro in {kind} position: {name}",
name = path.segments[0].identifier.name, kind = kind.name());
self.cx.span_err(path.span, &msg);
+ self.cx.trace_macros_diag();
kind.dummy(span)
})
}
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)
_ => {
let msg = &format!("macro `{}` may not be used for derive attributes", attr.path);
self.cx.span_err(span, msg);
+ self.cx.trace_macros_diag();
kind.dummy(span)
}
}
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",
if !traits.is_empty() &&
(kind == ExpansionKind::TraitItems || kind == ExpansionKind::ImplItems) {
self.cx.span_err(traits[0].span, "`derive` can be only be applied to items");
+ self.cx.trace_macros_diag();
return kind.expect_from_annotatables(::std::iter::once(item));
}
self.collect(kind, InvocationKind::Attr { attr: attr, traits: traits, item: item })
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 {