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)
})
}
_ => {
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 !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 })