@@ -141,66 +141,71 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
141
141
self . cfg . terminate ( block, self . source_info ( match_start_span) , terminator) ;
142
142
}
143
143
144
- TestKind :: Eq { value, ty } => {
144
+ TestKind :: Eq { value, mut ty } => {
145
145
let tcx = self . tcx ;
146
146
let success_block = target_block ( TestBranch :: Success ) ;
147
147
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,
153
174
test. span ,
154
- "matching on `String` went through without enabling string_deref_patterns"
155
175
) ;
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;
156
182
}
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 ( ) {
181
187
// Use `PartialEq::eq` instead of `BinOp::Eq`
182
188
// (the binop can only handle primitives)
183
189
self . non_scalar_compare (
184
190
block,
185
191
success_block,
186
192
fail_block,
187
193
source_info,
188
- value,
189
- place,
194
+ expect,
195
+ expect_ty,
196
+ Operand :: Copy ( place) ,
190
197
ty,
191
198
) ;
192
199
} 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) ;
196
201
self . compare (
197
202
block,
198
203
success_block,
199
204
fail_block,
200
205
source_info,
201
206
BinOp :: Eq ,
202
207
expect,
203
- val ,
208
+ Operand :: Copy ( place ) ,
204
209
) ;
205
210
}
206
211
}
@@ -371,12 +376,11 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
371
376
success_block : BasicBlock ,
372
377
fail_block : BasicBlock ,
373
378
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 > ,
376
382
mut ty : Ty < ' tcx > ,
377
383
) {
378
- let mut expect = self . literal_operand ( source_info. span , value) ;
379
-
380
384
// If we're using `b"..."` as a pattern, we need to insert an
381
385
// unsizing coercion, as the byte string has the type `&[u8; N]`.
382
386
//
@@ -391,7 +395,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
391
395
_ => None ,
392
396
} ;
393
397
let opt_ref_ty = unsize ( ty) ;
394
- let opt_ref_test_ty = unsize ( value . ty ( ) ) ;
398
+ let opt_ref_test_ty = unsize ( expect_ty ) ;
395
399
match ( opt_ref_ty, opt_ref_test_ty) {
396
400
// nothing to do, neither is an array
397
401
( None , None ) => { }
@@ -410,11 +414,11 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
410
414
PointerCoercion :: Unsize ,
411
415
CoercionSource :: Implicit ,
412
416
) ,
413
- Operand :: Copy ( val) ,
417
+ val,
414
418
ty,
415
419
) ,
416
420
) ;
417
- val = temp;
421
+ val = Operand :: Copy ( temp) ;
418
422
}
419
423
if opt_ref_test_ty. is_some ( ) {
420
424
let slice = self . temp ( ty, source_info. span ) ;
@@ -470,11 +474,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
470
474
471
475
const_ : method,
472
476
} ) ) ,
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 ( ) ,
478
479
destination : eq_result,
479
480
target : Some ( eq_block) ,
480
481
unwind : UnwindAction :: Continue ,
0 commit comments