@@ -15,7 +15,9 @@ use rustc::ty::{self, Ty, adjustment::{PointerCast}};
15
15
use rustc:: ty:: util:: IntTypeExt ;
16
16
use rustc:: ty:: layout:: VariantIdx ;
17
17
use rustc:: mir:: * ;
18
- use rustc:: hir:: { RangeEnd , Mutability } ;
18
+ use rustc:: hir:: RangeEnd ;
19
+ use syntax_pos:: symbol:: sym;
20
+
19
21
use std:: cmp:: Ordering ;
20
22
21
23
impl < ' a , ' gcx , ' tcx > Builder < ' a , ' gcx , ' tcx > {
@@ -252,10 +254,10 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
252
254
}
253
255
254
256
TestKind :: Eq { value, ty } => {
255
- // Use `PartialEq::eq` instead of `BinOp::Eq`
256
- // (the binop can only handle primitives)
257
257
if let [ success, fail] = * target_blocks {
258
258
if !ty. is_scalar ( ) {
259
+ // Use `PartialEq::eq` instead of `BinOp::Eq`
260
+ // (the binop can only handle primitives)
259
261
self . non_scalar_compare (
260
262
block,
261
263
success,
@@ -368,7 +370,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
368
370
) ;
369
371
}
370
372
371
- /// Compare using `std::compare::PartialEq::eq`
373
+ /// Compare two `&T` values using `<T as std::compare::PartialEq> ::eq`
372
374
fn non_scalar_compare (
373
375
& mut self ,
374
376
block : BasicBlock ,
@@ -381,8 +383,8 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
381
383
) {
382
384
use rustc:: middle:: lang_items:: EqTraitLangItem ;
383
385
384
- let mut expect = self . literal_operand ( source_info. span , ty, value) ;
385
- let val = Operand :: Copy ( place. clone ( ) ) ;
386
+ let mut expect = self . literal_operand ( source_info. span , value . ty , value) ;
387
+ let mut val = Operand :: Copy ( place. clone ( ) ) ;
386
388
387
389
// If we're using `b"..."` as a pattern, we need to insert an
388
390
// unsizing coercion, as the byte string has the type `&[u8; N]`.
@@ -399,7 +401,6 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
399
401
} ;
400
402
let opt_ref_ty = unsize ( ty) ;
401
403
let opt_ref_test_ty = unsize ( value. ty ) ;
402
- let mut place = place. clone ( ) ;
403
404
match ( opt_ref_ty, opt_ref_test_ty) {
404
405
// nothing to do, neither is an array
405
406
( None , None ) => { } ,
@@ -409,56 +410,33 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
409
410
// make both a slice
410
411
ty = tcx. mk_imm_ref ( region, tcx. mk_slice ( elem_ty) ) ;
411
412
if opt_ref_ty. is_some ( ) {
412
- place = self . temp ( ty, source_info. span ) ;
413
+ let temp = self . temp ( ty, source_info. span ) ;
413
414
self . cfg . push_assign (
414
- block, source_info, & place , Rvalue :: Cast (
415
+ block, source_info, & temp , Rvalue :: Cast (
415
416
CastKind :: Pointer ( PointerCast :: Unsize ) , val, ty
416
417
)
417
418
) ;
419
+ val = Operand :: Move ( temp) ;
418
420
}
419
421
if opt_ref_test_ty. is_some ( ) {
420
- let array = self . literal_operand (
421
- source_info. span ,
422
- value. ty ,
423
- value,
424
- ) ;
425
-
426
422
let slice = self . temp ( ty, source_info. span ) ;
427
423
self . cfg . push_assign (
428
424
block, source_info, & slice, Rvalue :: Cast (
429
- CastKind :: Pointer ( PointerCast :: Unsize ) , array , ty
425
+ CastKind :: Pointer ( PointerCast :: Unsize ) , expect , ty
430
426
)
431
427
) ;
432
428
expect = Operand :: Move ( slice) ;
433
429
}
434
430
} ,
435
431
}
436
- let eq_def_id = self . hir . tcx ( ) . require_lang_item ( EqTraitLangItem ) ;
437
- let ( mty, method) = self . hir . trait_method ( eq_def_id, "eq" , ty, & [ ty. into ( ) ] ) ;
438
432
439
- let re_erased = self . hir . tcx ( ) . lifetimes . re_erased ;
440
- // take the argument by reference
441
- let tam = ty:: TypeAndMut {
442
- ty,
443
- mutbl : Mutability :: MutImmutable ,
433
+ let deref_ty = match ty. sty {
434
+ ty:: Ref ( _, deref_ty, _) => deref_ty,
435
+ _ => bug ! ( "non_scalar_compare called on non-reference type: {}" , ty) ,
444
436
} ;
445
- let ref_ty = self . hir . tcx ( ) . mk_ref ( re_erased, tam) ;
446
-
447
- // let lhs_ref_place = &lhs;
448
- let ref_rvalue = Rvalue :: Ref ( re_erased, BorrowKind :: Shared , place) ;
449
- let lhs_ref_place = self . temp ( ref_ty, source_info. span ) ;
450
- self . cfg . push_assign ( block, source_info, & lhs_ref_place, ref_rvalue) ;
451
- let val = Operand :: Move ( lhs_ref_place) ;
452
437
453
- // let rhs_place = rhs;
454
- let rhs_place = self . temp ( ty, source_info. span ) ;
455
- self . cfg . push_assign ( block, source_info, & rhs_place, Rvalue :: Use ( expect) ) ;
456
-
457
- // let rhs_ref_place = &rhs_place;
458
- let ref_rvalue = Rvalue :: Ref ( re_erased, BorrowKind :: Shared , rhs_place) ;
459
- let rhs_ref_place = self . temp ( ref_ty, source_info. span ) ;
460
- self . cfg . push_assign ( block, source_info, & rhs_ref_place, ref_rvalue) ;
461
- let expect = Operand :: Move ( rhs_ref_place) ;
438
+ let eq_def_id = self . hir . tcx ( ) . require_lang_item ( EqTraitLangItem ) ;
439
+ let ( mty, method) = self . hir . trait_method ( eq_def_id, sym:: eq, deref_ty, & [ deref_ty. into ( ) ] ) ;
462
440
463
441
let bool_ty = self . hir . bool_ty ( ) ;
464
442
let eq_result = self . temp ( bool_ty, source_info. span ) ;
@@ -469,12 +447,10 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
469
447
span : source_info. span ,
470
448
ty : mty,
471
449
472
- // FIXME(#54571): This constant comes from user
473
- // input (a constant in a pattern). Are
474
- // there forms where users can add type
475
- // annotations here? For example, an
476
- // associated constant? Need to
477
- // experiment.
450
+ // FIXME(#54571): This constant comes from user input (a
451
+ // constant in a pattern). Are there forms where users can add
452
+ // type annotations here? For example, an associated constant?
453
+ // Need to experiment.
478
454
user_ty : None ,
479
455
480
456
literal : method,
0 commit comments