Skip to content

Commit e09a843

Browse files
committed
Handle unit-like types specially.
This change remains separate from the addition of adt.rs, even though it's necessary for compatibility with pre-trans::adt representation, to serve as an example of a change to the representation logic.
1 parent 7b2b4fa commit e09a843

File tree

1 file changed

+19
-6
lines changed
  • src/librustc/middle/trans

1 file changed

+19
-6
lines changed

src/librustc/middle/trans/adt.rs

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ use util::ppaux::ty_to_str;
2424

2525
// XXX: should this be done with boxed traits instead of ML-style?
2626
pub enum Repr {
27+
Unit(int),
2728
CEnum(int, int), /* discriminant range */
2829
Univariant(Struct, Destructor),
2930
General(~[Struct])
@@ -77,8 +78,11 @@ pub fn represent_type(cx: @CrateContext, t: ty::t) -> Repr {
7778
if cases.len() == 0 {
7879
// Uninhabitable; represent as unit
7980
Univariant(mk_struct(cx, ~[]), NoDtor)
80-
} else if cases.len() == 1 && cases[0].discr == 0 {
81+
} else if cases.len() == 1 && cases[0].tys.len() == 0 {
82+
Unit(cases[0].discr)
83+
} else if cases.len() == 1 {
8184
// struct, tuple, newtype, etc.
85+
assert cases[0].discr == 0;
8286
Univariant(mk_struct(cx, cases[0].tys), NoDtor)
8387
} else if cases.all(|c| c.tys.len() == 0) {
8488
let discrs = cases.map(|c| c.discr);
@@ -116,6 +120,7 @@ pub fn fields_of(cx: @CrateContext, r: &Repr) -> ~[TypeRef] {
116120
fn generic_fields_of(cx: @CrateContext, r: &Repr, sizing: bool)
117121
-> ~[TypeRef] {
118122
match *r {
123+
Unit(*) => ~[],
119124
CEnum(*) => ~[T_enum_discrim(cx)],
120125
Univariant(ref st, dt) => {
121126
let f = if sizing {
@@ -160,7 +165,7 @@ pub fn trans_switch(bcx: block, r: &Repr, scrutinee: ValueRef) ->
160165
CEnum(min, max) => {
161166
(_match::switch, Some(load_discr(bcx, scrutinee, min, max)))
162167
}
163-
Univariant(*) => {
168+
Unit(*) | Univariant(*) => {
164169
(_match::single, None)
165170
}
166171
General(ref cases) => {
@@ -175,7 +180,7 @@ pub fn trans_case(bcx: block, r: &Repr, discr: int) -> _match::opt_result {
175180
CEnum(*) => {
176181
_match::single_result(rslt(bcx, C_int(bcx.ccx(), discr)))
177182
}
178-
Univariant(*) => {
183+
Unit(*) | Univariant(*)=> {
179184
bcx.ccx().sess.bug(~"no cases for univariants or structs")
180185
}
181186
General(*) => {
@@ -186,6 +191,9 @@ pub fn trans_case(bcx: block, r: &Repr, discr: int) -> _match::opt_result {
186191

187192
pub fn trans_set_discr(bcx: block, r: &Repr, val: ValueRef, discr: int) {
188193
match *r {
194+
Unit(the_discr) => {
195+
assert discr == the_discr;
196+
}
189197
CEnum(min, max) => {
190198
assert min <= discr && discr <= max;
191199
Store(bcx, C_int(bcx.ccx(), discr), GEPi(bcx, val, [0, 0]))
@@ -205,7 +213,7 @@ pub fn trans_set_discr(bcx: block, r: &Repr, val: ValueRef, discr: int) {
205213

206214
pub fn num_args(r: &Repr, discr: int) -> uint {
207215
match *r {
208-
CEnum(*) => 0,
216+
Unit(*) | CEnum(*) => 0,
209217
Univariant(ref st, _dt) => { assert discr == 0; st.fields.len() }
210218
General(ref cases) => cases[discr as uint].fields.len()
211219
}
@@ -217,7 +225,7 @@ pub fn trans_GEP(bcx: block, r: &Repr, val: ValueRef, discr: int, ix: uint)
217225
// decide to do some kind of cdr-coding-like non-unique repr
218226
// someday), it'll need to return a possibly-new bcx as well.
219227
match *r {
220-
CEnum(*) => {
228+
Unit(*) | CEnum(*) => {
221229
bcx.ccx().sess.bug(~"element access in C-like enum")
222230
}
223231
Univariant(ref st, dt) => {
@@ -253,6 +261,9 @@ fn struct_GEP(bcx: block, st: &Struct, val: ValueRef, ix: uint,
253261
pub fn trans_const(ccx: @CrateContext, r: &Repr, discr: int,
254262
vals: &[ValueRef]) -> ValueRef {
255263
match *r {
264+
Unit(*) => {
265+
C_struct(~[])
266+
}
256267
CEnum(min, max) => {
257268
assert vals.len() == 0;
258269
assert min <= discr && discr <= max;
@@ -312,6 +323,7 @@ fn roundup(x: u64, a: u64) -> u64 { ((x + (a - 1)) / a) * a }
312323
pub fn const_get_discrim(ccx: @CrateContext, r: &Repr, val: ValueRef)
313324
-> int {
314325
match *r {
326+
Unit(discr) => discr,
315327
CEnum(*) => const_to_int(val) as int,
316328
Univariant(*) => 0,
317329
General(*) => const_to_int(const_get_elt(ccx, val, [0])) as int,
@@ -322,7 +334,8 @@ pub fn const_get_element(ccx: @CrateContext, r: &Repr, val: ValueRef,
322334
_discr: int, ix: uint) -> ValueRef {
323335
// Not to be confused with common::const_get_elt.
324336
match *r {
325-
CEnum(*) => ccx.sess.bug(~"element access in C-like enum const"),
337+
Unit(*) | CEnum(*) => ccx.sess.bug(~"element access in C-like enum \
338+
const"),
326339
Univariant(*) => const_struct_field(ccx, val, ix),
327340
General(*) => const_struct_field(ccx, const_get_elt(ccx, val,
328341
[1, 0]), ix)

0 commit comments

Comments
 (0)