macro in method position parsing
This commit is contained in:
parent
6ee2155fe0
commit
6c8bb5a68a
1 changed files with 42 additions and 13 deletions
|
@ -3246,6 +3246,7 @@ impl<'a> Parser<'a> {
|
||||||
} else if is_ident(&self.token)
|
} else if is_ident(&self.token)
|
||||||
&& !token::is_any_keyword(&self.token)
|
&& !token::is_any_keyword(&self.token)
|
||||||
&& self.look_ahead(1, |t| *t == token::NOT) {
|
&& self.look_ahead(1, |t| *t == token::NOT) {
|
||||||
|
// it's a macro invocation:
|
||||||
|
|
||||||
check_expected_item(self, !item_attrs.is_empty());
|
check_expected_item(self, !item_attrs.is_empty());
|
||||||
|
|
||||||
|
@ -4021,7 +4022,7 @@ impl<'a> Parser<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Parse a method in a trait impl, starting with `attrs` attributes.
|
/// Parse a method in a trait impl, starting with `attrs` attributes.
|
||||||
fn parse_method(&mut self,
|
pub fn parse_method(&mut self,
|
||||||
already_parsed_attrs: Option<Vec<Attribute>>) -> Gc<Method> {
|
already_parsed_attrs: Option<Vec<Attribute>>) -> Gc<Method> {
|
||||||
let next_attrs = self.parse_outer_attributes();
|
let next_attrs = self.parse_outer_attributes();
|
||||||
let attrs = match already_parsed_attrs {
|
let attrs = match already_parsed_attrs {
|
||||||
|
@ -4031,22 +4032,50 @@ impl<'a> Parser<'a> {
|
||||||
|
|
||||||
let lo = self.span.lo;
|
let lo = self.span.lo;
|
||||||
|
|
||||||
let visa = self.parse_visibility();
|
// code copied from parse_macro_use_or_failure... abstraction!
|
||||||
let fn_style = self.parse_fn_style();
|
let (method_, hi, new_attrs) = {
|
||||||
let ident = self.parse_ident();
|
if !token::is_any_keyword(&self.token)
|
||||||
let generics = self.parse_generics();
|
&& self.look_ahead(1, |t| *t == token::NOT)
|
||||||
let (explicit_self, decl) = self.parse_fn_decl_with_self(|p| {
|
&& (self.look_ahead(2, |t| *t == token::LPAREN)
|
||||||
p.parse_arg()
|
|| self.look_ahead(2, |t| *t == token::LBRACE)) {
|
||||||
});
|
// method macro.
|
||||||
|
let pth = self.parse_path(NoTypesAllowed).path;
|
||||||
|
self.expect(&token::NOT);
|
||||||
|
|
||||||
let (inner_attrs, body) = self.parse_inner_attrs_and_block();
|
// eat a matched-delimiter token tree:
|
||||||
let hi = body.span.hi;
|
let tts = match token::close_delimiter_for(&self.token) {
|
||||||
let attrs = attrs.append(inner_attrs.as_slice());
|
Some(ket) => {
|
||||||
|
self.bump();
|
||||||
|
self.parse_seq_to_end(&ket,
|
||||||
|
seq_sep_none(),
|
||||||
|
|p| p.parse_token_tree())
|
||||||
|
}
|
||||||
|
None => self.fatal("expected open delimiter")
|
||||||
|
};
|
||||||
|
let m_ = ast::MacInvocTT(pth, tts, EMPTY_CTXT);
|
||||||
|
let m: ast::Mac = codemap::Spanned { node: m_,
|
||||||
|
span: mk_sp(self.span.lo,
|
||||||
|
self.span.hi) };
|
||||||
|
(ast::MethMac(m), self.span.hi, attrs)
|
||||||
|
} else {
|
||||||
|
let visa = self.parse_visibility();
|
||||||
|
let fn_style = self.parse_fn_style();
|
||||||
|
let ident = self.parse_ident();
|
||||||
|
let generics = self.parse_generics();
|
||||||
|
let (explicit_self, decl) = self.parse_fn_decl_with_self(|p| {
|
||||||
|
p.parse_arg()
|
||||||
|
});
|
||||||
|
let (inner_attrs, body) = self.parse_inner_attrs_and_block();
|
||||||
|
let new_attrs = attrs.append(inner_attrs.as_slice());
|
||||||
|
(ast::MethDecl(ident, generics, explicit_self, fn_style, decl, body, visa),
|
||||||
|
body.span.hi, new_attrs)
|
||||||
|
}
|
||||||
|
};
|
||||||
box(GC) ast::Method {
|
box(GC) ast::Method {
|
||||||
attrs: attrs,
|
attrs: new_attrs,
|
||||||
id: ast::DUMMY_NODE_ID,
|
id: ast::DUMMY_NODE_ID,
|
||||||
span: mk_sp(lo, hi),
|
span: mk_sp(lo, hi),
|
||||||
node: ast::MethDecl(ident, generics, explicit_self, fn_style, decl, body, visa),
|
node: method_,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue