From 25f3ef5ff998eea060e73be04bfe88cbedf57dc9 Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Sun, 24 Feb 2019 12:38:06 +0100 Subject: [PATCH] Implement ProjectionElem::Subslice --- example/mini_core_hello_world.rs | 8 +++++++- src/base.rs | 34 ++++++++++++++++++++++++++------ 2 files changed, 35 insertions(+), 7 deletions(-) diff --git a/example/mini_core_hello_world.rs b/example/mini_core_hello_world.rs index 4fa08391f5a..d550ccbf61a 100644 --- a/example/mini_core_hello_world.rs +++ b/example/mini_core_hello_world.rs @@ -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), + } } diff --git a/src/base.rs b/src/base.rs index 75ad1099d53..6427c756ac8 100644 --- a/src/base.rs +++ b/src/base.rs @@ -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), } }