Skip to content

Commit 427deb6

Browse files
committed
Refactor impl block frontmatter checking in the parser
1 parent 7878a91 commit 427deb6

File tree

1 file changed

+44
-21
lines changed
  • compiler/rustc_parse/src/parser

1 file changed

+44
-21
lines changed

compiler/rustc_parse/src/parser/item.rs

Lines changed: 44 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -247,29 +247,22 @@ impl<'a> Parser<'a> {
247247
} else if self.check_keyword(exp!(Trait)) || self.check_trait_front_matter() {
248248
// TRAIT ITEM
249249
self.parse_item_trait(attrs, lo)?
250-
} else if let Const::Yes(const_span) = self.parse_constness(Case::Sensitive) {
251-
// CONST ITEM
252-
if self.token.is_keyword(kw::Impl) {
253-
// recover from `const impl`, suggest `impl const`
254-
self.recover_const_impl(const_span, attrs, def_())?
255-
} else {
256-
self.recover_const_mut(const_span);
257-
self.recover_missing_kw_before_item()?;
258-
let (ident, generics, ty, expr) = self.parse_const_item()?;
259-
ItemKind::Const(Box::new(ConstItem {
260-
defaultness: def_(),
261-
ident,
262-
generics,
263-
ty,
264-
expr,
265-
define_opaque: None,
266-
}))
267-
}
268-
} else if self.check_keyword(exp!(Impl))
269-
|| self.check_keyword(exp!(Unsafe)) && self.is_keyword_ahead(1, &[kw::Impl])
270-
{
250+
} else if self.check_impl_frontmatter() {
271251
// IMPL ITEM
272252
self.parse_item_impl(attrs, def_())?
253+
} else if let Const::Yes(const_span) = self.parse_constness(Case::Sensitive) {
254+
// CONST ITEM
255+
self.recover_const_mut(const_span);
256+
self.recover_missing_kw_before_item()?;
257+
let (ident, generics, ty, expr) = self.parse_const_item()?;
258+
ItemKind::Const(Box::new(ConstItem {
259+
defaultness: def_(),
260+
ident,
261+
generics,
262+
ty,
263+
expr,
264+
define_opaque: None,
265+
}))
273266
} else if self.is_reuse_path_item() {
274267
self.parse_item_delegation()?
275268
} else if self.check_keyword(exp!(Mod))
@@ -566,6 +559,9 @@ impl<'a> Parser<'a> {
566559
attrs: &mut AttrVec,
567560
defaultness: Defaultness,
568561
) -> PResult<'a, ItemKind> {
562+
if self.eat_keyword(exp!(Const)) {
563+
return self.recover_const_impl(self.prev_token.span, attrs, defaultness);
564+
}
569565
let safety = self.parse_safety(Case::Sensitive);
570566
self.expect_keyword(exp!(Impl))?;
571567

@@ -2594,6 +2590,33 @@ impl<'a> Parser<'a> {
25942590
Ok(body)
25952591
}
25962592

2593+
fn check_impl_frontmatter(&mut self) -> bool {
2594+
const ALL_QUALS: &[Symbol] = &[kw::Const, kw::Unsafe];
2595+
// In contrast to the loop below, this call inserts `impl` into the
2596+
// list of expected tokens shown in diagnostics.
2597+
if self.check_keyword(exp!(Impl)) {
2598+
return true;
2599+
}
2600+
let mut i = 0;
2601+
while i < ALL_QUALS.len() {
2602+
let action = self.look_ahead(i, |token| {
2603+
if token.is_keyword(kw::Impl) {
2604+
return Some(true);
2605+
}
2606+
if ALL_QUALS.iter().any(|&qual| token.is_keyword(qual)) {
2607+
// Ok, we found a legal keyword, keep looking for `impl`
2608+
return None;
2609+
}
2610+
Some(false)
2611+
});
2612+
if let Some(ret) = action {
2613+
return ret;
2614+
}
2615+
i += 1;
2616+
}
2617+
self.is_keyword_ahead(i, &[kw::Impl])
2618+
}
2619+
25972620
/// Is the current token the start of an `FnHeader` / not a valid parse?
25982621
///
25992622
/// `check_pub` adds additional `pub` to the checks in case users place it

0 commit comments

Comments
 (0)