diff --git a/src/librustc/mir/repr.rs b/src/librustc/mir/repr.rs index 8496f606b7b..3e71d3ba9f3 100644 --- a/src/librustc/mir/repr.rs +++ b/src/librustc/mir/repr.rs @@ -683,7 +683,7 @@ pub enum Rvalue<'tcx> { Use(Operand<'tcx>), // [x; 32] - Repeat(Operand<'tcx>, Constant<'tcx>), + Repeat(Operand<'tcx>, TypedConstVal<'tcx>), // &x or &mut x Ref(Region, BorrowKind, Lvalue<'tcx>), @@ -891,6 +891,20 @@ pub struct Constant<'tcx> { pub literal: Literal<'tcx>, } +#[derive(Clone, RustcEncodable, RustcDecodable)] +pub struct TypedConstVal<'tcx> { + pub ty: Ty<'tcx>, + pub span: Span, + pub value: ConstVal +} + +impl<'tcx> Debug for TypedConstVal<'tcx> { + fn fmt(&self, fmt: &mut Formatter) -> fmt::Result { + try!(write!(fmt, "const ")); + fmt_const_val(fmt, &self.value) + } +} + #[derive(Clone, Copy, Debug, PartialEq, RustcEncodable, RustcDecodable)] pub enum ItemKind { Constant, diff --git a/src/librustc/mir/visit.rs b/src/librustc/mir/visit.rs index 7c8ea22de8e..a38ef078c6f 100644 --- a/src/librustc/mir/visit.rs +++ b/src/librustc/mir/visit.rs @@ -213,9 +213,8 @@ macro_rules! make_mir_visitor { } Rvalue::Repeat(ref $($mutability)* value, - ref $($mutability)* len) => { + _) => { self.visit_operand(value); - self.visit_constant(len); } Rvalue::Ref(r, bk, ref $($mutability)* path) => { diff --git a/src/librustc_mir/build/expr/as_rvalue.rs b/src/librustc_mir/build/expr/as_rvalue.rs index 2f57dd22454..c389e8e7330 100644 --- a/src/librustc_mir/build/expr/as_rvalue.rs +++ b/src/librustc_mir/build/expr/as_rvalue.rs @@ -44,7 +44,6 @@ impl<'a,'tcx> Builder<'a,'tcx> { } ExprKind::Repeat { value, count } => { let value_operand = unpack!(block = this.as_operand(block, value)); - let count = this.as_constant(count); block.and(Rvalue::Repeat(value_operand, count)) } ExprKind::Borrow { region, borrow_kind, arg } => { diff --git a/src/librustc_mir/hair/cx/expr.rs b/src/librustc_mir/hair/cx/expr.rs index 57a43c3a180..d8a1930fd5c 100644 --- a/src/librustc_mir/hair/cx/expr.rs +++ b/src/librustc_mir/hair/cx/expr.rs @@ -15,6 +15,7 @@ use hair::cx::block; use hair::cx::to_ref::ToRef; use rustc::front::map; use rustc::middle::def::Def; +use rustc::middle::const_eval; use rustc::middle::region::CodeExtent; use rustc::middle::pat_util; use rustc::middle::ty::{self, VariantDef, Ty}; @@ -325,14 +326,11 @@ impl<'tcx> Mirror<'tcx> for &'tcx hir::Expr { hir::ExprRepeat(ref v, ref c) => ExprKind::Repeat { value: v.to_ref(), - count: Expr { + count: TypedConstVal { ty: cx.tcx.expr_ty(c), - temp_lifetime: None, span: c.span, - kind: ExprKind::Literal { - literal: cx.const_eval_literal(c) - } - }.to_ref() + value: const_eval::eval_const_expr(cx.tcx, c) + } }, hir::ExprRet(ref v) => ExprKind::Return { value: v.to_ref() }, diff --git a/src/librustc_mir/hair/mod.rs b/src/librustc_mir/hair/mod.rs index fb81cc7e6d9..d87b25a094e 100644 --- a/src/librustc_mir/hair/mod.rs +++ b/src/librustc_mir/hair/mod.rs @@ -14,7 +14,8 @@ //! unit-tested and separated from the Rust source and compiler data //! structures. -use rustc::mir::repr::{BinOp, BorrowKind, Field, Literal, Mutability, UnOp, ItemKind}; +use rustc::mir::repr::{BinOp, BorrowKind, Field, Literal, Mutability, UnOp, ItemKind, + TypedConstVal}; use rustc::middle::const_eval::ConstVal; use rustc::middle::def_id::DefId; use rustc::middle::region::CodeExtent; @@ -213,10 +214,7 @@ pub enum ExprKind<'tcx> { }, Repeat { value: ExprRef<'tcx>, - // FIXME(#29789): Add a separate hair::Constant<'tcx> so this could be more explicit about - // its contained data. Currently this should only contain expression of ExprKind::Literal - // kind. - count: ExprRef<'tcx>, + count: TypedConstVal<'tcx>, }, Vec { fields: Vec>, diff --git a/src/librustc_mir/transform/erase_regions.rs b/src/librustc_mir/transform/erase_regions.rs index 9679654d958..66604786d46 100644 --- a/src/librustc_mir/transform/erase_regions.rs +++ b/src/librustc_mir/transform/erase_regions.rs @@ -143,9 +143,9 @@ impl<'a, 'tcx> EraseRegions<'a, 'tcx> { Rvalue::Use(ref mut operand) => { self.erase_regions_operand(operand) } - Rvalue::Repeat(ref mut operand, ref mut constant) => { + Rvalue::Repeat(ref mut operand, ref mut value) => { self.erase_regions_operand(operand); - self.erase_regions_constant(constant); + value.ty = self.tcx.erase_regions(&value.ty); } Rvalue::Ref(ref mut region, _, ref mut lvalue) => { *region = ty::ReStatic; diff --git a/src/librustc_trans/trans/mir/rvalue.rs b/src/librustc_trans/trans/mir/rvalue.rs index f53653d7cad..fa925241c72 100644 --- a/src/librustc_trans/trans/mir/rvalue.rs +++ b/src/librustc_trans/trans/mir/rvalue.rs @@ -89,7 +89,7 @@ impl<'bcx, 'tcx> MirContext<'bcx, 'tcx> { mir::Rvalue::Repeat(ref elem, ref count) => { let elem = self.trans_operand(bcx, elem); - let size = self.trans_constant(bcx, count).immediate(); + let size = self.trans_constval(bcx, &count.value, count.ty).immediate(); let base = expr::get_dataptr(bcx, dest.llval); tvec::iter_vec_raw(bcx, base, elem.ty, size, |bcx, llslot, _| { self.store_operand(bcx, llslot, elem);