@@ -42,7 +42,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
42
42
TestKind :: Len { len : len as u64 , op }
43
43
}
44
44
45
- TestCase :: Deref { temp } => TestKind :: Deref { temp } ,
45
+ TestCase :: Deref { temp, mutability } => TestKind :: Deref { temp, mutability } ,
46
46
47
47
TestCase :: Or { .. } => bug ! ( "or-patterns should have already been handled" ) ,
48
48
@@ -149,7 +149,15 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
149
149
let ref_str = self . temp ( ref_str_ty, test. span ) ;
150
150
let eq_block = self . cfg . start_new_block ( ) ;
151
151
// `let ref_str: &str = <String as Deref>::deref(&place);`
152
- self . call_deref ( block, eq_block, place, ty, ref_str, test. span ) ;
152
+ self . call_deref (
153
+ block,
154
+ eq_block,
155
+ place,
156
+ Mutability :: Not ,
157
+ ty,
158
+ ref_str,
159
+ test. span ,
160
+ ) ;
153
161
self . non_scalar_compare (
154
162
eq_block,
155
163
success_block,
@@ -249,37 +257,46 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
249
257
) ;
250
258
}
251
259
252
- TestKind :: Deref { temp } => {
260
+ TestKind :: Deref { temp, mutability } => {
253
261
let ty = place_ty. ty ;
254
262
let target = target_block ( TestBranch :: Success ) ;
255
- self . call_deref ( block, target, place, ty, temp, test. span ) ;
263
+ self . call_deref ( block, target, place, mutability , ty, temp, test. span ) ;
256
264
}
257
265
}
258
266
}
259
267
260
268
/// Perform `let temp = <ty as Deref>::deref(&place)`.
269
+ /// or `let temp = <ty as DerefMut>::deref_mut(&mut place)`.
261
270
pub ( super ) fn call_deref (
262
271
& mut self ,
263
272
block : BasicBlock ,
264
273
target_block : BasicBlock ,
265
274
place : Place < ' tcx > ,
275
+ mutability : Mutability ,
266
276
ty : Ty < ' tcx > ,
267
277
temp : Place < ' tcx > ,
268
278
span : Span ,
269
279
) {
280
+ let ( trait_item, method) = match mutability {
281
+ Mutability :: Not => ( LangItem :: Deref , sym:: deref) ,
282
+ Mutability :: Mut => ( LangItem :: DerefMut , sym:: deref_mut) ,
283
+ } ;
284
+ let borrow_kind = super :: util:: ref_pat_borrow_kind ( mutability) ;
270
285
let source_info = self . source_info ( span) ;
271
286
let re_erased = self . tcx . lifetimes . re_erased ;
272
- let deref = self . tcx . require_lang_item ( LangItem :: Deref , None ) ;
273
- let method = trait_method ( self . tcx , deref , sym :: deref , [ ty] ) ;
274
- let ref_src = self . temp ( Ty :: new_imm_ref ( self . tcx , re_erased, ty) , span) ;
287
+ let trait_item = self . tcx . require_lang_item ( trait_item , None ) ;
288
+ let method = trait_method ( self . tcx , trait_item , method , [ ty] ) ;
289
+ let ref_src = self . temp ( Ty :: new_ref ( self . tcx , re_erased, ty, mutability ) , span) ;
275
290
// `let ref_src = &src_place;`
291
+ // or `let ref_src = &mut src_place;`
276
292
self . cfg . push_assign (
277
293
block,
278
294
source_info,
279
295
ref_src,
280
- Rvalue :: Ref ( re_erased, BorrowKind :: Shared , place) ,
296
+ Rvalue :: Ref ( re_erased, borrow_kind , place) ,
281
297
) ;
282
298
// `let temp = <Ty as Deref>::deref(ref_src);`
299
+ // or `let temp = <Ty as DerefMut>::deref_mut(ref_src);`
283
300
self . cfg . terminate (
284
301
block,
285
302
source_info,
@@ -686,7 +703,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
686
703
}
687
704
}
688
705
689
- ( TestKind :: Deref { temp : test_temp } , TestCase :: Deref { temp } )
706
+ ( TestKind :: Deref { temp : test_temp, .. } , TestCase :: Deref { temp, .. } )
690
707
if test_temp == temp =>
691
708
{
692
709
fully_matched = true ;
0 commit comments