@@ -42,6 +42,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
4242 TestKind :: Len { len : len as u64 , op }
4343 }
4444
45+ TestCase :: Deref { temp } => TestKind :: Deref { temp } ,
46+
4547 TestCase :: Or { .. } => bug ! ( "or-patterns should have already been handled" ) ,
4648
4749 TestCase :: Irrefutable { .. } => span_bug ! (
@@ -143,35 +145,11 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
143145 ) ;
144146 }
145147 let re_erased = tcx. lifetimes . re_erased ;
146- let ref_string = self . temp ( Ty :: new_imm_ref ( tcx, re_erased, ty) , test. span ) ;
147148 let ref_str_ty = Ty :: new_imm_ref ( tcx, re_erased, tcx. types . str_ ) ;
148149 let ref_str = self . temp ( ref_str_ty, test. span ) ;
149- let deref = tcx. require_lang_item ( LangItem :: Deref , None ) ;
150- let method = trait_method ( tcx, deref, sym:: deref, [ ty] ) ;
151150 let eq_block = self . cfg . start_new_block ( ) ;
152- self . cfg . push_assign (
153- block,
154- source_info,
155- ref_string,
156- Rvalue :: Ref ( re_erased, BorrowKind :: Shared , place) ,
157- ) ;
158- self . cfg . terminate (
159- block,
160- source_info,
161- TerminatorKind :: Call {
162- func : Operand :: Constant ( Box :: new ( ConstOperand {
163- span : test. span ,
164- user_ty : None ,
165- const_ : method,
166- } ) ) ,
167- args : vec ! [ Spanned { node: Operand :: Move ( ref_string) , span: DUMMY_SP } ] ,
168- destination : ref_str,
169- target : Some ( eq_block) ,
170- unwind : UnwindAction :: Continue ,
171- call_source : CallSource :: Misc ,
172- fn_span : source_info. span ,
173- } ,
174- ) ;
151+ // `let ref_str: &str = <String as Deref>::deref(&place);`
152+ self . call_deref ( block, eq_block, place, ty, ref_str, test. span ) ;
175153 self . non_scalar_compare (
176154 eq_block,
177155 success_block,
@@ -270,9 +248,57 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
270248 Operand :: Move ( expected) ,
271249 ) ;
272250 }
251+
252+ TestKind :: Deref { temp } => {
253+ let ty = place_ty. ty ;
254+ let target = target_block ( TestBranch :: Success ) ;
255+ self . call_deref ( block, target, place, ty, temp, test. span ) ;
256+ }
273257 }
274258 }
275259
260+ /// Perform `let temp = <ty as Deref>::deref(&place)`.
261+ pub ( super ) fn call_deref (
262+ & mut self ,
263+ block : BasicBlock ,
264+ target_block : BasicBlock ,
265+ place : Place < ' tcx > ,
266+ ty : Ty < ' tcx > ,
267+ temp : Place < ' tcx > ,
268+ span : Span ,
269+ ) {
270+ let source_info = self . source_info ( span) ;
271+ 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) ;
275+ // `let ref_src = &src_place;`
276+ self . cfg . push_assign (
277+ block,
278+ source_info,
279+ ref_src,
280+ Rvalue :: Ref ( re_erased, BorrowKind :: Shared , place) ,
281+ ) ;
282+ // `let temp = <Ty as Deref>::deref(ref_src);`
283+ self . cfg . terminate (
284+ block,
285+ source_info,
286+ TerminatorKind :: Call {
287+ func : Operand :: Constant ( Box :: new ( ConstOperand {
288+ span,
289+ user_ty : None ,
290+ const_ : method,
291+ } ) ) ,
292+ args : vec ! [ Spanned { node: Operand :: Move ( ref_src) , span } ] ,
293+ destination : temp,
294+ target : Some ( target_block) ,
295+ unwind : UnwindAction :: Continue ,
296+ call_source : CallSource :: Misc ,
297+ fn_span : source_info. span ,
298+ } ,
299+ ) ;
300+ }
301+
276302 /// Compare using the provided built-in comparison operator
277303 fn compare (
278304 & mut self ,
@@ -660,13 +686,21 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
660686 }
661687 }
662688
689+ ( TestKind :: Deref { temp : test_temp } , TestCase :: Deref { temp } )
690+ if test_temp == temp =>
691+ {
692+ fully_matched = true ;
693+ Some ( TestBranch :: Success )
694+ }
695+
663696 (
664697 TestKind :: Switch { .. }
665698 | TestKind :: SwitchInt { .. }
666699 | TestKind :: If
667700 | TestKind :: Len { .. }
668701 | TestKind :: Range { .. }
669- | TestKind :: Eq { .. } ,
702+ | TestKind :: Eq { .. }
703+ | TestKind :: Deref { .. } ,
670704 _,
671705 ) => {
672706 fully_matched = false ;
0 commit comments