about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/librustc/ty/sty.rs18
-rw-r--r--src/librustc_mir/interpret/intrinsics.rs21
-rw-r--r--src/librustc_mir/interpret/operand.rs11
3 files changed, 25 insertions, 25 deletions
diff --git a/src/librustc/ty/sty.rs b/src/librustc/ty/sty.rs
index 8f6fc02ab4b..d1d71a42872 100644
--- a/src/librustc/ty/sty.rs
+++ b/src/librustc/ty/sty.rs
@@ -1814,20 +1814,30 @@ impl<'tcx> TyS<'tcx> {
 
     pub fn simd_type(&self, tcx: TyCtxt<'tcx>) -> Ty<'tcx> {
         match self.kind {
-            Adt(def, substs) => {
-                def.non_enum_variant().fields[0].ty(tcx, substs)
-            }
+            Adt(def, substs) => def.non_enum_variant().fields[0].ty(tcx, substs),
             _ => bug!("simd_type called on invalid type")
         }
     }
 
-    pub fn simd_size(&self, _cx: TyCtxt<'_>) -> usize {
+    pub fn simd_size(&self, _tcx: TyCtxt<'tcx>) -> usize {
+        // Parameter currently unused, but probably needed in the future to
+        // allow `#[repr(simd)] struct Simd<T, const N: usize>([T; N]);`.
         match self.kind {
             Adt(def, _) => def.non_enum_variant().fields.len(),
             _ => bug!("simd_size called on invalid type")
         }
     }
 
+    pub fn simd_size_and_type(&self, tcx: TyCtxt<'tcx>) -> (usize, Ty<'tcx>) {
+        match self.kind {
+            Adt(def, substs) => {
+                let variant = def.non_enum_variant();
+                (variant.fields.len(), variant.fields[0].ty(tcx, substs))
+            }
+            _ => bug!("simd_size_and_type called on invalid type")
+        }
+    }
+
     #[inline]
     pub fn is_region_ptr(&self) -> bool {
         match self.kind {
diff --git a/src/librustc_mir/interpret/intrinsics.rs b/src/librustc_mir/interpret/intrinsics.rs
index 6117cf4038a..e43e6c0e43a 100644
--- a/src/librustc_mir/interpret/intrinsics.rs
+++ b/src/librustc_mir/interpret/intrinsics.rs
@@ -302,10 +302,11 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
                 self.copy_op_transmute(args[0], dest)?;
             }
             "simd_insert" => {
-                let index = self.read_scalar(args[1])?.to_u32()? as u64;
-                let scalar = args[2];
+                let index = u64::from(self.read_scalar(args[1])?.to_u32()?);
+                let elem = args[2];
                 let input = args[0];
-                let (len, e_ty) = self.read_vector_ty(input);
+                let (len, e_ty) = input.layout.ty.simd_size_and_type(self.tcx.tcx);
+                let len = len as u64;
                 assert!(
                     index < len,
                     "Index `{}` must be in bounds of vector type `{}`: `[0, {})`",
@@ -317,15 +318,15 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
                     dest.layout.ty, input.layout.ty
                 );
                 assert_eq!(
-                    scalar.layout.ty, e_ty,
-                    "Scalar type `{}` must match vector element type `{}`",
-                    scalar.layout.ty, e_ty
+                    elem.layout.ty, e_ty,
+                    "Scalar element type `{}` must match vector element type `{}`",
+                    elem.layout.ty, e_ty
                 );
 
                 for i in 0..len {
                     let place = self.place_field(dest, i)?;
                     let value = if i == index {
-                        scalar
+                        elem
                     } else {
                         self.operand_field(input, i)?
                     };
@@ -333,10 +334,10 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
                 }
             }
             "simd_extract" => {
-                let index = self.read_scalar(args[1])?.to_u32()? as _;
-                let (len, e_ty) = self.read_vector_ty(args[0]);
+                let index = u64::from(self.read_scalar(args[1])?.to_u32()?);
+                let (len, e_ty) = args[0].layout.ty.simd_size_and_type(self.tcx.tcx);
                 assert!(
-                    index < len,
+                    index < len as u64,
                     "index `{}` is out-of-bounds of vector type `{}` with length `{}`",
                     index, e_ty, len
                 );
diff --git a/src/librustc_mir/interpret/operand.rs b/src/librustc_mir/interpret/operand.rs
index 4d2ccdc20da..970f76a9d6d 100644
--- a/src/librustc_mir/interpret/operand.rs
+++ b/src/librustc_mir/interpret/operand.rs
@@ -315,17 +315,6 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
         }
     }
 
-    /// Read vector length and element type
-    pub fn read_vector_ty(
-        &self, op: OpTy<'tcx, M::PointerTag>
-    ) -> (u64, &rustc::ty::TyS<'tcx>) {
-        if let layout::Abi::Vector { .. } = op.layout.abi {
-            (op.layout.ty.simd_size(*self.tcx) as _, op.layout.ty.simd_type(*self.tcx))
-        } else {
-            bug!("Type `{}` is not a SIMD vector type", op.layout.ty)
-        }
-    }
-
     /// Read a scalar from a place
     pub fn read_scalar(
         &self,