Skip to content

Commit 446daa7

Browse files
committed
---
yaml --- r: 51274 b: refs/heads/incoming c: 58cec70 h: refs/heads/master v: v3
1 parent abbf400 commit 446daa7

File tree

3 files changed

+80
-43
lines changed

3 files changed

+80
-43
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ refs/heads/try: 8eb2bab100b42f0ba751552d8eff00eb2134c55a
66
refs/tags/release-0.1: 1f5c5126e96c79d22cb7862f75304136e204f105
77
refs/heads/ndm: f3868061cd7988080c30d6d5bf352a5a5fe2460b
88
refs/heads/try2: 147ecfdd8221e4a4d4e090486829a06da1e0ca3c
9-
refs/heads/incoming: ce24ebb8589cb6533359b0e398e6da88e9c228ef
9+
refs/heads/incoming: 58cec701277cc7dd881bb41d7f9469f077574a75
1010
refs/heads/dist-snap: 8b98e5a296d95c5e832db0756828e5bec31c6f50
1111
refs/tags/release-0.2: c870d2dffb391e14efb05aa27898f1f6333a9596
1212
refs/tags/release-0.3: b5f0d0f648d9a6153664837026ba1be43d3e2503

branches/incoming/src/librustc/middle/trans/adt.rs

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

7272
/// Representations.
7373
pub enum Repr {
74-
/// C-like enums; basically an int.
75-
CEnum(int, int), // discriminant range
7674
/**
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.
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.
8280
*/
83-
Univariant(Struct, bool),
81+
Unit(int),
82+
/// C-like enums; basically an int.
83+
CEnum(int, int), // discriminant range
84+
/// Single-case variants, and structs/tuples/records.
85+
Univariant(Struct, Destructor),
8486
/**
8587
* General-case enums: discriminant as int, followed by fields.
8688
* The fields start immediately after the discriminant, meaning
@@ -90,6 +92,18 @@ pub enum Repr {
9092
General(~[Struct])
9193
}
9294

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+
93107
/// For structs, and struct-like parts of anything fancier.
94108
struct Struct {
95109
size: u64,
@@ -115,17 +129,14 @@ pub fn represent_type(cx: @CrateContext, t: ty::t) -> @Repr {
115129
}
116130
let repr = @match ty::get(t).sty {
117131
ty::ty_tup(ref elems) => {
118-
Univariant(mk_struct(cx, *elems), false)
132+
Univariant(mk_struct(cx, *elems), NonStruct)
119133
}
120134
ty::ty_struct(def_id, ref substs) => {
121135
let fields = ty::lookup_struct_fields(cx.tcx, def_id);
122-
let ftys = do fields.map |field| {
136+
let dt = ty::ty_dtor(cx.tcx, def_id).is_present();
137+
Univariant(mk_struct(cx, fields.map(|field| {
123138
ty::lookup_field_type(cx.tcx, def_id, field.id, substs)
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)
139+
})), if dt { StructWithDtor } else { StructWithoutDtor })
129140
}
130141
ty::ty_enum(def_id, ref substs) => {
131142
struct Case { discr: int, tys: ~[ty::t] };
@@ -138,15 +149,18 @@ pub fn represent_type(cx: @CrateContext, t: ty::t) -> @Repr {
138149
};
139150
if cases.len() == 0 {
140151
// Uninhabitable; represent as unit
141-
Univariant(mk_struct(cx, ~[]), false)
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)
142160
} else if cases.all(|c| c.tys.len() == 0) {
143161
// All bodies empty -> intlike
144162
let discrs = cases.map(|c| c.discr);
145163
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)
150164
} else {
151165
// The general case. Since there's at least one
152166
// non-empty body, explicit discriminants should have
@@ -190,12 +204,18 @@ pub fn sizing_fields_of(cx: @CrateContext, r: &Repr) -> ~[TypeRef] {
190204
fn generic_fields_of(cx: @CrateContext, r: &Repr, sizing: bool)
191205
-> ~[TypeRef] {
192206
match *r {
207+
Unit(*) => ~[],
193208
CEnum(*) => ~[T_enum_discrim(cx)],
194-
Univariant(ref st, _dtor) => {
195-
if sizing {
209+
Univariant(ref st, dt) => {
210+
let f = if sizing {
196211
st.fields.map(|&ty| type_of::sizing_type_of(cx, ty))
197212
} else {
198213
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()]
199219
}
200220
}
201221
General(ref sts) => {
@@ -217,7 +237,7 @@ pub fn trans_switch(bcx: block, r: &Repr, scrutinee: ValueRef)
217237
CEnum(*) | General(*) => {
218238
(_match::switch, Some(trans_get_discr(bcx, r, scrutinee)))
219239
}
220-
Univariant(*) => {
240+
Unit(*) | Univariant(*) => {
221241
(_match::single, None)
222242
}
223243
}
@@ -227,6 +247,7 @@ pub fn trans_switch(bcx: block, r: &Repr, scrutinee: ValueRef)
227247
pub fn trans_get_discr(bcx: block, r: &Repr, scrutinee: ValueRef)
228248
-> ValueRef {
229249
match *r {
250+
Unit(the_disc) => C_int(bcx.ccx(), the_disc),
230251
CEnum(min, max) => load_discr(bcx, scrutinee, min, max),
231252
Univariant(*) => C_int(bcx.ccx(), 0),
232253
General(ref cases) => load_discr(bcx, scrutinee, 0,
@@ -264,7 +285,7 @@ pub fn trans_case(bcx: block, r: &Repr, discr: int) -> _match::opt_result {
264285
CEnum(*) => {
265286
_match::single_result(rslt(bcx, C_int(bcx.ccx(), discr)))
266287
}
267-
Univariant(*)=> {
288+
Unit(*) | Univariant(*)=> {
268289
bcx.ccx().sess.bug(~"no cases for univariants or structs")
269290
}
270291
General(*) => {
@@ -280,14 +301,16 @@ pub fn trans_case(bcx: block, r: &Repr, discr: int) -> _match::opt_result {
280301
*/
281302
pub fn trans_start_init(bcx: block, r: &Repr, val: ValueRef, discr: int) {
282303
match *r {
304+
Unit(the_discr) => {
305+
fail_unless!(discr == the_discr);
306+
}
283307
CEnum(min, max) => {
284308
fail_unless!(min <= discr && discr <= max);
285309
Store(bcx, C_int(bcx.ccx(), discr), GEPi(bcx, val, [0, 0]))
286310
}
287-
Univariant(ref st, true) => {
311+
Univariant(_, StructWithDtor) => {
288312
fail_unless!(discr == 0);
289-
Store(bcx, C_bool(true),
290-
GEPi(bcx, val, [0, st.fields.len() - 1]))
313+
Store(bcx, C_u8(1), GEPi(bcx, val, [0, 1]))
291314
}
292315
Univariant(*) => {
293316
fail_unless!(discr == 0);
@@ -304,11 +327,8 @@ pub fn trans_start_init(bcx: block, r: &Repr, val: ValueRef, discr: int) {
304327
*/
305328
pub fn num_args(r: &Repr, discr: int) -> uint {
306329
match *r {
307-
CEnum(*) => 0,
308-
Univariant(ref st, dtor) => {
309-
fail_unless!(discr == 0);
310-
st.fields.len() - (if dtor { 1 } else { 0 })
311-
}
330+
Unit(*) | CEnum(*) => 0,
331+
Univariant(ref st, _) => { fail_unless!(discr == 0); st.fields.len() }
312332
General(ref cases) => cases[discr as uint].fields.len()
313333
}
314334
}
@@ -320,11 +340,15 @@ pub fn trans_field_ptr(bcx: block, r: &Repr, val: ValueRef, discr: int,
320340
// decide to do some kind of cdr-coding-like non-unique repr
321341
// someday), it will need to return a possibly-new bcx as well.
322342
match *r {
323-
CEnum(*) => {
343+
Unit(*) | CEnum(*) => {
324344
bcx.ccx().sess.bug(~"element access in C-like enum")
325345
}
326-
Univariant(ref st, _dtor) => {
346+
Univariant(ref st, dt) => {
327347
fail_unless!(discr == 0);
348+
let val = match dt {
349+
NonStruct => val,
350+
StructWithDtor | StructWithoutDtor => GEPi(bcx, val, [0, 0])
351+
};
328352
struct_field_ptr(bcx, st, val, ix, false)
329353
}
330354
General(ref cases) => {
@@ -352,7 +376,7 @@ fn struct_field_ptr(bcx: block, st: &Struct, val: ValueRef, ix: uint,
352376
/// Access the struct drop flag, if present.
353377
pub fn trans_drop_flag_ptr(bcx: block, r: &Repr, val: ValueRef) -> ValueRef {
354378
match *r {
355-
Univariant(ref st, true) => GEPi(bcx, val, [0, st.fields.len() - 1]),
379+
Univariant(_, StructWithDtor) => GEPi(bcx, val, [0, 1]),
356380
_ => bcx.ccx().sess.bug(~"tried to get drop flag of non-droppable \
357381
type")
358382
}
@@ -383,14 +407,23 @@ pub fn trans_drop_flag_ptr(bcx: block, r: &Repr, val: ValueRef) -> ValueRef {
383407
pub fn trans_const(ccx: @CrateContext, r: &Repr, discr: int,
384408
vals: &[ValueRef]) -> ValueRef {
385409
match *r {
410+
Unit(*) => {
411+
C_struct(~[])
412+
}
386413
CEnum(min, max) => {
387414
fail_unless!(vals.len() == 0);
388415
fail_unless!(min <= discr && discr <= max);
389416
C_int(ccx, discr)
390417
}
391-
Univariant(ref st, _dro) => {
418+
Univariant(ref st, dt) => {
392419
fail_unless!(discr == 0);
393-
C_struct(build_const_struct(ccx, st, vals))
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+
}
394427
}
395428
General(ref cases) => {
396429
let case = &cases[discr as uint];
@@ -456,6 +489,7 @@ fn roundup(x: u64, a: u64) -> u64 { ((x + (a - 1)) / a) * a }
456489
pub fn const_get_discrim(ccx: @CrateContext, r: &Repr, val: ValueRef)
457490
-> int {
458491
match *r {
492+
Unit(discr) => discr,
459493
CEnum(*) => const_to_int(val) as int,
460494
Univariant(*) => 0,
461495
General(*) => const_to_int(const_get_elt(ccx, val, [0])) as int,
@@ -472,9 +506,11 @@ pub fn const_get_discrim(ccx: @CrateContext, r: &Repr, val: ValueRef)
472506
pub fn const_get_field(ccx: @CrateContext, r: &Repr, val: ValueRef,
473507
_discr: int, ix: uint) -> ValueRef {
474508
match *r {
475-
CEnum(*) => ccx.sess.bug(~"element access in C-like enum \
509+
Unit(*) | CEnum(*) => ccx.sess.bug(~"element access in C-like enum \
476510
const"),
477-
Univariant(*) => const_struct_field(ccx, val, ix),
511+
Univariant(_, NonStruct) => const_struct_field(ccx, val, ix),
512+
Univariant(*) => const_struct_field(ccx, const_get_elt(ccx, val,
513+
[0]), ix),
478514
General(*) => const_struct_field(ccx, const_get_elt(ccx, val,
479515
[1, 0]), ix)
480516
}
@@ -506,7 +542,8 @@ fn const_struct_field(ccx: @CrateContext, val: ValueRef, ix: uint)
506542
/// Is it safe to bitcast a value to the one field of its one variant?
507543
pub fn is_newtypeish(r: &Repr) -> bool {
508544
match *r {
509-
Univariant(ref st, false) => st.fields.len() == 1,
545+
Univariant(ref st, StructWithoutDtor)
546+
| Univariant(ref st, NonStruct) => st.fields.len() == 1,
510547
_ => false
511548
}
512549
}

branches/incoming/src/libstd/treemap.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -509,8 +509,8 @@ pub fn set_next<T>(iter: &mut TreeSetIterator/&r<T>) -> Option<&r/T> {
509509
}
510510

511511
/// Advance the iterator through the set
512-
fn set_advance<T>(iter: &mut TreeSetIterator/&r<T>,
513-
f: &fn(&r/T) -> bool) {
512+
pub fn set_advance<T>(iter: &mut TreeSetIterator/&r<T>,
513+
f: &fn(&r/T) -> bool) {
514514
do map_advance(&mut iter.iter) |(k, _)| { f(k) }
515515
}
516516

0 commit comments

Comments
 (0)