about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMazdak Farrokhzad <twingoow@gmail.com>2019-12-01 11:07:49 +0100
committerMazdak Farrokhzad <twingoow@gmail.com>2019-12-12 17:54:48 +0100
commit7672bff3780ef0e7ba5313bf23644465644e19e6 (patch)
tree9b7530f48523da9cfb6407ca8aed4fba155f5241
parent10270bcd30d1d85a003412e597e367f2e7c89942 (diff)
downloadrust-7672bff3780ef0e7ba5313bf23644465644e19e6.tar.gz
rust-7672bff3780ef0e7ba5313bf23644465644e19e6.zip
Unify associated function parsing.
-rw-r--r--src/librustc_parse/parser/item.rs65
-rw-r--r--src/libsyntax/ast.rs1
2 files changed, 24 insertions, 42 deletions
diff --git a/src/librustc_parse/parser/item.rs b/src/librustc_parse/parser/item.rs
index 3fc4cafc0da..32cc156783c 100644
--- a/src/librustc_parse/parser/item.rs
+++ b/src/librustc_parse/parser/item.rs
@@ -6,7 +6,7 @@ use crate::maybe_whole;
 use rustc_errors::{PResult, Applicability, DiagnosticBuilder, StashKey};
 use rustc_error_codes::*;
 use syntax::ast::{self, DUMMY_NODE_ID, Ident, Attribute, AttrKind, AttrStyle, AnonConst, Item};
-use syntax::ast::{ItemKind, ImplItem, ImplItemKind, TraitItem, TraitItemKind, UseTree, UseTreeKind};
+use syntax::ast::{ItemKind, ImplItem, TraitItem, TraitItemKind, UseTree, UseTreeKind};
 use syntax::ast::{AssocItemKind};
 use syntax::ast::{PathSegment, IsAuto, Constness, IsAsync, Unsafety, Defaultness, Extern, StrLit};
 use syntax::ast::{Visibility, VisibilityKind, Mutability, FnHeader, ForeignItem, ForeignItemKind};
@@ -705,7 +705,7 @@ impl<'a> Parser<'a> {
             // FIXME: code copied from `parse_macro_use_or_failure` -- use abstraction!
             (Ident::invalid(), ast::ImplItemKind::Macro(mac), Generics::default())
         } else {
-            self.parse_impl_method(at_end, &mut attrs)?
+            self.parse_assoc_fn(at_end, &mut attrs, |_| true)?
         };
 
         Ok(ImplItem {
@@ -876,7 +876,11 @@ impl<'a> Parser<'a> {
             // trait item macro.
             (Ident::invalid(), TraitItemKind::Macro(mac), Generics::default())
         } else {
-            self.parse_trait_item_method(at_end, &mut attrs)?
+            // This is somewhat dubious; We don't want to allow
+            // param names to be left off if there is a definition...
+            //
+            // We don't allow param names to be left off in edition 2018.
+            self.parse_assoc_fn(at_end, &mut attrs, |t| t.span.rust_2018())?
         };
 
         Ok(TraitItem {
@@ -1823,48 +1827,40 @@ impl<'a> Parser<'a> {
         })
     }
 
-    /// Parses a method or a macro invocation in a trait impl.
-    fn parse_impl_method(
-        &mut self,
-        at_end: &mut bool,
-        attrs: &mut Vec<Attribute>,
-    ) -> PResult<'a, (Ident, ImplItemKind, Generics)> {
-        let (ident, sig, generics) = self.parse_method_sig(|_| true)?;
-        let body = self.parse_trait_method_body(at_end, attrs)?;
-        Ok((ident, ast::ImplItemKind::Method(sig, body), generics))
-    }
-
-    fn parse_trait_item_method(
+    fn parse_assoc_fn(
         &mut self,
         at_end: &mut bool,
         attrs: &mut Vec<Attribute>,
-    ) -> PResult<'a, (Ident, TraitItemKind, Generics)> {
-        // This is somewhat dubious; We don't want to allow
-        // argument names to be left off if there is a definition...
-        //
-        // We don't allow argument names to be left off in edition 2018.
-        let (ident, sig, generics) = self.parse_method_sig(|t| t.span.rust_2018())?;
-        let body = self.parse_trait_method_body(at_end, attrs)?;
-        Ok((ident, TraitItemKind::Method(sig, body), generics))
+        is_name_required: fn(&token::Token) -> bool,
+    ) -> PResult<'a, (Ident, AssocItemKind, Generics)> {
+        let header = self.parse_fn_front_matter()?;
+        let (ident, decl, generics) = self.parse_fn_sig(ParamCfg {
+            is_self_allowed: true,
+            allow_c_variadic: false,
+            is_name_required,
+        })?;
+        let sig = FnSig { header, decl };
+        let body = self.parse_assoc_fn_body(at_end, attrs)?;
+        Ok((ident, AssocItemKind::Method(sig, body), generics))
     }
 
-    /// Parse the "body" of a method in a trait item definition.
+    /// Parse the "body" of a method in an associated item definition.
     /// This can either be `;` when there's no body,
     /// or e.g. a block when the method is a provided one.
-    fn parse_trait_method_body(
+    fn parse_assoc_fn_body(
         &mut self,
         at_end: &mut bool,
         attrs: &mut Vec<Attribute>,
     ) -> PResult<'a, Option<P<Block>>> {
         Ok(match self.token.kind {
             token::Semi => {
-                debug!("parse_trait_method_body(): parsing required method");
+                debug!("parse_assoc_fn_body(): parsing required method");
                 self.bump();
                 *at_end = true;
                 None
             }
             token::OpenDelim(token::Brace) => {
-                debug!("parse_trait_method_body(): parsing provided method");
+                debug!("parse_assoc_fn_body(): parsing provided method");
                 *at_end = true;
                 let (inner_attrs, body) = self.parse_inner_attrs_and_block()?;
                 attrs.extend(inner_attrs.iter().cloned());
@@ -1885,21 +1881,6 @@ impl<'a> Parser<'a> {
         })
     }
 
-    /// Parse the "signature", including the identifier, parameters, and generics
-    /// of a method. The body is not parsed as that differs between `trait`s and `impl`s.
-    fn parse_method_sig(
-        &mut self,
-        is_name_required: fn(&token::Token) -> bool,
-    ) -> PResult<'a, (Ident, FnSig, Generics)> {
-        let header = self.parse_fn_front_matter()?;
-        let (ident, decl, generics) = self.parse_fn_sig(ParamCfg {
-            is_self_allowed: true,
-            allow_c_variadic: false,
-            is_name_required,
-        })?;
-        Ok((ident, FnSig { header, decl }, generics))
-    }
-
     /// Parses all the "front matter" for a `fn` declaration, up to
     /// and including the `fn` keyword:
     ///
diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs
index dd8a7fa8665..5866f9db078 100644
--- a/src/libsyntax/ast.rs
+++ b/src/libsyntax/ast.rs
@@ -1640,6 +1640,7 @@ pub enum AssocItemKind  {
     Const(P<Ty>, Option<P<Expr>>),
 
     /// An associated function.
+    /// FIXME(Centril): Rename to `Fn`.
     Method(FnSig, Option<P<Block>>),
 
     /// An associated type.