@@ -42,7 +42,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
4242 TestKind :: Len { len : len as u64 , op }
4343 }
4444
45- TestCase :: Deref { temp } => TestKind :: Deref { temp } ,
45+ TestCase :: Deref { temp, mutability } => TestKind :: Deref { temp, mutability } ,
4646
4747 TestCase :: Or { .. } => bug ! ( "or-patterns should have already been handled" ) ,
4848
@@ -149,7 +149,15 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
149149 let ref_str = self . temp ( ref_str_ty, test. span ) ;
150150 let eq_block = self . cfg . start_new_block ( ) ;
151151 // `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+ ) ;
153161 self . non_scalar_compare (
154162 eq_block,
155163 success_block,
@@ -249,37 +257,46 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
249257 ) ;
250258 }
251259
252- TestKind :: Deref { temp } => {
260+ TestKind :: Deref { temp, mutability } => {
253261 let ty = place_ty. ty ;
254262 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 ) ;
256264 }
257265 }
258266 }
259267
260268 /// Perform `let temp = <ty as Deref>::deref(&place)`.
269+ /// or `let temp = <ty as DerefMut>::deref_mut(&mut place)`.
261270 pub ( super ) fn call_deref (
262271 & mut self ,
263272 block : BasicBlock ,
264273 target_block : BasicBlock ,
265274 place : Place < ' tcx > ,
275+ mutability : Mutability ,
266276 ty : Ty < ' tcx > ,
267277 temp : Place < ' tcx > ,
268278 span : Span ,
269279 ) {
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) ;
270285 let source_info = self . source_info ( span) ;
271286 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) ;
275290 // `let ref_src = &src_place;`
291+ // or `let ref_src = &mut src_place;`
276292 self . cfg . push_assign (
277293 block,
278294 source_info,
279295 ref_src,
280- Rvalue :: Ref ( re_erased, BorrowKind :: Shared , place) ,
296+ Rvalue :: Ref ( re_erased, borrow_kind , place) ,
281297 ) ;
282298 // `let temp = <Ty as Deref>::deref(ref_src);`
299+ // or `let temp = <Ty as DerefMut>::deref_mut(ref_src);`
283300 self . cfg . terminate (
284301 block,
285302 source_info,
@@ -686,7 +703,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
686703 }
687704 }
688705
689- ( TestKind :: Deref { temp : test_temp } , TestCase :: Deref { temp } )
706+ ( TestKind :: Deref { temp : test_temp, .. } , TestCase :: Deref { temp, .. } )
690707 if test_temp == temp =>
691708 {
692709 fully_matched = true ;
0 commit comments