@@ -4022,23 +4022,74 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
40224022 if let Some ( decl) = local_decl
40234023 && decl. can_be_made_mutable ( )
40244024 {
4025- let is_for_loop = matches ! (
4026- decl. local_info( ) ,
4027- LocalInfo :: User ( BindingForm :: Var ( VarBindingForm {
4028- opt_match_place: Some ( ( _, match_span) ) ,
4029- ..
4030- } ) ) if matches!( match_span. desugaring_kind( ) , Some ( DesugaringKind :: ForLoop ) )
4031- ) ;
4032- let message = if is_for_loop
4025+ let mut is_for_loop = false ;
4026+ let mut is_ref_pattern = false ;
4027+ if let LocalInfo :: User ( BindingForm :: Var ( VarBindingForm {
4028+ opt_match_place : Some ( ( _, match_span) ) ,
4029+ ..
4030+ } ) ) = * decl. local_info ( )
4031+ {
4032+ if matches ! ( match_span. desugaring_kind( ) , Some ( DesugaringKind :: ForLoop ) ) {
4033+ is_for_loop = true ;
4034+
4035+ if let Some ( body) = self . infcx . tcx . hir_maybe_body_owned_by ( self . mir_def_id ( ) ) {
4036+ struct RefPatternFinder < ' tcx > {
4037+ tcx : TyCtxt < ' tcx > ,
4038+ binding_span : Span ,
4039+ is_ref_pattern : bool ,
4040+ }
4041+
4042+ impl < ' tcx > Visitor < ' tcx > for RefPatternFinder < ' tcx > {
4043+ type NestedFilter = OnlyBodies ;
4044+
4045+ fn maybe_tcx ( & mut self ) -> Self :: MaybeTyCtxt {
4046+ self . tcx
4047+ }
4048+
4049+ fn visit_pat ( & mut self , pat : & ' tcx hir:: Pat < ' tcx > ) {
4050+ if !self . is_ref_pattern
4051+ && let hir:: PatKind :: Binding ( _, _, ident, _) = pat. kind
4052+ && ident. span == self . binding_span
4053+ {
4054+ self . is_ref_pattern =
4055+ self . tcx . hir_parent_iter ( pat. hir_id ) . any ( |( _, node) | {
4056+ matches ! (
4057+ node,
4058+ hir:: Node :: Pat ( hir:: Pat {
4059+ kind: hir:: PatKind :: Ref ( ..) ,
4060+ ..
4061+ } )
4062+ )
4063+ } ) ;
4064+ }
4065+ hir:: intravisit:: walk_pat ( self , pat) ;
4066+ }
4067+ }
4068+
4069+ let mut finder = RefPatternFinder {
4070+ tcx : self . infcx . tcx ,
4071+ binding_span : decl. source_info . span ,
4072+ is_ref_pattern : false ,
4073+ } ;
4074+
4075+ finder. visit_body ( body) ;
4076+ is_ref_pattern = finder. is_ref_pattern ;
4077+ }
4078+ }
4079+ }
4080+
4081+ let ( span, message) = if is_for_loop
4082+ && is_ref_pattern
40334083 && let Ok ( binding_name) =
40344084 self . infcx . tcx . sess . source_map ( ) . span_to_snippet ( decl. source_info . span )
40354085 {
4036- format ! ( "(mut {}) " , binding_name)
4086+ ( decl . source_info . span , format ! ( "(mut {})" , binding_name) )
40374087 } else {
4038- "mut " . to_string ( )
4088+ ( decl . source_info . span . shrink_to_lo ( ) , "mut " . to_string ( ) )
40394089 } ;
4090+
40404091 err. span_suggestion_verbose (
4041- decl . source_info . span . shrink_to_lo ( ) ,
4092+ span,
40424093 "consider making this binding mutable" ,
40434094 message,
40444095 Applicability :: MachineApplicable ,
0 commit comments