about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorHuon Wilson <dbau.pp+github@gmail.com>2015-08-12 15:37:21 -0700
committerHuon Wilson <dbau.pp+github@gmail.com>2015-08-17 14:41:40 -0700
commit8b68f58fef4ffb833c123f057638484fa59ded76 (patch)
tree9b21bb62dac14e1827a4e874beda25931b8de6f7 /src
parent1f5739fb3cdaff001d1af138a7b9b096a06c94e8 (diff)
downloadrust-8b68f58fef4ffb833c123f057638484fa59ded76.tar.gz
rust-8b68f58fef4ffb833c123f057638484fa59ded76.zip
Allow generic repr(simd) types.
Absolute correctness is checked at monomorphisation time.
Diffstat (limited to 'src')
-rw-r--r--src/librustc_trans/trans/type_of.rs16
-rw-r--r--src/librustc_typeck/check/mod.rs16
2 files changed, 22 insertions, 10 deletions
diff --git a/src/librustc_trans/trans/type_of.rs b/src/librustc_trans/trans/type_of.rs
index 3edd4530ceb..2e2f11bd133 100644
--- a/src/librustc_trans/trans/type_of.rs
+++ b/src/librustc_trans/trans/type_of.rs
@@ -224,7 +224,13 @@ pub fn sizing_type_of<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, t: Ty<'tcx>) -> Typ
 
         ty::TyStruct(..) => {
             if t.is_simd() {
-                let llet = type_of(cx, t.simd_type(cx.tcx()));
+                let e = t.simd_type(cx.tcx());
+                if !e.is_machine() {
+                    cx.sess().fatal(&format!("monomorphising SIMD type `{}` with \
+                                              a non-machine element type `{}`",
+                                             t, e))
+                }
+                let llet = type_of(cx, e);
                 let n = t.simd_size(cx.tcx()) as u64;
                 ensure_array_fits_in_address_space(cx, llet, n, t);
                 Type::vector(&llet, n)
@@ -410,7 +416,13 @@ pub fn in_memory_type_of<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, t: Ty<'tcx>) ->
       }
       ty::TyStruct(def, ref substs) => {
           if t.is_simd() {
-              let llet = in_memory_type_of(cx, t.simd_type(cx.tcx()));
+              let e = t.simd_type(cx.tcx());
+              if !e.is_machine() {
+                  cx.sess().fatal(&format!("monomorphising SIMD type `{}` with \
+                                            a non-machine element type `{}`",
+                                           t, e))
+              }
+              let llet = in_memory_type_of(cx, e);
               let n = t.simd_size(cx.tcx()) as u64;
               ensure_array_fits_in_address_space(cx, llet, n, t);
               Type::vector(&llet, n)
diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs
index 500e4287d61..a16415a03c0 100644
--- a/src/librustc_typeck/check/mod.rs
+++ b/src/librustc_typeck/check/mod.rs
@@ -4321,10 +4321,6 @@ pub fn check_instantiable(tcx: &ty::ctxt,
 
 pub fn check_simd(tcx: &ty::ctxt, sp: Span, id: ast::NodeId) {
     let t = tcx.node_id_to_type(id);
-    if t.needs_subst() {
-        span_err!(tcx.sess, sp, E0074, "SIMD vector cannot be generic");
-        return;
-    }
     match t.sty {
         ty::TyStruct(def, substs) => {
             let fields = &def.struct_variant().fields;
@@ -4337,10 +4333,14 @@ pub fn check_simd(tcx: &ty::ctxt, sp: Span, id: ast::NodeId) {
                 span_err!(tcx.sess, sp, E0076, "SIMD vector should be homogeneous");
                 return;
             }
-            if !e.is_machine() {
-                span_err!(tcx.sess, sp, E0077,
-                    "SIMD vector element type should be machine type");
-                return;
+            match e.sty {
+                ty::TyParam(_) => { /* struct<T>(T, T, T, T) is ok */ }
+                _ if e.is_machine()  => { /* struct(u8, u8, u8, u8) is ok */ }
+                _ => {
+                    span_err!(tcx.sess, sp, E0077,
+                              "SIMD vector element type should be machine type");
+                    return;
+                }
             }
         }
         _ => ()