Implement ProjectionElem::Subslice

This commit is contained in:
bjorn3 2019-02-24 12:38:06 +01:00
parent 99eb418f19
commit 25f3ef5ff9
2 changed files with 35 additions and 7 deletions

View File

@ -1,6 +1,6 @@
// Adapted from https://github.com/sunfishcode/mir2cranelift/blob/master/rust-examples/nocore-hello-world.rs
#![feature(no_core, unboxed_closures, start, lang_items, box_syntax)]
#![feature(no_core, unboxed_closures, start, lang_items, box_syntax, slice_patterns)]
#![no_core]
#![allow(dead_code)]
@ -184,4 +184,10 @@ fn main() {
}
[NoisyDropInner, NoisyDropInner];
let x = &[0u32, 42u32] as &[u32];
match x {
[] => assert_eq!(0u32, 1),
[_, ref y..] => assert_eq!(&x[1] as *const u32 as usize, &y[0] as *const u32 as usize),
}
}

View File

@ -1117,12 +1117,34 @@ pub fn trans_place<'a, 'tcx: 'a>(
};
base.place_index(fx, index)
}
ProjectionElem::Subslice { from, to } => unimpl!(
"projection subslice {:?} from {} to {}",
projection.base,
from,
to
),
ProjectionElem::Subslice { from, to } => {
// These indices are generated by slice patterns.
// slice[from:-to] in Python terms.
match base.layout().ty.sty {
ty::Array(elem_ty, len) => {
let elem_layout = fx.layout_of(elem_ty);
let ptr = base.to_addr(fx);
let len = crate::constant::force_eval_const(fx, len).unwrap_usize(fx.tcx);
CPlace::Addr(
fx.bcx.ins().iadd_imm(ptr, elem_layout.size.bytes() as i64 * from as i64),
None,
fx.layout_of(fx.tcx.mk_array(elem_ty, len - from as u64 - to as u64)),
)
}
ty::Slice(elem_ty) => {
let elem_layout = fx.layout_of(elem_ty);
let (ptr, len) = base.to_addr_maybe_unsized(fx);
let len = len.unwrap();
CPlace::Addr(
fx.bcx.ins().iadd_imm(ptr, elem_layout.size.bytes() as i64 * from as i64),
Some(fx.bcx.ins().iadd_imm(len, -(from as i64 + to as i64))),
base.layout(),
)
}
_ => unreachable!(),
}
}
ProjectionElem::Downcast(_adt_def, variant) => base.downcast_variant(fx, variant),
}
}