Add VariantIdx back
This commit is contained in:
parent
f14b7c9443
commit
e8a2673159
3 changed files with 87 additions and 61 deletions
|
@ -8,7 +8,7 @@ use tracing::debug;
|
||||||
use crate::{
|
use crate::{
|
||||||
Abi, AbiAndPrefAlign, Align, FieldsShape, IndexSlice, IndexVec, Integer, LayoutS, Niche,
|
Abi, AbiAndPrefAlign, Align, FieldsShape, IndexSlice, IndexVec, Integer, LayoutS, Niche,
|
||||||
NonZeroUsize, Primitive, ReprOptions, Scalar, Size, StructKind, TagEncoding, TargetDataLayout,
|
NonZeroUsize, Primitive, ReprOptions, Scalar, Size, StructKind, TagEncoding, TargetDataLayout,
|
||||||
VariantIdx, Variants, WrappingRange, FIRST_VARIANT,
|
Variants, WrappingRange,
|
||||||
};
|
};
|
||||||
pub trait LayoutCalculator {
|
pub trait LayoutCalculator {
|
||||||
type TargetDataLayoutRef: Borrow<TargetDataLayout>;
|
type TargetDataLayoutRef: Borrow<TargetDataLayout>;
|
||||||
|
@ -16,7 +16,11 @@ pub trait LayoutCalculator {
|
||||||
fn delay_bug(&self, txt: String);
|
fn delay_bug(&self, txt: String);
|
||||||
fn current_data_layout(&self) -> Self::TargetDataLayoutRef;
|
fn current_data_layout(&self) -> Self::TargetDataLayoutRef;
|
||||||
|
|
||||||
fn scalar_pair<FieldIdx: Idx>(&self, a: Scalar, b: Scalar) -> LayoutS<FieldIdx> {
|
fn scalar_pair<FieldIdx: Idx, VariantIdx: Idx>(
|
||||||
|
&self,
|
||||||
|
a: Scalar,
|
||||||
|
b: Scalar,
|
||||||
|
) -> LayoutS<FieldIdx, VariantIdx> {
|
||||||
let dl = self.current_data_layout();
|
let dl = self.current_data_layout();
|
||||||
let dl = dl.borrow();
|
let dl = dl.borrow();
|
||||||
let b_align = b.align(dl);
|
let b_align = b.align(dl);
|
||||||
|
@ -32,7 +36,7 @@ pub trait LayoutCalculator {
|
||||||
.max_by_key(|niche| niche.available(dl));
|
.max_by_key(|niche| niche.available(dl));
|
||||||
|
|
||||||
LayoutS {
|
LayoutS {
|
||||||
variants: Variants::Single { index: FIRST_VARIANT },
|
variants: Variants::Single { index: VariantIdx::new(0) },
|
||||||
fields: FieldsShape::Arbitrary {
|
fields: FieldsShape::Arbitrary {
|
||||||
offsets: [Size::ZERO, b_offset].into(),
|
offsets: [Size::ZERO, b_offset].into(),
|
||||||
memory_index: [0, 1].into(),
|
memory_index: [0, 1].into(),
|
||||||
|
@ -46,13 +50,18 @@ pub trait LayoutCalculator {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn univariant<'a, FieldIdx: Idx, F: Deref<Target = &'a LayoutS<FieldIdx>> + fmt::Debug>(
|
fn univariant<
|
||||||
|
'a,
|
||||||
|
FieldIdx: Idx,
|
||||||
|
VariantIdx: Idx,
|
||||||
|
F: Deref<Target = &'a LayoutS<FieldIdx, VariantIdx>> + fmt::Debug,
|
||||||
|
>(
|
||||||
&self,
|
&self,
|
||||||
dl: &TargetDataLayout,
|
dl: &TargetDataLayout,
|
||||||
fields: &IndexSlice<FieldIdx, F>,
|
fields: &IndexSlice<FieldIdx, F>,
|
||||||
repr: &ReprOptions,
|
repr: &ReprOptions,
|
||||||
kind: StructKind,
|
kind: StructKind,
|
||||||
) -> Option<LayoutS<FieldIdx>> {
|
) -> Option<LayoutS<FieldIdx, VariantIdx>> {
|
||||||
let layout = univariant(self, dl, fields, repr, kind, NicheBias::Start);
|
let layout = univariant(self, dl, fields, repr, kind, NicheBias::Start);
|
||||||
// Enums prefer niches close to the beginning or the end of the variants so that other
|
// Enums prefer niches close to the beginning or the end of the variants so that other
|
||||||
// (smaller) data-carrying variants can be packed into the space after/before the niche.
|
// (smaller) data-carrying variants can be packed into the space after/before the niche.
|
||||||
|
@ -115,11 +124,13 @@ pub trait LayoutCalculator {
|
||||||
layout
|
layout
|
||||||
}
|
}
|
||||||
|
|
||||||
fn layout_of_never_type<FieldIdx: Idx>(&self) -> LayoutS<FieldIdx> {
|
fn layout_of_never_type<FieldIdx: Idx, VariantIdx: Idx>(
|
||||||
|
&self,
|
||||||
|
) -> LayoutS<FieldIdx, VariantIdx> {
|
||||||
let dl = self.current_data_layout();
|
let dl = self.current_data_layout();
|
||||||
let dl = dl.borrow();
|
let dl = dl.borrow();
|
||||||
LayoutS {
|
LayoutS {
|
||||||
variants: Variants::Single { index: FIRST_VARIANT },
|
variants: Variants::Single { index: VariantIdx::new(0) },
|
||||||
fields: FieldsShape::Primitive,
|
fields: FieldsShape::Primitive,
|
||||||
abi: Abi::Uninhabited,
|
abi: Abi::Uninhabited,
|
||||||
largest_niche: None,
|
largest_niche: None,
|
||||||
|
@ -133,7 +144,8 @@ pub trait LayoutCalculator {
|
||||||
fn layout_of_struct_or_enum<
|
fn layout_of_struct_or_enum<
|
||||||
'a,
|
'a,
|
||||||
FieldIdx: Idx,
|
FieldIdx: Idx,
|
||||||
F: Deref<Target = &'a LayoutS<FieldIdx>> + fmt::Debug,
|
VariantIdx: Idx,
|
||||||
|
F: Deref<Target = &'a LayoutS<FieldIdx, VariantIdx>> + fmt::Debug,
|
||||||
>(
|
>(
|
||||||
&self,
|
&self,
|
||||||
repr: &ReprOptions,
|
repr: &ReprOptions,
|
||||||
|
@ -145,7 +157,7 @@ pub trait LayoutCalculator {
|
||||||
discriminants: impl Iterator<Item = (VariantIdx, i128)>,
|
discriminants: impl Iterator<Item = (VariantIdx, i128)>,
|
||||||
dont_niche_optimize_enum: bool,
|
dont_niche_optimize_enum: bool,
|
||||||
always_sized: bool,
|
always_sized: bool,
|
||||||
) -> Option<LayoutS<FieldIdx>> {
|
) -> Option<LayoutS<FieldIdx, VariantIdx>> {
|
||||||
let dl = self.current_data_layout();
|
let dl = self.current_data_layout();
|
||||||
let dl = dl.borrow();
|
let dl = dl.borrow();
|
||||||
|
|
||||||
|
@ -181,7 +193,7 @@ pub trait LayoutCalculator {
|
||||||
}
|
}
|
||||||
// If it's a struct, still compute a layout so that we can still compute the
|
// If it's a struct, still compute a layout so that we can still compute the
|
||||||
// field offsets.
|
// field offsets.
|
||||||
None => FIRST_VARIANT,
|
None => VariantIdx::new(0),
|
||||||
};
|
};
|
||||||
|
|
||||||
let is_struct = !is_enum ||
|
let is_struct = !is_enum ||
|
||||||
|
@ -284,12 +296,12 @@ pub trait LayoutCalculator {
|
||||||
// variant layouts, so we can't store them in the
|
// variant layouts, so we can't store them in the
|
||||||
// overall LayoutS. Store the overall LayoutS
|
// overall LayoutS. Store the overall LayoutS
|
||||||
// and the variant LayoutSs here until then.
|
// and the variant LayoutSs here until then.
|
||||||
struct TmpLayout<FieldIdx: Idx> {
|
struct TmpLayout<FieldIdx: Idx, VariantIdx: Idx> {
|
||||||
layout: LayoutS<FieldIdx>,
|
layout: LayoutS<FieldIdx, VariantIdx>,
|
||||||
variants: IndexVec<VariantIdx, LayoutS<FieldIdx>>,
|
variants: IndexVec<VariantIdx, LayoutS<FieldIdx, VariantIdx>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
let calculate_niche_filling_layout = || -> Option<TmpLayout<FieldIdx>> {
|
let calculate_niche_filling_layout = || -> Option<TmpLayout<FieldIdx, VariantIdx>> {
|
||||||
if dont_niche_optimize_enum {
|
if dont_niche_optimize_enum {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
@ -327,7 +339,8 @@ pub trait LayoutCalculator {
|
||||||
let niche_variants = all_indices.clone().find(|v| needs_disc(*v)).unwrap()
|
let niche_variants = all_indices.clone().find(|v| needs_disc(*v)).unwrap()
|
||||||
..=all_indices.rev().find(|v| needs_disc(*v)).unwrap();
|
..=all_indices.rev().find(|v| needs_disc(*v)).unwrap();
|
||||||
|
|
||||||
let count = niche_variants.size_hint().1.unwrap() as u128;
|
let count =
|
||||||
|
niche_variants.end().index() as u128 - niche_variants.start().index() as u128;
|
||||||
|
|
||||||
// Find the field with the largest niche
|
// Find the field with the largest niche
|
||||||
let (field_index, niche, (niche_start, niche_scalar)) = variants[largest_variant_index]
|
let (field_index, niche, (niche_start, niche_scalar)) = variants[largest_variant_index]
|
||||||
|
@ -660,7 +673,7 @@ pub trait LayoutCalculator {
|
||||||
// Common prim might be uninit.
|
// Common prim might be uninit.
|
||||||
Scalar::Union { value: prim }
|
Scalar::Union { value: prim }
|
||||||
};
|
};
|
||||||
let pair = self.scalar_pair(tag, prim_scalar);
|
let pair = self.scalar_pair::<FieldIdx, VariantIdx>(tag, prim_scalar);
|
||||||
let pair_offsets = match pair.fields {
|
let pair_offsets = match pair.fields {
|
||||||
FieldsShape::Arbitrary { ref offsets, ref memory_index } => {
|
FieldsShape::Arbitrary { ref offsets, ref memory_index } => {
|
||||||
assert_eq!(memory_index.raw, [0, 1]);
|
assert_eq!(memory_index.raw, [0, 1]);
|
||||||
|
@ -726,7 +739,7 @@ pub trait LayoutCalculator {
|
||||||
// pick the layout with the larger niche; otherwise,
|
// pick the layout with the larger niche; otherwise,
|
||||||
// pick tagged as it has simpler codegen.
|
// pick tagged as it has simpler codegen.
|
||||||
use cmp::Ordering::*;
|
use cmp::Ordering::*;
|
||||||
let niche_size = |tmp_l: &TmpLayout<FieldIdx>| {
|
let niche_size = |tmp_l: &TmpLayout<FieldIdx, VariantIdx>| {
|
||||||
tmp_l.layout.largest_niche.map_or(0, |n| n.available(dl))
|
tmp_l.layout.largest_niche.map_or(0, |n| n.available(dl))
|
||||||
};
|
};
|
||||||
match (tl.layout.size.cmp(&nl.layout.size), niche_size(&tl).cmp(&niche_size(&nl))) {
|
match (tl.layout.size.cmp(&nl.layout.size), niche_size(&tl).cmp(&niche_size(&nl))) {
|
||||||
|
@ -748,11 +761,16 @@ pub trait LayoutCalculator {
|
||||||
Some(best_layout.layout)
|
Some(best_layout.layout)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn layout_of_union<'a, FieldIdx: Idx, F: Deref<Target = &'a LayoutS<FieldIdx>> + fmt::Debug>(
|
fn layout_of_union<
|
||||||
|
'a,
|
||||||
|
FieldIdx: Idx,
|
||||||
|
VariantIdx: Idx,
|
||||||
|
F: Deref<Target = &'a LayoutS<FieldIdx, VariantIdx>> + fmt::Debug,
|
||||||
|
>(
|
||||||
&self,
|
&self,
|
||||||
repr: &ReprOptions,
|
repr: &ReprOptions,
|
||||||
variants: &IndexSlice<VariantIdx, IndexVec<FieldIdx, F>>,
|
variants: &IndexSlice<VariantIdx, IndexVec<FieldIdx, F>>,
|
||||||
) -> Option<LayoutS<FieldIdx>> {
|
) -> Option<LayoutS<FieldIdx, VariantIdx>> {
|
||||||
let dl = self.current_data_layout();
|
let dl = self.current_data_layout();
|
||||||
let dl = dl.borrow();
|
let dl = dl.borrow();
|
||||||
let mut align = if repr.pack.is_some() { dl.i8_align } else { dl.aggregate_align };
|
let mut align = if repr.pack.is_some() { dl.i8_align } else { dl.aggregate_align };
|
||||||
|
@ -769,7 +787,7 @@ pub trait LayoutCalculator {
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut size = Size::ZERO;
|
let mut size = Size::ZERO;
|
||||||
let only_variant = &variants[FIRST_VARIANT];
|
let only_variant = &variants[VariantIdx::new(0)];
|
||||||
for field in only_variant {
|
for field in only_variant {
|
||||||
if field.is_unsized() {
|
if field.is_unsized() {
|
||||||
self.delay_bug("unsized field in union".to_string());
|
self.delay_bug("unsized field in union".to_string());
|
||||||
|
@ -836,7 +854,7 @@ pub trait LayoutCalculator {
|
||||||
};
|
};
|
||||||
|
|
||||||
Some(LayoutS {
|
Some(LayoutS {
|
||||||
variants: Variants::Single { index: FIRST_VARIANT },
|
variants: Variants::Single { index: VariantIdx::new(0) },
|
||||||
fields: FieldsShape::Union(NonZeroUsize::new(only_variant.len())?),
|
fields: FieldsShape::Union(NonZeroUsize::new(only_variant.len())?),
|
||||||
abi,
|
abi,
|
||||||
largest_niche: None,
|
largest_niche: None,
|
||||||
|
@ -854,14 +872,19 @@ enum NicheBias {
|
||||||
End,
|
End,
|
||||||
}
|
}
|
||||||
|
|
||||||
fn univariant<'a, FieldIdx: Idx, F: Deref<Target = &'a LayoutS<FieldIdx>> + fmt::Debug>(
|
fn univariant<
|
||||||
|
'a,
|
||||||
|
FieldIdx: Idx,
|
||||||
|
VariantIdx: Idx,
|
||||||
|
F: Deref<Target = &'a LayoutS<FieldIdx, VariantIdx>> + fmt::Debug,
|
||||||
|
>(
|
||||||
this: &(impl LayoutCalculator + ?Sized),
|
this: &(impl LayoutCalculator + ?Sized),
|
||||||
dl: &TargetDataLayout,
|
dl: &TargetDataLayout,
|
||||||
fields: &IndexSlice<FieldIdx, F>,
|
fields: &IndexSlice<FieldIdx, F>,
|
||||||
repr: &ReprOptions,
|
repr: &ReprOptions,
|
||||||
kind: StructKind,
|
kind: StructKind,
|
||||||
niche_bias: NicheBias,
|
niche_bias: NicheBias,
|
||||||
) -> Option<LayoutS<FieldIdx>> {
|
) -> Option<LayoutS<FieldIdx, VariantIdx>> {
|
||||||
let pack = repr.pack;
|
let pack = repr.pack;
|
||||||
let mut align = if pack.is_some() { dl.i8_align } else { dl.aggregate_align };
|
let mut align = if pack.is_some() { dl.i8_align } else { dl.aggregate_align };
|
||||||
let mut max_repr_align = repr.align;
|
let mut max_repr_align = repr.align;
|
||||||
|
@ -1120,7 +1143,7 @@ fn univariant<'a, FieldIdx: Idx, F: Deref<Target = &'a LayoutS<FieldIdx>> + fmt:
|
||||||
} else {
|
} else {
|
||||||
((j, b), (i, a))
|
((j, b), (i, a))
|
||||||
};
|
};
|
||||||
let pair = this.scalar_pair(a, b);
|
let pair = this.scalar_pair::<FieldIdx, VariantIdx>(a, b);
|
||||||
let pair_offsets = match pair.fields {
|
let pair_offsets = match pair.fields {
|
||||||
FieldsShape::Arbitrary { ref offsets, ref memory_index } => {
|
FieldsShape::Arbitrary { ref offsets, ref memory_index } => {
|
||||||
assert_eq!(memory_index.raw, [0, 1]);
|
assert_eq!(memory_index.raw, [0, 1]);
|
||||||
|
@ -1162,7 +1185,7 @@ fn univariant<'a, FieldIdx: Idx, F: Deref<Target = &'a LayoutS<FieldIdx>> + fmt:
|
||||||
};
|
};
|
||||||
|
|
||||||
Some(LayoutS {
|
Some(LayoutS {
|
||||||
variants: Variants::Single { index: FIRST_VARIANT },
|
variants: Variants::Single { index: VariantIdx::new(0) },
|
||||||
fields: FieldsShape::Arbitrary { offsets, memory_index },
|
fields: FieldsShape::Arbitrary { offsets, memory_index },
|
||||||
abi,
|
abi,
|
||||||
largest_niche,
|
largest_niche,
|
||||||
|
@ -1173,8 +1196,13 @@ fn univariant<'a, FieldIdx: Idx, F: Deref<Target = &'a LayoutS<FieldIdx>> + fmt:
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn format_field_niches<'a, FieldIdx: Idx, F: Deref<Target = &'a LayoutS<FieldIdx>> + fmt::Debug>(
|
fn format_field_niches<
|
||||||
layout: &LayoutS<FieldIdx>,
|
'a,
|
||||||
|
FieldIdx: Idx,
|
||||||
|
VariantIdx: Idx,
|
||||||
|
F: Deref<Target = &'a LayoutS<FieldIdx, VariantIdx>> + fmt::Debug,
|
||||||
|
>(
|
||||||
|
layout: &LayoutS<FieldIdx, VariantIdx>,
|
||||||
fields: &IndexSlice<FieldIdx, F>,
|
fields: &IndexSlice<FieldIdx, F>,
|
||||||
dl: &TargetDataLayout,
|
dl: &TargetDataLayout,
|
||||||
) -> String {
|
) -> String {
|
||||||
|
|
|
@ -11,7 +11,6 @@ use std::ops::{Add, AddAssign, Mul, RangeInclusive, Sub};
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
|
|
||||||
use bitflags::bitflags;
|
use bitflags::bitflags;
|
||||||
use rustc_data_structures::intern::Interned;
|
|
||||||
use rustc_data_structures::stable_hasher::Hash64;
|
use rustc_data_structures::stable_hasher::Hash64;
|
||||||
#[cfg(feature = "nightly")]
|
#[cfg(feature = "nightly")]
|
||||||
use rustc_data_structures::stable_hasher::StableOrd;
|
use rustc_data_structures::stable_hasher::StableOrd;
|
||||||
|
@ -1360,7 +1359,7 @@ impl Abi {
|
||||||
|
|
||||||
#[derive(PartialEq, Eq, Hash, Clone, Debug)]
|
#[derive(PartialEq, Eq, Hash, Clone, Debug)]
|
||||||
#[cfg_attr(feature = "nightly", derive(HashStable_Generic))]
|
#[cfg_attr(feature = "nightly", derive(HashStable_Generic))]
|
||||||
pub enum Variants<FieldIdx: Idx> {
|
pub enum Variants<FieldIdx: Idx, VariantIdx: Idx> {
|
||||||
/// Single enum variants, structs/tuples, unions, and all non-ADTs.
|
/// Single enum variants, structs/tuples, unions, and all non-ADTs.
|
||||||
Single { index: VariantIdx },
|
Single { index: VariantIdx },
|
||||||
|
|
||||||
|
@ -1372,15 +1371,15 @@ pub enum Variants<FieldIdx: Idx> {
|
||||||
/// For enums, the tag is the sole field of the layout.
|
/// For enums, the tag is the sole field of the layout.
|
||||||
Multiple {
|
Multiple {
|
||||||
tag: Scalar,
|
tag: Scalar,
|
||||||
tag_encoding: TagEncoding,
|
tag_encoding: TagEncoding<VariantIdx>,
|
||||||
tag_field: usize,
|
tag_field: usize,
|
||||||
variants: IndexVec<VariantIdx, LayoutS<FieldIdx>>,
|
variants: IndexVec<VariantIdx, LayoutS<FieldIdx, VariantIdx>>,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(PartialEq, Eq, Hash, Clone, Debug)]
|
#[derive(PartialEq, Eq, Hash, Clone, Debug)]
|
||||||
#[cfg_attr(feature = "nightly", derive(HashStable_Generic))]
|
#[cfg_attr(feature = "nightly", derive(HashStable_Generic))]
|
||||||
pub enum TagEncoding {
|
pub enum TagEncoding<VariantIdx: Idx> {
|
||||||
/// The tag directly stores the discriminant, but possibly with a smaller layout
|
/// The tag directly stores the discriminant, but possibly with a smaller layout
|
||||||
/// (so converting the tag to the discriminant can require sign extension).
|
/// (so converting the tag to the discriminant can require sign extension).
|
||||||
Direct,
|
Direct,
|
||||||
|
@ -1488,27 +1487,9 @@ impl Niche {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
rustc_index::newtype_index! {
|
|
||||||
/// The *source-order* index of a variant in a type.
|
|
||||||
///
|
|
||||||
/// For enums, these are always `0..variant_count`, regardless of any
|
|
||||||
/// custom discriminants that may have been defined, and including any
|
|
||||||
/// variants that may end up uninhabited due to field types. (Some of the
|
|
||||||
/// variants may not be present in a monomorphized ABI [`Variants`], but
|
|
||||||
/// those skipped variants are always counted when determining the *index*.)
|
|
||||||
///
|
|
||||||
/// `struct`s, `tuples`, and `unions`s are considered to have a single variant
|
|
||||||
/// with variant index zero, aka [`FIRST_VARIANT`].
|
|
||||||
#[derive(HashStable_Generic)]
|
|
||||||
pub struct VariantIdx {
|
|
||||||
/// Equivalent to `VariantIdx(0)`.
|
|
||||||
const FIRST_VARIANT = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(PartialEq, Eq, Hash, Clone)]
|
#[derive(PartialEq, Eq, Hash, Clone)]
|
||||||
#[cfg_attr(feature = "nightly", derive(HashStable_Generic))]
|
#[cfg_attr(feature = "nightly", derive(HashStable_Generic))]
|
||||||
pub struct LayoutS<FieldIdx: Idx> {
|
pub struct LayoutS<FieldIdx: Idx, VariantIdx: Idx> {
|
||||||
/// Says where the fields are located within the layout.
|
/// Says where the fields are located within the layout.
|
||||||
pub fields: FieldsShape<FieldIdx>,
|
pub fields: FieldsShape<FieldIdx>,
|
||||||
|
|
||||||
|
@ -1519,7 +1500,7 @@ pub struct LayoutS<FieldIdx: Idx> {
|
||||||
///
|
///
|
||||||
/// To access all fields of this layout, both `fields` and the fields of the active variant
|
/// To access all fields of this layout, both `fields` and the fields of the active variant
|
||||||
/// must be taken into account.
|
/// must be taken into account.
|
||||||
pub variants: Variants<FieldIdx>,
|
pub variants: Variants<FieldIdx, VariantIdx>,
|
||||||
|
|
||||||
/// The `abi` defines how this data is passed between functions, and it defines
|
/// The `abi` defines how this data is passed between functions, and it defines
|
||||||
/// value restrictions via `valid_range`.
|
/// value restrictions via `valid_range`.
|
||||||
|
@ -1548,13 +1529,13 @@ pub struct LayoutS<FieldIdx: Idx> {
|
||||||
pub unadjusted_abi_align: Align,
|
pub unadjusted_abi_align: Align,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<FieldIdx: Idx> LayoutS<FieldIdx> {
|
impl<FieldIdx: Idx, VariantIdx: Idx> LayoutS<FieldIdx, VariantIdx> {
|
||||||
pub fn scalar<C: HasDataLayout>(cx: &C, scalar: Scalar) -> Self {
|
pub fn scalar<C: HasDataLayout>(cx: &C, scalar: Scalar) -> Self {
|
||||||
let largest_niche = Niche::from_scalar(cx, Size::ZERO, scalar);
|
let largest_niche = Niche::from_scalar(cx, Size::ZERO, scalar);
|
||||||
let size = scalar.size(cx);
|
let size = scalar.size(cx);
|
||||||
let align = scalar.align(cx);
|
let align = scalar.align(cx);
|
||||||
LayoutS {
|
LayoutS {
|
||||||
variants: Variants::Single { index: FIRST_VARIANT },
|
variants: Variants::Single { index: VariantIdx::new(0) },
|
||||||
fields: FieldsShape::Primitive,
|
fields: FieldsShape::Primitive,
|
||||||
abi: Abi::Scalar(scalar),
|
abi: Abi::Scalar(scalar),
|
||||||
largest_niche,
|
largest_niche,
|
||||||
|
@ -1566,10 +1547,10 @@ impl<FieldIdx: Idx> LayoutS<FieldIdx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<FieldIdx: Idx> fmt::Debug for LayoutS<FieldIdx>
|
impl<FieldIdx: Idx, VariantIdx: Idx> fmt::Debug for LayoutS<FieldIdx, VariantIdx>
|
||||||
where
|
where
|
||||||
FieldsShape<FieldIdx>: fmt::Debug,
|
FieldsShape<FieldIdx>: fmt::Debug,
|
||||||
Variants<FieldIdx>: fmt::Debug,
|
Variants<FieldIdx, VariantIdx>: fmt::Debug,
|
||||||
{
|
{
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
// This is how `Layout` used to print before it become
|
// This is how `Layout` used to print before it become
|
||||||
|
@ -1617,7 +1598,7 @@ pub struct PointeeInfo {
|
||||||
pub safe: Option<PointerKind>,
|
pub safe: Option<PointerKind>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<FieldIdx: Idx> LayoutS<FieldIdx> {
|
impl<FieldIdx: Idx, VariantIdx: Idx> LayoutS<FieldIdx, VariantIdx> {
|
||||||
/// Returns `true` if the layout corresponds to an unsized type.
|
/// Returns `true` if the layout corresponds to an unsized type.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn is_unsized(&self) -> bool {
|
pub fn is_unsized(&self) -> bool {
|
||||||
|
|
|
@ -45,9 +45,26 @@ rustc_index::newtype_index! {
|
||||||
pub struct FieldIdx {}
|
pub struct FieldIdx {}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
rustc_index::newtype_index! {
|
||||||
|
/// The *source-order* index of a variant in a type.
|
||||||
|
///
|
||||||
|
/// For enums, these are always `0..variant_count`, regardless of any
|
||||||
|
/// custom discriminants that may have been defined, and including any
|
||||||
|
/// variants that may end up uninhabited due to field types. (Some of the
|
||||||
|
/// variants may not be present in a monomorphized ABI [`Variants`], but
|
||||||
|
/// those skipped variants are always counted when determining the *index*.)
|
||||||
|
///
|
||||||
|
/// `struct`s, `tuples`, and `unions`s are considered to have a single variant
|
||||||
|
/// with variant index zero, aka [`FIRST_VARIANT`].
|
||||||
|
#[derive(HashStable_Generic)]
|
||||||
|
pub struct VariantIdx {
|
||||||
|
/// Equivalent to `VariantIdx(0)`.
|
||||||
|
const FIRST_VARIANT = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
#[derive(Copy, Clone, PartialEq, Eq, Hash, HashStable_Generic)]
|
#[derive(Copy, Clone, PartialEq, Eq, Hash, HashStable_Generic)]
|
||||||
#[rustc_pass_by_value]
|
#[rustc_pass_by_value]
|
||||||
pub struct Layout<'a>(pub Interned<'a, LayoutS<FieldIdx>>);
|
pub struct Layout<'a>(pub Interned<'a, LayoutS<FieldIdx, VariantIdx>>);
|
||||||
|
|
||||||
impl<'a> fmt::Debug for Layout<'a> {
|
impl<'a> fmt::Debug for Layout<'a> {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
|
@ -61,7 +78,7 @@ impl<'a> Layout<'a> {
|
||||||
&self.0.0.fields
|
&self.0.0.fields
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn variants(self) -> &'a Variants<FieldIdx> {
|
pub fn variants(self) -> &'a Variants<FieldIdx, VariantIdx> {
|
||||||
&self.0.0.variants
|
&self.0.0.variants
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -124,8 +141,8 @@ impl<'a, Ty: fmt::Display> fmt::Debug for TyAndLayout<'a, Ty> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, Ty> Deref for TyAndLayout<'a, Ty> {
|
impl<'a, Ty> Deref for TyAndLayout<'a, Ty> {
|
||||||
type Target = &'a LayoutS<FieldIdx>;
|
type Target = &'a LayoutS<FieldIdx, VariantIdx>;
|
||||||
fn deref(&self) -> &&'a LayoutS<FieldIdx> {
|
fn deref(&self) -> &&'a LayoutS<FieldIdx, VariantIdx> {
|
||||||
&self.layout.0.0
|
&self.layout.0.0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue