@@ -15,7 +15,9 @@ use rustc::ty::{self, Ty, adjustment::{PointerCast}};
1515use rustc:: ty:: util:: IntTypeExt ;
1616use rustc:: ty:: layout:: VariantIdx ;
1717use rustc:: mir:: * ;
18- use rustc:: hir:: { RangeEnd , Mutability } ;
18+ use rustc:: hir:: RangeEnd ;
19+ use syntax_pos:: symbol:: sym;
20+
1921use std:: cmp:: Ordering ;
2022
2123impl < ' a , ' gcx , ' tcx > Builder < ' a , ' gcx , ' tcx > {
@@ -252,10 +254,10 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
252254 }
253255
254256 TestKind :: Eq { value, ty } => {
255- // Use `PartialEq::eq` instead of `BinOp::Eq`
256- // (the binop can only handle primitives)
257257 if let [ success, fail] = * target_blocks {
258258 if !ty. is_scalar ( ) {
259+ // Use `PartialEq::eq` instead of `BinOp::Eq`
260+ // (the binop can only handle primitives)
259261 self . non_scalar_compare (
260262 block,
261263 success,
@@ -368,7 +370,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
368370 ) ;
369371 }
370372
371- /// Compare using `std::compare::PartialEq::eq`
373+ /// Compare two `&T` values using `<T as std::compare::PartialEq> ::eq`
372374 fn non_scalar_compare (
373375 & mut self ,
374376 block : BasicBlock ,
@@ -381,8 +383,8 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
381383 ) {
382384 use rustc:: middle:: lang_items:: EqTraitLangItem ;
383385
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 ( ) ) ;
386388
387389 // If we're using `b"..."` as a pattern, we need to insert an
388390 // unsizing coercion, as the byte string has the type `&[u8; N]`.
@@ -399,7 +401,6 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
399401 } ;
400402 let opt_ref_ty = unsize ( ty) ;
401403 let opt_ref_test_ty = unsize ( value. ty ) ;
402- let mut place = place. clone ( ) ;
403404 match ( opt_ref_ty, opt_ref_test_ty) {
404405 // nothing to do, neither is an array
405406 ( None , None ) => { } ,
@@ -409,56 +410,33 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
409410 // make both a slice
410411 ty = tcx. mk_imm_ref ( region, tcx. mk_slice ( elem_ty) ) ;
411412 if opt_ref_ty. is_some ( ) {
412- place = self . temp ( ty, source_info. span ) ;
413+ let temp = self . temp ( ty, source_info. span ) ;
413414 self . cfg . push_assign (
414- block, source_info, & place , Rvalue :: Cast (
415+ block, source_info, & temp , Rvalue :: Cast (
415416 CastKind :: Pointer ( PointerCast :: Unsize ) , val, ty
416417 )
417418 ) ;
419+ val = Operand :: Move ( temp) ;
418420 }
419421 if opt_ref_test_ty. is_some ( ) {
420- let array = self . literal_operand (
421- source_info. span ,
422- value. ty ,
423- value,
424- ) ;
425-
426422 let slice = self . temp ( ty, source_info. span ) ;
427423 self . cfg . push_assign (
428424 block, source_info, & slice, Rvalue :: Cast (
429- CastKind :: Pointer ( PointerCast :: Unsize ) , array , ty
425+ CastKind :: Pointer ( PointerCast :: Unsize ) , expect , ty
430426 )
431427 ) ;
432428 expect = Operand :: Move ( slice) ;
433429 }
434430 } ,
435431 }
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 ( ) ] ) ;
438432
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) ,
444436 } ;
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) ;
452437
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 ( ) ] ) ;
462440
463441 let bool_ty = self . hir . bool_ty ( ) ;
464442 let eq_result = self . temp ( bool_ty, source_info. span ) ;
@@ -469,12 +447,10 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
469447 span : source_info. span ,
470448 ty : mty,
471449
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.
478454 user_ty : None ,
479455
480456 literal : method,
0 commit comments