diff options
| author | bors <bors@rust-lang.org> | 2015-03-12 20:13:23 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2015-03-12 20:13:23 +0000 |
| commit | c9b03c24ec346e6405883032094f47805ef9c43e (patch) | |
| tree | cbb2bb6a0cd2a2e65b2cacd87d31bd8737f02e7d /src/libsyntax/parse | |
| parent | 538840bc2d1b634a2a34b2c8bd72d99894058b66 (diff) | |
| parent | 9da918548d77182ca64f375fb6da24036d5ad60c (diff) | |
| download | rust-c9b03c24ec346e6405883032094f47805ef9c43e.tar.gz rust-c9b03c24ec346e6405883032094f47805ef9c43e.zip | |
Auto merge of #23265 - eddyb:meth-ast-refactor, r=nikomatsakis
The end result is that common fields (id, name, attributes, etc.) are stored in now-structures `ImplItem` and `TraitItem`. The signature of a method is no longer duplicated between methods with a body (default/impl) and those without, they now share `MethodSig`. This is also a [breaking-change] because of minor bugfixes and changes to syntax extensions: * `pub fn` methods in a trait no longer parse - remove the `pub`, it has no meaning anymore * `MacResult::make_methods` is now `make_impl_items` and the return type has changed accordingly * `quote_method` is gone, because `P<ast::Method>` doesn't exist and it couldn't represent a full method anyways - could be replaced by `quote_impl_item`/`quote_trait_item` in the future, but I do hope we realize how silly that combinatorial macro expansion is and settle on a single `quote` macro + some type hints - or just no types at all (only token-trees) r? @nikomatsakis This is necessary (hopefully also sufficient) for associated constants.
Diffstat (limited to 'src/libsyntax/parse')
| -rw-r--r-- | src/libsyntax/parse/parser.rs | 155 |
1 files changed, 73 insertions, 82 deletions
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index ea413ac0dc8..39c43ff1e75 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -11,9 +11,9 @@ pub use self::PathParsingMode::*; use abi; -use ast::{AssociatedType, BareFnTy}; +use ast::{BareFnTy}; use ast::{RegionTyParamBound, TraitTyParamBound, TraitBoundModifier}; -use ast::{ProvidedMethod, Public, Unsafety}; +use ast::{Public, Unsafety}; use ast::{Mod, BiAdd, Arg, Arm, Attribute, BindByRef, BindByValue}; use ast::{BiBitAnd, BiBitOr, BiBitXor, BiRem, BiLt, BiGt, Block}; use ast::{BlockCheckMode, CaptureByRef, CaptureByValue, CaptureClause}; @@ -38,12 +38,11 @@ use ast::{LitBool, LitChar, LitByte, LitBinary}; use ast::{LitStr, LitInt, Local, LocalLet}; use ast::{MacStmtWithBraces, MacStmtWithSemicolon, MacStmtWithoutBraces}; use ast::{MutImmutable, MutMutable, Mac_, MacInvocTT, MatchSource}; -use ast::{Method, MutTy, BiMul, Mutability}; +use ast::{MutTy, BiMul, Mutability}; use ast::{MethodImplItem, NamedField, UnNeg, NoReturn, NodeId, UnNot}; use ast::{Pat, PatEnum, PatIdent, PatLit, PatRange, PatRegion, PatStruct}; use ast::{PatTup, PatBox, PatWild, PatWildMulti, PatWildSingle}; -use ast::{PolyTraitRef}; -use ast::{QSelf, RequiredMethod}; +use ast::{PolyTraitRef, QSelf}; use ast::{Return, BiShl, BiShr, Stmt, StmtDecl}; use ast::{StmtExpr, StmtSemi, StmtMac, StructDef, StructField}; use ast::{StructVariantKind, BiSub, StrStyle}; @@ -51,11 +50,10 @@ use ast::{SelfExplicit, SelfRegion, SelfStatic, SelfValue}; use ast::{Delimited, SequenceRepetition, TokenTree, TraitItem, TraitRef}; use ast::{TtDelimited, TtSequence, TtToken}; use ast::{TupleVariantKind, Ty, Ty_, TypeBinding}; -use ast::{TyFixedLengthVec, TyBareFn}; -use ast::{TyTypeof, TyInfer, TypeMethod}; +use ast::{TyFixedLengthVec, TyBareFn, TyTypeof, TyInfer}; use ast::{TyParam, TyParamBound, TyParen, TyPath, TyPolyTraitRef, TyPtr}; use ast::{TyRptr, TyTup, TyU32, TyVec, UnUniq}; -use ast::{TypeImplItem, TypeTraitItem, Typedef,}; +use ast::{TypeImplItem, TypeTraitItem}; use ast::{UnnamedField, UnsafeBlock}; use ast::{ViewPath, ViewPathGlob, ViewPathList, ViewPathSimple}; use ast::{Visibility, WhereClause}; @@ -1244,52 +1242,53 @@ impl<'a> Parser<'a> { /// Parses `type Foo;` in a trait declaration only. The `type` keyword has /// already been parsed. - fn parse_associated_type(&mut self, attrs: Vec<Attribute>) - -> AssociatedType - { - let ty_param = self.parse_ty_param(); + fn parse_assoc_ty_in_trait(&mut self, attrs: Vec<Attribute>) + -> P<TraitItem> { + let TyParam {id, ident, bounds, default, span} = self.parse_ty_param(); self.expect(&token::Semi); - AssociatedType { + P(TraitItem { + id: id, + ident: ident, attrs: attrs, - ty_param: ty_param, - } + node: TypeTraitItem(bounds, default), + span: span, + }) } /// Parses `type Foo = TYPE;` in an implementation declaration only. The /// `type` keyword has already been parsed. - fn parse_typedef(&mut self, attrs: Vec<Attribute>, vis: Visibility) - -> Typedef { + fn parse_assoc_ty_in_impl(&mut self, attrs: Vec<Attribute>, vis: Visibility) + -> P<ImplItem> { let lo = self.span.lo; let ident = self.parse_ident(); self.expect(&token::Eq); let typ = self.parse_ty_sum(); let hi = self.span.hi; self.expect(&token::Semi); - Typedef { + P(ImplItem { id: ast::DUMMY_NODE_ID, span: mk_sp(lo, hi), ident: ident, vis: vis, attrs: attrs, - typ: typ, - } + node: TypeImplItem(typ), + }) } /// Parse the items in a trait declaration - pub fn parse_trait_items(&mut self) -> Vec<TraitItem> { + pub fn parse_trait_items(&mut self) -> Vec<P<TraitItem>> { self.parse_unspanned_seq( &token::OpenDelim(token::Brace), &token::CloseDelim(token::Brace), seq_sep_none(), |p| { - let attrs = p.parse_outer_attributes(); + let mut attrs = p.parse_outer_attributes(); if p.eat_keyword(keywords::Type) { - TypeTraitItem(P(p.parse_associated_type(attrs))) + p.parse_assoc_ty_in_trait(attrs) } else { let lo = p.span.lo; - let vis = p.parse_visibility(); let style = p.parse_unsafety(); let abi = if p.eat_keyword(keywords::Extern) { p.parse_opt_abi().unwrap_or(abi::C) @@ -1309,44 +1308,27 @@ impl<'a> Parser<'a> { }); p.parse_where_clause(&mut generics); + let sig = ast::MethodSig { + unsafety: style, + decl: d, + generics: generics, + abi: abi, + explicit_self: explicit_self, + }; let hi = p.last_span.hi; - match p.token { + let body = match p.token { token::Semi => { p.bump(); debug!("parse_trait_methods(): parsing required method"); - RequiredMethod(TypeMethod { - ident: ident, - attrs: attrs, - unsafety: style, - decl: d, - generics: generics, - abi: abi, - explicit_self: explicit_self, - id: ast::DUMMY_NODE_ID, - span: mk_sp(lo, hi), - vis: vis, - }) + None } token::OpenDelim(token::Brace) => { debug!("parse_trait_methods(): parsing provided method"); let (inner_attrs, body) = p.parse_inner_attrs_and_block(); - let mut attrs = attrs; attrs.push_all(&inner_attrs[..]); - ProvidedMethod(P(ast::Method { - attrs: attrs, - id: ast::DUMMY_NODE_ID, - span: mk_sp(lo, hi), - node: ast::MethDecl(ident, - generics, - abi, - explicit_self, - style, - d, - body, - vis) - })) + Some(body) } _ => { @@ -1354,7 +1336,15 @@ impl<'a> Parser<'a> { p.fatal(&format!("expected `;` or `{{`, found `{}`", token_str)[..]) } - } + }; + + P(TraitItem { + id: ast::DUMMY_NODE_ID, + ident: ident, + attrs: attrs, + node: ast::MethodTraitItem(sig, body), + span: mk_sp(lo, hi), + }) } }) } @@ -4635,11 +4625,15 @@ impl<'a> Parser<'a> { (ident, ItemFn(decl, unsafety, abi, generics, body), Some(inner_attrs)) } - /// Parse a method in a trait impl - pub fn parse_method_with_outer_attributes(&mut self) -> P<Method> { + /// Parse an impl item. + pub fn parse_impl_item_with_outer_attributes(&mut self) -> P<ImplItem> { let attrs = self.parse_outer_attributes(); - let visa = self.parse_visibility(); - self.parse_method(attrs, visa) + let vis = self.parse_visibility(); + if self.eat_keyword(keywords::Type) { + self.parse_assoc_ty_in_impl(attrs, vis) + } else { + self.parse_method(attrs, vis) + } } fn complain_if_pub_macro(&mut self, visa: Visibility, span: Span) { @@ -4656,12 +4650,12 @@ impl<'a> Parser<'a> { /// Parse a method in a trait impl, starting with `attrs` attributes. pub fn parse_method(&mut self, attrs: Vec<Attribute>, - visa: Visibility) - -> P<Method> { + vis: Visibility) + -> P<ImplItem> { let lo = self.span.lo; // code copied from parse_macro_use_or_failure... abstraction! - let (method_, hi, new_attrs) = { + let (method_, hi, new_attrs, ident) = { if !self.token.is_any_keyword() && self.look_ahead(1, |t| *t == token::Not) && (self.look_ahead(2, |t| *t == token::OpenDelim(token::Paren)) @@ -4669,7 +4663,7 @@ impl<'a> Parser<'a> { // method macro. let last_span = self.last_span; - self.complain_if_pub_macro(visa, last_span); + self.complain_if_pub_macro(vis, last_span); let pth = self.parse_path(NoTypesAllowed); self.expect(&token::Not); @@ -4686,7 +4680,8 @@ impl<'a> Parser<'a> { if delim != token::Brace { self.expect(&token::Semi) } - (ast::MethMac(m), self.span.hi, attrs) + (ast::MacImplItem(m), self.span.hi, attrs, + token::special_idents::invalid) } else { let unsafety = self.parse_unsafety(); let abi = if self.eat_keyword(keywords::Extern) { @@ -4705,22 +4700,22 @@ impl<'a> Parser<'a> { let body_span = body.span; let mut new_attrs = attrs; new_attrs.push_all(&inner_attrs[..]); - (ast::MethDecl(ident, - generics, - abi, - explicit_self, - unsafety, - decl, - body, - visa), - body_span.hi, new_attrs) + (MethodImplItem(ast::MethodSig { + generics: generics, + abi: abi, + explicit_self: explicit_self, + unsafety: unsafety, + decl: decl + }, body), body_span.hi, new_attrs, ident) } }; - P(ast::Method { - attrs: new_attrs, + P(ImplItem { id: ast::DUMMY_NODE_ID, - span: mk_sp(lo, hi), + attrs: new_attrs, + vis: vis, + ident: ident, node: method_, + span: mk_sp(lo, hi), }) } @@ -4752,7 +4747,7 @@ impl<'a> Parser<'a> { (ident, ItemTrait(unsafety, tps, bounds, meths), None) } - fn parse_impl_items(&mut self) -> (Vec<ImplItem>, Vec<Attribute>) { + fn parse_impl_items(&mut self) -> (Vec<P<ImplItem>>, Vec<Attribute>) { let mut impl_items = Vec::new(); self.expect(&token::OpenDelim(token::Brace)); let (inner_attrs, mut method_attrs) = @@ -4764,15 +4759,11 @@ impl<'a> Parser<'a> { } let vis = self.parse_visibility(); - if self.eat_keyword(keywords::Type) { - impl_items.push(TypeImplItem(P(self.parse_typedef( - method_attrs, - vis)))) + impl_items.push(if self.eat_keyword(keywords::Type) { + self.parse_assoc_ty_in_impl(method_attrs, vis) } else { - impl_items.push(MethodImplItem(self.parse_method( - method_attrs, - vis))); - } + self.parse_method(method_attrs, vis) + }); method_attrs = vec![]; } (impl_items, inner_attrs) |
