diff options
| -rw-r--r-- | compiler/rustc_abi/src/layout.rs | 173 | ||||
| -rw-r--r-- | compiler/rustc_abi/src/lib.rs | 40 | ||||
| -rw-r--r-- | compiler/rustc_target/src/abi/mod.rs | 4 |
3 files changed, 113 insertions, 104 deletions
diff --git a/compiler/rustc_abi/src/layout.rs b/compiler/rustc_abi/src/layout.rs index cea52c52785..3e2e4ce4edc 100644 --- a/compiler/rustc_abi/src/layout.rs +++ b/compiler/rustc_abi/src/layout.rs @@ -1,12 +1,14 @@ -use std::fmt::Write; +use std::fmt::{self, Write}; +use std::ops::Deref; use std::{borrow::Borrow, cmp, iter, ops::Bound}; +use rustc_index::Idx; use tracing::debug; use crate::{ - Abi, AbiAndPrefAlign, Align, FieldIdx, FieldsShape, IndexSlice, IndexVec, Integer, Layout, - LayoutS, Niche, NonZeroUsize, Primitive, ReprOptions, Scalar, Size, StructKind, TagEncoding, - TargetDataLayout, VariantIdx, Variants, WrappingRange, FIRST_VARIANT, + Abi, AbiAndPrefAlign, Align, FieldsShape, IndexSlice, IndexVec, Integer, LayoutS, Niche, + NonZeroUsize, Primitive, ReprOptions, Scalar, Size, StructKind, TagEncoding, TargetDataLayout, + VariantIdx, Variants, WrappingRange, FIRST_VARIANT, }; pub trait LayoutCalculator { type TargetDataLayoutRef: Borrow<TargetDataLayout>; @@ -14,7 +16,7 @@ pub trait LayoutCalculator { fn delay_bug(&self, txt: String); fn current_data_layout(&self) -> Self::TargetDataLayoutRef; - fn scalar_pair(&self, a: Scalar, b: Scalar) -> LayoutS { + fn scalar_pair<FieldIdx: Idx>(&self, a: Scalar, b: Scalar) -> LayoutS<FieldIdx> { let dl = self.current_data_layout(); let dl = dl.borrow(); let b_align = b.align(dl); @@ -44,13 +46,13 @@ pub trait LayoutCalculator { } } - fn univariant( + fn univariant<'a, FieldIdx: Idx, F: Deref<Target = &'a LayoutS<FieldIdx>> + fmt::Debug>( &self, dl: &TargetDataLayout, - fields: &IndexSlice<FieldIdx, Layout<'_>>, + fields: &IndexSlice<FieldIdx, F>, repr: &ReprOptions, kind: StructKind, - ) -> Option<LayoutS> { + ) -> Option<LayoutS<FieldIdx>> { 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 // (smaller) data-carrying variants can be packed into the space after/before the niche. @@ -113,7 +115,7 @@ pub trait LayoutCalculator { layout } - fn layout_of_never_type(&self) -> LayoutS { + fn layout_of_never_type<FieldIdx: Idx>(&self) -> LayoutS<FieldIdx> { let dl = self.current_data_layout(); let dl = dl.borrow(); LayoutS { @@ -128,10 +130,14 @@ pub trait LayoutCalculator { } } - fn layout_of_struct_or_enum( + fn layout_of_struct_or_enum< + 'a, + FieldIdx: Idx, + F: Deref<Target = &'a LayoutS<FieldIdx>> + fmt::Debug, + >( &self, repr: &ReprOptions, - variants: &IndexSlice<VariantIdx, IndexVec<FieldIdx, Layout<'_>>>, + variants: &IndexSlice<VariantIdx, IndexVec<FieldIdx, F>>, is_enum: bool, is_unsafe_cell: bool, scalar_valid_range: (Bound<u128>, Bound<u128>), @@ -139,7 +145,7 @@ pub trait LayoutCalculator { discriminants: impl Iterator<Item = (VariantIdx, i128)>, dont_niche_optimize_enum: bool, always_sized: bool, - ) -> Option<LayoutS> { + ) -> Option<LayoutS<FieldIdx>> { let dl = self.current_data_layout(); let dl = dl.borrow(); @@ -154,11 +160,11 @@ pub trait LayoutCalculator { // but *not* an encoding of the discriminant (e.g., a tag value). // See issue #49298 for more details on the need to leave space // for non-ZST uninhabited data (mostly partial initialization). - let absent = |fields: &IndexSlice<FieldIdx, Layout<'_>>| { - let uninhabited = fields.iter().any(|f| f.abi().is_uninhabited()); + let absent = |fields: &IndexSlice<FieldIdx, F>| { + let uninhabited = fields.iter().any(|f| f.abi.is_uninhabited()); // We cannot ignore alignment; that might lead us to entirely discard a variant and // produce an enum that is less aligned than it should be! - let is_1zst = fields.iter().all(|f| f.0.is_1zst()); + let is_1zst = fields.iter().all(|f| f.is_1zst()); uninhabited && is_1zst }; let (present_first, present_second) = { @@ -278,12 +284,12 @@ pub trait LayoutCalculator { // variant layouts, so we can't store them in the // overall LayoutS. Store the overall LayoutS // and the variant LayoutSs here until then. - struct TmpLayout { - layout: LayoutS, - variants: IndexVec<VariantIdx, LayoutS>, + struct TmpLayout<FieldIdx: Idx> { + layout: LayoutS<FieldIdx>, + variants: IndexVec<VariantIdx, LayoutS<FieldIdx>>, } - let calculate_niche_filling_layout = || -> Option<TmpLayout> { + let calculate_niche_filling_layout = || -> Option<TmpLayout<FieldIdx>> { if dont_niche_optimize_enum { return None; } @@ -327,7 +333,7 @@ pub trait LayoutCalculator { let (field_index, niche, (niche_start, niche_scalar)) = variants[largest_variant_index] .iter() .enumerate() - .filter_map(|(j, field)| Some((j, field.largest_niche()?))) + .filter_map(|(j, field)| Some((j, field.largest_niche?))) .max_by_key(|(_, niche)| niche.available(dl)) .and_then(|(j, niche)| Some((j, niche, niche.reserve(dl, count)?)))?; let niche_offset = @@ -442,7 +448,7 @@ pub trait LayoutCalculator { let discr_type = repr.discr_type(); let bits = Integer::from_attr(dl, discr_type).size().bits(); for (i, mut val) in discriminants { - if variants[i].iter().any(|f| f.abi().is_uninhabited()) { + if variants[i].iter().any(|f| f.abi.is_uninhabited()) { continue; } if discr_type.is_signed() { @@ -483,7 +489,7 @@ pub trait LayoutCalculator { if repr.c() { for fields in variants { for field in fields { - prefix_align = prefix_align.max(field.align().abi); + prefix_align = prefix_align.max(field.align.abi); } } } @@ -502,9 +508,9 @@ pub trait LayoutCalculator { // Find the first field we can't move later // to make room for a larger discriminant. for field_idx in st.fields.index_by_increasing_offset() { - let field = &field_layouts[FieldIdx::from_usize(field_idx)]; - if !field.0.is_1zst() { - start_align = start_align.min(field.align().abi); + let field = &field_layouts[FieldIdx::new(field_idx)]; + if !field.is_1zst() { + start_align = start_align.min(field.align.abi); break; } } @@ -611,7 +617,7 @@ pub trait LayoutCalculator { }; // We skip *all* ZST here and later check if we are good in terms of alignment. // This lets us handle some cases involving aligned ZST. - let mut fields = iter::zip(field_layouts, offsets).filter(|p| !p.0.0.is_zst()); + let mut fields = iter::zip(field_layouts, offsets).filter(|p| !p.0.is_zst()); let (field, offset) = match (fields.next(), fields.next()) { (None, None) => { common_prim_initialized_in_all_variants = false; @@ -623,7 +629,7 @@ pub trait LayoutCalculator { break; } }; - let prim = match field.abi() { + let prim = match field.abi { Abi::Scalar(scalar) => { common_prim_initialized_in_all_variants &= matches!(scalar, Scalar::Initialized { .. }); @@ -662,8 +668,8 @@ pub trait LayoutCalculator { } _ => panic!(), }; - if pair_offsets[FieldIdx::from_u32(0)] == Size::ZERO - && pair_offsets[FieldIdx::from_u32(1)] == *offset + if pair_offsets[FieldIdx::new(0)] == Size::ZERO + && pair_offsets[FieldIdx::new(1)] == *offset && align == pair.align && size == pair.size { @@ -720,8 +726,9 @@ pub trait LayoutCalculator { // pick the layout with the larger niche; otherwise, // pick tagged as it has simpler codegen. use cmp::Ordering::*; - let niche_size = - |tmp_l: &TmpLayout| tmp_l.layout.largest_niche.map_or(0, |n| n.available(dl)); + let niche_size = |tmp_l: &TmpLayout<FieldIdx>| { + 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))) { (Greater, _) => nl, (Equal, Less) => nl, @@ -741,11 +748,11 @@ pub trait LayoutCalculator { Some(best_layout.layout) } - fn layout_of_union( + fn layout_of_union<'a, FieldIdx: Idx, F: Deref<Target = &'a LayoutS<FieldIdx>> + fmt::Debug>( &self, repr: &ReprOptions, - variants: &IndexSlice<VariantIdx, IndexVec<FieldIdx, Layout<'_>>>, - ) -> Option<LayoutS> { + variants: &IndexSlice<VariantIdx, IndexVec<FieldIdx, F>>, + ) -> Option<LayoutS<FieldIdx>> { let dl = self.current_data_layout(); let dl = dl.borrow(); let mut align = if repr.pack.is_some() { dl.i8_align } else { dl.aggregate_align }; @@ -764,22 +771,22 @@ pub trait LayoutCalculator { let mut size = Size::ZERO; let only_variant = &variants[FIRST_VARIANT]; for field in only_variant { - if field.0.is_unsized() { + if field.is_unsized() { self.delay_bug("unsized field in union".to_string()); } - align = align.max(field.align()); - max_repr_align = max_repr_align.max(field.max_repr_align()); - size = cmp::max(size, field.size()); + align = align.max(field.align); + max_repr_align = max_repr_align.max(field.max_repr_align); + size = cmp::max(size, field.size); - if field.0.is_zst() { + if field.is_zst() { // Nothing more to do for ZST fields continue; } if let Ok(common) = common_non_zst_abi_and_align { // Discard valid range information and allow undef - let field_abi = field.abi().to_union(); + let field_abi = field.abi.to_union(); if let Some((common_abi, common_align)) = common { if common_abi != field_abi { @@ -790,15 +797,14 @@ pub trait LayoutCalculator { // have the same alignment if !matches!(common_abi, Abi::Aggregate { .. }) { assert_eq!( - common_align, - field.align().abi, + common_align, field.align.abi, "non-Aggregate field with matching ABI but differing alignment" ); } } } else { // First non-ZST field: record its ABI and alignment - common_non_zst_abi_and_align = Ok(Some((field_abi, field.align().abi))); + common_non_zst_abi_and_align = Ok(Some((field_abi, field.align.abi))); } } } @@ -848,14 +854,14 @@ enum NicheBias { End, } -fn univariant( +fn univariant<'a, FieldIdx: Idx, F: Deref<Target = &'a LayoutS<FieldIdx>> + fmt::Debug>( this: &(impl LayoutCalculator + ?Sized), dl: &TargetDataLayout, - fields: &IndexSlice<FieldIdx, Layout<'_>>, + fields: &IndexSlice<FieldIdx, F>, repr: &ReprOptions, kind: StructKind, niche_bias: NicheBias, -) -> Option<LayoutS> { +) -> Option<LayoutS<FieldIdx>> { let pack = repr.pack; let mut align = if pack.is_some() { dl.i8_align } else { dl.aggregate_align }; let mut max_repr_align = repr.align; @@ -887,27 +893,27 @@ fn univariant( // To allow unsizing `&Foo<Type>` -> `&Foo<dyn Trait>`, the layout of the struct must // not depend on the layout of the tail. let max_field_align = - fields_excluding_tail.iter().map(|f| f.align().abi.bytes()).max().unwrap_or(1); + fields_excluding_tail.iter().map(|f| f.align.abi.bytes()).max().unwrap_or(1); let largest_niche_size = fields_excluding_tail .iter() - .filter_map(|f| f.largest_niche()) + .filter_map(|f| f.largest_niche) .map(|n| n.available(dl)) .max() .unwrap_or(0); // Calculates a sort key to group fields by their alignment or possibly some // size-derived pseudo-alignment. - let alignment_group_key = |layout: Layout<'_>| { + let alignment_group_key = |layout: &F| { if let Some(pack) = pack { // Return the packed alignment in bytes. - layout.align().abi.min(pack).bytes() + layout.align.abi.min(pack).bytes() } else { // Returns `log2(effective-align)`. This is ok since `pack` applies to all // fields equally. The calculation assumes that size is an integer multiple of // align, except for ZSTs. - let align = layout.align().abi.bytes(); - let size = layout.size().bytes(); - let niche_size = layout.largest_niche().map(|n| n.available(dl)).unwrap_or(0); + let align = layout.align.abi.bytes(); + let size = layout.size.bytes(); + let niche_size = layout.largest_niche.map(|n| n.available(dl)).unwrap_or(0); // Group [u8; 4] with align-4 or [u8; 6] with align-2 fields. let size_as_align = align.max(size).trailing_zeros(); let size_as_align = if largest_niche_size > 0 { @@ -942,9 +948,9 @@ fn univariant( // u16 to build a 4-byte group so that the u32 can be placed after it without // padding. This kind of packing can't be achieved by sorting. optimizing.sort_by_key(|&x| { - let f = fields[x]; - let field_size = f.size().bytes(); - let niche_size = f.largest_niche().map_or(0, |n| n.available(dl)); + let f = &fields[x]; + let field_size = f.size.bytes(); + let niche_size = f.largest_niche.map_or(0, |n| n.available(dl)); let niche_size_key = match niche_bias { // large niche first NicheBias::Start => !niche_size, @@ -952,8 +958,8 @@ fn univariant( NicheBias::End => niche_size, }; let inner_niche_offset_key = match niche_bias { - NicheBias::Start => f.largest_niche().map_or(0, |n| n.offset.bytes()), - NicheBias::End => f.largest_niche().map_or(0, |n| { + NicheBias::Start => f.largest_niche.map_or(0, |n| n.offset.bytes()), + NicheBias::End => f.largest_niche.map_or(0, |n| { !(field_size - n.value.size(dl).bytes() - n.offset.bytes()) }), }; @@ -977,8 +983,8 @@ fn univariant( // And put the largest niche in an alignment group at the end // so it can be used as discriminant in jagged enums optimizing.sort_by_key(|&x| { - let f = fields[x]; - let niche_size = f.largest_niche().map_or(0, |n| n.available(dl)); + let f = &fields[x]; + let niche_size = f.largest_niche.map_or(0, |n| n.available(dl)); (alignment_group_key(f), niche_size) }); } @@ -1014,24 +1020,24 @@ fn univariant( )); } - if field.0.is_unsized() { + if field.is_unsized() { sized = false; } // Invariant: offset < dl.obj_size_bound() <= 1<<61 let field_align = if let Some(pack) = pack { - field.align().min(AbiAndPrefAlign::new(pack)) + field.align.min(AbiAndPrefAlign::new(pack)) } else { - field.align() + field.align }; offset = offset.align_to(field_align.abi); align = align.max(field_align); - max_repr_align = max_repr_align.max(field.max_repr_align()); + max_repr_align = max_repr_align.max(field.max_repr_align); debug!("univariant offset: {:?} field: {:#?}", offset, field); offsets[i] = offset; - if let Some(mut niche) = field.largest_niche() { + if let Some(mut niche) = field.largest_niche { let available = niche.available(dl); // Pick up larger niches. let prefer_new_niche = match niche_bias { @@ -1046,7 +1052,7 @@ fn univariant( } } - offset = offset.checked_add(field.size(), dl)?; + offset = offset.checked_add(field.size, dl)?; } // The unadjusted ABI alignment does not include repr(align), but does include repr(pack). @@ -1070,7 +1076,7 @@ fn univariant( inverse_memory_index.invert_bijective_mapping() } else { debug_assert!(inverse_memory_index.iter().copied().eq(fields.indices())); - inverse_memory_index.into_iter().map(FieldIdx::as_u32).collect() + inverse_memory_index.into_iter().map(|it| it.index() as u32).collect() }; let size = min_size.align_to(align.abi); let mut layout_of_single_non_zst_field = None; @@ -1079,7 +1085,7 @@ fn univariant( if sized && size.bytes() > 0 { // We skip *all* ZST here and later check if we are good in terms of alignment. // This lets us handle some cases involving aligned ZST. - let mut non_zst_fields = fields.iter_enumerated().filter(|&(_, f)| !f.0.is_zst()); + let mut non_zst_fields = fields.iter_enumerated().filter(|&(_, f)| !f.is_zst()); match (non_zst_fields.next(), non_zst_fields.next(), non_zst_fields.next()) { // We have exactly one non-ZST field. @@ -1087,18 +1093,17 @@ fn univariant( layout_of_single_non_zst_field = Some(field); // Field fills the struct and it has a scalar or scalar pair ABI. - if offsets[i].bytes() == 0 && align.abi == field.align().abi && size == field.size() - { - match field.abi() { + if offsets[i].bytes() == 0 && align.abi == field.align.abi && size == field.size { + match field.abi { // For plain scalars, or vectors of them, we can't unpack // newtypes for `#[repr(C)]`, as that affects C ABIs. Abi::Scalar(_) | Abi::Vector { .. } if optimize => { - abi = field.abi(); + abi = field.abi; } // But scalar pairs are Rust-specific and get // treated as aggregates by C ABIs anyway. Abi::ScalarPair(..) => { - abi = field.abi(); + abi = field.abi; } _ => {} } @@ -1107,7 +1112,7 @@ fn univariant( // Two non-ZST fields, and they're both scalars. (Some((i, a)), Some((j, b)), None) => { - match (a.abi(), b.abi()) { + match (a.abi, b.abi) { (Abi::Scalar(a), Abi::Scalar(b)) => { // Order by the memory placement, not source order. let ((i, a), (j, b)) = if offsets[i] < offsets[j] { @@ -1123,8 +1128,8 @@ fn univariant( } _ => panic!(), }; - if offsets[i] == pair_offsets[FieldIdx::from_usize(0)] - && offsets[j] == pair_offsets[FieldIdx::from_usize(1)] + if offsets[i] == pair_offsets[FieldIdx::new(0)] + && offsets[j] == pair_offsets[FieldIdx::new(1)] && align == pair.align && size == pair.size { @@ -1140,13 +1145,13 @@ fn univariant( _ => {} } } - if fields.iter().any(|f| f.abi().is_uninhabited()) { + if fields.iter().any(|f| f.abi.is_uninhabited()) { abi = Abi::Uninhabited; } let unadjusted_abi_align = if repr.transparent() { match layout_of_single_non_zst_field { - Some(l) => l.unadjusted_abi_align(), + Some(l) => l.unadjusted_abi_align, None => { // `repr(transparent)` with all ZST fields. align.abi @@ -1168,17 +1173,17 @@ fn univariant( }) } -fn format_field_niches( - layout: &LayoutS, - fields: &IndexSlice<FieldIdx, Layout<'_>>, +fn format_field_niches<'a, FieldIdx: Idx, F: Deref<Target = &'a LayoutS<FieldIdx>> + fmt::Debug>( + layout: &LayoutS<FieldIdx>, + fields: &IndexSlice<FieldIdx, F>, dl: &TargetDataLayout, ) -> String { let mut s = String::new(); for i in layout.fields.index_by_increasing_offset() { let offset = layout.fields.offset(i); - let f = fields[i.into()]; - write!(s, "[o{}a{}s{}", offset.bytes(), f.align().abi.bytes(), f.size().bytes()).unwrap(); - if let Some(n) = f.largest_niche() { + let f = &fields[FieldIdx::new(i)]; + write!(s, "[o{}a{}s{}", offset.bytes(), f.align.abi.bytes(), f.size.bytes()).unwrap(); + if let Some(n) = f.largest_niche { write!( s, " n{}b{}s{}", diff --git a/compiler/rustc_abi/src/lib.rs b/compiler/rustc_abi/src/lib.rs index 6a313936bf5..2c1a70c277e 100644 --- a/compiler/rustc_abi/src/lib.rs +++ b/compiler/rustc_abi/src/lib.rs @@ -15,7 +15,7 @@ use rustc_data_structures::intern::Interned; use rustc_data_structures::stable_hasher::Hash64; #[cfg(feature = "nightly")] use rustc_data_structures::stable_hasher::StableOrd; -use rustc_index::{IndexSlice, IndexVec}; +use rustc_index::{Idx, IndexSlice, IndexVec}; #[cfg(feature = "nightly")] use rustc_macros::HashStable_Generic; #[cfg(feature = "nightly")] @@ -1134,7 +1134,7 @@ rustc_index::newtype_index! { /// Describes how the fields of a type are located in memory. #[derive(PartialEq, Eq, Hash, Clone, Debug)] #[cfg_attr(feature = "nightly", derive(HashStable_Generic))] -pub enum FieldsShape { +pub enum FieldsShape<FieldIdx: Idx> { /// Scalar primitives and `!`, which never have fields. Primitive, @@ -1174,7 +1174,7 @@ pub enum FieldsShape { }, } -impl FieldsShape { +impl<FieldIdx: Idx> FieldsShape<FieldIdx> { #[inline] pub fn count(&self) -> usize { match *self { @@ -1200,7 +1200,7 @@ impl FieldsShape { assert!(i < count, "tried to access field {i} of array with {count} fields"); stride * i } - FieldsShape::Arbitrary { ref offsets, .. } => offsets[FieldIdx::from_usize(i)], + FieldsShape::Arbitrary { ref offsets, .. } => offsets[FieldIdx::new(i)], } } @@ -1212,7 +1212,7 @@ impl FieldsShape { } FieldsShape::Union(_) | FieldsShape::Array { .. } => i, FieldsShape::Arbitrary { ref memory_index, .. } => { - memory_index[FieldIdx::from_usize(i)].try_into().unwrap() + memory_index[FieldIdx::new(i)].try_into().unwrap() } } } @@ -1228,7 +1228,7 @@ impl FieldsShape { if let FieldsShape::Arbitrary { ref memory_index, .. } = *self { if use_small { for (field_idx, &mem_idx) in memory_index.iter_enumerated() { - inverse_small[mem_idx as usize] = field_idx.as_u32() as u8; + inverse_small[mem_idx as usize] = field_idx.index() as u8; } } else { inverse_big = memory_index.invert_bijective_mapping(); @@ -1241,7 +1241,7 @@ impl FieldsShape { if use_small { inverse_small[i] as usize } else { - inverse_big[i as u32].as_usize() + inverse_big[i as u32].index() } } }) @@ -1386,7 +1386,7 @@ impl Abi { #[derive(PartialEq, Eq, Hash, Clone, Debug)] #[cfg_attr(feature = "nightly", derive(HashStable_Generic))] -pub enum Variants { +pub enum Variants<FieldIdx: Idx> { /// Single enum variants, structs/tuples, unions, and all non-ADTs. Single { index: VariantIdx }, @@ -1400,7 +1400,7 @@ pub enum Variants { tag: Scalar, tag_encoding: TagEncoding, tag_field: usize, - variants: IndexVec<VariantIdx, LayoutS>, + variants: IndexVec<VariantIdx, LayoutS<FieldIdx>>, }, } @@ -1534,9 +1534,9 @@ rustc_index::newtype_index! { #[derive(PartialEq, Eq, Hash, Clone)] #[cfg_attr(feature = "nightly", derive(HashStable_Generic))] -pub struct LayoutS { +pub struct LayoutS<FieldIdx: Idx> { /// Says where the fields are located within the layout. - pub fields: FieldsShape, + pub fields: FieldsShape<FieldIdx>, /// Encodes information about multi-variant layouts. /// Even with `Multiple` variants, a layout still has its own fields! Those are then @@ -1545,7 +1545,7 @@ pub struct LayoutS { /// /// To access all fields of this layout, both `fields` and the fields of the active variant /// must be taken into account. - pub variants: Variants, + pub variants: Variants<FieldIdx>, /// The `abi` defines how this data is passed between functions, and it defines /// value restrictions via `valid_range`. @@ -1574,7 +1574,7 @@ pub struct LayoutS { pub unadjusted_abi_align: Align, } -impl LayoutS { +impl<FieldIdx: Idx> LayoutS<FieldIdx> { pub fn scalar<C: HasDataLayout>(cx: &C, scalar: Scalar) -> Self { let largest_niche = Niche::from_scalar(cx, Size::ZERO, scalar); let size = scalar.size(cx); @@ -1592,7 +1592,11 @@ impl LayoutS { } } -impl fmt::Debug for LayoutS { +impl<FieldIdx: Idx> fmt::Debug for LayoutS<FieldIdx> +where + FieldsShape<FieldIdx>: fmt::Debug, + Variants<FieldIdx>: fmt::Debug, +{ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { // This is how `Layout` used to print before it become // `Interned<LayoutS>`. We print it like this to avoid having to update @@ -1622,7 +1626,7 @@ impl fmt::Debug for LayoutS { #[derive(Copy, Clone, PartialEq, Eq, Hash, HashStable_Generic)] #[rustc_pass_by_value] -pub struct Layout<'a>(pub Interned<'a, LayoutS>); +pub struct Layout<'a>(pub Interned<'a, LayoutS<FieldIdx>>); impl<'a> fmt::Debug for Layout<'a> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { @@ -1632,11 +1636,11 @@ impl<'a> fmt::Debug for Layout<'a> { } impl<'a> Layout<'a> { - pub fn fields(self) -> &'a FieldsShape { + pub fn fields(self) -> &'a FieldsShape<FieldIdx> { &self.0.0.fields } - pub fn variants(self) -> &'a Variants { + pub fn variants(self) -> &'a Variants<FieldIdx> { &self.0.0.variants } @@ -1694,7 +1698,7 @@ pub struct PointeeInfo { pub safe: Option<PointerKind>, } -impl LayoutS { +impl<FieldIdx: Idx> LayoutS<FieldIdx> { /// Returns `true` if the layout corresponds to an unsized type. #[inline] pub fn is_unsized(&self) -> bool { diff --git a/compiler/rustc_target/src/abi/mod.rs b/compiler/rustc_target/src/abi/mod.rs index 74fe98920c4..7d2239fe641 100644 --- a/compiler/rustc_target/src/abi/mod.rs +++ b/compiler/rustc_target/src/abi/mod.rs @@ -42,8 +42,8 @@ impl<'a, Ty: fmt::Display> fmt::Debug for TyAndLayout<'a, Ty> { } impl<'a, Ty> Deref for TyAndLayout<'a, Ty> { - type Target = &'a LayoutS; - fn deref(&self) -> &&'a LayoutS { + type Target = &'a LayoutS<FieldIdx>; + fn deref(&self) -> &&'a LayoutS<FieldIdx> { &self.layout.0.0 } } |
