From efd203aa0b7d748bcf5a76efe810f025306fd901 Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Wed, 8 Aug 2018 12:22:16 +0200 Subject: [PATCH] Implement indexing for arrays --- examples/example.rs | 4 ++++ examples/mini_core.rs | 14 ++++++++++++++ src/base.rs | 3 ++- src/common.rs | 15 +++++++++++++++ 4 files changed, 35 insertions(+), 1 deletion(-) diff --git a/examples/example.rs b/examples/example.rs index 0537db405d3e..74735c6a12de 100644 --- a/examples/example.rs +++ b/examples/example.rs @@ -142,3 +142,7 @@ unsafe fn call_uninit() -> u8 { /*unsafe fn deref_str_ptr(s: *const str) -> &'static str { &*s }*/ + +fn use_array(arr: [u8; 3]) -> u8 { + arr[1] +} diff --git a/examples/mini_core.rs b/examples/mini_core.rs index ff22aad5a65d..dc19d66b2144 100644 --- a/examples/mini_core.rs +++ b/examples/mini_core.rs @@ -141,3 +141,17 @@ pub mod intrinsics { pub fn uninit() -> T; } } + +#[lang = "index"] +pub trait Index { + type Output: ?Sized; + fn index(&self, index: Idx) -> &Self::Output; +} + +impl Index for [T; 3] { + type Output = T; + + fn index(&self, index: usize) -> &Self::Output { + &self[index] + } +} diff --git a/src/base.rs b/src/base.rs index e0c4b80afcc4..723eb8cdc766 100644 --- a/src/base.rs +++ b/src/base.rs @@ -800,7 +800,8 @@ pub fn trans_place<'a, 'tcx: 'a>( ), ProjectionElem::Field(field, _ty) => base.place_field(fx, field), ProjectionElem::Index(local) => { - unimplemented!("projection index {:?} {:?}", projection.base, local) + let index = fx.get_local_place(local).to_cvalue(fx).load_value(fx); + base.place_index(fx, index) } ProjectionElem::ConstantIndex { offset, diff --git a/src/common.rs b/src/common.rs index f49827b3a977..c3398a9e9f39 100644 --- a/src/common.rs +++ b/src/common.rs @@ -297,6 +297,21 @@ impl<'a, 'tcx: 'a> CPlace<'tcx> { CPlace::Addr(field_ptr, field_layout) } + pub fn place_index(self, fx: &mut FunctionCx<'a, 'tcx>, index: Value) -> CPlace<'tcx> { + let addr = self.expect_addr(); + let layout = self.layout(); + match layout.ty.sty { + TypeVariants::TyArray(elem_ty, _) => { + let elem_layout = fx.layout_of(elem_ty); + let size = fx.bcx.ins().iconst(types::I64, elem_layout.size.bytes() as i64); + let offset = fx.bcx.ins().imul(size, index); + CPlace::Addr(fx.bcx.ins().iadd(addr, offset), elem_layout) + } + TypeVariants::TySlice(_elem_ty) => unimplemented!("place_index(TySlice)"), + _ => bug!("place_index({:?})", layout.ty), + } + } + pub fn unchecked_cast_to(self, layout: TyLayout<'tcx>) -> Self { match self { CPlace::Var(var, _) => CPlace::Var(var, layout),