@@ -393,7 +393,7 @@ impl<'a> Parser<'a> {
393393 let and_span = self . prev_token . span ;
394394 let mut opt_lifetime =
395395 if self . check_lifetime ( ) { Some ( self . expect_lifetime ( ) ) } else { None } ;
396- let mutbl = self . parse_mutability ( ) ;
396+ let mut mutbl = self . parse_mutability ( ) ;
397397 if self . token . is_lifetime ( ) && mutbl == Mutability :: Mut && opt_lifetime. is_none ( ) {
398398 // A lifetime is invalid here: it would be part of a bare trait bound, which requires
399399 // it to be followed by a plus, but we disallow plus in the pointee type.
@@ -417,6 +417,26 @@ impl<'a> Parser<'a> {
417417
418418 opt_lifetime = Some ( self . expect_lifetime ( ) ) ;
419419 }
420+ } else if self . token . is_keyword ( kw:: Dyn )
421+ && mutbl == Mutability :: Not
422+ && self . look_ahead ( 1 , |t| t. is_keyword ( kw:: Mut ) )
423+ {
424+ // We have `&dyn mut ...`, which is invalid and should be `&mut dyn ...`.
425+ let span = and_span. to ( self . look_ahead ( 1 , |t| t. span ) ) ;
426+ let mut err = self . struct_span_err ( span, "`mut` must precede `dyn`" ) ;
427+ err. span_suggestion (
428+ span,
429+ "place `mut` before `dyn`" ,
430+ "&mut dyn" . to_string ( ) ,
431+ Applicability :: MachineApplicable ,
432+ ) ;
433+ err. emit ( ) ;
434+
435+ // Recovery
436+ mutbl = Mutability :: Mut ;
437+ let ( dyn_tok, dyn_tok_sp) = ( self . token . clone ( ) , self . token_spacing ) ;
438+ self . bump ( ) ;
439+ self . bump_with ( ( dyn_tok, dyn_tok_sp) ) ;
420440 }
421441 let ty = self . parse_ty_no_plus ( ) ?;
422442 Ok ( TyKind :: Rptr ( opt_lifetime, MutTy { ty, mutbl } ) )
0 commit comments