@@ -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