about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorMatthew Jasper <mjjasper1@gmail.com>2019-05-25 16:26:57 +0100
committerMatthew Jasper <mjjasper1@gmail.com>2019-06-13 21:05:21 +0100
commitef1fc86b521f457f736a8e110c851133cd953149 (patch)
treeae2cadbdda96b33e813c66c98e1989c1c767c873 /src
parentda22793a35b725e2fe2f7e2ac1d808404c39c4aa (diff)
downloadrust-ef1fc86b521f457f736a8e110c851133cd953149.tar.gz
rust-ef1fc86b521f457f736a8e110c851133cd953149.zip
Call str::eq and <[T]>::eq for match comparisons
We used to call the less efficient `<&str>::eq` and `<&[T]>::eq`.
Diffstat (limited to 'src')
-rw-r--r--src/librustc_mir/build/matches/test.rs66
-rw-r--r--src/librustc_mir/hair/cx/mod.rs3
-rw-r--r--src/libsyntax_pos/symbol.rs1
3 files changed, 23 insertions, 47 deletions
diff --git a/src/librustc_mir/build/matches/test.rs b/src/librustc_mir/build/matches/test.rs
index bbaf92bf9f5..47f0aa82a41 100644
--- a/src/librustc_mir/build/matches/test.rs
+++ b/src/librustc_mir/build/matches/test.rs
@@ -15,7 +15,9 @@ use rustc::ty::{self, Ty, adjustment::{PointerCast}};
 use rustc::ty::util::IntTypeExt;
 use rustc::ty::layout::VariantIdx;
 use rustc::mir::*;
-use rustc::hir::{RangeEnd, Mutability};
+use rustc::hir::RangeEnd;
+use syntax_pos::symbol::sym;
+
 use std::cmp::Ordering;
 
 impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
@@ -252,10 +254,10 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
             }
 
             TestKind::Eq { value, ty } => {
-                // Use `PartialEq::eq` instead of `BinOp::Eq`
-                // (the binop can only handle primitives)
                 if let [success, fail] = *target_blocks {
                     if !ty.is_scalar() {
+                        // Use `PartialEq::eq` instead of `BinOp::Eq`
+                        // (the binop can only handle primitives)
                         self.non_scalar_compare(
                             block,
                             success,
@@ -368,7 +370,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
         );
     }
 
-    /// Compare using `std::compare::PartialEq::eq`
+    /// Compare two `&T` values using `<T as std::compare::PartialEq>::eq`
     fn non_scalar_compare(
         &mut self,
         block: BasicBlock,
@@ -381,8 +383,8 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
     ) {
         use rustc::middle::lang_items::EqTraitLangItem;
 
-        let mut expect = self.literal_operand(source_info.span, ty, value);
-        let val = Operand::Copy(place.clone());
+        let mut expect = self.literal_operand(source_info.span, value.ty, value);
+        let mut val = Operand::Copy(place.clone());
 
         // If we're using `b"..."` as a pattern, we need to insert an
         // unsizing coercion, as the byte string has the type `&[u8; N]`.
@@ -399,7 +401,6 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
         };
         let opt_ref_ty = unsize(ty);
         let opt_ref_test_ty = unsize(value.ty);
-        let mut place = place.clone();
         match (opt_ref_ty, opt_ref_test_ty) {
             // nothing to do, neither is an array
             (None, None) => {},
@@ -409,56 +410,33 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
                 // make both a slice
                 ty = tcx.mk_imm_ref(region, tcx.mk_slice(elem_ty));
                 if opt_ref_ty.is_some() {
-                    place = self.temp(ty, source_info.span);
+                    let temp = self.temp(ty, source_info.span);
                     self.cfg.push_assign(
-                        block, source_info, &place, Rvalue::Cast(
+                        block, source_info, &temp, Rvalue::Cast(
                             CastKind::Pointer(PointerCast::Unsize), val, ty
                         )
                     );
+                    val = Operand::Move(temp);
                 }
                 if opt_ref_test_ty.is_some() {
-                    let array = self.literal_operand(
-                        source_info.span,
-                        value.ty,
-                        value,
-                    );
-
                     let slice = self.temp(ty, source_info.span);
                     self.cfg.push_assign(
                         block, source_info, &slice, Rvalue::Cast(
-                            CastKind::Pointer(PointerCast::Unsize), array, ty
+                            CastKind::Pointer(PointerCast::Unsize), expect, ty
                         )
                     );
                     expect = Operand::Move(slice);
                 }
             },
         }
-        let eq_def_id = self.hir.tcx().require_lang_item(EqTraitLangItem);
-        let (mty, method) = self.hir.trait_method(eq_def_id, "eq", ty, &[ty.into()]);
 
-        let re_erased = self.hir.tcx().lifetimes.re_erased;
-        // take the argument by reference
-        let tam = ty::TypeAndMut {
-            ty,
-            mutbl: Mutability::MutImmutable,
+        let deref_ty = match ty.sty {
+            ty::Ref(_, deref_ty, _) => deref_ty,
+            _ => bug!("non_scalar_compare called on non-reference type: {}", ty),
         };
-        let ref_ty = self.hir.tcx().mk_ref(re_erased, tam);
-
-        // let lhs_ref_place = &lhs;
-        let ref_rvalue = Rvalue::Ref(re_erased, BorrowKind::Shared, place);
-        let lhs_ref_place = self.temp(ref_ty, source_info.span);
-        self.cfg.push_assign(block, source_info, &lhs_ref_place, ref_rvalue);
-        let val = Operand::Move(lhs_ref_place);
 
-        // let rhs_place = rhs;
-        let rhs_place = self.temp(ty, source_info.span);
-        self.cfg.push_assign(block, source_info, &rhs_place, Rvalue::Use(expect));
-
-        // let rhs_ref_place = &rhs_place;
-        let ref_rvalue = Rvalue::Ref(re_erased, BorrowKind::Shared, rhs_place);
-        let rhs_ref_place = self.temp(ref_ty, source_info.span);
-        self.cfg.push_assign(block, source_info, &rhs_ref_place, ref_rvalue);
-        let expect = Operand::Move(rhs_ref_place);
+        let eq_def_id = self.hir.tcx().require_lang_item(EqTraitLangItem);
+        let (mty, method) = self.hir.trait_method(eq_def_id, sym::eq, deref_ty, &[deref_ty.into()]);
 
         let bool_ty = self.hir.bool_ty();
         let eq_result = self.temp(bool_ty, source_info.span);
@@ -469,12 +447,10 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
                 span: source_info.span,
                 ty: mty,
 
-                // FIXME(#54571): This constant comes from user
-                // input (a constant in a pattern).  Are
-                // there forms where users can add type
-                // annotations here?  For example, an
-                // associated constant? Need to
-                // experiment.
+                // FIXME(#54571): This constant comes from user input (a
+                // constant in a pattern).  Are there forms where users can add
+                // type annotations here?  For example, an associated constant?
+                // Need to experiment.
                 user_ty: None,
 
                 literal: method,
diff --git a/src/librustc_mir/hair/cx/mod.rs b/src/librustc_mir/hair/cx/mod.rs
index ff3383f6e14..92df8298441 100644
--- a/src/librustc_mir/hair/cx/mod.rs
+++ b/src/librustc_mir/hair/cx/mod.rs
@@ -168,11 +168,10 @@ impl<'a, 'gcx, 'tcx> Cx<'a, 'gcx, 'tcx> {
 
     pub fn trait_method(&mut self,
                         trait_def_id: DefId,
-                        method_name: &str,
+                        method_name: Symbol,
                         self_ty: Ty<'tcx>,
                         params: &[Kind<'tcx>])
                         -> (Ty<'tcx>, &'tcx ty::Const<'tcx>) {
-        let method_name = Symbol::intern(method_name);
         let substs = self.tcx.mk_substs_trait(self_ty, params);
         for item in self.tcx.associated_items(trait_def_id) {
             if item.kind == ty::AssocKind::Method && item.ident.name == method_name {
diff --git a/src/libsyntax_pos/symbol.rs b/src/libsyntax_pos/symbol.rs
index 9ca64a1231f..0d0233cc2e9 100644
--- a/src/libsyntax_pos/symbol.rs
+++ b/src/libsyntax_pos/symbol.rs
@@ -247,6 +247,7 @@ symbols! {
         eh_personality,
         eh_unwind_resume,
         enable,
+        eq,
         err,
         Err,
         Equal,