Skip to content

Commit 8e0d3b3

Browse files
committed
Add VariantIdx back
1 parent 59035a3 commit 8e0d3b3

File tree

3 files changed

+87
-61
lines changed

3 files changed

+87
-61
lines changed

compiler/rustc_abi/src/layout.rs

Lines changed: 55 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -8,15 +8,19 @@ use tracing::debug;
88
use crate::{
99
Abi, AbiAndPrefAlign, Align, FieldsShape, IndexSlice, IndexVec, Integer, LayoutS, Niche,
1010
NonZeroUsize, Primitive, ReprOptions, Scalar, Size, StructKind, TagEncoding, TargetDataLayout,
11-
VariantIdx, Variants, WrappingRange, FIRST_VARIANT,
11+
Variants, WrappingRange,
1212
};
1313
pub trait LayoutCalculator {
1414
type TargetDataLayoutRef: Borrow<TargetDataLayout>;
1515

1616
fn delay_bug(&self, txt: String);
1717
fn current_data_layout(&self) -> Self::TargetDataLayoutRef;
1818

19-
fn scalar_pair<FieldIdx: Idx>(&self, a: Scalar, b: Scalar) -> LayoutS<FieldIdx> {
19+
fn scalar_pair<FieldIdx: Idx, VariantIdx: Idx>(
20+
&self,
21+
a: Scalar,
22+
b: Scalar,
23+
) -> LayoutS<FieldIdx, VariantIdx> {
2024
let dl = self.current_data_layout();
2125
let dl = dl.borrow();
2226
let b_align = b.align(dl);
@@ -32,7 +36,7 @@ pub trait LayoutCalculator {
3236
.max_by_key(|niche| niche.available(dl));
3337

3438
LayoutS {
35-
variants: Variants::Single { index: FIRST_VARIANT },
39+
variants: Variants::Single { index: VariantIdx::new(0) },
3640
fields: FieldsShape::Arbitrary {
3741
offsets: [Size::ZERO, b_offset].into(),
3842
memory_index: [0, 1].into(),
@@ -46,13 +50,18 @@ pub trait LayoutCalculator {
4650
}
4751
}
4852

49-
fn univariant<'a, FieldIdx: Idx, F: Deref<Target = &'a LayoutS<FieldIdx>> + fmt::Debug>(
53+
fn univariant<
54+
'a,
55+
FieldIdx: Idx,
56+
VariantIdx: Idx,
57+
F: Deref<Target = &'a LayoutS<FieldIdx, VariantIdx>> + fmt::Debug,
58+
>(
5059
&self,
5160
dl: &TargetDataLayout,
5261
fields: &IndexSlice<FieldIdx, F>,
5362
repr: &ReprOptions,
5463
kind: StructKind,
55-
) -> Option<LayoutS<FieldIdx>> {
64+
) -> Option<LayoutS<FieldIdx, VariantIdx>> {
5665
let layout = univariant(self, dl, fields, repr, kind, NicheBias::Start);
5766
// Enums prefer niches close to the beginning or the end of the variants so that other (smaller)
5867
// data-carrying variants can be packed into the space after/before the niche.
@@ -115,11 +124,13 @@ pub trait LayoutCalculator {
115124
layout
116125
}
117126

118-
fn layout_of_never_type<FieldIdx: Idx>(&self) -> LayoutS<FieldIdx> {
127+
fn layout_of_never_type<FieldIdx: Idx, VariantIdx: Idx>(
128+
&self,
129+
) -> LayoutS<FieldIdx, VariantIdx> {
119130
let dl = self.current_data_layout();
120131
let dl = dl.borrow();
121132
LayoutS {
122-
variants: Variants::Single { index: FIRST_VARIANT },
133+
variants: Variants::Single { index: VariantIdx::new(0) },
123134
fields: FieldsShape::Primitive,
124135
abi: Abi::Uninhabited,
125136
largest_niche: None,
@@ -133,7 +144,8 @@ pub trait LayoutCalculator {
133144
fn layout_of_struct_or_enum<
134145
'a,
135146
FieldIdx: Idx,
136-
F: Deref<Target = &'a LayoutS<FieldIdx>> + fmt::Debug,
147+
VariantIdx: Idx,
148+
F: Deref<Target = &'a LayoutS<FieldIdx, VariantIdx>> + fmt::Debug,
137149
>(
138150
&self,
139151
repr: &ReprOptions,
@@ -145,7 +157,7 @@ pub trait LayoutCalculator {
145157
discriminants: impl Iterator<Item = (VariantIdx, i128)>,
146158
dont_niche_optimize_enum: bool,
147159
always_sized: bool,
148-
) -> Option<LayoutS<FieldIdx>> {
160+
) -> Option<LayoutS<FieldIdx, VariantIdx>> {
149161
let dl = self.current_data_layout();
150162
let dl = dl.borrow();
151163

@@ -181,7 +193,7 @@ pub trait LayoutCalculator {
181193
}
182194
// If it's a struct, still compute a layout so that we can still compute the
183195
// field offsets.
184-
None => FIRST_VARIANT,
196+
None => VariantIdx::new(0),
185197
};
186198

187199
let is_struct = !is_enum ||
@@ -284,12 +296,12 @@ pub trait LayoutCalculator {
284296
// variant layouts, so we can't store them in the
285297
// overall LayoutS. Store the overall LayoutS
286298
// and the variant LayoutSs here until then.
287-
struct TmpLayout<FieldIdx: Idx> {
288-
layout: LayoutS<FieldIdx>,
289-
variants: IndexVec<VariantIdx, LayoutS<FieldIdx>>,
299+
struct TmpLayout<FieldIdx: Idx, VariantIdx: Idx> {
300+
layout: LayoutS<FieldIdx, VariantIdx>,
301+
variants: IndexVec<VariantIdx, LayoutS<FieldIdx, VariantIdx>>,
290302
}
291303

292-
let calculate_niche_filling_layout = || -> Option<TmpLayout<FieldIdx>> {
304+
let calculate_niche_filling_layout = || -> Option<TmpLayout<FieldIdx, VariantIdx>> {
293305
if dont_niche_optimize_enum {
294306
return None;
295307
}
@@ -327,7 +339,8 @@ pub trait LayoutCalculator {
327339
let niche_variants = all_indices.clone().find(|v| needs_disc(*v)).unwrap()
328340
..=all_indices.rev().find(|v| needs_disc(*v)).unwrap();
329341

330-
let count = niche_variants.size_hint().1.unwrap() as u128;
342+
let count =
343+
niche_variants.end().index() as u128 - niche_variants.start().index() as u128;
331344

332345
// Find the field with the largest niche
333346
let (field_index, niche, (niche_start, niche_scalar)) = variants[largest_variant_index]
@@ -660,7 +673,7 @@ pub trait LayoutCalculator {
660673
// Common prim might be uninit.
661674
Scalar::Union { value: prim }
662675
};
663-
let pair = self.scalar_pair(tag, prim_scalar);
676+
let pair = self.scalar_pair::<FieldIdx, VariantIdx>(tag, prim_scalar);
664677
let pair_offsets = match pair.fields {
665678
FieldsShape::Arbitrary { ref offsets, ref memory_index } => {
666679
assert_eq!(memory_index.raw, [0, 1]);
@@ -725,7 +738,7 @@ pub trait LayoutCalculator {
725738
// pick the layout with the larger niche; otherwise,
726739
// pick tagged as it has simpler codegen.
727740
use cmp::Ordering::*;
728-
let niche_size = |tmp_l: &TmpLayout<FieldIdx>| {
741+
let niche_size = |tmp_l: &TmpLayout<FieldIdx, VariantIdx>| {
729742
tmp_l.layout.largest_niche.map_or(0, |n| n.available(dl))
730743
};
731744
match (tl.layout.size.cmp(&nl.layout.size), niche_size(&tl).cmp(&niche_size(&nl))) {
@@ -747,11 +760,16 @@ pub trait LayoutCalculator {
747760
Some(best_layout.layout)
748761
}
749762

750-
fn layout_of_union<'a, FieldIdx: Idx, F: Deref<Target = &'a LayoutS<FieldIdx>> + fmt::Debug>(
763+
fn layout_of_union<
764+
'a,
765+
FieldIdx: Idx,
766+
VariantIdx: Idx,
767+
F: Deref<Target = &'a LayoutS<FieldIdx, VariantIdx>> + fmt::Debug,
768+
>(
751769
&self,
752770
repr: &ReprOptions,
753771
variants: &IndexSlice<VariantIdx, IndexVec<FieldIdx, F>>,
754-
) -> Option<LayoutS<FieldIdx>> {
772+
) -> Option<LayoutS<FieldIdx, VariantIdx>> {
755773
let dl = self.current_data_layout();
756774
let dl = dl.borrow();
757775
let mut align = if repr.pack.is_some() { dl.i8_align } else { dl.aggregate_align };
@@ -768,7 +786,7 @@ pub trait LayoutCalculator {
768786
};
769787

770788
let mut size = Size::ZERO;
771-
let only_variant = &variants[FIRST_VARIANT];
789+
let only_variant = &variants[VariantIdx::new(0)];
772790
for field in only_variant {
773791
if field.is_unsized() {
774792
self.delay_bug("unsized field in union".to_string());
@@ -835,7 +853,7 @@ pub trait LayoutCalculator {
835853
};
836854

837855
Some(LayoutS {
838-
variants: Variants::Single { index: FIRST_VARIANT },
856+
variants: Variants::Single { index: VariantIdx::new(0) },
839857
fields: FieldsShape::Union(NonZeroUsize::new(only_variant.len())?),
840858
abi,
841859
largest_niche: None,
@@ -853,14 +871,19 @@ enum NicheBias {
853871
End,
854872
}
855873

856-
fn univariant<'a, FieldIdx: Idx, F: Deref<Target = &'a LayoutS<FieldIdx>> + fmt::Debug>(
874+
fn univariant<
875+
'a,
876+
FieldIdx: Idx,
877+
VariantIdx: Idx,
878+
F: Deref<Target = &'a LayoutS<FieldIdx, VariantIdx>> + fmt::Debug,
879+
>(
857880
this: &(impl LayoutCalculator + ?Sized),
858881
dl: &TargetDataLayout,
859882
fields: &IndexSlice<FieldIdx, F>,
860883
repr: &ReprOptions,
861884
kind: StructKind,
862885
niche_bias: NicheBias,
863-
) -> Option<LayoutS<FieldIdx>> {
886+
) -> Option<LayoutS<FieldIdx, VariantIdx>> {
864887
let pack = repr.pack;
865888
let mut align = if pack.is_some() { dl.i8_align } else { dl.aggregate_align };
866889
let mut max_repr_align = repr.align;
@@ -1120,7 +1143,7 @@ fn univariant<'a, FieldIdx: Idx, F: Deref<Target = &'a LayoutS<FieldIdx>> + fmt:
11201143
} else {
11211144
((j, b), (i, a))
11221145
};
1123-
let pair = this.scalar_pair(a, b);
1146+
let pair = this.scalar_pair::<FieldIdx, VariantIdx>(a, b);
11241147
let pair_offsets = match pair.fields {
11251148
FieldsShape::Arbitrary { ref offsets, ref memory_index } => {
11261149
assert_eq!(memory_index.raw, [0, 1]);
@@ -1162,7 +1185,7 @@ fn univariant<'a, FieldIdx: Idx, F: Deref<Target = &'a LayoutS<FieldIdx>> + fmt:
11621185
};
11631186

11641187
Some(LayoutS {
1165-
variants: Variants::Single { index: FIRST_VARIANT },
1188+
variants: Variants::Single { index: VariantIdx::new(0) },
11661189
fields: FieldsShape::Arbitrary { offsets, memory_index },
11671190
abi,
11681191
largest_niche,
@@ -1173,8 +1196,13 @@ fn univariant<'a, FieldIdx: Idx, F: Deref<Target = &'a LayoutS<FieldIdx>> + fmt:
11731196
})
11741197
}
11751198

1176-
fn format_field_niches<'a, FieldIdx: Idx, F: Deref<Target = &'a LayoutS<FieldIdx>> + fmt::Debug>(
1177-
layout: &LayoutS<FieldIdx>,
1199+
fn format_field_niches<
1200+
'a,
1201+
FieldIdx: Idx,
1202+
VariantIdx: Idx,
1203+
F: Deref<Target = &'a LayoutS<FieldIdx, VariantIdx>> + fmt::Debug,
1204+
>(
1205+
layout: &LayoutS<FieldIdx, VariantIdx>,
11781206
fields: &IndexSlice<FieldIdx, F>,
11791207
dl: &TargetDataLayout,
11801208
) -> String {

compiler/rustc_abi/src/lib.rs

Lines changed: 11 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ use std::ops::{Add, AddAssign, Mul, RangeInclusive, Sub};
1111
use std::str::FromStr;
1212

1313
use bitflags::bitflags;
14-
use rustc_data_structures::intern::Interned;
1514
use rustc_data_structures::stable_hasher::Hash64;
1615
#[cfg(feature = "nightly")]
1716
use rustc_data_structures::stable_hasher::StableOrd;
@@ -1359,7 +1358,7 @@ impl Abi {
13591358

13601359
#[derive(PartialEq, Eq, Hash, Clone, Debug)]
13611360
#[cfg_attr(feature = "nightly", derive(HashStable_Generic))]
1362-
pub enum Variants<FieldIdx: Idx> {
1361+
pub enum Variants<FieldIdx: Idx, VariantIdx: Idx> {
13631362
/// Single enum variants, structs/tuples, unions, and all non-ADTs.
13641363
Single { index: VariantIdx },
13651364

@@ -1371,15 +1370,15 @@ pub enum Variants<FieldIdx: Idx> {
13711370
/// For enums, the tag is the sole field of the layout.
13721371
Multiple {
13731372
tag: Scalar,
1374-
tag_encoding: TagEncoding,
1373+
tag_encoding: TagEncoding<VariantIdx>,
13751374
tag_field: usize,
1376-
variants: IndexVec<VariantIdx, LayoutS<FieldIdx>>,
1375+
variants: IndexVec<VariantIdx, LayoutS<FieldIdx, VariantIdx>>,
13771376
},
13781377
}
13791378

13801379
#[derive(PartialEq, Eq, Hash, Clone, Debug)]
13811380
#[cfg_attr(feature = "nightly", derive(HashStable_Generic))]
1382-
pub enum TagEncoding {
1381+
pub enum TagEncoding<VariantIdx: Idx> {
13831382
/// The tag directly stores the discriminant, but possibly with a smaller layout
13841383
/// (so converting the tag to the discriminant can require sign extension).
13851384
Direct,
@@ -1485,27 +1484,9 @@ impl Niche {
14851484
}
14861485
}
14871486

1488-
rustc_index::newtype_index! {
1489-
/// The *source-order* index of a variant in a type.
1490-
///
1491-
/// For enums, these are always `0..variant_count`, regardless of any
1492-
/// custom discriminants that may have been defined, and including any
1493-
/// variants that may end up uninhabited due to field types. (Some of the
1494-
/// variants may not be present in a monomorphized ABI [`Variants`], but
1495-
/// those skipped variants are always counted when determining the *index*.)
1496-
///
1497-
/// `struct`s, `tuples`, and `unions`s are considered to have a single variant
1498-
/// with variant index zero, aka [`FIRST_VARIANT`].
1499-
#[derive(HashStable_Generic)]
1500-
pub struct VariantIdx {
1501-
/// Equivalent to `VariantIdx(0)`.
1502-
const FIRST_VARIANT = 0;
1503-
}
1504-
}
1505-
15061487
#[derive(PartialEq, Eq, Hash, Clone)]
15071488
#[cfg_attr(feature = "nightly", derive(HashStable_Generic))]
1508-
pub struct LayoutS<FieldIdx: Idx> {
1489+
pub struct LayoutS<FieldIdx: Idx, VariantIdx: Idx> {
15091490
/// Says where the fields are located within the layout.
15101491
pub fields: FieldsShape<FieldIdx>,
15111492

@@ -1516,7 +1497,7 @@ pub struct LayoutS<FieldIdx: Idx> {
15161497
///
15171498
/// To access all fields of this layout, both `fields` and the fields of the active variant
15181499
/// must be taken into account.
1519-
pub variants: Variants<FieldIdx>,
1500+
pub variants: Variants<FieldIdx, VariantIdx>,
15201501

15211502
/// The `abi` defines how this data is passed between functions, and it defines
15221503
/// value restrictions via `valid_range`.
@@ -1545,13 +1526,13 @@ pub struct LayoutS<FieldIdx: Idx> {
15451526
pub unadjusted_abi_align: Align,
15461527
}
15471528

1548-
impl<FieldIdx: Idx> LayoutS<FieldIdx> {
1529+
impl<FieldIdx: Idx, VariantIdx: Idx> LayoutS<FieldIdx, VariantIdx> {
15491530
pub fn scalar<C: HasDataLayout>(cx: &C, scalar: Scalar) -> Self {
15501531
let largest_niche = Niche::from_scalar(cx, Size::ZERO, scalar);
15511532
let size = scalar.size(cx);
15521533
let align = scalar.align(cx);
15531534
LayoutS {
1554-
variants: Variants::Single { index: FIRST_VARIANT },
1535+
variants: Variants::Single { index: VariantIdx::new(0) },
15551536
fields: FieldsShape::Primitive,
15561537
abi: Abi::Scalar(scalar),
15571538
largest_niche,
@@ -1563,10 +1544,10 @@ impl<FieldIdx: Idx> LayoutS<FieldIdx> {
15631544
}
15641545
}
15651546

1566-
impl<FieldIdx: Idx> fmt::Debug for LayoutS<FieldIdx>
1547+
impl<FieldIdx: Idx, VariantIdx: Idx> fmt::Debug for LayoutS<FieldIdx, VariantIdx>
15671548
where
15681549
FieldsShape<FieldIdx>: fmt::Debug,
1569-
Variants<FieldIdx>: fmt::Debug,
1550+
Variants<FieldIdx, VariantIdx>: fmt::Debug,
15701551
{
15711552
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
15721553
// This is how `Layout` used to print before it become
@@ -1614,7 +1595,7 @@ pub struct PointeeInfo {
16141595
pub safe: Option<PointerKind>,
16151596
}
16161597

1617-
impl<FieldIdx: Idx> LayoutS<FieldIdx> {
1598+
impl<FieldIdx: Idx, VariantIdx: Idx> LayoutS<FieldIdx, VariantIdx> {
16181599
/// Returns `true` if the layout corresponds to an unsized type.
16191600
#[inline]
16201601
pub fn is_unsized(&self) -> bool {

compiler/rustc_target/src/abi/mod.rs

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -45,9 +45,26 @@ rustc_index::newtype_index! {
4545
pub struct FieldIdx {}
4646
}
4747

48+
rustc_index::newtype_index! {
49+
/// The *source-order* index of a variant in a type.
50+
///
51+
/// For enums, these are always `0..variant_count`, regardless of any
52+
/// custom discriminants that may have been defined, and including any
53+
/// variants that may end up uninhabited due to field types. (Some of the
54+
/// variants may not be present in a monomorphized ABI [`Variants`], but
55+
/// those skipped variants are always counted when determining the *index*.)
56+
///
57+
/// `struct`s, `tuples`, and `unions`s are considered to have a single variant
58+
/// with variant index zero, aka [`FIRST_VARIANT`].
59+
#[derive(HashStable_Generic)]
60+
pub struct VariantIdx {
61+
/// Equivalent to `VariantIdx(0)`.
62+
const FIRST_VARIANT = 0;
63+
}
64+
}
4865
#[derive(Copy, Clone, PartialEq, Eq, Hash, HashStable_Generic)]
4966
#[rustc_pass_by_value]
50-
pub struct Layout<'a>(pub Interned<'a, LayoutS<FieldIdx>>);
67+
pub struct Layout<'a>(pub Interned<'a, LayoutS<FieldIdx, VariantIdx>>);
5168

5269
impl<'a> fmt::Debug for Layout<'a> {
5370
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
@@ -61,7 +78,7 @@ impl<'a> Layout<'a> {
6178
&self.0.0.fields
6279
}
6380

64-
pub fn variants(self) -> &'a Variants<FieldIdx> {
81+
pub fn variants(self) -> &'a Variants<FieldIdx, VariantIdx> {
6582
&self.0.0.variants
6683
}
6784

@@ -124,8 +141,8 @@ impl<'a, Ty: fmt::Display> fmt::Debug for TyAndLayout<'a, Ty> {
124141
}
125142

126143
impl<'a, Ty> Deref for TyAndLayout<'a, Ty> {
127-
type Target = &'a LayoutS<FieldIdx>;
128-
fn deref(&self) -> &&'a LayoutS<FieldIdx> {
144+
type Target = &'a LayoutS<FieldIdx, VariantIdx>;
145+
fn deref(&self) -> &&'a LayoutS<FieldIdx, VariantIdx> {
129146
&self.layout.0.0
130147
}
131148
}

0 commit comments

Comments
 (0)