]> git.lizzy.rs Git - rust.git/commitdiff
fix len() on non-array but array-layout types (e.g. SIMD)
authorRalf Jung <post@ralfj.de>
Sat, 25 Aug 2018 16:32:01 +0000 (18:32 +0200)
committerRalf Jung <post@ralfj.de>
Mon, 27 Aug 2018 16:12:49 +0000 (18:12 +0200)
src/librustc_mir/interpret/place.rs
src/librustc_mir/interpret/validity.rs

index e031c86ee96de0df6eb2623d392756b27b9b763b..f79c4d5721faedc37b8cff0b30428b06673d72b9 100644 (file)
@@ -137,19 +137,20 @@ fn from_aligned_ptr(ptr: Pointer, layout: TyLayout<'tcx>) -> Self {
 
     #[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),
         }
     }
 
index e72be125878b6bf0773ff501b398ca0708a3d95a..3ca40aa9f4259c7d944b9f1f5f1d168e7765184c 100644 (file)
@@ -332,8 +332,9 @@ pub fn validate_operand(
                             }
                         }
                     }
-                    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 @@ pub fn validate_operand(
                             path.truncate(path_len);
                         }
                     }
-                    _ => bug!("Array layout for non-array type {:?}", dest.layout.ty),
                 }
             },
             layout::FieldPlacement::Array { .. } => {