Skip to content

Commit 44bf0a6

Browse files
committed
Auto merge of #158576 - camelid:move-layout, r=<try>
Move `Layout` to `rustc_type_ir` and `rustc_middle` and implement (de)serialization
2 parents 5165714 + 519a985 commit 44bf0a6

139 files changed

Lines changed: 1067 additions & 989 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

Cargo.lock

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3902,7 +3902,6 @@ dependencies = [
39023902
"rustc_mir_dataflow",
39033903
"rustc_session",
39043904
"rustc_span",
3905-
"rustc_target",
39063905
"rustc_trait_selection",
39073906
"tracing",
39083907
]
@@ -4670,7 +4669,6 @@ dependencies = [
46704669
"rustc_middle",
46714670
"rustc_session",
46724671
"rustc_span",
4673-
"rustc_target",
46744672
]
46754673

46764674
[[package]]
@@ -4813,6 +4811,7 @@ version = "0.0.0"
48134811
dependencies = [
48144812
"arrayvec",
48154813
"bitflags",
4814+
"derive-where",
48164815
"object 0.37.3",
48174816
"rustc_abi",
48184817
"rustc_data_structures",
@@ -4821,6 +4820,7 @@ dependencies = [
48214820
"rustc_macros",
48224821
"rustc_serialize",
48234822
"rustc_span",
4823+
"rustc_type_ir",
48244824
"schemars",
48254825
"serde",
48264826
"serde_derive",

compiler/rustc_abi/src/callconv.rs

Lines changed: 1 addition & 147 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,3 @@
1-
#[cfg(feature = "nightly")]
2-
use crate::{BackendRepr, FieldsShape, Primitive, Size, TyAbiInterface, TyAndLayout, Variants};
3-
41
mod reg;
52

63
pub use reg::{Reg, RegKind};
@@ -35,8 +32,7 @@ impl HomogeneousAggregate {
3532
/// Try to combine two `HomogeneousAggregate`s, e.g. from two fields in
3633
/// the same `struct`. Only succeeds if only one of them has any data,
3734
/// or both units are identical.
38-
#[cfg(feature = "nightly")]
39-
fn merge(self, other: HomogeneousAggregate) -> Result<HomogeneousAggregate, Heterogeneous> {
35+
pub fn merge(self, other: HomogeneousAggregate) -> Result<HomogeneousAggregate, Heterogeneous> {
4036
match (self, other) {
4137
(x, HomogeneousAggregate::NoData) | (HomogeneousAggregate::NoData, x) => Ok(x),
4238

@@ -49,145 +45,3 @@ impl HomogeneousAggregate {
4945
}
5046
}
5147
}
52-
53-
#[cfg(feature = "nightly")]
54-
impl<'a, Ty> TyAndLayout<'a, Ty> {
55-
/// Returns `Homogeneous` if this layout is an aggregate containing fields of
56-
/// only a single type (e.g., `(u32, u32)`). Such aggregates are often
57-
/// special-cased in ABIs.
58-
///
59-
/// Note: We generally ignore 1-ZST fields when computing this value (see #56877).
60-
///
61-
/// This is public so that it can be used in unit tests, but
62-
/// should generally only be relevant to the ABI details of
63-
/// specific targets.
64-
#[tracing::instrument(skip(cx), level = "debug")]
65-
pub fn homogeneous_aggregate<C>(&self, cx: &C) -> Result<HomogeneousAggregate, Heterogeneous>
66-
where
67-
Ty: TyAbiInterface<'a, C> + Copy,
68-
{
69-
match self.backend_repr {
70-
// The primitive for this algorithm.
71-
BackendRepr::Scalar(scalar) => {
72-
let kind = match scalar.primitive() {
73-
Primitive::Int(..) | Primitive::Pointer(_) => RegKind::Integer,
74-
Primitive::Float(_) => RegKind::Float,
75-
};
76-
Ok(HomogeneousAggregate::Homogeneous(Reg { kind, size: self.size }))
77-
}
78-
79-
BackendRepr::SimdVector { element, count: _ } => {
80-
assert!(!self.is_zst());
81-
82-
Ok(HomogeneousAggregate::Homogeneous(Reg {
83-
kind: RegKind::Vector { hint_vector_elem: element.primitive() },
84-
size: self.size,
85-
}))
86-
}
87-
88-
BackendRepr::SimdScalableVector { .. } => {
89-
unreachable!("`homogeneous_aggregate` should not be called for scalable vectors")
90-
}
91-
92-
BackendRepr::ScalarPair(..) | BackendRepr::Memory { sized: true } => {
93-
// Helper for computing `homogeneous_aggregate`, allowing a custom
94-
// starting offset (used below for handling variants).
95-
let from_fields_at =
96-
|layout: Self,
97-
start: Size|
98-
-> Result<(HomogeneousAggregate, Size), Heterogeneous> {
99-
let is_union = match layout.fields {
100-
FieldsShape::Primitive => {
101-
unreachable!("aggregates can't have `FieldsShape::Primitive`")
102-
}
103-
FieldsShape::Array { count, .. } => {
104-
assert_eq!(start, Size::ZERO);
105-
106-
let result = if count > 0 {
107-
layout.field(cx, 0).homogeneous_aggregate(cx)?
108-
} else {
109-
HomogeneousAggregate::NoData
110-
};
111-
return Ok((result, layout.size));
112-
}
113-
FieldsShape::Union(_) => true,
114-
FieldsShape::Arbitrary { .. } => false,
115-
};
116-
117-
let mut result = HomogeneousAggregate::NoData;
118-
let mut total = start;
119-
120-
for i in 0..layout.fields.count() {
121-
let field = layout.field(cx, i);
122-
if field.is_1zst() {
123-
// No data here and no impact on layout, can be ignored.
124-
// (We might be able to also ignore all aligned ZST but that's less clear.)
125-
continue;
126-
}
127-
128-
if !is_union && total != layout.fields.offset(i) {
129-
// This field isn't just after the previous one we considered, abort.
130-
return Err(Heterogeneous);
131-
}
132-
133-
result = result.merge(field.homogeneous_aggregate(cx)?)?;
134-
135-
// Keep track of the offset (without padding).
136-
let size = field.size;
137-
if is_union {
138-
total = total.max(size);
139-
} else {
140-
total += size;
141-
}
142-
}
143-
144-
Ok((result, total))
145-
};
146-
147-
let (mut result, mut total) = from_fields_at(*self, Size::ZERO)?;
148-
149-
match &self.variants {
150-
Variants::Single { .. } | Variants::Empty => {}
151-
Variants::Multiple { variants, .. } => {
152-
// Treat enum variants like union members.
153-
// HACK(eddyb) pretend the `enum` field (discriminant)
154-
// is at the start of every variant (otherwise the gap
155-
// at the start of all variants would disqualify them).
156-
//
157-
// NB: for all tagged `enum`s (which include all non-C-like
158-
// `enum`s with defined FFI representation), this will
159-
// match the homogeneous computation on the equivalent
160-
// `struct { tag; union { variant1; ... } }` and/or
161-
// `union { struct { tag; variant1; } ... }`
162-
// (the offsets of variant fields should be identical
163-
// between the two for either to be a homogeneous aggregate).
164-
let variant_start = total;
165-
for variant_idx in variants.indices() {
166-
let (variant_result, variant_total) =
167-
from_fields_at(self.for_variant(cx, variant_idx), variant_start)?;
168-
169-
result = result.merge(variant_result)?;
170-
total = total.max(variant_total);
171-
}
172-
}
173-
}
174-
175-
// There needs to be no padding.
176-
if total != self.size {
177-
Err(Heterogeneous)
178-
} else {
179-
match result {
180-
HomogeneousAggregate::Homogeneous(_) => {
181-
assert_ne!(total, Size::ZERO);
182-
}
183-
HomogeneousAggregate::NoData => {
184-
assert_eq!(total, Size::ZERO);
185-
}
186-
}
187-
Ok(result)
188-
}
189-
}
190-
BackendRepr::Memory { sized: false } => Err(Heterogeneous),
191-
}
192-
}
193-
}

compiler/rustc_abi/src/layout.rs

Lines changed: 10 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,6 @@ use crate::{
1818
mod coroutine;
1919
mod simple;
2020

21-
#[cfg(feature = "nightly")]
22-
mod ty;
23-
24-
#[cfg(feature = "nightly")]
25-
pub use ty::{Layout, TyAbiInterface, TyAndLayout};
26-
2721
rustc_index::newtype_index! {
2822
/// The *source-order* index of a field in a variant.
2923
///
@@ -86,11 +80,11 @@ rustc_index::newtype_index! {
8680
// but *not* an encoding of the discriminant (e.g., a tag value).
8781
// See issue #49298 for more details on the need to leave space
8882
// for non-ZST uninhabited data (mostly partial initialization).
89-
fn absent<'a, FieldIdx, VariantIdx, F>(fields: &IndexSlice<FieldIdx, F>) -> bool
83+
fn absent<FieldIdx, VariantIdx, F>(fields: &IndexSlice<FieldIdx, F>) -> bool
9084
where
9185
FieldIdx: Idx,
9286
VariantIdx: Idx,
93-
F: Deref<Target = &'a LayoutData<FieldIdx, VariantIdx>> + fmt::Debug,
87+
F: Deref<Target = LayoutData<FieldIdx, VariantIdx>> + fmt::Debug,
9488
{
9589
let uninhabited = fields.iter().any(|f| f.is_uninhabited());
9690
// We cannot ignore alignment; that might lead us to entirely discard a variant and
@@ -240,8 +234,7 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
240234
/// This uses dedicated code instead of [`Self::layout_of_struct_or_enum`], as coroutine
241235
/// fields may be shared between multiple variants (see the [`coroutine`] module for details).
242236
pub fn coroutine<
243-
'a,
244-
F: Deref<Target = &'a LayoutData<FieldIdx, VariantIdx>> + fmt::Debug + Copy,
237+
F: Deref<Target = LayoutData<FieldIdx, VariantIdx>> + fmt::Debug + Copy,
245238
VariantIdx: Idx,
246239
FieldIdx: Idx,
247240
LocalIdx: Idx,
@@ -264,10 +257,9 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
264257
}
265258

266259
pub fn univariant<
267-
'a,
268260
FieldIdx: Idx,
269261
VariantIdx: Idx,
270-
F: Deref<Target = &'a LayoutData<FieldIdx, VariantIdx>> + fmt::Debug + Copy,
262+
F: Deref<Target = LayoutData<FieldIdx, VariantIdx>> + fmt::Debug + Copy,
271263
>(
272264
&self,
273265
fields: &IndexSlice<FieldIdx, F>,
@@ -339,10 +331,9 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
339331
}
340332

341333
pub fn layout_of_struct_or_enum<
342-
'a,
343334
FieldIdx: Idx,
344335
VariantIdx: Idx,
345-
F: Deref<Target = &'a LayoutData<FieldIdx, VariantIdx>> + fmt::Debug + Copy,
336+
F: Deref<Target = LayoutData<FieldIdx, VariantIdx>> + fmt::Debug + Copy,
346337
>(
347338
&self,
348339
repr: &ReprOptions,
@@ -393,10 +384,9 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
393384
}
394385

395386
pub fn layout_of_union<
396-
'a,
397387
FieldIdx: Idx,
398388
VariantIdx: Idx,
399-
F: Deref<Target = &'a LayoutData<FieldIdx, VariantIdx>> + fmt::Debug + Copy,
389+
F: Deref<Target = LayoutData<FieldIdx, VariantIdx>> + fmt::Debug + Copy,
400390
>(
401391
&self,
402392
repr: &ReprOptions,
@@ -519,10 +509,9 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
519509

520510
/// single-variant enums are just structs, if you think about it
521511
fn layout_of_struct<
522-
'a,
523512
FieldIdx: Idx,
524513
VariantIdx: Idx,
525-
F: Deref<Target = &'a LayoutData<FieldIdx, VariantIdx>> + fmt::Debug + Copy,
514+
F: Deref<Target = LayoutData<FieldIdx, VariantIdx>> + fmt::Debug + Copy,
526515
>(
527516
&self,
528517
repr: &ReprOptions,
@@ -572,10 +561,9 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
572561
}
573562

574563
fn layout_of_enum<
575-
'a,
576564
FieldIdx: Idx,
577565
VariantIdx: Idx,
578-
F: Deref<Target = &'a LayoutData<FieldIdx, VariantIdx>> + fmt::Debug + Copy,
566+
F: Deref<Target = LayoutData<FieldIdx, VariantIdx>> + fmt::Debug + Copy,
579567
>(
580568
&self,
581569
repr: &ReprOptions,
@@ -1092,10 +1080,9 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
10921080
}
10931081

10941082
fn univariant_biased<
1095-
'a,
10961083
FieldIdx: Idx,
10971084
VariantIdx: Idx,
1098-
F: Deref<Target = &'a LayoutData<FieldIdx, VariantIdx>> + fmt::Debug + Copy,
1085+
F: Deref<Target = LayoutData<FieldIdx, VariantIdx>> + fmt::Debug + Copy,
10991086
>(
11001087
&self,
11011088
fields: &IndexSlice<FieldIdx, F>,
@@ -1433,10 +1420,9 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
14331420
}
14341421

14351422
fn format_field_niches<
1436-
'a,
14371423
FieldIdx: Idx,
14381424
VariantIdx: Idx,
1439-
F: Deref<Target = &'a LayoutData<FieldIdx, VariantIdx>> + fmt::Debug,
1425+
F: Deref<Target = LayoutData<FieldIdx, VariantIdx>> + fmt::Debug,
14401426
>(
14411427
&self,
14421428
layout: &LayoutData<FieldIdx, VariantIdx>,

compiler/rustc_abi/src/layout/coroutine.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -137,8 +137,7 @@ fn coroutine_saved_local_eligibility<VariantIdx: Idx, FieldIdx: Idx, LocalIdx: I
137137

138138
/// Compute the full coroutine layout.
139139
pub(super) fn layout<
140-
'a,
141-
F: core::ops::Deref<Target = &'a LayoutData<FieldIdx, VariantIdx>> + core::fmt::Debug + Copy,
140+
F: core::ops::Deref<Target = LayoutData<FieldIdx, VariantIdx>> + core::fmt::Debug + Copy,
142141
VariantIdx: Idx,
143142
FieldIdx: Idx,
144143
LocalIdx: Idx,

0 commit comments

Comments
 (0)