about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMazdak Farrokhzad <twingoow@gmail.com>2019-12-01 11:30:04 +0100
committerMazdak Farrokhzad <twingoow@gmail.com>2019-12-12 17:54:49 +0100
commit63a9030e7b75312261733187f827df66db55cb1b (patch)
treef519e681c1c9a098fa7930bc87d55f32161c582a
parent7672bff3780ef0e7ba5313bf23644465644e19e6 (diff)
downloadrust-63a9030e7b75312261733187f827df66db55cb1b.tar.gz
rust-63a9030e7b75312261733187f827df66db55cb1b.zip
Unify associated item parsing.
An exception is `fn` params.
-rw-r--r--src/librustc_parse/parser/item.rs70
-rw-r--r--src/test/ui/did_you_mean/issue-40006.rs4
-rw-r--r--src/test/ui/did_you_mean/issue-40006.stderr12
-rw-r--r--src/test/ui/parser/issue-21153.stderr2
4 files changed, 29 insertions, 59 deletions
diff --git a/src/librustc_parse/parser/item.rs b/src/librustc_parse/parser/item.rs
index 32cc156783c..3fbdbb4cb22 100644
--- a/src/librustc_parse/parser/item.rs
+++ b/src/librustc_parse/parser/item.rs
@@ -6,8 +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, TraitItem, TraitItemKind, UseTree, UseTreeKind};
-use syntax::ast::{AssocItemKind};
+use syntax::ast::{AssocItem, AssocItemKind, ItemKind, UseTree, UseTreeKind};
 use syntax::ast::{PathSegment, IsAuto, Constness, IsAsync, Unsafety, Defaultness, Extern, StrLit};
 use syntax::ast::{Visibility, VisibilityKind, Mutability, FnHeader, ForeignItem, ForeignItemKind};
 use syntax::ast::{Ty, TyKind, Generics, TraitRef, EnumDef, Variant, VariantData, StructField};
@@ -649,7 +648,7 @@ impl<'a> Parser<'a> {
         Ok((Ident::invalid(), item_kind, Some(attrs)))
     }
 
-    fn parse_impl_body(&mut self) -> PResult<'a, (Vec<ImplItem>, Vec<Attribute>)> {
+    fn parse_impl_body(&mut self) -> PResult<'a, (Vec<AssocItem>, Vec<Attribute>)> {
         self.expect(&token::OpenDelim(token::Brace))?;
         let attrs = self.parse_inner_attributes()?;
 
@@ -671,12 +670,12 @@ impl<'a> Parser<'a> {
     }
 
     /// Parses an impl item.
-    pub fn parse_impl_item(&mut self, at_end: &mut bool) -> PResult<'a, ImplItem> {
+    pub fn parse_impl_item(&mut self, at_end: &mut bool) -> PResult<'a, AssocItem> {
         maybe_whole!(self, NtImplItem, |x| x);
         let attrs = self.parse_outer_attributes()?;
         let mut unclosed_delims = vec![];
         let (mut item, tokens) = self.collect_tokens(|this| {
-            let item = this.parse_impl_item_(at_end, attrs);
+            let item = this.parse_assoc_item(at_end, attrs, |_| true);
             unclosed_delims.append(&mut this.unclosed_delims);
             item
         })?;
@@ -689,38 +688,6 @@ impl<'a> Parser<'a> {
         Ok(item)
     }
 
-    fn parse_impl_item_(
-        &mut self,
-        at_end: &mut bool,
-        mut attrs: Vec<Attribute>,
-    ) -> PResult<'a, ImplItem> {
-        let lo = self.token.span;
-        let vis = self.parse_visibility(FollowedByType::No)?;
-        let defaultness = self.parse_defaultness();
-        let (name, kind, generics) = if self.eat_keyword(kw::Type) {
-            self.parse_assoc_ty()?
-        } else if self.is_const_item() {
-            self.parse_assoc_const()?
-        } else if let Some(mac) = self.parse_assoc_macro_invoc("impl", Some(&vis), at_end)? {
-            // FIXME: code copied from `parse_macro_use_or_failure` -- use abstraction!
-            (Ident::invalid(), ast::ImplItemKind::Macro(mac), Generics::default())
-        } else {
-            self.parse_assoc_fn(at_end, &mut attrs, |_| true)?
-        };
-
-        Ok(ImplItem {
-            id: DUMMY_NODE_ID,
-            span: lo.to(self.prev_span),
-            ident: name,
-            attrs,
-            vis,
-            defaultness,
-            generics,
-            kind,
-            tokens: None,
-        })
-    }
-
     /// Parses defaultness (i.e., `default` or nothing).
     fn parse_defaultness(&mut self) -> Defaultness {
         // `pub` is included for better error messages
@@ -843,12 +810,19 @@ impl<'a> Parser<'a> {
     }
 
     /// Parses the items in a trait declaration.
-    pub fn parse_trait_item(&mut self, at_end: &mut bool) -> PResult<'a, TraitItem> {
+    pub fn parse_trait_item(&mut self, at_end: &mut bool) -> PResult<'a, AssocItem> {
         maybe_whole!(self, NtTraitItem, |x| x);
         let attrs = self.parse_outer_attributes()?;
         let mut unclosed_delims = vec![];
         let (mut item, tokens) = self.collect_tokens(|this| {
-            let item = this.parse_trait_item_(at_end, 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.
+            //
+            // FIXME(Centril): bake closure into param parsing.
+            // Also add semantic restrictions and add tests.
+            let item = this.parse_assoc_item(at_end, attrs, |t| t.span.rust_2018());
             unclosed_delims.append(&mut this.unclosed_delims);
             item
         })?;
@@ -860,11 +834,12 @@ impl<'a> Parser<'a> {
         Ok(item)
     }
 
-    fn parse_trait_item_(
+    fn parse_assoc_item(
         &mut self,
         at_end: &mut bool,
         mut attrs: Vec<Attribute>,
-    ) -> PResult<'a, TraitItem> {
+        is_name_required: fn(&token::Token) -> bool,
+    ) -> PResult<'a, AssocItem> {
         let lo = self.token.span;
         let vis = self.parse_visibility(FollowedByType::No)?;
         let defaultness = self.parse_defaultness();
@@ -872,18 +847,13 @@ impl<'a> Parser<'a> {
             self.parse_assoc_ty()?
         } else if self.is_const_item() {
             self.parse_assoc_const()?
-        } else if let Some(mac) = self.parse_assoc_macro_invoc("trait", None, &mut false)? {
-            // trait item macro.
-            (Ident::invalid(), TraitItemKind::Macro(mac), Generics::default())
+        } else if let Some(mac) = self.parse_assoc_macro_invoc("associated", Some(&vis), at_end)? {
+            (Ident::invalid(), AssocItemKind::Macro(mac), Generics::default())
         } else {
-            // 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())?
+            self.parse_assoc_fn(at_end, &mut attrs, is_name_required)?
         };
 
-        Ok(TraitItem {
+        Ok(AssocItem {
             id: DUMMY_NODE_ID,
             span: lo.to(self.prev_span),
             ident: name,
diff --git a/src/test/ui/did_you_mean/issue-40006.rs b/src/test/ui/did_you_mean/issue-40006.rs
index b3c1f60b7eb..ea21592997b 100644
--- a/src/test/ui/did_you_mean/issue-40006.rs
+++ b/src/test/ui/did_you_mean/issue-40006.rs
@@ -18,10 +18,10 @@ trait A { //~ ERROR missing
 trait B {
     fn xxx() { ### } //~ ERROR expected
 }
-trait C { //~ ERROR missing `fn`, `type`, or `const` for trait-item declaration
+trait C { //~ ERROR missing `fn`, `type`, or `const` for associated-item declaration
     L = M;
 }
-trait D { //~ ERROR missing `fn`, `type`, or `const` for trait-item declaration
+trait D { //~ ERROR missing `fn`, `type`, or `const` for associated-item declaration
     Z = { 2 + 3 };
 }
 trait E {
diff --git a/src/test/ui/did_you_mean/issue-40006.stderr b/src/test/ui/did_you_mean/issue-40006.stderr
index 30ae6ed4c6d..d1e995013cb 100644
--- a/src/test/ui/did_you_mean/issue-40006.stderr
+++ b/src/test/ui/did_you_mean/issue-40006.stderr
@@ -1,4 +1,4 @@
-error: missing `fn`, `type`, or `const` for impl-item declaration
+error: missing `fn`, `type`, or `const` for associated-item declaration
   --> $DIR/issue-40006.rs:1:13
    |
 LL |   impl dyn A {
@@ -6,7 +6,7 @@ LL |   impl dyn A {
 LL | |     Y
    | |____^ missing `fn`, `type`, or `const`
 
-error: missing `fn`, `type`, or `const` for trait-item declaration
+error: missing `fn`, `type`, or `const` for associated-item declaration
   --> $DIR/issue-40006.rs:7:10
    |
 LL |   trait X {
@@ -14,7 +14,7 @@ LL |   trait X {
 LL | |     X() {}
    | |____^ missing `fn`, `type`, or `const`
 
-error: missing `fn`, `type`, or `const` for trait-item declaration
+error: missing `fn`, `type`, or `const` for associated-item declaration
   --> $DIR/issue-40006.rs:15:10
    |
 LL |   trait A {
@@ -28,7 +28,7 @@ error: expected `[`, found `#`
 LL |     fn xxx() { ### }
    |                 ^ expected `[`
 
-error: missing `fn`, `type`, or `const` for trait-item declaration
+error: missing `fn`, `type`, or `const` for associated-item declaration
   --> $DIR/issue-40006.rs:21:10
    |
 LL |   trait C {
@@ -36,7 +36,7 @@ LL |   trait C {
 LL | |     L = M;
    | |____^ missing `fn`, `type`, or `const`
 
-error: missing `fn`, `type`, or `const` for trait-item declaration
+error: missing `fn`, `type`, or `const` for associated-item declaration
   --> $DIR/issue-40006.rs:24:10
    |
 LL |   trait D {
@@ -50,7 +50,7 @@ error: expected one of `!` or `::`, found `(`
 LL |     ::Y ();
    |         ^ expected one of `!` or `::`
 
-error: missing `fn`, `type`, or `const` for impl-item declaration
+error: missing `fn`, `type`, or `const` for associated-item declaration
   --> $DIR/issue-40006.rs:32:8
    |
 LL |     pub hello_method(&self) {
diff --git a/src/test/ui/parser/issue-21153.stderr b/src/test/ui/parser/issue-21153.stderr
index 70f55f0aeb9..6e20a9ce3c4 100644
--- a/src/test/ui/parser/issue-21153.stderr
+++ b/src/test/ui/parser/issue-21153.stderr
@@ -1,4 +1,4 @@
-error: missing `fn`, `type`, or `const` for trait-item declaration
+error: missing `fn`, `type`, or `const` for associated-item declaration
   --> $DIR/issue-21153.rs:1:29
    |
 LL |   trait MyTrait<T>: Iterator {