fn build_const_struct<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
                                st: &Struct<'tcx>, vals: &[ValueRef])
                                -> Vec<ValueRef> {
    assert_eq!(vals.len(), st.fields.len());

    let target_offsets = compute_struct_field_offsets(ccx, st);

    // offset of current value
    let mut offset = 0;
    let mut cfields = Vec::new();
    for (&val, target_offset) in vals.iter().zip(target_offsets) {
        if !st.packed {
            let val_align = machine::llalign_of_min(ccx, val_ty(val));
            offset = roundup(offset, val_align);
        }
        if offset != target_offset {
            cfields.push(padding(ccx, target_offset - offset));
            offset = target_offset;
        }
        assert!(!is_undef(val));
        cfields.push(val);
        offset += machine::llsize_of_alloc(ccx, val_ty(val));
    }

    assert!(st.sized && offset <= st.size);
    if offset != st.size {
        cfields.push(padding(ccx, st.size - offset));
    }

    cfields
}
/// Building structs is a little complicated, because we might need to
/// insert padding if a field's value is less aligned than its type.
///
/// Continuing the example from `trans_const`, a value of type `(u32,
/// E)` should have the `E` at offset 8, but if that field's
/// initializer is 4-byte aligned then simply translating the tuple as
/// a two-element struct will locate it at offset 4, and accesses to it
/// will read the wrong memory.
Building structs is a little complicated, because we might need to
insert padding if a field's value is less aligned than its type.


Building structs is a little complicated because we might need to insert padding if a field ' s value is less aligned than its type .
fn build_const_struct<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
                                st: &Struct<'tcx>, vals: &[ValueRef])
                                -> Vec<ValueRef> {
    assert_eq!(vals.len(), st.fields.len());
    let target_offsets = compute_struct_field_offsets(ccx, st);
    // offset of current value
    let mut offset = 0;
    let mut cfields = Vec::new();
    for (&val, target_offset) in vals.iter().zip(target_offsets) {
        if !st.packed {
            let val_align = machine::llalign_of_min(ccx, val_ty(val));
            offset = roundup(offset, val_align);
        }
        if offset != target_offset {
            cfields.push(padding(ccx, target_offset - offset));
            offset = target_offset;
        }
        assert!(!is_undef(val));
        cfields.push(val);
        offset += machine::llsize_of_alloc(ccx, val_ty(val));
    }
    assert!(st.sized && offset <= st.size);
    if offset != st.size {
        cfields.push(padding(ccx, st.size - offset));
    }
    cfields
}
fn build_const_struct < ' a , ' tcx > ( ccx : & CrateContext < ' a , ' tcx > , st : & Struct < ' tcx > , vals : & [ ValueRef ] ) -> Vec < ValueRef > { assert_eq ! ( vals len ( ) st fields len ( ) ) ; let target_offsets = compute_struct_field_offsets ( ccx , st ) ; // offset of current value let mut offset = 0 ; let mut cfields = Vec :: new ( ) ; for ( & val , target_offset ) in vals . iter ( ) . zip ( target_offsets ) { if ! st . packed { let val_align = machine :: llalign_of_min ( ccx , val_ty ( val ) ) ; offset = roundup ( offset , val_align ) ; } if offset != target_offset { cfields . push ( padding ( ccx , target_offset - offset ) ) ; offset = target_offset ; } assert ! ( is_undef ( val ) ) ; cfields . push ( val ) ; offset += machine :: llsize_of_alloc ( ccx , val_ty ( val ) ) ; } assert ! ( st sized offset st size ) ; if offset != st . size { cfields . push ( padding ( ccx , st . size - offset ) ) ; } cfields }
Building structs is a little complicated, because we might need to
insert padding if a field's value is less aligned than its type.
Building structs is a little complicated because we might need to insert padding if a field ' s value is less aligned than its type .
ccx
&CrateContext<'a, 'tcx>
st
&Struct<'tcx>
vals
&[ValueRef]
ccx
&CrateContext<'a, 'tcx>
st
&Struct<'tcx>
vals
&[ValueRef]