Skip to content

Commit 5652b75

Browse files
committed
Call str::eq and <[T]>::eq for match comparisons
We used to call the less efficient `<&str>::eq` and `<&[T]>::eq`.
1 parent 662ef27 commit 5652b75

File tree

3 files changed

+23
-47
lines changed

3 files changed

+23
-47
lines changed

src/librustc_mir/build/matches/test.rs

+21-45
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,9 @@ use rustc::ty::{self, Ty, adjustment::{PointerCast}};
1515
use rustc::ty::util::IntTypeExt;
1616
use rustc::ty::layout::VariantIdx;
1717
use rustc::mir::*;
18-
use rustc::hir::{RangeEnd, Mutability};
18+
use rustc::hir::RangeEnd;
19+
use syntax_pos::symbol::sym;
20+
1921
use std::cmp::Ordering;
2022

2123
impl<'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,

src/librustc_mir/hair/cx/mod.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -163,11 +163,10 @@ impl<'a, 'gcx, 'tcx> Cx<'a, 'gcx, 'tcx> {
163163

164164
pub fn trait_method(&mut self,
165165
trait_def_id: DefId,
166-
method_name: &str,
166+
method_name: Symbol,
167167
self_ty: Ty<'tcx>,
168168
params: &[Kind<'tcx>])
169169
-> (Ty<'tcx>, &'tcx ty::Const<'tcx>) {
170-
let method_name = Symbol::intern(method_name);
171170
let substs = self.tcx.mk_substs_trait(self_ty, params);
172171
for item in self.tcx.associated_items(trait_def_id) {
173172
if item.kind == ty::AssociatedKind::Method && item.ident.name == method_name {

src/libsyntax_pos/symbol.rs

+1
Original file line numberDiff line numberDiff line change
@@ -229,6 +229,7 @@ symbols! {
229229
eh_personality,
230230
eh_unwind_resume,
231231
enable,
232+
eq,
232233
err,
233234
Err,
234235
except,

0 commit comments

Comments
 (0)