]> git.lizzy.rs Git - rust.git/commitdiff
Check SIMD vector types
authorSeo Sanghyeon <sanxiyn@gmail.com>
Thu, 2 May 2013 11:47:11 +0000 (20:47 +0900)
committerSeo Sanghyeon <sanxiyn@gmail.com>
Tue, 7 May 2013 14:35:33 +0000 (23:35 +0900)
src/librustc/middle/ty.rs
src/librustc/middle/typeck/check/mod.rs

index 892635416c2a4be8d80cb9779443db8d690a9a57..d06c1efbc3045d3a0ffd0a3e2918b5c2802c6d5d 100644 (file)
@@ -2381,6 +2381,14 @@ pub fn type_is_signed(ty: t) -> bool {
     }
 }
 
+pub fn type_is_machine(ty: t) -> bool {
+    match get(ty).sty {
+        ty_int(ast::ty_i) | ty_uint(ast::ty_u) | ty_float(ast::ty_f) => false,
+        ty_int(*) | ty_uint(*) | ty_float(*) => true,
+        _ => false
+    }
+}
+
 // Whether a type is Plain Old Data -- meaning it does not contain pointers
 // that the cycle collector might care about.
 pub fn type_is_pod(cx: ctxt, ty: t) -> bool {
@@ -3896,7 +3904,7 @@ pub fn has_attr(tcx: ctxt, did: def_id, attr: &str) -> bool {
                     attrs: ref attrs,
                     _
                 }, _)) => attr::attrs_contains_name(*attrs, attr),
-            _ => tcx.sess.bug(fmt!("lookup_packed: %? is not an item",
+            _ => tcx.sess.bug(fmt!("has_attr: %? is not an item",
                                    did))
         }
     } else {
@@ -3908,11 +3916,16 @@ pub fn has_attr(tcx: ctxt, did: def_id, attr: &str) -> bool {
     }
 }
 
-/// Determine whether an item is annotated with `#[packed]` or not
+/// Determine whether an item is annotated with `#[packed]`
 pub fn lookup_packed(tcx: ctxt, did: def_id) -> bool {
     has_attr(tcx, did, "packed")
 }
 
+/// Determine whether an item is annotated with `#[simd]` 
+pub fn lookup_simd(tcx: ctxt, did: def_id) -> bool {
+    has_attr(tcx, did, "simd")
+}
+
 // Look up a field ID, whether or not it's local
 // Takes a list of type substs in case the struct is generic
 pub fn lookup_field_type(tcx: ctxt,
index e171765ef6c4ef82d686e9b99b461a2b3f5a8064..9d547a9584f7c41dc2f4c5d4cebeaaffb73aa338 100644 (file)
@@ -561,8 +561,14 @@ pub fn check_no_duplicate_fields(tcx: ty::ctxt,
 }
 
 pub fn check_struct(ccx: @mut CrateCtxt, id: ast::node_id, span: span) {
+    let tcx = ccx.tcx;
+
     // Check that the class is instantiable
-    check_instantiable(ccx.tcx, span, id);
+    check_instantiable(tcx, span, id);
+
+    if ty::lookup_simd(tcx, local_def(id)) {
+        check_simd(tcx, span, id);
+    }
 }
 
 pub fn check_item(ccx: @mut CrateCtxt, it: @ast::item) {
@@ -3047,6 +3053,35 @@ pub fn check_instantiable(tcx: ty::ctxt,
     }
 }
 
+pub fn check_simd(tcx: ty::ctxt, sp: span, id: ast::node_id) {
+    let t = ty::node_id_to_type(tcx, id);
+    if ty::type_needs_subst(t) {
+        tcx.sess.span_err(sp, "SIMD vector cannot be generic");
+        return;
+    }
+    match ty::get(t).sty {
+        ty::ty_struct(did, ref substs) => {
+            let fields = ty::lookup_struct_fields(tcx, did);
+            if fields.is_empty() {
+                tcx.sess.span_err(sp, "SIMD vector cannot be empty");
+                return;
+            }
+            let e = ty::lookup_field_type(tcx, did, fields[0].id, substs);
+            if !vec::all(fields,
+                         |f| ty::lookup_field_type(tcx, did, f.id, substs) == e) {
+                tcx.sess.span_err(sp, "SIMD vector should be homogeneous");
+                return;
+            }
+            if !ty::type_is_machine(e) {
+                tcx.sess.span_err(sp, "SIMD vector element type should be \
+                                       machine type");
+                return;
+            }
+        }
+        _ => ()
+    }
+}
+
 pub fn check_enum_variants(ccx: @mut CrateCtxt,
                            sp: span,
                            vs: &[ast::variant],