@@ -141,66 +141,71 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
141141                self . cfg . terminate ( block,  self . source_info ( match_start_span) ,  terminator) ; 
142142            } 
143143
144-             TestKind :: Eq  {  value,  ty }  => { 
144+             TestKind :: Eq  {  value,  mut   ty }  => { 
145145                let  tcx = self . tcx ; 
146146                let  success_block = target_block ( TestBranch :: Success ) ; 
147147                let  fail_block = target_block ( TestBranch :: Failure ) ; 
148-                 if  let  ty:: Adt ( def,  _)  = ty. kind ( ) 
149-                     && tcx. is_lang_item ( def. did ( ) ,  LangItem :: String ) 
150-                 { 
151-                     if  !tcx. features ( ) . string_deref_patterns ( )  { 
152-                         span_bug ! ( 
148+ 
149+                 let  expect_ty = value. ty ( ) ; 
150+                 let  expect = self . literal_operand ( test. span ,  value) ; 
151+ 
152+                 let  mut  place = place; 
153+                 let  mut  block = block; 
154+                 match  ty. kind ( )  { 
155+                     ty:: Adt ( def,  _)  if  tcx. is_lang_item ( def. did ( ) ,  LangItem :: String )  => { 
156+                         if  !tcx. features ( ) . string_deref_patterns ( )  { 
157+                             span_bug ! ( 
158+                                 test. span, 
159+                                 "matching on `String` went through without enabling string_deref_patterns" 
160+                             ) ; 
161+                         } 
162+                         let  re_erased = tcx. lifetimes . re_erased ; 
163+                         let  ref_str_ty = Ty :: new_imm_ref ( tcx,  re_erased,  tcx. types . str_ ) ; 
164+                         let  ref_str = self . temp ( ref_str_ty,  test. span ) ; 
165+                         let  eq_block = self . cfg . start_new_block ( ) ; 
166+                         // `let ref_str: &str = <String as Deref>::deref(&place);` 
167+                         self . call_deref ( 
168+                             block, 
169+                             eq_block, 
170+                             place, 
171+                             Mutability :: Not , 
172+                             ty, 
173+                             ref_str, 
153174                            test. span , 
154-                             "matching on `String` went through without enabling string_deref_patterns" 
155175                        ) ; 
176+                         // Since we generated a `ref_str = <String as Deref>::deref(&place) -> eq_block` terminator, 
177+                         // we need to add all further statements to `eq_block`. 
178+                         // Similarly, the normal test code should be generated for the `&str`, instead of the `String`. 
179+                         block = eq_block; 
180+                         place = ref_str; 
181+                         ty = ref_str_ty; 
156182                    } 
157-                     let  re_erased = tcx. lifetimes . re_erased ; 
158-                     let  ref_str_ty = Ty :: new_imm_ref ( tcx,  re_erased,  tcx. types . str_ ) ; 
159-                     let  ref_str = self . temp ( ref_str_ty,  test. span ) ; 
160-                     let  eq_block = self . cfg . start_new_block ( ) ; 
161-                     // `let ref_str: &str = <String as Deref>::deref(&place);` 
162-                     self . call_deref ( 
163-                         block, 
164-                         eq_block, 
165-                         place, 
166-                         Mutability :: Not , 
167-                         ty, 
168-                         ref_str, 
169-                         test. span , 
170-                     ) ; 
171-                     self . non_scalar_compare ( 
172-                         eq_block, 
173-                         success_block, 
174-                         fail_block, 
175-                         source_info, 
176-                         value, 
177-                         ref_str, 
178-                         ref_str_ty, 
179-                     ) ; 
180-                 }  else  if  !ty. is_scalar ( )  { 
183+                     _ => { } 
184+                 } 
185+ 
186+                 if  !ty. is_scalar ( )  { 
181187                    // Use `PartialEq::eq` instead of `BinOp::Eq` 
182188                    // (the binop can only handle primitives) 
183189                    self . non_scalar_compare ( 
184190                        block, 
185191                        success_block, 
186192                        fail_block, 
187193                        source_info, 
188-                         value, 
189-                         place, 
194+                         expect, 
195+                         expect_ty, 
196+                         Operand :: Copy ( place) , 
190197                        ty, 
191198                    ) ; 
192199                }  else  { 
193-                     assert_eq ! ( value. ty( ) ,  ty) ; 
194-                     let  expect = self . literal_operand ( test. span ,  value) ; 
195-                     let  val = Operand :: Copy ( place) ; 
200+                     assert_eq ! ( expect_ty,  ty) ; 
196201                    self . compare ( 
197202                        block, 
198203                        success_block, 
199204                        fail_block, 
200205                        source_info, 
201206                        BinOp :: Eq , 
202207                        expect, 
203-                         val , 
208+                         Operand :: Copy ( place ) , 
204209                    ) ; 
205210                } 
206211            } 
@@ -371,12 +376,11 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
371376        success_block :  BasicBlock , 
372377        fail_block :  BasicBlock , 
373378        source_info :  SourceInfo , 
374-         value :  Const < ' tcx > , 
375-         mut  val :  Place < ' tcx > , 
379+         mut  expect :  Operand < ' tcx > , 
380+         expect_ty :  Ty < ' tcx > , 
381+         mut  val :  Operand < ' tcx > , 
376382        mut  ty :  Ty < ' tcx > , 
377383    )  { 
378-         let  mut  expect = self . literal_operand ( source_info. span ,  value) ; 
379- 
380384        // If we're using `b"..."` as a pattern, we need to insert an 
381385        // unsizing coercion, as the byte string has the type `&[u8; N]`. 
382386        // 
@@ -391,7 +395,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
391395            _ => None , 
392396        } ; 
393397        let  opt_ref_ty = unsize ( ty) ; 
394-         let  opt_ref_test_ty = unsize ( value . ty ( ) ) ; 
398+         let  opt_ref_test_ty = unsize ( expect_ty ) ; 
395399        match  ( opt_ref_ty,  opt_ref_test_ty)  { 
396400            // nothing to do, neither is an array 
397401            ( None ,  None )  => { } 
@@ -410,11 +414,11 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
410414                                PointerCoercion :: Unsize , 
411415                                CoercionSource :: Implicit , 
412416                            ) , 
413-                             Operand :: Copy ( val) , 
417+                             val, 
414418                            ty, 
415419                        ) , 
416420                    ) ; 
417-                     val = temp; 
421+                     val = Operand :: Copy ( temp) ; 
418422                } 
419423                if  opt_ref_test_ty. is_some ( )  { 
420424                    let  slice = self . temp ( ty,  source_info. span ) ; 
@@ -470,11 +474,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
470474
471475                const_ :  method, 
472476            } ) ) , 
473-             args :  [ Spanned  {  node :  Operand :: Copy ( val) ,  span :  DUMMY_SP  } ,  Spanned  { 
474-                 node :  expect, 
475-                 span :  DUMMY_SP , 
476-             } ] 
477-             . into ( ) , 
477+             args :  [ Spanned  {  node :  val,  span :  DUMMY_SP  } ,  Spanned  {  node :  expect,  span :  DUMMY_SP  } ] 
478+                 . into ( ) , 
478479            destination :  eq_result, 
479480            target :  Some ( eq_block) , 
480481            unwind :  UnwindAction :: Continue , 
0 commit comments