parser: fuse trait parsing & layer with is_path_start_item
This commit is contained in:
parent
fd64b3bcdf
commit
15e07a6a11
2 changed files with 27 additions and 35 deletions
|
|
@ -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())
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue