Skip to content

Commit 6c8bb5a

Browse files
committed
macro in method position parsing
1 parent 6ee2155 commit 6c8bb5a

File tree

1 file changed

+42
-13
lines changed

1 file changed

+42
-13
lines changed

src/libsyntax/parse/parser.rs

Lines changed: 42 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3246,6 +3246,7 @@ impl<'a> Parser<'a> {
32463246
} else if is_ident(&self.token)
32473247
&& !token::is_any_keyword(&self.token)
32483248
&& self.look_ahead(1, |t| *t == token::NOT) {
3249+
// it's a macro invocation:
32493250

32503251
check_expected_item(self, !item_attrs.is_empty());
32513252

@@ -4021,7 +4022,7 @@ impl<'a> Parser<'a> {
40214022
}
40224023

40234024
/// Parse a method in a trait impl, starting with `attrs` attributes.
4024-
fn parse_method(&mut self,
4025+
pub fn parse_method(&mut self,
40254026
already_parsed_attrs: Option<Vec<Attribute>>) -> Gc<Method> {
40264027
let next_attrs = self.parse_outer_attributes();
40274028
let attrs = match already_parsed_attrs {
@@ -4031,22 +4032,50 @@ impl<'a> Parser<'a> {
40314032

40324033
let lo = self.span.lo;
40334034

4034-
let visa = self.parse_visibility();
4035-
let fn_style = self.parse_fn_style();
4036-
let ident = self.parse_ident();
4037-
let generics = self.parse_generics();
4038-
let (explicit_self, decl) = self.parse_fn_decl_with_self(|p| {
4039-
p.parse_arg()
4040-
});
4035+
// code copied from parse_macro_use_or_failure... abstraction!
4036+
let (method_, hi, new_attrs) = {
4037+
if !token::is_any_keyword(&self.token)
4038+
&& self.look_ahead(1, |t| *t == token::NOT)
4039+
&& (self.look_ahead(2, |t| *t == token::LPAREN)
4040+
|| self.look_ahead(2, |t| *t == token::LBRACE)) {
4041+
// method macro.
4042+
let pth = self.parse_path(NoTypesAllowed).path;
4043+
self.expect(&token::NOT);
40414044

4042-
let (inner_attrs, body) = self.parse_inner_attrs_and_block();
4043-
let hi = body.span.hi;
4044-
let attrs = attrs.append(inner_attrs.as_slice());
4045+
// eat a matched-delimiter token tree:
4046+
let tts = match token::close_delimiter_for(&self.token) {
4047+
Some(ket) => {
4048+
self.bump();
4049+
self.parse_seq_to_end(&ket,
4050+
seq_sep_none(),
4051+
|p| p.parse_token_tree())
4052+
}
4053+
None => self.fatal("expected open delimiter")
4054+
};
4055+
let m_ = ast::MacInvocTT(pth, tts, EMPTY_CTXT);
4056+
let m: ast::Mac = codemap::Spanned { node: m_,
4057+
span: mk_sp(self.span.lo,
4058+
self.span.hi) };
4059+
(ast::MethMac(m), self.span.hi, attrs)
4060+
} else {
4061+
let visa = self.parse_visibility();
4062+
let fn_style = self.parse_fn_style();
4063+
let ident = self.parse_ident();
4064+
let generics = self.parse_generics();
4065+
let (explicit_self, decl) = self.parse_fn_decl_with_self(|p| {
4066+
p.parse_arg()
4067+
});
4068+
let (inner_attrs, body) = self.parse_inner_attrs_and_block();
4069+
let new_attrs = attrs.append(inner_attrs.as_slice());
4070+
(ast::MethDecl(ident, generics, explicit_self, fn_style, decl, body, visa),
4071+
body.span.hi, new_attrs)
4072+
}
4073+
};
40454074
box(GC) ast::Method {
4046-
attrs: attrs,
4075+
attrs: new_attrs,
40474076
id: ast::DUMMY_NODE_ID,
40484077
span: mk_sp(lo, hi),
4049-
node: ast::MethDecl(ident, generics, explicit_self, fn_style, decl, body, visa),
4078+
node: method_,
40504079
}
40514080
}
40524081

0 commit comments

Comments
 (0)