Skip to content

Commit 15e07a6

Browse files
committed
parser: fuse trait parsing & layer with is_path_start_item
1 parent fd64b3b commit 15e07a6

File tree

2 files changed

+27
-35
lines changed

2 files changed

+27
-35
lines changed

src/librustc_parse/parser/item.rs

Lines changed: 26 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -152,11 +152,9 @@ impl<'a> Parser<'a> {
152152
}
153153

154154
self.parse_item_const(None)?
155-
} else if self.check_keyword(kw::Unsafe) && self.is_keyword_ahead(1, &[kw::Trait, kw::Auto])
156-
{
157-
// UNSAFE TRAIT ITEM
158-
let unsafety = self.parse_unsafety();
159-
self.parse_item_trait(attrs, lo, unsafety)?
155+
} else if self.check_keyword(kw::Trait) || self.check_auto_or_unsafe_trait_item() {
156+
// TRAIT ITEM
157+
self.parse_item_trait(attrs, lo)?
160158
} else if self.check_keyword(kw::Impl)
161159
|| self.check_keyword(kw::Unsafe) && self.is_keyword_ahead(1, &[kw::Impl])
162160
|| self.check_keyword(kw::Default) && self.is_keyword_ahead(1, &[kw::Impl, kw::Unsafe])
@@ -176,11 +174,6 @@ impl<'a> Parser<'a> {
176174
} else if self.eat_keyword(kw::Enum) {
177175
// ENUM ITEM
178176
self.parse_item_enum()?
179-
} else if self.check_keyword(kw::Trait)
180-
|| (self.check_keyword(kw::Auto) && self.is_keyword_ahead(1, &[kw::Trait]))
181-
{
182-
// TRAIT ITEM
183-
self.parse_item_trait(attrs, lo, Unsafe::No)?
184177
} else if self.eat_keyword(kw::Struct) {
185178
// STRUCT ITEM
186179
self.parse_item_struct()?
@@ -209,6 +202,15 @@ impl<'a> Parser<'a> {
209202
Ok(Some(info))
210203
}
211204

205+
/// When parsing a statement, would the start of a path be an item?
206+
pub(super) fn is_path_start_item(&mut self) -> bool {
207+
self.is_crate_vis() // no: `crate::b`, yes: `crate $item`
208+
|| self.is_union_item() // no: `union::b`, yes: `union U { .. }`
209+
|| self.check_auto_or_unsafe_trait_item() // no: `auto::b`, yes: `auto trait X { .. }`
210+
|| self.is_async_fn() // no(2015): `async::b`, yes: `async fn`
211+
|| self.is_macro_rules_item() // no: `macro_rules::b`, yes: `macro_rules! mac`
212+
}
213+
212214
/// Recover on encountering a struct or method definition where the user
213215
/// forgot to add the `struct` or `fn` keyword after writing `pub`: `pub S {}`.
214216
fn recover_missing_kw_before_item(&mut self) -> PResult<'a, ()> {
@@ -338,7 +340,7 @@ impl<'a> Parser<'a> {
338340
Err(err)
339341
}
340342

341-
pub(super) fn is_async_fn(&self) -> bool {
343+
fn is_async_fn(&self) -> bool {
342344
self.token.is_keyword(kw::Async) && self.is_keyword_ahead(1, &[kw::Fn])
343345
}
344346

@@ -609,13 +611,17 @@ impl<'a> Parser<'a> {
609611
}
610612
}
611613

612-
/// Parses `auto? trait Foo { ... }` or `trait Foo = Bar;`.
613-
fn parse_item_trait(
614-
&mut self,
615-
attrs: &mut Vec<Attribute>,
616-
lo: Span,
617-
unsafety: Unsafe,
618-
) -> PResult<'a, ItemInfo> {
614+
/// Is this an `(unsafe auto? | auto) trait` item?
615+
fn check_auto_or_unsafe_trait_item(&mut self) -> bool {
616+
// auto trait
617+
self.check_keyword(kw::Auto) && self.is_keyword_ahead(1, &[kw::Trait])
618+
// unsafe auto trait
619+
|| self.check_keyword(kw::Unsafe) && self.is_keyword_ahead(1, &[kw::Trait, kw::Auto])
620+
}
621+
622+
/// Parses `unsafe? auto? trait Foo { ... }` or `trait Foo = Bar;`.
623+
fn parse_item_trait(&mut self, attrs: &mut Vec<Attribute>, lo: Span) -> PResult<'a, ItemInfo> {
624+
let unsafety = self.parse_unsafety();
619625
// Parse optional `auto` prefix.
620626
let is_auto = if self.eat_keyword(kw::Auto) { IsAuto::Yes } else { IsAuto::No };
621627

@@ -1179,7 +1185,7 @@ impl<'a> Parser<'a> {
11791185
Ok((class_name, ItemKind::Union(vdata, generics)))
11801186
}
11811187

1182-
pub(super) fn is_union_item(&self) -> bool {
1188+
fn is_union_item(&self) -> bool {
11831189
self.token.is_keyword(kw::Union)
11841190
&& self.look_ahead(1, |t| t.is_ident() && !t.is_reserved_ident())
11851191
}
@@ -1362,7 +1368,7 @@ impl<'a> Parser<'a> {
13621368
}
13631369

13641370
/// Is this unambiguously the start of a `macro_rules! foo` item defnition?
1365-
pub(super) fn is_macro_rules_item(&mut self) -> bool {
1371+
fn is_macro_rules_item(&mut self) -> bool {
13661372
self.check_keyword(sym::macro_rules)
13671373
&& self.look_ahead(1, |t| *t == token::Not)
13681374
&& self.look_ahead(2, |t| t.is_ident())

src/librustc_parse/parser/stmt.rs

Lines changed: 1 addition & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -61,11 +61,7 @@ impl<'a> Parser<'a> {
6161
// like a path (1 token), but it fact not a path.
6262
if self.token.is_path_start()
6363
&& !self.token.is_qpath_start()
64-
&& !self.is_union_item() // `union::b::c` - path, `union U { ... }` - not a path.
65-
&& !self.is_crate_vis() // `crate::b::c` - path, `crate struct S;` - not a path.
66-
&& !self.is_auto_trait_item()
67-
&& !self.is_async_fn()
68-
&& !self.is_macro_rules_item()
64+
&& !self.is_path_start_item() // Confirm we don't steal syntax from `parse_item_`.
6965
{
7066
let path = self.parse_path(PathStyle::Expr)?;
7167

@@ -295,16 +291,6 @@ impl<'a> Parser<'a> {
295291
}
296292
}
297293

298-
fn is_auto_trait_item(&self) -> bool {
299-
// auto trait
300-
(self.token.is_keyword(kw::Auto) &&
301-
self.is_keyword_ahead(1, &[kw::Trait]))
302-
|| // unsafe auto trait
303-
(self.token.is_keyword(kw::Unsafe) &&
304-
self.is_keyword_ahead(1, &[kw::Auto]) &&
305-
self.is_keyword_ahead(2, &[kw::Trait]))
306-
}
307-
308294
/// Parses a block. No inner attributes are allowed.
309295
pub fn parse_block(&mut self) -> PResult<'a, P<Block>> {
310296
maybe_whole!(self, NtBlock, |x| x);

0 commit comments

Comments
 (0)