@@ -64,12 +64,29 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
64
64
Place :: ty_from( local, proj_base, self . body, self . infcx. tcx) . ty
65
65
) ) ;
66
66
67
- item_msg = format ! ( "`{}`" , access_place_desc. unwrap( ) ) ;
68
- if self . is_upvar_field_projection ( access_place. as_ref ( ) ) . is_some ( ) {
69
- reason = ", as it is not declared as mutable" . to_string ( ) ;
67
+ let imm_borrow_derefed = self . upvars [ upvar_index. index ( ) ]
68
+ . place
69
+ . place
70
+ . deref_tys ( )
71
+ . any ( |ty| matches ! ( ty. kind( ) , ty:: Ref ( .., hir:: Mutability :: Not ) ) ) ;
72
+
73
+ // If the place is immutable then:
74
+ //
75
+ // - Either we deref a immutable ref to get to our final place.
76
+ // - We don't capture derefs of raw ptrs
77
+ // - Or the final place is immut because the root variable of the capture
78
+ // isn't marked mut and we should suggest that to the user.
79
+ if imm_borrow_derefed {
80
+ // If we deref an immutable ref then the suggestion here doesn't help.
81
+ return ;
70
82
} else {
71
- let name = self . upvars [ upvar_index. index ( ) ] . name ;
72
- reason = format ! ( ", as `{}` is not declared as mutable" , name) ;
83
+ item_msg = format ! ( "`{}`" , access_place_desc. unwrap( ) ) ;
84
+ if self . is_upvar_field_projection ( access_place. as_ref ( ) ) . is_some ( ) {
85
+ reason = ", as it is not declared as mutable" . to_string ( ) ;
86
+ } else {
87
+ let name = self . upvars [ upvar_index. index ( ) ] . name ;
88
+ reason = format ! ( ", as `{}` is not declared as mutable" , name) ;
89
+ }
73
90
}
74
91
}
75
92
@@ -259,9 +276,12 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
259
276
Place :: ty_from( local, proj_base, self . body, self . infcx. tcx) . ty
260
277
) ) ;
261
278
279
+ let captured_place = & self . upvars [ upvar_index. index ( ) ] . place ;
280
+
262
281
err. span_label ( span, format ! ( "cannot {ACT}" , ACT = act) ) ;
263
282
264
- let upvar_hir_id = self . upvars [ upvar_index. index ( ) ] . var_hir_id ;
283
+ let upvar_hir_id = captured_place. get_root_variable ( ) ;
284
+
265
285
if let Some ( Node :: Binding ( pat) ) = self . infcx . tcx . hir ( ) . find ( upvar_hir_id) {
266
286
if let hir:: PatKind :: Binding (
267
287
hir:: BindingAnnotation :: Unannotated ,
0 commit comments