Skip to content

Commit 08f9f13

Browse files
committed
rustc: hide details in Layout in favor of Abi or FieldPlacement.
1 parent ed788a6 commit 08f9f13

File tree

10 files changed

+353
-484
lines changed

10 files changed

+353
-484
lines changed

src/librustc/ty/layout.rs

Lines changed: 273 additions & 345 deletions
Large diffs are not rendered by default.

src/librustc_lint/types.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -753,11 +753,11 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for VariantSizeDifferences {
753753
bug!("failed to get layout for `{}`: {}", t, e)
754754
});
755755

756-
if let Layout::General { ref variants, size, discr, .. } = *layout.layout {
756+
if let Layout::General { ref variants, discr, .. } = *layout.layout {
757757
let discr_size = discr.size(cx.tcx).bytes();
758758

759759
debug!("enum `{}` is {} bytes large with layout:\n{:#?}",
760-
t, size.bytes(), layout);
760+
t, layout.size(cx.tcx).bytes(), layout);
761761

762762
let (largest, slargest, largest_index) = enum_definition.variants
763763
.iter()

src/librustc_trans/abi.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -307,8 +307,8 @@ impl<'tcx> LayoutExt<'tcx> for FullLayout<'tcx> {
307307
}
308308

309309
layout::Abi::Aggregate { .. } => {
310-
if let Layout::Array { count, .. } = *self.layout {
311-
if count > 0 {
310+
if let Layout::Array { .. } = *self.layout {
311+
if self.fields.count() > 0 {
312312
return self.field(ccx, 0).homogeneous_aggregate(ccx);
313313
}
314314
}

src/librustc_trans/adt.rs

Lines changed: 47 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@
4242
//! taken to it, implementing them for Rust seems difficult.
4343
4444
use rustc::ty::{self, Ty};
45-
use rustc::ty::layout::{self, Align, HasDataLayout, LayoutOf, Size, FullLayout};
45+
use rustc::ty::layout::{self, HasDataLayout, LayoutOf, Size, FullLayout};
4646

4747
use context::CrateContext;
4848
use type_::Type;
@@ -72,11 +72,7 @@ pub fn finish_type_of<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
7272
return;
7373
}
7474
match *l.layout {
75-
layout::NullablePointer { .. } |
76-
layout::General { .. } |
77-
layout::UntaggedUnion { .. } => { }
78-
79-
layout::Univariant(ref variant) => {
75+
layout::Univariant(_) => {
8076
let is_enum = if let ty::TyAdt(def, _) = t.sty {
8177
def.is_enum()
8278
} else {
@@ -87,9 +83,11 @@ pub fn finish_type_of<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
8783
} else {
8884
l
8985
};
90-
llty.set_struct_body(&struct_llfields(cx, variant_layout), variant.packed)
91-
},
92-
_ => bug!("This function cannot handle {} with layout {:#?}", t, l)
86+
llty.set_struct_body(&struct_llfields(cx, variant_layout),
87+
variant_layout.is_packed())
88+
}
89+
90+
_ => {}
9391
}
9492
}
9593

@@ -102,81 +100,65 @@ fn generic_type_of<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
102100
return cx.llvm_type_of(value.to_ty(cx.tcx()));
103101
}
104102
match *l.layout {
105-
layout::Univariant(ref variant) => {
103+
layout::Univariant(_) => {
106104
match name {
107105
None => {
108-
Type::struct_(cx, &struct_llfields(cx, l), variant.packed)
106+
Type::struct_(cx, &struct_llfields(cx, l), l.is_packed())
109107
}
110108
Some(name) => {
111109
Type::named_struct(cx, name)
112110
}
113111
}
114112
}
115-
layout::UntaggedUnion(ref un) => {
116-
// Use alignment-sized ints to fill all the union storage.
117-
let fill = union_fill(cx, un.stride(), un.align);
118-
match name {
119-
None => {
120-
Type::struct_(cx, &[fill], un.packed)
121-
}
122-
Some(name) => {
123-
let mut llty = Type::named_struct(cx, name);
124-
llty.set_struct_body(&[fill], un.packed);
125-
llty
126-
}
127-
}
128-
}
129-
layout::NullablePointer { size, align, .. } |
130-
layout::General { size, align, .. } => {
131-
let fill = union_fill(cx, size, align);
113+
_ => {
114+
let align = l.align(cx);
115+
let abi_align = align.abi();
116+
let elem_ty = if let Some(ity) = layout::Integer::for_abi_align(cx, align) {
117+
Type::from_integer(cx, ity)
118+
} else {
119+
let vec_align = cx.data_layout().vector_align(Size::from_bytes(abi_align));
120+
assert_eq!(vec_align.abi(), abi_align);
121+
Type::vector(&Type::i32(cx), abi_align / 4)
122+
};
123+
124+
let size = l.size(cx).bytes();
125+
assert_eq!(size % abi_align, 0);
126+
let fill = Type::array(&elem_ty, size / abi_align);
132127
match name {
133128
None => {
134-
Type::struct_(cx, &[fill], false)
129+
Type::struct_(cx, &[fill], l.is_packed())
135130
}
136131
Some(name) => {
137132
let mut llty = Type::named_struct(cx, name);
138-
llty.set_struct_body(&[fill], false);
133+
llty.set_struct_body(&[fill], l.is_packed());
139134
llty
140135
}
141136
}
142137
}
143-
_ => bug!("Unsupported type {} represented as {:#?}", t, l)
144138
}
145139
}
146140

147-
fn union_fill(cx: &CrateContext, size: Size, align: Align) -> Type {
148-
let abi_align = align.abi();
149-
let elem_ty = if let Some(ity) = layout::Integer::for_abi_align(cx, align) {
150-
Type::from_integer(cx, ity)
151-
} else {
152-
let vec_align = cx.data_layout().vector_align(Size::from_bytes(abi_align));
153-
assert_eq!(vec_align.abi(), abi_align);
154-
Type::vector(&Type::i32(cx), abi_align / 4)
155-
};
156-
157-
let size = size.bytes();
158-
assert_eq!(size % abi_align, 0);
159-
Type::array(&elem_ty, size / abi_align)
160-
}
161-
162141
/// Double an index and add 1 to account for padding.
163142
pub fn memory_index_to_gep(index: u64) -> u64 {
164143
1 + index * 2
165144
}
166145

167146
pub fn struct_llfields<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
168147
layout: FullLayout<'tcx>) -> Vec<Type> {
169-
let variant = match *layout.layout {
170-
layout::Univariant(ref variant) => variant,
171-
_ => bug!("unexpected {:#?}", layout)
172-
};
148+
debug!("struct_llfields: {:#?}", layout);
149+
let align = layout.align(cx);
150+
let size = layout.size(cx);
173151
let field_count = layout.fields.count();
174-
debug!("struct_llfields: variant: {:?}", variant);
152+
175153
let mut offset = Size::from_bytes(0);
176154
let mut result: Vec<Type> = Vec::with_capacity(1 + field_count * 2);
177-
for i in variant.field_index_by_increasing_offset() {
155+
let field_index_by_increasing_offset = match *layout.layout {
156+
layout::Univariant(ref variant) => variant.field_index_by_increasing_offset(),
157+
_ => bug!("unexpected {:#?}", layout)
158+
};
159+
for i in field_index_by_increasing_offset {
178160
let field = layout.field(cx, i);
179-
let target_offset = variant.offsets[i as usize];
161+
let target_offset = layout.fields.offset(i as usize);
180162
debug!("struct_llfields: {}: {:?} offset: {:?} target_offset: {:?}",
181163
i, field, offset, target_offset);
182164
assert!(target_offset >= offset);
@@ -187,30 +169,30 @@ pub fn struct_llfields<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
187169
let llty = cx.llvm_type_of(field.ty);
188170
result.push(llty);
189171

190-
if variant.packed {
172+
if layout.is_packed() {
191173
assert_eq!(padding.bytes(), 0);
192174
} else {
193175
let field_align = field.align(cx);
194-
assert!(field_align.abi() <= variant.align.abi(),
176+
assert!(field_align.abi() <= align.abi(),
195177
"non-packed type has field with larger align ({}): {:#?}",
196-
field_align.abi(), variant);
178+
field_align.abi(), layout);
197179
}
198180

199181
offset = target_offset + field.size(cx);
200182
}
201-
if variant.sized && field_count > 0 {
202-
if offset > variant.stride() {
203-
bug!("variant: {:?} stride: {:?} offset: {:?}",
204-
variant, variant.stride(), offset);
183+
if !layout.is_unsized() && field_count > 0 {
184+
if offset > size {
185+
bug!("layout: {:#?} stride: {:?} offset: {:?}",
186+
layout, size, offset);
205187
}
206-
let padding = variant.stride() - offset;
207-
debug!("struct_llfields: pad_bytes: {:?} offset: {:?} min_size: {:?} stride: {:?}",
208-
padding, offset, variant.min_size, variant.stride());
188+
let padding = size - offset;
189+
debug!("struct_llfields: pad_bytes: {:?} offset: {:?} stride: {:?}",
190+
padding, offset, size);
209191
result.push(Type::array(&Type::i8(cx), padding.bytes()));
210192
assert!(result.len() == 1 + field_count * 2);
211193
} else {
212-
debug!("struct_llfields: offset: {:?} min_size: {:?} stride: {:?}",
213-
offset, variant.min_size, variant.stride());
194+
debug!("struct_llfields: offset: {:?} stride: {:?}",
195+
offset, size);
214196
}
215197

216198
result

src/librustc_trans/common.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,9 +65,9 @@ pub fn type_is_imm_pair<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, ty: Ty<'tcx>)
6565
let layout = ccx.layout_of(ty);
6666
match *layout.layout {
6767
Layout::FatPointer { .. } => true,
68-
Layout::Univariant(ref variant) => {
68+
Layout::Univariant(_) => {
6969
// There must be only 2 fields.
70-
if variant.offsets.len() != 2 {
70+
if layout.fields.count() != 2 {
7171
return false;
7272
}
7373

src/librustc_trans/debuginfo/metadata.rs

Lines changed: 2 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -939,20 +939,6 @@ impl<'tcx> StructMemberDescriptionFactory<'tcx> {
939939
fn create_member_descriptions<'a>(&self, cx: &CrateContext<'a, 'tcx>)
940940
-> Vec<MemberDescription> {
941941
let layout = cx.layout_of(self.ty);
942-
943-
let tmp;
944-
let offsets = match *layout.layout {
945-
layout::Univariant(ref variant) => &variant.offsets,
946-
layout::Vector { element, count } => {
947-
let element_size = element.size(cx).bytes();
948-
tmp = (0..count).
949-
map(|i| layout::Size::from_bytes(i*element_size))
950-
.collect::<Vec<layout::Size>>();
951-
&tmp
952-
}
953-
_ => bug!("{} is not a struct", self.ty)
954-
};
955-
956942
self.variant.fields.iter().enumerate().map(|(i, f)| {
957943
let name = if self.variant.ctor_kind == CtorKind::Fn {
958944
format!("__{}", i)
@@ -964,7 +950,7 @@ impl<'tcx> StructMemberDescriptionFactory<'tcx> {
964950
MemberDescription {
965951
name,
966952
type_metadata: type_metadata(cx, field.ty, self.span),
967-
offset: offsets[i],
953+
offset: layout.fields.offset(i),
968954
size,
969955
align,
970956
flags: DIFlags::FlagZero,
@@ -1022,18 +1008,12 @@ impl<'tcx> TupleMemberDescriptionFactory<'tcx> {
10221008
fn create_member_descriptions<'a>(&self, cx: &CrateContext<'a, 'tcx>)
10231009
-> Vec<MemberDescription> {
10241010
let layout = cx.layout_of(self.ty);
1025-
let offsets = if let layout::Univariant(ref variant) = *layout.layout {
1026-
&variant.offsets
1027-
} else {
1028-
bug!("{} is not a tuple", self.ty);
1029-
};
1030-
10311011
self.component_types.iter().enumerate().map(|(i, &component_type)| {
10321012
let (size, align) = cx.size_and_align_of(component_type);
10331013
MemberDescription {
10341014
name: format!("__{}", i),
10351015
type_metadata: type_metadata(cx, component_type, self.span),
1036-
offset: offsets[i],
1016+
offset: layout.fields.offset(i),
10371017
size,
10381018
align,
10391019
flags: DIFlags::FlagZero,

src/librustc_trans/glue.rs

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -58,23 +58,17 @@ pub fn size_and_align_of_dst<'a, 'tcx>(bcx: &Builder<'a, 'tcx>, t: Ty<'tcx>, inf
5858
let layout = ccx.layout_of(t);
5959
debug!("DST {} layout: {:?}", t, layout);
6060

61-
let (sized_size, sized_align) = match *layout.layout {
62-
ty::layout::Layout::Univariant(ref variant) => {
63-
(variant.offsets.last().map_or(0, |o| o.bytes()), variant.align.abi())
64-
}
65-
_ => {
66-
bug!("size_and_align_of_dst: expcted Univariant for `{}`, found {:#?}",
67-
t, layout);
68-
}
69-
};
61+
let i = layout.fields.count() - 1;
62+
let sized_size = layout.fields.offset(i).bytes();
63+
let sized_align = layout.align(ccx).abi();
7064
debug!("DST {} statically sized prefix size: {} align: {}",
7165
t, sized_size, sized_align);
7266
let sized_size = C_usize(ccx, sized_size);
7367
let sized_align = C_usize(ccx, sized_align);
7468

7569
// Recurse to get the size of the dynamically sized field (must be
7670
// the last field).
77-
let field_ty = layout.field(ccx, layout.fields.count() - 1).ty;
71+
let field_ty = layout.field(ccx, i).ty;
7872
let (unsized_size, unsized_align) = size_and_align_of_dst(bcx, field_ty, info);
7973

8074
// FIXME (#26403, #27023): We should be adding padding

src/librustc_trans/mir/constant.rs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1108,14 +1108,14 @@ fn trans_const_adt<'a, 'tcx>(
11081108
build_const_struct(ccx, l.for_variant(variant_index), vals, Some(discr))
11091109
}
11101110
}
1111-
layout::UntaggedUnion(ref un) => {
1111+
layout::UntaggedUnion => {
11121112
assert_eq!(variant_index, 0);
11131113
let contents = [
11141114
vals[0].llval,
1115-
padding(ccx, un.stride() - ccx.size_of(vals[0].ty))
1115+
padding(ccx, l.size(ccx) - ccx.size_of(vals[0].ty))
11161116
];
11171117

1118-
Const::new(C_struct(ccx, &contents, un.packed), t)
1118+
Const::new(C_struct(ccx, &contents, l.is_packed()), t)
11191119
}
11201120
layout::Univariant(_) => {
11211121
assert_eq!(variant_index, 0);
@@ -1162,11 +1162,11 @@ fn build_const_struct<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
11621162
offset = ccx.size_of(discr.ty);
11631163
}
11641164

1165-
let st = match *layout.layout {
1166-
layout::Univariant(ref variant) => variant,
1165+
let field_index_by_increasing_offset = match *layout.layout {
1166+
layout::Univariant(ref variant) => variant.field_index_by_increasing_offset(),
11671167
_ => bug!("unexpected {:#?}", layout)
11681168
};
1169-
let parts = st.field_index_by_increasing_offset().map(|i| {
1169+
let parts = field_index_by_increasing_offset.map(|i| {
11701170
(vals[i], layout.fields.offset(i))
11711171
});
11721172
for (val, target_offset) in parts {
@@ -1178,7 +1178,7 @@ fn build_const_struct<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
11781178
// Pad to the size of the whole type, not e.g. the variant.
11791179
cfields.push(padding(ccx, ccx.size_of(layout.ty) - offset));
11801180

1181-
Const::new(C_struct(ccx, &cfields, st.packed), layout.ty)
1181+
Const::new(C_struct(ccx, &cfields, layout.is_packed()), layout.ty)
11821182
}
11831183

11841184
fn padding(ccx: &CrateContext, size: Size) -> ValueRef {

0 commit comments

Comments
 (0)