[const-prop] Handle Rvalue::Len
This commit is contained in:
parent
1e50e01bb7
commit
dee05ab2cc
2 changed files with 46 additions and 23 deletions
|
|
@ -17,8 +17,7 @@ use syntax_pos::{Span, DUMMY_SP};
|
|||
use rustc::ty::subst::InternalSubsts;
|
||||
use rustc_data_structures::indexed_vec::IndexVec;
|
||||
use rustc::ty::layout::{
|
||||
LayoutOf, TyLayout, LayoutError,
|
||||
HasTyCtxt, TargetDataLayout, HasDataLayout,
|
||||
LayoutOf, TyLayout, LayoutError, HasTyCtxt, TargetDataLayout, HasDataLayout, Size,
|
||||
};
|
||||
|
||||
use crate::interpret::{
|
||||
|
|
@ -386,10 +385,30 @@ impl<'a, 'mir, 'tcx> ConstPropagator<'a, 'mir, 'tcx> {
|
|||
this.ecx.cast(op, kind, dest.into())?;
|
||||
Ok(dest.into())
|
||||
})
|
||||
}
|
||||
},
|
||||
Rvalue::Len(ref place) => {
|
||||
let place = self.eval_place(&place, source_info)?;
|
||||
let mplace = place.try_as_mplace().ok()?;
|
||||
|
||||
// FIXME(oli-obk): evaluate static/constant slice lengths
|
||||
Rvalue::Len(_) => None,
|
||||
if let ty::Slice(_) = mplace.layout.ty.sty {
|
||||
let len = mplace.meta.unwrap().to_usize(&self.ecx).unwrap();
|
||||
|
||||
Some(ImmTy {
|
||||
imm: Immediate::Scalar(
|
||||
Scalar::from_uint(
|
||||
len,
|
||||
Size::from_bits(
|
||||
self.tcx.sess.target.usize_ty.bit_width().unwrap() as u64
|
||||
)
|
||||
).into(),
|
||||
),
|
||||
layout: self.tcx.layout_of(self.param_env.and(self.tcx.types.usize)).ok()?,
|
||||
}.into())
|
||||
} else {
|
||||
trace!("not slice: {:?}", mplace.layout.ty.sty);
|
||||
None
|
||||
}
|
||||
},
|
||||
Rvalue::NullaryOp(NullOp::SizeOf, ty) => {
|
||||
type_size_of(self.tcx, self.param_env, ty).and_then(|n| Some(
|
||||
ImmTy {
|
||||
|
|
|
|||
|
|
@ -1,22 +1,22 @@
|
|||
fn test() -> &'static [u32] {
|
||||
&[1, 2]
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let x = test()[0];
|
||||
(&[1u32, 2, 3] as &[u32])[1];
|
||||
}
|
||||
|
||||
// END RUST SOURCE
|
||||
// START rustc.main.ConstProp.before.mir
|
||||
// bb1: {
|
||||
// bb0: {
|
||||
// ...
|
||||
// _3 = const 0usize;
|
||||
// _4 = Len((*_2));
|
||||
// _5 = Lt(_3, _4);
|
||||
// assert(move _5, "index out of bounds: the len is move _4 but the index is _3") -> bb2;
|
||||
// _4 = &(promoted[0]: [u32; 3]);
|
||||
// _3 = _4;
|
||||
// _2 = move _3 as &[u32] (Pointer(Unsize));
|
||||
// ...
|
||||
// _6 = const 1usize;
|
||||
// _7 = Len((*_2));
|
||||
// _8 = Lt(_6, _7);
|
||||
// assert(move _8, "index out of bounds: the len is move _7 but the index is _6") -> bb1;
|
||||
// }
|
||||
// bb2: {
|
||||
// _1 = (*_2)[_3];
|
||||
// bb1: {
|
||||
// _1 = (*_2)[_6];
|
||||
// ...
|
||||
// return;
|
||||
// }
|
||||
|
|
@ -24,13 +24,17 @@ fn main() {
|
|||
// START rustc.main.ConstProp.after.mir
|
||||
// bb0: {
|
||||
// ...
|
||||
// _3 = const 0usize;
|
||||
// _4 = Len((*_2));
|
||||
// _5 = Lt(_3, _4);
|
||||
// assert(move _5, "index out of bounds: the len is move _4 but the index is _3") -> bb2;
|
||||
// _4 = const Scalar(AllocId(0).0x0) : &[u32; 3];
|
||||
// _3 = const Scalar(AllocId(0).0x0) : &[u32; 3];
|
||||
// _2 = move _3 as &[u32] (Pointer(Unsize));
|
||||
// ...
|
||||
// _6 = const 1usize;
|
||||
// _7 = const 3usize;
|
||||
// _8 = const true;
|
||||
// assert(const true, "index out of bounds: the len is move _7 but the index is _6") -> bb1;
|
||||
// }
|
||||
// bb2: {
|
||||
// _1 = (*_2)[_3];
|
||||
// bb1: {
|
||||
// _1 = (*_2)[_6];
|
||||
// ...
|
||||
// return;
|
||||
// }
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue