Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
73 changes: 38 additions & 35 deletions src/libsyntax/parse/parser.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -1087,6 +1087,11 @@ impl<'a> Parser<'a> {
}
}

/// Returns whether any of the given keywords are `dist` tokens ahead of the current one.
fn is_keyword_ahead(&self, dist: usize, kws: &[Symbol]) -> bool {

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We could possibly reduce this to just one keyword... that is one option... :)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

18 single keyword vs 5 multiple keywords.
+ look_ahead is a single array lookup and a match, more or less, so not much reason to optimize.
Might be reasonable to reduce to one keyword.

self.look_ahead(dist, |t| kws.iter().any(|&kw| t.is_keyword(kw)))
}

/// Is the current token one of the keywords that signals a bare function type?
fn token_is_bare_fn_keyword(&mut self) -> bool {
self.check_keyword(kw::Fn) ||
Expand DownExpand Up@@ -4270,7 +4275,7 @@ impl<'a> Parser<'a> {
self.token.is_keyword(kw::Async) &&
(
( // `async move {`
self.look_ahead(1, |t| t.is_keyword(kw::Move)) &&
self.is_keyword_ahead(1, &[kw::Move]) &&
self.look_ahead(2, |t| *t == token::OpenDelim(token::Brace))
) || ( // `async {`
self.look_ahead(1, |t| *t == token::OpenDelim(token::Brace))
Expand All@@ -4280,12 +4285,12 @@ impl<'a> Parser<'a> {

fn is_async_fn(&self) -> bool {
self.token.is_keyword(kw::Async) &&
self.look_ahead(1, |t| t.is_keyword(kw::Fn))
self.is_keyword_ahead(1, &[kw::Fn])
}

fn is_do_catch_block(&self) -> bool {
self.token.is_keyword(kw::Do) &&
self.look_ahead(1, |t| t.is_keyword(kw::Catch)) &&
self.is_keyword_ahead(1, &[kw::Catch]) &&
self.look_ahead(2, |t| *t == token::OpenDelim(token::Brace)) &&
!self.restrictions.contains(Restrictions::NO_STRUCT_LITERAL)
}
Expand All@@ -4309,17 +4314,17 @@ impl<'a> Parser<'a> {

fn is_existential_type_decl(&self) -> bool {
self.token.is_keyword(kw::Existential) &&
self.look_ahead(1, |t| t.is_keyword(kw::Type))
self.is_keyword_ahead(1, &[kw::Type])
}

fn is_auto_trait_item(&self) -> bool {
// auto trait
(self.token.is_keyword(kw::Auto)
&& self.look_ahead(1, |t| t.is_keyword(kw::Trait)))
(self.token.is_keyword(kw::Auto) &&
self.is_keyword_ahead(1, &[kw::Trait]))
|| // unsafe auto trait
(self.token.is_keyword(kw::Unsafe) &&
self.look_ahead(1, |t| t.is_keyword(kw::Auto)) &&
self.look_ahead(2, |t| t.is_keyword(kw::Trait)))
self.is_keyword_ahead(1, &[kw::Auto]) &&
self.is_keyword_ahead(2, &[kw::Trait]))
}

fn eat_macro_def(&mut self, attrs: &[Attribute], vis: &Visibility, lo: Span)
Expand DownExpand Up@@ -5486,7 +5491,7 @@ impl<'a> Parser<'a> {
(if isolated_self(self, 1) {
self.bump();
SelfKind::Region(None, Mutability::Immutable)
} else if self.look_ahead(1, |t| t.is_keyword(kw::Mut)) &&
} else if self.is_keyword_ahead(1, &[kw::Mut]) &&
isolated_self(self, 2) {
self.bump();
self.bump();
Expand All@@ -5497,7 +5502,7 @@ impl<'a> Parser<'a> {
let lt = self.expect_lifetime();
SelfKind::Region(Some(lt), Mutability::Immutable)
} else if self.look_ahead(1, |t| t.is_lifetime()) &&
self.look_ahead(2, |t| t.is_keyword(kw::Mut)) &&
self.is_keyword_ahead(2, &[kw::Mut]) &&
isolated_self(self, 3) {
self.bump();
let lt = self.expect_lifetime();
Expand DownExpand Up@@ -5676,8 +5681,7 @@ impl<'a> Parser<'a> {
/// (returns `false` for things like `const fn`, etc.).
fn is_const_item(&self) -> bool {
self.token.is_keyword(kw::Const) &&
!self.look_ahead(1, |t| t.is_keyword(kw::Fn)) &&
!self.look_ahead(1, |t| t.is_keyword(kw::Unsafe))
!self.is_keyword_ahead(1, &[kw::Fn, kw::Unsafe])
}

/// Parses all the "front matter" for a `fn` declaration, up to
Expand DownExpand Up@@ -5955,7 +5959,7 @@ impl<'a> Parser<'a> {
self.look_ahead(1, |t| t.is_lifetime() || t.is_ident()) &&
self.look_ahead(2, |t| t == &token::Gt || t == &token::Comma ||
t == &token::Colon || t == &token::Eq) ||
self.look_ahead(1, |t| t.is_keyword(kw::Const)))
self.is_keyword_ahead(1, &[kw::Const]))
}

fn parse_impl_body(&mut self) -> PResult<'a, (Vec<ImplItem>, Vec<Attribute>)> {
Expand DownExpand Up@@ -6316,7 +6320,7 @@ impl<'a> Parser<'a> {
// `()` or a tuple might be allowed. For example, `struct Struct(pub (), pub (usize));`.
// Because of this, we only `bump` the `(` if we're assured it is appropriate to do so
// by the following tokens.
if self.look_ahead(1, |t| t.is_keyword(kw::Crate)) &&
if self.is_keyword_ahead(1, &[kw::Crate]) &&
self.look_ahead(2, |t| t != &token::ModSep) // account for `pub(crate::foo)`
{
// `pub(crate)`
Expand All@@ -6328,7 +6332,7 @@ impl<'a> Parser<'a> {
VisibilityKind::Crate(CrateSugar::PubCrate),
);
return Ok(vis)
} else if self.look_ahead(1, |t| t.is_keyword(kw::In)) {
} else if self.is_keyword_ahead(1, &[kw::In]) {
// `pub(in path)`
self.bump(); // `(`
self.bump(); // `in`
Expand All@@ -6340,8 +6344,7 @@ impl<'a> Parser<'a> {
});
return Ok(vis)
} else if self.look_ahead(2, |t| t == &token::CloseDelim(token::Paren)) &&
self.look_ahead(1, |t| t.is_keyword(kw::Super) ||
t.is_keyword(kw::SelfLower))
self.is_keyword_ahead(1, &[kw::Super, kw::SelfLower])
{
// `pub(self)` or `pub(super)`
self.bump(); // `(`
Expand DownExpand Up@@ -6380,13 +6383,16 @@ impl<'a> Parser<'a> {
fn parse_defaultness(&mut self) -> Defaultness {
// `pub` is included for better error messages
if self.check_keyword(kw::Default) &&
self.look_ahead(1, |t| t.is_keyword(kw::Impl) ||
t.is_keyword(kw::Const) ||
t.is_keyword(kw::Fn) ||
t.is_keyword(kw::Unsafe) ||
t.is_keyword(kw::Extern) ||
t.is_keyword(kw::Type) ||
t.is_keyword(kw::Pub)) {
self.is_keyword_ahead(1, &[
kw::Impl,
kw::Const,
kw::Fn,
kw::Unsafe,
kw::Extern,
kw::Type,
kw::Pub,
])
{
self.bump(); // `default`
Defaultness::Default
} else {
Expand DownExpand Up@@ -6880,7 +6886,7 @@ impl<'a> Parser<'a> {
// Ident ["<"...">"] ["where" ...] ("=" | ":") Ty ";"
if self.check_keyword(kw::Type) ||
self.check_keyword(kw::Existential) &&
self.look_ahead(1, |t| t.is_keyword(kw::Type)) {
self.is_keyword_ahead(1, &[kw::Type]) {
let existential = self.eat_keyword(kw::Existential);
assert!(self.eat_keyword(kw::Type));
Some(self.parse_existential_or_alias(existential))
Expand DownExpand Up@@ -7157,7 +7163,7 @@ impl<'a> Parser<'a> {
let const_span = self.prev_span;
if self.check_keyword(kw::Fn)
|| (self.check_keyword(kw::Unsafe)
&& self.look_ahead(1, |t| t.is_keyword(kw::Fn))) {
&& self.is_keyword_ahead(1, &[kw::Fn])) {
// CONST FUNCTION ITEM
let unsafety = self.parse_unsafety();
self.bump();
Expand DownExpand Up@@ -7202,10 +7208,10 @@ impl<'a> Parser<'a> {
// `unsafe async fn` or `async fn`
if (
self.check_keyword(kw::Unsafe) &&
self.look_ahead(1, |t| t.is_keyword(kw::Async))
self.is_keyword_ahead(1, &[kw::Async])
) || (
self.check_keyword(kw::Async) &&
self.look_ahead(1, |t| t.is_keyword(kw::Fn))
self.is_keyword_ahead(1, &[kw::Fn])
)
{
// ASYNC FUNCTION ITEM
Expand DownExpand Up@@ -7239,8 +7245,7 @@ impl<'a> Parser<'a> {
return Ok(Some(item));
}
if self.check_keyword(kw::Unsafe) &&
(self.look_ahead(1, |t| t.is_keyword(kw::Trait)) ||
self.look_ahead(1, |t| t.is_keyword(kw::Auto)))
self.is_keyword_ahead(1, &[kw::Trait, kw::Auto])
{
// UNSAFE TRAIT ITEM
self.bump(); // `unsafe`
Expand All@@ -7263,11 +7268,9 @@ impl<'a> Parser<'a> {
}
if self.check_keyword(kw::Impl) ||
self.check_keyword(kw::Unsafe) &&
self.look_ahead(1, |t| t.is_keyword(kw::Impl)) ||
self.check_keyword(kw::Default) &&
self.look_ahead(1, |t| t.is_keyword(kw::Impl)) ||

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

side-note (pre existing): default unsafe fn is eaten by this if and will error?

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah I believe so.

self.is_keyword_ahead(1, &[kw::Impl]) ||
self.check_keyword(kw::Default) &&
self.look_ahead(1, |t| t.is_keyword(kw::Unsafe)) {
self.is_keyword_ahead(1, &[kw::Impl, kw::Unsafe]) {
// IMPL ITEM
let defaultness = self.parse_defaultness();
let unsafety = self.parse_unsafety();
Expand DownExpand Up@@ -7360,7 +7363,7 @@ impl<'a> Parser<'a> {
}
if self.check_keyword(kw::Trait)
|| (self.check_keyword(kw::Auto)
&& self.look_ahead(1, |t| t.is_keyword(kw::Trait)))
&& self.is_keyword_ahead(1, &[kw::Trait]))
{
let is_auto = if self.eat_keyword(kw::Trait) {
IsAuto::No
Expand Down