diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index cc3a7dc095bd25136e3b1ab9ed890a2661d5b627..e0c94dffb5cae342603ddb9cf1fcdc6e9e9dc777 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -3246,6 +3246,7 @@ fn check_expected_item(p: &mut Parser, found_attrs: bool) { } else if is_ident(&self.token) && !token::is_any_keyword(&self.token) && self.look_ahead(1, |t| *t == token::NOT) { + // it's a macro invocation: check_expected_item(self, !item_attrs.is_empty()); @@ -4021,7 +4022,7 @@ fn parse_item_fn(&mut self, fn_style: FnStyle, abi: abi::Abi) -> ItemInfo { } /// 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>) -> Gc { let next_attrs = self.parse_outer_attributes(); let attrs = match already_parsed_attrs { @@ -4031,22 +4032,50 @@ fn parse_method(&mut self, let lo = self.span.lo; - 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() - }); + // code copied from parse_macro_use_or_failure... abstraction! + let (method_, hi, new_attrs) = { + if !token::is_any_keyword(&self.token) + && self.look_ahead(1, |t| *t == token::NOT) + && (self.look_ahead(2, |t| *t == token::LPAREN) + || 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(); - let hi = body.span.hi; - let attrs = attrs.append(inner_attrs.as_slice()); + // eat a matched-delimiter token tree: + let tts = match token::close_delimiter_for(&self.token) { + 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 { - attrs: attrs, + attrs: new_attrs, id: ast::DUMMY_NODE_ID, span: mk_sp(lo, hi), - node: ast::MethDecl(ident, generics, explicit_self, fn_style, decl, body, visa), + node: method_, } }