From 46e73764896316ef1384591656cfca01280c5e5c Mon Sep 17 00:00:00 2001 From: Luqman Aden Date: Thu, 4 Dec 2014 16:56:57 -0500 Subject: [PATCH] librustc: Add NonZero lang item and use it if possible for nullable pointer enum opt. --- src/librustc/middle/lang_items.rs | 2 ++ src/librustc_trans/trans/adt.rs | 14 +++++++++++++- 2 files changed, 15 insertions(+), 1 deletion(-) 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);