fn resolve_macro_invocation(&mut self, invoc: &Invocation, invoc_id: Mark, force: bool)
-> Result<Option<Lrc<SyntaxExtension>>, Indeterminate> {
let (path, kind, derives_in_scope, after_derive) = match invoc.kind {
- InvocationKind::Attr { attr: None, .. } =>
- return Ok(None),
- InvocationKind::Attr { attr: Some(ref attr), ref traits, after_derive, .. } =>
- (&attr.path, MacroKind::Attr, traits.clone(), after_derive),
+ InvocationKind::Attr { ref attr, ref derives, after_derive, .. } =>
+ (&attr.path, MacroKind::Attr, derives.clone(), after_derive),
InvocationKind::Bang { ref mac, .. } =>
(&mac.node.path, MacroKind::Bang, Vec::new(), false),
InvocationKind::Derive { ref path, .. } =>
(path, MacroKind::Derive, Vec::new(), false),
+ InvocationKind::DeriveContainer { .. } =>
+ return Ok(None),
};
let parent_scope = self.invoc_parent_scope(invoc_id, derives_in_scope);
span: Span,
},
Attr {
- attr: Option<ast::Attribute>,
- traits: Vec<Path>,
+ attr: ast::Attribute,
item: Annotatable,
+ // Required for resolving derive helper attributes.
+ derives: Vec<Path>,
// We temporarily report errors for attribute macros placed after derives
after_derive: bool,
},
item: Annotatable,
item_with_markers: Annotatable,
},
+ /// "Invocation" that contains all derives from an item,
+ /// broken into multiple `Derive` invocations when expanded.
+ /// FIXME: Find a way to remove it.
+ DeriveContainer {
+ derives: Vec<Path>,
+ item: Annotatable,
+ },
}
impl Invocation {
pub fn span(&self) -> Span {
- match self.kind {
- InvocationKind::Bang { span, .. } => span,
- InvocationKind::Attr { attr: Some(ref attr), .. } => attr.span,
- InvocationKind::Attr { attr: None, .. } => DUMMY_SP,
- InvocationKind::Derive { ref path, .. } => path.span,
+ match &self.kind {
+ InvocationKind::Bang { span, .. } => *span,
+ InvocationKind::Attr { attr, .. } => attr.span,
+ InvocationKind::Derive { path, .. } => path.span,
+ InvocationKind::DeriveContainer { item, .. } => item.span(),
}
}
}
let (expanded_fragment, new_invocations) = if let Some(ext) = ext {
let fragment = self.expand_invoc(invoc, &ext.kind);
self.collect_invocations(fragment, &[])
- } else if let InvocationKind::Attr { attr: None, traits, item, .. } = invoc.kind {
+ } else if let InvocationKind::DeriveContainer { derives: traits, item } = invoc.kind {
if !item.derive_allowed() {
let attr = attr::find_by_name(item.attrs(), sym::derive)
.expect("`derive` attribute should exist");
}
_ => unreachable!()
}
- InvocationKind::Attr { attr: Some(attr), mut item, .. } => match ext {
+ InvocationKind::Attr { attr, mut item, .. } => match ext {
SyntaxExtensionKind::Attr(expander) => {
self.gate_proc_macro_attr_item(span, &item);
let item_tok = TokenTree::token(token::Interpolated(Lrc::new(match item {
}
_ => unreachable!()
}
- _ => unreachable!()
+ InvocationKind::DeriveContainer { .. } => unreachable!()
}
}
impl<'a, 'b> InvocationCollector<'a, 'b> {
fn collect(&mut self, fragment_kind: AstFragmentKind, kind: InvocationKind) -> AstFragment {
// Expansion info for all the collected invocations is set upon their resolution,
- // with exception of the "derive container" case which is not resolved and can get
+ // with exception of the derive container case which is not resolved and can get
// its expansion info immediately.
let expn_info = match &kind {
- InvocationKind::Attr { attr: None, item, .. } => Some(ExpnInfo::default(
+ InvocationKind::DeriveContainer { item, .. } => Some(ExpnInfo::default(
ExpnKind::Macro(MacroKind::Attr, sym::derive),
item.span(), self.cx.parse_sess.edition,
)),
fn collect_attr(&mut self,
attr: Option<ast::Attribute>,
- traits: Vec<Path>,
+ derives: Vec<Path>,
item: Annotatable,
kind: AstFragmentKind,
after_derive: bool)
-> AstFragment {
- self.collect(kind, InvocationKind::Attr { attr, traits, item, after_derive })
+ self.collect(kind, match attr {
+ Some(attr) => InvocationKind::Attr { attr, item, derives, after_derive },
+ None => InvocationKind::DeriveContainer { derives, item },
+ })
}
fn find_attr_invoc(&self, attrs: &mut Vec<ast::Attribute>, after_derive: &mut bool)