From c38cc896dc69383cef01b40b1139b4e9c030a6dd Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sat, 25 Aug 2018 18:32:01 +0200 Subject: [PATCH] fix len() on non-array but array-layout types (e.g. SIMD) --- src/librustc_mir/interpret/place.rs | 23 ++++++++++++----------- src/librustc_mir/interpret/validity.rs | 6 +++--- 2 files changed, 15 insertions(+), 14 deletions(-) diff --git a/src/librustc_mir/interpret/place.rs b/src/librustc_mir/interpret/place.rs index e031c86ee96d..f79c4d5721fa 100644 --- a/src/librustc_mir/interpret/place.rs +++ b/src/librustc_mir/interpret/place.rs @@ -137,19 +137,20 @@ impl<'tcx> MPlaceTy<'tcx> { #[inline] pub(super) fn len(self, cx: impl HasDataLayout) -> EvalResult<'tcx, u64> { - match self.layout.ty.sty { - ty::Array(..) => { - // Sized, get length from layout. - debug_assert!(self.extra.is_none()); - match self.layout.fields { - layout::FieldPlacement::Array { count, .. } => Ok(count), - _ => bug!("Length for non-array layout {:?} requested", self.layout), - } + if self.layout.is_unsized() { + // We need to consult `extra` metadata + match self.layout.ty.sty { + ty::Slice(..) | ty::Str => + return self.extra.unwrap().to_usize(cx), + _ => bug!("len not supported on unsized type {:?}", self.layout.ty), } - ty::Slice(..) | ty::Str => { - self.extra.unwrap().to_usize(cx) + } else { + // Go through the layout. There are lots of types that support a length, + // e.g. SIMD types. + match self.layout.fields { + layout::FieldPlacement::Array { count, .. } => Ok(count), + _ => bug!("len not supported on sized type {:?}", self.layout.ty), } - _ => bug!("len not supported on type {:?}", self.layout.ty), } } diff --git a/src/librustc_mir/interpret/validity.rs b/src/librustc_mir/interpret/validity.rs index e72be125878b..3ca40aa9f425 100644 --- a/src/librustc_mir/interpret/validity.rs +++ b/src/librustc_mir/interpret/validity.rs @@ -332,8 +332,9 @@ impl<'a, 'mir, 'tcx, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M> { } } } - ty::Array(..) | ty::Slice(..) => { - // This handles the unsized case correctly as well + _ => { + // This handles the unsized case correctly as well, as well as + // SIMD an all sorts of other array-like types. for (i, field) in self.mplace_array_fields(dest)?.enumerate() { let field = field?; path.push(PathElem::ArrayElem(i)); @@ -341,7 +342,6 @@ impl<'a, 'mir, 'tcx, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M> { path.truncate(path_len); } } - _ => bug!("Array layout for non-array type {:?}", dest.layout.ty), } }, layout::FieldPlacement::Array { .. } => {