Skip to content

Commit 018323f

Browse files
committed
rustc: collapse the remains of Layout into Variants (enums vs everything else).
1 parent b28f668 commit 018323f

File tree

9 files changed

+188
-236
lines changed

9 files changed

+188
-236
lines changed

src/librustc/ty/layout.rs

Lines changed: 64 additions & 122 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
@@ -13,7 +13,7 @@
1313
use rustc::hir::def_id::DefId;
1414
use rustc::ty::subst::Substs;
1515
use rustc::ty::{self, AdtKind, Ty, TyCtxt};
16-
use rustc::ty::layout::{Layout, LayoutOf};
16+
use rustc::ty::layout::{self, LayoutOf};
1717
use middle::const_val::ConstVal;
1818
use rustc_const_eval::ConstContext;
1919
use util::nodemap::FxHashSet;
@@ -753,7 +753,7 @@ 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, discr, .. } = layout.layout {
756+
if let layout::Variants::Tagged { ref variants, discr, .. } = layout.variants {
757757
let discr_size = discr.size(cx.tcx).bytes();
758758

759759
debug!("enum `{}` is {} bytes large with layout:\n{:#?}",

src/librustc_trans/cabi_x86_64.rs

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
use abi::{ArgType, ArgAttribute, CastTarget, FnType, LayoutExt, Reg, RegKind};
1515
use context::CrateContext;
1616

17-
use rustc::ty::layout::{self, Layout, TyLayout, Size};
17+
use rustc::ty::layout::{self, TyLayout, Size};
1818

1919
#[derive(Clone, Copy, PartialEq, Debug)]
2020
enum Class {
@@ -87,17 +87,15 @@ fn classify_arg<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, arg: &ArgType<'tcx>)
8787
}
8888

8989
layout::Abi::Aggregate { .. } => {
90-
// FIXME(eddyb) have to work around Rust enums for now.
91-
// Fix is either guarantee no data where there is no field,
92-
// by putting variants in fields, or be more clever.
93-
match layout.layout {
94-
Layout::General { .. } |
95-
Layout::NullablePointer { .. } => return Err(Memory),
96-
_ => {}
97-
}
98-
for i in 0..layout.fields.count() {
99-
let field_off = off + layout.fields.offset(i);
100-
classify(ccx, layout.field(ccx, i), cls, field_off)?;
90+
match layout.variants {
91+
layout::Variants::Single { .. } => {
92+
for i in 0..layout.fields.count() {
93+
let field_off = off + layout.fields.offset(i);
94+
classify(ccx, layout.field(ccx, i), cls, field_off)?;
95+
}
96+
}
97+
layout::Variants::Tagged { .. } |
98+
layout::Variants::NicheFilling { .. } => return Err(Memory),
10199
}
102100
}
103101

src/librustc_trans/debuginfo/metadata.rs

Lines changed: 48 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -1119,7 +1119,7 @@ fn prepare_union_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
11191119
// offset of zero bytes).
11201120
struct EnumMemberDescriptionFactory<'tcx> {
11211121
enum_type: Ty<'tcx>,
1122-
type_rep: TyLayout<'tcx>,
1122+
layout: TyLayout<'tcx>,
11231123
discriminant_type_metadata: Option<DIType>,
11241124
containing_scope: DIScope,
11251125
span: Span,
@@ -1129,45 +1129,16 @@ impl<'tcx> EnumMemberDescriptionFactory<'tcx> {
11291129
fn create_member_descriptions<'a>(&self, cx: &CrateContext<'a, 'tcx>)
11301130
-> Vec<MemberDescription> {
11311131
let adt = &self.enum_type.ty_adt_def().unwrap();
1132-
match self.type_rep.layout {
1133-
layout::Layout::General { ref variants, .. } => {
1134-
let discriminant_info = RegularDiscriminant(self.discriminant_type_metadata
1135-
.expect(""));
1136-
(0..variants.len()).map(|i| {
1137-
let variant = self.type_rep.for_variant(i);
1138-
let (variant_type_metadata, member_desc_factory) =
1139-
describe_enum_variant(cx,
1140-
variant,
1141-
&adt.variants[i],
1142-
discriminant_info,
1143-
self.containing_scope,
1144-
self.span);
1145-
1146-
let member_descriptions = member_desc_factory
1147-
.create_member_descriptions(cx);
1148-
1149-
set_members_of_composite_type(cx,
1150-
variant_type_metadata,
1151-
&member_descriptions);
1152-
MemberDescription {
1153-
name: "".to_string(),
1154-
type_metadata: variant_type_metadata,
1155-
offset: Size::from_bytes(0),
1156-
size: variant.size,
1157-
align: variant.align,
1158-
flags: DIFlags::FlagZero
1159-
}
1160-
}).collect()
1161-
},
1162-
layout::Layout::Univariant => {
1132+
match self.layout.variants {
1133+
layout::Variants::Single { .. } => {
11631134
assert!(adt.variants.len() <= 1);
11641135

11651136
if adt.variants.is_empty() {
11661137
vec![]
11671138
} else {
11681139
let (variant_type_metadata, member_description_factory) =
11691140
describe_enum_variant(cx,
1170-
self.type_rep,
1141+
self.layout,
11711142
&adt.variants[0],
11721143
NoDiscriminant,
11731144
self.containing_scope,
@@ -1184,19 +1155,48 @@ impl<'tcx> EnumMemberDescriptionFactory<'tcx> {
11841155
name: "".to_string(),
11851156
type_metadata: variant_type_metadata,
11861157
offset: Size::from_bytes(0),
1187-
size: self.type_rep.size,
1188-
align: self.type_rep.align,
1158+
size: self.layout.size,
1159+
align: self.layout.align,
11891160
flags: DIFlags::FlagZero
11901161
}
11911162
]
11921163
}
11931164
}
1194-
layout::Layout::NullablePointer {
1165+
layout::Variants::Tagged { ref variants, .. } => {
1166+
let discriminant_info = RegularDiscriminant(self.discriminant_type_metadata
1167+
.expect(""));
1168+
(0..variants.len()).map(|i| {
1169+
let variant = self.layout.for_variant(i);
1170+
let (variant_type_metadata, member_desc_factory) =
1171+
describe_enum_variant(cx,
1172+
variant,
1173+
&adt.variants[i],
1174+
discriminant_info,
1175+
self.containing_scope,
1176+
self.span);
1177+
1178+
let member_descriptions = member_desc_factory
1179+
.create_member_descriptions(cx);
1180+
1181+
set_members_of_composite_type(cx,
1182+
variant_type_metadata,
1183+
&member_descriptions);
1184+
MemberDescription {
1185+
name: "".to_string(),
1186+
type_metadata: variant_type_metadata,
1187+
offset: Size::from_bytes(0),
1188+
size: variant.size,
1189+
align: variant.align,
1190+
flags: DIFlags::FlagZero
1191+
}
1192+
}).collect()
1193+
}
1194+
layout::Variants::NicheFilling {
11951195
nndiscr,
11961196
discr,
11971197
..
11981198
} => {
1199-
let variant = self.type_rep.for_variant(nndiscr as usize);
1199+
let variant = self.layout.for_variant(nndiscr as usize);
12001200
// Create a description of the non-null variant
12011201
let (variant_type_metadata, member_description_factory) =
12021202
describe_enum_variant(cx,
@@ -1237,8 +1237,8 @@ impl<'tcx> EnumMemberDescriptionFactory<'tcx> {
12371237
}
12381238
}
12391239
compute_field_path(cx, &mut name,
1240-
self.type_rep,
1241-
self.type_rep.fields.offset(0),
1240+
self.layout,
1241+
self.layout.fields.offset(0),
12421242
discr.size(cx));
12431243
name.push_str(&adt.variants[(1 - nndiscr) as usize].name.as_str());
12441244

@@ -1253,8 +1253,7 @@ impl<'tcx> EnumMemberDescriptionFactory<'tcx> {
12531253
flags: DIFlags::FlagZero
12541254
}
12551255
]
1256-
},
1257-
ref l @ _ => bug!("Not an enum layout: {:#?}", l)
1256+
}
12581257
}
12591258
}
12601259
}
@@ -1429,21 +1428,20 @@ fn prepare_enum_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
14291428
}
14301429
};
14311430

1432-
let type_rep = cx.layout_of(enum_type);
1431+
let layout = cx.layout_of(enum_type);
14331432

1434-
let discriminant_type_metadata = match type_rep.layout {
1435-
layout::Layout::NullablePointer { .. } |
1436-
layout::Layout::Univariant { .. } => None,
1437-
layout::Layout::General { discr, .. } => Some(discriminant_type_metadata(discr)),
1438-
ref l @ _ => bug!("Not an enum layout: {:#?}", l)
1433+
let discriminant_type_metadata = match layout.variants {
1434+
layout::Variants::Single { .. } |
1435+
layout::Variants::NicheFilling { .. } => None,
1436+
layout::Variants::Tagged { discr, .. } => Some(discriminant_type_metadata(discr)),
14391437
};
14401438

1441-
match (type_rep.abi, discriminant_type_metadata) {
1439+
match (layout.abi, discriminant_type_metadata) {
14421440
(layout::Abi::Scalar(_), Some(discr)) => return FinalMetadata(discr),
14431441
_ => {}
14441442
}
14451443

1446-
let (enum_type_size, enum_type_align) = type_rep.size_and_align();
1444+
let (enum_type_size, enum_type_align) = layout.size_and_align();
14471445

14481446
let enum_name = CString::new(enum_name).unwrap();
14491447
let unique_type_id_str = CString::new(
@@ -1471,7 +1469,7 @@ fn prepare_enum_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
14711469
enum_metadata,
14721470
EnumMDF(EnumMemberDescriptionFactory {
14731471
enum_type,
1474-
type_rep,
1472+
layout,
14751473
discriminant_type_metadata,
14761474
containing_scope,
14771475
span,

src/librustc_trans/intrinsic.rs

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -394,12 +394,7 @@ pub fn trans_intrinsic_call<'a, 'tcx>(bcx: &Builder<'a, 'tcx>,
394394
},
395395

396396
"discriminant_value" => {
397-
match substs.type_at(0).sty {
398-
ty::TyAdt(adt, ..) if adt.is_enum() => {
399-
args[0].deref(bcx.ccx).trans_get_discr(bcx, ret_ty)
400-
}
401-
_ => C_null(llret_ty)
402-
}
397+
args[0].deref(bcx.ccx).trans_get_discr(bcx, ret_ty)
403398
}
404399

405400
"align_offset" => {

src/librustc_trans/mir/constant.rs

Lines changed: 21 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1094,8 +1094,26 @@ fn trans_const_adt<'a, 'tcx>(
10941094
mir::AggregateKind::Adt(_, index, _, _) => index,
10951095
_ => 0,
10961096
};
1097-
match l.layout {
1098-
layout::Layout::General { .. } => {
1097+
match l.variants {
1098+
layout::Variants::Single { index } => {
1099+
assert_eq!(variant_index, index);
1100+
if let layout::Abi::Vector { .. } = l.abi {
1101+
Const::new(C_vector(&vals.iter().map(|x| x.llval).collect::<Vec<_>>()), t)
1102+
} else if let layout::FieldPlacement::Union(_) = l.fields {
1103+
assert_eq!(variant_index, 0);
1104+
assert_eq!(vals.len(), 1);
1105+
let contents = [
1106+
vals[0].llval,
1107+
padding(ccx, l.size - ccx.size_of(vals[0].ty))
1108+
];
1109+
1110+
Const::new(C_struct(ccx, &contents, l.is_packed()), t)
1111+
} else {
1112+
assert_eq!(variant_index, 0);
1113+
build_const_struct(ccx, l, vals, None)
1114+
}
1115+
}
1116+
layout::Variants::Tagged { .. } => {
10991117
let discr = match *kind {
11001118
mir::AggregateKind::Adt(adt_def, _, _, _) => {
11011119
adt_def.discriminant_for_variant(ccx.tcx(), variant_index)
@@ -1112,23 +1130,7 @@ fn trans_const_adt<'a, 'tcx>(
11121130
build_const_struct(ccx, l.for_variant(variant_index), vals, Some(discr))
11131131
}
11141132
}
1115-
layout::Layout::UntaggedUnion => {
1116-
assert_eq!(variant_index, 0);
1117-
let contents = [
1118-
vals[0].llval,
1119-
padding(ccx, l.size - ccx.size_of(vals[0].ty))
1120-
];
1121-
1122-
Const::new(C_struct(ccx, &contents, l.is_packed()), t)
1123-
}
1124-
layout::Layout::Univariant => {
1125-
assert_eq!(variant_index, 0);
1126-
build_const_struct(ccx, l, vals, None)
1127-
}
1128-
layout::Layout::Vector => {
1129-
Const::new(C_vector(&vals.iter().map(|x| x.llval).collect::<Vec<_>>()), t)
1130-
}
1131-
layout::Layout::NullablePointer { nndiscr, .. } => {
1133+
layout::Variants::NicheFilling { nndiscr, .. } => {
11321134
if variant_index as u64 == nndiscr {
11331135
build_const_struct(ccx, l.for_variant(variant_index), vals, None)
11341136
} else {
@@ -1137,7 +1139,6 @@ fn trans_const_adt<'a, 'tcx>(
11371139
Const::new(C_null(ccx.layout_of(t).llvm_type(ccx)), t)
11381140
}
11391141
}
1140-
_ => bug!("trans_const_adt: cannot handle type {} repreented as {:#?}", t, l)
11411142
}
11421143
}
11431144

src/librustc_trans/mir/lvalue.rs

Lines changed: 22 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -296,19 +296,24 @@ impl<'a, 'tcx> LvalueRef<'tcx> {
296296
/// Obtain the actual discriminant of a value.
297297
pub fn trans_get_discr(self, bcx: &Builder<'a, 'tcx>, cast_to: Ty<'tcx>) -> ValueRef {
298298
let cast_to = bcx.ccx.layout_of(cast_to).immediate_llvm_type(bcx.ccx);
299-
match self.layout.layout {
300-
layout::Layout::Univariant { .. } |
301-
layout::Layout::UntaggedUnion { .. } => return C_uint(cast_to, 0),
302-
_ => {}
299+
match self.layout.variants {
300+
layout::Variants::Single { index } => {
301+
assert_eq!(index, 0);
302+
return C_uint(cast_to, 0);
303+
}
304+
layout::Variants::Tagged { .. } |
305+
layout::Variants::NicheFilling { .. } => {},
303306
}
304307

305308
let discr = self.project_field(bcx, 0);
306309
let discr_scalar = match discr.layout.abi {
307310
layout::Abi::Scalar(discr) => discr,
308311
_ => bug!("discriminant not scalar: {:#?}", discr.layout)
309312
};
310-
let (min, max) = match self.layout.layout {
311-
layout::Layout::General { ref discr_range, .. } => (discr_range.start, discr_range.end),
313+
let (min, max) = match self.layout.variants {
314+
layout::Variants::Tagged { ref discr_range, .. } => {
315+
(discr_range.start, discr_range.end)
316+
}
312317
_ => (0, u64::max_value()),
313318
};
314319
let max_next = max.wrapping_add(1);
@@ -333,20 +338,20 @@ impl<'a, 'tcx> LvalueRef<'tcx> {
333338
bcx.load(discr.llval, discr.alignment.non_abi())
334339
}
335340
};
336-
match self.layout.layout {
337-
layout::Layout::General { .. } => {
341+
match self.layout.variants {
342+
layout::Variants::Single { .. } => bug!(),
343+
layout::Variants::Tagged { .. } => {
338344
let signed = match discr_scalar {
339345
layout::Int(_, signed) => signed,
340346
_ => false
341347
};
342348
bcx.intcast(lldiscr, cast_to, signed)
343349
}
344-
layout::Layout::NullablePointer { nndiscr, .. } => {
350+
layout::Variants::NicheFilling { nndiscr, .. } => {
345351
let cmp = if nndiscr == 0 { llvm::IntEQ } else { llvm::IntNE };
346352
let zero = C_null(discr.layout.llvm_type(bcx.ccx));
347353
bcx.intcast(bcx.icmp(cmp, lldiscr, zero), cast_to, false)
348354
}
349-
_ => bug!("{} is not an enum", self.layout.ty)
350355
}
351356
}
352357

@@ -356,13 +361,17 @@ impl<'a, 'tcx> LvalueRef<'tcx> {
356361
let to = self.layout.ty.ty_adt_def().unwrap()
357362
.discriminant_for_variant(bcx.tcx(), variant_index)
358363
.to_u128_unchecked() as u64;
359-
match self.layout.layout {
360-
layout::Layout::General { .. } => {
364+
match self.layout.variants {
365+
layout::Variants::Single { index } => {
366+
assert_eq!(to, 0);
367+
assert_eq!(variant_index, index);
368+
}
369+
layout::Variants::Tagged { .. } => {
361370
let ptr = self.project_field(bcx, 0);
362371
bcx.store(C_int(ptr.layout.llvm_type(bcx.ccx), to as i64),
363372
ptr.llval, ptr.alignment.non_abi());
364373
}
365-
layout::Layout::NullablePointer { nndiscr, .. } => {
374+
layout::Variants::NicheFilling { nndiscr, .. } => {
366375
if to != nndiscr {
367376
let use_memset = match self.layout.abi {
368377
layout::Abi::Scalar(_) => false,
@@ -385,9 +394,6 @@ impl<'a, 'tcx> LvalueRef<'tcx> {
385394
}
386395
}
387396
}
388-
_ => {
389-
assert_eq!(to, 0);
390-
}
391397
}
392398
}
393399

0 commit comments

Comments
 (0)