Skip to content

Commit a16ff53

Browse files
committed
Refactor impl block frontmatter checking in the parser
1 parent 217cb73 commit a16ff53

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
@@ -250,29 +250,22 @@ impl<'a> Parser<'a> {
250250
} else if self.check_keyword(exp!(Trait)) || self.check_trait_front_matter() {
251251
// TRAIT ITEM
252252
self.parse_item_trait(attrs, lo)?
253-
} else if let Const::Yes(const_span) = self.parse_constness(Case::Sensitive) {
254-
// CONST ITEM
255-
if self.token.is_keyword(kw::Impl) {
256-
// recover from `const impl`, suggest `impl const`
257-
self.recover_const_impl(const_span, attrs, def_())?
258-
} else {
259-
self.recover_const_mut(const_span);
260-
self.recover_missing_kw_before_item()?;
261-
let (ident, generics, ty, rhs) = self.parse_const_item(attrs)?;
262-
ItemKind::Const(Box::new(ConstItem {
263-
defaultness: def_(),
264-
ident,
265-
generics,
266-
ty,
267-
rhs,
268-
define_opaque: None,
269-
}))
270-
}
271-
} else if self.check_keyword(exp!(Impl))
272-
|| self.check_keyword(exp!(Unsafe)) && self.is_keyword_ahead(1, &[kw::Impl])
273-
{
253+
} else if self.check_impl_frontmatter() {
274254
// IMPL ITEM
275255
self.parse_item_impl(attrs, def_())?
256+
} else if let Const::Yes(const_span) = self.parse_constness(Case::Sensitive) {
257+
// CONST ITEM
258+
self.recover_const_mut(const_span);
259+
self.recover_missing_kw_before_item()?;
260+
let (ident, generics, ty, rhs) = self.parse_const_item(attrs)?;
261+
ItemKind::Const(Box::new(ConstItem {
262+
defaultness: def_(),
263+
ident,
264+
generics,
265+
ty,
266+
rhs,
267+
define_opaque: None,
268+
}))
276269
} else if self.is_reuse_path_item() {
277270
self.parse_item_delegation()?
278271
} else if self.check_keyword(exp!(Mod))
@@ -569,6 +562,9 @@ impl<'a> Parser<'a> {
569562
attrs: &mut AttrVec,
570563
defaultness: Defaultness,
571564
) -> PResult<'a, ItemKind> {
565+
if self.eat_keyword(exp!(Const)) {
566+
return self.recover_const_impl(self.prev_token.span, attrs, defaultness);
567+
}
572568
let safety = self.parse_safety(Case::Sensitive);
573569
self.expect_keyword(exp!(Impl))?;
574570

@@ -2624,6 +2620,33 @@ impl<'a> Parser<'a> {
26242620
Ok(body)
26252621
}
26262622

2623+
fn check_impl_frontmatter(&mut self) -> bool {
2624+
const ALL_QUALS: &[Symbol] = &[kw::Const, kw::Unsafe];
2625+
// In contrast to the loop below, this call inserts `impl` into the
2626+
// list of expected tokens shown in diagnostics.
2627+
if self.check_keyword(exp!(Impl)) {
2628+
return true;
2629+
}
2630+
let mut i = 0;
2631+
while i < ALL_QUALS.len() {
2632+
let action = self.look_ahead(i, |token| {
2633+
if token.is_keyword(kw::Impl) {
2634+
return Some(true);
2635+
}
2636+
if ALL_QUALS.iter().any(|&qual| token.is_keyword(qual)) {
2637+
// Ok, we found a legal keyword, keep looking for `impl`
2638+
return None;
2639+
}
2640+
Some(false)
2641+
});
2642+
if let Some(ret) = action {
2643+
return ret;
2644+
}
2645+
i += 1;
2646+
}
2647+
self.is_keyword_ahead(i, &[kw::Impl])
2648+
}
2649+
26272650
/// Is the current token the start of an `FnHeader` / not a valid parse?
26282651
///
26292652
/// `check_pub` adds additional `pub` to the checks in case users place it

0 commit comments

Comments
 (0)