diff options
| author | Mazdak Farrokhzad <twingoow@gmail.com> | 2020-01-31 13:37:23 +0100 |
|---|---|---|
| committer | Mazdak Farrokhzad <twingoow@gmail.com> | 2020-02-13 15:16:36 +0100 |
| commit | 15e07a6a11bc5ed86e33403eb4b7d718d1636855 (patch) | |
| tree | 36c36cef6be5290b58d19b7173a83b5982e2732f /src/librustc_parse/parser | |
| parent | fd64b3bcdfcc844b9b25318106917937f7b17b94 (diff) | |
| download | rust-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.rs | 46 | ||||
| -rw-r--r-- | src/librustc_parse/parser/stmt.rs | 16 |
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); |
