@@ -247,9 +247,14 @@ impl<'a> Parser<'a> {
247
247
( ident, ItemKind :: Static ( ty, m, expr) )
248
248
} else if let Const :: Yes ( const_span) = self . parse_constness ( ) {
249
249
// CONST ITEM
250
- self . recover_const_mut ( const_span) ;
251
- let ( ident, ty, expr) = self . parse_item_global ( None ) ?;
252
- ( ident, ItemKind :: Const ( def ( ) , ty, expr) )
250
+ if self . token . is_keyword ( kw:: Impl ) {
251
+ // recover from `const impl`, suggest `impl const`
252
+ self . recover_const_impl ( const_span, attrs, def ( ) ) ?
253
+ } else {
254
+ self . recover_const_mut ( const_span) ;
255
+ let ( ident, ty, expr) = self . parse_item_global ( None ) ?;
256
+ ( ident, ItemKind :: Const ( def ( ) , ty, expr) )
257
+ }
253
258
} else if self . check_keyword ( kw:: Trait ) || self . check_auto_or_unsafe_trait_item ( ) {
254
259
// TRAIT ITEM
255
260
self . parse_item_trait ( attrs, lo) ?
@@ -988,6 +993,36 @@ impl<'a> Parser<'a> {
988
993
}
989
994
}
990
995
996
+ /// Recover on `const impl` with `const` already eaten.
997
+ fn recover_const_impl (
998
+ & mut self ,
999
+ const_span : Span ,
1000
+ attrs : & mut Vec < Attribute > ,
1001
+ defaultness : Defaultness ,
1002
+ ) -> PResult < ' a , ItemInfo > {
1003
+ let impl_span = self . token . span ;
1004
+ let mut err = self . expected_ident_found ( ) ;
1005
+ let mut impl_info = self . parse_item_impl ( attrs, defaultness) ?;
1006
+ match impl_info. 1 {
1007
+ // only try to recover if this is implementing a trait for a type
1008
+ ItemKind :: Impl { of_trait : Some ( ref trai) , ref mut constness, .. } => {
1009
+ * constness = Const :: Yes ( const_span) ;
1010
+
1011
+ let before_trait = trai. path . span . shrink_to_lo ( ) ;
1012
+ let const_up_to_impl = const_span. with_hi ( impl_span. lo ( ) ) ;
1013
+ err. multipart_suggestion (
1014
+ "you might have meant to write a const trait impl" ,
1015
+ vec ! [ ( const_up_to_impl, "" . to_owned( ) ) , ( before_trait, "const " . to_owned( ) ) ] ,
1016
+ Applicability :: MaybeIncorrect ,
1017
+ )
1018
+ . emit ( ) ;
1019
+ }
1020
+ ItemKind :: Impl { .. } => return Err ( err) ,
1021
+ _ => unreachable ! ( ) ,
1022
+ }
1023
+ Ok ( impl_info)
1024
+ }
1025
+
991
1026
/// Parse `["const" | ("static" "mut"?)] $ident ":" $ty (= $expr)?` with
992
1027
/// `["const" | ("static" "mut"?)]` already parsed and stored in `m`.
993
1028
///
0 commit comments