Skip to content

Commit e13111f

Browse files
committed
Even more comments for ADT-related interfaces
1 parent 6840b48 commit e13111f

File tree

2 files changed

+46
-6
lines changed

2 files changed

+46
-6
lines changed

src/librustc/middle/trans/adt.rs

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -394,9 +394,20 @@ pub fn trans_drop_flag_ptr(bcx: block, r: &Repr, val: ValueRef) -> ValueRef {
394394
* alignment!) from the representation's `type_of`, so it needs a
395395
* pointer cast before use.
396396
*
397-
* Currently it has the same size as the type, but this may be changed
398-
* in the future to avoid allocating unnecessary space after values of
399-
* shorter-than-maximum cases.
397+
* The LLVM type system does not directly support unions, and only
398+
* pointers can be bitcast, so a constant (and, by extension, the
399+
* GlobalVariable initialized by it) will have a type that can vary
400+
* depending on which case of an enum it is.
401+
*
402+
* To understand the alignment situation, consider `enum E { V64(u64),
403+
* V32(u32, u32) }` on win32. The type should have 8-byte alignment
404+
* to accommodate the u64 (currently it doesn't; this is a known bug),
405+
* but `V32(x, y)` would have LLVM type `{i32, i32, i32}`, which is
406+
* 4-byte aligned.
407+
*
408+
* Currently the returned value has the same size as the type, but
409+
* this may be changed in the future to avoid allocating unnecessary
410+
* space after values of shorter-than-maximum cases.
400411
*/
401412
pub fn trans_const(ccx: @CrateContext, r: &Repr, discr: int,
402413
vals: &[ValueRef]) -> ValueRef {
@@ -424,6 +435,9 @@ pub fn trans_const(ccx: @CrateContext, r: &Repr, discr: int,
424435
let max_sz = cases.map(|s| s.size).max();
425436
let body = build_const_struct(ccx, case, vals);
426437

438+
// The unary packed struct has alignment 1 regardless of
439+
// its contents, so it will always be located at the
440+
// expected offset at runtime.
427441
C_struct([C_int(ccx, discr),
428442
C_packed_struct([C_struct(body)]),
429443
padding(max_sz - case.size)])
@@ -434,6 +448,12 @@ pub fn trans_const(ccx: @CrateContext, r: &Repr, discr: int,
434448
/**
435449
* Building structs is a little complicated, because we might need to
436450
* insert padding if a field's value is less aligned than its type.
451+
*
452+
* Continuing the example from `trans_const`, a value of type `(u32,
453+
* E)` should have the `E` at offset 8, but if that field's
454+
* initializer is 4-byte aligned then simply translating the tuple as
455+
* a two-element struct will locate it at offset 4, and accesses to it
456+
* will read the wrong memory.
437457
*/
438458
fn build_const_struct(ccx: @CrateContext, st: &Struct, vals: &[ValueRef])
439459
-> ~[ValueRef] {

src/librustc/middle/trans/expr.rs

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1158,9 +1158,9 @@ fn trans_rec_or_struct(bcx: block,
11581158
let mut need_base = vec::from_elem(field_tys.len(), true);
11591159

11601160
let numbered_fields = do fields.map |field| {
1161-
match do vec::position(field_tys) |field_ty| {
1162-
field_ty.ident == field.node.ident
1163-
} {
1161+
let opt_pos = vec::position(field_tys, |field_ty|
1162+
field_ty.ident == field.node.ident);
1163+
match opt_pos {
11641164
Some(i) => {
11651165
need_base[i] = false;
11661166
(i, field.node.expr)
@@ -1196,11 +1196,31 @@ fn trans_rec_or_struct(bcx: block,
11961196
}
11971197
}
11981198

1199+
/**
1200+
* Information that `trans_adt` needs in order to fill in the fields
1201+
* of a struct copied from a base struct (e.g., from an expression
1202+
* like `Foo { a: b, ..base }`.
1203+
*
1204+
* Note that `fields` may be empty; the base expression must always be
1205+
* evaluated for side-effects.
1206+
*/
11991207
struct StructBaseInfo {
1208+
/// The base expression; will be evaluated after all explicit fields.
12001209
expr: @ast::expr,
1210+
/// The indices of fields to copy paired with their types.
12011211
fields: ~[(uint, ty::t)]
12021212
}
12031213

1214+
/**
1215+
* Constructs an ADT instance:
1216+
*
1217+
* - `fields` should be a list of field indices paired with the
1218+
* expression to store into that field. The initializers will be
1219+
* evaluated in the order specified by `fields`.
1220+
*
1221+
* - `optbase` contains information on the base struct (if any) from
1222+
* which remaining fields are copied; see comments on `StructBaseInfo`.
1223+
*/
12041224
fn trans_adt(bcx: block, repr: &adt::Repr, discr: int,
12051225
fields: &[(uint, @ast::expr)],
12061226
optbase: Option<StructBaseInfo>,

0 commit comments

Comments
 (0)