Skip to content

Commit 085575d

Browse files
committed
Even more comments for ADT-related interfaces
1 parent 9e779c6 commit 085575d

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

432+
// The unary packed struct has alignment 1 regardless of
433+
// its contents, so it will always be located at the
434+
// expected offset at runtime.
421435
C_struct([C_int(ccx, discr),
422436
C_packed_struct([C_struct(body)]),
423437
padding(max_sz - case.size)])
@@ -428,6 +442,12 @@ pub fn trans_const(ccx: @CrateContext, r: &Repr, discr: int,
428442
/**
429443
* Building structs is a little complicated, because we might need to
430444
* insert padding if a field's value is less aligned than its type.
445+
*
446+
* Continuing the example from `trans_const`, a value of type `(u32,
447+
* E)` should have the `E` at offset 8, but if that field's
448+
* initializer is 4-byte aligned then simply translating the tuple as
449+
* a two-element struct will locate it at offset 4, and accesses to it
450+
* will read the wrong memory.
431451
*/
432452
fn build_const_struct(ccx: @CrateContext, st: &Struct, vals: &[ValueRef])
433453
-> ~[ValueRef] {

src/librustc/middle/trans/expr.rs

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

11121112
let numbered_fields = do fields.map |field| {
1113-
match do vec::position(field_tys) |field_ty| {
1114-
field_ty.ident == field.node.ident
1115-
} {
1113+
let opt_pos = vec::position(field_tys, |field_ty|
1114+
field_ty.ident == field.node.ident);
1115+
match opt_pos {
11161116
Some(i) => {
11171117
need_base[i] = false;
11181118
(i, field.node.expr)
@@ -1148,11 +1148,31 @@ fn trans_rec_or_struct(bcx: block,
11481148
}
11491149
}
11501150

1151+
/**
1152+
* Information that `trans_adt` needs in order to fill in the fields
1153+
* of a struct copied from a base struct (e.g., from an expression
1154+
* like `Foo { a: b, ..base }`.
1155+
*
1156+
* Note that `fields` may be empty; the base expression must always be
1157+
* evaluated for side-effects.
1158+
*/
11511159
struct StructBaseInfo {
1160+
/// The base expression; will be evaluated after all explicit fields.
11521161
expr: @ast::expr,
1162+
/// The indices of fields to copy paired with their types.
11531163
fields: ~[(uint, ty::t)]
11541164
}
11551165

1166+
/**
1167+
* Constructs an ADT instance:
1168+
*
1169+
* - `fields` should be a list of field indices paired with the
1170+
* expression to store into that field. The initializers will be
1171+
* evaluated in the order specified by `fields`.
1172+
*
1173+
* - `optbase` contains information on the base struct (if any) from
1174+
* which remaining fields are copied; see comments on `StructBaseInfo`.
1175+
*/
11561176
fn trans_adt(bcx: block, repr: &adt::Repr, discr: int,
11571177
fields: &[(uint, @ast::expr)],
11581178
optbase: Option<StructBaseInfo>,

0 commit comments

Comments
 (0)