Skip to content

Commit b40ce8b

Browse files
committed
Auto merge of #156670 - JonathanBrouwer:rollup-u90lYRn, r=JonathanBrouwer
Rollup of 14 pull requests Successful merges: - #151742 (Remove redundant information in `rustc_abi::Variants`) - #151362 (Add interior-mutability suggestion to `static_mut_refs`) - #156121 (compiler: suggest `.collect()` when `String` is expected and `Iterator` is found) - #156208 (Emit retags in codegen to support BorrowSanitizer (part 1)) - #156596 (Split `LintExpectationId`s) - #156607 (ci: Update FreeBSD version to FreeBSD 14) - #156376 (suggest hex escapes for C-style escapes) - #156577 (Test EII UI tests with prefer-dynamic) - #156585 (explicit tail calls: ignore some tests on unsupported LLVM targets) - #156598 (Avoid rustfix suggestions for macro-expanded unused imports) - #156616 (rustdoc: add test case for `-Drustdoc::` and `--cap-lints`) - #156633 (Add regression test for issue #41261) - #156635 (rename unexpected_try_recover function) - #156636 (minor `rustc_mir_transform` cleanup)
2 parents 507271b + fc7ac3d commit b40ce8b

90 files changed

Lines changed: 1834 additions & 1836 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.

compiler/rustc_abi/src/layout.rs

Lines changed: 36 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ use tracing::{debug, trace};
1111
use crate::{
1212
AbiAlign, Align, BackendRepr, FieldsShape, HasDataLayout, IndexSlice, IndexVec, Integer,
1313
LayoutData, Niche, NonZeroUsize, NumScalableVectors, Primitive, ReprOptions, Scalar, Size,
14-
StructKind, TagEncoding, TargetDataLayout, Variants, WrappingRange,
14+
StructKind, TagEncoding, TargetDataLayout, VariantLayout, Variants, WrappingRange,
1515
};
1616

1717
mod coroutine;
@@ -589,6 +589,10 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
589589
}
590590

591591
let calculate_niche_filling_layout = || -> Option<LayoutData<FieldIdx, VariantIdx>> {
592+
struct VariantLayoutInfo {
593+
align_abi: Align,
594+
}
595+
592596
if repr.inhibit_enum_layout_opt() {
593597
return None;
594598
}
@@ -600,18 +604,22 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
600604
let mut align = dl.aggregate_align;
601605
let mut max_repr_align = repr.align;
602606
let mut unadjusted_abi_align = align;
607+
let mut combined_seed = repr.field_shuffle_seed;
603608

609+
let mut variants_info = IndexVec::<VariantIdx, _>::with_capacity(variants.len());
604610
let mut variant_layouts = variants
605-
.iter_enumerated()
606-
.map(|(j, v)| {
607-
let mut st = self.univariant(v, repr, StructKind::AlwaysSized).ok()?;
608-
st.variants = Variants::Single { index: j };
611+
.iter()
612+
.map(|v| {
613+
let st = self.univariant(v, repr, StructKind::AlwaysSized).ok()?;
614+
615+
variants_info.push(VariantLayoutInfo { align_abi: st.align.abi });
609616

610617
align = align.max(st.align.abi);
611618
max_repr_align = max_repr_align.max(st.max_repr_align);
612619
unadjusted_abi_align = unadjusted_abi_align.max(st.unadjusted_abi_align);
620+
combined_seed = combined_seed.wrapping_add(st.randomization_seed);
613621

614-
Some(st)
622+
Some(VariantLayout::from_layout(st))
615623
})
616624
.collect::<Option<IndexVec<VariantIdx, _>>>()?;
617625

@@ -649,23 +657,16 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
649657
}
650658

651659
// Determine if it'll fit after the niche.
652-
let this_align = layout.align.abi;
660+
let this_align = variants_info[i].align_abi;
653661
let this_offset = (niche_offset + niche_size).align_to(this_align);
654662

655663
if this_offset + layout.size > size {
656664
return false;
657665
}
658666

659667
// It'll fit, but we need to make some adjustments.
660-
match layout.fields {
661-
FieldsShape::Arbitrary { ref mut offsets, .. } => {
662-
for offset in offsets.iter_mut() {
663-
*offset += this_offset;
664-
}
665-
}
666-
FieldsShape::Primitive | FieldsShape::Array { .. } | FieldsShape::Union(..) => {
667-
panic!("Layout of fields should be Arbitrary for variants")
668-
}
668+
for offset in layout.field_offsets.iter_mut() {
669+
*offset += this_offset;
669670
}
670671

671672
// It can't be a Scalar or ScalarPair because the offset isn't 0.
@@ -687,7 +688,7 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
687688
.iter_enumerated()
688689
.all(|(i, layout)| i == largest_variant_index || layout.size == Size::ZERO);
689690
let same_size = size == variant_layouts[largest_variant_index].size;
690-
let same_align = align == variant_layouts[largest_variant_index].align.abi;
691+
let same_align = align == variants_info[largest_variant_index].align_abi;
691692

692693
let uninhabited = variant_layouts.iter().all(|v| v.is_uninhabited());
693694
let abi = if same_size && same_align && others_zst {
@@ -710,11 +711,6 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
710711
BackendRepr::Memory { sized: true }
711712
};
712713

713-
let combined_seed = variant_layouts
714-
.iter()
715-
.map(|v| v.randomization_seed)
716-
.fold(repr.field_shuffle_seed, |acc, seed| acc.wrapping_add(seed));
717-
718714
let layout = LayoutData {
719715
variants: Variants::Multiple {
720716
tag: niche_scalar,
@@ -807,6 +803,7 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
807803
let mut align = dl.aggregate_align;
808804
let mut max_repr_align = repr.align;
809805
let mut unadjusted_abi_align = align;
806+
let mut combined_seed = repr.field_shuffle_seed;
810807

811808
let mut size = Size::ZERO;
812809

@@ -830,14 +827,13 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
830827

831828
// Create the set of structs that represent each variant.
832829
let mut layout_variants = variants
833-
.iter_enumerated()
834-
.map(|(i, field_layouts)| {
835-
let mut st = self.univariant(
830+
.iter()
831+
.map(|field_layouts| {
832+
let st = self.univariant(
836833
field_layouts,
837834
repr,
838835
StructKind::Prefixed(min_ity.size(), prefix_align),
839836
)?;
840-
st.variants = Variants::Single { index: i };
841837
// Find the first field we can't move later
842838
// to make room for a larger discriminant.
843839
for field_idx in st.fields.index_by_increasing_offset() {
@@ -851,7 +847,8 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
851847
align = align.max(st.align.abi);
852848
max_repr_align = max_repr_align.max(st.max_repr_align);
853849
unadjusted_abi_align = unadjusted_abi_align.max(st.unadjusted_abi_align);
854-
Ok(st)
850+
combined_seed = combined_seed.wrapping_add(st.randomization_seed);
851+
Ok(VariantLayout::from_layout(st))
855852
})
856853
.collect::<Result<IndexVec<VariantIdx, _>, _>>()?;
857854

@@ -906,23 +903,16 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
906903
let old_ity_size = min_ity.size();
907904
let new_ity_size = ity.size();
908905
for variant in &mut layout_variants {
909-
match variant.fields {
910-
FieldsShape::Arbitrary { ref mut offsets, .. } => {
911-
for i in offsets {
912-
if *i <= old_ity_size {
913-
assert_eq!(*i, old_ity_size);
914-
*i = new_ity_size;
915-
}
916-
}
917-
// We might be making the struct larger.
918-
if variant.size <= old_ity_size {
919-
variant.size = new_ity_size;
920-
}
921-
}
922-
FieldsShape::Primitive | FieldsShape::Array { .. } | FieldsShape::Union(..) => {
923-
panic!("encountered a non-arbitrary layout during enum layout")
906+
for i in &mut variant.field_offsets {
907+
if *i <= old_ity_size {
908+
assert_eq!(*i, old_ity_size);
909+
*i = new_ity_size;
924910
}
925911
}
912+
// We might be making the struct larger.
913+
if variant.size <= old_ity_size {
914+
variant.size = new_ity_size;
915+
}
926916
}
927917
}
928918

@@ -947,12 +937,10 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
947937
let mut common_prim = None;
948938
let mut common_prim_initialized_in_all_variants = true;
949939
for (field_layouts, layout_variant) in iter::zip(variants, &layout_variants) {
950-
let FieldsShape::Arbitrary { ref offsets, .. } = layout_variant.fields else {
951-
panic!("encountered a non-arbitrary layout during enum layout");
952-
};
953940
// We skip *all* ZST here and later check if we are good in terms of alignment.
954941
// This lets us handle some cases involving aligned ZST.
955-
let mut fields = iter::zip(field_layouts, offsets).filter(|p| !p.0.is_zst());
942+
let mut fields = iter::zip(field_layouts, &layout_variant.field_offsets)
943+
.filter(|p| !p.0.is_zst());
956944
let (field, offset) = match (fields.next(), fields.next()) {
957945
(None, None) => {
958946
common_prim_initialized_in_all_variants = false;
@@ -1047,25 +1035,17 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
10471035
for variant in &mut layout_variants {
10481036
// We only do this for variants with fields; the others are not accessed anyway.
10491037
// Also do not overwrite any already existing "clever" ABIs.
1050-
if variant.fields.count() > 0
1051-
&& matches!(variant.backend_repr, BackendRepr::Memory { .. })
1038+
if matches!(variant.backend_repr, BackendRepr::Memory { .. } if variant.has_fields())
10521039
{
10531040
variant.backend_repr = abi;
1054-
// Also need to bump up the size and alignment, so that the entire value fits
1055-
// in here.
1041+
// Also need to bump up the size, so that the entire value fits in here.
10561042
variant.size = cmp::max(variant.size, size);
1057-
variant.align.abi = cmp::max(variant.align.abi, align);
10581043
}
10591044
}
10601045
}
10611046

10621047
let largest_niche = Niche::from_scalar(dl, Size::ZERO, tag);
10631048

1064-
let combined_seed = layout_variants
1065-
.iter()
1066-
.map(|v| v.randomization_seed)
1067-
.fold(repr.field_shuffle_seed, |acc, seed| acc.wrapping_add(seed));
1068-
10691049
let tagged_layout = LayoutData {
10701050
variants: Variants::Multiple {
10711051
tag,

compiler/rustc_abi/src/layout/coroutine.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ use tracing::{debug, trace};
2727

2828
use crate::{
2929
BackendRepr, FieldsShape, HasDataLayout, Integer, LayoutData, Primitive, ReprOptions, Scalar,
30-
StructKind, TagEncoding, Variants, WrappingRange,
30+
StructKind, TagEncoding, VariantLayout, Variants, WrappingRange,
3131
};
3232

3333
/// Overlap eligibility and variant assignment for each CoroutineSavedLocal.
@@ -230,7 +230,6 @@ pub(super) fn layout<
230230
&ReprOptions::default(),
231231
StructKind::Prefixed(prefix_size, prefix_align.abi),
232232
)?;
233-
variant.variants = Variants::Single { index };
234233

235234
let FieldsShape::Arbitrary { offsets, in_memory_order } = variant.fields else {
236235
unreachable!();
@@ -281,7 +280,7 @@ pub(super) fn layout<
281280

282281
size = size.max(variant.size);
283282
align = align.max(variant.align);
284-
Ok(variant)
283+
Ok(VariantLayout::from_layout(variant))
285284
})
286285
.collect::<Result<IndexVec<VariantIdx, _>, _>>()?;
287286

compiler/rustc_abi/src/layout/simple.rs

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,34 @@ impl<FieldIdx: Idx, VariantIdx: Idx> LayoutData<FieldIdx, VariantIdx> {
143143
size: Size::ZERO,
144144
max_repr_align: None,
145145
unadjusted_abi_align: dl.i8_align,
146+
// Variant layouts never flow back into actual layout computations,
147+
// so dummy values are fine here.
148+
randomization_seed: Hash64::ZERO,
149+
}
150+
}
151+
152+
/// Returns a layout for an inhabited variant.
153+
pub fn for_variant(parent: &Self, index: VariantIdx) -> Self {
154+
let layout = match &parent.variants {
155+
Variants::Multiple { variants, .. } => &variants[index],
156+
_ => panic!("Expected multi-variant layout in `Layout::for_variant`"),
157+
};
158+
159+
Self {
160+
fields: FieldsShape::Arbitrary {
161+
offsets: layout.field_offsets.clone(),
162+
in_memory_order: layout.fields_in_memory_order.clone(),
163+
},
164+
variants: Variants::Single { index },
165+
backend_repr: layout.backend_repr,
166+
largest_niche: layout.largest_niche,
167+
uninhabited: layout.uninhabited,
168+
size: layout.size,
169+
align: parent.align,
170+
max_repr_align: parent.max_repr_align,
171+
unadjusted_abi_align: parent.unadjusted_abi_align,
172+
// Variant layouts never flow back into actual layout computations,
173+
// so dummy values are fine here.
146174
randomization_seed: Hash64::ZERO,
147175
}
148176
}

compiler/rustc_abi/src/lib.rs

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1953,7 +1953,7 @@ pub enum Variants<FieldIdx: Idx, VariantIdx: Idx> {
19531953
tag: Scalar,
19541954
tag_encoding: TagEncoding<VariantIdx>,
19551955
tag_field: FieldIdx,
1956-
variants: IndexVec<VariantIdx, LayoutData<FieldIdx, VariantIdx>>,
1956+
variants: IndexVec<VariantIdx, VariantLayout<FieldIdx>>,
19571957
},
19581958
}
19591959

@@ -2319,3 +2319,40 @@ pub enum AbiFromStrErr {
23192319
/// no "-unwind" variant can be used here
23202320
NoExplicitUnwind,
23212321
}
2322+
2323+
// NOTE: This struct is generic over the FieldIdx and VariantIdx for rust-analyzer usage.
2324+
#[derive(PartialEq, Eq, Hash, Clone, Debug)]
2325+
#[cfg_attr(feature = "nightly", derive(StableHash))]
2326+
pub struct VariantLayout<FieldIdx: Idx> {
2327+
pub size: Size,
2328+
pub backend_repr: BackendRepr,
2329+
pub field_offsets: IndexVec<FieldIdx, Size>,
2330+
fields_in_memory_order: IndexVec<u32, FieldIdx>,
2331+
largest_niche: Option<Niche>,
2332+
uninhabited: bool,
2333+
}
2334+
2335+
impl<FieldIdx: Idx> VariantLayout<FieldIdx> {
2336+
pub fn from_layout(layout: LayoutData<FieldIdx, impl Idx>) -> Self {
2337+
let FieldsShape::Arbitrary { offsets, in_memory_order } = layout.fields else {
2338+
panic!("Layout of fields should be Arbitrary for variants");
2339+
};
2340+
2341+
Self {
2342+
size: layout.size,
2343+
backend_repr: layout.backend_repr,
2344+
field_offsets: offsets,
2345+
fields_in_memory_order: in_memory_order,
2346+
largest_niche: layout.largest_niche,
2347+
uninhabited: layout.uninhabited,
2348+
}
2349+
}
2350+
2351+
pub fn is_uninhabited(&self) -> bool {
2352+
self.uninhabited
2353+
}
2354+
2355+
pub fn has_fields(&self) -> bool {
2356+
self.field_offsets.len() > 0
2357+
}
2358+
}

compiler/rustc_codegen_gcc/src/intrinsic/mod.rs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ use std::iter;
66

77
use gccjit::{ComparisonOp, Function, FunctionType, RValue, ToRValue, Type, UnaryOp};
88
use rustc_abi::{BackendRepr, HasDataLayout, WrappingRange};
9-
use rustc_codegen_ssa::MemFlags;
109
use rustc_codegen_ssa::base::wants_msvc_seh;
1110
use rustc_codegen_ssa::common::IntPredicate;
1211
use rustc_codegen_ssa::errors::InvalidMonomorphization;
@@ -18,6 +17,7 @@ use rustc_codegen_ssa::traits::{
1817
ArgAbiBuilderMethods, BaseTypeCodegenMethods, BuilderMethods, ConstCodegenMethods,
1918
IntrinsicCallBuilderMethods, LayoutTypeCodegenMethods,
2019
};
20+
use rustc_codegen_ssa::{MemFlags, RetagInfo};
2121
use rustc_data_structures::fx::FxHashSet;
2222
#[cfg(feature = "master")]
2323
use rustc_middle::ty::layout::FnAbiOf;
@@ -702,6 +702,14 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tc
702702
// FIXME(antoyo): implement.
703703
self.context.new_rvalue_from_int(self.int_type, 0)
704704
}
705+
706+
fn retag_reg(&mut self, _ptr: Self::Value, _info: &RetagInfo<Self::Value>) -> Self::Value {
707+
unimplemented!()
708+
}
709+
710+
fn retag_mem(&mut self, _ptr: Self::Value, _info: &RetagInfo<Self::Value>) {
711+
unimplemented!()
712+
}
705713
}
706714

707715
impl<'a, 'gcc, 'tcx> ArgAbiBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tcx> {

0 commit comments

Comments
 (0)