Skip to content

Commit 02276e9

Browse files
committed
rustc: collapse Layout::{Raw,StructWrapped}NullablePointer into one variant.
1 parent caef91d commit 02276e9

File tree

9 files changed

+91
-205
lines changed

9 files changed

+91
-205
lines changed

src/librustc/ty/layout.rs

Lines changed: 31 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -1133,24 +1133,14 @@ pub enum Layout {
11331133
},
11341134

11351135
/// Two cases distinguished by a nullable pointer: the case with discriminant
1136-
/// `nndiscr` must have single field which is known to be nonnull due to its type.
1137-
/// The other case is known to be zero sized. Hence we represent the enum
1138-
/// as simply a nullable pointer: if not null it indicates the `nndiscr` variant,
1139-
/// otherwise it indicates the other case.
1136+
/// `nndiscr` is represented by the struct `nonnull`, where the field at the
1137+
/// `discr_offset` offset is known to be nonnull due to its type; if that field is null, then
1138+
/// it represents the other case, which is known to be zero sized.
11401139
///
11411140
/// For example, `std::option::Option` instantiated at a safe pointer type
11421141
/// is represented such that `None` is a null pointer and `Some` is the
11431142
/// identity function.
1144-
RawNullablePointer {
1145-
nndiscr: u64,
1146-
discr: Primitive
1147-
},
1148-
1149-
/// Two cases distinguished by a nullable pointer: the case with discriminant
1150-
/// `nndiscr` is represented by the struct `nonnull`, where the field at the
1151-
/// `discr_offset` offset is known to be nonnull due to its type; if that field is null, then
1152-
/// it represents the other case, which is known to be zero sized.
1153-
StructWrappedNullablePointer {
1143+
NullablePointer {
11541144
nndiscr: u64,
11551145
nonnull: Struct,
11561146
discr: Primitive,
@@ -1259,18 +1249,16 @@ impl<'a, 'tcx> Layout {
12591249
FieldPlacement::union(def.struct_variant().fields.len())
12601250
}
12611251

1262-
General { .. } |
1263-
RawNullablePointer { .. } => FieldPlacement::union(1),
1252+
General { .. } => FieldPlacement::union(1),
12641253

1265-
StructWrappedNullablePointer { ref discr_offset, .. } => {
1254+
NullablePointer { ref discr_offset, .. } => {
12661255
FieldPlacement::Arbitrary {
12671256
offsets: ref_slice(discr_offset)
12681257
}
12691258
}
12701259
};
12711260
let abi = match *layout {
1272-
Scalar { value, .. } |
1273-
RawNullablePointer { discr: value, .. } => Abi::Scalar(value),
1261+
Scalar { value, .. } => Abi::Scalar(value),
12741262
CEnum { discr, .. } => Abi::Scalar(Int(discr)),
12751263

12761264
Vector { .. } => Abi::Vector,
@@ -1279,8 +1267,15 @@ impl<'a, 'tcx> Layout {
12791267
FatPointer { .. } |
12801268
Univariant(_) |
12811269
UntaggedUnion(_) |
1282-
General { .. } |
1283-
StructWrappedNullablePointer { .. } => Abi::Aggregate
1270+
General { .. } => Abi::Aggregate,
1271+
1272+
NullablePointer { discr, discr_offset, .. } => {
1273+
if discr_offset.bytes() == 0 && discr.size(cx) == layout.size(cx) {
1274+
Abi::Scalar(discr)
1275+
} else {
1276+
Abi::Aggregate
1277+
}
1278+
}
12841279
};
12851280
Ok(CachedLayout {
12861281
layout,
@@ -1562,15 +1557,6 @@ impl<'a, 'tcx> Layout {
15621557
// out of arrays with just the indexing operator.
15631558
let mut st = if discr == 0 { st0 } else { st1 };
15641559

1565-
// FIXME(eddyb) should take advantage of a newtype.
1566-
if offset.bytes() == 0 && primitive.size(dl) == st.stride() &&
1567-
variants[discr].len() == 1 {
1568-
return success(RawNullablePointer {
1569-
nndiscr: discr as u64,
1570-
discr: primitive,
1571-
});
1572-
}
1573-
15741560
let mut discr_align = primitive.align(dl);
15751561
if offset.abi_align(discr_align) != offset {
15761562
st.packed = true;
@@ -1579,7 +1565,7 @@ impl<'a, 'tcx> Layout {
15791565
st.align = st.align.max(discr_align);
15801566
st.primitive_align = st.primitive_align.max(discr_align);
15811567

1582-
return success(StructWrappedNullablePointer {
1568+
return success(NullablePointer {
15831569
nndiscr: discr as u64,
15841570
nonnull: st,
15851571
discr: primitive,
@@ -1715,8 +1701,7 @@ impl<'a, 'tcx> Layout {
17151701
match *self {
17161702
Scalar {..} | Vector {..} | FatPointer {..} |
17171703
CEnum {..} | UntaggedUnion {..} | General {..} |
1718-
RawNullablePointer {..} |
1719-
StructWrappedNullablePointer {..} => false,
1704+
NullablePointer {..} => false,
17201705

17211706
Array { sized, .. } |
17221707
Univariant(Struct { sized, .. }) => !sized
@@ -1727,7 +1712,7 @@ impl<'a, 'tcx> Layout {
17271712
let dl = cx.data_layout();
17281713

17291714
match *self {
1730-
Scalar { value, .. } | RawNullablePointer { discr: value, .. } => {
1715+
Scalar { value, .. } => {
17311716
value.size(dl)
17321717
}
17331718

@@ -1760,7 +1745,7 @@ impl<'a, 'tcx> Layout {
17601745
UntaggedUnion(ref un) => un.stride(),
17611746

17621747
Univariant(ref variant) |
1763-
StructWrappedNullablePointer { nonnull: ref variant, .. } => {
1748+
NullablePointer { nonnull: ref variant, .. } => {
17641749
variant.stride()
17651750
}
17661751
}
@@ -1770,7 +1755,7 @@ impl<'a, 'tcx> Layout {
17701755
let dl = cx.data_layout();
17711756

17721757
match *self {
1773-
Scalar { value, .. } | RawNullablePointer { discr: value, .. } => {
1758+
Scalar { value, .. } => {
17741759
value.align(dl)
17751760
}
17761761

@@ -1794,7 +1779,7 @@ impl<'a, 'tcx> Layout {
17941779
UntaggedUnion(ref un) => un.align,
17951780

17961781
Univariant(ref variant) |
1797-
StructWrappedNullablePointer { nonnull: ref variant, .. } => {
1782+
NullablePointer { nonnull: ref variant, .. } => {
17981783
variant.align
17991784
}
18001785
}
@@ -1809,7 +1794,7 @@ impl<'a, 'tcx> Layout {
18091794
match *self {
18101795
Array { primitive_align, .. } | General { primitive_align, .. } => primitive_align,
18111796
Univariant(ref variant) |
1812-
StructWrappedNullablePointer { nonnull: ref variant, .. } => {
1797+
NullablePointer { nonnull: ref variant, .. } => {
18131798
variant.primitive_align
18141799
},
18151800

@@ -1924,11 +1909,11 @@ impl<'a, 'tcx> Layout {
19241909
};
19251910

19261911
match *layout {
1927-
Layout::StructWrappedNullablePointer { nonnull: ref variant_layout,
1928-
nndiscr,
1929-
discr: _,
1930-
discr_offset: _ } => {
1931-
debug!("print-type-size t: `{:?}` adt struct-wrapped nullable nndiscr {} is {:?}",
1912+
Layout::NullablePointer { nonnull: ref variant_layout,
1913+
nndiscr,
1914+
discr: _,
1915+
discr_offset: _ } => {
1916+
debug!("print-type-size t: `{:?}` adt nullable nndiscr {} is {:?}",
19321917
ty, nndiscr, variant_layout);
19331918
let variant_def = &adt_def.variants[nndiscr as usize];
19341919
let fields: Vec<_> =
@@ -1941,13 +1926,6 @@ impl<'a, 'tcx> Layout {
19411926
&fields,
19421927
variant_layout)]);
19431928
}
1944-
Layout::RawNullablePointer { nndiscr, discr } => {
1945-
debug!("print-type-size t: `{:?}` adt raw nullable nndiscr {} is {:?}",
1946-
ty, nndiscr, discr);
1947-
let variant_def = &adt_def.variants[nndiscr as usize];
1948-
record(adt_kind.into(), None,
1949-
vec![build_primitive_info(variant_def.name, &discr)]);
1950-
}
19511929
Layout::Univariant(ref variant_layout) => {
19521930
let variant_names = || {
19531931
adt_def.variants.iter().map(|v|format!("{}", v.name)).collect::<Vec<_>>()
@@ -2314,7 +2292,7 @@ impl<'a, 'tcx> FullLayout<'tcx> {
23142292
}
23152293
}
23162294

2317-
StructWrappedNullablePointer { nndiscr, ref nonnull, .. }
2295+
NullablePointer { nndiscr, ref nonnull, .. }
23182296
if nndiscr as usize == variant_index => {
23192297
FieldPlacement::Arbitrary {
23202298
offsets: &nonnull.offsets
@@ -2402,8 +2380,7 @@ impl<'a, 'tcx> FullLayout<'tcx> {
24022380
General { discr, .. } => {
24032381
return [discr.to_ty(tcx, false)][i];
24042382
}
2405-
RawNullablePointer { discr, .. } |
2406-
StructWrappedNullablePointer { discr, .. } => {
2383+
NullablePointer { discr, .. } => {
24072384
return [discr.to_ty(tcx)][i];
24082385
}
24092386
_ if def.variants.len() > 1 => return [][i],
@@ -2483,11 +2460,7 @@ impl<'gcx> HashStable<StableHashingContext<'gcx>> for Layout
24832460
align.hash_stable(hcx, hasher);
24842461
primitive_align.hash_stable(hcx, hasher);
24852462
}
2486-
RawNullablePointer { nndiscr, ref discr } => {
2487-
nndiscr.hash_stable(hcx, hasher);
2488-
discr.hash_stable(hcx, hasher);
2489-
}
2490-
StructWrappedNullablePointer {
2463+
NullablePointer {
24912464
nndiscr,
24922465
ref nonnull,
24932466
ref discr,

src/librustc_trans/adt.rs

Lines changed: 9 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -69,10 +69,11 @@ pub fn finish_type_of<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
6969
let l = cx.layout_of(t);
7070
debug!("finish_type_of: {} with layout {:#?}", t, l);
7171
match *l {
72-
layout::CEnum { .. } | layout::General { .. }
73-
| layout::UntaggedUnion { .. } | layout::RawNullablePointer { .. } => { }
74-
layout::Univariant { ..}
75-
| layout::StructWrappedNullablePointer { .. } => {
72+
layout::CEnum { .. } | layout::General { .. } | layout::UntaggedUnion { .. } => { }
73+
layout::Univariant { ..} | layout::NullablePointer { .. } => {
74+
if let layout::Abi::Scalar(_) = l.abi {
75+
return;
76+
}
7677
let (variant_layout, variant) = match *l {
7778
layout::Univariant(ref variant) => {
7879
let is_enum = if let ty::TyAdt(def, _) = t.sty {
@@ -86,7 +87,7 @@ pub fn finish_type_of<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
8687
(l, variant)
8788
}
8889
}
89-
layout::StructWrappedNullablePointer { nndiscr, ref nonnull, .. } =>
90+
layout::NullablePointer { nndiscr, ref nonnull, .. } =>
9091
(l.for_variant(nndiscr as usize), nonnull),
9192
_ => unreachable!()
9293
};
@@ -103,15 +104,10 @@ fn generic_type_of<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
103104
debug!("adt::generic_type_of t: {:?} name: {:?}", t, name);
104105
match *l {
105106
layout::CEnum { discr, .. } => Type::from_integer(cx, discr),
106-
layout::RawNullablePointer { nndiscr, .. } => {
107-
let nnfield = l.for_variant(nndiscr as usize).field(cx, 0);
108-
if let layout::Scalar { value: layout::Pointer, .. } = *nnfield {
109-
Type::i8p(cx)
110-
} else {
111-
cx.llvm_type_of(nnfield.ty)
107+
layout::NullablePointer { nndiscr, ref nonnull, .. } => {
108+
if let layout::Abi::Scalar(_) = l.abi {
109+
return cx.llvm_type_of(l.field(cx, 0).ty);
112110
}
113-
}
114-
layout::StructWrappedNullablePointer { nndiscr, ref nonnull, .. } => {
115111
match name {
116112
None => {
117113
Type::struct_(cx, &struct_llfields(cx, l.for_variant(nndiscr as usize),

src/librustc_trans/cabi_x86_64.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ fn classify_arg<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, arg: &ArgType<'tcx>)
9292
// by putting variants in fields, or be more clever.
9393
match *layout {
9494
Layout::General { .. } |
95-
Layout::StructWrappedNullablePointer { .. } => return Err(Memory),
95+
Layout::NullablePointer { .. } => return Err(Memory),
9696
_ => {}
9797
}
9898
for i in 0..layout.fields.count() {

src/librustc_trans/debuginfo/metadata.rs

Lines changed: 2 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -1142,7 +1142,6 @@ struct EnumMemberDescriptionFactory<'tcx> {
11421142
type_rep: FullLayout<'tcx>,
11431143
discriminant_type_metadata: Option<DIType>,
11441144
containing_scope: DIScope,
1145-
file_metadata: DIFile,
11461145
span: Span,
11471146
}
11481147

@@ -1218,76 +1217,7 @@ impl<'tcx> EnumMemberDescriptionFactory<'tcx> {
12181217
]
12191218
}
12201219
}
1221-
layout::RawNullablePointer { nndiscr, .. } => {
1222-
// As far as debuginfo is concerned, the pointer this enum
1223-
// represents is still wrapped in a struct. This is to make the
1224-
// DWARF representation of enums uniform.
1225-
1226-
// First create a description of the artificial wrapper struct:
1227-
let non_null_variant = &adt.variants[nndiscr as usize];
1228-
let non_null_variant_name = non_null_variant.name.as_str();
1229-
1230-
// The llvm type and metadata of the pointer
1231-
let nnfield = self.type_rep.for_variant(nndiscr as usize).field(cx, 0);
1232-
let (size, align) = nnfield.size_and_align(cx);
1233-
let non_null_type_metadata = type_metadata(cx, nnfield.ty, self.span);
1234-
1235-
// For the metadata of the wrapper struct, we need to create a
1236-
// MemberDescription of the struct's single field.
1237-
let sole_struct_member_description = MemberDescription {
1238-
name: match non_null_variant.ctor_kind {
1239-
CtorKind::Fn => "__0".to_string(),
1240-
CtorKind::Fictive => {
1241-
non_null_variant.fields[0].name.to_string()
1242-
}
1243-
CtorKind::Const => bug!()
1244-
},
1245-
type_metadata: non_null_type_metadata,
1246-
offset: Size::from_bytes(0),
1247-
size,
1248-
align,
1249-
flags: DIFlags::FlagZero
1250-
};
1251-
1252-
let unique_type_id = debug_context(cx).type_map
1253-
.borrow_mut()
1254-
.get_unique_type_id_of_enum_variant(
1255-
cx,
1256-
self.enum_type,
1257-
&non_null_variant_name);
1258-
1259-
// Now we can create the metadata of the artificial struct
1260-
let artificial_struct_metadata =
1261-
composite_type_metadata(cx,
1262-
nnfield.ty,
1263-
&non_null_variant_name,
1264-
unique_type_id,
1265-
&[sole_struct_member_description],
1266-
self.containing_scope,
1267-
self.file_metadata,
1268-
syntax_pos::DUMMY_SP);
1269-
1270-
// Encode the information about the null variant in the union
1271-
// member's name.
1272-
let null_variant_name = adt.variants[(1 - nndiscr) as usize].name;
1273-
let union_member_name = format!("RUST$ENCODED$ENUM${}${}",
1274-
0,
1275-
null_variant_name);
1276-
1277-
// Finally create the (singleton) list of descriptions of union
1278-
// members.
1279-
vec![
1280-
MemberDescription {
1281-
name: union_member_name,
1282-
type_metadata: artificial_struct_metadata,
1283-
offset: Size::from_bytes(0),
1284-
size,
1285-
align,
1286-
flags: DIFlags::FlagZero
1287-
}
1288-
]
1289-
},
1290-
layout::StructWrappedNullablePointer {
1220+
layout::NullablePointer {
12911221
nonnull: ref struct_def,
12921222
nndiscr,
12931223
discr,
@@ -1566,9 +1496,7 @@ fn prepare_enum_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
15661496
layout::CEnum { discr, signed, .. } => {
15671497
return FinalMetadata(discriminant_type_metadata(discr, signed))
15681498
},
1569-
layout::RawNullablePointer { .. } |
1570-
layout::StructWrappedNullablePointer { .. } |
1571-
layout::Univariant { .. } => None,
1499+
layout::NullablePointer { .. } | layout::Univariant { .. } => None,
15721500
layout::General { discr, .. } => Some(discriminant_type_metadata(discr, false)),
15731501
ref l @ _ => bug!("Not an enum layout: {:#?}", l)
15741502
};
@@ -1604,7 +1532,6 @@ fn prepare_enum_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
16041532
type_rep,
16051533
discriminant_type_metadata,
16061534
containing_scope,
1607-
file_metadata,
16081535
span,
16091536
}),
16101537
);

src/librustc_trans/mir/constant.rs

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1127,15 +1127,7 @@ fn trans_const_adt<'a, 'tcx>(
11271127
layout::Vector { .. } => {
11281128
Const::new(C_vector(&vals.iter().map(|x| x.llval).collect::<Vec<_>>()), t)
11291129
}
1130-
layout::RawNullablePointer { nndiscr, .. } => {
1131-
if variant_index as u64 == nndiscr {
1132-
assert_eq!(vals.len(), 1);
1133-
Const::new(vals[0].llval, t)
1134-
} else {
1135-
Const::new(C_null(ccx.llvm_type_of(t)), t)
1136-
}
1137-
}
1138-
layout::StructWrappedNullablePointer { ref nonnull, nndiscr, .. } => {
1130+
layout::NullablePointer { ref nonnull, nndiscr, .. } => {
11391131
if variant_index as u64 == nndiscr {
11401132
build_const_struct(ccx, l, &nonnull, vals, None)
11411133
} else {

0 commit comments

Comments
 (0)