Skip to content

Commit 04dd61d

Browse files
committed
Make trans::adt know that some structs are unsized
1 parent ceeac26 commit 04dd61d

File tree

3 files changed

+23
-27
lines changed

3 files changed

+23
-27
lines changed

src/librustc/middle/trans/adt.rs

+19-26
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ use std::num::Int;
4949
use std::rc::Rc;
5050

5151
use llvm::{ValueRef, True, IntEQ, IntNE};
52+
use back::abi::slice_elt_base;
5253
use middle::subst;
5354
use middle::subst::Subst;
5455
use middle::trans::_match;
@@ -235,7 +236,7 @@ fn represent_type_uncached(cx: &CrateContext, t: ty::t) -> Repr {
235236
if cases[1 - discr].is_zerolen(cx, t) {
236237
let st = mk_struct(cx, cases[discr].tys.as_slice(),
237238
false, t);
238-
match cases[discr].find_ptr() {
239+
match cases[discr].find_ptr(cx) {
239240
Some(ThinPointer(_)) if st.fields.len() == 1 => {
240241
return RawNullablePointer {
241242
nndiscr: discr as Disr,
@@ -290,47 +291,38 @@ struct Case {
290291
#[deriving(Eq, PartialEq, Show)]
291292
pub enum PointerField {
292293
ThinPointer(uint),
293-
FatPointer(uint, uint)
294+
FatPointer(uint)
294295
}
295296

296297
impl Case {
297298
fn is_zerolen(&self, cx: &CrateContext, scapegoat: ty::t) -> bool {
298299
mk_struct(cx, self.tys.as_slice(), false, scapegoat).size == 0
299300
}
300301

301-
fn find_ptr(&self) -> Option<PointerField> {
302-
use back::abi::{fn_field_code, slice_elt_base, trt_field_box};
303-
302+
fn find_ptr(&self, cx: &CrateContext) -> Option<PointerField> {
304303
for (i, &ty) in self.tys.iter().enumerate() {
305304
match ty::get(ty).sty {
306-
// &T/&mut T could either be a thin or fat pointer depending on T
307-
ty::ty_rptr(_, ty::mt { ty, .. }) => match ty::get(ty).sty {
305+
// &T/&mut T/Box<T> could either be a thin or fat pointer depending on T
306+
ty::ty_rptr(_, ty::mt { ty, .. }) | ty::ty_uniq(ty) => match ty::get(ty).sty {
308307
// &[T] and &str are a pointer and length pair
309-
ty::ty_vec(_, None) | ty::ty_str => return Some(FatPointer(i, slice_elt_base)),
310-
311-
// &Trait/&mut Trait are a pair of pointers: the actual object and a vtable
312-
ty::ty_trait(..) => return Some(FatPointer(i, trt_field_box)),
313-
314-
// Any other &T/&mut T is just a pointer
315-
_ => return Some(ThinPointer(i))
316-
},
308+
ty::ty_vec(_, None) | ty::ty_str => return Some(FatPointer(i)),
317309

318-
// Box<T> could either be a thin or fat pointer depending on T
319-
ty::ty_uniq(t) => match ty::get(t).sty {
320-
ty::ty_vec(_, None) => return Some(FatPointer(i, slice_elt_base)),
310+
// &Trait is a pair of pointers: the actual object and a vtable
311+
ty::ty_trait(..) => return Some(FatPointer(i)),
321312

322-
// Box<Trait> is a pair of pointers: the actual object and a vtable
323-
ty::ty_trait(..) => return Some(FatPointer(i, trt_field_box)),
313+
ty::ty_struct(..) if !ty::type_is_sized(cx.tcx(), ty) => {
314+
return Some(FatPointer(i))
315+
}
324316

325-
// Any other Box<T> is just a pointer
317+
// Any other &T is just a pointer
326318
_ => return Some(ThinPointer(i))
327319
},
328320

329321
// Functions are just pointers
330322
ty::ty_bare_fn(..) => return Some(ThinPointer(i)),
331323

332324
// Closures are a pair of pointers: the code and environment
333-
ty::ty_closure(..) => return Some(FatPointer(i, fn_field_code)),
325+
ty::ty_closure(..) => return Some(FatPointer(i)),
334326

335327
// Anything else is not a pointer
336328
_ => continue
@@ -636,6 +628,7 @@ pub fn trans_get_discr(bcx: Block, r: &Repr, scrutinee: ValueRef, cast_to: Optio
636628
-> ValueRef {
637629
let signed;
638630
let val;
631+
debug!("trans_get_discr r: {}", r);
639632
match *r {
640633
CEnum(ity, min, max) => {
641634
val = load_discr(bcx, ity, scrutinee, min, max);
@@ -671,7 +664,7 @@ fn struct_wrapped_nullable_bitdiscr(bcx: Block, nndiscr: Disr, ptrfield: Pointer
671664
scrutinee: ValueRef) -> ValueRef {
672665
let llptrptr = match ptrfield {
673666
ThinPointer(field) => GEPi(bcx, scrutinee, [0, field]),
674-
FatPointer(field, pair) => GEPi(bcx, scrutinee, [0, field, pair])
667+
FatPointer(field) => GEPi(bcx, scrutinee, [0, field, slice_elt_base])
675668
};
676669
let llptr = Load(bcx, llptrptr);
677670
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) {
767760
ThinPointer(field) =>
768761
(GEPi(bcx, val, [0, field]),
769762
type_of::type_of(bcx.ccx(), nonnull.fields[field])),
770-
FatPointer(field, pair) => {
771-
let v = GEPi(bcx, val, [0, field, pair]);
763+
FatPointer(field) => {
764+
let v = GEPi(bcx, val, [0, field, slice_elt_base]);
772765
(v, val_ty(v).element_type())
773766
}
774767
};
@@ -1102,7 +1095,7 @@ pub fn const_get_discrim(ccx: &CrateContext, r: &Repr, val: ValueRef)
11021095
StructWrappedNullablePointer { nndiscr, ptrfield, .. } => {
11031096
let (idx, sub_idx) = match ptrfield {
11041097
ThinPointer(field) => (field, None),
1105-
FatPointer(field, pair) => (field, Some(pair))
1098+
FatPointer(field) => (field, Some(slice_elt_base))
11061099
};
11071100
if is_null(const_struct_field(ccx, val, idx, sub_idx)) {
11081101
/* subtraction as uint is ok because nndiscr is either 0 or 1 */

src/librustc/middle/trans/debuginfo.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -2255,7 +2255,7 @@ impl EnumMemberDescriptionFactory {
22552255
let null_variant_name = token::get_name((*self.variants)[null_variant_index].name);
22562256
let discrfield = match ptrfield {
22572257
adt::ThinPointer(field) => format!("{}", field),
2258-
adt::FatPointer(field, pair) => format!("{}${}", field, pair)
2258+
adt::FatPointer(field) => format!("{}", field)
22592259
};
22602260
let union_member_name = format!("RUST$ENCODED$ENUM${}${}",
22612261
discrfield,

src/librustc_back/abi.rs

+3
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,9 @@ pub const box_field_refcnt: uint = 0u;
1414
pub const box_field_drop_glue: uint = 1u;
1515
pub const box_field_body: uint = 4u;
1616

17+
// FIXME(18590) although we have three different layouts here, the compiler relies on
18+
// them being the same. We should replace them with one set of constants.
19+
1720
// The two halves of a closure: code and environment.
1821
pub const fn_field_code: uint = 0u;
1922
pub const fn_field_box: uint = 1u;

0 commit comments

Comments
 (0)