about summary refs log tree commit diff
diff options
context:
space:
mode:
authorJed Davis <jld@panix.com>2013-04-06 19:52:35 -0700
committerJed Davis <jld@panix.com>2013-04-22 08:49:56 -0700
commit70452e5231d4101811b2ea6a2c4be4adc2b5460b (patch)
treee35e224fe084b820622c6ed52419bf20ee488afa
parent7f45ae54ea6609febda24a116e8c30b8fcda466b (diff)
downloadrust-70452e5231d4101811b2ea6a2c4be4adc2b5460b.tar.gz
rust-70452e5231d4101811b2ea6a2c4be4adc2b5460b.zip
Consider nullability for equivalence of monomorphized fns.
-rw-r--r--src/librustc/middle/trans/base.rs5
-rw-r--r--src/librustc/middle/trans/common.rs33
-rw-r--r--src/librustc/middle/trans/monomorphize.rs14
3 files changed, 40 insertions, 12 deletions
diff --git a/src/librustc/middle/trans/base.rs b/src/librustc/middle/trans/base.rs
index 3ad021b2f51..2d9f834040a 100644
--- a/src/librustc/middle/trans/base.rs
+++ b/src/librustc/middle/trans/base.rs
@@ -2007,6 +2007,11 @@ pub fn trans_enum_variant(ccx: @CrateContext,
     // XXX is there a better way to reconstruct the ty::t?
     let repr = adt::represent_type(ccx, enum_ty);
 
+    debug!("trans_enum_variant: name=%s tps=%s repr=%? enum_ty=%s",
+           unsafe { str::raw::from_c_str(llvm::LLVMGetValueName(llfndecl)) },
+           ~"[" + str::connect(ty_param_substs.map(|&t| ty_to_str(ccx.tcx, t)), ", ") + ~"]",
+           repr, ty_to_str(ccx.tcx, enum_ty));
+
     adt::trans_start_init(bcx, repr, fcx.llretptr.get(), disr);
     for vec::eachi(args) |i, va| {
         let lldestptr = adt::trans_field_ptr(bcx,
diff --git a/src/librustc/middle/trans/common.rs b/src/librustc/middle/trans/common.rs
index 3180fb5a4c8..faf7ddd4ff7 100644
--- a/src/librustc/middle/trans/common.rs
+++ b/src/librustc/middle/trans/common.rs
@@ -1311,11 +1311,36 @@ pub enum mono_param_id {
     mono_any,
     mono_repr(uint /* size */,
               uint /* align */,
-              bool /* is_float */,
+              MonoDataClass,
               datum::DatumMode),
 }
 
 #[deriving(Eq)]
+pub enum MonoDataClass {
+    MonoBits,    // Anything not treated differently from arbitrary integer data
+    MonoNonNull, // Non-null pointers (used for optional-pointer optimization)
+    // FIXME(#3547)---scalars and floats are
+    // treated differently in most ABIs.  But we
+    // should be doing something more detailed
+    // here.
+    MonoFloat
+}
+
+pub fn mono_data_classify(t: ty::t) -> MonoDataClass {
+    match ty::get(t).sty {
+        ty::ty_float(_) => MonoFloat,
+        ty::ty_rptr(*) | ty::ty_uniq(*) |
+        ty::ty_box(*) | ty::ty_opaque_box(*) |
+        ty::ty_estr(ty::vstore_uniq) | ty::ty_evec(_, ty::vstore_uniq) |
+        ty::ty_estr(ty::vstore_box) | ty::ty_evec(_, ty::vstore_box) |
+        ty::ty_bare_fn(*) => MonoNonNull,
+        // Is that everything?  Would closures or slices qualify?
+        _ => MonoBits
+    }
+}
+
+
+#[deriving(Eq)]
 pub struct mono_id_ {
     def: ast::def_id,
     params: ~[mono_param_id],
@@ -1338,6 +1363,12 @@ impl to_bytes::IterBytes for mono_param_id {
     }
 }
 
+impl to_bytes::IterBytes for MonoDataClass {
+    fn iter_bytes(&self, lsb0: bool, f:to_bytes::Cb) {
+        (*self as u8).iter_bytes(lsb0, f)
+    }
+}
+
 impl to_bytes::IterBytes for mono_id_ {
     fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) {
         to_bytes::iter_bytes_2(&self.def, &self.params, lsb0, f);
diff --git a/src/librustc/middle/trans/monomorphize.rs b/src/librustc/middle/trans/monomorphize.rs
index 52ca8ec49bb..a0fcdf7fde8 100644
--- a/src/librustc/middle/trans/monomorphize.rs
+++ b/src/librustc/middle/trans/monomorphize.rs
@@ -395,22 +395,14 @@ pub fn make_mono_id(ccx: @CrateContext,
                             let size = machine::llbitsize_of_real(ccx, llty);
                             let align = machine::llalign_of_pref(ccx, llty);
                             let mode = datum::appropriate_mode(subst);
-
-                            // FIXME(#3547)---scalars and floats are
-                            // treated differently in most ABIs.  But we
-                            // should be doing something more detailed
-                            // here.
-                            let is_float = match ty::get(subst).sty {
-                                ty::ty_float(_) => true,
-                                _ => false
-                            };
+                            let data_class = mono_data_classify(subst);
 
                             // Special value for nil to prevent problems
                             // with undef return pointers.
                             if size <= 8u && ty::type_is_nil(subst) {
-                                mono_repr(0u, 0u, is_float, mode)
+                                mono_repr(0u, 0u, data_class, mode)
                             } else {
-                                mono_repr(size, align, is_float, mode)
+                                mono_repr(size, align, data_class, mode)
                             }
                         } else {
                             mono_precise(subst, None)