From 9cc5ee359a27b096d4945c672eb1383f4490fbf1 Mon Sep 17 00:00:00 2001 From: Eduard Burtescu Date: Tue, 8 Mar 2016 14:17:35 +0200 Subject: [PATCH] mir: Unsize ConstVal::ByteStr before comparing &[u8] against it. --- src/librustc/middle/ty/sty.rs | 2 +- src/librustc_mir/build/matches/test.rs | 25 ++++++++++++++++++++++--- 2 files changed, 23 insertions(+), 4 deletions(-) diff --git a/src/librustc/middle/ty/sty.rs b/src/librustc/middle/ty/sty.rs index bbc5948f2ca..2d4d4e51ba7 100644 --- a/src/librustc/middle/ty/sty.rs +++ b/src/librustc/middle/ty/sty.rs @@ -948,7 +948,7 @@ impl<'tcx> TyS<'tcx> { } } - 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, diff --git a/src/librustc_mir/build/matches/test.rs b/src/librustc_mir/build/matches/test.rs index d42c8ff7bd7..bdec261ce65 100644 --- a/src/librustc_mir/build/matches/test.rs +++ b/src/librustc_mir/build/matches/test.rs @@ -175,9 +175,28 @@ impl<'a,'tcx> Builder<'a,'tcx> { } 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());