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