about summary refs log tree commit diff
diff options
context:
space:
mode:
authorRalf Jung <post@ralfj.de>2018-08-25 18:32:01 +0200
committerRalf Jung <post@ralfj.de>2018-08-27 18:12:49 +0200
commitc38cc896dc69383cef01b40b1139b4e9c030a6dd (patch)
treea694f95531aefa3fe6b06fc977acea2bc13e268d
parent07bdd48b604c314ef081636662a0ef35e941e39b (diff)
downloadrust-c38cc896dc69383cef01b40b1139b4e9c030a6dd.tar.gz
rust-c38cc896dc69383cef01b40b1139b4e9c030a6dd.zip
fix len() on non-array but array-layout types (e.g. SIMD)
-rw-r--r--src/librustc_mir/interpret/place.rs23
-rw-r--r--src/librustc_mir/interpret/validity.rs6
2 files changed, 15 insertions, 14 deletions
diff --git a/src/librustc_mir/interpret/place.rs b/src/librustc_mir/interpret/place.rs
index e031c86ee96..f79c4d5721f 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 e72be125878..3ca40aa9f42 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 { .. } => {