about summary refs log tree commit diff
path: root/src/libsyntax/parse/parser.rs
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2015-03-12 20:13:23 +0000
committerbors <bors@rust-lang.org>2015-03-12 20:13:23 +0000
commitc9b03c24ec346e6405883032094f47805ef9c43e (patch)
treecbb2bb6a0cd2a2e65b2cacd87d31bd8737f02e7d /src/libsyntax/parse/parser.rs
parent538840bc2d1b634a2a34b2c8bd72d99894058b66 (diff)
parent9da918548d77182ca64f375fb6da24036d5ad60c (diff)
downloadrust-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/parser.rs')
-rw-r--r--src/libsyntax/parse/parser.rs155
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)