about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorAlex Crichton <alex@alexcrichton.com>2014-11-06 13:30:37 -0800
committerAlex Crichton <alex@alexcrichton.com>2014-11-06 13:30:37 -0800
commitb747f7039401e95305abeb3b0c5be7d69a8fdfdc (patch)
treece55f64c1647ea72ed8b62e4a85c1849371c9787 /src
parent73aaeb0fbdb14290b68288324e678068d2cfa6be (diff)
parent9af15e3a6b38ce5f44764476b521ab52dea07975 (diff)
downloadrust-b747f7039401e95305abeb3b0c5be7d69a8fdfdc.tar.gz
rust-b747f7039401e95305abeb3b0c5be7d69a8fdfdc.zip
rollup merge of #18591 : nick29581/dst-bug-str
Diffstat (limited to 'src')
-rw-r--r--src/librustc/middle/trans/adt.rs45
-rw-r--r--src/librustc/middle/trans/debuginfo.rs2
-rw-r--r--src/librustc_back/abi.rs3
-rw-r--r--src/test/run-pass/issue-18353.rs21
4 files changed, 44 insertions, 27 deletions
diff --git a/src/librustc/middle/trans/adt.rs b/src/librustc/middle/trans/adt.rs
index 7ff94c28d93..0d3a84eb8bc 100644
--- a/src/librustc/middle/trans/adt.rs
+++ b/src/librustc/middle/trans/adt.rs
@@ -49,6 +49,7 @@ use std::num::Int;
 use std::rc::Rc;
 
 use llvm::{ValueRef, True, IntEQ, IntNE};
+use back::abi::slice_elt_base;
 use middle::subst;
 use middle::subst::Subst;
 use middle::trans::_match;
@@ -235,7 +236,7 @@ fn represent_type_uncached(cx: &CrateContext, t: ty::t) -> Repr {
                     if cases[1 - discr].is_zerolen(cx, t) {
                         let st = mk_struct(cx, cases[discr].tys.as_slice(),
                                            false, t);
-                        match cases[discr].find_ptr() {
+                        match cases[discr].find_ptr(cx) {
                             Some(ThinPointer(_)) if st.fields.len() == 1 => {
                                 return RawNullablePointer {
                                     nndiscr: discr as Disr,
@@ -290,7 +291,7 @@ struct Case {
 #[deriving(Eq, PartialEq, Show)]
 pub enum PointerField {
     ThinPointer(uint),
-    FatPointer(uint, uint)
+    FatPointer(uint)
 }
 
 impl Case {
@@ -298,31 +299,22 @@ impl Case {
         mk_struct(cx, self.tys.as_slice(), false, scapegoat).size == 0
     }
 
-    fn find_ptr(&self) -> Option<PointerField> {
-        use back::abi::{fn_field_code, slice_elt_base, trt_field_box};
-
+    fn find_ptr(&self, cx: &CrateContext) -> Option<PointerField> {
         for (i, &ty) in self.tys.iter().enumerate() {
             match ty::get(ty).sty {
-                // &T/&mut T could either be a thin or fat pointer depending on T
-                ty::ty_rptr(_, ty::mt { ty, .. }) => match ty::get(ty).sty {
+                // &T/&mut T/Box<T> could either be a thin or fat pointer depending on T
+                ty::ty_rptr(_, ty::mt { ty, .. }) | ty::ty_uniq(ty) => match ty::get(ty).sty {
                     // &[T] and &str are a pointer and length pair
-                    ty::ty_vec(_, None) | ty::ty_str => return Some(FatPointer(i, slice_elt_base)),
-
-                    // &Trait/&mut Trait are a pair of pointers: the actual object and a vtable
-                    ty::ty_trait(..) => return Some(FatPointer(i, trt_field_box)),
-
-                    // Any other &T/&mut T is just a pointer
-                    _ => return Some(ThinPointer(i))
-                },
+                    ty::ty_vec(_, None) | ty::ty_str => return Some(FatPointer(i)),
 
-                // Box<T> could either be a thin or fat pointer depending on T
-                ty::ty_uniq(t) => match ty::get(t).sty {
-                    ty::ty_vec(_, None) => return Some(FatPointer(i, slice_elt_base)),
+                    // &Trait is a pair of pointers: the actual object and a vtable
+                    ty::ty_trait(..) => return Some(FatPointer(i)),
 
-                    // Box<Trait> is a pair of pointers: the actual object and a vtable
-                    ty::ty_trait(..) => return Some(FatPointer(i, trt_field_box)),
+                    ty::ty_struct(..) if !ty::type_is_sized(cx.tcx(), ty) => {
+                        return Some(FatPointer(i))
+                    }
 
-                    // Any other Box<T> is just a pointer
+                    // Any other &T is just a pointer
                     _ => return Some(ThinPointer(i))
                 },
 
@@ -330,7 +322,7 @@ impl Case {
                 ty::ty_bare_fn(..) => return Some(ThinPointer(i)),
 
                 // Closures are a pair of pointers: the code and environment
-                ty::ty_closure(..) => return Some(FatPointer(i, fn_field_code)),
+                ty::ty_closure(..) => return Some(FatPointer(i)),
 
                 // Anything else is not a pointer
                 _ => continue
@@ -636,6 +628,7 @@ pub fn trans_get_discr(bcx: Block, r: &Repr, scrutinee: ValueRef, cast_to: Optio
     -> ValueRef {
     let signed;
     let val;
+    debug!("trans_get_discr r: {}", r);
     match *r {
         CEnum(ity, min, max) => {
             val = load_discr(bcx, ity, scrutinee, min, max);
@@ -671,7 +664,7 @@ fn struct_wrapped_nullable_bitdiscr(bcx: Block, nndiscr: Disr, ptrfield: Pointer
                                     scrutinee: ValueRef) -> ValueRef {
     let llptrptr = match ptrfield {
         ThinPointer(field) => GEPi(bcx, scrutinee, [0, field]),
-        FatPointer(field, pair) => GEPi(bcx, scrutinee, [0, field, pair])
+        FatPointer(field) => GEPi(bcx, scrutinee, [0, field, slice_elt_base])
     };
     let llptr = Load(bcx, llptrptr);
     let cmp = if nndiscr == 0 { IntEQ } else { IntNE };
@@ -767,8 +760,8 @@ pub fn trans_set_discr(bcx: Block, r: &Repr, val: ValueRef, discr: Disr) {
                     ThinPointer(field) =>
                         (GEPi(bcx, val, [0, field]),
                          type_of::type_of(bcx.ccx(), nonnull.fields[field])),
-                    FatPointer(field, pair) => {
-                        let v = GEPi(bcx, val, [0, field, pair]);
+                    FatPointer(field) => {
+                        let v = GEPi(bcx, val, [0, field, slice_elt_base]);
                         (v, val_ty(v).element_type())
                     }
                 };
@@ -1102,7 +1095,7 @@ pub fn const_get_discrim(ccx: &CrateContext, r: &Repr, val: ValueRef)
         StructWrappedNullablePointer { nndiscr, ptrfield, .. } => {
             let (idx, sub_idx) = match ptrfield {
                 ThinPointer(field) => (field, None),
-                FatPointer(field, pair) => (field, Some(pair))
+                FatPointer(field) => (field, Some(slice_elt_base))
             };
             if is_null(const_struct_field(ccx, val, idx, sub_idx)) {
                 /* subtraction as uint is ok because nndiscr is either 0 or 1 */
diff --git a/src/librustc/middle/trans/debuginfo.rs b/src/librustc/middle/trans/debuginfo.rs
index c84543773a4..8309811cf0b 100644
--- a/src/librustc/middle/trans/debuginfo.rs
+++ b/src/librustc/middle/trans/debuginfo.rs
@@ -2255,7 +2255,7 @@ impl EnumMemberDescriptionFactory {
                 let null_variant_name = token::get_name((*self.variants)[null_variant_index].name);
                 let discrfield = match ptrfield {
                     adt::ThinPointer(field) => format!("{}", field),
-                    adt::FatPointer(field, pair) => format!("{}${}", field, pair)
+                    adt::FatPointer(field) => format!("{}", field)
                 };
                 let union_member_name = format!("RUST$ENCODED$ENUM${}${}",
                                                 discrfield,
diff --git a/src/librustc_back/abi.rs b/src/librustc_back/abi.rs
index 19dd6b8459f..335317be4b4 100644
--- a/src/librustc_back/abi.rs
+++ b/src/librustc_back/abi.rs
@@ -14,6 +14,9 @@ pub const box_field_refcnt: uint = 0u;
 pub const box_field_drop_glue: uint = 1u;
 pub const box_field_body: uint = 4u;
 
+// FIXME(18590) although we have three different layouts here, the compiler relies on
+// them being the same. We should replace them with one set of constants.
+
 // The two halves of a closure: code and environment.
 pub const fn_field_code: uint = 0u;
 pub const fn_field_box: uint = 1u;
diff --git a/src/test/run-pass/issue-18353.rs b/src/test/run-pass/issue-18353.rs
new file mode 100644
index 00000000000..c734c1a3222
--- /dev/null
+++ b/src/test/run-pass/issue-18353.rs
@@ -0,0 +1,21 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// Test that wrapping an unsized struct in an enum which gets optimised does
+// not ICE.
+
+struct Str {
+    f: [u8]
+}
+
+fn main() {
+    let str: Option<&Str> = None;
+    str.is_some();
+}