Skip to content

Commit c8562ad

Browse files
committed
---
yaml --- r: 48623 b: refs/heads/snap-stage3 c: ce24ebb h: refs/heads/master i: 48621: 7b216c4 48619: 712efb5 48615: dcca31d 48607: b89427f v: v3
1 parent 86058cc commit c8562ad

File tree

2 files changed

+41
-78
lines changed

2 files changed

+41
-78
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
---
22
refs/heads/master: 3bbcac322669cff3abde5be937cc4ec3860f3985
33
refs/heads/snap-stage1: e33de59e47c5076a89eadeb38f4934f58a3618a6
4-
refs/heads/snap-stage3: 2ebb67487c1530822d83d6da6f71fa62cb68f2cd
4+
refs/heads/snap-stage3: ce24ebb8589cb6533359b0e398e6da88e9c228ef
55
refs/heads/try: 2a8fb58d79e685d5ca07b039badcf2ae3ef077ea
66
refs/tags/release-0.1: 1f5c5126e96c79d22cb7862f75304136e204f105
77
refs/heads/ndm: f3868061cd7988080c30d6d5bf352a5a5fe2460b

branches/snap-stage3/src/librustc/middle/trans/adt.rs

Lines changed: 40 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -71,18 +71,16 @@ use util::ppaux::ty_to_str;
7171

7272
/// Representations.
7373
pub enum Repr {
74-
/**
75-
* `Unit` exists only so that an enum with a single C-like variant
76-
* can occupy no space, for ABI compatibility with rustc from
77-
* before (and during) the creation of this module. It may not be
78-
* worth keeping around; `CEnum` and `Univariant` cover it
79-
* overwise.
80-
*/
81-
Unit(int),
8274
/// C-like enums; basically an int.
8375
CEnum(int, int), // discriminant range
84-
/// Single-case variants, and structs/tuples/records.
85-
Univariant(Struct, Destructor),
76+
/**
77+
* Single-case variants, and structs/tuples/records.
78+
*
79+
* Structs with destructors need a dynamic destroyedness flag to
80+
* avoid running the destructor too many times; this is included
81+
* in the `Struct` if present.
82+
*/
83+
Univariant(Struct, bool),
8684
/**
8785
* General-case enums: discriminant as int, followed by fields.
8886
* The fields start immediately after the discriminant, meaning
@@ -92,18 +90,6 @@ pub enum Repr {
9290
General(~[Struct])
9391
}
9492

95-
/**
96-
* Structs without destructors have historically had an extra layer of
97-
* LLVM-struct to make accessing them work the same as structs with
98-
* destructors. This could probably be flattened to a boolean now
99-
* that this module exists.
100-
*/
101-
enum Destructor {
102-
StructWithDtor,
103-
StructWithoutDtor,
104-
NonStruct
105-
}
106-
10793
/// For structs, and struct-like parts of anything fancier.
10894
struct Struct {
10995
size: u64,
@@ -129,14 +115,17 @@ pub fn represent_type(cx: @CrateContext, t: ty::t) -> @Repr {
129115
}
130116
let repr = @match ty::get(t).sty {
131117
ty::ty_tup(ref elems) => {
132-
Univariant(mk_struct(cx, *elems), NonStruct)
118+
Univariant(mk_struct(cx, *elems), false)
133119
}
134120
ty::ty_struct(def_id, ref substs) => {
135121
let fields = ty::lookup_struct_fields(cx.tcx, def_id);
136-
let dt = ty::ty_dtor(cx.tcx, def_id).is_present();
137-
Univariant(mk_struct(cx, fields.map(|field| {
122+
let ftys = do fields.map |field| {
138123
ty::lookup_field_type(cx.tcx, def_id, field.id, substs)
139-
})), if dt { StructWithDtor } else { StructWithoutDtor })
124+
};
125+
let dtor = ty::ty_dtor(cx.tcx, def_id).is_present();
126+
let ftys =
127+
if dtor { ftys + [ty::mk_bool(cx.tcx)] } else { ftys };
128+
Univariant(mk_struct(cx, ftys), dtor)
140129
}
141130
ty::ty_enum(def_id, ref substs) => {
142131
struct Case { discr: int, tys: ~[ty::t] };
@@ -149,18 +138,15 @@ pub fn represent_type(cx: @CrateContext, t: ty::t) -> @Repr {
149138
};
150139
if cases.len() == 0 {
151140
// Uninhabitable; represent as unit
152-
Unit(0)
153-
} else if cases.len() == 1 && cases[0].tys.len() == 0 {
154-
// `()`-like; see comment on definition of `Unit`.
155-
Unit(cases[0].discr)
156-
} else if cases.len() == 1 {
157-
// Equivalent to a struct/tuple/newtype.
158-
fail_unless!(cases[0].discr == 0);
159-
Univariant(mk_struct(cx, cases[0].tys), NonStruct)
141+
Univariant(mk_struct(cx, ~[]), false)
160142
} else if cases.all(|c| c.tys.len() == 0) {
161143
// All bodies empty -> intlike
162144
let discrs = cases.map(|c| c.discr);
163145
CEnum(discrs.min(), discrs.max())
146+
} else if cases.len() == 1 {
147+
// Equivalent to a struct/tuple/newtype.
148+
fail_unless!(cases[0].discr == 0);
149+
Univariant(mk_struct(cx, cases[0].tys), false)
164150
} else {
165151
// The general case. Since there's at least one
166152
// non-empty body, explicit discriminants should have
@@ -204,18 +190,12 @@ pub fn sizing_fields_of(cx: @CrateContext, r: &Repr) -> ~[TypeRef] {
204190
fn generic_fields_of(cx: @CrateContext, r: &Repr, sizing: bool)
205191
-> ~[TypeRef] {
206192
match *r {
207-
Unit(*) => ~[],
208193
CEnum(*) => ~[T_enum_discrim(cx)],
209-
Univariant(ref st, dt) => {
210-
let f = if sizing {
194+
Univariant(ref st, _dtor) => {
195+
if sizing {
211196
st.fields.map(|&ty| type_of::sizing_type_of(cx, ty))
212197
} else {
213198
st.fields.map(|&ty| type_of::type_of(cx, ty))
214-
};
215-
match dt {
216-
NonStruct => f,
217-
StructWithoutDtor => ~[T_struct(f)],
218-
StructWithDtor => ~[T_struct(f), T_i8()]
219199
}
220200
}
221201
General(ref sts) => {
@@ -237,7 +217,7 @@ pub fn trans_switch(bcx: block, r: &Repr, scrutinee: ValueRef)
237217
CEnum(*) | General(*) => {
238218
(_match::switch, Some(trans_get_discr(bcx, r, scrutinee)))
239219
}
240-
Unit(*) | Univariant(*) => {
220+
Univariant(*) => {
241221
(_match::single, None)
242222
}
243223
}
@@ -247,7 +227,6 @@ pub fn trans_switch(bcx: block, r: &Repr, scrutinee: ValueRef)
247227
pub fn trans_get_discr(bcx: block, r: &Repr, scrutinee: ValueRef)
248228
-> ValueRef {
249229
match *r {
250-
Unit(the_disc) => C_int(bcx.ccx(), the_disc),
251230
CEnum(min, max) => load_discr(bcx, scrutinee, min, max),
252231
Univariant(*) => C_int(bcx.ccx(), 0),
253232
General(ref cases) => load_discr(bcx, scrutinee, 0,
@@ -285,7 +264,7 @@ pub fn trans_case(bcx: block, r: &Repr, discr: int) -> _match::opt_result {
285264
CEnum(*) => {
286265
_match::single_result(rslt(bcx, C_int(bcx.ccx(), discr)))
287266
}
288-
Unit(*) | Univariant(*)=> {
267+
Univariant(*)=> {
289268
bcx.ccx().sess.bug(~"no cases for univariants or structs")
290269
}
291270
General(*) => {
@@ -301,16 +280,14 @@ pub fn trans_case(bcx: block, r: &Repr, discr: int) -> _match::opt_result {
301280
*/
302281
pub fn trans_start_init(bcx: block, r: &Repr, val: ValueRef, discr: int) {
303282
match *r {
304-
Unit(the_discr) => {
305-
fail_unless!(discr == the_discr);
306-
}
307283
CEnum(min, max) => {
308284
fail_unless!(min <= discr && discr <= max);
309285
Store(bcx, C_int(bcx.ccx(), discr), GEPi(bcx, val, [0, 0]))
310286
}
311-
Univariant(_, StructWithDtor) => {
287+
Univariant(ref st, true) => {
312288
fail_unless!(discr == 0);
313-
Store(bcx, C_u8(1), GEPi(bcx, val, [0, 1]))
289+
Store(bcx, C_bool(true),
290+
GEPi(bcx, val, [0, st.fields.len() - 1]))
314291
}
315292
Univariant(*) => {
316293
fail_unless!(discr == 0);
@@ -327,8 +304,11 @@ pub fn trans_start_init(bcx: block, r: &Repr, val: ValueRef, discr: int) {
327304
*/
328305
pub fn num_args(r: &Repr, discr: int) -> uint {
329306
match *r {
330-
Unit(*) | CEnum(*) => 0,
331-
Univariant(ref st, _) => { fail_unless!(discr == 0); st.fields.len() }
307+
CEnum(*) => 0,
308+
Univariant(ref st, dtor) => {
309+
fail_unless!(discr == 0);
310+
st.fields.len() - (if dtor { 1 } else { 0 })
311+
}
332312
General(ref cases) => cases[discr as uint].fields.len()
333313
}
334314
}
@@ -340,15 +320,11 @@ pub fn trans_field_ptr(bcx: block, r: &Repr, val: ValueRef, discr: int,
340320
// decide to do some kind of cdr-coding-like non-unique repr
341321
// someday), it will need to return a possibly-new bcx as well.
342322
match *r {
343-
Unit(*) | CEnum(*) => {
323+
CEnum(*) => {
344324
bcx.ccx().sess.bug(~"element access in C-like enum")
345325
}
346-
Univariant(ref st, dt) => {
326+
Univariant(ref st, _dtor) => {
347327
fail_unless!(discr == 0);
348-
let val = match dt {
349-
NonStruct => val,
350-
StructWithDtor | StructWithoutDtor => GEPi(bcx, val, [0, 0])
351-
};
352328
struct_field_ptr(bcx, st, val, ix, false)
353329
}
354330
General(ref cases) => {
@@ -376,7 +352,7 @@ fn struct_field_ptr(bcx: block, st: &Struct, val: ValueRef, ix: uint,
376352
/// Access the struct drop flag, if present.
377353
pub fn trans_drop_flag_ptr(bcx: block, r: &Repr, val: ValueRef) -> ValueRef {
378354
match *r {
379-
Univariant(_, StructWithDtor) => GEPi(bcx, val, [0, 1]),
355+
Univariant(ref st, true) => GEPi(bcx, val, [0, st.fields.len() - 1]),
380356
_ => bcx.ccx().sess.bug(~"tried to get drop flag of non-droppable \
381357
type")
382358
}
@@ -407,23 +383,14 @@ pub fn trans_drop_flag_ptr(bcx: block, r: &Repr, val: ValueRef) -> ValueRef {
407383
pub fn trans_const(ccx: @CrateContext, r: &Repr, discr: int,
408384
vals: &[ValueRef]) -> ValueRef {
409385
match *r {
410-
Unit(*) => {
411-
C_struct(~[])
412-
}
413386
CEnum(min, max) => {
414387
fail_unless!(vals.len() == 0);
415388
fail_unless!(min <= discr && discr <= max);
416389
C_int(ccx, discr)
417390
}
418-
Univariant(ref st, dt) => {
391+
Univariant(ref st, _dro) => {
419392
fail_unless!(discr == 0);
420-
let s = C_struct(build_const_struct(ccx, st, vals));
421-
match dt {
422-
NonStruct => s,
423-
// The actual destructor flag doesn't need to be present.
424-
// But add an extra struct layer for compatibility.
425-
StructWithDtor | StructWithoutDtor => C_struct(~[s])
426-
}
393+
C_struct(build_const_struct(ccx, st, vals))
427394
}
428395
General(ref cases) => {
429396
let case = &cases[discr as uint];
@@ -489,7 +456,6 @@ fn roundup(x: u64, a: u64) -> u64 { ((x + (a - 1)) / a) * a }
489456
pub fn const_get_discrim(ccx: @CrateContext, r: &Repr, val: ValueRef)
490457
-> int {
491458
match *r {
492-
Unit(discr) => discr,
493459
CEnum(*) => const_to_int(val) as int,
494460
Univariant(*) => 0,
495461
General(*) => const_to_int(const_get_elt(ccx, val, [0])) as int,
@@ -506,11 +472,9 @@ pub fn const_get_discrim(ccx: @CrateContext, r: &Repr, val: ValueRef)
506472
pub fn const_get_field(ccx: @CrateContext, r: &Repr, val: ValueRef,
507473
_discr: int, ix: uint) -> ValueRef {
508474
match *r {
509-
Unit(*) | CEnum(*) => ccx.sess.bug(~"element access in C-like enum \
475+
CEnum(*) => ccx.sess.bug(~"element access in C-like enum \
510476
const"),
511-
Univariant(_, NonStruct) => const_struct_field(ccx, val, ix),
512-
Univariant(*) => const_struct_field(ccx, const_get_elt(ccx, val,
513-
[0]), ix),
477+
Univariant(*) => const_struct_field(ccx, val, ix),
514478
General(*) => const_struct_field(ccx, const_get_elt(ccx, val,
515479
[1, 0]), ix)
516480
}
@@ -542,8 +506,7 @@ fn const_struct_field(ccx: @CrateContext, val: ValueRef, ix: uint)
542506
/// Is it safe to bitcast a value to the one field of its one variant?
543507
pub fn is_newtypeish(r: &Repr) -> bool {
544508
match *r {
545-
Univariant(ref st, StructWithoutDtor)
546-
| Univariant(ref st, NonStruct) => st.fields.len() == 1,
509+
Univariant(ref st, false) => st.fields.len() == 1,
547510
_ => false
548511
}
549512
}

0 commit comments

Comments
 (0)