about summary refs log tree commit diff
path: root/src/librustc_parse/parser
diff options
context:
space:
mode:
authorMazdak Farrokhzad <twingoow@gmail.com>2020-01-31 13:37:23 +0100
committerMazdak Farrokhzad <twingoow@gmail.com>2020-02-13 15:16:36 +0100
commit15e07a6a11bc5ed86e33403eb4b7d718d1636855 (patch)
tree36c36cef6be5290b58d19b7173a83b5982e2732f /src/librustc_parse/parser
parentfd64b3bcdfcc844b9b25318106917937f7b17b94 (diff)
downloadrust-15e07a6a11bc5ed86e33403eb4b7d718d1636855.tar.gz
rust-15e07a6a11bc5ed86e33403eb4b7d718d1636855.zip
parser: fuse `trait` parsing & layer with `is_path_start_item`
Diffstat (limited to 'src/librustc_parse/parser')
-rw-r--r--src/librustc_parse/parser/item.rs46
-rw-r--r--src/librustc_parse/parser/stmt.rs16
2 files changed, 27 insertions, 35 deletions
diff --git a/src/librustc_parse/parser/item.rs b/src/librustc_parse/parser/item.rs
index 27b3d501751..6de82d8f9be 100644
--- a/src/librustc_parse/parser/item.rs
+++ b/src/librustc_parse/parser/item.rs
@@ -152,11 +152,9 @@ impl<'a> Parser<'a> {
             }
 
             self.parse_item_const(None)?
-        } else if self.check_keyword(kw::Unsafe) && self.is_keyword_ahead(1, &[kw::Trait, kw::Auto])
-        {
-            // UNSAFE TRAIT ITEM
-            let unsafety = self.parse_unsafety();
-            self.parse_item_trait(attrs, lo, unsafety)?
+        } else if self.check_keyword(kw::Trait) || self.check_auto_or_unsafe_trait_item() {
+            // TRAIT ITEM
+            self.parse_item_trait(attrs, lo)?
         } else if self.check_keyword(kw::Impl)
             || self.check_keyword(kw::Unsafe) && self.is_keyword_ahead(1, &[kw::Impl])
             || self.check_keyword(kw::Default) && self.is_keyword_ahead(1, &[kw::Impl, kw::Unsafe])
@@ -176,11 +174,6 @@ impl<'a> Parser<'a> {
         } else if self.eat_keyword(kw::Enum) {
             // ENUM ITEM
             self.parse_item_enum()?
-        } else if self.check_keyword(kw::Trait)
-            || (self.check_keyword(kw::Auto) && self.is_keyword_ahead(1, &[kw::Trait]))
-        {
-            // TRAIT ITEM
-            self.parse_item_trait(attrs, lo, Unsafe::No)?
         } else if self.eat_keyword(kw::Struct) {
             // STRUCT ITEM
             self.parse_item_struct()?
@@ -209,6 +202,15 @@ impl<'a> Parser<'a> {
         Ok(Some(info))
     }
 
+    /// When parsing a statement, would the start of a path be an item?
+    pub(super) fn is_path_start_item(&mut self) -> bool {
+        self.is_crate_vis() // no: `crate::b`, yes: `crate $item`
+        || self.is_union_item() // no: `union::b`, yes: `union U { .. }`
+        || self.check_auto_or_unsafe_trait_item() // no: `auto::b`, yes: `auto trait X { .. }`
+        || self.is_async_fn() // no(2015): `async::b`, yes: `async fn`
+        || self.is_macro_rules_item() // no: `macro_rules::b`, yes: `macro_rules! mac`
+    }
+
     /// Recover on encountering a struct or method definition where the user
     /// forgot to add the `struct` or `fn` keyword after writing `pub`: `pub S {}`.
     fn recover_missing_kw_before_item(&mut self) -> PResult<'a, ()> {
@@ -338,7 +340,7 @@ impl<'a> Parser<'a> {
         Err(err)
     }
 
-    pub(super) fn is_async_fn(&self) -> bool {
+    fn is_async_fn(&self) -> bool {
         self.token.is_keyword(kw::Async) && self.is_keyword_ahead(1, &[kw::Fn])
     }
 
@@ -609,13 +611,17 @@ impl<'a> Parser<'a> {
         }
     }
 
-    /// Parses `auto? trait Foo { ... }` or `trait Foo = Bar;`.
-    fn parse_item_trait(
-        &mut self,
-        attrs: &mut Vec<Attribute>,
-        lo: Span,
-        unsafety: Unsafe,
-    ) -> PResult<'a, ItemInfo> {
+    /// Is this an `(unsafe auto? | auto) trait` item?
+    fn check_auto_or_unsafe_trait_item(&mut self) -> bool {
+        // auto trait
+        self.check_keyword(kw::Auto) && self.is_keyword_ahead(1, &[kw::Trait])
+            // unsafe auto trait
+            || self.check_keyword(kw::Unsafe) && self.is_keyword_ahead(1, &[kw::Trait, kw::Auto])
+    }
+
+    /// Parses `unsafe? auto? trait Foo { ... }` or `trait Foo = Bar;`.
+    fn parse_item_trait(&mut self, attrs: &mut Vec<Attribute>, lo: Span) -> PResult<'a, ItemInfo> {
+        let unsafety = self.parse_unsafety();
         // Parse optional `auto` prefix.
         let is_auto = if self.eat_keyword(kw::Auto) { IsAuto::Yes } else { IsAuto::No };
 
@@ -1179,7 +1185,7 @@ impl<'a> Parser<'a> {
         Ok((class_name, ItemKind::Union(vdata, generics)))
     }
 
-    pub(super) fn is_union_item(&self) -> bool {
+    fn is_union_item(&self) -> bool {
         self.token.is_keyword(kw::Union)
             && self.look_ahead(1, |t| t.is_ident() && !t.is_reserved_ident())
     }
@@ -1362,7 +1368,7 @@ impl<'a> Parser<'a> {
     }
 
     /// Is this unambiguously the start of a `macro_rules! foo` item defnition?
-    pub(super) fn is_macro_rules_item(&mut self) -> bool {
+    fn is_macro_rules_item(&mut self) -> bool {
         self.check_keyword(sym::macro_rules)
             && self.look_ahead(1, |t| *t == token::Not)
             && self.look_ahead(2, |t| t.is_ident())
diff --git a/src/librustc_parse/parser/stmt.rs b/src/librustc_parse/parser/stmt.rs
index b111b45e709..439d0368d09 100644
--- a/src/librustc_parse/parser/stmt.rs
+++ b/src/librustc_parse/parser/stmt.rs
@@ -61,11 +61,7 @@ impl<'a> Parser<'a> {
         // like a path (1 token), but it fact not a path.
         if self.token.is_path_start()
             && !self.token.is_qpath_start()
-            && !self.is_union_item() // `union::b::c` - path, `union U { ... }` - not a path.
-            && !self.is_crate_vis() // `crate::b::c` - path, `crate struct S;` - not a path.
-            && !self.is_auto_trait_item()
-            && !self.is_async_fn()
-            && !self.is_macro_rules_item()
+            && !self.is_path_start_item() // Confirm we don't steal syntax from `parse_item_`.
         {
             let path = self.parse_path(PathStyle::Expr)?;
 
@@ -295,16 +291,6 @@ impl<'a> Parser<'a> {
         }
     }
 
-    fn is_auto_trait_item(&self) -> bool {
-        // auto trait
-        (self.token.is_keyword(kw::Auto) &&
-            self.is_keyword_ahead(1, &[kw::Trait]))
-        || // unsafe auto trait
-        (self.token.is_keyword(kw::Unsafe) &&
-         self.is_keyword_ahead(1, &[kw::Auto]) &&
-         self.is_keyword_ahead(2, &[kw::Trait]))
-    }
-
     /// Parses a block. No inner attributes are allowed.
     pub fn parse_block(&mut self) -> PResult<'a, P<Block>> {
         maybe_whole!(self, NtBlock, |x| x);