@@ -393,49 +393,18 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
393
393
Place :: ty_from( local, proj_base, self . body, self . infcx. tcx) . ty
394
394
) ) ;
395
395
396
- let captured_place = self . upvars [ upvar_index. index ( ) ] ;
397
-
398
- err. span_label ( span, format ! ( "cannot {act}" ) ) ;
399
-
400
- let upvar_hir_id = captured_place. get_root_variable ( ) ;
401
-
402
- if let Node :: Pat ( pat) = self . infcx . tcx . hir_node ( upvar_hir_id)
403
- && let hir:: PatKind :: Binding ( hir:: BindingMode :: NONE , _, upvar_ident, _) =
404
- pat. kind
405
- {
406
- if upvar_ident. name == kw:: SelfLower {
407
- for ( _, node) in self . infcx . tcx . hir_parent_iter ( upvar_hir_id) {
408
- if let Some ( fn_decl) = node. fn_decl ( ) {
409
- if !matches ! (
410
- fn_decl. implicit_self,
411
- hir:: ImplicitSelfKind :: RefImm | hir:: ImplicitSelfKind :: RefMut
412
- ) {
413
- err. span_suggestion_verbose (
414
- upvar_ident. span . shrink_to_lo ( ) ,
415
- "consider changing this to be mutable" ,
416
- "mut " ,
417
- Applicability :: MachineApplicable ,
418
- ) ;
419
- break ;
420
- }
421
- }
422
- }
423
- } else {
424
- err. span_suggestion_verbose (
425
- upvar_ident. span . shrink_to_lo ( ) ,
426
- "consider changing this to be mutable" ,
427
- "mut " ,
428
- Applicability :: MachineApplicable ,
429
- ) ;
430
- }
431
- }
396
+ self . suggest_mutable_upvar ( * upvar_index, the_place_err, & mut err, span, act) ;
397
+ }
432
398
433
- let tcx = self . infcx . tcx ;
434
- if let ty:: Ref ( _, ty, Mutability :: Mut ) = the_place_err. ty ( self . body , tcx) . ty . kind ( )
435
- && let ty:: Closure ( id, _) = * ty. kind ( )
436
- {
437
- self . show_mutating_upvar ( tcx, id. expect_local ( ) , the_place_err, & mut err) ;
438
- }
399
+ PlaceRef { local, projection : [ ] }
400
+ if let Some ( upvar_index) = self
401
+ . body
402
+ . local_upvar_map
403
+ . iter_enumerated ( )
404
+ . filter_map ( |( field, & local) | local. map ( |local| ( field, local) ) )
405
+ . find_map ( |( field, relocated) | ( relocated == local) . then_some ( field) ) =>
406
+ {
407
+ self . suggest_mutable_upvar ( upvar_index, the_place_err, & mut err, span, act) ;
439
408
}
440
409
441
410
// complete hack to approximate old AST-borrowck
@@ -542,6 +511,58 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
542
511
}
543
512
}
544
513
514
+ fn suggest_mutable_upvar (
515
+ & self ,
516
+ upvar_index : FieldIdx ,
517
+ the_place_err : PlaceRef < ' tcx > ,
518
+ err : & mut Diag < ' infcx > ,
519
+ span : Span ,
520
+ act : & str ,
521
+ ) {
522
+ let captured_place = self . upvars [ upvar_index. index ( ) ] ;
523
+
524
+ err. span_label ( span, format ! ( "cannot {act}" ) ) ;
525
+
526
+ let upvar_hir_id = captured_place. get_root_variable ( ) ;
527
+
528
+ if let Node :: Pat ( pat) = self . infcx . tcx . hir_node ( upvar_hir_id)
529
+ && let hir:: PatKind :: Binding ( hir:: BindingMode :: NONE , _, upvar_ident, _) = pat. kind
530
+ {
531
+ if upvar_ident. name == kw:: SelfLower {
532
+ for ( _, node) in self . infcx . tcx . hir_parent_iter ( upvar_hir_id) {
533
+ if let Some ( fn_decl) = node. fn_decl ( ) {
534
+ if !matches ! (
535
+ fn_decl. implicit_self,
536
+ hir:: ImplicitSelfKind :: RefImm | hir:: ImplicitSelfKind :: RefMut
537
+ ) {
538
+ err. span_suggestion_verbose (
539
+ upvar_ident. span . shrink_to_lo ( ) ,
540
+ "consider changing this to be mutable" ,
541
+ "mut " ,
542
+ Applicability :: MachineApplicable ,
543
+ ) ;
544
+ break ;
545
+ }
546
+ }
547
+ }
548
+ } else {
549
+ err. span_suggestion_verbose (
550
+ upvar_ident. span . shrink_to_lo ( ) ,
551
+ "consider changing this to be mutable" ,
552
+ "mut " ,
553
+ Applicability :: MachineApplicable ,
554
+ ) ;
555
+ }
556
+ }
557
+
558
+ let tcx = self . infcx . tcx ;
559
+ if let ty:: Ref ( _, ty, Mutability :: Mut ) = the_place_err. ty ( self . body , tcx) . ty . kind ( )
560
+ && let ty:: Closure ( id, _) = * ty. kind ( )
561
+ {
562
+ self . show_mutating_upvar ( tcx, id. expect_local ( ) , the_place_err, err) ;
563
+ }
564
+ }
565
+
545
566
/// Suggest `map[k] = v` => `map.insert(k, v)` and the like.
546
567
fn suggest_map_index_mut_alternatives ( & self , ty : Ty < ' tcx > , err : & mut Diag < ' infcx > , span : Span ) {
547
568
let Some ( adt) = ty. ty_adt_def ( ) else { return } ;
0 commit comments