Skip to content

Commit 35decad

Browse files
committed
Auto merge of #29616 - nagisa:mir-repeat, r=nikomatsakis
r? @nikomatsakis I went ahead and replaced repeat count with a `Constant`, because it cannot be non-constant to the best of my knowledge.
2 parents cc30948 + e4e880d commit 35decad

File tree

9 files changed

+76
-14
lines changed

9 files changed

+76
-14
lines changed

src/librustc_mir/build/expr/as_rvalue.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -44,8 +44,8 @@ impl<'a,'tcx> Builder<'a,'tcx> {
4444
}
4545
ExprKind::Repeat { value, count } => {
4646
let value_operand = unpack!(block = this.as_operand(block, value));
47-
let count_operand = unpack!(block = this.as_operand(block, count));
48-
block.and(Rvalue::Repeat(value_operand, count_operand))
47+
let count = this.as_constant(count);
48+
block.and(Rvalue::Repeat(value_operand, count))
4949
}
5050
ExprKind::Borrow { region, borrow_kind, arg } => {
5151
let arg_lvalue = unpack!(block = this.as_lvalue(block, arg));

src/librustc_mir/hair/cx/expr.rs

+14-7
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@ use hair::cx::Cx;
1515
use hair::cx::block;
1616
use hair::cx::to_ref::ToRef;
1717
use rustc::front::map;
18-
use rustc::middle::const_eval;
1918
use rustc::middle::def;
2019
use rustc::middle::region::CodeExtent;
2120
use rustc::middle::pat_util;
@@ -80,10 +79,9 @@ impl<'tcx> Mirror<'tcx> for &'tcx hir::Expr {
8079
}
8180
}
8281

83-
hir::ExprLit(..) => {
84-
let value = const_eval::eval_const_expr(cx.tcx, self);
85-
ExprKind::Literal { literal: Literal::Value { value: value } }
86-
}
82+
hir::ExprLit(..) => ExprKind::Literal {
83+
literal: cx.const_eval_literal(self)
84+
},
8785

8886
hir::ExprBinary(op, ref lhs, ref rhs) => {
8987
if cx.tcx.is_method_call(self.id) {
@@ -272,8 +270,17 @@ impl<'tcx> Mirror<'tcx> for &'tcx hir::Expr {
272270

273271
// Now comes the rote stuff:
274272

275-
hir::ExprRepeat(ref v, ref c) =>
276-
ExprKind::Repeat { value: v.to_ref(), count: c.to_ref() },
273+
hir::ExprRepeat(ref v, ref c) => ExprKind::Repeat {
274+
value: v.to_ref(),
275+
count: Expr {
276+
ty: cx.tcx.expr_ty(c),
277+
temp_lifetime: None,
278+
span: c.span,
279+
kind: ExprKind::Literal {
280+
literal: cx.const_eval_literal(c)
281+
}
282+
}.to_ref()
283+
},
277284
hir::ExprRet(ref v) =>
278285
ExprKind::Return { value: v.to_ref() },
279286
hir::ExprBreak(label) =>

src/librustc_mir/hair/cx/mod.rs

+6-1
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,14 @@
1818
use hair::*;
1919
use repr::*;
2020

21-
use rustc::middle::const_eval::ConstVal;
21+
use rustc::middle::const_eval::{self, ConstVal};
2222
use rustc::middle::def_id::DefId;
2323
use rustc::middle::infer::InferCtxt;
2424
use rustc::middle::subst::{Subst, Substs};
2525
use rustc::middle::ty::{self, Ty};
2626
use syntax::codemap::Span;
2727
use syntax::parse::token;
28+
use rustc_front::hir;
2829

2930
#[derive(Copy, Clone)]
3031
pub struct Cx<'a, 'tcx: 'a> {
@@ -71,6 +72,10 @@ impl<'a,'tcx:'a> Cx<'a, 'tcx> {
7172
Literal::Value { value: ConstVal::Bool(false) }
7273
}
7374

75+
pub fn const_eval_literal(&mut self, e: &hir::Expr) -> Literal<'tcx> {
76+
Literal::Value { value: const_eval::eval_const_expr(self.tcx, e) }
77+
}
78+
7479
pub fn partial_eq(&mut self, ty: Ty<'tcx>) -> ItemRef<'tcx> {
7580
let eq_def_id = self.tcx.lang_items.eq_trait().unwrap();
7681
self.cmp_method_ref(eq_def_id, "eq", ty)

src/librustc_mir/hair/mod.rs

+3
Original file line numberDiff line numberDiff line change
@@ -210,6 +210,9 @@ pub enum ExprKind<'tcx> {
210210
},
211211
Repeat {
212212
value: ExprRef<'tcx>,
213+
// FIXME(#29789): Add a separate hair::Constant<'tcx> so this could be more explicit about
214+
// its contained data. Currently this should only contain expression of ExprKind::Literal
215+
// kind.
213216
count: ExprRef<'tcx>,
214217
},
215218
Vec {

src/librustc_mir/repr.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -569,7 +569,7 @@ pub enum Rvalue<'tcx> {
569569
Use(Operand<'tcx>),
570570

571571
// [x; 32]
572-
Repeat(Operand<'tcx>, Operand<'tcx>),
572+
Repeat(Operand<'tcx>, Constant<'tcx>),
573573

574574
// &x or &mut x
575575
Ref(Region, BorrowKind, Lvalue<'tcx>),

src/librustc_mir/visit.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,7 @@ pub trait Visitor<'tcx> {
141141

142142
Rvalue::Repeat(ref value, ref len) => {
143143
self.visit_operand(value);
144-
self.visit_operand(len);
144+
self.visit_constant(len);
145145
}
146146

147147
Rvalue::Ref(r, bk, ref path) => {

src/librustc_trans/trans/mir/rvalue.rs

+8-2
Original file line numberDiff line numberDiff line change
@@ -49,8 +49,14 @@ impl<'bcx, 'tcx> MirContext<'bcx, 'tcx> {
4949
unimplemented!()
5050
}
5151

52-
mir::Rvalue::Repeat(..) => {
53-
unimplemented!()
52+
mir::Rvalue::Repeat(ref elem, ref count) => {
53+
let elem = self.trans_operand(bcx, elem);
54+
let size = self.trans_constant(bcx, count);
55+
let base = expr::get_dataptr(bcx, lldest);
56+
tvec::iter_vec_raw(bcx, base, elem.ty, size, |b, vref, _| {
57+
build::Store(b, elem.llval, vref);
58+
b
59+
})
5460
}
5561

5662
mir::Rvalue::Aggregate(_, ref operands) => {

src/test/run-pass/mir_trans_array.rs

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
#![feature(rustc_attrs)]
11+
12+
#[rustc_mir]
13+
fn into_inner() -> [u64; 1024] {
14+
let mut x = 10 + 20;
15+
[x; 1024]
16+
}
17+
18+
fn main(){
19+
let x: &[u64] = &[30; 1024];
20+
assert_eq!(&into_inner()[..], x);
21+
}
+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
#![feature(rustc_attrs)]
11+
12+
#[rustc_mir]
13+
fn into_inner(x: u64) -> [u64; 1024] {
14+
[x; 2*4*8*16]
15+
}
16+
17+
fn main(){
18+
let x: &[u64] = &[42; 1024];
19+
assert_eq!(&into_inner(42)[..], x);
20+
}

0 commit comments

Comments
 (0)