]> git.lizzy.rs Git - rust.git/commitdiff
mir: Unsize ConstVal::ByteStr before comparing &[u8] against it.
authorEduard Burtescu <edy.burt@gmail.com>
Tue, 8 Mar 2016 12:17:35 +0000 (14:17 +0200)
committerEduard Burtescu <edy.burt@gmail.com>
Thu, 17 Mar 2016 19:51:53 +0000 (21:51 +0200)
src/librustc/middle/ty/sty.rs
src/librustc_mir/build/matches/test.rs

index bbc5948f2cac71f5eff6c444a3f5aa29868ea8ba..2d4d4e51ba73fe5d4bbe160821f0228eaeb9ab0e 100644 (file)
@@ -948,7 +948,7 @@ pub fn is_self(&self) -> bool {
         }
     }
 
-    fn is_slice(&self) -> bool {
+    pub fn is_slice(&self) -> bool {
         match self.sty {
             TyRawPtr(mt) | TyRef(_, mt) => match mt.ty.sty {
                 TySlice(_) | TyStr => true,
index d42c8ff7bd79fab67f204babfd78e5ac6f8fb703..bdec261ce65afc7a44481c87e141e8ab45745d88 100644 (file)
@@ -175,9 +175,28 @@ pub fn perform_test(&mut self,
             }
 
             TestKind::Eq { ref value, ty } => {
-                let expect = self.literal_operand(test.span, ty.clone(), Literal::Value {
-                    value: value.clone()
-                });
+                // If we're matching against &[u8] with b"...", we need to insert
+                // an unsizing coercion, as the byte string has type &[u8; N].
+                let expect = match *value {
+                    ConstVal::ByteStr(ref bytes) if ty.is_slice() => {
+                        let tcx = self.hir.tcx();
+                        let array_ty = tcx.mk_array(tcx.types.u8, bytes.len());
+                        let ref_ty = tcx.mk_imm_ref(tcx.mk_region(ty::ReStatic), array_ty);
+                        let array = self.literal_operand(test.span, ref_ty, Literal::Value {
+                            value: value.clone()
+                        });
+
+                        let sliced = self.temp(ty);
+                        self.cfg.push_assign(block, test.span, &sliced,
+                                             Rvalue::Cast(CastKind::Unsize, array, ty));
+                        Operand::Consume(sliced)
+                    }
+                    _ => {
+                        self.literal_operand(test.span, ty, Literal::Value {
+                            value: value.clone()
+                        })
+                    }
+                };
                 let val = Operand::Consume(lvalue.clone());
                 let fail = self.cfg.start_new_block();
                 let block = self.compare(block, fail, test.span, BinOp::Eq, expect, val.clone());