about summary refs log tree commit diff
diff options
context:
space:
mode:
authorLuqman Aden <laden@csclub.uwaterloo.ca>2014-12-04 16:56:57 -0500
committerLuqman Aden <laden@csclub.uwaterloo.ca>2014-12-28 19:40:47 -0500
commit46e73764896316ef1384591656cfca01280c5e5c (patch)
tree59dd2f945e0c67df1228cea22a09beae22a4629a
parent6d91419f27b25810f2cfcd263e0e20b62910f4ff (diff)
downloadrust-46e73764896316ef1384591656cfca01280c5e5c.tar.gz
rust-46e73764896316ef1384591656cfca01280c5e5c.zip
librustc: Add NonZero lang item and use it if possible for nullable pointer enum opt.
-rw-r--r--src/librustc/middle/lang_items.rs2
-rw-r--r--src/librustc_trans/trans/adt.rs14
2 files changed, 15 insertions, 1 deletions
diff --git a/src/librustc/middle/lang_items.rs b/src/librustc/middle/lang_items.rs
index ca3087f08c4..90e3e2bb34a 100644
--- a/src/librustc/middle/lang_items.rs
+++ b/src/librustc/middle/lang_items.rs
@@ -327,6 +327,8 @@ lets_do_this! {
     NoSyncItem,                      "no_sync_bound",           no_sync_bound;
     ManagedItem,                     "managed_bound",           managed_bound;
 
+    NonZeroItem,                     "non_zero",                non_zero;
+
     IteratorItem,                    "iterator",                iterator;
 
     StackExhaustedLangItem,          "stack_exhausted",         stack_exhausted;
diff --git a/src/librustc_trans/trans/adt.rs b/src/librustc_trans/trans/adt.rs
index 28a2174889c..c3db50e3b20 100644
--- a/src/librustc_trans/trans/adt.rs
+++ b/src/librustc_trans/trans/adt.rs
@@ -357,7 +357,19 @@ fn find_discr_field_candidate<'tcx>(tcx: &ty::ctxt<'tcx>, ty: Ty<'tcx>) -> Optio
         // Closures are a pair of pointers: the code and environment
         ty::ty_closure(..) => Some(vec![FAT_PTR_ADDR]),
 
-        // Perhaps one of the fields of this struct is non-null
+        // Is this the NonZero lang item wrapping a pointer or integer type?
+        ty::ty_struct(did, ref substs) if Some(did) == tcx.lang_items.non_zero() => {
+            let nonzero_fields = ty::lookup_struct_fields(tcx, did);
+            assert_eq!(nonzero_fields.len(), 1);
+            let nonzero_field = ty::lookup_field_type(tcx, did, nonzero_fields[0].id, substs);
+            match nonzero_field.sty {
+                ty::ty_ptr(..) | ty::ty_int(..) |
+                ty::ty_uint(..) => Some(vec![0]),
+                _ => None
+            }
+        },
+
+        // Perhaps one of the fields of this struct is non-zero
         // let's recurse and find out
         ty::ty_struct(def_id, ref substs) => {
             let fields = ty::lookup_struct_fields(tcx, def_id);