From a4bd5f55e7f93baca5ffc398a429a0039517a318 Mon Sep 17 00:00:00 2001 From: thiago-fealves Date: Sun, 3 May 2026 18:47:34 -0300 Subject: [PATCH 01/29] compiler: suggest `.collect()` when `String` is expected and `Iterator` is found This commit adds a diagnostic suggestion to help users who forget to call `.collect()` when they have an iterator and the function or variable expects a `String`. The logic checks if the expected type is `std::string::String` and if the found type implements the `Iterator` trait, if so the compiler provides a suggestion to add `.collect()` Includes also a UI test to verify if the suggestion appears correctly --- compiler/rustc_hir_typeck/src/demand.rs | 1 + .../src/fn_ctxt/suggestions.rs | 72 +++++++++++++++++++ tests/ui/suggestions/suggest-collect.rs | 16 +++++ tests/ui/suggestions/suggest-collect.stderr | 63 ++++++++++++++++ 4 files changed, 152 insertions(+) create mode 100644 tests/ui/suggestions/suggest-collect.rs create mode 100644 tests/ui/suggestions/suggest-collect.stderr diff --git a/compiler/rustc_hir_typeck/src/demand.rs b/compiler/rustc_hir_typeck/src/demand.rs index 5454b282d5226..6e4d6aa80a63a 100644 --- a/compiler/rustc_hir_typeck/src/demand.rs +++ b/compiler/rustc_hir_typeck/src/demand.rs @@ -40,6 +40,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { || self.suggest_semicolon_in_repeat_expr(err, expr, expr_ty) || self.suggest_deref_ref_or_into(err, expr, expected, expr_ty, expected_ty_expr) || self.suggest_option_to_bool(err, expr, expr_ty, expected) + || self.suggest_collect(err, expr, expected, expr_ty) || self.suggest_compatible_variants(err, expr, expected, expr_ty) || self.suggest_non_zero_new_unwrap(err, expr, expected, expr_ty) || self.suggest_calling_boxed_future_when_appropriate(err, expr, expected, expr_ty) diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs index afd5356d5a1e7..1ce004e11e996 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs @@ -250,6 +250,78 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } } + /// Suggests calling `.collect()` on an `Iterator` it can be collected in the return type + /// ```compile_fail + /// let x: String = "foo".chars().map(|c| c); // with a .collect() here the code compiles + /// ``` + pub(crate) fn suggest_collect( + &self, + err: &mut Diag<'_>, + expr: &hir::Expr<'_>, + expected_type: Ty<'tcx>, + found_type: Ty<'tcx>, + ) -> bool { + let tcx = self.tcx; + let expected = self.resolve_vars_if_possible(expected_type); + let found = self.resolve_vars_if_possible(found_type); + + if expected.references_error() || found.references_error() { + return false; + } + + if expected.is_unit() { + return false; + } + + let Some(iterator_trait_id) = tcx.get_diagnostic_item(sym::Iterator) else { + return false; + }; + + if !self + .infcx + .type_implements_trait(iterator_trait_id, [found], self.param_env) + .must_apply_modulo_regions() + { + return false; + } + + let Some(from_iterator_trait_id) = tcx.get_diagnostic_item(sym::FromIterator) else { + return false; + }; + + let Some(iterator_item_id) = tcx + .associated_items(iterator_trait_id) + .in_definition_order() + .find(|item| item.name() == sym::Item) + .map(|item| item.def_id) + else { + return false; + }; + + let item_type = Ty::new_projection(tcx, iterator_item_id, [found]); + let item_type = + self.normalize(expr.span, rustc_middle::ty::Unnormalized::new_wip(item_type)); + + let can_collect = self + .infcx + .type_implements_trait(from_iterator_trait_id, [expected, item_type], self.param_env) + .may_apply(); + + if can_collect { + err.span_suggestion_verbose( + expr.span.shrink_to_hi(), + format!( + "consider using `.collect()` to convert the `Iterator` into a `{expected}`" + ), + ".collect()", + rustc_errors::Applicability::MaybeIncorrect, + ); + return true; + } + + false + } + pub(crate) fn suggest_remove_last_method_call( &self, err: &mut Diag<'_>, diff --git a/tests/ui/suggestions/suggest-collect.rs b/tests/ui/suggestions/suggest-collect.rs new file mode 100644 index 0000000000000..44e8909fca20f --- /dev/null +++ b/tests/ui/suggestions/suggest-collect.rs @@ -0,0 +1,16 @@ +fn main() { + let _x: String = "hello".chars().map(|c| c); + //~^ ERROR mismatched types + //~| HELP consider using `.collect()` to convert the `Iterator` into a `String` + + let _y: Vec = vec![1, 2, 3].into_iter().map(|x| x); + //~^ ERROR mismatched types + //~| HELP consider using `.collect()` to convert the `Iterator` into a `Vec` + + let res: Result, _> = ["1", "2"].into_iter().map(|s| s.parse::()); + //~^ ERROR mismatched types + //~| HELP consider using `.collect()` to convert the `Iterator` into a `Result, _>` + let (a, b): (Vec, Vec) = vec![1, 2].into_iter().map(|x| (x, x)); + //~^ ERROR mismatched types + //~| HELP consider using `.collect()` to convert the `Iterator` into a `(Vec, Vec)` +} diff --git a/tests/ui/suggestions/suggest-collect.stderr b/tests/ui/suggestions/suggest-collect.stderr new file mode 100644 index 0000000000000..a7bca2bbcaa7b --- /dev/null +++ b/tests/ui/suggestions/suggest-collect.stderr @@ -0,0 +1,63 @@ +error[E0308]: mismatched types + --> $DIR/suggest-collect.rs:2:22 + | +LL | let _x: String = "hello".chars().map(|c| c); + | ------ ^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `String`, found `Map, {closure@...}>` + | | + | expected due to this + | + = note: expected struct `String` + found struct `Map, {closure@$DIR/suggest-collect.rs:2:42: 2:45}>` +help: consider using `.collect()` to convert the `Iterator` into a `String` + | +LL | let _x: String = "hello".chars().map(|c| c).collect(); + | ++++++++++ + +error[E0308]: mismatched types + --> $DIR/suggest-collect.rs:6:24 + | +LL | let _y: Vec = vec![1, 2, 3].into_iter().map(|x| x); + | -------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `Vec`, found `Map, {closure@...}>` + | | + | expected due to this + | + = note: expected struct `Vec` + found struct `Map, {closure@$DIR/suggest-collect.rs:6:54: 6:57}>` +help: consider using `.collect()` to convert the `Iterator` into a `Vec` + | +LL | let _y: Vec = vec![1, 2, 3].into_iter().map(|x| x).collect(); + | ++++++++++ + +error[E0308]: mismatched types + --> $DIR/suggest-collect.rs:10:36 + | +LL | let res: Result, _> = ["1", "2"].into_iter().map(|s| s.parse::()); + | ------------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `Result, _>`, found `Map, {closure@...}>` + | | + | expected due to this + | + = note: expected enum `Result, _>` + found struct `Map, {closure@$DIR/suggest-collect.rs:10:63: 10:66}>` +help: consider using `.collect()` to convert the `Iterator` into a `Result, _>` + | +LL | let res: Result, _> = ["1", "2"].into_iter().map(|s| s.parse::()).collect(); + | ++++++++++ + +error[E0308]: mismatched types + --> $DIR/suggest-collect.rs:13:40 + | +LL | let (a, b): (Vec, Vec) = vec![1, 2].into_iter().map(|x| (x, x)); + | -------------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `(Vec, Vec)`, found `Map, {closure@...}>` + | | + | expected due to this + | + = note: expected tuple `(Vec, Vec)` + found struct `Map, {closure@$DIR/suggest-collect.rs:13:67: 13:70}>` +help: consider using `.collect()` to convert the `Iterator` into a `(Vec, Vec)` + | +LL | let (a, b): (Vec, Vec) = vec![1, 2].into_iter().map(|x| (x, x)).collect(); + | ++++++++++ + +error: aborting due to 4 previous errors + +For more information about this error, try `rustc --explain E0308`. From e1941ffee672efea442b269011d6b40be6dbbff9 Mon Sep 17 00:00:00 2001 From: Thiago Felipe Alves do Carmo <63806038+thiago-fealves@users.noreply.github.com> Date: Mon, 4 May 2026 15:47:45 +0000 Subject: [PATCH 02/29] Update compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs Co-authored-by: Qai Juang --- compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs index 1ce004e11e996..77aa9fb3daab8 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs @@ -265,11 +265,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let expected = self.resolve_vars_if_possible(expected_type); let found = self.resolve_vars_if_possible(found_type); - if expected.references_error() || found.references_error() { - return false; - } - - if expected.is_unit() { + if expected.references_error() || found.references_error() || expected.is_unit() { return false; } From 464dc07de29d58e60ec3a0a9502fa365ab3123bd Mon Sep 17 00:00:00 2001 From: Moulins Date: Wed, 17 Dec 2025 21:33:34 +0100 Subject: [PATCH 03/29] Introduce `VariantLayout` struct For now, this is a 1-to-1 copy of `LayoutData`, but this will change. --- compiler/rustc_abi/src/layout.rs | 6 +-- compiler/rustc_abi/src/layout/coroutine.rs | 4 +- compiler/rustc_abi/src/layout/simple.rs | 21 ++++++++++ compiler/rustc_abi/src/lib.rs | 39 ++++++++++++++++++- compiler/rustc_middle/src/ty/layout.rs | 4 +- src/librustdoc/html/render/type_layout.rs | 2 +- .../enum-discriminant/wrapping_niche.stderr | 12 +++--- tests/ui/layout/debug.stderr | 16 ++++---- tests/ui/layout/hexagon-enum.stderr | 10 ++--- ...-scalarpair-payload-might-be-uninit.stderr | 24 ++++++------ .../issue-96185-overaligned-enum.stderr | 8 ++-- tests/ui/layout/thumb-enum.stderr | 10 ++--- .../layout/zero-sized-array-enum-niche.stderr | 18 ++++----- ...-variants.aarch64-unknown-linux-gnu.stderr | 10 ++--- ...-c-dead-variants.armebv7r-none-eabi.stderr | 10 ++--- ...-dead-variants.i686-pc-windows-msvc.stderr | 10 ++--- ...d-variants.x86_64-unknown-linux-gnu.stderr | 10 ++--- tests/ui/repr/repr-c-int-dead-variants.stderr | 10 ++--- tests/ui/type/pattern_types/non_null.stderr | 4 +- .../type/pattern_types/range_patterns.stderr | 8 ++-- 20 files changed, 147 insertions(+), 89 deletions(-) diff --git a/compiler/rustc_abi/src/layout.rs b/compiler/rustc_abi/src/layout.rs index 2a2765a436bb5..a82ff1aba9b22 100644 --- a/compiler/rustc_abi/src/layout.rs +++ b/compiler/rustc_abi/src/layout.rs @@ -11,7 +11,7 @@ use tracing::{debug, trace}; use crate::{ AbiAlign, Align, BackendRepr, FieldsShape, HasDataLayout, IndexSlice, IndexVec, Integer, LayoutData, Niche, NonZeroUsize, NumScalableVectors, Primitive, ReprOptions, Scalar, Size, - StructKind, TagEncoding, TargetDataLayout, Variants, WrappingRange, + StructKind, TagEncoding, TargetDataLayout, VariantLayout, Variants, WrappingRange, }; mod coroutine; @@ -611,7 +611,7 @@ impl LayoutCalculator { max_repr_align = max_repr_align.max(st.max_repr_align); unadjusted_abi_align = unadjusted_abi_align.max(st.unadjusted_abi_align); - Some(st) + Some(VariantLayout::from_layout(st)) }) .collect::>>()?; @@ -851,7 +851,7 @@ impl LayoutCalculator { align = align.max(st.align.abi); max_repr_align = max_repr_align.max(st.max_repr_align); unadjusted_abi_align = unadjusted_abi_align.max(st.unadjusted_abi_align); - Ok(st) + Ok(VariantLayout::from_layout(st)) }) .collect::, _>>()?; diff --git a/compiler/rustc_abi/src/layout/coroutine.rs b/compiler/rustc_abi/src/layout/coroutine.rs index 815cf1e28a08c..812ed1f4274fd 100644 --- a/compiler/rustc_abi/src/layout/coroutine.rs +++ b/compiler/rustc_abi/src/layout/coroutine.rs @@ -27,7 +27,7 @@ use tracing::{debug, trace}; use crate::{ BackendRepr, FieldsShape, HasDataLayout, Integer, LayoutData, Primitive, ReprOptions, Scalar, - StructKind, TagEncoding, Variants, WrappingRange, + StructKind, TagEncoding, VariantLayout, Variants, WrappingRange, }; /// Overlap eligibility and variant assignment for each CoroutineSavedLocal. @@ -281,7 +281,7 @@ pub(super) fn layout< size = size.max(variant.size); align = align.max(variant.align); - Ok(variant) + Ok(VariantLayout::from_layout(variant)) }) .collect::, _>>()?; diff --git a/compiler/rustc_abi/src/layout/simple.rs b/compiler/rustc_abi/src/layout/simple.rs index 3784611b157be..cb584d7cf5788 100644 --- a/compiler/rustc_abi/src/layout/simple.rs +++ b/compiler/rustc_abi/src/layout/simple.rs @@ -146,4 +146,25 @@ impl LayoutData { randomization_seed: Hash64::ZERO, } } + + /// Returns a layout for an inhabited variant. + pub fn for_variant(parent: &Self, index: VariantIdx) -> Self { + let layout = match &parent.variants { + Variants::Multiple { variants, .. } => &variants[index], + _ => panic!("Expected multi-variant layout in `Layout::for_variant`"), + }; + + Self { + fields: layout.fields.clone(), + variants: layout.variants.clone(), + backend_repr: layout.backend_repr, + largest_niche: layout.largest_niche, + uninhabited: layout.uninhabited, + align: layout.align, + size: layout.size, + max_repr_align: layout.max_repr_align, + unadjusted_abi_align: layout.unadjusted_abi_align, + randomization_seed: layout.randomization_seed, + } + } } diff --git a/compiler/rustc_abi/src/lib.rs b/compiler/rustc_abi/src/lib.rs index c63575704de17..7ec68bd2b275b 100644 --- a/compiler/rustc_abi/src/lib.rs +++ b/compiler/rustc_abi/src/lib.rs @@ -1953,7 +1953,7 @@ pub enum Variants { tag: Scalar, tag_encoding: TagEncoding, tag_field: FieldIdx, - variants: IndexVec>, + variants: IndexVec>, }, } @@ -2319,3 +2319,40 @@ pub enum AbiFromStrErr { /// no "-unwind" variant can be used here NoExplicitUnwind, } + +// NOTE: This struct is generic over the FieldIdx and VariantIdx for rust-analyzer usage. +#[derive(PartialEq, Eq, Hash, Clone, Debug)] +#[cfg_attr(feature = "nightly", derive(StableHash))] +pub struct VariantLayout { + pub size: Size, + pub align: AbiAlign, + pub backend_repr: BackendRepr, + pub fields: FieldsShape, + largest_niche: Option, + uninhabited: bool, + pub variants: Variants, + max_repr_align: Option, + unadjusted_abi_align: Align, + randomization_seed: Hash64, +} + +impl VariantLayout { + pub fn from_layout(layout: LayoutData) -> Self { + Self { + size: layout.size, + align: layout.align, + backend_repr: layout.backend_repr, + fields: layout.fields, + largest_niche: layout.largest_niche, + uninhabited: layout.uninhabited, + variants: layout.variants, + max_repr_align: layout.max_repr_align, + unadjusted_abi_align: layout.unadjusted_abi_align, + randomization_seed: layout.randomization_seed, + } + } + + pub fn is_uninhabited(&self) -> bool { + self.uninhabited + } +} diff --git a/compiler/rustc_middle/src/ty/layout.rs b/compiler/rustc_middle/src/ty/layout.rs index e2fc663852374..168aa5e9b0219 100644 --- a/compiler/rustc_middle/src/ty/layout.rs +++ b/compiler/rustc_middle/src/ty/layout.rs @@ -781,8 +781,8 @@ where tcx.mk_layout(LayoutData::uninhabited_variant(cx, variant_index, fields)) } - Variants::Multiple { ref variants, .. } => { - cx.tcx().mk_layout(variants[variant_index].clone()) + Variants::Multiple { .. } => { + cx.tcx().mk_layout(LayoutData::for_variant(&this, variant_index)) } }; diff --git a/src/librustdoc/html/render/type_layout.rs b/src/librustdoc/html/render/type_layout.rs index e17058c4ca80c..c3a8582deaeee 100644 --- a/src/librustdoc/html/render/type_layout.rs +++ b/src/librustdoc/html/render/type_layout.rs @@ -54,7 +54,7 @@ pub(crate) fn document_type_layout(cx: &Context<'_>, ty_def_id: DefId) -> impl f span_bug!(tcx.def_span(ty_def_id), "not an adt") }; let name = adt.variant(variant_idx).name; - let is_unsized = variant_layout.is_unsized(); + let is_unsized = variant_layout.backend_repr.is_unsized(); let is_uninhabited = variant_layout.is_uninhabited(); let size = variant_layout.size.bytes() - tag_size; let type_layout_size = TypeLayoutSize { is_unsized, is_uninhabited, size }; diff --git a/tests/ui/enum-discriminant/wrapping_niche.stderr b/tests/ui/enum-discriminant/wrapping_niche.stderr index 9b97ad4aeac7e..b130d022ea922 100644 --- a/tests/ui/enum-discriminant/wrapping_niche.stderr +++ b/tests/ui/enum-discriminant/wrapping_niche.stderr @@ -42,7 +42,7 @@ error: layout_of(UnsignedAroundZero) = Layout { tag_encoding: Direct, tag_field: 0, variants: [ - Layout { + VariantLayout { size: Size(2 bytes), align: AbiAlign { abi: Align(2 bytes), @@ -63,7 +63,7 @@ error: layout_of(UnsignedAroundZero) = Layout { unadjusted_abi_align: Align(2 bytes), randomization_seed: 9885373149222004003, }, - Layout { + VariantLayout { size: Size(2 bytes), align: AbiAlign { abi: Align(2 bytes), @@ -84,7 +84,7 @@ error: layout_of(UnsignedAroundZero) = Layout { unadjusted_abi_align: Align(2 bytes), randomization_seed: 9885373149222004003, }, - Layout { + VariantLayout { size: Size(2 bytes), align: AbiAlign { abi: Align(2 bytes), @@ -160,7 +160,7 @@ error: layout_of(SignedAroundZero) = Layout { tag_encoding: Direct, tag_field: 0, variants: [ - Layout { + VariantLayout { size: Size(2 bytes), align: AbiAlign { abi: Align(2 bytes), @@ -181,7 +181,7 @@ error: layout_of(SignedAroundZero) = Layout { unadjusted_abi_align: Align(2 bytes), randomization_seed: 2684536712112553499, }, - Layout { + VariantLayout { size: Size(2 bytes), align: AbiAlign { abi: Align(2 bytes), @@ -202,7 +202,7 @@ error: layout_of(SignedAroundZero) = Layout { unadjusted_abi_align: Align(2 bytes), randomization_seed: 2684536712112553499, }, - Layout { + VariantLayout { size: Size(2 bytes), align: AbiAlign { abi: Align(2 bytes), diff --git a/tests/ui/layout/debug.stderr b/tests/ui/layout/debug.stderr index bfd2f7ec95da1..c4b1b560f9590 100644 --- a/tests/ui/layout/debug.stderr +++ b/tests/ui/layout/debug.stderr @@ -58,7 +58,7 @@ error: layout_of(E) = Layout { tag_encoding: Direct, tag_field: 0, variants: [ - Layout { + VariantLayout { size: Size(4 bytes), align: AbiAlign { abi: Align(1 bytes), @@ -79,7 +79,7 @@ error: layout_of(E) = Layout { unadjusted_abi_align: Align(1 bytes), randomization_seed: $SEED, }, - Layout { + VariantLayout { size: Size(12 bytes), align: AbiAlign { abi: Align(4 bytes), @@ -242,7 +242,7 @@ error: layout_of(Result) = Layout { tag_encoding: Direct, tag_field: 0, variants: [ - Layout { + VariantLayout { size: Size(8 bytes), align: AbiAlign { abi: Align(4 bytes), @@ -280,7 +280,7 @@ error: layout_of(Result) = Layout { unadjusted_abi_align: Align(4 bytes), randomization_seed: $SEED, }, - Layout { + VariantLayout { size: Size(8 bytes), align: AbiAlign { abi: Align(4 bytes), @@ -662,7 +662,7 @@ error: layout_of(Option) = Layout { }, tag_field: 0, variants: [ - Layout { + VariantLayout { size: Size(0 bytes), align: AbiAlign { abi: Align(1 bytes), @@ -683,7 +683,7 @@ error: layout_of(Option) = Layout { unadjusted_abi_align: Align(1 bytes), randomization_seed: $SEED, }, - Layout { + VariantLayout { size: Size(1 bytes), align: AbiAlign { abi: Align(1 bytes), @@ -782,7 +782,7 @@ error: layout_of(Option) = Layout { }, tag_field: 0, variants: [ - Layout { + VariantLayout { size: Size(0 bytes), align: AbiAlign { abi: Align(1 bytes), @@ -803,7 +803,7 @@ error: layout_of(Option) = Layout { unadjusted_abi_align: Align(1 bytes), randomization_seed: $SEED, }, - Layout { + VariantLayout { size: Size(4 bytes), align: AbiAlign { abi: Align(4 bytes), diff --git a/tests/ui/layout/hexagon-enum.stderr b/tests/ui/layout/hexagon-enum.stderr index 20e0a8642a66f..e2f888a9dd860 100644 --- a/tests/ui/layout/hexagon-enum.stderr +++ b/tests/ui/layout/hexagon-enum.stderr @@ -42,7 +42,7 @@ error: layout_of(A) = Layout { tag_encoding: Direct, tag_field: 0, variants: [ - Layout { + VariantLayout { size: Size(1 bytes), align: AbiAlign { abi: Align(1 bytes), @@ -118,7 +118,7 @@ error: layout_of(B) = Layout { tag_encoding: Direct, tag_field: 0, variants: [ - Layout { + VariantLayout { size: Size(1 bytes), align: AbiAlign { abi: Align(1 bytes), @@ -194,7 +194,7 @@ error: layout_of(C) = Layout { tag_encoding: Direct, tag_field: 0, variants: [ - Layout { + VariantLayout { size: Size(2 bytes), align: AbiAlign { abi: Align(2 bytes), @@ -270,7 +270,7 @@ error: layout_of(P) = Layout { tag_encoding: Direct, tag_field: 0, variants: [ - Layout { + VariantLayout { size: Size(4 bytes), align: AbiAlign { abi: Align(4 bytes), @@ -346,7 +346,7 @@ error: layout_of(T) = Layout { tag_encoding: Direct, tag_field: 0, variants: [ - Layout { + VariantLayout { size: Size(4 bytes), align: AbiAlign { abi: Align(4 bytes), diff --git a/tests/ui/layout/issue-96158-scalarpair-payload-might-be-uninit.stderr b/tests/ui/layout/issue-96158-scalarpair-payload-might-be-uninit.stderr index 61cfcbdc07f75..bcb38889bded8 100644 --- a/tests/ui/layout/issue-96158-scalarpair-payload-might-be-uninit.stderr +++ b/tests/ui/layout/issue-96158-scalarpair-payload-might-be-uninit.stderr @@ -48,7 +48,7 @@ error: layout_of(MissingPayloadField) = Layout { tag_encoding: Direct, tag_field: 0, variants: [ - Layout { + VariantLayout { size: Size(2 bytes), align: AbiAlign { abi: Align(1 bytes), @@ -85,7 +85,7 @@ error: layout_of(MissingPayloadField) = Layout { unadjusted_abi_align: Align(1 bytes), randomization_seed: $SEED, }, - Layout { + VariantLayout { size: Size(1 bytes), align: AbiAlign { abi: Align(1 bytes), @@ -168,7 +168,7 @@ error: layout_of(CommonPayloadField) = Layout { tag_encoding: Direct, tag_field: 0, variants: [ - Layout { + VariantLayout { size: Size(2 bytes), align: AbiAlign { abi: Align(1 bytes), @@ -206,7 +206,7 @@ error: layout_of(CommonPayloadField) = Layout { unadjusted_abi_align: Align(1 bytes), randomization_seed: $SEED, }, - Layout { + VariantLayout { size: Size(2 bytes), align: AbiAlign { abi: Align(1 bytes), @@ -305,7 +305,7 @@ error: layout_of(CommonPayloadFieldIsMaybeUninit) = Layout { tag_encoding: Direct, tag_field: 0, variants: [ - Layout { + VariantLayout { size: Size(2 bytes), align: AbiAlign { abi: Align(1 bytes), @@ -342,7 +342,7 @@ error: layout_of(CommonPayloadFieldIsMaybeUninit) = Layout { unadjusted_abi_align: Align(1 bytes), randomization_seed: $SEED, }, - Layout { + VariantLayout { size: Size(2 bytes), align: AbiAlign { abi: Align(1 bytes), @@ -444,7 +444,7 @@ error: layout_of(NicheFirst) = Layout { }, tag_field: 0, variants: [ - Layout { + VariantLayout { size: Size(2 bytes), align: AbiAlign { abi: Align(1 bytes), @@ -493,7 +493,7 @@ error: layout_of(NicheFirst) = Layout { unadjusted_abi_align: Align(1 bytes), randomization_seed: $SEED, }, - Layout { + VariantLayout { size: Size(0 bytes), align: AbiAlign { abi: Align(1 bytes), @@ -514,7 +514,7 @@ error: layout_of(NicheFirst) = Layout { unadjusted_abi_align: Align(1 bytes), randomization_seed: $SEED, }, - Layout { + VariantLayout { size: Size(0 bytes), align: AbiAlign { abi: Align(1 bytes), @@ -600,7 +600,7 @@ error: layout_of(NicheSecond) = Layout { }, tag_field: 0, variants: [ - Layout { + VariantLayout { size: Size(2 bytes), align: AbiAlign { abi: Align(1 bytes), @@ -649,7 +649,7 @@ error: layout_of(NicheSecond) = Layout { unadjusted_abi_align: Align(1 bytes), randomization_seed: $SEED, }, - Layout { + VariantLayout { size: Size(0 bytes), align: AbiAlign { abi: Align(1 bytes), @@ -670,7 +670,7 @@ error: layout_of(NicheSecond) = Layout { unadjusted_abi_align: Align(1 bytes), randomization_seed: $SEED, }, - Layout { + VariantLayout { size: Size(0 bytes), align: AbiAlign { abi: Align(1 bytes), diff --git a/tests/ui/layout/issue-96185-overaligned-enum.stderr b/tests/ui/layout/issue-96185-overaligned-enum.stderr index 64e2f42c042f1..20607303599ec 100644 --- a/tests/ui/layout/issue-96185-overaligned-enum.stderr +++ b/tests/ui/layout/issue-96185-overaligned-enum.stderr @@ -36,7 +36,7 @@ error: layout_of(Aligned1) = Layout { tag_encoding: Direct, tag_field: 0, variants: [ - Layout { + VariantLayout { size: Size(8 bytes), align: AbiAlign { abi: Align(8 bytes), @@ -59,7 +59,7 @@ error: layout_of(Aligned1) = Layout { unadjusted_abi_align: Align(1 bytes), randomization_seed: $SEED, }, - Layout { + VariantLayout { size: Size(8 bytes), align: AbiAlign { abi: Align(8 bytes), @@ -139,7 +139,7 @@ error: layout_of(Aligned2) = Layout { tag_encoding: Direct, tag_field: 0, variants: [ - Layout { + VariantLayout { size: Size(1 bytes), align: AbiAlign { abi: Align(1 bytes), @@ -162,7 +162,7 @@ error: layout_of(Aligned2) = Layout { unadjusted_abi_align: Align(1 bytes), randomization_seed: $SEED, }, - Layout { + VariantLayout { size: Size(1 bytes), align: AbiAlign { abi: Align(1 bytes), diff --git a/tests/ui/layout/thumb-enum.stderr b/tests/ui/layout/thumb-enum.stderr index a6e603652123b..07be46db6ed85 100644 --- a/tests/ui/layout/thumb-enum.stderr +++ b/tests/ui/layout/thumb-enum.stderr @@ -42,7 +42,7 @@ error: layout_of(A) = Layout { tag_encoding: Direct, tag_field: 0, variants: [ - Layout { + VariantLayout { size: Size(1 bytes), align: AbiAlign { abi: Align(1 bytes), @@ -118,7 +118,7 @@ error: layout_of(B) = Layout { tag_encoding: Direct, tag_field: 0, variants: [ - Layout { + VariantLayout { size: Size(1 bytes), align: AbiAlign { abi: Align(1 bytes), @@ -194,7 +194,7 @@ error: layout_of(C) = Layout { tag_encoding: Direct, tag_field: 0, variants: [ - Layout { + VariantLayout { size: Size(2 bytes), align: AbiAlign { abi: Align(2 bytes), @@ -270,7 +270,7 @@ error: layout_of(P) = Layout { tag_encoding: Direct, tag_field: 0, variants: [ - Layout { + VariantLayout { size: Size(4 bytes), align: AbiAlign { abi: Align(4 bytes), @@ -346,7 +346,7 @@ error: layout_of(T) = Layout { tag_encoding: Direct, tag_field: 0, variants: [ - Layout { + VariantLayout { size: Size(4 bytes), align: AbiAlign { abi: Align(4 bytes), diff --git a/tests/ui/layout/zero-sized-array-enum-niche.stderr b/tests/ui/layout/zero-sized-array-enum-niche.stderr index a29586f3bb2fa..ddbcf97dfa4d1 100644 --- a/tests/ui/layout/zero-sized-array-enum-niche.stderr +++ b/tests/ui/layout/zero-sized-array-enum-niche.stderr @@ -36,7 +36,7 @@ error: layout_of(Result<[u32; 0], bool>) = Layout { tag_encoding: Direct, tag_field: 0, variants: [ - Layout { + VariantLayout { size: Size(4 bytes), align: AbiAlign { abi: Align(4 bytes), @@ -61,7 +61,7 @@ error: layout_of(Result<[u32; 0], bool>) = Layout { unadjusted_abi_align: Align(4 bytes), randomization_seed: $SEED, }, - Layout { + VariantLayout { size: Size(2 bytes), align: AbiAlign { abi: Align(1 bytes), @@ -144,7 +144,7 @@ error: layout_of(MultipleAlignments) = Layout { tag_encoding: Direct, tag_field: 0, variants: [ - Layout { + VariantLayout { size: Size(2 bytes), align: AbiAlign { abi: Align(2 bytes), @@ -169,7 +169,7 @@ error: layout_of(MultipleAlignments) = Layout { unadjusted_abi_align: Align(2 bytes), randomization_seed: $SEED, }, - Layout { + VariantLayout { size: Size(4 bytes), align: AbiAlign { abi: Align(4 bytes), @@ -194,7 +194,7 @@ error: layout_of(MultipleAlignments) = Layout { unadjusted_abi_align: Align(4 bytes), randomization_seed: $SEED, }, - Layout { + VariantLayout { size: Size(2 bytes), align: AbiAlign { abi: Align(1 bytes), @@ -277,7 +277,7 @@ error: layout_of(Result<[u32; 0], Packed>>) = Layout { tag_encoding: Direct, tag_field: 0, variants: [ - Layout { + VariantLayout { size: Size(4 bytes), align: AbiAlign { abi: Align(4 bytes), @@ -302,7 +302,7 @@ error: layout_of(Result<[u32; 0], Packed>>) = Layout { unadjusted_abi_align: Align(4 bytes), randomization_seed: $SEED, }, - Layout { + VariantLayout { size: Size(3 bytes), align: AbiAlign { abi: Align(1 bytes), @@ -389,7 +389,7 @@ error: layout_of(Result<[u32; 0], Packed>) = Layout { }, tag_field: 0, variants: [ - Layout { + VariantLayout { size: Size(0 bytes), align: AbiAlign { abi: Align(4 bytes), @@ -414,7 +414,7 @@ error: layout_of(Result<[u32; 0], Packed>) = Layout { unadjusted_abi_align: Align(4 bytes), randomization_seed: $SEED, }, - Layout { + VariantLayout { size: Size(2 bytes), align: AbiAlign { abi: Align(1 bytes), diff --git a/tests/ui/repr/repr-c-dead-variants.aarch64-unknown-linux-gnu.stderr b/tests/ui/repr/repr-c-dead-variants.aarch64-unknown-linux-gnu.stderr index 62f6ec92d493c..5e764a7c77e91 100644 --- a/tests/ui/repr/repr-c-dead-variants.aarch64-unknown-linux-gnu.stderr +++ b/tests/ui/repr/repr-c-dead-variants.aarch64-unknown-linux-gnu.stderr @@ -42,7 +42,7 @@ error: layout_of(Univariant) = Layout { tag_encoding: Direct, tag_field: 0, variants: [ - Layout { + VariantLayout { size: Size(4 bytes), align: AbiAlign { abi: Align(4 bytes), @@ -134,7 +134,7 @@ error: layout_of(TwoVariants) = Layout { tag_encoding: Direct, tag_field: 0, variants: [ - Layout { + VariantLayout { size: Size(8 bytes), align: AbiAlign { abi: Align(4 bytes), @@ -171,7 +171,7 @@ error: layout_of(TwoVariants) = Layout { unadjusted_abi_align: Align(4 bytes), randomization_seed: $SEED, }, - Layout { + VariantLayout { size: Size(8 bytes), align: AbiAlign { abi: Align(4 bytes), @@ -257,7 +257,7 @@ error: layout_of(DeadBranchHasOtherField) = Layout { tag_encoding: Direct, tag_field: 0, variants: [ - Layout { + VariantLayout { size: Size(16 bytes), align: AbiAlign { abi: Align(8 bytes), @@ -286,7 +286,7 @@ error: layout_of(DeadBranchHasOtherField) = Layout { unadjusted_abi_align: Align(8 bytes), randomization_seed: $SEED, }, - Layout { + VariantLayout { size: Size(16 bytes), align: AbiAlign { abi: Align(8 bytes), diff --git a/tests/ui/repr/repr-c-dead-variants.armebv7r-none-eabi.stderr b/tests/ui/repr/repr-c-dead-variants.armebv7r-none-eabi.stderr index 3e0efad974cd2..05bbb6004545f 100644 --- a/tests/ui/repr/repr-c-dead-variants.armebv7r-none-eabi.stderr +++ b/tests/ui/repr/repr-c-dead-variants.armebv7r-none-eabi.stderr @@ -42,7 +42,7 @@ error: layout_of(Univariant) = Layout { tag_encoding: Direct, tag_field: 0, variants: [ - Layout { + VariantLayout { size: Size(1 bytes), align: AbiAlign { abi: Align(1 bytes), @@ -134,7 +134,7 @@ error: layout_of(TwoVariants) = Layout { tag_encoding: Direct, tag_field: 0, variants: [ - Layout { + VariantLayout { size: Size(2 bytes), align: AbiAlign { abi: Align(1 bytes), @@ -171,7 +171,7 @@ error: layout_of(TwoVariants) = Layout { unadjusted_abi_align: Align(1 bytes), randomization_seed: $SEED, }, - Layout { + VariantLayout { size: Size(2 bytes), align: AbiAlign { abi: Align(1 bytes), @@ -257,7 +257,7 @@ error: layout_of(DeadBranchHasOtherField) = Layout { tag_encoding: Direct, tag_field: 0, variants: [ - Layout { + VariantLayout { size: Size(16 bytes), align: AbiAlign { abi: Align(8 bytes), @@ -286,7 +286,7 @@ error: layout_of(DeadBranchHasOtherField) = Layout { unadjusted_abi_align: Align(8 bytes), randomization_seed: $SEED, }, - Layout { + VariantLayout { size: Size(16 bytes), align: AbiAlign { abi: Align(8 bytes), diff --git a/tests/ui/repr/repr-c-dead-variants.i686-pc-windows-msvc.stderr b/tests/ui/repr/repr-c-dead-variants.i686-pc-windows-msvc.stderr index 62f6ec92d493c..5e764a7c77e91 100644 --- a/tests/ui/repr/repr-c-dead-variants.i686-pc-windows-msvc.stderr +++ b/tests/ui/repr/repr-c-dead-variants.i686-pc-windows-msvc.stderr @@ -42,7 +42,7 @@ error: layout_of(Univariant) = Layout { tag_encoding: Direct, tag_field: 0, variants: [ - Layout { + VariantLayout { size: Size(4 bytes), align: AbiAlign { abi: Align(4 bytes), @@ -134,7 +134,7 @@ error: layout_of(TwoVariants) = Layout { tag_encoding: Direct, tag_field: 0, variants: [ - Layout { + VariantLayout { size: Size(8 bytes), align: AbiAlign { abi: Align(4 bytes), @@ -171,7 +171,7 @@ error: layout_of(TwoVariants) = Layout { unadjusted_abi_align: Align(4 bytes), randomization_seed: $SEED, }, - Layout { + VariantLayout { size: Size(8 bytes), align: AbiAlign { abi: Align(4 bytes), @@ -257,7 +257,7 @@ error: layout_of(DeadBranchHasOtherField) = Layout { tag_encoding: Direct, tag_field: 0, variants: [ - Layout { + VariantLayout { size: Size(16 bytes), align: AbiAlign { abi: Align(8 bytes), @@ -286,7 +286,7 @@ error: layout_of(DeadBranchHasOtherField) = Layout { unadjusted_abi_align: Align(8 bytes), randomization_seed: $SEED, }, - Layout { + VariantLayout { size: Size(16 bytes), align: AbiAlign { abi: Align(8 bytes), diff --git a/tests/ui/repr/repr-c-dead-variants.x86_64-unknown-linux-gnu.stderr b/tests/ui/repr/repr-c-dead-variants.x86_64-unknown-linux-gnu.stderr index 62f6ec92d493c..5e764a7c77e91 100644 --- a/tests/ui/repr/repr-c-dead-variants.x86_64-unknown-linux-gnu.stderr +++ b/tests/ui/repr/repr-c-dead-variants.x86_64-unknown-linux-gnu.stderr @@ -42,7 +42,7 @@ error: layout_of(Univariant) = Layout { tag_encoding: Direct, tag_field: 0, variants: [ - Layout { + VariantLayout { size: Size(4 bytes), align: AbiAlign { abi: Align(4 bytes), @@ -134,7 +134,7 @@ error: layout_of(TwoVariants) = Layout { tag_encoding: Direct, tag_field: 0, variants: [ - Layout { + VariantLayout { size: Size(8 bytes), align: AbiAlign { abi: Align(4 bytes), @@ -171,7 +171,7 @@ error: layout_of(TwoVariants) = Layout { unadjusted_abi_align: Align(4 bytes), randomization_seed: $SEED, }, - Layout { + VariantLayout { size: Size(8 bytes), align: AbiAlign { abi: Align(4 bytes), @@ -257,7 +257,7 @@ error: layout_of(DeadBranchHasOtherField) = Layout { tag_encoding: Direct, tag_field: 0, variants: [ - Layout { + VariantLayout { size: Size(16 bytes), align: AbiAlign { abi: Align(8 bytes), @@ -286,7 +286,7 @@ error: layout_of(DeadBranchHasOtherField) = Layout { unadjusted_abi_align: Align(8 bytes), randomization_seed: $SEED, }, - Layout { + VariantLayout { size: Size(16 bytes), align: AbiAlign { abi: Align(8 bytes), diff --git a/tests/ui/repr/repr-c-int-dead-variants.stderr b/tests/ui/repr/repr-c-int-dead-variants.stderr index b25e4a9b7b6f5..12155358ad517 100644 --- a/tests/ui/repr/repr-c-int-dead-variants.stderr +++ b/tests/ui/repr/repr-c-int-dead-variants.stderr @@ -42,7 +42,7 @@ error: layout_of(UnivariantU8) = Layout { tag_encoding: Direct, tag_field: 0, variants: [ - Layout { + VariantLayout { size: Size(1 bytes), align: AbiAlign { abi: Align(1 bytes), @@ -134,7 +134,7 @@ error: layout_of(TwoVariantsU8) = Layout { tag_encoding: Direct, tag_field: 0, variants: [ - Layout { + VariantLayout { size: Size(2 bytes), align: AbiAlign { abi: Align(1 bytes), @@ -171,7 +171,7 @@ error: layout_of(TwoVariantsU8) = Layout { unadjusted_abi_align: Align(1 bytes), randomization_seed: $SEED, }, - Layout { + VariantLayout { size: Size(2 bytes), align: AbiAlign { abi: Align(1 bytes), @@ -257,7 +257,7 @@ error: layout_of(DeadBranchHasOtherFieldU8) = Layout { tag_encoding: Direct, tag_field: 0, variants: [ - Layout { + VariantLayout { size: Size(16 bytes), align: AbiAlign { abi: Align(8 bytes), @@ -286,7 +286,7 @@ error: layout_of(DeadBranchHasOtherFieldU8) = Layout { unadjusted_abi_align: Align(8 bytes), randomization_seed: $SEED, }, - Layout { + VariantLayout { size: Size(16 bytes), align: AbiAlign { abi: Align(8 bytes), diff --git a/tests/ui/type/pattern_types/non_null.stderr b/tests/ui/type/pattern_types/non_null.stderr index 9f27be86bff44..e24688d8e101f 100644 --- a/tests/ui/type/pattern_types/non_null.stderr +++ b/tests/ui/type/pattern_types/non_null.stderr @@ -86,7 +86,7 @@ error: layout_of(Option<(*const ()) is !null>) = Layout { }, tag_field: 0, variants: [ - Layout { + VariantLayout { size: Size(0 bytes), align: AbiAlign { abi: Align(1 bytes), @@ -107,7 +107,7 @@ error: layout_of(Option<(*const ()) is !null>) = Layout { unadjusted_abi_align: Align(1 bytes), randomization_seed: $SEED, }, - Layout { + VariantLayout { size: Size(8 bytes), align: AbiAlign { abi: Align(8 bytes), diff --git a/tests/ui/type/pattern_types/range_patterns.stderr b/tests/ui/type/pattern_types/range_patterns.stderr index d0dad5648d76f..c1755546806e7 100644 --- a/tests/ui/type/pattern_types/range_patterns.stderr +++ b/tests/ui/type/pattern_types/range_patterns.stderr @@ -127,7 +127,7 @@ error: layout_of(Option<(u32) is 1..>) = Layout { }, tag_field: 0, variants: [ - Layout { + VariantLayout { size: Size(0 bytes), align: AbiAlign { abi: Align(1 bytes), @@ -148,7 +148,7 @@ error: layout_of(Option<(u32) is 1..>) = Layout { unadjusted_abi_align: Align(1 bytes), randomization_seed: $SEED, }, - Layout { + VariantLayout { size: Size(4 bytes), align: AbiAlign { abi: Align(4 bytes), @@ -238,7 +238,7 @@ error: layout_of(Option>) = Layout { }, tag_field: 0, variants: [ - Layout { + VariantLayout { size: Size(0 bytes), align: AbiAlign { abi: Align(1 bytes), @@ -259,7 +259,7 @@ error: layout_of(Option>) = Layout { unadjusted_abi_align: Align(1 bytes), randomization_seed: $SEED, }, - Layout { + VariantLayout { size: Size(4 bytes), align: AbiAlign { abi: Align(4 bytes), From 1162bdc1f3fe4a85f6b1d217578f40669c43aeb5 Mon Sep 17 00:00:00 2001 From: Moulins Date: Wed, 17 Dec 2025 22:37:23 +0100 Subject: [PATCH 04/29] Remove redundant `VariantLayout.variants` field It was always set to `Variants::Single`. --- compiler/rustc_abi/src/layout.rs | 14 ++++---- compiler/rustc_abi/src/layout/coroutine.rs | 1 - compiler/rustc_abi/src/layout/simple.rs | 2 +- compiler/rustc_abi/src/lib.rs | 10 +++--- .../rustc_ty_utils/src/layout/invariant.rs | 2 -- .../enum-discriminant/wrapping_niche.stderr | 18 ---------- tests/ui/layout/debug.stderr | 24 ------------- tests/ui/layout/hexagon-enum.stderr | 15 -------- ...-scalarpair-payload-might-be-uninit.stderr | 36 ------------------- .../issue-96185-overaligned-enum.stderr | 12 ------- tests/ui/layout/thumb-enum.stderr | 15 -------- .../layout/zero-sized-array-enum-niche.stderr | 27 -------------- ...-variants.aarch64-unknown-linux-gnu.stderr | 15 -------- ...-c-dead-variants.armebv7r-none-eabi.stderr | 15 -------- ...-dead-variants.i686-pc-windows-msvc.stderr | 15 -------- ...d-variants.x86_64-unknown-linux-gnu.stderr | 15 -------- tests/ui/repr/repr-c-int-dead-variants.stderr | 15 -------- tests/ui/type/pattern_types/non_null.stderr | 6 ---- .../type/pattern_types/range_patterns.stderr | 12 ------- 19 files changed, 11 insertions(+), 258 deletions(-) diff --git a/compiler/rustc_abi/src/layout.rs b/compiler/rustc_abi/src/layout.rs index a82ff1aba9b22..a2e6a5f89f400 100644 --- a/compiler/rustc_abi/src/layout.rs +++ b/compiler/rustc_abi/src/layout.rs @@ -602,10 +602,9 @@ impl LayoutCalculator { let mut unadjusted_abi_align = align; let mut variant_layouts = variants - .iter_enumerated() - .map(|(j, v)| { - let mut st = self.univariant(v, repr, StructKind::AlwaysSized).ok()?; - st.variants = Variants::Single { index: j }; + .iter() + .map(|v| { + let st = self.univariant(v, repr, StructKind::AlwaysSized).ok()?; align = align.max(st.align.abi); max_repr_align = max_repr_align.max(st.max_repr_align); @@ -830,14 +829,13 @@ impl LayoutCalculator { // Create the set of structs that represent each variant. let mut layout_variants = variants - .iter_enumerated() - .map(|(i, field_layouts)| { - let mut st = self.univariant( + .iter() + .map(|field_layouts| { + let st = self.univariant( field_layouts, repr, StructKind::Prefixed(min_ity.size(), prefix_align), )?; - st.variants = Variants::Single { index: i }; // 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() { diff --git a/compiler/rustc_abi/src/layout/coroutine.rs b/compiler/rustc_abi/src/layout/coroutine.rs index 812ed1f4274fd..fd68d06c93829 100644 --- a/compiler/rustc_abi/src/layout/coroutine.rs +++ b/compiler/rustc_abi/src/layout/coroutine.rs @@ -230,7 +230,6 @@ pub(super) fn layout< &ReprOptions::default(), StructKind::Prefixed(prefix_size, prefix_align.abi), )?; - variant.variants = Variants::Single { index }; let FieldsShape::Arbitrary { offsets, in_memory_order } = variant.fields else { unreachable!(); diff --git a/compiler/rustc_abi/src/layout/simple.rs b/compiler/rustc_abi/src/layout/simple.rs index cb584d7cf5788..7c714b6a880df 100644 --- a/compiler/rustc_abi/src/layout/simple.rs +++ b/compiler/rustc_abi/src/layout/simple.rs @@ -156,7 +156,7 @@ impl LayoutData { Self { fields: layout.fields.clone(), - variants: layout.variants.clone(), + variants: Variants::Single { index }, backend_repr: layout.backend_repr, largest_niche: layout.largest_niche, uninhabited: layout.uninhabited, diff --git a/compiler/rustc_abi/src/lib.rs b/compiler/rustc_abi/src/lib.rs index 7ec68bd2b275b..f6e1b8a95b7d7 100644 --- a/compiler/rustc_abi/src/lib.rs +++ b/compiler/rustc_abi/src/lib.rs @@ -1953,7 +1953,7 @@ pub enum Variants { tag: Scalar, tag_encoding: TagEncoding, tag_field: FieldIdx, - variants: IndexVec>, + variants: IndexVec>, }, } @@ -2323,21 +2323,20 @@ pub enum AbiFromStrErr { // NOTE: This struct is generic over the FieldIdx and VariantIdx for rust-analyzer usage. #[derive(PartialEq, Eq, Hash, Clone, Debug)] #[cfg_attr(feature = "nightly", derive(StableHash))] -pub struct VariantLayout { +pub struct VariantLayout { pub size: Size, pub align: AbiAlign, pub backend_repr: BackendRepr, pub fields: FieldsShape, largest_niche: Option, uninhabited: bool, - pub variants: Variants, max_repr_align: Option, unadjusted_abi_align: Align, randomization_seed: Hash64, } -impl VariantLayout { - pub fn from_layout(layout: LayoutData) -> Self { +impl VariantLayout { + pub fn from_layout(layout: LayoutData) -> Self { Self { size: layout.size, align: layout.align, @@ -2345,7 +2344,6 @@ impl VariantLayout { fields: layout.fields, largest_niche: layout.largest_niche, uninhabited: layout.uninhabited, - variants: layout.variants, max_repr_align: layout.max_repr_align, unadjusted_abi_align: layout.unadjusted_abi_align, randomization_seed: layout.randomization_seed, diff --git a/compiler/rustc_ty_utils/src/layout/invariant.rs b/compiler/rustc_ty_utils/src/layout/invariant.rs index a9edaa7371a88..2c74f9dad95fd 100644 --- a/compiler/rustc_ty_utils/src/layout/invariant.rs +++ b/compiler/rustc_ty_utils/src/layout/invariant.rs @@ -302,8 +302,6 @@ pub(super) fn layout_sanity_check<'tcx>(cx: &LayoutCx<'tcx>, layout: &TyAndLayou } } for variant in variants.iter() { - // No nested "multiple". - assert_matches!(variant.variants, Variants::Single { .. }); // Variants should have the same or a smaller size as the full thing, // and same for alignment. if variant.size > layout.size { diff --git a/tests/ui/enum-discriminant/wrapping_niche.stderr b/tests/ui/enum-discriminant/wrapping_niche.stderr index b130d022ea922..568922c224584 100644 --- a/tests/ui/enum-discriminant/wrapping_niche.stderr +++ b/tests/ui/enum-discriminant/wrapping_niche.stderr @@ -56,9 +56,6 @@ error: layout_of(UnsignedAroundZero) = Layout { }, largest_niche: None, uninhabited: false, - variants: Single { - index: 0, - }, max_repr_align: None, unadjusted_abi_align: Align(2 bytes), randomization_seed: 9885373149222004003, @@ -77,9 +74,6 @@ error: layout_of(UnsignedAroundZero) = Layout { }, largest_niche: None, uninhabited: false, - variants: Single { - index: 1, - }, max_repr_align: None, unadjusted_abi_align: Align(2 bytes), randomization_seed: 9885373149222004003, @@ -98,9 +92,6 @@ error: layout_of(UnsignedAroundZero) = Layout { }, largest_niche: None, uninhabited: false, - variants: Single { - index: 2, - }, max_repr_align: None, unadjusted_abi_align: Align(2 bytes), randomization_seed: 9885373149222004003, @@ -174,9 +165,6 @@ error: layout_of(SignedAroundZero) = Layout { }, largest_niche: None, uninhabited: false, - variants: Single { - index: 0, - }, max_repr_align: None, unadjusted_abi_align: Align(2 bytes), randomization_seed: 2684536712112553499, @@ -195,9 +183,6 @@ error: layout_of(SignedAroundZero) = Layout { }, largest_niche: None, uninhabited: false, - variants: Single { - index: 1, - }, max_repr_align: None, unadjusted_abi_align: Align(2 bytes), randomization_seed: 2684536712112553499, @@ -216,9 +201,6 @@ error: layout_of(SignedAroundZero) = Layout { }, largest_niche: None, uninhabited: false, - variants: Single { - index: 2, - }, max_repr_align: None, unadjusted_abi_align: Align(2 bytes), randomization_seed: 2684536712112553499, diff --git a/tests/ui/layout/debug.stderr b/tests/ui/layout/debug.stderr index c4b1b560f9590..17b9c61eb72b4 100644 --- a/tests/ui/layout/debug.stderr +++ b/tests/ui/layout/debug.stderr @@ -72,9 +72,6 @@ error: layout_of(E) = Layout { }, largest_niche: None, uninhabited: false, - variants: Single { - index: 0, - }, max_repr_align: None, unadjusted_abi_align: Align(1 bytes), randomization_seed: $SEED, @@ -101,9 +98,6 @@ error: layout_of(E) = Layout { }, largest_niche: None, uninhabited: true, - variants: Single { - index: 1, - }, max_repr_align: None, unadjusted_abi_align: Align(4 bytes), randomization_seed: $SEED, @@ -273,9 +267,6 @@ error: layout_of(Result) = Layout { }, largest_niche: None, uninhabited: false, - variants: Single { - index: 0, - }, max_repr_align: None, unadjusted_abi_align: Align(4 bytes), randomization_seed: $SEED, @@ -311,9 +302,6 @@ error: layout_of(Result) = Layout { }, largest_niche: None, uninhabited: false, - variants: Single { - index: 1, - }, max_repr_align: None, unadjusted_abi_align: Align(4 bytes), randomization_seed: $SEED, @@ -676,9 +664,6 @@ error: layout_of(Option) = Layout { }, largest_niche: None, uninhabited: false, - variants: Single { - index: 0, - }, max_repr_align: None, unadjusted_abi_align: Align(1 bytes), randomization_seed: $SEED, @@ -716,9 +701,6 @@ error: layout_of(Option) = Layout { }, ), uninhabited: false, - variants: Single { - index: 1, - }, max_repr_align: None, unadjusted_abi_align: Align(1 bytes), randomization_seed: $SEED, @@ -796,9 +778,6 @@ error: layout_of(Option) = Layout { }, largest_niche: None, uninhabited: false, - variants: Single { - index: 0, - }, max_repr_align: None, unadjusted_abi_align: Align(1 bytes), randomization_seed: $SEED, @@ -836,9 +815,6 @@ error: layout_of(Option) = Layout { }, ), uninhabited: false, - variants: Single { - index: 1, - }, max_repr_align: None, unadjusted_abi_align: Align(4 bytes), randomization_seed: $SEED, diff --git a/tests/ui/layout/hexagon-enum.stderr b/tests/ui/layout/hexagon-enum.stderr index e2f888a9dd860..ce68514f30277 100644 --- a/tests/ui/layout/hexagon-enum.stderr +++ b/tests/ui/layout/hexagon-enum.stderr @@ -56,9 +56,6 @@ error: layout_of(A) = Layout { }, largest_niche: None, uninhabited: false, - variants: Single { - index: 0, - }, max_repr_align: None, unadjusted_abi_align: Align(1 bytes), randomization_seed: $SEED, @@ -132,9 +129,6 @@ error: layout_of(B) = Layout { }, largest_niche: None, uninhabited: false, - variants: Single { - index: 0, - }, max_repr_align: None, unadjusted_abi_align: Align(1 bytes), randomization_seed: $SEED, @@ -208,9 +202,6 @@ error: layout_of(C) = Layout { }, largest_niche: None, uninhabited: false, - variants: Single { - index: 0, - }, max_repr_align: None, unadjusted_abi_align: Align(2 bytes), randomization_seed: $SEED, @@ -284,9 +275,6 @@ error: layout_of(P) = Layout { }, largest_niche: None, uninhabited: false, - variants: Single { - index: 0, - }, max_repr_align: None, unadjusted_abi_align: Align(4 bytes), randomization_seed: $SEED, @@ -360,9 +348,6 @@ error: layout_of(T) = Layout { }, largest_niche: None, uninhabited: false, - variants: Single { - index: 0, - }, max_repr_align: None, unadjusted_abi_align: Align(4 bytes), randomization_seed: $SEED, diff --git a/tests/ui/layout/issue-96158-scalarpair-payload-might-be-uninit.stderr b/tests/ui/layout/issue-96158-scalarpair-payload-might-be-uninit.stderr index bcb38889bded8..9f78cfd792365 100644 --- a/tests/ui/layout/issue-96158-scalarpair-payload-might-be-uninit.stderr +++ b/tests/ui/layout/issue-96158-scalarpair-payload-might-be-uninit.stderr @@ -78,9 +78,6 @@ error: layout_of(MissingPayloadField) = Layout { }, largest_niche: None, uninhabited: false, - variants: Single { - index: 0, - }, max_repr_align: None, unadjusted_abi_align: Align(1 bytes), randomization_seed: $SEED, @@ -99,9 +96,6 @@ error: layout_of(MissingPayloadField) = Layout { }, largest_niche: None, uninhabited: false, - variants: Single { - index: 1, - }, max_repr_align: None, unadjusted_abi_align: Align(1 bytes), randomization_seed: $SEED, @@ -199,9 +193,6 @@ error: layout_of(CommonPayloadField) = Layout { }, largest_niche: None, uninhabited: false, - variants: Single { - index: 0, - }, max_repr_align: None, unadjusted_abi_align: Align(1 bytes), randomization_seed: $SEED, @@ -237,9 +228,6 @@ error: layout_of(CommonPayloadField) = Layout { }, largest_niche: None, uninhabited: false, - variants: Single { - index: 1, - }, max_repr_align: None, unadjusted_abi_align: Align(1 bytes), randomization_seed: $SEED, @@ -335,9 +323,6 @@ error: layout_of(CommonPayloadFieldIsMaybeUninit) = Layout { }, largest_niche: None, uninhabited: false, - variants: Single { - index: 0, - }, max_repr_align: None, unadjusted_abi_align: Align(1 bytes), randomization_seed: $SEED, @@ -372,9 +357,6 @@ error: layout_of(CommonPayloadFieldIsMaybeUninit) = Layout { }, largest_niche: None, uninhabited: false, - variants: Single { - index: 1, - }, max_repr_align: None, unadjusted_abi_align: Align(1 bytes), randomization_seed: $SEED, @@ -486,9 +468,6 @@ error: layout_of(NicheFirst) = Layout { }, ), uninhabited: false, - variants: Single { - index: 0, - }, max_repr_align: None, unadjusted_abi_align: Align(1 bytes), randomization_seed: $SEED, @@ -507,9 +486,6 @@ error: layout_of(NicheFirst) = Layout { }, largest_niche: None, uninhabited: false, - variants: Single { - index: 1, - }, max_repr_align: None, unadjusted_abi_align: Align(1 bytes), randomization_seed: $SEED, @@ -528,9 +504,6 @@ error: layout_of(NicheFirst) = Layout { }, largest_niche: None, uninhabited: false, - variants: Single { - index: 2, - }, max_repr_align: None, unadjusted_abi_align: Align(1 bytes), randomization_seed: $SEED, @@ -642,9 +615,6 @@ error: layout_of(NicheSecond) = Layout { }, ), uninhabited: false, - variants: Single { - index: 0, - }, max_repr_align: None, unadjusted_abi_align: Align(1 bytes), randomization_seed: $SEED, @@ -663,9 +633,6 @@ error: layout_of(NicheSecond) = Layout { }, largest_niche: None, uninhabited: false, - variants: Single { - index: 1, - }, max_repr_align: None, unadjusted_abi_align: Align(1 bytes), randomization_seed: $SEED, @@ -684,9 +651,6 @@ error: layout_of(NicheSecond) = Layout { }, largest_niche: None, uninhabited: false, - variants: Single { - index: 2, - }, max_repr_align: None, unadjusted_abi_align: Align(1 bytes), randomization_seed: $SEED, diff --git a/tests/ui/layout/issue-96185-overaligned-enum.stderr b/tests/ui/layout/issue-96185-overaligned-enum.stderr index 20607303599ec..cc5818e78c71b 100644 --- a/tests/ui/layout/issue-96185-overaligned-enum.stderr +++ b/tests/ui/layout/issue-96185-overaligned-enum.stderr @@ -50,9 +50,6 @@ error: layout_of(Aligned1) = Layout { }, largest_niche: None, uninhabited: false, - variants: Single { - index: 0, - }, max_repr_align: Some( Align(8 bytes), ), @@ -73,9 +70,6 @@ error: layout_of(Aligned1) = Layout { }, largest_niche: None, uninhabited: false, - variants: Single { - index: 1, - }, max_repr_align: Some( Align(8 bytes), ), @@ -153,9 +147,6 @@ error: layout_of(Aligned2) = Layout { }, largest_niche: None, uninhabited: false, - variants: Single { - index: 0, - }, max_repr_align: Some( Align(1 bytes), ), @@ -176,9 +167,6 @@ error: layout_of(Aligned2) = Layout { }, largest_niche: None, uninhabited: false, - variants: Single { - index: 1, - }, max_repr_align: Some( Align(1 bytes), ), diff --git a/tests/ui/layout/thumb-enum.stderr b/tests/ui/layout/thumb-enum.stderr index 07be46db6ed85..3c5f906d67aa8 100644 --- a/tests/ui/layout/thumb-enum.stderr +++ b/tests/ui/layout/thumb-enum.stderr @@ -56,9 +56,6 @@ error: layout_of(A) = Layout { }, largest_niche: None, uninhabited: false, - variants: Single { - index: 0, - }, max_repr_align: None, unadjusted_abi_align: Align(1 bytes), randomization_seed: $SEED, @@ -132,9 +129,6 @@ error: layout_of(B) = Layout { }, largest_niche: None, uninhabited: false, - variants: Single { - index: 0, - }, max_repr_align: None, unadjusted_abi_align: Align(1 bytes), randomization_seed: $SEED, @@ -208,9 +202,6 @@ error: layout_of(C) = Layout { }, largest_niche: None, uninhabited: false, - variants: Single { - index: 0, - }, max_repr_align: None, unadjusted_abi_align: Align(2 bytes), randomization_seed: $SEED, @@ -284,9 +275,6 @@ error: layout_of(P) = Layout { }, largest_niche: None, uninhabited: false, - variants: Single { - index: 0, - }, max_repr_align: None, unadjusted_abi_align: Align(4 bytes), randomization_seed: $SEED, @@ -360,9 +348,6 @@ error: layout_of(T) = Layout { }, largest_niche: None, uninhabited: false, - variants: Single { - index: 0, - }, max_repr_align: None, unadjusted_abi_align: Align(4 bytes), randomization_seed: $SEED, diff --git a/tests/ui/layout/zero-sized-array-enum-niche.stderr b/tests/ui/layout/zero-sized-array-enum-niche.stderr index ddbcf97dfa4d1..1a1e261eae5ee 100644 --- a/tests/ui/layout/zero-sized-array-enum-niche.stderr +++ b/tests/ui/layout/zero-sized-array-enum-niche.stderr @@ -54,9 +54,6 @@ error: layout_of(Result<[u32; 0], bool>) = Layout { }, largest_niche: None, uninhabited: false, - variants: Single { - index: 0, - }, max_repr_align: None, unadjusted_abi_align: Align(4 bytes), randomization_seed: $SEED, @@ -88,9 +85,6 @@ error: layout_of(Result<[u32; 0], bool>) = Layout { }, ), uninhabited: false, - variants: Single { - index: 1, - }, max_repr_align: None, unadjusted_abi_align: Align(1 bytes), randomization_seed: $SEED, @@ -162,9 +156,6 @@ error: layout_of(MultipleAlignments) = Layout { }, largest_niche: None, uninhabited: false, - variants: Single { - index: 0, - }, max_repr_align: None, unadjusted_abi_align: Align(2 bytes), randomization_seed: $SEED, @@ -187,9 +178,6 @@ error: layout_of(MultipleAlignments) = Layout { }, largest_niche: None, uninhabited: false, - variants: Single { - index: 1, - }, max_repr_align: None, unadjusted_abi_align: Align(4 bytes), randomization_seed: $SEED, @@ -221,9 +209,6 @@ error: layout_of(MultipleAlignments) = Layout { }, ), uninhabited: false, - variants: Single { - index: 2, - }, max_repr_align: None, unadjusted_abi_align: Align(1 bytes), randomization_seed: $SEED, @@ -295,9 +280,6 @@ error: layout_of(Result<[u32; 0], Packed>>) = Layout { }, largest_niche: None, uninhabited: false, - variants: Single { - index: 0, - }, max_repr_align: None, unadjusted_abi_align: Align(4 bytes), randomization_seed: $SEED, @@ -329,9 +311,6 @@ error: layout_of(Result<[u32; 0], Packed>>) = Layout { }, ), uninhabited: false, - variants: Single { - index: 1, - }, max_repr_align: None, unadjusted_abi_align: Align(1 bytes), randomization_seed: $SEED, @@ -407,9 +386,6 @@ error: layout_of(Result<[u32; 0], Packed>) = Layout { }, largest_niche: None, uninhabited: false, - variants: Single { - index: 0, - }, max_repr_align: None, unadjusted_abi_align: Align(4 bytes), randomization_seed: $SEED, @@ -441,9 +417,6 @@ error: layout_of(Result<[u32; 0], Packed>) = Layout { }, ), uninhabited: false, - variants: Single { - index: 1, - }, max_repr_align: None, unadjusted_abi_align: Align(1 bytes), randomization_seed: $SEED, diff --git a/tests/ui/repr/repr-c-dead-variants.aarch64-unknown-linux-gnu.stderr b/tests/ui/repr/repr-c-dead-variants.aarch64-unknown-linux-gnu.stderr index 5e764a7c77e91..e8a99c7226af5 100644 --- a/tests/ui/repr/repr-c-dead-variants.aarch64-unknown-linux-gnu.stderr +++ b/tests/ui/repr/repr-c-dead-variants.aarch64-unknown-linux-gnu.stderr @@ -66,9 +66,6 @@ error: layout_of(Univariant) = Layout { }, largest_niche: None, uninhabited: true, - variants: Single { - index: 0, - }, max_repr_align: None, unadjusted_abi_align: Align(4 bytes), randomization_seed: $SEED, @@ -164,9 +161,6 @@ error: layout_of(TwoVariants) = Layout { }, largest_niche: None, uninhabited: true, - variants: Single { - index: 0, - }, max_repr_align: None, unadjusted_abi_align: Align(4 bytes), randomization_seed: $SEED, @@ -201,9 +195,6 @@ error: layout_of(TwoVariants) = Layout { }, largest_niche: None, uninhabited: false, - variants: Single { - index: 1, - }, max_repr_align: None, unadjusted_abi_align: Align(4 bytes), randomization_seed: $SEED, @@ -277,9 +268,6 @@ error: layout_of(DeadBranchHasOtherField) = Layout { }, largest_niche: None, uninhabited: true, - variants: Single { - index: 0, - }, max_repr_align: Some( Align(8 bytes), ), @@ -304,9 +292,6 @@ error: layout_of(DeadBranchHasOtherField) = Layout { }, largest_niche: None, uninhabited: false, - variants: Single { - index: 1, - }, max_repr_align: None, unadjusted_abi_align: Align(8 bytes), randomization_seed: $SEED, diff --git a/tests/ui/repr/repr-c-dead-variants.armebv7r-none-eabi.stderr b/tests/ui/repr/repr-c-dead-variants.armebv7r-none-eabi.stderr index 05bbb6004545f..30e0b7923bbd0 100644 --- a/tests/ui/repr/repr-c-dead-variants.armebv7r-none-eabi.stderr +++ b/tests/ui/repr/repr-c-dead-variants.armebv7r-none-eabi.stderr @@ -66,9 +66,6 @@ error: layout_of(Univariant) = Layout { }, largest_niche: None, uninhabited: true, - variants: Single { - index: 0, - }, max_repr_align: None, unadjusted_abi_align: Align(1 bytes), randomization_seed: $SEED, @@ -164,9 +161,6 @@ error: layout_of(TwoVariants) = Layout { }, largest_niche: None, uninhabited: true, - variants: Single { - index: 0, - }, max_repr_align: None, unadjusted_abi_align: Align(1 bytes), randomization_seed: $SEED, @@ -201,9 +195,6 @@ error: layout_of(TwoVariants) = Layout { }, largest_niche: None, uninhabited: false, - variants: Single { - index: 1, - }, max_repr_align: None, unadjusted_abi_align: Align(1 bytes), randomization_seed: $SEED, @@ -277,9 +268,6 @@ error: layout_of(DeadBranchHasOtherField) = Layout { }, largest_niche: None, uninhabited: true, - variants: Single { - index: 0, - }, max_repr_align: Some( Align(8 bytes), ), @@ -304,9 +292,6 @@ error: layout_of(DeadBranchHasOtherField) = Layout { }, largest_niche: None, uninhabited: false, - variants: Single { - index: 1, - }, max_repr_align: None, unadjusted_abi_align: Align(8 bytes), randomization_seed: $SEED, diff --git a/tests/ui/repr/repr-c-dead-variants.i686-pc-windows-msvc.stderr b/tests/ui/repr/repr-c-dead-variants.i686-pc-windows-msvc.stderr index 5e764a7c77e91..e8a99c7226af5 100644 --- a/tests/ui/repr/repr-c-dead-variants.i686-pc-windows-msvc.stderr +++ b/tests/ui/repr/repr-c-dead-variants.i686-pc-windows-msvc.stderr @@ -66,9 +66,6 @@ error: layout_of(Univariant) = Layout { }, largest_niche: None, uninhabited: true, - variants: Single { - index: 0, - }, max_repr_align: None, unadjusted_abi_align: Align(4 bytes), randomization_seed: $SEED, @@ -164,9 +161,6 @@ error: layout_of(TwoVariants) = Layout { }, largest_niche: None, uninhabited: true, - variants: Single { - index: 0, - }, max_repr_align: None, unadjusted_abi_align: Align(4 bytes), randomization_seed: $SEED, @@ -201,9 +195,6 @@ error: layout_of(TwoVariants) = Layout { }, largest_niche: None, uninhabited: false, - variants: Single { - index: 1, - }, max_repr_align: None, unadjusted_abi_align: Align(4 bytes), randomization_seed: $SEED, @@ -277,9 +268,6 @@ error: layout_of(DeadBranchHasOtherField) = Layout { }, largest_niche: None, uninhabited: true, - variants: Single { - index: 0, - }, max_repr_align: Some( Align(8 bytes), ), @@ -304,9 +292,6 @@ error: layout_of(DeadBranchHasOtherField) = Layout { }, largest_niche: None, uninhabited: false, - variants: Single { - index: 1, - }, max_repr_align: None, unadjusted_abi_align: Align(8 bytes), randomization_seed: $SEED, diff --git a/tests/ui/repr/repr-c-dead-variants.x86_64-unknown-linux-gnu.stderr b/tests/ui/repr/repr-c-dead-variants.x86_64-unknown-linux-gnu.stderr index 5e764a7c77e91..e8a99c7226af5 100644 --- a/tests/ui/repr/repr-c-dead-variants.x86_64-unknown-linux-gnu.stderr +++ b/tests/ui/repr/repr-c-dead-variants.x86_64-unknown-linux-gnu.stderr @@ -66,9 +66,6 @@ error: layout_of(Univariant) = Layout { }, largest_niche: None, uninhabited: true, - variants: Single { - index: 0, - }, max_repr_align: None, unadjusted_abi_align: Align(4 bytes), randomization_seed: $SEED, @@ -164,9 +161,6 @@ error: layout_of(TwoVariants) = Layout { }, largest_niche: None, uninhabited: true, - variants: Single { - index: 0, - }, max_repr_align: None, unadjusted_abi_align: Align(4 bytes), randomization_seed: $SEED, @@ -201,9 +195,6 @@ error: layout_of(TwoVariants) = Layout { }, largest_niche: None, uninhabited: false, - variants: Single { - index: 1, - }, max_repr_align: None, unadjusted_abi_align: Align(4 bytes), randomization_seed: $SEED, @@ -277,9 +268,6 @@ error: layout_of(DeadBranchHasOtherField) = Layout { }, largest_niche: None, uninhabited: true, - variants: Single { - index: 0, - }, max_repr_align: Some( Align(8 bytes), ), @@ -304,9 +292,6 @@ error: layout_of(DeadBranchHasOtherField) = Layout { }, largest_niche: None, uninhabited: false, - variants: Single { - index: 1, - }, max_repr_align: None, unadjusted_abi_align: Align(8 bytes), randomization_seed: $SEED, diff --git a/tests/ui/repr/repr-c-int-dead-variants.stderr b/tests/ui/repr/repr-c-int-dead-variants.stderr index 12155358ad517..73a2898b67608 100644 --- a/tests/ui/repr/repr-c-int-dead-variants.stderr +++ b/tests/ui/repr/repr-c-int-dead-variants.stderr @@ -66,9 +66,6 @@ error: layout_of(UnivariantU8) = Layout { }, largest_niche: None, uninhabited: true, - variants: Single { - index: 0, - }, max_repr_align: None, unadjusted_abi_align: Align(1 bytes), randomization_seed: $SEED, @@ -164,9 +161,6 @@ error: layout_of(TwoVariantsU8) = Layout { }, largest_niche: None, uninhabited: true, - variants: Single { - index: 0, - }, max_repr_align: None, unadjusted_abi_align: Align(1 bytes), randomization_seed: $SEED, @@ -201,9 +195,6 @@ error: layout_of(TwoVariantsU8) = Layout { }, largest_niche: None, uninhabited: false, - variants: Single { - index: 1, - }, max_repr_align: None, unadjusted_abi_align: Align(1 bytes), randomization_seed: $SEED, @@ -277,9 +268,6 @@ error: layout_of(DeadBranchHasOtherFieldU8) = Layout { }, largest_niche: None, uninhabited: true, - variants: Single { - index: 0, - }, max_repr_align: Some( Align(8 bytes), ), @@ -304,9 +292,6 @@ error: layout_of(DeadBranchHasOtherFieldU8) = Layout { }, largest_niche: None, uninhabited: false, - variants: Single { - index: 1, - }, max_repr_align: None, unadjusted_abi_align: Align(8 bytes), randomization_seed: $SEED, diff --git a/tests/ui/type/pattern_types/non_null.stderr b/tests/ui/type/pattern_types/non_null.stderr index e24688d8e101f..1911f0e328410 100644 --- a/tests/ui/type/pattern_types/non_null.stderr +++ b/tests/ui/type/pattern_types/non_null.stderr @@ -100,9 +100,6 @@ error: layout_of(Option<(*const ()) is !null>) = Layout { }, largest_niche: None, uninhabited: false, - variants: Single { - index: 0, - }, max_repr_align: None, unadjusted_abi_align: Align(1 bytes), randomization_seed: $SEED, @@ -142,9 +139,6 @@ error: layout_of(Option<(*const ()) is !null>) = Layout { }, ), uninhabited: false, - variants: Single { - index: 1, - }, max_repr_align: None, unadjusted_abi_align: Align(8 bytes), randomization_seed: $SEED, diff --git a/tests/ui/type/pattern_types/range_patterns.stderr b/tests/ui/type/pattern_types/range_patterns.stderr index c1755546806e7..392b84c2647c0 100644 --- a/tests/ui/type/pattern_types/range_patterns.stderr +++ b/tests/ui/type/pattern_types/range_patterns.stderr @@ -141,9 +141,6 @@ error: layout_of(Option<(u32) is 1..>) = Layout { }, largest_niche: None, uninhabited: false, - variants: Single { - index: 0, - }, max_repr_align: None, unadjusted_abi_align: Align(1 bytes), randomization_seed: $SEED, @@ -181,9 +178,6 @@ error: layout_of(Option<(u32) is 1..>) = Layout { }, ), uninhabited: false, - variants: Single { - index: 1, - }, max_repr_align: None, unadjusted_abi_align: Align(4 bytes), randomization_seed: $SEED, @@ -252,9 +246,6 @@ error: layout_of(Option>) = Layout { }, largest_niche: None, uninhabited: false, - variants: Single { - index: 0, - }, max_repr_align: None, unadjusted_abi_align: Align(1 bytes), randomization_seed: $SEED, @@ -292,9 +283,6 @@ error: layout_of(Option>) = Layout { }, ), uninhabited: false, - variants: Single { - index: 1, - }, max_repr_align: None, unadjusted_abi_align: Align(4 bytes), randomization_seed: $SEED, From 0569574938af400dfbfd88fea5a402a52f4cb4cf Mon Sep 17 00:00:00 2001 From: Moulins Date: Wed, 17 Dec 2025 23:18:27 +0100 Subject: [PATCH 05/29] Store `FieldsShape::Arbitrary` fields directly in `VariantLayout` Enum variants always have `Arbitrary` layout, so the enum isn't needed. --- compiler/rustc_abi/src/layout.rs | 43 ++---- compiler/rustc_abi/src/layout/simple.rs | 5 +- compiler/rustc_abi/src/lib.rs | 14 +- .../src/unstable/convert/stable/abi.rs | 7 +- .../rustc_ty_utils/src/layout/invariant.rs | 5 +- .../enum-discriminant/wrapping_niche.stderr | 36 ++--- tests/ui/layout/debug.stderr | 96 ++++++------- tests/ui/layout/hexagon-enum.stderr | 30 ++-- ...-scalarpair-payload-might-be-uninit.stderr | 136 ++++++++---------- .../issue-96185-overaligned-enum.stderr | 24 ++-- tests/ui/layout/thumb-enum.stderr | 30 ++-- .../layout/zero-sized-array-enum-niche.stderr | 126 +++++++--------- ...-variants.aarch64-unknown-linux-gnu.stderr | 74 +++++----- ...-c-dead-variants.armebv7r-none-eabi.stderr | 74 +++++----- ...-dead-variants.i686-pc-windows-msvc.stderr | 74 +++++----- ...d-variants.x86_64-unknown-linux-gnu.stderr | 74 +++++----- tests/ui/repr/repr-c-int-dead-variants.stderr | 74 +++++----- tests/ui/type/pattern_types/non_null.stderr | 20 ++- .../type/pattern_types/range_patterns.stderr | 40 +++--- 19 files changed, 406 insertions(+), 576 deletions(-) diff --git a/compiler/rustc_abi/src/layout.rs b/compiler/rustc_abi/src/layout.rs index a2e6a5f89f400..f12c0c5c248d0 100644 --- a/compiler/rustc_abi/src/layout.rs +++ b/compiler/rustc_abi/src/layout.rs @@ -656,15 +656,8 @@ impl LayoutCalculator { } // It'll fit, but we need to make some adjustments. - match layout.fields { - FieldsShape::Arbitrary { ref mut offsets, .. } => { - for offset in offsets.iter_mut() { - *offset += this_offset; - } - } - FieldsShape::Primitive | FieldsShape::Array { .. } | FieldsShape::Union(..) => { - panic!("Layout of fields should be Arbitrary for variants") - } + for offset in layout.field_offsets.iter_mut() { + *offset += this_offset; } // It can't be a Scalar or ScalarPair because the offset isn't 0. @@ -904,23 +897,16 @@ impl LayoutCalculator { let old_ity_size = min_ity.size(); let new_ity_size = ity.size(); for variant in &mut layout_variants { - match variant.fields { - FieldsShape::Arbitrary { ref mut offsets, .. } => { - for i in offsets { - if *i <= old_ity_size { - assert_eq!(*i, old_ity_size); - *i = new_ity_size; - } - } - // We might be making the struct larger. - if variant.size <= old_ity_size { - variant.size = new_ity_size; - } - } - FieldsShape::Primitive | FieldsShape::Array { .. } | FieldsShape::Union(..) => { - panic!("encountered a non-arbitrary layout during enum layout") + for i in &mut variant.field_offsets { + if *i <= old_ity_size { + assert_eq!(*i, old_ity_size); + *i = new_ity_size; } } + // We might be making the struct larger. + if variant.size <= old_ity_size { + variant.size = new_ity_size; + } } } @@ -945,12 +931,10 @@ impl LayoutCalculator { let mut common_prim = None; let mut common_prim_initialized_in_all_variants = true; for (field_layouts, layout_variant) in iter::zip(variants, &layout_variants) { - let FieldsShape::Arbitrary { ref offsets, .. } = layout_variant.fields else { - panic!("encountered a non-arbitrary layout during enum layout"); - }; // 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.is_zst()); + let mut fields = iter::zip(field_layouts, &layout_variant.field_offsets) + .filter(|p| !p.0.is_zst()); let (field, offset) = match (fields.next(), fields.next()) { (None, None) => { common_prim_initialized_in_all_variants = false; @@ -1045,8 +1029,7 @@ impl LayoutCalculator { for variant in &mut layout_variants { // We only do this for variants with fields; the others are not accessed anyway. // Also do not overwrite any already existing "clever" ABIs. - if variant.fields.count() > 0 - && matches!(variant.backend_repr, BackendRepr::Memory { .. }) + if matches!(variant.backend_repr, BackendRepr::Memory { .. } if variant.has_fields()) { variant.backend_repr = abi; // Also need to bump up the size and alignment, so that the entire value fits diff --git a/compiler/rustc_abi/src/layout/simple.rs b/compiler/rustc_abi/src/layout/simple.rs index 7c714b6a880df..1ce22a0293346 100644 --- a/compiler/rustc_abi/src/layout/simple.rs +++ b/compiler/rustc_abi/src/layout/simple.rs @@ -155,7 +155,10 @@ impl LayoutData { }; Self { - fields: layout.fields.clone(), + fields: FieldsShape::Arbitrary { + offsets: layout.field_offsets.clone(), + in_memory_order: layout.fields_in_memory_order.clone(), + }, variants: Variants::Single { index }, backend_repr: layout.backend_repr, largest_niche: layout.largest_niche, diff --git a/compiler/rustc_abi/src/lib.rs b/compiler/rustc_abi/src/lib.rs index f6e1b8a95b7d7..92d9e4bb7e9bf 100644 --- a/compiler/rustc_abi/src/lib.rs +++ b/compiler/rustc_abi/src/lib.rs @@ -2327,7 +2327,8 @@ pub struct VariantLayout { pub size: Size, pub align: AbiAlign, pub backend_repr: BackendRepr, - pub fields: FieldsShape, + pub field_offsets: IndexVec, + fields_in_memory_order: IndexVec, largest_niche: Option, uninhabited: bool, max_repr_align: Option, @@ -2337,11 +2338,16 @@ pub struct VariantLayout { impl VariantLayout { pub fn from_layout(layout: LayoutData) -> Self { + let FieldsShape::Arbitrary { offsets, in_memory_order } = layout.fields else { + panic!("Layout of fields should be Arbitrary for variants"); + }; + Self { size: layout.size, align: layout.align, backend_repr: layout.backend_repr, - fields: layout.fields, + field_offsets: offsets, + fields_in_memory_order: in_memory_order, largest_niche: layout.largest_niche, uninhabited: layout.uninhabited, max_repr_align: layout.max_repr_align, @@ -2353,4 +2359,8 @@ impl VariantLayout { pub fn is_uninhabited(&self) -> bool { self.uninhabited } + + pub fn has_fields(&self) -> bool { + self.field_offsets.len() > 0 + } } diff --git a/compiler/rustc_public/src/unstable/convert/stable/abi.rs b/compiler/rustc_public/src/unstable/convert/stable/abi.rs index b98a9804ce8b2..f42399241cd28 100644 --- a/compiler/rustc_public/src/unstable/convert/stable/abi.rs +++ b/compiler/rustc_public/src/unstable/convert/stable/abi.rs @@ -217,11 +217,8 @@ impl<'tcx> Stable<'tcx> for rustc_abi::Variants VariantFields { - offsets: offsets.iter().as_slice().stable(tables, cx), - }, - _ => panic!("variant layout should be Arbitrary"), + .map(|v| VariantFields { + offsets: v.field_offsets.iter().as_slice().stable(tables, cx), }) .collect(), } diff --git a/compiler/rustc_ty_utils/src/layout/invariant.rs b/compiler/rustc_ty_utils/src/layout/invariant.rs index 2c74f9dad95fd..c33891941afda 100644 --- a/compiler/rustc_ty_utils/src/layout/invariant.rs +++ b/compiler/rustc_ty_utils/src/layout/invariant.rs @@ -319,10 +319,7 @@ pub(super) fn layout_sanity_check<'tcx>(cx: &LayoutCx<'tcx>, layout: &TyAndLayou ) } // Skip empty variants. - if variant.size == Size::ZERO - || variant.fields.count() == 0 - || variant.is_uninhabited() - { + if variant.size == Size::ZERO || !variant.has_fields() || variant.is_uninhabited() { // These are never actually accessed anyway, so we can skip the coherence check // for them. They also fail that check, since they may have // a different ABI even when the main type is diff --git a/tests/ui/enum-discriminant/wrapping_niche.stderr b/tests/ui/enum-discriminant/wrapping_niche.stderr index 568922c224584..b3b0a560b28ab 100644 --- a/tests/ui/enum-discriminant/wrapping_niche.stderr +++ b/tests/ui/enum-discriminant/wrapping_niche.stderr @@ -50,10 +50,8 @@ error: layout_of(UnsignedAroundZero) = Layout { backend_repr: Memory { sized: true, }, - fields: Arbitrary { - offsets: [], - in_memory_order: [], - }, + field_offsets: [], + fields_in_memory_order: [], largest_niche: None, uninhabited: false, max_repr_align: None, @@ -68,10 +66,8 @@ error: layout_of(UnsignedAroundZero) = Layout { backend_repr: Memory { sized: true, }, - fields: Arbitrary { - offsets: [], - in_memory_order: [], - }, + field_offsets: [], + fields_in_memory_order: [], largest_niche: None, uninhabited: false, max_repr_align: None, @@ -86,10 +82,8 @@ error: layout_of(UnsignedAroundZero) = Layout { backend_repr: Memory { sized: true, }, - fields: Arbitrary { - offsets: [], - in_memory_order: [], - }, + field_offsets: [], + fields_in_memory_order: [], largest_niche: None, uninhabited: false, max_repr_align: None, @@ -159,10 +153,8 @@ error: layout_of(SignedAroundZero) = Layout { backend_repr: Memory { sized: true, }, - fields: Arbitrary { - offsets: [], - in_memory_order: [], - }, + field_offsets: [], + fields_in_memory_order: [], largest_niche: None, uninhabited: false, max_repr_align: None, @@ -177,10 +169,8 @@ error: layout_of(SignedAroundZero) = Layout { backend_repr: Memory { sized: true, }, - fields: Arbitrary { - offsets: [], - in_memory_order: [], - }, + field_offsets: [], + fields_in_memory_order: [], largest_niche: None, uninhabited: false, max_repr_align: None, @@ -195,10 +185,8 @@ error: layout_of(SignedAroundZero) = Layout { backend_repr: Memory { sized: true, }, - fields: Arbitrary { - offsets: [], - in_memory_order: [], - }, + field_offsets: [], + fields_in_memory_order: [], largest_niche: None, uninhabited: false, max_repr_align: None, diff --git a/tests/ui/layout/debug.stderr b/tests/ui/layout/debug.stderr index 17b9c61eb72b4..84f5c1169acdc 100644 --- a/tests/ui/layout/debug.stderr +++ b/tests/ui/layout/debug.stderr @@ -66,10 +66,8 @@ error: layout_of(E) = Layout { backend_repr: Memory { sized: true, }, - fields: Arbitrary { - offsets: [], - in_memory_order: [], - }, + field_offsets: [], + fields_in_memory_order: [], largest_niche: None, uninhabited: false, max_repr_align: None, @@ -84,18 +82,16 @@ error: layout_of(E) = Layout { backend_repr: Memory { sized: true, }, - fields: Arbitrary { - offsets: [ - Size(4 bytes), - Size(4 bytes), - Size(8 bytes), - ], - in_memory_order: [ - 0, - 1, - 2, - ], - }, + field_offsets: [ + Size(4 bytes), + Size(4 bytes), + Size(8 bytes), + ], + fields_in_memory_order: [ + 0, + 1, + 2, + ], largest_niche: None, uninhabited: true, max_repr_align: None, @@ -257,14 +253,12 @@ error: layout_of(Result) = Layout { valid_range: 0..=4294967295, }, ), - fields: Arbitrary { - offsets: [ - Size(4 bytes), - ], - in_memory_order: [ - 0, - ], - }, + field_offsets: [ + Size(4 bytes), + ], + fields_in_memory_order: [ + 0, + ], largest_niche: None, uninhabited: false, max_repr_align: None, @@ -292,14 +286,12 @@ error: layout_of(Result) = Layout { valid_range: 0..=4294967295, }, ), - fields: Arbitrary { - offsets: [ - Size(4 bytes), - ], - in_memory_order: [ - 0, - ], - }, + field_offsets: [ + Size(4 bytes), + ], + fields_in_memory_order: [ + 0, + ], largest_niche: None, uninhabited: false, max_repr_align: None, @@ -658,10 +650,8 @@ error: layout_of(Option) = Layout { backend_repr: Memory { sized: true, }, - fields: Arbitrary { - offsets: [], - in_memory_order: [], - }, + field_offsets: [], + fields_in_memory_order: [], largest_niche: None, uninhabited: false, max_repr_align: None, @@ -682,14 +672,12 @@ error: layout_of(Option) = Layout { valid_range: 0..=1, }, ), - fields: Arbitrary { - offsets: [ - Size(0 bytes), - ], - in_memory_order: [ - 0, - ], - }, + field_offsets: [ + Size(0 bytes), + ], + fields_in_memory_order: [ + 0, + ], largest_niche: Some( Niche { offset: Size(0 bytes), @@ -772,10 +760,8 @@ error: layout_of(Option) = Layout { backend_repr: Memory { sized: true, }, - fields: Arbitrary { - offsets: [], - in_memory_order: [], - }, + field_offsets: [], + fields_in_memory_order: [], largest_niche: None, uninhabited: false, max_repr_align: None, @@ -796,14 +782,12 @@ error: layout_of(Option) = Layout { valid_range: 0..=1114111, }, ), - fields: Arbitrary { - offsets: [ - Size(0 bytes), - ], - in_memory_order: [ - 0, - ], - }, + field_offsets: [ + Size(0 bytes), + ], + fields_in_memory_order: [ + 0, + ], largest_niche: Some( Niche { offset: Size(0 bytes), diff --git a/tests/ui/layout/hexagon-enum.stderr b/tests/ui/layout/hexagon-enum.stderr index ce68514f30277..e00848b1b0154 100644 --- a/tests/ui/layout/hexagon-enum.stderr +++ b/tests/ui/layout/hexagon-enum.stderr @@ -50,10 +50,8 @@ error: layout_of(A) = Layout { backend_repr: Memory { sized: true, }, - fields: Arbitrary { - offsets: [], - in_memory_order: [], - }, + field_offsets: [], + fields_in_memory_order: [], largest_niche: None, uninhabited: false, max_repr_align: None, @@ -123,10 +121,8 @@ error: layout_of(B) = Layout { backend_repr: Memory { sized: true, }, - fields: Arbitrary { - offsets: [], - in_memory_order: [], - }, + field_offsets: [], + fields_in_memory_order: [], largest_niche: None, uninhabited: false, max_repr_align: None, @@ -196,10 +192,8 @@ error: layout_of(C) = Layout { backend_repr: Memory { sized: true, }, - fields: Arbitrary { - offsets: [], - in_memory_order: [], - }, + field_offsets: [], + fields_in_memory_order: [], largest_niche: None, uninhabited: false, max_repr_align: None, @@ -269,10 +263,8 @@ error: layout_of(P) = Layout { backend_repr: Memory { sized: true, }, - fields: Arbitrary { - offsets: [], - in_memory_order: [], - }, + field_offsets: [], + fields_in_memory_order: [], largest_niche: None, uninhabited: false, max_repr_align: None, @@ -342,10 +334,8 @@ error: layout_of(T) = Layout { backend_repr: Memory { sized: true, }, - fields: Arbitrary { - offsets: [], - in_memory_order: [], - }, + field_offsets: [], + fields_in_memory_order: [], largest_niche: None, uninhabited: false, max_repr_align: None, diff --git a/tests/ui/layout/issue-96158-scalarpair-payload-might-be-uninit.stderr b/tests/ui/layout/issue-96158-scalarpair-payload-might-be-uninit.stderr index 9f78cfd792365..c9d7551a3d954 100644 --- a/tests/ui/layout/issue-96158-scalarpair-payload-might-be-uninit.stderr +++ b/tests/ui/layout/issue-96158-scalarpair-payload-might-be-uninit.stderr @@ -68,14 +68,12 @@ error: layout_of(MissingPayloadField) = Layout { ), }, ), - fields: Arbitrary { - offsets: [ - Size(1 bytes), - ], - in_memory_order: [ - 0, - ], - }, + field_offsets: [ + Size(1 bytes), + ], + fields_in_memory_order: [ + 0, + ], largest_niche: None, uninhabited: false, max_repr_align: None, @@ -90,10 +88,8 @@ error: layout_of(MissingPayloadField) = Layout { backend_repr: Memory { sized: true, }, - fields: Arbitrary { - offsets: [], - in_memory_order: [], - }, + field_offsets: [], + fields_in_memory_order: [], largest_niche: None, uninhabited: false, max_repr_align: None, @@ -183,14 +179,12 @@ error: layout_of(CommonPayloadField) = Layout { valid_range: 0..=255, }, ), - fields: Arbitrary { - offsets: [ - Size(1 bytes), - ], - in_memory_order: [ - 0, - ], - }, + field_offsets: [ + Size(1 bytes), + ], + fields_in_memory_order: [ + 0, + ], largest_niche: None, uninhabited: false, max_repr_align: None, @@ -218,14 +212,12 @@ error: layout_of(CommonPayloadField) = Layout { valid_range: 0..=255, }, ), - fields: Arbitrary { - offsets: [ - Size(1 bytes), - ], - in_memory_order: [ - 0, - ], - }, + field_offsets: [ + Size(1 bytes), + ], + fields_in_memory_order: [ + 0, + ], largest_niche: None, uninhabited: false, max_repr_align: None, @@ -313,14 +305,12 @@ error: layout_of(CommonPayloadFieldIsMaybeUninit) = Layout { ), }, ), - fields: Arbitrary { - offsets: [ - Size(1 bytes), - ], - in_memory_order: [ - 0, - ], - }, + field_offsets: [ + Size(1 bytes), + ], + fields_in_memory_order: [ + 0, + ], largest_niche: None, uninhabited: false, max_repr_align: None, @@ -347,14 +337,12 @@ error: layout_of(CommonPayloadFieldIsMaybeUninit) = Layout { ), }, ), - fields: Arbitrary { - offsets: [ - Size(1 bytes), - ], - in_memory_order: [ - 0, - ], - }, + field_offsets: [ + Size(1 bytes), + ], + fields_in_memory_order: [ + 0, + ], largest_niche: None, uninhabited: false, max_repr_align: None, @@ -447,16 +435,14 @@ error: layout_of(NicheFirst) = Layout { valid_range: 0..=255, }, ), - fields: Arbitrary { - offsets: [ - Size(0 bytes), - Size(1 bytes), - ], - in_memory_order: [ - 0, - 1, - ], - }, + field_offsets: [ + Size(0 bytes), + Size(1 bytes), + ], + fields_in_memory_order: [ + 0, + 1, + ], largest_niche: Some( Niche { offset: Size(0 bytes), @@ -480,10 +466,8 @@ error: layout_of(NicheFirst) = Layout { backend_repr: Memory { sized: true, }, - fields: Arbitrary { - offsets: [], - in_memory_order: [], - }, + field_offsets: [], + fields_in_memory_order: [], largest_niche: None, uninhabited: false, max_repr_align: None, @@ -498,10 +482,8 @@ error: layout_of(NicheFirst) = Layout { backend_repr: Memory { sized: true, }, - fields: Arbitrary { - offsets: [], - in_memory_order: [], - }, + field_offsets: [], + fields_in_memory_order: [], largest_niche: None, uninhabited: false, max_repr_align: None, @@ -594,16 +576,14 @@ error: layout_of(NicheSecond) = Layout { valid_range: 0..=255, }, ), - fields: Arbitrary { - offsets: [ - Size(1 bytes), - Size(0 bytes), - ], - in_memory_order: [ - 1, - 0, - ], - }, + field_offsets: [ + Size(1 bytes), + Size(0 bytes), + ], + fields_in_memory_order: [ + 1, + 0, + ], largest_niche: Some( Niche { offset: Size(0 bytes), @@ -627,10 +607,8 @@ error: layout_of(NicheSecond) = Layout { backend_repr: Memory { sized: true, }, - fields: Arbitrary { - offsets: [], - in_memory_order: [], - }, + field_offsets: [], + fields_in_memory_order: [], largest_niche: None, uninhabited: false, max_repr_align: None, @@ -645,10 +623,8 @@ error: layout_of(NicheSecond) = Layout { backend_repr: Memory { sized: true, }, - fields: Arbitrary { - offsets: [], - in_memory_order: [], - }, + field_offsets: [], + fields_in_memory_order: [], largest_niche: None, uninhabited: false, max_repr_align: None, diff --git a/tests/ui/layout/issue-96185-overaligned-enum.stderr b/tests/ui/layout/issue-96185-overaligned-enum.stderr index cc5818e78c71b..7e88d4c6fcc9e 100644 --- a/tests/ui/layout/issue-96185-overaligned-enum.stderr +++ b/tests/ui/layout/issue-96185-overaligned-enum.stderr @@ -44,10 +44,8 @@ error: layout_of(Aligned1) = Layout { backend_repr: Memory { sized: true, }, - fields: Arbitrary { - offsets: [], - in_memory_order: [], - }, + field_offsets: [], + fields_in_memory_order: [], largest_niche: None, uninhabited: false, max_repr_align: Some( @@ -64,10 +62,8 @@ error: layout_of(Aligned1) = Layout { backend_repr: Memory { sized: true, }, - fields: Arbitrary { - offsets: [], - in_memory_order: [], - }, + field_offsets: [], + fields_in_memory_order: [], largest_niche: None, uninhabited: false, max_repr_align: Some( @@ -141,10 +137,8 @@ error: layout_of(Aligned2) = Layout { backend_repr: Memory { sized: true, }, - fields: Arbitrary { - offsets: [], - in_memory_order: [], - }, + field_offsets: [], + fields_in_memory_order: [], largest_niche: None, uninhabited: false, max_repr_align: Some( @@ -161,10 +155,8 @@ error: layout_of(Aligned2) = Layout { backend_repr: Memory { sized: true, }, - fields: Arbitrary { - offsets: [], - in_memory_order: [], - }, + field_offsets: [], + fields_in_memory_order: [], largest_niche: None, uninhabited: false, max_repr_align: Some( diff --git a/tests/ui/layout/thumb-enum.stderr b/tests/ui/layout/thumb-enum.stderr index 3c5f906d67aa8..053ea65a48b79 100644 --- a/tests/ui/layout/thumb-enum.stderr +++ b/tests/ui/layout/thumb-enum.stderr @@ -50,10 +50,8 @@ error: layout_of(A) = Layout { backend_repr: Memory { sized: true, }, - fields: Arbitrary { - offsets: [], - in_memory_order: [], - }, + field_offsets: [], + fields_in_memory_order: [], largest_niche: None, uninhabited: false, max_repr_align: None, @@ -123,10 +121,8 @@ error: layout_of(B) = Layout { backend_repr: Memory { sized: true, }, - fields: Arbitrary { - offsets: [], - in_memory_order: [], - }, + field_offsets: [], + fields_in_memory_order: [], largest_niche: None, uninhabited: false, max_repr_align: None, @@ -196,10 +192,8 @@ error: layout_of(C) = Layout { backend_repr: Memory { sized: true, }, - fields: Arbitrary { - offsets: [], - in_memory_order: [], - }, + field_offsets: [], + fields_in_memory_order: [], largest_niche: None, uninhabited: false, max_repr_align: None, @@ -269,10 +263,8 @@ error: layout_of(P) = Layout { backend_repr: Memory { sized: true, }, - fields: Arbitrary { - offsets: [], - in_memory_order: [], - }, + field_offsets: [], + fields_in_memory_order: [], largest_niche: None, uninhabited: false, max_repr_align: None, @@ -342,10 +334,8 @@ error: layout_of(T) = Layout { backend_repr: Memory { sized: true, }, - fields: Arbitrary { - offsets: [], - in_memory_order: [], - }, + field_offsets: [], + fields_in_memory_order: [], largest_niche: None, uninhabited: false, max_repr_align: None, diff --git a/tests/ui/layout/zero-sized-array-enum-niche.stderr b/tests/ui/layout/zero-sized-array-enum-niche.stderr index 1a1e261eae5ee..e39cde3f1a2eb 100644 --- a/tests/ui/layout/zero-sized-array-enum-niche.stderr +++ b/tests/ui/layout/zero-sized-array-enum-niche.stderr @@ -44,14 +44,12 @@ error: layout_of(Result<[u32; 0], bool>) = Layout { backend_repr: Memory { sized: true, }, - fields: Arbitrary { - offsets: [ - Size(4 bytes), - ], - in_memory_order: [ - 0, - ], - }, + field_offsets: [ + Size(4 bytes), + ], + fields_in_memory_order: [ + 0, + ], largest_niche: None, uninhabited: false, max_repr_align: None, @@ -66,14 +64,12 @@ error: layout_of(Result<[u32; 0], bool>) = Layout { backend_repr: Memory { sized: true, }, - fields: Arbitrary { - offsets: [ - Size(1 bytes), - ], - in_memory_order: [ - 0, - ], - }, + field_offsets: [ + Size(1 bytes), + ], + fields_in_memory_order: [ + 0, + ], largest_niche: Some( Niche { offset: Size(1 bytes), @@ -146,14 +142,12 @@ error: layout_of(MultipleAlignments) = Layout { backend_repr: Memory { sized: true, }, - fields: Arbitrary { - offsets: [ - Size(2 bytes), - ], - in_memory_order: [ - 0, - ], - }, + field_offsets: [ + Size(2 bytes), + ], + fields_in_memory_order: [ + 0, + ], largest_niche: None, uninhabited: false, max_repr_align: None, @@ -168,14 +162,12 @@ error: layout_of(MultipleAlignments) = Layout { backend_repr: Memory { sized: true, }, - fields: Arbitrary { - offsets: [ - Size(4 bytes), - ], - in_memory_order: [ - 0, - ], - }, + field_offsets: [ + Size(4 bytes), + ], + fields_in_memory_order: [ + 0, + ], largest_niche: None, uninhabited: false, max_repr_align: None, @@ -190,14 +182,12 @@ error: layout_of(MultipleAlignments) = Layout { backend_repr: Memory { sized: true, }, - fields: Arbitrary { - offsets: [ - Size(1 bytes), - ], - in_memory_order: [ - 0, - ], - }, + field_offsets: [ + Size(1 bytes), + ], + fields_in_memory_order: [ + 0, + ], largest_niche: Some( Niche { offset: Size(1 bytes), @@ -270,14 +260,12 @@ error: layout_of(Result<[u32; 0], Packed>>) = Layout { backend_repr: Memory { sized: true, }, - fields: Arbitrary { - offsets: [ - Size(4 bytes), - ], - in_memory_order: [ - 0, - ], - }, + field_offsets: [ + Size(4 bytes), + ], + fields_in_memory_order: [ + 0, + ], largest_niche: None, uninhabited: false, max_repr_align: None, @@ -292,14 +280,12 @@ error: layout_of(Result<[u32; 0], Packed>>) = Layout { backend_repr: Memory { sized: true, }, - fields: Arbitrary { - offsets: [ - Size(1 bytes), - ], - in_memory_order: [ - 0, - ], - }, + field_offsets: [ + Size(1 bytes), + ], + fields_in_memory_order: [ + 0, + ], largest_niche: Some( Niche { offset: Size(1 bytes), @@ -376,14 +362,12 @@ error: layout_of(Result<[u32; 0], Packed>) = Layout { backend_repr: Memory { sized: true, }, - fields: Arbitrary { - offsets: [ - Size(0 bytes), - ], - in_memory_order: [ - 0, - ], - }, + field_offsets: [ + Size(0 bytes), + ], + fields_in_memory_order: [ + 0, + ], largest_niche: None, uninhabited: false, max_repr_align: None, @@ -398,14 +382,12 @@ error: layout_of(Result<[u32; 0], Packed>) = Layout { backend_repr: Memory { sized: true, }, - fields: Arbitrary { - offsets: [ - Size(0 bytes), - ], - in_memory_order: [ - 0, - ], - }, + field_offsets: [ + Size(0 bytes), + ], + fields_in_memory_order: [ + 0, + ], largest_niche: Some( Niche { offset: Size(0 bytes), diff --git a/tests/ui/repr/repr-c-dead-variants.aarch64-unknown-linux-gnu.stderr b/tests/ui/repr/repr-c-dead-variants.aarch64-unknown-linux-gnu.stderr index e8a99c7226af5..46a1eee98c772 100644 --- a/tests/ui/repr/repr-c-dead-variants.aarch64-unknown-linux-gnu.stderr +++ b/tests/ui/repr/repr-c-dead-variants.aarch64-unknown-linux-gnu.stderr @@ -56,14 +56,12 @@ error: layout_of(Univariant) = Layout { valid_range: 0..=0, }, ), - fields: Arbitrary { - offsets: [ - Size(4 bytes), - ], - in_memory_order: [ - 0, - ], - }, + field_offsets: [ + Size(4 bytes), + ], + fields_in_memory_order: [ + 0, + ], largest_niche: None, uninhabited: true, max_repr_align: None, @@ -151,14 +149,12 @@ error: layout_of(TwoVariants) = Layout { ), }, ), - fields: Arbitrary { - offsets: [ - Size(4 bytes), - ], - in_memory_order: [ - 0, - ], - }, + field_offsets: [ + Size(4 bytes), + ], + fields_in_memory_order: [ + 0, + ], largest_niche: None, uninhabited: true, max_repr_align: None, @@ -185,14 +181,12 @@ error: layout_of(TwoVariants) = Layout { ), }, ), - fields: Arbitrary { - offsets: [ - Size(4 bytes), - ], - in_memory_order: [ - 0, - ], - }, + field_offsets: [ + Size(4 bytes), + ], + fields_in_memory_order: [ + 0, + ], largest_niche: None, uninhabited: false, max_repr_align: None, @@ -256,16 +250,14 @@ error: layout_of(DeadBranchHasOtherField) = Layout { backend_repr: Memory { sized: true, }, - fields: Arbitrary { - offsets: [ - Size(8 bytes), - Size(8 bytes), - ], - in_memory_order: [ - 0, - 1, - ], - }, + field_offsets: [ + Size(8 bytes), + Size(8 bytes), + ], + fields_in_memory_order: [ + 0, + 1, + ], largest_niche: None, uninhabited: true, max_repr_align: Some( @@ -282,14 +274,12 @@ error: layout_of(DeadBranchHasOtherField) = Layout { backend_repr: Memory { sized: true, }, - fields: Arbitrary { - offsets: [ - Size(8 bytes), - ], - in_memory_order: [ - 0, - ], - }, + field_offsets: [ + Size(8 bytes), + ], + fields_in_memory_order: [ + 0, + ], largest_niche: None, uninhabited: false, max_repr_align: None, diff --git a/tests/ui/repr/repr-c-dead-variants.armebv7r-none-eabi.stderr b/tests/ui/repr/repr-c-dead-variants.armebv7r-none-eabi.stderr index 30e0b7923bbd0..35c0d22f23254 100644 --- a/tests/ui/repr/repr-c-dead-variants.armebv7r-none-eabi.stderr +++ b/tests/ui/repr/repr-c-dead-variants.armebv7r-none-eabi.stderr @@ -56,14 +56,12 @@ error: layout_of(Univariant) = Layout { valid_range: 0..=0, }, ), - fields: Arbitrary { - offsets: [ - Size(1 bytes), - ], - in_memory_order: [ - 0, - ], - }, + field_offsets: [ + Size(1 bytes), + ], + fields_in_memory_order: [ + 0, + ], largest_niche: None, uninhabited: true, max_repr_align: None, @@ -151,14 +149,12 @@ error: layout_of(TwoVariants) = Layout { ), }, ), - fields: Arbitrary { - offsets: [ - Size(1 bytes), - ], - in_memory_order: [ - 0, - ], - }, + field_offsets: [ + Size(1 bytes), + ], + fields_in_memory_order: [ + 0, + ], largest_niche: None, uninhabited: true, max_repr_align: None, @@ -185,14 +181,12 @@ error: layout_of(TwoVariants) = Layout { ), }, ), - fields: Arbitrary { - offsets: [ - Size(1 bytes), - ], - in_memory_order: [ - 0, - ], - }, + field_offsets: [ + Size(1 bytes), + ], + fields_in_memory_order: [ + 0, + ], largest_niche: None, uninhabited: false, max_repr_align: None, @@ -256,16 +250,14 @@ error: layout_of(DeadBranchHasOtherField) = Layout { backend_repr: Memory { sized: true, }, - fields: Arbitrary { - offsets: [ - Size(8 bytes), - Size(8 bytes), - ], - in_memory_order: [ - 0, - 1, - ], - }, + field_offsets: [ + Size(8 bytes), + Size(8 bytes), + ], + fields_in_memory_order: [ + 0, + 1, + ], largest_niche: None, uninhabited: true, max_repr_align: Some( @@ -282,14 +274,12 @@ error: layout_of(DeadBranchHasOtherField) = Layout { backend_repr: Memory { sized: true, }, - fields: Arbitrary { - offsets: [ - Size(8 bytes), - ], - in_memory_order: [ - 0, - ], - }, + field_offsets: [ + Size(8 bytes), + ], + fields_in_memory_order: [ + 0, + ], largest_niche: None, uninhabited: false, max_repr_align: None, diff --git a/tests/ui/repr/repr-c-dead-variants.i686-pc-windows-msvc.stderr b/tests/ui/repr/repr-c-dead-variants.i686-pc-windows-msvc.stderr index e8a99c7226af5..46a1eee98c772 100644 --- a/tests/ui/repr/repr-c-dead-variants.i686-pc-windows-msvc.stderr +++ b/tests/ui/repr/repr-c-dead-variants.i686-pc-windows-msvc.stderr @@ -56,14 +56,12 @@ error: layout_of(Univariant) = Layout { valid_range: 0..=0, }, ), - fields: Arbitrary { - offsets: [ - Size(4 bytes), - ], - in_memory_order: [ - 0, - ], - }, + field_offsets: [ + Size(4 bytes), + ], + fields_in_memory_order: [ + 0, + ], largest_niche: None, uninhabited: true, max_repr_align: None, @@ -151,14 +149,12 @@ error: layout_of(TwoVariants) = Layout { ), }, ), - fields: Arbitrary { - offsets: [ - Size(4 bytes), - ], - in_memory_order: [ - 0, - ], - }, + field_offsets: [ + Size(4 bytes), + ], + fields_in_memory_order: [ + 0, + ], largest_niche: None, uninhabited: true, max_repr_align: None, @@ -185,14 +181,12 @@ error: layout_of(TwoVariants) = Layout { ), }, ), - fields: Arbitrary { - offsets: [ - Size(4 bytes), - ], - in_memory_order: [ - 0, - ], - }, + field_offsets: [ + Size(4 bytes), + ], + fields_in_memory_order: [ + 0, + ], largest_niche: None, uninhabited: false, max_repr_align: None, @@ -256,16 +250,14 @@ error: layout_of(DeadBranchHasOtherField) = Layout { backend_repr: Memory { sized: true, }, - fields: Arbitrary { - offsets: [ - Size(8 bytes), - Size(8 bytes), - ], - in_memory_order: [ - 0, - 1, - ], - }, + field_offsets: [ + Size(8 bytes), + Size(8 bytes), + ], + fields_in_memory_order: [ + 0, + 1, + ], largest_niche: None, uninhabited: true, max_repr_align: Some( @@ -282,14 +274,12 @@ error: layout_of(DeadBranchHasOtherField) = Layout { backend_repr: Memory { sized: true, }, - fields: Arbitrary { - offsets: [ - Size(8 bytes), - ], - in_memory_order: [ - 0, - ], - }, + field_offsets: [ + Size(8 bytes), + ], + fields_in_memory_order: [ + 0, + ], largest_niche: None, uninhabited: false, max_repr_align: None, diff --git a/tests/ui/repr/repr-c-dead-variants.x86_64-unknown-linux-gnu.stderr b/tests/ui/repr/repr-c-dead-variants.x86_64-unknown-linux-gnu.stderr index e8a99c7226af5..46a1eee98c772 100644 --- a/tests/ui/repr/repr-c-dead-variants.x86_64-unknown-linux-gnu.stderr +++ b/tests/ui/repr/repr-c-dead-variants.x86_64-unknown-linux-gnu.stderr @@ -56,14 +56,12 @@ error: layout_of(Univariant) = Layout { valid_range: 0..=0, }, ), - fields: Arbitrary { - offsets: [ - Size(4 bytes), - ], - in_memory_order: [ - 0, - ], - }, + field_offsets: [ + Size(4 bytes), + ], + fields_in_memory_order: [ + 0, + ], largest_niche: None, uninhabited: true, max_repr_align: None, @@ -151,14 +149,12 @@ error: layout_of(TwoVariants) = Layout { ), }, ), - fields: Arbitrary { - offsets: [ - Size(4 bytes), - ], - in_memory_order: [ - 0, - ], - }, + field_offsets: [ + Size(4 bytes), + ], + fields_in_memory_order: [ + 0, + ], largest_niche: None, uninhabited: true, max_repr_align: None, @@ -185,14 +181,12 @@ error: layout_of(TwoVariants) = Layout { ), }, ), - fields: Arbitrary { - offsets: [ - Size(4 bytes), - ], - in_memory_order: [ - 0, - ], - }, + field_offsets: [ + Size(4 bytes), + ], + fields_in_memory_order: [ + 0, + ], largest_niche: None, uninhabited: false, max_repr_align: None, @@ -256,16 +250,14 @@ error: layout_of(DeadBranchHasOtherField) = Layout { backend_repr: Memory { sized: true, }, - fields: Arbitrary { - offsets: [ - Size(8 bytes), - Size(8 bytes), - ], - in_memory_order: [ - 0, - 1, - ], - }, + field_offsets: [ + Size(8 bytes), + Size(8 bytes), + ], + fields_in_memory_order: [ + 0, + 1, + ], largest_niche: None, uninhabited: true, max_repr_align: Some( @@ -282,14 +274,12 @@ error: layout_of(DeadBranchHasOtherField) = Layout { backend_repr: Memory { sized: true, }, - fields: Arbitrary { - offsets: [ - Size(8 bytes), - ], - in_memory_order: [ - 0, - ], - }, + field_offsets: [ + Size(8 bytes), + ], + fields_in_memory_order: [ + 0, + ], largest_niche: None, uninhabited: false, max_repr_align: None, diff --git a/tests/ui/repr/repr-c-int-dead-variants.stderr b/tests/ui/repr/repr-c-int-dead-variants.stderr index 73a2898b67608..0f0099bb18cc8 100644 --- a/tests/ui/repr/repr-c-int-dead-variants.stderr +++ b/tests/ui/repr/repr-c-int-dead-variants.stderr @@ -56,14 +56,12 @@ error: layout_of(UnivariantU8) = Layout { valid_range: 0..=0, }, ), - fields: Arbitrary { - offsets: [ - Size(1 bytes), - ], - in_memory_order: [ - 0, - ], - }, + field_offsets: [ + Size(1 bytes), + ], + fields_in_memory_order: [ + 0, + ], largest_niche: None, uninhabited: true, max_repr_align: None, @@ -151,14 +149,12 @@ error: layout_of(TwoVariantsU8) = Layout { ), }, ), - fields: Arbitrary { - offsets: [ - Size(1 bytes), - ], - in_memory_order: [ - 0, - ], - }, + field_offsets: [ + Size(1 bytes), + ], + fields_in_memory_order: [ + 0, + ], largest_niche: None, uninhabited: true, max_repr_align: None, @@ -185,14 +181,12 @@ error: layout_of(TwoVariantsU8) = Layout { ), }, ), - fields: Arbitrary { - offsets: [ - Size(1 bytes), - ], - in_memory_order: [ - 0, - ], - }, + field_offsets: [ + Size(1 bytes), + ], + fields_in_memory_order: [ + 0, + ], largest_niche: None, uninhabited: false, max_repr_align: None, @@ -256,16 +250,14 @@ error: layout_of(DeadBranchHasOtherFieldU8) = Layout { backend_repr: Memory { sized: true, }, - fields: Arbitrary { - offsets: [ - Size(8 bytes), - Size(8 bytes), - ], - in_memory_order: [ - 0, - 1, - ], - }, + field_offsets: [ + Size(8 bytes), + Size(8 bytes), + ], + fields_in_memory_order: [ + 0, + 1, + ], largest_niche: None, uninhabited: true, max_repr_align: Some( @@ -282,14 +274,12 @@ error: layout_of(DeadBranchHasOtherFieldU8) = Layout { backend_repr: Memory { sized: true, }, - fields: Arbitrary { - offsets: [ - Size(8 bytes), - ], - in_memory_order: [ - 0, - ], - }, + field_offsets: [ + Size(8 bytes), + ], + fields_in_memory_order: [ + 0, + ], largest_niche: None, uninhabited: false, max_repr_align: None, diff --git a/tests/ui/type/pattern_types/non_null.stderr b/tests/ui/type/pattern_types/non_null.stderr index 1911f0e328410..fb9f855e71b92 100644 --- a/tests/ui/type/pattern_types/non_null.stderr +++ b/tests/ui/type/pattern_types/non_null.stderr @@ -94,10 +94,8 @@ error: layout_of(Option<(*const ()) is !null>) = Layout { backend_repr: Memory { sized: true, }, - fields: Arbitrary { - offsets: [], - in_memory_order: [], - }, + field_offsets: [], + fields_in_memory_order: [], largest_niche: None, uninhabited: false, max_repr_align: None, @@ -119,14 +117,12 @@ error: layout_of(Option<(*const ()) is !null>) = Layout { valid_range: 1..=18446744073709551615, }, ), - fields: Arbitrary { - offsets: [ - Size(0 bytes), - ], - in_memory_order: [ - 0, - ], - }, + field_offsets: [ + Size(0 bytes), + ], + fields_in_memory_order: [ + 0, + ], largest_niche: Some( Niche { offset: Size(0 bytes), diff --git a/tests/ui/type/pattern_types/range_patterns.stderr b/tests/ui/type/pattern_types/range_patterns.stderr index 392b84c2647c0..661bd5d3922d6 100644 --- a/tests/ui/type/pattern_types/range_patterns.stderr +++ b/tests/ui/type/pattern_types/range_patterns.stderr @@ -135,10 +135,8 @@ error: layout_of(Option<(u32) is 1..>) = Layout { backend_repr: Memory { sized: true, }, - fields: Arbitrary { - offsets: [], - in_memory_order: [], - }, + field_offsets: [], + fields_in_memory_order: [], largest_niche: None, uninhabited: false, max_repr_align: None, @@ -159,14 +157,12 @@ error: layout_of(Option<(u32) is 1..>) = Layout { valid_range: 1..=4294967295, }, ), - fields: Arbitrary { - offsets: [ - Size(0 bytes), - ], - in_memory_order: [ - 0, - ], - }, + field_offsets: [ + Size(0 bytes), + ], + fields_in_memory_order: [ + 0, + ], largest_niche: Some( Niche { offset: Size(0 bytes), @@ -240,10 +236,8 @@ error: layout_of(Option>) = Layout { backend_repr: Memory { sized: true, }, - fields: Arbitrary { - offsets: [], - in_memory_order: [], - }, + field_offsets: [], + fields_in_memory_order: [], largest_niche: None, uninhabited: false, max_repr_align: None, @@ -264,14 +258,12 @@ error: layout_of(Option>) = Layout { valid_range: 1..=4294967295, }, ), - fields: Arbitrary { - offsets: [ - Size(0 bytes), - ], - in_memory_order: [ - 0, - ], - }, + field_offsets: [ + Size(0 bytes), + ], + fields_in_memory_order: [ + 0, + ], largest_niche: Some( Niche { offset: Size(0 bytes), From 34599644085de9fc360665367bff14ac2e78bbcd Mon Sep 17 00:00:00 2001 From: Moulins Date: Thu, 18 Dec 2025 19:07:38 +0100 Subject: [PATCH 06/29] Remove unused `VariantLayout.randomization_seed` field This field is only used during layout calculations, so re-synthetized `LayoutData`s for enum variants can use a dummy value instead. --- compiler/rustc_abi/src/layout.rs | 14 ++++---------- compiler/rustc_abi/src/layout/simple.rs | 6 +++++- compiler/rustc_abi/src/lib.rs | 2 -- tests/ui/enum-discriminant/wrapping_niche.stderr | 6 ------ tests/ui/layout/debug.stderr | 8 -------- tests/ui/layout/hexagon-enum.stderr | 5 ----- ...96158-scalarpair-payload-might-be-uninit.stderr | 12 ------------ .../ui/layout/issue-96185-overaligned-enum.stderr | 4 ---- tests/ui/layout/thumb-enum.stderr | 5 ----- tests/ui/layout/zero-sized-array-enum-niche.stderr | 9 --------- ...-dead-variants.aarch64-unknown-linux-gnu.stderr | 5 ----- .../repr-c-dead-variants.armebv7r-none-eabi.stderr | 5 ----- ...epr-c-dead-variants.i686-pc-windows-msvc.stderr | 5 ----- ...c-dead-variants.x86_64-unknown-linux-gnu.stderr | 5 ----- tests/ui/repr/repr-c-int-dead-variants.stderr | 5 ----- tests/ui/type/pattern_types/non_null.stderr | 2 -- tests/ui/type/pattern_types/range_patterns.stderr | 4 ---- 17 files changed, 9 insertions(+), 93 deletions(-) diff --git a/compiler/rustc_abi/src/layout.rs b/compiler/rustc_abi/src/layout.rs index f12c0c5c248d0..3910e342ff74d 100644 --- a/compiler/rustc_abi/src/layout.rs +++ b/compiler/rustc_abi/src/layout.rs @@ -600,6 +600,7 @@ impl LayoutCalculator { let mut align = dl.aggregate_align; let mut max_repr_align = repr.align; let mut unadjusted_abi_align = align; + let mut combined_seed = repr.field_shuffle_seed; let mut variant_layouts = variants .iter() @@ -609,6 +610,7 @@ impl LayoutCalculator { align = align.max(st.align.abi); max_repr_align = max_repr_align.max(st.max_repr_align); unadjusted_abi_align = unadjusted_abi_align.max(st.unadjusted_abi_align); + combined_seed = combined_seed.wrapping_add(st.randomization_seed); Some(VariantLayout::from_layout(st)) }) @@ -702,11 +704,6 @@ impl LayoutCalculator { BackendRepr::Memory { sized: true } }; - let combined_seed = variant_layouts - .iter() - .map(|v| v.randomization_seed) - .fold(repr.field_shuffle_seed, |acc, seed| acc.wrapping_add(seed)); - let layout = LayoutData { variants: Variants::Multiple { tag: niche_scalar, @@ -799,6 +796,7 @@ impl LayoutCalculator { let mut align = dl.aggregate_align; let mut max_repr_align = repr.align; let mut unadjusted_abi_align = align; + let mut combined_seed = repr.field_shuffle_seed; let mut size = Size::ZERO; @@ -842,6 +840,7 @@ impl LayoutCalculator { align = align.max(st.align.abi); max_repr_align = max_repr_align.max(st.max_repr_align); unadjusted_abi_align = unadjusted_abi_align.max(st.unadjusted_abi_align); + combined_seed = combined_seed.wrapping_add(st.randomization_seed); Ok(VariantLayout::from_layout(st)) }) .collect::, _>>()?; @@ -1042,11 +1041,6 @@ impl LayoutCalculator { let largest_niche = Niche::from_scalar(dl, Size::ZERO, tag); - let combined_seed = layout_variants - .iter() - .map(|v| v.randomization_seed) - .fold(repr.field_shuffle_seed, |acc, seed| acc.wrapping_add(seed)); - let tagged_layout = LayoutData { variants: Variants::Multiple { tag, diff --git a/compiler/rustc_abi/src/layout/simple.rs b/compiler/rustc_abi/src/layout/simple.rs index 1ce22a0293346..6442fe69d202c 100644 --- a/compiler/rustc_abi/src/layout/simple.rs +++ b/compiler/rustc_abi/src/layout/simple.rs @@ -143,6 +143,8 @@ impl LayoutData { size: Size::ZERO, max_repr_align: None, unadjusted_abi_align: dl.i8_align, + // Variant layouts never flow back into actual layout computations, + // so dummy values are fine here. randomization_seed: Hash64::ZERO, } } @@ -167,7 +169,9 @@ impl LayoutData { size: layout.size, max_repr_align: layout.max_repr_align, unadjusted_abi_align: layout.unadjusted_abi_align, - randomization_seed: layout.randomization_seed, + // Variant layouts never flow back into actual layout computations, + // so dummy values are fine here. + randomization_seed: Hash64::ZERO, } } } diff --git a/compiler/rustc_abi/src/lib.rs b/compiler/rustc_abi/src/lib.rs index 92d9e4bb7e9bf..108a4daf71358 100644 --- a/compiler/rustc_abi/src/lib.rs +++ b/compiler/rustc_abi/src/lib.rs @@ -2333,7 +2333,6 @@ pub struct VariantLayout { uninhabited: bool, max_repr_align: Option, unadjusted_abi_align: Align, - randomization_seed: Hash64, } impl VariantLayout { @@ -2352,7 +2351,6 @@ impl VariantLayout { uninhabited: layout.uninhabited, max_repr_align: layout.max_repr_align, unadjusted_abi_align: layout.unadjusted_abi_align, - randomization_seed: layout.randomization_seed, } } diff --git a/tests/ui/enum-discriminant/wrapping_niche.stderr b/tests/ui/enum-discriminant/wrapping_niche.stderr index b3b0a560b28ab..bd42f79c38b39 100644 --- a/tests/ui/enum-discriminant/wrapping_niche.stderr +++ b/tests/ui/enum-discriminant/wrapping_niche.stderr @@ -56,7 +56,6 @@ error: layout_of(UnsignedAroundZero) = Layout { uninhabited: false, max_repr_align: None, unadjusted_abi_align: Align(2 bytes), - randomization_seed: 9885373149222004003, }, VariantLayout { size: Size(2 bytes), @@ -72,7 +71,6 @@ error: layout_of(UnsignedAroundZero) = Layout { uninhabited: false, max_repr_align: None, unadjusted_abi_align: Align(2 bytes), - randomization_seed: 9885373149222004003, }, VariantLayout { size: Size(2 bytes), @@ -88,7 +86,6 @@ error: layout_of(UnsignedAroundZero) = Layout { uninhabited: false, max_repr_align: None, unadjusted_abi_align: Align(2 bytes), - randomization_seed: 9885373149222004003, }, ], }, @@ -159,7 +156,6 @@ error: layout_of(SignedAroundZero) = Layout { uninhabited: false, max_repr_align: None, unadjusted_abi_align: Align(2 bytes), - randomization_seed: 2684536712112553499, }, VariantLayout { size: Size(2 bytes), @@ -175,7 +171,6 @@ error: layout_of(SignedAroundZero) = Layout { uninhabited: false, max_repr_align: None, unadjusted_abi_align: Align(2 bytes), - randomization_seed: 2684536712112553499, }, VariantLayout { size: Size(2 bytes), @@ -191,7 +186,6 @@ error: layout_of(SignedAroundZero) = Layout { uninhabited: false, max_repr_align: None, unadjusted_abi_align: Align(2 bytes), - randomization_seed: 2684536712112553499, }, ], }, diff --git a/tests/ui/layout/debug.stderr b/tests/ui/layout/debug.stderr index 84f5c1169acdc..1008604e75e9b 100644 --- a/tests/ui/layout/debug.stderr +++ b/tests/ui/layout/debug.stderr @@ -72,7 +72,6 @@ error: layout_of(E) = Layout { uninhabited: false, max_repr_align: None, unadjusted_abi_align: Align(1 bytes), - randomization_seed: $SEED, }, VariantLayout { size: Size(12 bytes), @@ -96,7 +95,6 @@ error: layout_of(E) = Layout { uninhabited: true, max_repr_align: None, unadjusted_abi_align: Align(4 bytes), - randomization_seed: $SEED, }, ], }, @@ -263,7 +261,6 @@ error: layout_of(Result) = Layout { uninhabited: false, max_repr_align: None, unadjusted_abi_align: Align(4 bytes), - randomization_seed: $SEED, }, VariantLayout { size: Size(8 bytes), @@ -296,7 +293,6 @@ error: layout_of(Result) = Layout { uninhabited: false, max_repr_align: None, unadjusted_abi_align: Align(4 bytes), - randomization_seed: $SEED, }, ], }, @@ -656,7 +652,6 @@ error: layout_of(Option) = Layout { uninhabited: false, max_repr_align: None, unadjusted_abi_align: Align(1 bytes), - randomization_seed: $SEED, }, VariantLayout { size: Size(1 bytes), @@ -691,7 +686,6 @@ error: layout_of(Option) = Layout { uninhabited: false, max_repr_align: None, unadjusted_abi_align: Align(1 bytes), - randomization_seed: $SEED, }, ], }, @@ -766,7 +760,6 @@ error: layout_of(Option) = Layout { uninhabited: false, max_repr_align: None, unadjusted_abi_align: Align(1 bytes), - randomization_seed: $SEED, }, VariantLayout { size: Size(4 bytes), @@ -801,7 +794,6 @@ error: layout_of(Option) = Layout { uninhabited: false, max_repr_align: None, unadjusted_abi_align: Align(4 bytes), - randomization_seed: $SEED, }, ], }, diff --git a/tests/ui/layout/hexagon-enum.stderr b/tests/ui/layout/hexagon-enum.stderr index e00848b1b0154..73431de7016eb 100644 --- a/tests/ui/layout/hexagon-enum.stderr +++ b/tests/ui/layout/hexagon-enum.stderr @@ -56,7 +56,6 @@ error: layout_of(A) = Layout { uninhabited: false, max_repr_align: None, unadjusted_abi_align: Align(1 bytes), - randomization_seed: $SEED, }, ], }, @@ -127,7 +126,6 @@ error: layout_of(B) = Layout { uninhabited: false, max_repr_align: None, unadjusted_abi_align: Align(1 bytes), - randomization_seed: $SEED, }, ], }, @@ -198,7 +196,6 @@ error: layout_of(C) = Layout { uninhabited: false, max_repr_align: None, unadjusted_abi_align: Align(2 bytes), - randomization_seed: $SEED, }, ], }, @@ -269,7 +266,6 @@ error: layout_of(P) = Layout { uninhabited: false, max_repr_align: None, unadjusted_abi_align: Align(4 bytes), - randomization_seed: $SEED, }, ], }, @@ -340,7 +336,6 @@ error: layout_of(T) = Layout { uninhabited: false, max_repr_align: None, unadjusted_abi_align: Align(4 bytes), - randomization_seed: $SEED, }, ], }, diff --git a/tests/ui/layout/issue-96158-scalarpair-payload-might-be-uninit.stderr b/tests/ui/layout/issue-96158-scalarpair-payload-might-be-uninit.stderr index c9d7551a3d954..20f9e69ff51d4 100644 --- a/tests/ui/layout/issue-96158-scalarpair-payload-might-be-uninit.stderr +++ b/tests/ui/layout/issue-96158-scalarpair-payload-might-be-uninit.stderr @@ -78,7 +78,6 @@ error: layout_of(MissingPayloadField) = Layout { uninhabited: false, max_repr_align: None, unadjusted_abi_align: Align(1 bytes), - randomization_seed: $SEED, }, VariantLayout { size: Size(1 bytes), @@ -94,7 +93,6 @@ error: layout_of(MissingPayloadField) = Layout { uninhabited: false, max_repr_align: None, unadjusted_abi_align: Align(1 bytes), - randomization_seed: $SEED, }, ], }, @@ -189,7 +187,6 @@ error: layout_of(CommonPayloadField) = Layout { uninhabited: false, max_repr_align: None, unadjusted_abi_align: Align(1 bytes), - randomization_seed: $SEED, }, VariantLayout { size: Size(2 bytes), @@ -222,7 +219,6 @@ error: layout_of(CommonPayloadField) = Layout { uninhabited: false, max_repr_align: None, unadjusted_abi_align: Align(1 bytes), - randomization_seed: $SEED, }, ], }, @@ -315,7 +311,6 @@ error: layout_of(CommonPayloadFieldIsMaybeUninit) = Layout { uninhabited: false, max_repr_align: None, unadjusted_abi_align: Align(1 bytes), - randomization_seed: $SEED, }, VariantLayout { size: Size(2 bytes), @@ -347,7 +342,6 @@ error: layout_of(CommonPayloadFieldIsMaybeUninit) = Layout { uninhabited: false, max_repr_align: None, unadjusted_abi_align: Align(1 bytes), - randomization_seed: $SEED, }, ], }, @@ -456,7 +450,6 @@ error: layout_of(NicheFirst) = Layout { uninhabited: false, max_repr_align: None, unadjusted_abi_align: Align(1 bytes), - randomization_seed: $SEED, }, VariantLayout { size: Size(0 bytes), @@ -472,7 +465,6 @@ error: layout_of(NicheFirst) = Layout { uninhabited: false, max_repr_align: None, unadjusted_abi_align: Align(1 bytes), - randomization_seed: $SEED, }, VariantLayout { size: Size(0 bytes), @@ -488,7 +480,6 @@ error: layout_of(NicheFirst) = Layout { uninhabited: false, max_repr_align: None, unadjusted_abi_align: Align(1 bytes), - randomization_seed: $SEED, }, ], }, @@ -597,7 +588,6 @@ error: layout_of(NicheSecond) = Layout { uninhabited: false, max_repr_align: None, unadjusted_abi_align: Align(1 bytes), - randomization_seed: $SEED, }, VariantLayout { size: Size(0 bytes), @@ -613,7 +603,6 @@ error: layout_of(NicheSecond) = Layout { uninhabited: false, max_repr_align: None, unadjusted_abi_align: Align(1 bytes), - randomization_seed: $SEED, }, VariantLayout { size: Size(0 bytes), @@ -629,7 +618,6 @@ error: layout_of(NicheSecond) = Layout { uninhabited: false, max_repr_align: None, unadjusted_abi_align: Align(1 bytes), - randomization_seed: $SEED, }, ], }, diff --git a/tests/ui/layout/issue-96185-overaligned-enum.stderr b/tests/ui/layout/issue-96185-overaligned-enum.stderr index 7e88d4c6fcc9e..80efc35cf6384 100644 --- a/tests/ui/layout/issue-96185-overaligned-enum.stderr +++ b/tests/ui/layout/issue-96185-overaligned-enum.stderr @@ -52,7 +52,6 @@ error: layout_of(Aligned1) = Layout { Align(8 bytes), ), unadjusted_abi_align: Align(1 bytes), - randomization_seed: $SEED, }, VariantLayout { size: Size(8 bytes), @@ -70,7 +69,6 @@ error: layout_of(Aligned1) = Layout { Align(8 bytes), ), unadjusted_abi_align: Align(1 bytes), - randomization_seed: $SEED, }, ], }, @@ -145,7 +143,6 @@ error: layout_of(Aligned2) = Layout { Align(1 bytes), ), unadjusted_abi_align: Align(1 bytes), - randomization_seed: $SEED, }, VariantLayout { size: Size(1 bytes), @@ -163,7 +160,6 @@ error: layout_of(Aligned2) = Layout { Align(1 bytes), ), unadjusted_abi_align: Align(1 bytes), - randomization_seed: $SEED, }, ], }, diff --git a/tests/ui/layout/thumb-enum.stderr b/tests/ui/layout/thumb-enum.stderr index 053ea65a48b79..d2d4af352a093 100644 --- a/tests/ui/layout/thumb-enum.stderr +++ b/tests/ui/layout/thumb-enum.stderr @@ -56,7 +56,6 @@ error: layout_of(A) = Layout { uninhabited: false, max_repr_align: None, unadjusted_abi_align: Align(1 bytes), - randomization_seed: $SEED, }, ], }, @@ -127,7 +126,6 @@ error: layout_of(B) = Layout { uninhabited: false, max_repr_align: None, unadjusted_abi_align: Align(1 bytes), - randomization_seed: $SEED, }, ], }, @@ -198,7 +196,6 @@ error: layout_of(C) = Layout { uninhabited: false, max_repr_align: None, unadjusted_abi_align: Align(2 bytes), - randomization_seed: $SEED, }, ], }, @@ -269,7 +266,6 @@ error: layout_of(P) = Layout { uninhabited: false, max_repr_align: None, unadjusted_abi_align: Align(4 bytes), - randomization_seed: $SEED, }, ], }, @@ -340,7 +336,6 @@ error: layout_of(T) = Layout { uninhabited: false, max_repr_align: None, unadjusted_abi_align: Align(4 bytes), - randomization_seed: $SEED, }, ], }, diff --git a/tests/ui/layout/zero-sized-array-enum-niche.stderr b/tests/ui/layout/zero-sized-array-enum-niche.stderr index e39cde3f1a2eb..dabc9f2a0bc67 100644 --- a/tests/ui/layout/zero-sized-array-enum-niche.stderr +++ b/tests/ui/layout/zero-sized-array-enum-niche.stderr @@ -54,7 +54,6 @@ error: layout_of(Result<[u32; 0], bool>) = Layout { uninhabited: false, max_repr_align: None, unadjusted_abi_align: Align(4 bytes), - randomization_seed: $SEED, }, VariantLayout { size: Size(2 bytes), @@ -83,7 +82,6 @@ error: layout_of(Result<[u32; 0], bool>) = Layout { uninhabited: false, max_repr_align: None, unadjusted_abi_align: Align(1 bytes), - randomization_seed: $SEED, }, ], }, @@ -152,7 +150,6 @@ error: layout_of(MultipleAlignments) = Layout { uninhabited: false, max_repr_align: None, unadjusted_abi_align: Align(2 bytes), - randomization_seed: $SEED, }, VariantLayout { size: Size(4 bytes), @@ -172,7 +169,6 @@ error: layout_of(MultipleAlignments) = Layout { uninhabited: false, max_repr_align: None, unadjusted_abi_align: Align(4 bytes), - randomization_seed: $SEED, }, VariantLayout { size: Size(2 bytes), @@ -201,7 +197,6 @@ error: layout_of(MultipleAlignments) = Layout { uninhabited: false, max_repr_align: None, unadjusted_abi_align: Align(1 bytes), - randomization_seed: $SEED, }, ], }, @@ -270,7 +265,6 @@ error: layout_of(Result<[u32; 0], Packed>>) = Layout { uninhabited: false, max_repr_align: None, unadjusted_abi_align: Align(4 bytes), - randomization_seed: $SEED, }, VariantLayout { size: Size(3 bytes), @@ -299,7 +293,6 @@ error: layout_of(Result<[u32; 0], Packed>>) = Layout { uninhabited: false, max_repr_align: None, unadjusted_abi_align: Align(1 bytes), - randomization_seed: $SEED, }, ], }, @@ -372,7 +365,6 @@ error: layout_of(Result<[u32; 0], Packed>) = Layout { uninhabited: false, max_repr_align: None, unadjusted_abi_align: Align(4 bytes), - randomization_seed: $SEED, }, VariantLayout { size: Size(2 bytes), @@ -401,7 +393,6 @@ error: layout_of(Result<[u32; 0], Packed>) = Layout { uninhabited: false, max_repr_align: None, unadjusted_abi_align: Align(1 bytes), - randomization_seed: $SEED, }, ], }, diff --git a/tests/ui/repr/repr-c-dead-variants.aarch64-unknown-linux-gnu.stderr b/tests/ui/repr/repr-c-dead-variants.aarch64-unknown-linux-gnu.stderr index 46a1eee98c772..6917390e9bb91 100644 --- a/tests/ui/repr/repr-c-dead-variants.aarch64-unknown-linux-gnu.stderr +++ b/tests/ui/repr/repr-c-dead-variants.aarch64-unknown-linux-gnu.stderr @@ -66,7 +66,6 @@ error: layout_of(Univariant) = Layout { uninhabited: true, max_repr_align: None, unadjusted_abi_align: Align(4 bytes), - randomization_seed: $SEED, }, ], }, @@ -159,7 +158,6 @@ error: layout_of(TwoVariants) = Layout { uninhabited: true, max_repr_align: None, unadjusted_abi_align: Align(4 bytes), - randomization_seed: $SEED, }, VariantLayout { size: Size(8 bytes), @@ -191,7 +189,6 @@ error: layout_of(TwoVariants) = Layout { uninhabited: false, max_repr_align: None, unadjusted_abi_align: Align(4 bytes), - randomization_seed: $SEED, }, ], }, @@ -264,7 +261,6 @@ error: layout_of(DeadBranchHasOtherField) = Layout { Align(8 bytes), ), unadjusted_abi_align: Align(8 bytes), - randomization_seed: $SEED, }, VariantLayout { size: Size(16 bytes), @@ -284,7 +280,6 @@ error: layout_of(DeadBranchHasOtherField) = Layout { uninhabited: false, max_repr_align: None, unadjusted_abi_align: Align(8 bytes), - randomization_seed: $SEED, }, ], }, diff --git a/tests/ui/repr/repr-c-dead-variants.armebv7r-none-eabi.stderr b/tests/ui/repr/repr-c-dead-variants.armebv7r-none-eabi.stderr index 35c0d22f23254..1ad3b8b22f7cc 100644 --- a/tests/ui/repr/repr-c-dead-variants.armebv7r-none-eabi.stderr +++ b/tests/ui/repr/repr-c-dead-variants.armebv7r-none-eabi.stderr @@ -66,7 +66,6 @@ error: layout_of(Univariant) = Layout { uninhabited: true, max_repr_align: None, unadjusted_abi_align: Align(1 bytes), - randomization_seed: $SEED, }, ], }, @@ -159,7 +158,6 @@ error: layout_of(TwoVariants) = Layout { uninhabited: true, max_repr_align: None, unadjusted_abi_align: Align(1 bytes), - randomization_seed: $SEED, }, VariantLayout { size: Size(2 bytes), @@ -191,7 +189,6 @@ error: layout_of(TwoVariants) = Layout { uninhabited: false, max_repr_align: None, unadjusted_abi_align: Align(1 bytes), - randomization_seed: $SEED, }, ], }, @@ -264,7 +261,6 @@ error: layout_of(DeadBranchHasOtherField) = Layout { Align(8 bytes), ), unadjusted_abi_align: Align(8 bytes), - randomization_seed: $SEED, }, VariantLayout { size: Size(16 bytes), @@ -284,7 +280,6 @@ error: layout_of(DeadBranchHasOtherField) = Layout { uninhabited: false, max_repr_align: None, unadjusted_abi_align: Align(8 bytes), - randomization_seed: $SEED, }, ], }, diff --git a/tests/ui/repr/repr-c-dead-variants.i686-pc-windows-msvc.stderr b/tests/ui/repr/repr-c-dead-variants.i686-pc-windows-msvc.stderr index 46a1eee98c772..6917390e9bb91 100644 --- a/tests/ui/repr/repr-c-dead-variants.i686-pc-windows-msvc.stderr +++ b/tests/ui/repr/repr-c-dead-variants.i686-pc-windows-msvc.stderr @@ -66,7 +66,6 @@ error: layout_of(Univariant) = Layout { uninhabited: true, max_repr_align: None, unadjusted_abi_align: Align(4 bytes), - randomization_seed: $SEED, }, ], }, @@ -159,7 +158,6 @@ error: layout_of(TwoVariants) = Layout { uninhabited: true, max_repr_align: None, unadjusted_abi_align: Align(4 bytes), - randomization_seed: $SEED, }, VariantLayout { size: Size(8 bytes), @@ -191,7 +189,6 @@ error: layout_of(TwoVariants) = Layout { uninhabited: false, max_repr_align: None, unadjusted_abi_align: Align(4 bytes), - randomization_seed: $SEED, }, ], }, @@ -264,7 +261,6 @@ error: layout_of(DeadBranchHasOtherField) = Layout { Align(8 bytes), ), unadjusted_abi_align: Align(8 bytes), - randomization_seed: $SEED, }, VariantLayout { size: Size(16 bytes), @@ -284,7 +280,6 @@ error: layout_of(DeadBranchHasOtherField) = Layout { uninhabited: false, max_repr_align: None, unadjusted_abi_align: Align(8 bytes), - randomization_seed: $SEED, }, ], }, diff --git a/tests/ui/repr/repr-c-dead-variants.x86_64-unknown-linux-gnu.stderr b/tests/ui/repr/repr-c-dead-variants.x86_64-unknown-linux-gnu.stderr index 46a1eee98c772..6917390e9bb91 100644 --- a/tests/ui/repr/repr-c-dead-variants.x86_64-unknown-linux-gnu.stderr +++ b/tests/ui/repr/repr-c-dead-variants.x86_64-unknown-linux-gnu.stderr @@ -66,7 +66,6 @@ error: layout_of(Univariant) = Layout { uninhabited: true, max_repr_align: None, unadjusted_abi_align: Align(4 bytes), - randomization_seed: $SEED, }, ], }, @@ -159,7 +158,6 @@ error: layout_of(TwoVariants) = Layout { uninhabited: true, max_repr_align: None, unadjusted_abi_align: Align(4 bytes), - randomization_seed: $SEED, }, VariantLayout { size: Size(8 bytes), @@ -191,7 +189,6 @@ error: layout_of(TwoVariants) = Layout { uninhabited: false, max_repr_align: None, unadjusted_abi_align: Align(4 bytes), - randomization_seed: $SEED, }, ], }, @@ -264,7 +261,6 @@ error: layout_of(DeadBranchHasOtherField) = Layout { Align(8 bytes), ), unadjusted_abi_align: Align(8 bytes), - randomization_seed: $SEED, }, VariantLayout { size: Size(16 bytes), @@ -284,7 +280,6 @@ error: layout_of(DeadBranchHasOtherField) = Layout { uninhabited: false, max_repr_align: None, unadjusted_abi_align: Align(8 bytes), - randomization_seed: $SEED, }, ], }, diff --git a/tests/ui/repr/repr-c-int-dead-variants.stderr b/tests/ui/repr/repr-c-int-dead-variants.stderr index 0f0099bb18cc8..857002c379caa 100644 --- a/tests/ui/repr/repr-c-int-dead-variants.stderr +++ b/tests/ui/repr/repr-c-int-dead-variants.stderr @@ -66,7 +66,6 @@ error: layout_of(UnivariantU8) = Layout { uninhabited: true, max_repr_align: None, unadjusted_abi_align: Align(1 bytes), - randomization_seed: $SEED, }, ], }, @@ -159,7 +158,6 @@ error: layout_of(TwoVariantsU8) = Layout { uninhabited: true, max_repr_align: None, unadjusted_abi_align: Align(1 bytes), - randomization_seed: $SEED, }, VariantLayout { size: Size(2 bytes), @@ -191,7 +189,6 @@ error: layout_of(TwoVariantsU8) = Layout { uninhabited: false, max_repr_align: None, unadjusted_abi_align: Align(1 bytes), - randomization_seed: $SEED, }, ], }, @@ -264,7 +261,6 @@ error: layout_of(DeadBranchHasOtherFieldU8) = Layout { Align(8 bytes), ), unadjusted_abi_align: Align(8 bytes), - randomization_seed: $SEED, }, VariantLayout { size: Size(16 bytes), @@ -284,7 +280,6 @@ error: layout_of(DeadBranchHasOtherFieldU8) = Layout { uninhabited: false, max_repr_align: None, unadjusted_abi_align: Align(8 bytes), - randomization_seed: $SEED, }, ], }, diff --git a/tests/ui/type/pattern_types/non_null.stderr b/tests/ui/type/pattern_types/non_null.stderr index fb9f855e71b92..a6da4a2502aa4 100644 --- a/tests/ui/type/pattern_types/non_null.stderr +++ b/tests/ui/type/pattern_types/non_null.stderr @@ -100,7 +100,6 @@ error: layout_of(Option<(*const ()) is !null>) = Layout { uninhabited: false, max_repr_align: None, unadjusted_abi_align: Align(1 bytes), - randomization_seed: $SEED, }, VariantLayout { size: Size(8 bytes), @@ -137,7 +136,6 @@ error: layout_of(Option<(*const ()) is !null>) = Layout { uninhabited: false, max_repr_align: None, unadjusted_abi_align: Align(8 bytes), - randomization_seed: $SEED, }, ], }, diff --git a/tests/ui/type/pattern_types/range_patterns.stderr b/tests/ui/type/pattern_types/range_patterns.stderr index 661bd5d3922d6..4b81cec00d73f 100644 --- a/tests/ui/type/pattern_types/range_patterns.stderr +++ b/tests/ui/type/pattern_types/range_patterns.stderr @@ -141,7 +141,6 @@ error: layout_of(Option<(u32) is 1..>) = Layout { uninhabited: false, max_repr_align: None, unadjusted_abi_align: Align(1 bytes), - randomization_seed: $SEED, }, VariantLayout { size: Size(4 bytes), @@ -176,7 +175,6 @@ error: layout_of(Option<(u32) is 1..>) = Layout { uninhabited: false, max_repr_align: None, unadjusted_abi_align: Align(4 bytes), - randomization_seed: $SEED, }, ], }, @@ -242,7 +240,6 @@ error: layout_of(Option>) = Layout { uninhabited: false, max_repr_align: None, unadjusted_abi_align: Align(1 bytes), - randomization_seed: $SEED, }, VariantLayout { size: Size(4 bytes), @@ -277,7 +274,6 @@ error: layout_of(Option>) = Layout { uninhabited: false, max_repr_align: None, unadjusted_abi_align: Align(4 bytes), - randomization_seed: $SEED, }, ], }, From 75015f405a3835ffc264038933411231bc936382 Mon Sep 17 00:00:00 2001 From: Moulins Date: Wed, 14 Jan 2026 00:20:50 +0100 Subject: [PATCH 07/29] Remove per-variant alignment in `VariantLayout` Reusing the alignment of the enclosing enum in `LayoutData::for_variant` doesn't appear to cause any issues. --- compiler/rustc_abi/src/layout.rs | 15 +++-- compiler/rustc_abi/src/layout/simple.rs | 6 +- compiler/rustc_abi/src/lib.rs | 6 -- .../rustc_ty_utils/src/layout/invariant.rs | 10 +--- .../enum-discriminant/wrapping_niche.stderr | 30 ---------- tests/ui/layout/debug.stderr | 40 ------------- tests/ui/layout/hexagon-enum.stderr | 25 -------- ...-scalarpair-payload-might-be-uninit.stderr | 60 ------------------- .../issue-96185-overaligned-enum.stderr | 28 --------- tests/ui/layout/thumb-enum.stderr | 25 -------- .../layout/zero-sized-array-enum-niche.stderr | 45 -------------- ...-variants.aarch64-unknown-linux-gnu.stderr | 27 --------- ...-c-dead-variants.armebv7r-none-eabi.stderr | 27 --------- ...-dead-variants.i686-pc-windows-msvc.stderr | 27 --------- ...d-variants.x86_64-unknown-linux-gnu.stderr | 27 --------- tests/ui/repr/repr-c-int-dead-variants.stderr | 27 --------- tests/ui/type/pattern_types/non_null.stderr | 10 ---- .../type/pattern_types/range_patterns.stderr | 20 ------- 18 files changed, 14 insertions(+), 441 deletions(-) diff --git a/compiler/rustc_abi/src/layout.rs b/compiler/rustc_abi/src/layout.rs index 3910e342ff74d..8ab80c77ff9a5 100644 --- a/compiler/rustc_abi/src/layout.rs +++ b/compiler/rustc_abi/src/layout.rs @@ -589,6 +589,10 @@ impl LayoutCalculator { } let calculate_niche_filling_layout = || -> Option> { + struct VariantLayoutInfo { + align_abi: Align, + } + if repr.inhibit_enum_layout_opt() { return None; } @@ -602,11 +606,14 @@ impl LayoutCalculator { let mut unadjusted_abi_align = align; let mut combined_seed = repr.field_shuffle_seed; + let mut variants_info = IndexVec::::with_capacity(variants.len()); let mut variant_layouts = variants .iter() .map(|v| { let st = self.univariant(v, repr, StructKind::AlwaysSized).ok()?; + variants_info.push(VariantLayoutInfo { align_abi: st.align.abi }); + align = align.max(st.align.abi); max_repr_align = max_repr_align.max(st.max_repr_align); unadjusted_abi_align = unadjusted_abi_align.max(st.unadjusted_abi_align); @@ -650,7 +657,7 @@ impl LayoutCalculator { } // Determine if it'll fit after the niche. - let this_align = layout.align.abi; + let this_align = variants_info[i].align_abi; let this_offset = (niche_offset + niche_size).align_to(this_align); if this_offset + layout.size > size { @@ -681,7 +688,7 @@ impl LayoutCalculator { .iter_enumerated() .all(|(i, layout)| i == largest_variant_index || layout.size == Size::ZERO); let same_size = size == variant_layouts[largest_variant_index].size; - let same_align = align == variant_layouts[largest_variant_index].align.abi; + let same_align = align == variants_info[largest_variant_index].align_abi; let uninhabited = variant_layouts.iter().all(|v| v.is_uninhabited()); let abi = if same_size && same_align && others_zst { @@ -1031,10 +1038,8 @@ impl LayoutCalculator { if matches!(variant.backend_repr, BackendRepr::Memory { .. } if variant.has_fields()) { variant.backend_repr = abi; - // Also need to bump up the size and alignment, so that the entire value fits - // in here. + // Also need to bump up the size, so that the entire value fits in here. variant.size = cmp::max(variant.size, size); - variant.align.abi = cmp::max(variant.align.abi, align); } } } diff --git a/compiler/rustc_abi/src/layout/simple.rs b/compiler/rustc_abi/src/layout/simple.rs index 6442fe69d202c..b103e1e97bd96 100644 --- a/compiler/rustc_abi/src/layout/simple.rs +++ b/compiler/rustc_abi/src/layout/simple.rs @@ -165,10 +165,10 @@ impl LayoutData { backend_repr: layout.backend_repr, largest_niche: layout.largest_niche, uninhabited: layout.uninhabited, - align: layout.align, size: layout.size, - max_repr_align: layout.max_repr_align, - unadjusted_abi_align: layout.unadjusted_abi_align, + align: parent.align, + max_repr_align: parent.max_repr_align, + unadjusted_abi_align: parent.unadjusted_abi_align, // Variant layouts never flow back into actual layout computations, // so dummy values are fine here. randomization_seed: Hash64::ZERO, diff --git a/compiler/rustc_abi/src/lib.rs b/compiler/rustc_abi/src/lib.rs index 108a4daf71358..5e1a95d620f2a 100644 --- a/compiler/rustc_abi/src/lib.rs +++ b/compiler/rustc_abi/src/lib.rs @@ -2325,14 +2325,11 @@ pub enum AbiFromStrErr { #[cfg_attr(feature = "nightly", derive(StableHash))] pub struct VariantLayout { pub size: Size, - pub align: AbiAlign, pub backend_repr: BackendRepr, pub field_offsets: IndexVec, fields_in_memory_order: IndexVec, largest_niche: Option, uninhabited: bool, - max_repr_align: Option, - unadjusted_abi_align: Align, } impl VariantLayout { @@ -2343,14 +2340,11 @@ impl VariantLayout { Self { size: layout.size, - align: layout.align, backend_repr: layout.backend_repr, field_offsets: offsets, fields_in_memory_order: in_memory_order, largest_niche: layout.largest_niche, uninhabited: layout.uninhabited, - max_repr_align: layout.max_repr_align, - unadjusted_abi_align: layout.unadjusted_abi_align, } } diff --git a/compiler/rustc_ty_utils/src/layout/invariant.rs b/compiler/rustc_ty_utils/src/layout/invariant.rs index c33891941afda..8c07a7ec3d2de 100644 --- a/compiler/rustc_ty_utils/src/layout/invariant.rs +++ b/compiler/rustc_ty_utils/src/layout/invariant.rs @@ -302,8 +302,7 @@ pub(super) fn layout_sanity_check<'tcx>(cx: &LayoutCx<'tcx>, layout: &TyAndLayou } } for variant in variants.iter() { - // Variants should have the same or a smaller size as the full thing, - // and same for alignment. + // Variants should have the same or a smaller size as the full thing. if variant.size > layout.size { bug!( "Type with size {} bytes has variant with size {} bytes: {layout:#?}", @@ -311,13 +310,6 @@ pub(super) fn layout_sanity_check<'tcx>(cx: &LayoutCx<'tcx>, layout: &TyAndLayou variant.size.bytes(), ) } - if variant.align.abi > layout.align.abi { - bug!( - "Type with alignment {} bytes has variant with alignment {} bytes: {layout:#?}", - layout.align.bytes(), - variant.align.bytes(), - ) - } // Skip empty variants. if variant.size == Size::ZERO || !variant.has_fields() || variant.is_uninhabited() { // These are never actually accessed anyway, so we can skip the coherence check diff --git a/tests/ui/enum-discriminant/wrapping_niche.stderr b/tests/ui/enum-discriminant/wrapping_niche.stderr index bd42f79c38b39..b24948fb39ddf 100644 --- a/tests/ui/enum-discriminant/wrapping_niche.stderr +++ b/tests/ui/enum-discriminant/wrapping_niche.stderr @@ -44,9 +44,6 @@ error: layout_of(UnsignedAroundZero) = Layout { variants: [ VariantLayout { size: Size(2 bytes), - align: AbiAlign { - abi: Align(2 bytes), - }, backend_repr: Memory { sized: true, }, @@ -54,14 +51,9 @@ error: layout_of(UnsignedAroundZero) = Layout { fields_in_memory_order: [], largest_niche: None, uninhabited: false, - max_repr_align: None, - unadjusted_abi_align: Align(2 bytes), }, VariantLayout { size: Size(2 bytes), - align: AbiAlign { - abi: Align(2 bytes), - }, backend_repr: Memory { sized: true, }, @@ -69,14 +61,9 @@ error: layout_of(UnsignedAroundZero) = Layout { fields_in_memory_order: [], largest_niche: None, uninhabited: false, - max_repr_align: None, - unadjusted_abi_align: Align(2 bytes), }, VariantLayout { size: Size(2 bytes), - align: AbiAlign { - abi: Align(2 bytes), - }, backend_repr: Memory { sized: true, }, @@ -84,8 +71,6 @@ error: layout_of(UnsignedAroundZero) = Layout { fields_in_memory_order: [], largest_niche: None, uninhabited: false, - max_repr_align: None, - unadjusted_abi_align: Align(2 bytes), }, ], }, @@ -144,9 +129,6 @@ error: layout_of(SignedAroundZero) = Layout { variants: [ VariantLayout { size: Size(2 bytes), - align: AbiAlign { - abi: Align(2 bytes), - }, backend_repr: Memory { sized: true, }, @@ -154,14 +136,9 @@ error: layout_of(SignedAroundZero) = Layout { fields_in_memory_order: [], largest_niche: None, uninhabited: false, - max_repr_align: None, - unadjusted_abi_align: Align(2 bytes), }, VariantLayout { size: Size(2 bytes), - align: AbiAlign { - abi: Align(2 bytes), - }, backend_repr: Memory { sized: true, }, @@ -169,14 +146,9 @@ error: layout_of(SignedAroundZero) = Layout { fields_in_memory_order: [], largest_niche: None, uninhabited: false, - max_repr_align: None, - unadjusted_abi_align: Align(2 bytes), }, VariantLayout { size: Size(2 bytes), - align: AbiAlign { - abi: Align(2 bytes), - }, backend_repr: Memory { sized: true, }, @@ -184,8 +156,6 @@ error: layout_of(SignedAroundZero) = Layout { fields_in_memory_order: [], largest_niche: None, uninhabited: false, - max_repr_align: None, - unadjusted_abi_align: Align(2 bytes), }, ], }, diff --git a/tests/ui/layout/debug.stderr b/tests/ui/layout/debug.stderr index 1008604e75e9b..f08d1200b9fbc 100644 --- a/tests/ui/layout/debug.stderr +++ b/tests/ui/layout/debug.stderr @@ -60,9 +60,6 @@ error: layout_of(E) = Layout { variants: [ VariantLayout { size: Size(4 bytes), - align: AbiAlign { - abi: Align(1 bytes), - }, backend_repr: Memory { sized: true, }, @@ -70,14 +67,9 @@ error: layout_of(E) = Layout { fields_in_memory_order: [], largest_niche: None, uninhabited: false, - max_repr_align: None, - unadjusted_abi_align: Align(1 bytes), }, VariantLayout { size: Size(12 bytes), - align: AbiAlign { - abi: Align(4 bytes), - }, backend_repr: Memory { sized: true, }, @@ -93,8 +85,6 @@ error: layout_of(E) = Layout { ], largest_niche: None, uninhabited: true, - max_repr_align: None, - unadjusted_abi_align: Align(4 bytes), }, ], }, @@ -232,9 +222,6 @@ error: layout_of(Result) = Layout { variants: [ VariantLayout { size: Size(8 bytes), - align: AbiAlign { - abi: Align(4 bytes), - }, backend_repr: ScalarPair( Initialized { value: Int( @@ -259,14 +246,9 @@ error: layout_of(Result) = Layout { ], largest_niche: None, uninhabited: false, - max_repr_align: None, - unadjusted_abi_align: Align(4 bytes), }, VariantLayout { size: Size(8 bytes), - align: AbiAlign { - abi: Align(4 bytes), - }, backend_repr: ScalarPair( Initialized { value: Int( @@ -291,8 +273,6 @@ error: layout_of(Result) = Layout { ], largest_niche: None, uninhabited: false, - max_repr_align: None, - unadjusted_abi_align: Align(4 bytes), }, ], }, @@ -640,9 +620,6 @@ error: layout_of(Option) = Layout { variants: [ VariantLayout { size: Size(0 bytes), - align: AbiAlign { - abi: Align(1 bytes), - }, backend_repr: Memory { sized: true, }, @@ -650,14 +627,9 @@ error: layout_of(Option) = Layout { fields_in_memory_order: [], largest_niche: None, uninhabited: false, - max_repr_align: None, - unadjusted_abi_align: Align(1 bytes), }, VariantLayout { size: Size(1 bytes), - align: AbiAlign { - abi: Align(1 bytes), - }, backend_repr: Scalar( Initialized { value: Int( @@ -684,8 +656,6 @@ error: layout_of(Option) = Layout { }, ), uninhabited: false, - max_repr_align: None, - unadjusted_abi_align: Align(1 bytes), }, ], }, @@ -748,9 +718,6 @@ error: layout_of(Option) = Layout { variants: [ VariantLayout { size: Size(0 bytes), - align: AbiAlign { - abi: Align(1 bytes), - }, backend_repr: Memory { sized: true, }, @@ -758,14 +725,9 @@ error: layout_of(Option) = Layout { fields_in_memory_order: [], largest_niche: None, uninhabited: false, - max_repr_align: None, - unadjusted_abi_align: Align(1 bytes), }, VariantLayout { size: Size(4 bytes), - align: AbiAlign { - abi: Align(4 bytes), - }, backend_repr: Scalar( Initialized { value: Int( @@ -792,8 +754,6 @@ error: layout_of(Option) = Layout { }, ), uninhabited: false, - max_repr_align: None, - unadjusted_abi_align: Align(4 bytes), }, ], }, diff --git a/tests/ui/layout/hexagon-enum.stderr b/tests/ui/layout/hexagon-enum.stderr index 73431de7016eb..993ff476b6b6c 100644 --- a/tests/ui/layout/hexagon-enum.stderr +++ b/tests/ui/layout/hexagon-enum.stderr @@ -44,9 +44,6 @@ error: layout_of(A) = Layout { variants: [ VariantLayout { size: Size(1 bytes), - align: AbiAlign { - abi: Align(1 bytes), - }, backend_repr: Memory { sized: true, }, @@ -54,8 +51,6 @@ error: layout_of(A) = Layout { fields_in_memory_order: [], largest_niche: None, uninhabited: false, - max_repr_align: None, - unadjusted_abi_align: Align(1 bytes), }, ], }, @@ -114,9 +109,6 @@ error: layout_of(B) = Layout { variants: [ VariantLayout { size: Size(1 bytes), - align: AbiAlign { - abi: Align(1 bytes), - }, backend_repr: Memory { sized: true, }, @@ -124,8 +116,6 @@ error: layout_of(B) = Layout { fields_in_memory_order: [], largest_niche: None, uninhabited: false, - max_repr_align: None, - unadjusted_abi_align: Align(1 bytes), }, ], }, @@ -184,9 +174,6 @@ error: layout_of(C) = Layout { variants: [ VariantLayout { size: Size(2 bytes), - align: AbiAlign { - abi: Align(2 bytes), - }, backend_repr: Memory { sized: true, }, @@ -194,8 +181,6 @@ error: layout_of(C) = Layout { fields_in_memory_order: [], largest_niche: None, uninhabited: false, - max_repr_align: None, - unadjusted_abi_align: Align(2 bytes), }, ], }, @@ -254,9 +239,6 @@ error: layout_of(P) = Layout { variants: [ VariantLayout { size: Size(4 bytes), - align: AbiAlign { - abi: Align(4 bytes), - }, backend_repr: Memory { sized: true, }, @@ -264,8 +246,6 @@ error: layout_of(P) = Layout { fields_in_memory_order: [], largest_niche: None, uninhabited: false, - max_repr_align: None, - unadjusted_abi_align: Align(4 bytes), }, ], }, @@ -324,9 +304,6 @@ error: layout_of(T) = Layout { variants: [ VariantLayout { size: Size(4 bytes), - align: AbiAlign { - abi: Align(4 bytes), - }, backend_repr: Memory { sized: true, }, @@ -334,8 +311,6 @@ error: layout_of(T) = Layout { fields_in_memory_order: [], largest_niche: None, uninhabited: false, - max_repr_align: None, - unadjusted_abi_align: Align(4 bytes), }, ], }, diff --git a/tests/ui/layout/issue-96158-scalarpair-payload-might-be-uninit.stderr b/tests/ui/layout/issue-96158-scalarpair-payload-might-be-uninit.stderr index 20f9e69ff51d4..7e6294f894c3e 100644 --- a/tests/ui/layout/issue-96158-scalarpair-payload-might-be-uninit.stderr +++ b/tests/ui/layout/issue-96158-scalarpair-payload-might-be-uninit.stderr @@ -50,9 +50,6 @@ error: layout_of(MissingPayloadField) = Layout { variants: [ VariantLayout { size: Size(2 bytes), - align: AbiAlign { - abi: Align(1 bytes), - }, backend_repr: ScalarPair( Initialized { value: Int( @@ -76,14 +73,9 @@ error: layout_of(MissingPayloadField) = Layout { ], largest_niche: None, uninhabited: false, - max_repr_align: None, - unadjusted_abi_align: Align(1 bytes), }, VariantLayout { size: Size(1 bytes), - align: AbiAlign { - abi: Align(1 bytes), - }, backend_repr: Memory { sized: true, }, @@ -91,8 +83,6 @@ error: layout_of(MissingPayloadField) = Layout { fields_in_memory_order: [], largest_niche: None, uninhabited: false, - max_repr_align: None, - unadjusted_abi_align: Align(1 bytes), }, ], }, @@ -158,9 +148,6 @@ error: layout_of(CommonPayloadField) = Layout { variants: [ VariantLayout { size: Size(2 bytes), - align: AbiAlign { - abi: Align(1 bytes), - }, backend_repr: ScalarPair( Initialized { value: Int( @@ -185,14 +172,9 @@ error: layout_of(CommonPayloadField) = Layout { ], largest_niche: None, uninhabited: false, - max_repr_align: None, - unadjusted_abi_align: Align(1 bytes), }, VariantLayout { size: Size(2 bytes), - align: AbiAlign { - abi: Align(1 bytes), - }, backend_repr: ScalarPair( Initialized { value: Int( @@ -217,8 +199,6 @@ error: layout_of(CommonPayloadField) = Layout { ], largest_niche: None, uninhabited: false, - max_repr_align: None, - unadjusted_abi_align: Align(1 bytes), }, ], }, @@ -283,9 +263,6 @@ error: layout_of(CommonPayloadFieldIsMaybeUninit) = Layout { variants: [ VariantLayout { size: Size(2 bytes), - align: AbiAlign { - abi: Align(1 bytes), - }, backend_repr: ScalarPair( Initialized { value: Int( @@ -309,14 +286,9 @@ error: layout_of(CommonPayloadFieldIsMaybeUninit) = Layout { ], largest_niche: None, uninhabited: false, - max_repr_align: None, - unadjusted_abi_align: Align(1 bytes), }, VariantLayout { size: Size(2 bytes), - align: AbiAlign { - abi: Align(1 bytes), - }, backend_repr: ScalarPair( Initialized { value: Int( @@ -340,8 +312,6 @@ error: layout_of(CommonPayloadFieldIsMaybeUninit) = Layout { ], largest_niche: None, uninhabited: false, - max_repr_align: None, - unadjusted_abi_align: Align(1 bytes), }, ], }, @@ -410,9 +380,6 @@ error: layout_of(NicheFirst) = Layout { variants: [ VariantLayout { size: Size(2 bytes), - align: AbiAlign { - abi: Align(1 bytes), - }, backend_repr: ScalarPair( Initialized { value: Int( @@ -448,14 +415,9 @@ error: layout_of(NicheFirst) = Layout { }, ), uninhabited: false, - max_repr_align: None, - unadjusted_abi_align: Align(1 bytes), }, VariantLayout { size: Size(0 bytes), - align: AbiAlign { - abi: Align(1 bytes), - }, backend_repr: Memory { sized: true, }, @@ -463,14 +425,9 @@ error: layout_of(NicheFirst) = Layout { fields_in_memory_order: [], largest_niche: None, uninhabited: false, - max_repr_align: None, - unadjusted_abi_align: Align(1 bytes), }, VariantLayout { size: Size(0 bytes), - align: AbiAlign { - abi: Align(1 bytes), - }, backend_repr: Memory { sized: true, }, @@ -478,8 +435,6 @@ error: layout_of(NicheFirst) = Layout { fields_in_memory_order: [], largest_niche: None, uninhabited: false, - max_repr_align: None, - unadjusted_abi_align: Align(1 bytes), }, ], }, @@ -548,9 +503,6 @@ error: layout_of(NicheSecond) = Layout { variants: [ VariantLayout { size: Size(2 bytes), - align: AbiAlign { - abi: Align(1 bytes), - }, backend_repr: ScalarPair( Initialized { value: Int( @@ -586,14 +538,9 @@ error: layout_of(NicheSecond) = Layout { }, ), uninhabited: false, - max_repr_align: None, - unadjusted_abi_align: Align(1 bytes), }, VariantLayout { size: Size(0 bytes), - align: AbiAlign { - abi: Align(1 bytes), - }, backend_repr: Memory { sized: true, }, @@ -601,14 +548,9 @@ error: layout_of(NicheSecond) = Layout { fields_in_memory_order: [], largest_niche: None, uninhabited: false, - max_repr_align: None, - unadjusted_abi_align: Align(1 bytes), }, VariantLayout { size: Size(0 bytes), - align: AbiAlign { - abi: Align(1 bytes), - }, backend_repr: Memory { sized: true, }, @@ -616,8 +558,6 @@ error: layout_of(NicheSecond) = Layout { fields_in_memory_order: [], largest_niche: None, uninhabited: false, - max_repr_align: None, - unadjusted_abi_align: Align(1 bytes), }, ], }, diff --git a/tests/ui/layout/issue-96185-overaligned-enum.stderr b/tests/ui/layout/issue-96185-overaligned-enum.stderr index 80efc35cf6384..8937af2f5d494 100644 --- a/tests/ui/layout/issue-96185-overaligned-enum.stderr +++ b/tests/ui/layout/issue-96185-overaligned-enum.stderr @@ -38,9 +38,6 @@ error: layout_of(Aligned1) = Layout { variants: [ VariantLayout { size: Size(8 bytes), - align: AbiAlign { - abi: Align(8 bytes), - }, backend_repr: Memory { sized: true, }, @@ -48,16 +45,9 @@ error: layout_of(Aligned1) = Layout { fields_in_memory_order: [], largest_niche: None, uninhabited: false, - max_repr_align: Some( - Align(8 bytes), - ), - unadjusted_abi_align: Align(1 bytes), }, VariantLayout { size: Size(8 bytes), - align: AbiAlign { - abi: Align(8 bytes), - }, backend_repr: Memory { sized: true, }, @@ -65,10 +55,6 @@ error: layout_of(Aligned1) = Layout { fields_in_memory_order: [], largest_niche: None, uninhabited: false, - max_repr_align: Some( - Align(8 bytes), - ), - unadjusted_abi_align: Align(1 bytes), }, ], }, @@ -129,9 +115,6 @@ error: layout_of(Aligned2) = Layout { variants: [ VariantLayout { size: Size(1 bytes), - align: AbiAlign { - abi: Align(1 bytes), - }, backend_repr: Memory { sized: true, }, @@ -139,16 +122,9 @@ error: layout_of(Aligned2) = Layout { fields_in_memory_order: [], largest_niche: None, uninhabited: false, - max_repr_align: Some( - Align(1 bytes), - ), - unadjusted_abi_align: Align(1 bytes), }, VariantLayout { size: Size(1 bytes), - align: AbiAlign { - abi: Align(1 bytes), - }, backend_repr: Memory { sized: true, }, @@ -156,10 +132,6 @@ error: layout_of(Aligned2) = Layout { fields_in_memory_order: [], largest_niche: None, uninhabited: false, - max_repr_align: Some( - Align(1 bytes), - ), - unadjusted_abi_align: Align(1 bytes), }, ], }, diff --git a/tests/ui/layout/thumb-enum.stderr b/tests/ui/layout/thumb-enum.stderr index d2d4af352a093..200002490d5c5 100644 --- a/tests/ui/layout/thumb-enum.stderr +++ b/tests/ui/layout/thumb-enum.stderr @@ -44,9 +44,6 @@ error: layout_of(A) = Layout { variants: [ VariantLayout { size: Size(1 bytes), - align: AbiAlign { - abi: Align(1 bytes), - }, backend_repr: Memory { sized: true, }, @@ -54,8 +51,6 @@ error: layout_of(A) = Layout { fields_in_memory_order: [], largest_niche: None, uninhabited: false, - max_repr_align: None, - unadjusted_abi_align: Align(1 bytes), }, ], }, @@ -114,9 +109,6 @@ error: layout_of(B) = Layout { variants: [ VariantLayout { size: Size(1 bytes), - align: AbiAlign { - abi: Align(1 bytes), - }, backend_repr: Memory { sized: true, }, @@ -124,8 +116,6 @@ error: layout_of(B) = Layout { fields_in_memory_order: [], largest_niche: None, uninhabited: false, - max_repr_align: None, - unadjusted_abi_align: Align(1 bytes), }, ], }, @@ -184,9 +174,6 @@ error: layout_of(C) = Layout { variants: [ VariantLayout { size: Size(2 bytes), - align: AbiAlign { - abi: Align(2 bytes), - }, backend_repr: Memory { sized: true, }, @@ -194,8 +181,6 @@ error: layout_of(C) = Layout { fields_in_memory_order: [], largest_niche: None, uninhabited: false, - max_repr_align: None, - unadjusted_abi_align: Align(2 bytes), }, ], }, @@ -254,9 +239,6 @@ error: layout_of(P) = Layout { variants: [ VariantLayout { size: Size(4 bytes), - align: AbiAlign { - abi: Align(4 bytes), - }, backend_repr: Memory { sized: true, }, @@ -264,8 +246,6 @@ error: layout_of(P) = Layout { fields_in_memory_order: [], largest_niche: None, uninhabited: false, - max_repr_align: None, - unadjusted_abi_align: Align(4 bytes), }, ], }, @@ -324,9 +304,6 @@ error: layout_of(T) = Layout { variants: [ VariantLayout { size: Size(4 bytes), - align: AbiAlign { - abi: Align(4 bytes), - }, backend_repr: Memory { sized: true, }, @@ -334,8 +311,6 @@ error: layout_of(T) = Layout { fields_in_memory_order: [], largest_niche: None, uninhabited: false, - max_repr_align: None, - unadjusted_abi_align: Align(4 bytes), }, ], }, diff --git a/tests/ui/layout/zero-sized-array-enum-niche.stderr b/tests/ui/layout/zero-sized-array-enum-niche.stderr index dabc9f2a0bc67..6618f162853e5 100644 --- a/tests/ui/layout/zero-sized-array-enum-niche.stderr +++ b/tests/ui/layout/zero-sized-array-enum-niche.stderr @@ -38,9 +38,6 @@ error: layout_of(Result<[u32; 0], bool>) = Layout { variants: [ VariantLayout { size: Size(4 bytes), - align: AbiAlign { - abi: Align(4 bytes), - }, backend_repr: Memory { sized: true, }, @@ -52,14 +49,9 @@ error: layout_of(Result<[u32; 0], bool>) = Layout { ], largest_niche: None, uninhabited: false, - max_repr_align: None, - unadjusted_abi_align: Align(4 bytes), }, VariantLayout { size: Size(2 bytes), - align: AbiAlign { - abi: Align(1 bytes), - }, backend_repr: Memory { sized: true, }, @@ -80,8 +72,6 @@ error: layout_of(Result<[u32; 0], bool>) = Layout { }, ), uninhabited: false, - max_repr_align: None, - unadjusted_abi_align: Align(1 bytes), }, ], }, @@ -134,9 +124,6 @@ error: layout_of(MultipleAlignments) = Layout { variants: [ VariantLayout { size: Size(2 bytes), - align: AbiAlign { - abi: Align(2 bytes), - }, backend_repr: Memory { sized: true, }, @@ -148,14 +135,9 @@ error: layout_of(MultipleAlignments) = Layout { ], largest_niche: None, uninhabited: false, - max_repr_align: None, - unadjusted_abi_align: Align(2 bytes), }, VariantLayout { size: Size(4 bytes), - align: AbiAlign { - abi: Align(4 bytes), - }, backend_repr: Memory { sized: true, }, @@ -167,14 +149,9 @@ error: layout_of(MultipleAlignments) = Layout { ], largest_niche: None, uninhabited: false, - max_repr_align: None, - unadjusted_abi_align: Align(4 bytes), }, VariantLayout { size: Size(2 bytes), - align: AbiAlign { - abi: Align(1 bytes), - }, backend_repr: Memory { sized: true, }, @@ -195,8 +172,6 @@ error: layout_of(MultipleAlignments) = Layout { }, ), uninhabited: false, - max_repr_align: None, - unadjusted_abi_align: Align(1 bytes), }, ], }, @@ -249,9 +224,6 @@ error: layout_of(Result<[u32; 0], Packed>>) = Layout { variants: [ VariantLayout { size: Size(4 bytes), - align: AbiAlign { - abi: Align(4 bytes), - }, backend_repr: Memory { sized: true, }, @@ -263,14 +235,9 @@ error: layout_of(Result<[u32; 0], Packed>>) = Layout { ], largest_niche: None, uninhabited: false, - max_repr_align: None, - unadjusted_abi_align: Align(4 bytes), }, VariantLayout { size: Size(3 bytes), - align: AbiAlign { - abi: Align(1 bytes), - }, backend_repr: Memory { sized: true, }, @@ -291,8 +258,6 @@ error: layout_of(Result<[u32; 0], Packed>>) = Layout { }, ), uninhabited: false, - max_repr_align: None, - unadjusted_abi_align: Align(1 bytes), }, ], }, @@ -349,9 +314,6 @@ error: layout_of(Result<[u32; 0], Packed>) = Layout { variants: [ VariantLayout { size: Size(0 bytes), - align: AbiAlign { - abi: Align(4 bytes), - }, backend_repr: Memory { sized: true, }, @@ -363,14 +325,9 @@ error: layout_of(Result<[u32; 0], Packed>) = Layout { ], largest_niche: None, uninhabited: false, - max_repr_align: None, - unadjusted_abi_align: Align(4 bytes), }, VariantLayout { size: Size(2 bytes), - align: AbiAlign { - abi: Align(1 bytes), - }, backend_repr: Memory { sized: true, }, @@ -391,8 +348,6 @@ error: layout_of(Result<[u32; 0], Packed>) = Layout { }, ), uninhabited: false, - max_repr_align: None, - unadjusted_abi_align: Align(1 bytes), }, ], }, diff --git a/tests/ui/repr/repr-c-dead-variants.aarch64-unknown-linux-gnu.stderr b/tests/ui/repr/repr-c-dead-variants.aarch64-unknown-linux-gnu.stderr index 6917390e9bb91..28fafa7800305 100644 --- a/tests/ui/repr/repr-c-dead-variants.aarch64-unknown-linux-gnu.stderr +++ b/tests/ui/repr/repr-c-dead-variants.aarch64-unknown-linux-gnu.stderr @@ -44,9 +44,6 @@ error: layout_of(Univariant) = Layout { variants: [ VariantLayout { size: Size(4 bytes), - align: AbiAlign { - abi: Align(4 bytes), - }, backend_repr: Scalar( Initialized { value: Int( @@ -64,8 +61,6 @@ error: layout_of(Univariant) = Layout { ], largest_niche: None, uninhabited: true, - max_repr_align: None, - unadjusted_abi_align: Align(4 bytes), }, ], }, @@ -130,9 +125,6 @@ error: layout_of(TwoVariants) = Layout { variants: [ VariantLayout { size: Size(8 bytes), - align: AbiAlign { - abi: Align(4 bytes), - }, backend_repr: ScalarPair( Initialized { value: Int( @@ -156,14 +148,9 @@ error: layout_of(TwoVariants) = Layout { ], largest_niche: None, uninhabited: true, - max_repr_align: None, - unadjusted_abi_align: Align(4 bytes), }, VariantLayout { size: Size(8 bytes), - align: AbiAlign { - abi: Align(4 bytes), - }, backend_repr: ScalarPair( Initialized { value: Int( @@ -187,8 +174,6 @@ error: layout_of(TwoVariants) = Layout { ], largest_niche: None, uninhabited: false, - max_repr_align: None, - unadjusted_abi_align: Align(4 bytes), }, ], }, @@ -241,9 +226,6 @@ error: layout_of(DeadBranchHasOtherField) = Layout { variants: [ VariantLayout { size: Size(16 bytes), - align: AbiAlign { - abi: Align(8 bytes), - }, backend_repr: Memory { sized: true, }, @@ -257,16 +239,9 @@ error: layout_of(DeadBranchHasOtherField) = Layout { ], largest_niche: None, uninhabited: true, - max_repr_align: Some( - Align(8 bytes), - ), - unadjusted_abi_align: Align(8 bytes), }, VariantLayout { size: Size(16 bytes), - align: AbiAlign { - abi: Align(8 bytes), - }, backend_repr: Memory { sized: true, }, @@ -278,8 +253,6 @@ error: layout_of(DeadBranchHasOtherField) = Layout { ], largest_niche: None, uninhabited: false, - max_repr_align: None, - unadjusted_abi_align: Align(8 bytes), }, ], }, diff --git a/tests/ui/repr/repr-c-dead-variants.armebv7r-none-eabi.stderr b/tests/ui/repr/repr-c-dead-variants.armebv7r-none-eabi.stderr index 1ad3b8b22f7cc..45193552b507f 100644 --- a/tests/ui/repr/repr-c-dead-variants.armebv7r-none-eabi.stderr +++ b/tests/ui/repr/repr-c-dead-variants.armebv7r-none-eabi.stderr @@ -44,9 +44,6 @@ error: layout_of(Univariant) = Layout { variants: [ VariantLayout { size: Size(1 bytes), - align: AbiAlign { - abi: Align(1 bytes), - }, backend_repr: Scalar( Initialized { value: Int( @@ -64,8 +61,6 @@ error: layout_of(Univariant) = Layout { ], largest_niche: None, uninhabited: true, - max_repr_align: None, - unadjusted_abi_align: Align(1 bytes), }, ], }, @@ -130,9 +125,6 @@ error: layout_of(TwoVariants) = Layout { variants: [ VariantLayout { size: Size(2 bytes), - align: AbiAlign { - abi: Align(1 bytes), - }, backend_repr: ScalarPair( Initialized { value: Int( @@ -156,14 +148,9 @@ error: layout_of(TwoVariants) = Layout { ], largest_niche: None, uninhabited: true, - max_repr_align: None, - unadjusted_abi_align: Align(1 bytes), }, VariantLayout { size: Size(2 bytes), - align: AbiAlign { - abi: Align(1 bytes), - }, backend_repr: ScalarPair( Initialized { value: Int( @@ -187,8 +174,6 @@ error: layout_of(TwoVariants) = Layout { ], largest_niche: None, uninhabited: false, - max_repr_align: None, - unadjusted_abi_align: Align(1 bytes), }, ], }, @@ -241,9 +226,6 @@ error: layout_of(DeadBranchHasOtherField) = Layout { variants: [ VariantLayout { size: Size(16 bytes), - align: AbiAlign { - abi: Align(8 bytes), - }, backend_repr: Memory { sized: true, }, @@ -257,16 +239,9 @@ error: layout_of(DeadBranchHasOtherField) = Layout { ], largest_niche: None, uninhabited: true, - max_repr_align: Some( - Align(8 bytes), - ), - unadjusted_abi_align: Align(8 bytes), }, VariantLayout { size: Size(16 bytes), - align: AbiAlign { - abi: Align(8 bytes), - }, backend_repr: Memory { sized: true, }, @@ -278,8 +253,6 @@ error: layout_of(DeadBranchHasOtherField) = Layout { ], largest_niche: None, uninhabited: false, - max_repr_align: None, - unadjusted_abi_align: Align(8 bytes), }, ], }, diff --git a/tests/ui/repr/repr-c-dead-variants.i686-pc-windows-msvc.stderr b/tests/ui/repr/repr-c-dead-variants.i686-pc-windows-msvc.stderr index 6917390e9bb91..28fafa7800305 100644 --- a/tests/ui/repr/repr-c-dead-variants.i686-pc-windows-msvc.stderr +++ b/tests/ui/repr/repr-c-dead-variants.i686-pc-windows-msvc.stderr @@ -44,9 +44,6 @@ error: layout_of(Univariant) = Layout { variants: [ VariantLayout { size: Size(4 bytes), - align: AbiAlign { - abi: Align(4 bytes), - }, backend_repr: Scalar( Initialized { value: Int( @@ -64,8 +61,6 @@ error: layout_of(Univariant) = Layout { ], largest_niche: None, uninhabited: true, - max_repr_align: None, - unadjusted_abi_align: Align(4 bytes), }, ], }, @@ -130,9 +125,6 @@ error: layout_of(TwoVariants) = Layout { variants: [ VariantLayout { size: Size(8 bytes), - align: AbiAlign { - abi: Align(4 bytes), - }, backend_repr: ScalarPair( Initialized { value: Int( @@ -156,14 +148,9 @@ error: layout_of(TwoVariants) = Layout { ], largest_niche: None, uninhabited: true, - max_repr_align: None, - unadjusted_abi_align: Align(4 bytes), }, VariantLayout { size: Size(8 bytes), - align: AbiAlign { - abi: Align(4 bytes), - }, backend_repr: ScalarPair( Initialized { value: Int( @@ -187,8 +174,6 @@ error: layout_of(TwoVariants) = Layout { ], largest_niche: None, uninhabited: false, - max_repr_align: None, - unadjusted_abi_align: Align(4 bytes), }, ], }, @@ -241,9 +226,6 @@ error: layout_of(DeadBranchHasOtherField) = Layout { variants: [ VariantLayout { size: Size(16 bytes), - align: AbiAlign { - abi: Align(8 bytes), - }, backend_repr: Memory { sized: true, }, @@ -257,16 +239,9 @@ error: layout_of(DeadBranchHasOtherField) = Layout { ], largest_niche: None, uninhabited: true, - max_repr_align: Some( - Align(8 bytes), - ), - unadjusted_abi_align: Align(8 bytes), }, VariantLayout { size: Size(16 bytes), - align: AbiAlign { - abi: Align(8 bytes), - }, backend_repr: Memory { sized: true, }, @@ -278,8 +253,6 @@ error: layout_of(DeadBranchHasOtherField) = Layout { ], largest_niche: None, uninhabited: false, - max_repr_align: None, - unadjusted_abi_align: Align(8 bytes), }, ], }, diff --git a/tests/ui/repr/repr-c-dead-variants.x86_64-unknown-linux-gnu.stderr b/tests/ui/repr/repr-c-dead-variants.x86_64-unknown-linux-gnu.stderr index 6917390e9bb91..28fafa7800305 100644 --- a/tests/ui/repr/repr-c-dead-variants.x86_64-unknown-linux-gnu.stderr +++ b/tests/ui/repr/repr-c-dead-variants.x86_64-unknown-linux-gnu.stderr @@ -44,9 +44,6 @@ error: layout_of(Univariant) = Layout { variants: [ VariantLayout { size: Size(4 bytes), - align: AbiAlign { - abi: Align(4 bytes), - }, backend_repr: Scalar( Initialized { value: Int( @@ -64,8 +61,6 @@ error: layout_of(Univariant) = Layout { ], largest_niche: None, uninhabited: true, - max_repr_align: None, - unadjusted_abi_align: Align(4 bytes), }, ], }, @@ -130,9 +125,6 @@ error: layout_of(TwoVariants) = Layout { variants: [ VariantLayout { size: Size(8 bytes), - align: AbiAlign { - abi: Align(4 bytes), - }, backend_repr: ScalarPair( Initialized { value: Int( @@ -156,14 +148,9 @@ error: layout_of(TwoVariants) = Layout { ], largest_niche: None, uninhabited: true, - max_repr_align: None, - unadjusted_abi_align: Align(4 bytes), }, VariantLayout { size: Size(8 bytes), - align: AbiAlign { - abi: Align(4 bytes), - }, backend_repr: ScalarPair( Initialized { value: Int( @@ -187,8 +174,6 @@ error: layout_of(TwoVariants) = Layout { ], largest_niche: None, uninhabited: false, - max_repr_align: None, - unadjusted_abi_align: Align(4 bytes), }, ], }, @@ -241,9 +226,6 @@ error: layout_of(DeadBranchHasOtherField) = Layout { variants: [ VariantLayout { size: Size(16 bytes), - align: AbiAlign { - abi: Align(8 bytes), - }, backend_repr: Memory { sized: true, }, @@ -257,16 +239,9 @@ error: layout_of(DeadBranchHasOtherField) = Layout { ], largest_niche: None, uninhabited: true, - max_repr_align: Some( - Align(8 bytes), - ), - unadjusted_abi_align: Align(8 bytes), }, VariantLayout { size: Size(16 bytes), - align: AbiAlign { - abi: Align(8 bytes), - }, backend_repr: Memory { sized: true, }, @@ -278,8 +253,6 @@ error: layout_of(DeadBranchHasOtherField) = Layout { ], largest_niche: None, uninhabited: false, - max_repr_align: None, - unadjusted_abi_align: Align(8 bytes), }, ], }, diff --git a/tests/ui/repr/repr-c-int-dead-variants.stderr b/tests/ui/repr/repr-c-int-dead-variants.stderr index 857002c379caa..c2f7fec38c81f 100644 --- a/tests/ui/repr/repr-c-int-dead-variants.stderr +++ b/tests/ui/repr/repr-c-int-dead-variants.stderr @@ -44,9 +44,6 @@ error: layout_of(UnivariantU8) = Layout { variants: [ VariantLayout { size: Size(1 bytes), - align: AbiAlign { - abi: Align(1 bytes), - }, backend_repr: Scalar( Initialized { value: Int( @@ -64,8 +61,6 @@ error: layout_of(UnivariantU8) = Layout { ], largest_niche: None, uninhabited: true, - max_repr_align: None, - unadjusted_abi_align: Align(1 bytes), }, ], }, @@ -130,9 +125,6 @@ error: layout_of(TwoVariantsU8) = Layout { variants: [ VariantLayout { size: Size(2 bytes), - align: AbiAlign { - abi: Align(1 bytes), - }, backend_repr: ScalarPair( Initialized { value: Int( @@ -156,14 +148,9 @@ error: layout_of(TwoVariantsU8) = Layout { ], largest_niche: None, uninhabited: true, - max_repr_align: None, - unadjusted_abi_align: Align(1 bytes), }, VariantLayout { size: Size(2 bytes), - align: AbiAlign { - abi: Align(1 bytes), - }, backend_repr: ScalarPair( Initialized { value: Int( @@ -187,8 +174,6 @@ error: layout_of(TwoVariantsU8) = Layout { ], largest_niche: None, uninhabited: false, - max_repr_align: None, - unadjusted_abi_align: Align(1 bytes), }, ], }, @@ -241,9 +226,6 @@ error: layout_of(DeadBranchHasOtherFieldU8) = Layout { variants: [ VariantLayout { size: Size(16 bytes), - align: AbiAlign { - abi: Align(8 bytes), - }, backend_repr: Memory { sized: true, }, @@ -257,16 +239,9 @@ error: layout_of(DeadBranchHasOtherFieldU8) = Layout { ], largest_niche: None, uninhabited: true, - max_repr_align: Some( - Align(8 bytes), - ), - unadjusted_abi_align: Align(8 bytes), }, VariantLayout { size: Size(16 bytes), - align: AbiAlign { - abi: Align(8 bytes), - }, backend_repr: Memory { sized: true, }, @@ -278,8 +253,6 @@ error: layout_of(DeadBranchHasOtherFieldU8) = Layout { ], largest_niche: None, uninhabited: false, - max_repr_align: None, - unadjusted_abi_align: Align(8 bytes), }, ], }, diff --git a/tests/ui/type/pattern_types/non_null.stderr b/tests/ui/type/pattern_types/non_null.stderr index a6da4a2502aa4..7d3e61770c2c7 100644 --- a/tests/ui/type/pattern_types/non_null.stderr +++ b/tests/ui/type/pattern_types/non_null.stderr @@ -88,9 +88,6 @@ error: layout_of(Option<(*const ()) is !null>) = Layout { variants: [ VariantLayout { size: Size(0 bytes), - align: AbiAlign { - abi: Align(1 bytes), - }, backend_repr: Memory { sized: true, }, @@ -98,14 +95,9 @@ error: layout_of(Option<(*const ()) is !null>) = Layout { fields_in_memory_order: [], largest_niche: None, uninhabited: false, - max_repr_align: None, - unadjusted_abi_align: Align(1 bytes), }, VariantLayout { size: Size(8 bytes), - align: AbiAlign { - abi: Align(8 bytes), - }, backend_repr: Scalar( Initialized { value: Pointer( @@ -134,8 +126,6 @@ error: layout_of(Option<(*const ()) is !null>) = Layout { }, ), uninhabited: false, - max_repr_align: None, - unadjusted_abi_align: Align(8 bytes), }, ], }, diff --git a/tests/ui/type/pattern_types/range_patterns.stderr b/tests/ui/type/pattern_types/range_patterns.stderr index 4b81cec00d73f..556376164d9a3 100644 --- a/tests/ui/type/pattern_types/range_patterns.stderr +++ b/tests/ui/type/pattern_types/range_patterns.stderr @@ -129,9 +129,6 @@ error: layout_of(Option<(u32) is 1..>) = Layout { variants: [ VariantLayout { size: Size(0 bytes), - align: AbiAlign { - abi: Align(1 bytes), - }, backend_repr: Memory { sized: true, }, @@ -139,14 +136,9 @@ error: layout_of(Option<(u32) is 1..>) = Layout { fields_in_memory_order: [], largest_niche: None, uninhabited: false, - max_repr_align: None, - unadjusted_abi_align: Align(1 bytes), }, VariantLayout { size: Size(4 bytes), - align: AbiAlign { - abi: Align(4 bytes), - }, backend_repr: Scalar( Initialized { value: Int( @@ -173,8 +165,6 @@ error: layout_of(Option<(u32) is 1..>) = Layout { }, ), uninhabited: false, - max_repr_align: None, - unadjusted_abi_align: Align(4 bytes), }, ], }, @@ -228,9 +218,6 @@ error: layout_of(Option>) = Layout { variants: [ VariantLayout { size: Size(0 bytes), - align: AbiAlign { - abi: Align(1 bytes), - }, backend_repr: Memory { sized: true, }, @@ -238,14 +225,9 @@ error: layout_of(Option>) = Layout { fields_in_memory_order: [], largest_niche: None, uninhabited: false, - max_repr_align: None, - unadjusted_abi_align: Align(1 bytes), }, VariantLayout { size: Size(4 bytes), - align: AbiAlign { - abi: Align(4 bytes), - }, backend_repr: Scalar( Initialized { value: Int( @@ -272,8 +254,6 @@ error: layout_of(Option>) = Layout { }, ), uninhabited: false, - max_repr_align: None, - unadjusted_abi_align: Align(4 bytes), }, ], }, From 19c636511095f8f9dd9247c55034a903e2593ea2 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Fri, 15 May 2026 14:37:12 +1000 Subject: [PATCH 08/29] Inline and remove `late_lint_crate_inner` It has a single call site. --- compiler/rustc_lint/src/late.rs | 8 -------- 1 file changed, 8 deletions(-) diff --git a/compiler/rustc_lint/src/late.rs b/compiler/rustc_lint/src/late.rs index 3cc0d46d8541f..0a074c6652a1d 100644 --- a/compiler/rustc_lint/src/late.rs +++ b/compiler/rustc_lint/src/late.rs @@ -439,14 +439,6 @@ fn late_lint_crate<'tcx>(tcx: TyCtxt<'tcx>) { filtered_passes.push(Box::new(HardwiredLints)); let pass = RuntimeCombinedLateLintPass { passes: &mut filtered_passes[..] }; - late_lint_crate_inner(tcx, context, pass); -} - -fn late_lint_crate_inner<'tcx, T: LateLintPass<'tcx>>( - tcx: TyCtxt<'tcx>, - context: LateContext<'tcx>, - pass: T, -) { let mut cx = LateContextAndPass { context, pass }; // Visit the whole crate. From 40332688e0185b6ea6f1ba7286958d7bea1b18e8 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Fri, 15 May 2026 17:57:02 +1000 Subject: [PATCH 09/29] Remove an unnecessary `push` argument It's always `None`. --- compiler/rustc_lint/src/early.rs | 2 +- compiler/rustc_lint/src/levels.rs | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/compiler/rustc_lint/src/early.rs b/compiler/rustc_lint/src/early.rs index 903e223e97938..df6683c14df42 100644 --- a/compiler/rustc_lint/src/early.rs +++ b/compiler/rustc_lint/src/early.rs @@ -53,7 +53,7 @@ impl<'ecx, T: EarlyLintPass> EarlyContextAndPass<'ecx, T> { { let is_crate_node = id == ast::CRATE_NODE_ID; debug!(?id); - let push = self.context.builder.push(attrs, is_crate_node, None); + let push = self.context.builder.push(attrs, is_crate_node); debug!("early context: enter_attrs({:?})", attrs); lint_callback!(self, check_attributes, attrs); diff --git a/compiler/rustc_lint/src/levels.rs b/compiler/rustc_lint/src/levels.rs index ad74b0ee906a1..25cc788b63bfa 100644 --- a/compiler/rustc_lint/src/levels.rs +++ b/compiler/rustc_lint/src/levels.rs @@ -417,13 +417,12 @@ impl<'s> LintLevelsBuilder<'s, TopDown> { &mut self, attrs: &[ast::Attribute], is_crate_node: bool, - source_hir_id: Option, ) -> BuilderPush { let prev = self.provider.cur; self.provider.cur = self.provider.sets.list.push(LintSet { specs: FxIndexMap::default(), parent: prev }); - self.add(attrs, is_crate_node, source_hir_id); + self.add(attrs, is_crate_node, None); if self.provider.current_specs().is_empty() { self.provider.sets.list.pop(); From ecf01910d554f37fcc101c48fe43b1d0f749e5db Mon Sep 17 00:00:00 2001 From: cijiugechu Date: Fri, 15 May 2026 17:43:09 +0800 Subject: [PATCH 10/29] Avoid rustfix suggestions for macro-expanded unused imports --- compiler/rustc_resolve/src/check_unused.rs | 15 ++++++++----- compiler/rustc_resolve/src/errors.rs | 2 +- ...ed-import-in-macro-expansion-rustfix.fixed | 22 +++++++++++++++++++ ...nused-import-in-macro-expansion-rustfix.rs | 22 +++++++++++++++++++ 4 files changed, 55 insertions(+), 6 deletions(-) create mode 100644 tests/ui/imports/unused-import-in-macro-expansion-rustfix.fixed create mode 100644 tests/ui/imports/unused-import-in-macro-expansion-rustfix.rs diff --git a/compiler/rustc_resolve/src/check_unused.rs b/compiler/rustc_resolve/src/check_unused.rs index 8ab0087ae6158..efa6e08a34fa4 100644 --- a/compiler/rustc_resolve/src/check_unused.rs +++ b/compiler/rustc_resolve/src/check_unused.rs @@ -486,6 +486,9 @@ impl Resolver<'_, '_> { let remove_whole_use = remove_spans.len() == 1 && remove_spans[0] == unused.item_span; let num_to_remove = ms.primary_spans().len(); + // Only offer rustfix suggestions for spans that point at directly editable code. + let can_suggest_removal = + remove_spans.iter().all(|span| span.can_be_used_for_suggestions()); // If we are in the `--test` mode, suppress a help that adds the `#[cfg(test)]` // attribute; however, if not, suggest adding the attribute. There is no way to @@ -516,11 +519,13 @@ impl Resolver<'_, '_> { unused.use_tree_id, ms, move |dcx, level, sess| { - let sugg = if remove_whole_use { - errors::UnusedImportsSugg::RemoveWholeUse { span: remove_spans[0] } - } else { - errors::UnusedImportsSugg::RemoveImports { remove_spans, num_to_remove } - }; + let sugg = can_suggest_removal.then(|| { + if remove_whole_use { + errors::UnusedImportsSugg::RemoveWholeUse { span: remove_spans[0] } + } else { + errors::UnusedImportsSugg::RemoveImports { remove_spans, num_to_remove } + } + }); let test_module_span = test_module_span.map(|span| { sess.downcast_ref::() .expect("expected a `Session`") diff --git a/compiler/rustc_resolve/src/errors.rs b/compiler/rustc_resolve/src/errors.rs index 342484a8c0d51..4bcc7a5eb02e8 100644 --- a/compiler/rustc_resolve/src/errors.rs +++ b/compiler/rustc_resolve/src/errors.rs @@ -1742,7 +1742,7 @@ pub(crate) struct ElidedLifetimesInPaths { )] pub(crate) struct UnusedImports { #[subdiagnostic] - pub sugg: UnusedImportsSugg, + pub sugg: Option, #[help("if this is a test module, consider adding a `#[cfg(test)]` to the containing module")] pub test_module_span: Option, diff --git a/tests/ui/imports/unused-import-in-macro-expansion-rustfix.fixed b/tests/ui/imports/unused-import-in-macro-expansion-rustfix.fixed new file mode 100644 index 0000000000000..00cc0238688d9 --- /dev/null +++ b/tests/ui/imports/unused-import-in-macro-expansion-rustfix.fixed @@ -0,0 +1,22 @@ +//@ edition:2024 +//@ run-rustfix +//@ rustfix-only-machine-applicable +//@ check-pass + +mod m { + macro_rules! define_new_macro { + ($name:ident) => { + macro_rules! $name { + () => {}; + } + pub(crate) use $name; + }; + } + + define_new_macro!(item_used); + define_new_macro!(item_unused); +} + +fn main() { + m::item_used!(); +} diff --git a/tests/ui/imports/unused-import-in-macro-expansion-rustfix.rs b/tests/ui/imports/unused-import-in-macro-expansion-rustfix.rs new file mode 100644 index 0000000000000..00cc0238688d9 --- /dev/null +++ b/tests/ui/imports/unused-import-in-macro-expansion-rustfix.rs @@ -0,0 +1,22 @@ +//@ edition:2024 +//@ run-rustfix +//@ rustfix-only-machine-applicable +//@ check-pass + +mod m { + macro_rules! define_new_macro { + ($name:ident) => { + macro_rules! $name { + () => {}; + } + pub(crate) use $name; + }; + } + + define_new_macro!(item_used); + define_new_macro!(item_unused); +} + +fn main() { + m::item_used!(); +} From 9d769128a75769e6930db0f7bfae2bdbc4106adb Mon Sep 17 00:00:00 2001 From: cijiugechu Date: Fri, 15 May 2026 17:49:11 +0800 Subject: [PATCH 11/29] comment for issue id --- tests/ui/imports/unused-import-in-macro-expansion-rustfix.fixed | 1 + tests/ui/imports/unused-import-in-macro-expansion-rustfix.rs | 1 + 2 files changed, 2 insertions(+) diff --git a/tests/ui/imports/unused-import-in-macro-expansion-rustfix.fixed b/tests/ui/imports/unused-import-in-macro-expansion-rustfix.fixed index 00cc0238688d9..a60805eb3287d 100644 --- a/tests/ui/imports/unused-import-in-macro-expansion-rustfix.fixed +++ b/tests/ui/imports/unused-import-in-macro-expansion-rustfix.fixed @@ -1,3 +1,4 @@ +// Regression test for //@ edition:2024 //@ run-rustfix //@ rustfix-only-machine-applicable diff --git a/tests/ui/imports/unused-import-in-macro-expansion-rustfix.rs b/tests/ui/imports/unused-import-in-macro-expansion-rustfix.rs index 00cc0238688d9..a60805eb3287d 100644 --- a/tests/ui/imports/unused-import-in-macro-expansion-rustfix.rs +++ b/tests/ui/imports/unused-import-in-macro-expansion-rustfix.rs @@ -1,3 +1,4 @@ +// Regression test for //@ edition:2024 //@ run-rustfix //@ rustfix-only-machine-applicable From 209ee9daac941699f8043fa24c9db68e084f6699 Mon Sep 17 00:00:00 2001 From: cijiugechu Date: Fri, 15 May 2026 17:49:33 +0800 Subject: [PATCH 12/29] use edition 2021 --- tests/ui/imports/unused-import-in-macro-expansion-rustfix.fixed | 2 +- tests/ui/imports/unused-import-in-macro-expansion-rustfix.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/ui/imports/unused-import-in-macro-expansion-rustfix.fixed b/tests/ui/imports/unused-import-in-macro-expansion-rustfix.fixed index a60805eb3287d..3b7c8051122fc 100644 --- a/tests/ui/imports/unused-import-in-macro-expansion-rustfix.fixed +++ b/tests/ui/imports/unused-import-in-macro-expansion-rustfix.fixed @@ -1,5 +1,5 @@ // Regression test for -//@ edition:2024 +//@ edition:2021 //@ run-rustfix //@ rustfix-only-machine-applicable //@ check-pass diff --git a/tests/ui/imports/unused-import-in-macro-expansion-rustfix.rs b/tests/ui/imports/unused-import-in-macro-expansion-rustfix.rs index a60805eb3287d..3b7c8051122fc 100644 --- a/tests/ui/imports/unused-import-in-macro-expansion-rustfix.rs +++ b/tests/ui/imports/unused-import-in-macro-expansion-rustfix.rs @@ -1,5 +1,5 @@ // Regression test for -//@ edition:2024 +//@ edition:2021 //@ run-rustfix //@ rustfix-only-machine-applicable //@ check-pass From 19045f8546e0dde19b46d4e767990bc353066955 Mon Sep 17 00:00:00 2001 From: Kajetan Puchalski Date: Fri, 15 May 2026 14:24:02 +0100 Subject: [PATCH 13/29] ci: Update FreeBSD version to FreeBSD 14 FreeBSD 12 & 13 are now EOL. The decision to move to FreeBSD 13 was not implemented due to the issues with the toolchain. Now that FreeBSD 14 is the most recent supported version, we should use it for builds in CI. Signed-off-by: Kajetan Puchalski --- src/ci/docker/host-x86_64/dist-various-2/Dockerfile | 6 +++--- .../host-x86_64/dist-x86_64-freebsd/Dockerfile | 6 +++--- src/ci/docker/scripts/freebsd-toolchain.sh | 13 +++++++------ 3 files changed, 13 insertions(+), 12 deletions(-) diff --git a/src/ci/docker/host-x86_64/dist-various-2/Dockerfile b/src/ci/docker/host-x86_64/dist-various-2/Dockerfile index 0414933801294..77a8807da40ba 100644 --- a/src/ci/docker/host-x86_64/dist-various-2/Dockerfile +++ b/src/ci/docker/host-x86_64/dist-various-2/Dockerfile @@ -50,9 +50,9 @@ ENV \ CFLAGS_x86_64_fortanix_unknown_sgx="-D__ELF__ -isystem/usr/include/x86_64-linux-gnu -mlvi-hardening -mllvm -x86-experimental-lvi-inline-asm-hardening" \ CXX_x86_64_fortanix_unknown_sgx=clang++-11 \ CXXFLAGS_x86_64_fortanix_unknown_sgx="-D__ELF__ -isystem/usr/include/x86_64-linux-gnu -mlvi-hardening -mllvm -x86-experimental-lvi-inline-asm-hardening" \ - AR_i686_unknown_freebsd=i686-unknown-freebsd12-ar \ - CC_i686_unknown_freebsd=i686-unknown-freebsd12-clang \ - CXX_i686_unknown_freebsd=i686-unknown-freebsd12-clang++ \ + AR_i686_unknown_freebsd=i686-unknown-freebsd14-ar \ + CC_i686_unknown_freebsd=i686-unknown-freebsd14-clang \ + CXX_i686_unknown_freebsd=i686-unknown-freebsd14-clang++ \ CC_aarch64_unknown_uefi=clang-11 \ CXX_aarch64_unknown_uefi=clang++-11 \ CC_i686_unknown_uefi=clang-11 \ diff --git a/src/ci/docker/host-x86_64/dist-x86_64-freebsd/Dockerfile b/src/ci/docker/host-x86_64/dist-x86_64-freebsd/Dockerfile index e62aa74662bed..5f11437c786c2 100644 --- a/src/ci/docker/host-x86_64/dist-x86_64-freebsd/Dockerfile +++ b/src/ci/docker/host-x86_64/dist-x86_64-freebsd/Dockerfile @@ -29,9 +29,9 @@ COPY scripts/cmake.sh /scripts/ RUN /scripts/cmake.sh ENV \ - AR_x86_64_unknown_freebsd=x86_64-unknown-freebsd12-ar \ - CC_x86_64_unknown_freebsd=x86_64-unknown-freebsd12-clang \ - CXX_x86_64_unknown_freebsd=x86_64-unknown-freebsd12-clang++ + AR_x86_64_unknown_freebsd=x86_64-unknown-freebsd14-ar \ + CC_x86_64_unknown_freebsd=x86_64-unknown-freebsd14-clang \ + CXX_x86_64_unknown_freebsd=x86_64-unknown-freebsd14-clang++ ENV HOSTS=x86_64-unknown-freebsd diff --git a/src/ci/docker/scripts/freebsd-toolchain.sh b/src/ci/docker/scripts/freebsd-toolchain.sh index 56b3c5cd82e7d..5308288d911a0 100755 --- a/src/ci/docker/scripts/freebsd-toolchain.sh +++ b/src/ci/docker/scripts/freebsd-toolchain.sh @@ -5,8 +5,9 @@ set -eux arch=$1 binutils_version=2.40 -freebsd_version=12.3 -triple=$arch-unknown-freebsd12 +freebsd_version=14.4 +freebsd_date=2026-03-10 +triple=$arch-unknown-freebsd14 sysroot=/usr/local/$triple hide_output() { @@ -52,16 +53,16 @@ files_to_extract=( "./usr/lib/*crt*.o" ) # Try to unpack only the libraries the build needs, to save space. -for lib in c cxxrt gcc_s m thr util; do +for lib in c c++ cxxrt gcc_s m thr util; do files_to_extract=("${files_to_extract[@]}" "./lib/lib${lib}.*" "./usr/lib/lib${lib}.*") done -for lib in c++ c_nonshared compiler_rt execinfo gcc pthread rt ssp_nonshared procstat devstat kvm memstat; do +for lib in c_nonshared compiler_rt execinfo gcc pthread rt ssp_nonshared procstat devstat kvm memstat; do files_to_extract=("${files_to_extract[@]}" "./usr/lib/lib${lib}.*") done # Originally downloaded from: # URL=https://download.freebsd.org/ftp/releases/${freebsd_arch}/${freebsd_version}-RELEASE/base.txz -URL=https://ci-mirrors.rust-lang.org/rustc/2022-05-06-freebsd-${freebsd_version}-${freebsd_arch}-base.txz +URL=https://ci-mirrors.rust-lang.org/rustc/${freebsd_date}-freebsd-${freebsd_version}-${freebsd_arch}-base.txz curl "$URL" | tar xJf - -C "$sysroot" --wildcards "${files_to_extract[@]}" # Clang can do cross-builds out of the box, if we give it the right @@ -70,7 +71,7 @@ curl "$URL" | tar xJf - -C "$sysroot" --wildcards "${files_to_extract[@]}" # there might be other problems.) # # The --target option is last because the cross-build of LLVM uses -# --target without an OS version ("-freebsd" vs. "-freebsd12"). This +# --target without an OS version ("-freebsd" vs. "-freebsd14"). This # makes Clang default to libstdc++ (which no longer exists), and also # controls other features, like GNU-style symbol table hashing and # anything predicated on the version number in the __FreeBSD__ From e15861bdd26d35447a1d96f2c3fc5715fd3497d2 Mon Sep 17 00:00:00 2001 From: Ian McCormack Date: Thu, 30 Apr 2026 19:49:04 -0400 Subject: [PATCH 14/29] Add trait methods for experimental retags to cg. --- .../rustc_codegen_gcc/src/intrinsic/mod.rs | 10 +++- compiler/rustc_codegen_llvm/src/context.rs | 55 ++++++++++++++----- compiler/rustc_codegen_llvm/src/intrinsic.rs | 27 +++++++++ compiler/rustc_codegen_ssa/src/lib.rs | 32 +++++++++++ .../rustc_codegen_ssa/src/traits/intrinsic.rs | 5 ++ 5 files changed, 113 insertions(+), 16 deletions(-) diff --git a/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs b/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs index d823e209fd7d9..6fb25174bf1e0 100644 --- a/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs +++ b/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs @@ -6,7 +6,6 @@ use std::iter; use gccjit::{ComparisonOp, Function, FunctionType, RValue, ToRValue, Type, UnaryOp}; use rustc_abi::{BackendRepr, HasDataLayout, WrappingRange}; -use rustc_codegen_ssa::MemFlags; use rustc_codegen_ssa::base::wants_msvc_seh; use rustc_codegen_ssa::common::IntPredicate; use rustc_codegen_ssa::errors::InvalidMonomorphization; @@ -18,6 +17,7 @@ use rustc_codegen_ssa::traits::{ ArgAbiBuilderMethods, BaseTypeCodegenMethods, BuilderMethods, ConstCodegenMethods, IntrinsicCallBuilderMethods, LayoutTypeCodegenMethods, }; +use rustc_codegen_ssa::{MemFlags, RetagInfo}; use rustc_data_structures::fx::FxHashSet; #[cfg(feature = "master")] use rustc_middle::ty::layout::FnAbiOf; @@ -702,6 +702,14 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tc // FIXME(antoyo): implement. self.context.new_rvalue_from_int(self.int_type, 0) } + + fn retag_reg(&mut self, _ptr: Self::Value, _info: &RetagInfo) -> Self::Value { + unimplemented!() + } + + fn retag_mem(&mut self, _ptr: Self::Value, _info: &RetagInfo) { + unimplemented!() + } } impl<'a, 'gcc, 'tcx> ArgAbiBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tcx> { diff --git a/compiler/rustc_codegen_llvm/src/context.rs b/compiler/rustc_codegen_llvm/src/context.rs index 5b730b820b84a..3e575f969afab 100644 --- a/compiler/rustc_codegen_llvm/src/context.rs +++ b/compiler/rustc_codegen_llvm/src/context.rs @@ -959,22 +959,47 @@ impl<'ll> CodegenCx<'ll, '_> { base_name: &str, type_params: &[&'ll Type], ) -> (&'ll Type, &'ll Value) { - // This isn't an "LLVM intrinsic", but LLVM's optimization passes - // recognize it like one (including turning it into `bcmp` sometimes) - // and we use it to implement intrinsics like `raw_eq` and `compare_bytes` - if base_name == "memcmp" { - let fn_ty = self - .type_func(&[self.type_ptr(), self.type_ptr(), self.type_isize()], self.type_int()); - let f = self.declare_cfn("memcmp", llvm::UnnamedAddr::No, fn_ty); - - return (fn_ty, f); - } - - let intrinsic = llvm::Intrinsic::lookup(base_name.as_bytes()) - .unwrap_or_else(|| bug!("Unknown intrinsic: `{base_name}`")); - let f = intrinsic.get_declaration(self.llmod, &type_params); + match base_name { + // This isn't an "LLVM intrinsic", but LLVM's optimization passes + // recognize it like one (including turning it into `bcmp` sometimes) + // and we use it to implement intrinsics like `raw_eq` and `compare_bytes` + "memcmp" => { + let fn_ty = self.type_func( + &[self.type_ptr(), self.type_ptr(), self.type_isize()], + self.type_int(), + ); + let f = self.declare_cfn("memcmp", llvm::UnnamedAddr::No, fn_ty); - (self.get_type_of_global(f), f) + (fn_ty, f) + } + // Experimental retag intrinsics. + // This form is used to retag a pointer that has already been stored in a register. It receives + // the pointer and returns an alias with the same address, but different provenance. + "__rust_retag_reg" => { + let fn_ty = self.type_func(type_params, self.type_ptr()); + let llfn = self.declare_cfn(base_name, llvm::UnnamedAddr::No, fn_ty); + let nounwind = llvm::AttributeKind::NoUnwind.create_attr(self.llcx); + attributes::apply_to_llfn(llfn, llvm::AttributePlace::Function, &[nounwind]); + (fn_ty, llfn) + } + // This form is used to retag a pointer that is stored in another place. It receives a pointer to the + // place and returns `void`. This communicates the indirection without requiring an explicit load and + // store. If we used the `reg` form instead, then we would need to load the place, retag it, and then + // store the result back, which would be undefined behavior for `readonly` places. + "__rust_retag_mem" => { + let fn_ty = self.type_func(type_params, self.type_void()); + let llfn = self.declare_cfn(base_name, llvm::UnnamedAddr::No, fn_ty); + let nounwind = llvm::AttributeKind::NoUnwind.create_attr(self.llcx); + attributes::apply_to_llfn(llfn, llvm::AttributePlace::Function, &[nounwind]); + (fn_ty, llfn) + } + _ => { + let intrinsic = llvm::Intrinsic::lookup(base_name.as_bytes()) + .unwrap_or_else(|| bug!("Unknown intrinsic: `{base_name}`")); + let f = intrinsic.get_declaration(self.llmod, &type_params); + (self.get_type_of_global(f), f) + } + } } pub(crate) fn eh_catch_typeinfo(&self) -> &'ll Value { diff --git a/compiler/rustc_codegen_llvm/src/intrinsic.rs b/compiler/rustc_codegen_llvm/src/intrinsic.rs index f2b90403403d1..ec6f068f46580 100644 --- a/compiler/rustc_codegen_llvm/src/intrinsic.rs +++ b/compiler/rustc_codegen_llvm/src/intrinsic.rs @@ -6,6 +6,7 @@ use rustc_abi::{ AddressSpace, Align, BackendRepr, CVariadicStatus, Float, HasDataLayout, Integer, NumScalableVectors, Primitive, Size, WrappingRange, }; +use rustc_codegen_ssa::RetagInfo; use rustc_codegen_ssa::base::{compare_simd_types, wants_msvc_seh, wants_wasm_eh}; use rustc_codegen_ssa::common::{IntPredicate, TypeKind}; use rustc_codegen_ssa::errors::{ExpectedPointerMutability, InvalidMonomorphization}; @@ -1047,6 +1048,14 @@ impl<'ll, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> { fn va_end(&mut self, va_list: &'ll Value) -> &'ll Value { self.call_intrinsic("llvm.va_end", &[self.val_ty(va_list)], &[va_list]) } + + fn retag_reg(&mut self, ptr: Self::Value, info: &RetagInfo) -> Self::Value { + codegen_retag_inner(self, "__rust_retag_reg", ptr, info) + } + + fn retag_mem(&mut self, ptr: Self::Value, info: &RetagInfo) { + codegen_retag_inner(self, "__rust_retag_mem", ptr, info); + } } fn llvm_arch_for(rust_arch: &Arch) -> Option<&'static str> { @@ -1763,6 +1772,24 @@ fn get_rust_try_fn<'a, 'll, 'tcx>( rust_try } +fn codegen_retag_inner<'ll, 'tcx>( + bx: &mut Builder<'_, 'll, 'tcx>, + name: &'static str, + ptr: &'ll Value, + info: &RetagInfo<&'ll Value>, +) -> &'ll Value { + let size = bx.const_usize(info.size.bytes()); + let perms = bx.const_u8(info.flags.bits()); + + bx.call_intrinsic( + name, + // Retag intrinsics have special handling within `CodegenCx::declare_intrinsic` + // to ensure that each form has the correct return type. + &[bx.type_ptr(), bx.val_ty(size), bx.type_i8(), bx.type_ptr(), bx.type_ptr()], + &[ptr, size, perms, info.im_layout, info.pin_layout], + ) +} + fn codegen_autodiff<'ll, 'tcx>( bx: &mut Builder<'_, 'll, 'tcx>, tcx: TyCtxt<'tcx>, diff --git a/compiler/rustc_codegen_ssa/src/lib.rs b/compiler/rustc_codegen_ssa/src/lib.rs index ec1eb7eeb6fc0..b5b9f5ad17b4e 100644 --- a/compiler/rustc_codegen_ssa/src/lib.rs +++ b/compiler/rustc_codegen_ssa/src/lib.rs @@ -17,6 +17,7 @@ use std::io; use std::path::{Path, PathBuf}; use std::sync::Arc; +use rustc_abi::Size; use rustc_data_structures::fx::{FxHashSet, FxIndexMap}; use rustc_data_structures::unord::UnordMap; use rustc_hir::CRATE_HIR_ID; @@ -167,6 +168,37 @@ bitflags::bitflags! { } } +#[derive(Debug, Copy, Clone)] +pub struct RetagInfo { + /// The size of the initial range within the allocation that is + /// associated with the permission created by the retag. + pub size: Size, + /// Encoded type information used to determine the kind of permission + /// created by the retag. + pub flags: RetagFlags, + /// A pointer to a constant array of (offset, size) pairs describing + /// the ranges covered by `UnsafeCell` within the pointee type. + pub im_layout: V, + /// A pointer to a constant array of (offset, size) pairs describing + /// the ranges covered by `UnsafePinned` within the pointee type. + pub pin_layout: V, +} + +bitflags::bitflags! { + #[repr(C)] + #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] + pub struct RetagFlags: u8 { + /// If this is a function-entry retag. + const IS_PROTECTED = 1 << 0; + /// If this is a mutable reference or a `Box`. + const IS_MUTABLE = 1 << 1; + /// If this is a `Box`. + const IS_BOX = 1 << 2; + /// If the pointee type is `Freeze` + const IS_FREEZE = 1 << 3; + } +} + // This is the same as `rustc_session::cstore::NativeLib`, except: // - (important) the `foreign_module` field is missing, because it contains a `DefId`, which can't // be encoded with `FileEncoder`. diff --git a/compiler/rustc_codegen_ssa/src/traits/intrinsic.rs b/compiler/rustc_codegen_ssa/src/traits/intrinsic.rs index d1e6436f6b1eb..fffd9b75f2bf7 100644 --- a/compiler/rustc_codegen_ssa/src/traits/intrinsic.rs +++ b/compiler/rustc_codegen_ssa/src/traits/intrinsic.rs @@ -2,6 +2,7 @@ use rustc_middle::ty; use rustc_span::Span; use super::BackendTypes; +use crate::RetagInfo; use crate::mir::operand::OperandRef; use crate::mir::place::PlaceRef; @@ -49,4 +50,8 @@ pub trait IntrinsicCallBuilderMethods<'tcx>: BackendTypes { /// Trait method used to inject `va_end` on the "spoofed" `VaList` before /// Rust defined C-variadic functions return. fn va_end(&mut self, val: Self::Value) -> Self::Value; + /// Trait method used to retag a pointer stored within a place. + fn retag_mem(&mut self, place: Self::Value, info: &RetagInfo); + /// Trait method used to retag a pointer that has been loaded into a register. + fn retag_reg(&mut self, ptr: Self::Value, info: &RetagInfo) -> Self::Value; } From 5f2e455a1cf7cad807effb6f7be51f75180934f9 Mon Sep 17 00:00:00 2001 From: Michael Howell Date: Fri, 15 May 2026 10:46:35 -0700 Subject: [PATCH 15/29] rustdoc: add test case for `-Drustdoc::` CLI param This works, but I couldn't find any test cases for it. --- ...rr => unescaped_backticks.deny_cli.stderr} | 134 +++++++++--------- tests/rustdoc-ui/lints/unescaped_backticks.rs | 133 ++++++++--------- 2 files changed, 133 insertions(+), 134 deletions(-) rename tests/rustdoc-ui/lints/{unescaped_backticks.stderr => unescaped_backticks.deny_cli.stderr} (91%) diff --git a/tests/rustdoc-ui/lints/unescaped_backticks.stderr b/tests/rustdoc-ui/lints/unescaped_backticks.deny_cli.stderr similarity index 91% rename from tests/rustdoc-ui/lints/unescaped_backticks.stderr rename to tests/rustdoc-ui/lints/unescaped_backticks.deny_cli.stderr index 1bcb88e108f20..3424a355b506b 100644 --- a/tests/rustdoc-ui/lints/unescaped_backticks.stderr +++ b/tests/rustdoc-ui/lints/unescaped_backticks.deny_cli.stderr @@ -1,14 +1,10 @@ error: unescaped backtick - --> $DIR/unescaped_backticks.rs:187:70 + --> $DIR/unescaped_backticks.rs:190:70 | LL | /// if you want your MIR to be modified by the full MIR pipeline, or `#![custom_mir(dialect = | ^ | -note: the lint level is defined here - --> $DIR/unescaped_backticks.rs:1:9 - | -LL | #![deny(rustdoc::unescaped_backticks)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: requested on the command line with `-D rustdoc::unescaped-backticks` help: the closing backtick of an inline code may be missing | LL | /// "runtime", phase = "optimized")]` if you don't. @@ -19,7 +15,7 @@ LL | /// if you want your MIR to be modified by the full MIR pipeline, or \`#![c | + error: unescaped backtick - --> $DIR/unescaped_backticks.rs:232:13 + --> $DIR/unescaped_backticks.rs:235:13 | LL | //! `#![rustc_expected_cgu_reuse(module="spike", cfg="rpass2", kind="post-lto")] | ^ @@ -34,7 +30,7 @@ LL | //! \`#![rustc_expected_cgu_reuse(module="spike", cfg="rpass2", kin | + error: unescaped backtick - --> $DIR/unescaped_backticks.rs:237:13 + --> $DIR/unescaped_backticks.rs:240:13 | LL | /// `cfg=... | ^ @@ -49,7 +45,7 @@ LL | /// \`cfg=... | + error: unescaped backtick - --> $DIR/unescaped_backticks.rs:241:42 + --> $DIR/unescaped_backticks.rs:244:42 | LL | /// `cfg=... and not `#[cfg_attr]` | ^ @@ -64,7 +60,7 @@ LL | /// `cfg=... and not `#[cfg_attr]\` | + error: unescaped backtick - --> $DIR/unescaped_backticks.rs:193:93 + --> $DIR/unescaped_backticks.rs:196:93 | LL | /// Constructs a `TyKind::Error` type and registers a `span_delayed_bug` with the given `msg to | ^ @@ -79,7 +75,7 @@ LL | /// Constructs a `TyKind::Error` type and registers a `span_delayed_bug | + error: unescaped backtick - --> $DIR/unescaped_backticks.rs:202:34 + --> $DIR/unescaped_backticks.rs:205:34 | LL | /// in `nt_to_tokenstream` | ^ @@ -94,7 +90,7 @@ LL | /// in `nt_to_tokenstream\` | + error: unescaped backtick - --> $DIR/unescaped_backticks.rs:208:62 + --> $DIR/unescaped_backticks.rs:211:62 | LL | /// that `Option` only takes up 4 bytes, because `newtype_index! reserves | ^ @@ -109,7 +105,7 @@ LL | /// that `Option` only takes up 4 bytes, because \`newtype_inde | + error: unescaped backtick - --> $DIR/unescaped_backticks.rs:216:52 + --> $DIR/unescaped_backticks.rs:219:52 | LL | /// also avoids the need to import `OpenOptions`. | ^ @@ -124,7 +120,7 @@ LL | /// also avoids the need to import `OpenOptions\`. | + error: unescaped backtick - --> $DIR/unescaped_backticks.rs:221:47 + --> $DIR/unescaped_backticks.rs:224:47 | LL | /// `ChunkedBitSet`. Has no effect if `row` does not exist. | ^ @@ -139,7 +135,7 @@ LL | /// `ChunkedBitSet`. Has no effect if `row\` does not exist. | + error: unescaped backtick - --> $DIR/unescaped_backticks.rs:247:12 + --> $DIR/unescaped_backticks.rs:250:12 | LL | /// RWU`s can get very large, so it uses a more compact representation. | ^ @@ -154,7 +150,7 @@ LL | /// RWU\`s can get very large, so it uses a more compact representation | + error: unescaped backtick - --> $DIR/unescaped_backticks.rs:254:15 + --> $DIR/unescaped_backticks.rs:257:15 | LL | /// in `U2`. | ^ @@ -169,7 +165,7 @@ LL | /// in `U2\`. | + error: unescaped backtick - --> $DIR/unescaped_backticks.rs:271:42 + --> $DIR/unescaped_backticks.rs:274:42 | LL | /// because it contains `[type error]`. Yuck! (See issue #29857 for | ^ @@ -184,7 +180,7 @@ LL | /// because it contains `[type error]\`. Yuck! (See issue #29857 for | + error: unescaped backtick - --> $DIR/unescaped_backticks.rs:281:53 + --> $DIR/unescaped_backticks.rs:284:53 | LL | /// well as the second instance of `A: AutoTrait`) to suppress | ^ @@ -199,7 +195,7 @@ LL | /// well as the second instance of `A: AutoTrait\`) to suppress | + error: unescaped backtick - --> $DIR/unescaped_backticks.rs:291:40 + --> $DIR/unescaped_backticks.rs:294:40 | LL | /// `'a` with `'b` and not `'static`. But it will have to do for | ^ @@ -211,7 +207,7 @@ LL | /// `'a` with `'b` and not `'static\`. But it will have to do for | + error: unescaped backtick - --> $DIR/unescaped_backticks.rs:300:54 + --> $DIR/unescaped_backticks.rs:303:54 | LL | /// `None`. Otherwise, it will return `Some(Dispatch)`. | ^ @@ -226,7 +222,7 @@ LL | /// `None`. Otherwise, it will return `Some(Dispatch)\`. | + error: unescaped backtick - --> $DIR/unescaped_backticks.rs:304:13 + --> $DIR/unescaped_backticks.rs:307:13 | LL | /// or `None` if it isn't. | ^ @@ -238,7 +234,7 @@ LL | /// or `None\` if it isn't. | + error: unescaped backtick - --> $DIR/unescaped_backticks.rs:308:14 + --> $DIR/unescaped_backticks.rs:311:14 | LL | /// `on_event` should be called. | ^ @@ -253,7 +249,7 @@ LL | /// `on_event\` should be called. | + error: unescaped backtick - --> $DIR/unescaped_backticks.rs:313:29 + --> $DIR/unescaped_backticks.rs:316:29 | LL | /// [`rebuild_interest_cache`][rebuild] is called after the value of the max | ^ @@ -268,7 +264,7 @@ LL | /// [`rebuild_interest_cache\`][rebuild] is called after the value of the m | + error: unescaped backtick - --> $DIR/unescaped_backticks.rs:323:5 + --> $DIR/unescaped_backticks.rs:326:5 | LL | / /// The Subscriber` may be accessed by calling [`WeakDispatch::upgrade`], ... | @@ -284,7 +280,7 @@ LL | | /// level changes. to this: `None`. Otherwise, it will return `Some(Dispatch)\`. error: unescaped backtick - --> $DIR/unescaped_backticks.rs:323:5 + --> $DIR/unescaped_backticks.rs:326:5 | LL | / /// The Subscriber` may be accessed by calling [`WeakDispatch::upgrade`], ... | @@ -298,7 +294,7 @@ LL | | /// level changes. to this: or `None\` if it isn't. error: unescaped backtick - --> $DIR/unescaped_backticks.rs:323:5 + --> $DIR/unescaped_backticks.rs:326:5 | LL | / /// The Subscriber` may be accessed by calling [`WeakDispatch::upgrade`], ... | @@ -314,7 +310,7 @@ LL | | /// level changes. to this: `on_event\` should be called. error: unescaped backtick - --> $DIR/unescaped_backticks.rs:323:5 + --> $DIR/unescaped_backticks.rs:326:5 | LL | / /// The Subscriber` may be accessed by calling [`WeakDispatch::upgrade`], ... | @@ -330,7 +326,7 @@ LL | | /// level changes. to this: [`rebuild_interest_cache\`][rebuild] is called after the value of the max error: unescaped backtick - --> $DIR/unescaped_backticks.rs:349:56 + --> $DIR/unescaped_backticks.rs:352:56 | LL | /// instead and use [`CloneCounterObserver::counter`] to increment. | ^ @@ -342,7 +338,7 @@ LL | /// instead and use [`CloneCounterObserver::counter\`] to increment. | + error: unescaped backtick - --> $DIR/unescaped_backticks.rs:12:5 + --> $DIR/unescaped_backticks.rs:15:5 | LL | /// ` | ^ @@ -354,7 +350,7 @@ LL | /// \` | + error: unescaped backtick - --> $DIR/unescaped_backticks.rs:19:7 + --> $DIR/unescaped_backticks.rs:22:7 | LL | /// \` | ^ @@ -369,7 +365,7 @@ LL | /// \\` | + error: unescaped backtick - --> $DIR/unescaped_backticks.rs:26:6 + --> $DIR/unescaped_backticks.rs:29:6 | LL | /// [`link1] | ^ @@ -384,7 +380,7 @@ LL | /// [\`link1] | + error: unescaped backtick - --> $DIR/unescaped_backticks.rs:30:11 + --> $DIR/unescaped_backticks.rs:33:11 | LL | /// [link2`] | ^ @@ -399,7 +395,7 @@ LL | /// [link2\`] | + error: unescaped backtick - --> $DIR/unescaped_backticks.rs:34:6 + --> $DIR/unescaped_backticks.rs:37:6 | LL | /// [`link_long](link_long) | ^ @@ -414,7 +410,7 @@ LL | /// [\`link_long](link_long) | + error: unescaped backtick - --> $DIR/unescaped_backticks.rs:38:6 + --> $DIR/unescaped_backticks.rs:41:6 | LL | /// [`broken-link] | ^ @@ -429,7 +425,7 @@ LL | /// [\`broken-link] | + error: unescaped backtick - --> $DIR/unescaped_backticks.rs:45:8 + --> $DIR/unescaped_backticks.rs:48:8 | LL | /// | ^ @@ -444,7 +440,7 @@ LL | /// | + error: unescaped backtick - --> $DIR/unescaped_backticks.rs:55:6 + --> $DIR/unescaped_backticks.rs:58:6 | LL | /// 🦀`🦀 | ^ @@ -463,7 +459,7 @@ LL | /// 🦀\`🦀 | + error: unescaped backtick - --> $DIR/unescaped_backticks.rs:59:5 + --> $DIR/unescaped_backticks.rs:62:5 | LL | /// `foo( | ^ @@ -478,7 +474,7 @@ LL | /// \`foo( | + error: unescaped backtick - --> $DIR/unescaped_backticks.rs:65:14 + --> $DIR/unescaped_backticks.rs:68:14 | LL | /// `foo `bar` | ^ @@ -493,7 +489,7 @@ LL | /// `foo `bar\` | + error: unescaped backtick - --> $DIR/unescaped_backticks.rs:71:5 + --> $DIR/unescaped_backticks.rs:74:5 | LL | /// `foo( | ^ @@ -508,7 +504,7 @@ LL | /// \`foo( | + error: unescaped backtick - --> $DIR/unescaped_backticks.rs:76:83 + --> $DIR/unescaped_backticks.rs:79:83 | LL | /// Addition is commutative, which means that add(a, b)` is the same as `add(b, a)`. | ^ @@ -523,7 +519,7 @@ LL | /// Addition is commutative, which means that add(a, b)` is the same as `ad | + error: unescaped backtick - --> $DIR/unescaped_backticks.rs:80:51 + --> $DIR/unescaped_backticks.rs:83:51 | LL | /// or even to add a number `n` to 42 (`add(42, b)`)! | ^ @@ -538,7 +534,7 @@ LL | /// or even to add a number `n` to 42 (`add(42, b)\`)! | + error: unescaped backtick - --> $DIR/unescaped_backticks.rs:84:83 + --> $DIR/unescaped_backticks.rs:87:83 | LL | /// Addition is commutative, which means that `add(a, b) is the same as `add(b, a)`. | ^ @@ -553,7 +549,7 @@ LL | /// Addition is commutative, which means that `add(a, b) is the same as `ad | + error: unescaped backtick - --> $DIR/unescaped_backticks.rs:88:51 + --> $DIR/unescaped_backticks.rs:91:51 | LL | /// or even to add a number `n` to 42 (`add(42, n)`)! | ^ @@ -568,7 +564,7 @@ LL | /// or even to add a number `n` to 42 (`add(42, n)\`)! | + error: unescaped backtick - --> $DIR/unescaped_backticks.rs:92:83 + --> $DIR/unescaped_backticks.rs:95:83 | LL | /// Addition is commutative, which means that `add(a, b)` is the same as add(b, a)`. | ^ @@ -583,7 +579,7 @@ LL | /// Addition is commutative, which means that `add(a, b)` is the same as ad | + error: unescaped backtick - --> $DIR/unescaped_backticks.rs:96:50 + --> $DIR/unescaped_backticks.rs:99:50 | LL | /// or even to add a number `n` to 42 (add(42, n)`)! | ^ @@ -598,7 +594,7 @@ LL | /// or even to add a number `n` to 42 (add(42, n)\`)! | + error: unescaped backtick - --> $DIR/unescaped_backticks.rs:100:74 + --> $DIR/unescaped_backticks.rs:103:74 | LL | /// Addition is commutative, which means that `add(a, b)` is the same as `add(b, a). | ^ @@ -613,7 +609,7 @@ LL | /// Addition is commutative, which means that `add(a, b)` is the same as \` | + error: unescaped backtick - --> $DIR/unescaped_backticks.rs:104:51 + --> $DIR/unescaped_backticks.rs:107:51 | LL | /// or even to add a number `n` to 42 (`add(42, n)`)! | ^ @@ -628,7 +624,7 @@ LL | /// or even to add a number `n` to 42 (`add(42, n)\`)! | + error: unescaped backtick - --> $DIR/unescaped_backticks.rs:108:10 + --> $DIR/unescaped_backticks.rs:111:10 | LL | #[doc = "`"] | ^ @@ -639,7 +635,7 @@ LL | #[doc = "`"] to this: \` error: unescaped backtick - --> $DIR/unescaped_backticks.rs:115:26 + --> $DIR/unescaped_backticks.rs:118:26 | LL | #[doc = concat!("\\", "`")] | ^ @@ -652,7 +648,7 @@ LL | #[doc = concat!("\\", "`")] to this: \\` error: unescaped backtick - --> $DIR/unescaped_backticks.rs:119:9 + --> $DIR/unescaped_backticks.rs:122:9 | LL | #[doc = "Addition is commutative, which means that add(a, b)` is the same as `add(b, a)`."] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -665,7 +661,7 @@ LL | #[doc = "Addition is commutative, which means that add(a, b)` is the same a to this: Addition is commutative, which means that add(a, b)` is the same as `add(b, a)\`. error: unescaped backtick - --> $DIR/unescaped_backticks.rs:123:9 + --> $DIR/unescaped_backticks.rs:126:9 | LL | #[doc = "Addition is commutative, which means that `add(a, b) is the same as `add(b, a)`."] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -678,7 +674,7 @@ LL | #[doc = "Addition is commutative, which means that `add(a, b) is the same a to this: Addition is commutative, which means that `add(a, b) is the same as `add(b, a)\`. error: unescaped backtick - --> $DIR/unescaped_backticks.rs:127:9 + --> $DIR/unescaped_backticks.rs:130:9 | LL | #[doc = "Addition is commutative, which means that `add(a, b)` is the same as add(b, a)`."] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -691,7 +687,7 @@ LL | #[doc = "Addition is commutative, which means that `add(a, b)` is the same to this: Addition is commutative, which means that `add(a, b)` is the same as add(b, a)\`. error: unescaped backtick - --> $DIR/unescaped_backticks.rs:131:9 + --> $DIR/unescaped_backticks.rs:134:9 | LL | #[doc = "Addition is commutative, which means that `add(a, b)` is the same as `add(b, a)."] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -704,7 +700,7 @@ LL | #[doc = "Addition is commutative, which means that `add(a, b)` is the same to this: Addition is commutative, which means that `add(a, b)` is the same as \`add(b, a). error: unescaped backtick - --> $DIR/unescaped_backticks.rs:136:5 + --> $DIR/unescaped_backticks.rs:139:5 | LL | /// `foo | ^ @@ -719,7 +715,7 @@ LL | /// \`foo | + error: unescaped backtick - --> $DIR/unescaped_backticks.rs:140:7 + --> $DIR/unescaped_backticks.rs:143:7 | LL | /// # `(heading | ^ @@ -734,7 +730,7 @@ LL | /// # \`(heading | + error: unescaped backtick - --> $DIR/unescaped_backticks.rs:142:17 + --> $DIR/unescaped_backticks.rs:145:17 | LL | /// ## heading2)` | ^ @@ -749,7 +745,7 @@ LL | /// ## heading2)\` | + error: unescaped backtick - --> $DIR/unescaped_backticks.rs:145:11 + --> $DIR/unescaped_backticks.rs:148:11 | LL | /// multi `( | ^ @@ -764,7 +760,7 @@ LL | /// multi \`( | + error: unescaped backtick - --> $DIR/unescaped_backticks.rs:151:10 + --> $DIR/unescaped_backticks.rs:154:10 | LL | /// para)`(graph | ^ @@ -783,7 +779,7 @@ LL | /// para)\`(graph | + error: unescaped backtick - --> $DIR/unescaped_backticks.rs:154:10 + --> $DIR/unescaped_backticks.rs:157:10 | LL | /// para)`(graph2 | ^ @@ -802,7 +798,7 @@ LL | /// para)\`(graph2 | + error: unescaped backtick - --> $DIR/unescaped_backticks.rs:157:12 + --> $DIR/unescaped_backticks.rs:160:12 | LL | /// 1. foo)` | ^ @@ -817,7 +813,7 @@ LL | /// 1. foo)\` | + error: unescaped backtick - --> $DIR/unescaped_backticks.rs:159:8 + --> $DIR/unescaped_backticks.rs:162:8 | LL | /// 2. `(bar | ^ @@ -832,7 +828,7 @@ LL | /// 2. \`(bar | + error: unescaped backtick - --> $DIR/unescaped_backticks.rs:161:11 + --> $DIR/unescaped_backticks.rs:164:11 | LL | /// * baz)` | ^ @@ -847,7 +843,7 @@ LL | /// * baz)\` | + error: unescaped backtick - --> $DIR/unescaped_backticks.rs:163:7 + --> $DIR/unescaped_backticks.rs:166:7 | LL | /// * `(quux | ^ @@ -862,7 +858,7 @@ LL | /// * \`(quux | + error: unescaped backtick - --> $DIR/unescaped_backticks.rs:166:5 + --> $DIR/unescaped_backticks.rs:169:5 | LL | /// `#![this_is_actually_an_image(and(not), an = "attribute")] | ^ @@ -877,7 +873,7 @@ LL | /// \`#![this_is_actually_an_image(and(not), an = "attribute")] | + error: unescaped backtick - --> $DIR/unescaped_backticks.rs:169:62 + --> $DIR/unescaped_backticks.rs:172:62 | LL | /// #![this_is_actually_an_image(and(not), an = "attribute")]` | ^ @@ -892,7 +888,7 @@ LL | /// #![this_is_actually_an_image(and(not), an = "attribute")]\` | + error: unescaped backtick - --> $DIR/unescaped_backticks.rs:174:7 + --> $DIR/unescaped_backticks.rs:177:7 | LL | /// | `table( | )head` | | ^ @@ -907,7 +903,7 @@ LL | /// | \`table( | )head` | | + error: unescaped backtick - --> $DIR/unescaped_backticks.rs:174:22 + --> $DIR/unescaped_backticks.rs:177:22 | LL | /// | `table( | )head` | | ^ @@ -922,7 +918,7 @@ LL | /// | `table( | )head\` | | + error: unescaped backtick - --> $DIR/unescaped_backticks.rs:178:12 + --> $DIR/unescaped_backticks.rs:181:12 | LL | /// | table`( | )`body | | ^ @@ -937,7 +933,7 @@ LL | /// | table\`( | )`body | | + error: unescaped backtick - --> $DIR/unescaped_backticks.rs:178:18 + --> $DIR/unescaped_backticks.rs:181:18 | LL | /// | table`( | )`body | | ^ diff --git a/tests/rustdoc-ui/lints/unescaped_backticks.rs b/tests/rustdoc-ui/lints/unescaped_backticks.rs index 8d6239296bf78..a0c25ca2eaf03 100644 --- a/tests/rustdoc-ui/lints/unescaped_backticks.rs +++ b/tests/rustdoc-ui/lints/unescaped_backticks.rs @@ -1,4 +1,7 @@ -#![deny(rustdoc::unescaped_backticks)] +//@revisions: deny_cli allow_cli +//@[deny_cli] compile-flags: -Drustdoc::unescaped_backticks +//@[allow_cli] compile-flags: -Arustdoc::unescaped_backticks +//@[allow_cli] check-pass #![allow(rustdoc::broken_intra_doc_links)] #![allow(rustdoc::invalid_html_tags)] #![allow(rustdoc::redundant_explicit_links)] @@ -10,40 +13,40 @@ pub fn empty() {} pub fn empty2() {} /// ` -//~^ ERROR unescaped backtick +//[deny_cli]~^ ERROR unescaped backtick pub fn single() {} /// \` pub fn escaped() {} /// \\` -//~^ ERROR unescaped backtick +//[deny_cli]~^ ERROR unescaped backtick pub fn not_escaped() {} /// \\\` pub fn not_not_escaped() {} /// [`link1] -//~^ ERROR unescaped backtick +//[deny_cli]~^ ERROR unescaped backtick pub fn link1() {} /// [link2`] -//~^ ERROR unescaped backtick +//[deny_cli]~^ ERROR unescaped backtick pub fn link2() {} /// [`link_long](link_long) -//~^ ERROR unescaped backtick +//[deny_cli]~^ ERROR unescaped backtick pub fn link_long() {} /// [`broken-link] -//~^ ERROR unescaped backtick +//[deny_cli]~^ ERROR unescaped backtick pub fn broken_link() {} /// pub fn url() {} /// -//~^ ERROR unescaped backtick +//[deny_cli]~^ ERROR unescaped backtick pub fn not_url() {} ///

`

@@ -53,131 +56,131 @@ pub fn html_tag() {} pub fn html_escape() {} /// 🦀`🦀 -//~^ ERROR unescaped backtick +//[deny_cli]~^ ERROR unescaped backtick pub fn unicode() {} /// `foo( -//~^ ERROR unescaped backtick +//[deny_cli]~^ ERROR unescaped backtick /// /// paragraph pub fn paragraph() {} /// `foo `bar` -//~^ ERROR unescaped backtick +//[deny_cli]~^ ERROR unescaped backtick /// /// paragraph pub fn paragraph2() {} /// `foo( -//~^ ERROR unescaped backtick +//[deny_cli]~^ ERROR unescaped backtick /// not paragraph pub fn not_paragraph() {} /// Addition is commutative, which means that add(a, b)` is the same as `add(b, a)`. -//~^ ERROR unescaped backtick +//[deny_cli]~^ ERROR unescaped backtick /// /// You could use this function to add 42 to a number `n` (add(n, 42)`), /// or even to add a number `n` to 42 (`add(42, b)`)! -//~^ ERROR unescaped backtick +//[deny_cli]~^ ERROR unescaped backtick pub fn add1(a: i32, b: i32) -> i32 { a + b } /// Addition is commutative, which means that `add(a, b) is the same as `add(b, a)`. -//~^ ERROR unescaped backtick +//[deny_cli]~^ ERROR unescaped backtick /// /// You could use this function to add 42 to a number `n` (`add(n, 42)), /// or even to add a number `n` to 42 (`add(42, n)`)! -//~^ ERROR unescaped backtick +//[deny_cli]~^ ERROR unescaped backtick pub fn add2(a: i32, b: i32) -> i32 { a + b } /// Addition is commutative, which means that `add(a, b)` is the same as add(b, a)`. -//~^ ERROR unescaped backtick +//[deny_cli]~^ ERROR unescaped backtick /// /// You could use this function to add 42 to a number `n` (`add(n, 42)`), /// or even to add a number `n` to 42 (add(42, n)`)! -//~^ ERROR unescaped backtick +//[deny_cli]~^ ERROR unescaped backtick pub fn add3(a: i32, b: i32) -> i32 { a + b } /// Addition is commutative, which means that `add(a, b)` is the same as `add(b, a). -//~^ ERROR unescaped backtick +//[deny_cli]~^ ERROR unescaped backtick /// /// You could use this function to add 42 to a number `n` (`add(n, 42)), /// or even to add a number `n` to 42 (`add(42, n)`)! -//~^ ERROR unescaped backtick +//[deny_cli]~^ ERROR unescaped backtick pub fn add4(a: i32, b: i32) -> i32 { a + b } #[doc = "`"] -//~^ ERROR unescaped backtick +//[deny_cli]~^ ERROR unescaped backtick pub fn attr() {} #[doc = concat!("\\", "`")] pub fn attr_escaped() {} #[doc = concat!("\\\\", "`")] -//~^ ERROR unescaped backtick +//[deny_cli]~^ ERROR unescaped backtick pub fn attr_not_escaped() {} #[doc = "Addition is commutative, which means that add(a, b)` is the same as `add(b, a)`."] -//~^ ERROR unescaped backtick +//[deny_cli]~^ ERROR unescaped backtick pub fn attr_add1(a: i32, b: i32) -> i32 { a + b } #[doc = "Addition is commutative, which means that `add(a, b) is the same as `add(b, a)`."] -//~^ ERROR unescaped backtick +//[deny_cli]~^ ERROR unescaped backtick pub fn attr_add2(a: i32, b: i32) -> i32 { a + b } #[doc = "Addition is commutative, which means that `add(a, b)` is the same as add(b, a)`."] -//~^ ERROR unescaped backtick +//[deny_cli]~^ ERROR unescaped backtick pub fn attr_add3(a: i32, b: i32) -> i32 { a + b } #[doc = "Addition is commutative, which means that `add(a, b)` is the same as `add(b, a)."] -//~^ ERROR unescaped backtick +//[deny_cli]~^ ERROR unescaped backtick pub fn attr_add4(a: i32, b: i32) -> i32 { a + b } /// ``double backticks`` /// `foo -//~^ ERROR unescaped backtick +//[deny_cli]~^ ERROR unescaped backtick pub fn double_backticks() {} /// # `(heading -//~^ ERROR unescaped backtick +//[deny_cli]~^ ERROR unescaped backtick /// ## heading2)` -//~^ ERROR unescaped backtick +//[deny_cli]~^ ERROR unescaped backtick /// /// multi `( -//~^ ERROR unescaped backtick +//[deny_cli]~^ ERROR unescaped backtick /// line /// ) heading /// = /// /// para)`(graph -//~^ ERROR unescaped backtick +//[deny_cli]~^ ERROR unescaped backtick /// /// para)`(graph2 -//~^ ERROR unescaped backtick +//[deny_cli]~^ ERROR unescaped backtick /// /// 1. foo)` -//~^ ERROR unescaped backtick +//[deny_cli]~^ ERROR unescaped backtick /// 2. `(bar -//~^ ERROR unescaped backtick +//[deny_cli]~^ ERROR unescaped backtick /// * baz)` -//~^ ERROR unescaped backtick +//[deny_cli]~^ ERROR unescaped backtick /// * `(quux -//~^ ERROR unescaped backtick +//[deny_cli]~^ ERROR unescaped backtick /// /// `#![this_is_actually_an_image(and(not), an = "attribute")] -//~^ ERROR unescaped backtick +//[deny_cli]~^ ERROR unescaped backtick /// /// #![this_is_actually_an_image(and(not), an = "attribute")]` -//~^ ERROR unescaped backtick +//[deny_cli]~^ ERROR unescaped backtick /// /// [this_is_actually_an_image(and(not), an = "attribute")]: `.png /// /// | `table( | )head` | -//~^ ERROR unescaped backtick -//~| ERROR unescaped backtick +//[deny_cli]~^ ERROR unescaped backtick +//[deny_cli]~| ERROR unescaped backtick /// |---------|--------| /// | table`( | )`body | -//~^ ERROR unescaped backtick -//~| ERROR unescaped backtick +//[deny_cli]~^ ERROR unescaped backtick +//[deny_cli]~| ERROR unescaped backtick pub fn complicated_markdown() {} /// The `custom_mir` attribute tells the compiler to treat the function as being custom MIR. This @@ -185,13 +188,13 @@ pub fn complicated_markdown() {} /// another function. The `dialect` and `phase` parameters indicate which [version of MIR][dialect /// docs] you are inserting here. Generally you'll want to use `#![custom_mir(dialect = "built")]` /// if you want your MIR to be modified by the full MIR pipeline, or `#![custom_mir(dialect = -//~^ ERROR unescaped backtick +//[deny_cli]~^ ERROR unescaped backtick /// "runtime", phase = "optimized")] if you don't. pub mod mir {} pub mod rustc { /// Constructs a `TyKind::Error` type and registers a `span_delayed_bug` with the given `msg to - //~^ ERROR unescaped backtick + //[deny_cli]~^ ERROR unescaped backtick /// ensure it gets used. pub fn ty_error_with_message() {} @@ -200,13 +203,13 @@ pub mod rustc { /// if we parsed no predicates (e.g. `struct Foo where {} /// This allows us to accurately pretty-print /// in `nt_to_tokenstream` - //~^ ERROR unescaped backtick + //[deny_cli]~^ ERROR unescaped backtick pub has_where_token: bool, } /// A symbol is an interned or gensymed string. The use of `newtype_index!` means /// that `Option` only takes up 4 bytes, because `newtype_index! reserves - //~^ ERROR unescaped backtick + //[deny_cli]~^ ERROR unescaped backtick /// the last 256 values for tagging purposes. pub struct Symbol(); @@ -214,12 +217,12 @@ pub mod rustc { /// readable code. Instead of `OpenOptions::new().read(true).open("foo.txt")` /// you can write `File::with_options().read(true).open("foo.txt"). This /// also avoids the need to import `OpenOptions`. - //~^ ERROR unescaped backtick + //[deny_cli]~^ ERROR unescaped backtick pub fn with_options() {} /// Subtracts `set from `row`. `set` can be either `BitSet` or /// `ChunkedBitSet`. Has no effect if `row` does not exist. - //~^ ERROR unescaped backtick + //[deny_cli]~^ ERROR unescaped backtick /// /// Returns true if the row was changed. pub fn subtract_row() {} @@ -230,29 +233,29 @@ pub mod rustc { //! perturb the reuse results. //! //! `#![rustc_expected_cgu_reuse(module="spike", cfg="rpass2", kind="post-lto")] - //~^ ERROR unescaped backtick + //[deny_cli]~^ ERROR unescaped backtick //! allows for doing a more fine-grained check to see if pre- or post-lto data //! was re-used. /// `cfg=... - //~^ ERROR unescaped backtick + //[deny_cli]~^ ERROR unescaped backtick pub fn foo() {} /// `cfg=... and not `#[cfg_attr]` - //~^ ERROR unescaped backtick + //[deny_cli]~^ ERROR unescaped backtick pub fn bar() {} } /// Conceptually, this is like a `Vec>`. But the number of /// RWU`s can get very large, so it uses a more compact representation. - //~^ ERROR unescaped backtick + //[deny_cli]~^ ERROR unescaped backtick pub struct RWUTable {} /// Like [Self::canonicalize_query], but preserves distinct universes. For /// example, canonicalizing `&'?0: Trait<'?1>`, where `'?0` is in `U1` and /// `'?1` is in `U3` would be canonicalized to have ?0` in `U1` and `'?1` /// in `U2`. - //~^ ERROR unescaped backtick + //[deny_cli]~^ ERROR unescaped backtick /// /// This is used for Chalk integration. pub fn canonicalize_query_preserving_universes() {} @@ -269,7 +272,7 @@ pub mod rustc { /// ` as Trait>::Foo`. We are supposed to report /// an error for this obligation, but we legitimately should not, /// because it contains `[type error]`. Yuck! (See issue #29857 for - //~^ ERROR unescaped backtick + //[deny_cli]~^ ERROR unescaped backtick /// one case where this arose.) pub fn normalize_to_error() {} @@ -279,7 +282,7 @@ pub mod rustc { /// encountered a problem (later on) with `A: AutoTrait. So we /// currently set a flag on the stack node for `B: AutoTrait` (as /// well as the second instance of `A: AutoTrait`) to suppress - //~^ ERROR unescaped backtick + //[deny_cli]~^ ERROR unescaped backtick /// caching. pub struct TraitObligationStack; @@ -289,7 +292,7 @@ pub mod rustc { /// actually stricter than necessary: ideally, we'd support bounds /// like `for<'a: 'b`>` that might then allow us to approximate /// `'a` with `'b` and not `'static`. But it will have to do for - //~^ ERROR unescaped backtick + //[deny_cli]~^ ERROR unescaped backtick /// now. pub fn add_incompatible_universe(){} } @@ -298,20 +301,20 @@ pub mod rustc { /// which returns an `Option`. If all [`Dispatch`] clones that point /// at the `Subscriber` have been dropped, [`WeakDispatch::upgrade`] will return /// `None`. Otherwise, it will return `Some(Dispatch)`. -//~^ ERROR unescaped backtick +//[deny_cli]~^ ERROR unescaped backtick /// /// Returns some reference to this `[`Subscriber`] value if it is of type `T`, /// or `None` if it isn't. -//~^ ERROR unescaped backtick +//[deny_cli]~^ ERROR unescaped backtick /// /// Called before the filtered [`Layer]'s [`on_event`], to determine if /// `on_event` should be called. -//~^ ERROR unescaped backtick +//[deny_cli]~^ ERROR unescaped backtick /// /// Therefore, if the `Filter will change the value returned by this /// method, it is responsible for ensuring that /// [`rebuild_interest_cache`][rebuild] is called after the value of the max -//~^ ERROR unescaped backtick +//[deny_cli]~^ ERROR unescaped backtick /// level changes. pub mod tracing {} @@ -321,10 +324,10 @@ macro_rules! id { id! { /// The Subscriber` may be accessed by calling [`WeakDispatch::upgrade`], - //~^ ERROR unescaped backtick - //~| ERROR unescaped backtick - //~| ERROR unescaped backtick - //~| ERROR unescaped backtick + //[deny_cli]~^ ERROR unescaped backtick + //[deny_cli]~| ERROR unescaped backtick + //[deny_cli]~| ERROR unescaped backtick + //[deny_cli]~| ERROR unescaped backtick /// which returns an `Option`. If all [`Dispatch`] clones that point /// at the `Subscriber` have been dropped, [`WeakDispatch::upgrade`] will return /// `None`. Otherwise, it will return `Some(Dispatch)`. @@ -347,7 +350,7 @@ pub mod trillium_server_common { /// One-indexed, because the first CloneCounter is included. If you don't /// want the original to count, construct a [``CloneCounterObserver`] /// instead and use [`CloneCounterObserver::counter`] to increment. - //~^ ERROR unescaped backtick + //[deny_cli]~^ ERROR unescaped backtick pub struct CloneCounter; /// This is used by the above. From 0344a0226199f732da17a92f9afc02fc951a5daf Mon Sep 17 00:00:00 2001 From: Michael Howell Date: Fri, 15 May 2026 11:13:16 -0700 Subject: [PATCH 16/29] rustdoc: add test case for `--cap-lints=allow` --- .../lints/unescaped_backticks.deny_cli.stderr | 128 +++++++++--------- tests/rustdoc-ui/lints/unescaped_backticks.rs | 4 +- 2 files changed, 67 insertions(+), 65 deletions(-) diff --git a/tests/rustdoc-ui/lints/unescaped_backticks.deny_cli.stderr b/tests/rustdoc-ui/lints/unescaped_backticks.deny_cli.stderr index 3424a355b506b..6a2396ea1f9d6 100644 --- a/tests/rustdoc-ui/lints/unescaped_backticks.deny_cli.stderr +++ b/tests/rustdoc-ui/lints/unescaped_backticks.deny_cli.stderr @@ -1,5 +1,5 @@ error: unescaped backtick - --> $DIR/unescaped_backticks.rs:190:70 + --> $DIR/unescaped_backticks.rs:192:70 | LL | /// if you want your MIR to be modified by the full MIR pipeline, or `#![custom_mir(dialect = | ^ @@ -15,7 +15,7 @@ LL | /// if you want your MIR to be modified by the full MIR pipeline, or \`#![c | + error: unescaped backtick - --> $DIR/unescaped_backticks.rs:235:13 + --> $DIR/unescaped_backticks.rs:237:13 | LL | //! `#![rustc_expected_cgu_reuse(module="spike", cfg="rpass2", kind="post-lto")] | ^ @@ -30,7 +30,7 @@ LL | //! \`#![rustc_expected_cgu_reuse(module="spike", cfg="rpass2", kin | + error: unescaped backtick - --> $DIR/unescaped_backticks.rs:240:13 + --> $DIR/unescaped_backticks.rs:242:13 | LL | /// `cfg=... | ^ @@ -45,7 +45,7 @@ LL | /// \`cfg=... | + error: unescaped backtick - --> $DIR/unescaped_backticks.rs:244:42 + --> $DIR/unescaped_backticks.rs:246:42 | LL | /// `cfg=... and not `#[cfg_attr]` | ^ @@ -60,7 +60,7 @@ LL | /// `cfg=... and not `#[cfg_attr]\` | + error: unescaped backtick - --> $DIR/unescaped_backticks.rs:196:93 + --> $DIR/unescaped_backticks.rs:198:93 | LL | /// Constructs a `TyKind::Error` type and registers a `span_delayed_bug` with the given `msg to | ^ @@ -75,7 +75,7 @@ LL | /// Constructs a `TyKind::Error` type and registers a `span_delayed_bug | + error: unescaped backtick - --> $DIR/unescaped_backticks.rs:205:34 + --> $DIR/unescaped_backticks.rs:207:34 | LL | /// in `nt_to_tokenstream` | ^ @@ -90,7 +90,7 @@ LL | /// in `nt_to_tokenstream\` | + error: unescaped backtick - --> $DIR/unescaped_backticks.rs:211:62 + --> $DIR/unescaped_backticks.rs:213:62 | LL | /// that `Option` only takes up 4 bytes, because `newtype_index! reserves | ^ @@ -105,7 +105,7 @@ LL | /// that `Option` only takes up 4 bytes, because \`newtype_inde | + error: unescaped backtick - --> $DIR/unescaped_backticks.rs:219:52 + --> $DIR/unescaped_backticks.rs:221:52 | LL | /// also avoids the need to import `OpenOptions`. | ^ @@ -120,7 +120,7 @@ LL | /// also avoids the need to import `OpenOptions\`. | + error: unescaped backtick - --> $DIR/unescaped_backticks.rs:224:47 + --> $DIR/unescaped_backticks.rs:226:47 | LL | /// `ChunkedBitSet`. Has no effect if `row` does not exist. | ^ @@ -135,7 +135,7 @@ LL | /// `ChunkedBitSet`. Has no effect if `row\` does not exist. | + error: unescaped backtick - --> $DIR/unescaped_backticks.rs:250:12 + --> $DIR/unescaped_backticks.rs:252:12 | LL | /// RWU`s can get very large, so it uses a more compact representation. | ^ @@ -150,7 +150,7 @@ LL | /// RWU\`s can get very large, so it uses a more compact representation | + error: unescaped backtick - --> $DIR/unescaped_backticks.rs:257:15 + --> $DIR/unescaped_backticks.rs:259:15 | LL | /// in `U2`. | ^ @@ -165,7 +165,7 @@ LL | /// in `U2\`. | + error: unescaped backtick - --> $DIR/unescaped_backticks.rs:274:42 + --> $DIR/unescaped_backticks.rs:276:42 | LL | /// because it contains `[type error]`. Yuck! (See issue #29857 for | ^ @@ -180,7 +180,7 @@ LL | /// because it contains `[type error]\`. Yuck! (See issue #29857 for | + error: unescaped backtick - --> $DIR/unescaped_backticks.rs:284:53 + --> $DIR/unescaped_backticks.rs:286:53 | LL | /// well as the second instance of `A: AutoTrait`) to suppress | ^ @@ -195,7 +195,7 @@ LL | /// well as the second instance of `A: AutoTrait\`) to suppress | + error: unescaped backtick - --> $DIR/unescaped_backticks.rs:294:40 + --> $DIR/unescaped_backticks.rs:296:40 | LL | /// `'a` with `'b` and not `'static`. But it will have to do for | ^ @@ -207,7 +207,7 @@ LL | /// `'a` with `'b` and not `'static\`. But it will have to do for | + error: unescaped backtick - --> $DIR/unescaped_backticks.rs:303:54 + --> $DIR/unescaped_backticks.rs:305:54 | LL | /// `None`. Otherwise, it will return `Some(Dispatch)`. | ^ @@ -222,7 +222,7 @@ LL | /// `None`. Otherwise, it will return `Some(Dispatch)\`. | + error: unescaped backtick - --> $DIR/unescaped_backticks.rs:307:13 + --> $DIR/unescaped_backticks.rs:309:13 | LL | /// or `None` if it isn't. | ^ @@ -234,7 +234,7 @@ LL | /// or `None\` if it isn't. | + error: unescaped backtick - --> $DIR/unescaped_backticks.rs:311:14 + --> $DIR/unescaped_backticks.rs:313:14 | LL | /// `on_event` should be called. | ^ @@ -249,7 +249,7 @@ LL | /// `on_event\` should be called. | + error: unescaped backtick - --> $DIR/unescaped_backticks.rs:316:29 + --> $DIR/unescaped_backticks.rs:318:29 | LL | /// [`rebuild_interest_cache`][rebuild] is called after the value of the max | ^ @@ -264,7 +264,7 @@ LL | /// [`rebuild_interest_cache\`][rebuild] is called after the value of the m | + error: unescaped backtick - --> $DIR/unescaped_backticks.rs:326:5 + --> $DIR/unescaped_backticks.rs:328:5 | LL | / /// The Subscriber` may be accessed by calling [`WeakDispatch::upgrade`], ... | @@ -280,7 +280,7 @@ LL | | /// level changes. to this: `None`. Otherwise, it will return `Some(Dispatch)\`. error: unescaped backtick - --> $DIR/unescaped_backticks.rs:326:5 + --> $DIR/unescaped_backticks.rs:328:5 | LL | / /// The Subscriber` may be accessed by calling [`WeakDispatch::upgrade`], ... | @@ -294,7 +294,7 @@ LL | | /// level changes. to this: or `None\` if it isn't. error: unescaped backtick - --> $DIR/unescaped_backticks.rs:326:5 + --> $DIR/unescaped_backticks.rs:328:5 | LL | / /// The Subscriber` may be accessed by calling [`WeakDispatch::upgrade`], ... | @@ -310,7 +310,7 @@ LL | | /// level changes. to this: `on_event\` should be called. error: unescaped backtick - --> $DIR/unescaped_backticks.rs:326:5 + --> $DIR/unescaped_backticks.rs:328:5 | LL | / /// The Subscriber` may be accessed by calling [`WeakDispatch::upgrade`], ... | @@ -326,7 +326,7 @@ LL | | /// level changes. to this: [`rebuild_interest_cache\`][rebuild] is called after the value of the max error: unescaped backtick - --> $DIR/unescaped_backticks.rs:352:56 + --> $DIR/unescaped_backticks.rs:354:56 | LL | /// instead and use [`CloneCounterObserver::counter`] to increment. | ^ @@ -338,7 +338,7 @@ LL | /// instead and use [`CloneCounterObserver::counter\`] to increment. | + error: unescaped backtick - --> $DIR/unescaped_backticks.rs:15:5 + --> $DIR/unescaped_backticks.rs:17:5 | LL | /// ` | ^ @@ -350,7 +350,7 @@ LL | /// \` | + error: unescaped backtick - --> $DIR/unescaped_backticks.rs:22:7 + --> $DIR/unescaped_backticks.rs:24:7 | LL | /// \` | ^ @@ -365,7 +365,7 @@ LL | /// \\` | + error: unescaped backtick - --> $DIR/unescaped_backticks.rs:29:6 + --> $DIR/unescaped_backticks.rs:31:6 | LL | /// [`link1] | ^ @@ -380,7 +380,7 @@ LL | /// [\`link1] | + error: unescaped backtick - --> $DIR/unescaped_backticks.rs:33:11 + --> $DIR/unescaped_backticks.rs:35:11 | LL | /// [link2`] | ^ @@ -395,7 +395,7 @@ LL | /// [link2\`] | + error: unescaped backtick - --> $DIR/unescaped_backticks.rs:37:6 + --> $DIR/unescaped_backticks.rs:39:6 | LL | /// [`link_long](link_long) | ^ @@ -410,7 +410,7 @@ LL | /// [\`link_long](link_long) | + error: unescaped backtick - --> $DIR/unescaped_backticks.rs:41:6 + --> $DIR/unescaped_backticks.rs:43:6 | LL | /// [`broken-link] | ^ @@ -425,7 +425,7 @@ LL | /// [\`broken-link] | + error: unescaped backtick - --> $DIR/unescaped_backticks.rs:48:8 + --> $DIR/unescaped_backticks.rs:50:8 | LL | /// | ^ @@ -440,7 +440,7 @@ LL | /// | + error: unescaped backtick - --> $DIR/unescaped_backticks.rs:58:6 + --> $DIR/unescaped_backticks.rs:60:6 | LL | /// 🦀`🦀 | ^ @@ -459,7 +459,7 @@ LL | /// 🦀\`🦀 | + error: unescaped backtick - --> $DIR/unescaped_backticks.rs:62:5 + --> $DIR/unescaped_backticks.rs:64:5 | LL | /// `foo( | ^ @@ -474,7 +474,7 @@ LL | /// \`foo( | + error: unescaped backtick - --> $DIR/unescaped_backticks.rs:68:14 + --> $DIR/unescaped_backticks.rs:70:14 | LL | /// `foo `bar` | ^ @@ -489,7 +489,7 @@ LL | /// `foo `bar\` | + error: unescaped backtick - --> $DIR/unescaped_backticks.rs:74:5 + --> $DIR/unescaped_backticks.rs:76:5 | LL | /// `foo( | ^ @@ -504,7 +504,7 @@ LL | /// \`foo( | + error: unescaped backtick - --> $DIR/unescaped_backticks.rs:79:83 + --> $DIR/unescaped_backticks.rs:81:83 | LL | /// Addition is commutative, which means that add(a, b)` is the same as `add(b, a)`. | ^ @@ -519,7 +519,7 @@ LL | /// Addition is commutative, which means that add(a, b)` is the same as `ad | + error: unescaped backtick - --> $DIR/unescaped_backticks.rs:83:51 + --> $DIR/unescaped_backticks.rs:85:51 | LL | /// or even to add a number `n` to 42 (`add(42, b)`)! | ^ @@ -534,7 +534,7 @@ LL | /// or even to add a number `n` to 42 (`add(42, b)\`)! | + error: unescaped backtick - --> $DIR/unescaped_backticks.rs:87:83 + --> $DIR/unescaped_backticks.rs:89:83 | LL | /// Addition is commutative, which means that `add(a, b) is the same as `add(b, a)`. | ^ @@ -549,7 +549,7 @@ LL | /// Addition is commutative, which means that `add(a, b) is the same as `ad | + error: unescaped backtick - --> $DIR/unescaped_backticks.rs:91:51 + --> $DIR/unescaped_backticks.rs:93:51 | LL | /// or even to add a number `n` to 42 (`add(42, n)`)! | ^ @@ -564,7 +564,7 @@ LL | /// or even to add a number `n` to 42 (`add(42, n)\`)! | + error: unescaped backtick - --> $DIR/unescaped_backticks.rs:95:83 + --> $DIR/unescaped_backticks.rs:97:83 | LL | /// Addition is commutative, which means that `add(a, b)` is the same as add(b, a)`. | ^ @@ -579,7 +579,7 @@ LL | /// Addition is commutative, which means that `add(a, b)` is the same as ad | + error: unescaped backtick - --> $DIR/unescaped_backticks.rs:99:50 + --> $DIR/unescaped_backticks.rs:101:50 | LL | /// or even to add a number `n` to 42 (add(42, n)`)! | ^ @@ -594,7 +594,7 @@ LL | /// or even to add a number `n` to 42 (add(42, n)\`)! | + error: unescaped backtick - --> $DIR/unescaped_backticks.rs:103:74 + --> $DIR/unescaped_backticks.rs:105:74 | LL | /// Addition is commutative, which means that `add(a, b)` is the same as `add(b, a). | ^ @@ -609,7 +609,7 @@ LL | /// Addition is commutative, which means that `add(a, b)` is the same as \` | + error: unescaped backtick - --> $DIR/unescaped_backticks.rs:107:51 + --> $DIR/unescaped_backticks.rs:109:51 | LL | /// or even to add a number `n` to 42 (`add(42, n)`)! | ^ @@ -624,7 +624,7 @@ LL | /// or even to add a number `n` to 42 (`add(42, n)\`)! | + error: unescaped backtick - --> $DIR/unescaped_backticks.rs:111:10 + --> $DIR/unescaped_backticks.rs:113:10 | LL | #[doc = "`"] | ^ @@ -635,7 +635,7 @@ LL | #[doc = "`"] to this: \` error: unescaped backtick - --> $DIR/unescaped_backticks.rs:118:26 + --> $DIR/unescaped_backticks.rs:120:26 | LL | #[doc = concat!("\\", "`")] | ^ @@ -648,7 +648,7 @@ LL | #[doc = concat!("\\", "`")] to this: \\` error: unescaped backtick - --> $DIR/unescaped_backticks.rs:122:9 + --> $DIR/unescaped_backticks.rs:124:9 | LL | #[doc = "Addition is commutative, which means that add(a, b)` is the same as `add(b, a)`."] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -661,7 +661,7 @@ LL | #[doc = "Addition is commutative, which means that add(a, b)` is the same a to this: Addition is commutative, which means that add(a, b)` is the same as `add(b, a)\`. error: unescaped backtick - --> $DIR/unescaped_backticks.rs:126:9 + --> $DIR/unescaped_backticks.rs:128:9 | LL | #[doc = "Addition is commutative, which means that `add(a, b) is the same as `add(b, a)`."] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -674,7 +674,7 @@ LL | #[doc = "Addition is commutative, which means that `add(a, b) is the same a to this: Addition is commutative, which means that `add(a, b) is the same as `add(b, a)\`. error: unescaped backtick - --> $DIR/unescaped_backticks.rs:130:9 + --> $DIR/unescaped_backticks.rs:132:9 | LL | #[doc = "Addition is commutative, which means that `add(a, b)` is the same as add(b, a)`."] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -687,7 +687,7 @@ LL | #[doc = "Addition is commutative, which means that `add(a, b)` is the same to this: Addition is commutative, which means that `add(a, b)` is the same as add(b, a)\`. error: unescaped backtick - --> $DIR/unescaped_backticks.rs:134:9 + --> $DIR/unescaped_backticks.rs:136:9 | LL | #[doc = "Addition is commutative, which means that `add(a, b)` is the same as `add(b, a)."] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -700,7 +700,7 @@ LL | #[doc = "Addition is commutative, which means that `add(a, b)` is the same to this: Addition is commutative, which means that `add(a, b)` is the same as \`add(b, a). error: unescaped backtick - --> $DIR/unescaped_backticks.rs:139:5 + --> $DIR/unescaped_backticks.rs:141:5 | LL | /// `foo | ^ @@ -715,7 +715,7 @@ LL | /// \`foo | + error: unescaped backtick - --> $DIR/unescaped_backticks.rs:143:7 + --> $DIR/unescaped_backticks.rs:145:7 | LL | /// # `(heading | ^ @@ -730,7 +730,7 @@ LL | /// # \`(heading | + error: unescaped backtick - --> $DIR/unescaped_backticks.rs:145:17 + --> $DIR/unescaped_backticks.rs:147:17 | LL | /// ## heading2)` | ^ @@ -745,7 +745,7 @@ LL | /// ## heading2)\` | + error: unescaped backtick - --> $DIR/unescaped_backticks.rs:148:11 + --> $DIR/unescaped_backticks.rs:150:11 | LL | /// multi `( | ^ @@ -760,7 +760,7 @@ LL | /// multi \`( | + error: unescaped backtick - --> $DIR/unescaped_backticks.rs:154:10 + --> $DIR/unescaped_backticks.rs:156:10 | LL | /// para)`(graph | ^ @@ -779,7 +779,7 @@ LL | /// para)\`(graph | + error: unescaped backtick - --> $DIR/unescaped_backticks.rs:157:10 + --> $DIR/unescaped_backticks.rs:159:10 | LL | /// para)`(graph2 | ^ @@ -798,7 +798,7 @@ LL | /// para)\`(graph2 | + error: unescaped backtick - --> $DIR/unescaped_backticks.rs:160:12 + --> $DIR/unescaped_backticks.rs:162:12 | LL | /// 1. foo)` | ^ @@ -813,7 +813,7 @@ LL | /// 1. foo)\` | + error: unescaped backtick - --> $DIR/unescaped_backticks.rs:162:8 + --> $DIR/unescaped_backticks.rs:164:8 | LL | /// 2. `(bar | ^ @@ -828,7 +828,7 @@ LL | /// 2. \`(bar | + error: unescaped backtick - --> $DIR/unescaped_backticks.rs:164:11 + --> $DIR/unescaped_backticks.rs:166:11 | LL | /// * baz)` | ^ @@ -843,7 +843,7 @@ LL | /// * baz)\` | + error: unescaped backtick - --> $DIR/unescaped_backticks.rs:166:7 + --> $DIR/unescaped_backticks.rs:168:7 | LL | /// * `(quux | ^ @@ -858,7 +858,7 @@ LL | /// * \`(quux | + error: unescaped backtick - --> $DIR/unescaped_backticks.rs:169:5 + --> $DIR/unescaped_backticks.rs:171:5 | LL | /// `#![this_is_actually_an_image(and(not), an = "attribute")] | ^ @@ -873,7 +873,7 @@ LL | /// \`#![this_is_actually_an_image(and(not), an = "attribute")] | + error: unescaped backtick - --> $DIR/unescaped_backticks.rs:172:62 + --> $DIR/unescaped_backticks.rs:174:62 | LL | /// #![this_is_actually_an_image(and(not), an = "attribute")]` | ^ @@ -888,7 +888,7 @@ LL | /// #![this_is_actually_an_image(and(not), an = "attribute")]\` | + error: unescaped backtick - --> $DIR/unescaped_backticks.rs:177:7 + --> $DIR/unescaped_backticks.rs:179:7 | LL | /// | `table( | )head` | | ^ @@ -903,7 +903,7 @@ LL | /// | \`table( | )head` | | + error: unescaped backtick - --> $DIR/unescaped_backticks.rs:177:22 + --> $DIR/unescaped_backticks.rs:179:22 | LL | /// | `table( | )head` | | ^ @@ -918,7 +918,7 @@ LL | /// | `table( | )head\` | | + error: unescaped backtick - --> $DIR/unescaped_backticks.rs:181:12 + --> $DIR/unescaped_backticks.rs:183:12 | LL | /// | table`( | )`body | | ^ @@ -933,7 +933,7 @@ LL | /// | table\`( | )`body | | + error: unescaped backtick - --> $DIR/unescaped_backticks.rs:181:18 + --> $DIR/unescaped_backticks.rs:183:18 | LL | /// | table`( | )`body | | ^ diff --git a/tests/rustdoc-ui/lints/unescaped_backticks.rs b/tests/rustdoc-ui/lints/unescaped_backticks.rs index a0c25ca2eaf03..55ea1ac699d00 100644 --- a/tests/rustdoc-ui/lints/unescaped_backticks.rs +++ b/tests/rustdoc-ui/lints/unescaped_backticks.rs @@ -1,4 +1,6 @@ -//@revisions: deny_cli allow_cli +//@revisions: deny_cli allow_cli capped +//@[capped] compile-flags: --cap-lints=allow +//@[capped] check-pass //@[deny_cli] compile-flags: -Drustdoc::unescaped_backticks //@[allow_cli] compile-flags: -Arustdoc::unescaped_backticks //@[allow_cli] check-pass From 124126e0839b6a2aaa94cc7df1ca520122c66ddd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9C=9D=E5=80=89=E6=B0=B4=E5=B8=8C?= Date: Fri, 15 May 2026 00:06:14 +0800 Subject: [PATCH 17/29] Test EII UI tests with prefer-dynamic --- tests/ui/eii/default/auxiliary/decl_with_default.rs | 1 - tests/ui/eii/default/auxiliary/decl_with_default_panics.rs | 1 - tests/ui/eii/default/auxiliary/impl1.rs | 1 - tests/ui/eii/default/call_default.rs | 1 - tests/ui/eii/default/call_default_panics.rs | 1 - tests/ui/eii/default/call_impl.rs | 1 - tests/ui/eii/duplicate/auxiliary/impl1.rs | 1 - tests/ui/eii/duplicate/auxiliary/impl2.rs | 1 - tests/ui/eii/duplicate/auxiliary/impl3.rs | 1 - tests/ui/eii/duplicate/auxiliary/impl4.rs | 1 - tests/ui/eii/duplicate/duplicate1.rs | 1 - tests/ui/eii/duplicate/duplicate1.stderr | 4 ++-- tests/ui/eii/duplicate/duplicate2.rs | 1 - tests/ui/eii/duplicate/duplicate2.stderr | 4 ++-- tests/ui/eii/duplicate/duplicate3.rs | 1 - tests/ui/eii/duplicate/duplicate3.stderr | 4 ++-- tests/ui/eii/static/auxiliary/cross_crate_def.rs | 1 - 17 files changed, 6 insertions(+), 20 deletions(-) diff --git a/tests/ui/eii/default/auxiliary/decl_with_default.rs b/tests/ui/eii/default/auxiliary/decl_with_default.rs index 8d962c19c94d9..ba855cb854afd 100644 --- a/tests/ui/eii/default/auxiliary/decl_with_default.rs +++ b/tests/ui/eii/default/auxiliary/decl_with_default.rs @@ -1,4 +1,3 @@ -//@ no-prefer-dynamic #![crate_type = "rlib"] #![feature(extern_item_impls)] diff --git a/tests/ui/eii/default/auxiliary/decl_with_default_panics.rs b/tests/ui/eii/default/auxiliary/decl_with_default_panics.rs index 14778a40cde4a..3867bfb85c9fe 100644 --- a/tests/ui/eii/default/auxiliary/decl_with_default_panics.rs +++ b/tests/ui/eii/default/auxiliary/decl_with_default_panics.rs @@ -1,4 +1,3 @@ -//@ no-prefer-dynamic //@ needs-unwind //@ exec-env:RUST_BACKTRACE=1 #![crate_type = "rlib"] diff --git a/tests/ui/eii/default/auxiliary/impl1.rs b/tests/ui/eii/default/auxiliary/impl1.rs index 3510ea1eb3f27..84edf24e12816 100644 --- a/tests/ui/eii/default/auxiliary/impl1.rs +++ b/tests/ui/eii/default/auxiliary/impl1.rs @@ -1,4 +1,3 @@ -//@ no-prefer-dynamic //@ aux-build: decl_with_default.rs #![crate_type = "rlib"] #![feature(extern_item_impls)] diff --git a/tests/ui/eii/default/call_default.rs b/tests/ui/eii/default/call_default.rs index 8806c7fa7d8ce..07b2a650d3c42 100644 --- a/tests/ui/eii/default/call_default.rs +++ b/tests/ui/eii/default/call_default.rs @@ -1,4 +1,3 @@ -//@ no-prefer-dynamic //@ aux-build: decl_with_default.rs //@ run-pass //@ check-run-results diff --git a/tests/ui/eii/default/call_default_panics.rs b/tests/ui/eii/default/call_default_panics.rs index db664e0cbcb0d..379ba8ea070b6 100644 --- a/tests/ui/eii/default/call_default_panics.rs +++ b/tests/ui/eii/default/call_default_panics.rs @@ -1,4 +1,3 @@ -//@ no-prefer-dynamic //@ aux-build: decl_with_default_panics.rs //@ edition: 2021 //@ run-pass diff --git a/tests/ui/eii/default/call_impl.rs b/tests/ui/eii/default/call_impl.rs index 1a972774beaeb..4553427b8c799 100644 --- a/tests/ui/eii/default/call_impl.rs +++ b/tests/ui/eii/default/call_impl.rs @@ -1,4 +1,3 @@ -//@ no-prefer-dynamic //@ aux-build: decl_with_default.rs //@ aux-build: impl1.rs //@ run-pass diff --git a/tests/ui/eii/duplicate/auxiliary/impl1.rs b/tests/ui/eii/duplicate/auxiliary/impl1.rs index e99932c69b90b..ffa2cd79818cc 100644 --- a/tests/ui/eii/duplicate/auxiliary/impl1.rs +++ b/tests/ui/eii/duplicate/auxiliary/impl1.rs @@ -1,4 +1,3 @@ -//@ no-prefer-dynamic //@ aux-build: decl.rs #![crate_type = "rlib"] #![feature(extern_item_impls)] diff --git a/tests/ui/eii/duplicate/auxiliary/impl2.rs b/tests/ui/eii/duplicate/auxiliary/impl2.rs index 3a09c824b8292..592234f53fd40 100644 --- a/tests/ui/eii/duplicate/auxiliary/impl2.rs +++ b/tests/ui/eii/duplicate/auxiliary/impl2.rs @@ -1,4 +1,3 @@ -//@ no-prefer-dynamic //@ aux-build: decl.rs #![crate_type = "rlib"] #![feature(extern_item_impls)] diff --git a/tests/ui/eii/duplicate/auxiliary/impl3.rs b/tests/ui/eii/duplicate/auxiliary/impl3.rs index 09bdd8509da29..5e9fdaba0bb6b 100644 --- a/tests/ui/eii/duplicate/auxiliary/impl3.rs +++ b/tests/ui/eii/duplicate/auxiliary/impl3.rs @@ -1,4 +1,3 @@ -//@ no-prefer-dynamic //@ aux-build: decl.rs #![crate_type = "rlib"] #![feature(extern_item_impls)] diff --git a/tests/ui/eii/duplicate/auxiliary/impl4.rs b/tests/ui/eii/duplicate/auxiliary/impl4.rs index fd68a83de1252..068cc18d78e6a 100644 --- a/tests/ui/eii/duplicate/auxiliary/impl4.rs +++ b/tests/ui/eii/duplicate/auxiliary/impl4.rs @@ -1,4 +1,3 @@ -//@ no-prefer-dynamic //@ aux-build: decl.rs #![crate_type = "rlib"] #![feature(extern_item_impls)] diff --git a/tests/ui/eii/duplicate/duplicate1.rs b/tests/ui/eii/duplicate/duplicate1.rs index 2128cac70eb30..3d770232af50f 100644 --- a/tests/ui/eii/duplicate/duplicate1.rs +++ b/tests/ui/eii/duplicate/duplicate1.rs @@ -1,4 +1,3 @@ -//@ no-prefer-dynamic //@ aux-build: impl1.rs //@ aux-build: impl2.rs //@ ignore-backends: gcc diff --git a/tests/ui/eii/duplicate/duplicate1.stderr b/tests/ui/eii/duplicate/duplicate1.stderr index 54cc141f88694..f691043e6a597 100644 --- a/tests/ui/eii/duplicate/duplicate1.stderr +++ b/tests/ui/eii/duplicate/duplicate1.stderr @@ -1,10 +1,10 @@ error: multiple implementations of `#[eii1]` - --> $DIR/auxiliary/impl1.rs:10:1 + --> $DIR/auxiliary/impl1.rs:9:1 | LL | fn other(x: u64) { | ^^^^^^^^^^^^^^^^ first implemented here in crate `impl1` | - ::: $DIR/auxiliary/impl2.rs:10:1 + ::: $DIR/auxiliary/impl2.rs:9:1 | LL | fn other(x: u64) { | ---------------- also implemented here in crate `impl2` diff --git a/tests/ui/eii/duplicate/duplicate2.rs b/tests/ui/eii/duplicate/duplicate2.rs index b0f1b1266e4ca..4311969ed8894 100644 --- a/tests/ui/eii/duplicate/duplicate2.rs +++ b/tests/ui/eii/duplicate/duplicate2.rs @@ -1,4 +1,3 @@ -//@ no-prefer-dynamic //@ aux-build: impl1.rs //@ aux-build: impl2.rs //@ aux-build: impl3.rs diff --git a/tests/ui/eii/duplicate/duplicate2.stderr b/tests/ui/eii/duplicate/duplicate2.stderr index 033e43c8b2fbd..492d2b3e6004b 100644 --- a/tests/ui/eii/duplicate/duplicate2.stderr +++ b/tests/ui/eii/duplicate/duplicate2.stderr @@ -1,10 +1,10 @@ error: multiple implementations of `#[eii1]` - --> $DIR/auxiliary/impl1.rs:10:1 + --> $DIR/auxiliary/impl1.rs:9:1 | LL | fn other(x: u64) { | ^^^^^^^^^^^^^^^^ first implemented here in crate `impl1` | - ::: $DIR/auxiliary/impl2.rs:10:1 + ::: $DIR/auxiliary/impl2.rs:9:1 | LL | fn other(x: u64) { | ---------------- also implemented here in crate `impl2` diff --git a/tests/ui/eii/duplicate/duplicate3.rs b/tests/ui/eii/duplicate/duplicate3.rs index 4b2b0fc111b58..4504ba30c246e 100644 --- a/tests/ui/eii/duplicate/duplicate3.rs +++ b/tests/ui/eii/duplicate/duplicate3.rs @@ -1,4 +1,3 @@ -//@ no-prefer-dynamic //@ aux-build: impl1.rs //@ aux-build: impl2.rs //@ aux-build: impl3.rs diff --git a/tests/ui/eii/duplicate/duplicate3.stderr b/tests/ui/eii/duplicate/duplicate3.stderr index 801d40e69c552..f3ca087a27325 100644 --- a/tests/ui/eii/duplicate/duplicate3.stderr +++ b/tests/ui/eii/duplicate/duplicate3.stderr @@ -1,10 +1,10 @@ error: multiple implementations of `#[eii1]` - --> $DIR/auxiliary/impl1.rs:10:1 + --> $DIR/auxiliary/impl1.rs:9:1 | LL | fn other(x: u64) { | ^^^^^^^^^^^^^^^^ first implemented here in crate `impl1` | - ::: $DIR/auxiliary/impl2.rs:10:1 + ::: $DIR/auxiliary/impl2.rs:9:1 | LL | fn other(x: u64) { | ---------------- also implemented here in crate `impl2` diff --git a/tests/ui/eii/static/auxiliary/cross_crate_def.rs b/tests/ui/eii/static/auxiliary/cross_crate_def.rs index 70933440a62be..56d3f6fcdc557 100644 --- a/tests/ui/eii/static/auxiliary/cross_crate_def.rs +++ b/tests/ui/eii/static/auxiliary/cross_crate_def.rs @@ -1,4 +1,3 @@ -//@ no-prefer-dynamic #![crate_type = "rlib"] #![feature(extern_item_impls)] From 87821d9f784fe4f3a408919c21c7b1aaa3a50255 Mon Sep 17 00:00:00 2001 From: Eval Exec Date: Sat, 16 May 2026 03:14:52 -0400 Subject: [PATCH 18/29] Add regression test for issue 41261 --- .../ambiguous-cast-suggestion-issue-41261.rs | 19 +++++++++++++++++++ ...biguous-cast-suggestion-issue-41261.stderr | 17 +++++++++++++++++ 2 files changed, 36 insertions(+) create mode 100644 tests/ui/inference/ambiguous-cast-suggestion-issue-41261.rs create mode 100644 tests/ui/inference/ambiguous-cast-suggestion-issue-41261.stderr diff --git a/tests/ui/inference/ambiguous-cast-suggestion-issue-41261.rs b/tests/ui/inference/ambiguous-cast-suggestion-issue-41261.rs new file mode 100644 index 0000000000000..b1c4dfb9f1003 --- /dev/null +++ b/tests/ui/inference/ambiguous-cast-suggestion-issue-41261.rs @@ -0,0 +1,19 @@ +//@ edition: 2021 + +// Regression test for issue #41261. +// The diagnostic should point at the ambiguous cast, not at the later method call. + +struct S { + v: Vec<(u32, Vec)>, +} + +impl S { + pub fn remove(&mut self, i: u32) -> Option> { + self.v.get_mut(i as _).map(|&mut (_, ref mut v2)| { + //~^ ERROR type annotations needed + v2.drain(..) + }) + } +} + +fn main() {} diff --git a/tests/ui/inference/ambiguous-cast-suggestion-issue-41261.stderr b/tests/ui/inference/ambiguous-cast-suggestion-issue-41261.stderr new file mode 100644 index 0000000000000..da66f6237203e --- /dev/null +++ b/tests/ui/inference/ambiguous-cast-suggestion-issue-41261.stderr @@ -0,0 +1,17 @@ +error[E0282]: type annotations needed for `&mut (_, _)` + --> $DIR/ambiguous-cast-suggestion-issue-41261.rs:12:37 + | +LL | self.v.get_mut(i as _).map(|&mut (_, ref mut v2)| { + | ^^^^^^^^^^^^^^^^^^^^ +LL | +LL | v2.drain(..) + | -- type must be known at this point + | +help: consider giving this closure parameter an explicit type, where the placeholders `_` are specified + | +LL | self.v.get_mut(i as _).map(|&mut (_, ref mut v2): &mut (_, _)| { + | +++++++++++++ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0282`. From 6d91f14af9538e9d776595df8570f1e28b7c6443 Mon Sep 17 00:00:00 2001 From: b1yd <2156864690@qq.com> Date: Sat, 16 May 2026 16:03:00 +0800 Subject: [PATCH 19/29] fix --- compiler/rustc_parse/src/parser/diagnostics.rs | 7 +++---- compiler/rustc_parse/src/parser/mod.rs | 2 +- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/compiler/rustc_parse/src/parser/diagnostics.rs b/compiler/rustc_parse/src/parser/diagnostics.rs index 47ac91feefd4b..4ef2788c5baf5 100644 --- a/compiler/rustc_parse/src/parser/diagnostics.rs +++ b/compiler/rustc_parse/src/parser/diagnostics.rs @@ -1889,9 +1889,8 @@ impl<'a> Parser<'a> { true } - /// Creates a `Diag` for an unexpected token `t` and tries to recover if it is a - /// closing delimiter. - pub(super) fn unexpected_try_recover(&mut self, t: &TokenKind) -> PResult<'a, Recovered> { + /// Creates a `Diag` for an unexpected token `t` + pub(super) fn unexpected_err(&mut self, t: &TokenKind) -> Diag<'a> { let token_str = pprust::token_kind_to_string(t); let this_token_str = super::token_descr(&self.token); let (prev_sp, sp) = match (&self.token.kind, self.subparser_name) { @@ -1926,7 +1925,7 @@ impl<'a> Parser<'a> { err.span_label(prev_sp, label_exp); err.span_label(sp, "unexpected token"); } - Err(err) + err } pub(super) fn expect_semi(&mut self) -> PResult<'a, ()> { diff --git a/compiler/rustc_parse/src/parser/mod.rs b/compiler/rustc_parse/src/parser/mod.rs index 9303be8ff0ccd..850d64c8ecf44 100644 --- a/compiler/rustc_parse/src/parser/mod.rs +++ b/compiler/rustc_parse/src/parser/mod.rs @@ -409,7 +409,7 @@ impl<'a> Parser<'a> { self.bump(); Ok(Recovered::No) } else { - self.unexpected_try_recover(&exp.tok) + Err(self.unexpected_err(&exp.tok)) } } else { self.expect_one_of(slice::from_ref(&exp), &[]) From 053761df0a0e72f6846dd1a2ac8975c12207ad0a Mon Sep 17 00:00:00 2001 From: human9000 Date: Mon, 11 May 2026 19:11:49 +0500 Subject: [PATCH 20/29] minor `rustc_mir_transform` cleanup --- compiler/rustc_mir_transform/src/inline.rs | 3 +-- compiler/rustc_mir_transform/src/pass_manager.rs | 9 ++++----- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/compiler/rustc_mir_transform/src/inline.rs b/compiler/rustc_mir_transform/src/inline.rs index fbe3a827d6394..31871c62fa7a2 100644 --- a/compiler/rustc_mir_transform/src/inline.rs +++ b/compiler/rustc_mir_transform/src/inline.rs @@ -1072,8 +1072,7 @@ fn make_call_args<'tcx, I: Inliner<'tcx>>( // // and the vector is `[closure_ref, tmp0, tmp1, tmp2]`. if callsite.fn_sig.abi() == ExternAbi::RustCall && callee_body.spread_arg.is_none() { - // FIXME(edition_2024): switch back to a normal method call. - let mut args = <_>::into_iter(args); + let mut args = args.into_iter(); let self_ = create_temp_if_necessary( inliner, args.next().unwrap().node, diff --git a/compiler/rustc_mir_transform/src/pass_manager.rs b/compiler/rustc_mir_transform/src/pass_manager.rs index ef4cf82cf1b5d..fbf16f91610c5 100644 --- a/compiler/rustc_mir_transform/src/pass_manager.rs +++ b/compiler/rustc_mir_transform/src/pass_manager.rs @@ -296,15 +296,14 @@ fn run_passes_inner<'tcx>( if is_optimization_stage(body, phase_change, optimizations) && let Some(limit) = &tcx.sess.opts.unstable_opts.mir_opt_bisect_limit - { - if limited_by_opt_bisect( + && limited_by_opt_bisect( tcx, tcx.def_path_debug_str(body.source.def_id()), *limit, *pass, - ) { - continue; - } + ) + { + continue; } let dumper = if pass.is_mir_dump_enabled() From 22cf1fb6fe6b97ebc190824375a2c9701abb850a Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Fri, 15 May 2026 17:58:21 +1000 Subject: [PATCH 21/29] Split `LintExpectationId` `LintExpectationId` has two variants, `Unstable` and `Stable`. There are some places where both variants are possible, but there are also places where only one of `Unstable` or `Stable` is possible. This commit encodes this into the type system by introducing new types `UnstableLintExpectationId` and `StableLintExpectationId`. The variants of `LintExpectationId` now enclose these. This makes it clearer what values are possible where. Other things of note: - `LintLevelsProvider` gets an associated type and some method changes. - `LintContext` gets an associated type. - `LevelSpec` is made generic. `UnstableLevelSpec` and `StableLevelSpec` typedefs are added. - The unstable types are now guaranteed by the type system to never be stably hashed. Previously this was a runtime check. --- compiler/rustc_codegen_ssa/src/lib.rs | 6 +- compiler/rustc_lint/src/context.rs | 23 ++- compiler/rustc_lint/src/expect.rs | 30 ++-- compiler/rustc_lint/src/levels.rs | 162 ++++++++++-------- compiler/rustc_lint_defs/src/lib.rs | 69 ++++---- compiler/rustc_middle/src/lint.rs | 61 ++++--- compiler/rustc_middle/src/queries.rs | 4 +- compiler/rustc_passes/src/dead.rs | 11 +- .../clippy/clippy_lints/src/duplicate_mod.rs | 6 +- 9 files changed, 211 insertions(+), 161 deletions(-) diff --git a/compiler/rustc_codegen_ssa/src/lib.rs b/compiler/rustc_codegen_ssa/src/lib.rs index ec1eb7eeb6fc0..fc57310804873 100644 --- a/compiler/rustc_codegen_ssa/src/lib.rs +++ b/compiler/rustc_codegen_ssa/src/lib.rs @@ -26,7 +26,7 @@ use rustc_lint_defs::builtin::LINKER_INFO; use rustc_macros::{Decodable, Encodable}; use rustc_metadata::EncodedMetadata; use rustc_middle::dep_graph::WorkProduct; -use rustc_middle::lint::LevelSpec; +use rustc_middle::lint::StableLevelSpec; use rustc_middle::middle::debugger_visualizer::DebuggerVisualizerFile; use rustc_middle::middle::dependency_format::Dependencies; use rustc_middle::middle::exported_symbols::SymbolExportKind; @@ -342,8 +342,8 @@ impl CompiledModules { /// Instead, encode exactly the information we need. #[derive(Copy, Clone, Debug, Encodable, Decodable)] pub struct CodegenLintLevelSpecs { - linker_messages: LevelSpec, - linker_info: LevelSpec, + linker_messages: StableLevelSpec, + linker_info: StableLevelSpec, } impl CodegenLintLevelSpecs { diff --git a/compiler/rustc_lint/src/context.rs b/compiler/rustc_lint/src/context.rs index 4825b61bc6e41..3cbd02e2ed8d9 100644 --- a/compiler/rustc_lint/src/context.rs +++ b/compiler/rustc_lint/src/context.rs @@ -20,14 +20,17 @@ use rustc_hir::def_id::{CrateNum, DefId}; use rustc_hir::definitions::{DefPathData, DisambiguatedDefPathData}; use rustc_hir::{Pat, PatKind}; use rustc_middle::bug; -use rustc_middle::lint::LevelSpec; +use rustc_middle::lint::{LevelSpec, StableLevelSpec, UnstableLevelSpec}; use rustc_middle::middle::privacy::EffectiveVisibilities; use rustc_middle::ty::layout::{LayoutError, LayoutOfHelpers, TyAndLayout}; use rustc_middle::ty::print::{PrintError, PrintTraitRefExt as _, Printer, with_no_trimmed_paths}; use rustc_middle::ty::{ self, GenericArg, RegisteredTools, Ty, TyCtxt, TypingEnv, TypingMode, Unnormalized, }; -use rustc_session::lint::{FutureIncompatibleInfo, Lint, LintExpectationId, LintId}; +use rustc_session::lint::{ + FutureIncompatibleInfo, Lint, LintExpectationId, LintId, StableLintExpectationId, + UnstableLintExpectationId, +}; use rustc_session::{DynLintStore, Session}; use rustc_span::edit_distance::find_best_match_for_names; use rustc_span::{Ident, Span, Symbol, sym}; @@ -510,6 +513,8 @@ pub struct EarlyContext<'a> { } pub trait LintContext { + type LintExpectationId: Copy + Into; + fn sess(&self) -> &Session; // FIXME: These methods should not take an Into -- instead, callers should need to @@ -538,7 +543,7 @@ pub trait LintContext { } /// This returns the lint level spec for the given lint at the current location. - fn get_lint_level_spec(&self, lint: &'static Lint) -> LevelSpec; + fn get_lint_level_spec(&self, lint: &'static Lint) -> LevelSpec; /// This function can be used to manually fulfill an expectation. This can /// be used for lints which contain several spans, and should be suppressed, @@ -547,7 +552,7 @@ pub trait LintContext { /// Note that this function should only be called for [`LintExpectationId`]s /// retrieved from the current lint pass. Buffered or manually created ids can /// cause ICEs. - fn fulfill_expectation(&self, expectation: LintExpectationId) { + fn fulfill_expectation(&self, expectation: Self::LintExpectationId) { // We need to make sure that submitted expectation ids are correctly fulfilled suppressed // and stored between compilation sessions. To not manually do these steps, we simply create // a dummy diagnostic and emit it as usual, which will be suppressed and stored like a @@ -556,7 +561,7 @@ pub trait LintContext { .dcx() .struct_expect( "this is a dummy diagnostic, to submit and store an expectation", - expectation, + expectation.into(), ) .emit(); } @@ -585,6 +590,8 @@ impl<'a> EarlyContext<'a> { } impl<'tcx> LintContext for LateContext<'tcx> { + type LintExpectationId = StableLintExpectationId; + /// Gets the overall compiler `Session` object. fn sess(&self) -> &Session { self.tcx.sess @@ -604,12 +611,14 @@ impl<'tcx> LintContext for LateContext<'tcx> { } } - fn get_lint_level_spec(&self, lint: &'static Lint) -> LevelSpec { + fn get_lint_level_spec(&self, lint: &'static Lint) -> StableLevelSpec { self.tcx.lint_level_spec_at_node(lint, self.last_node_with_lint_attrs) } } impl LintContext for EarlyContext<'_> { + type LintExpectationId = UnstableLintExpectationId; + /// Gets the overall compiler `Session` object. fn sess(&self) -> &Session { self.builder.sess() @@ -624,7 +633,7 @@ impl LintContext for EarlyContext<'_> { self.builder.opt_span_lint(lint, span.map(|s| s.into()), decorator) } - fn get_lint_level_spec(&self, lint: &'static Lint) -> LevelSpec { + fn get_lint_level_spec(&self, lint: &'static Lint) -> UnstableLevelSpec { self.builder.lint_level_spec(lint) } } diff --git a/compiler/rustc_lint/src/expect.rs b/compiler/rustc_lint/src/expect.rs index 481e116d06e01..5364a4141805b 100644 --- a/compiler/rustc_lint/src/expect.rs +++ b/compiler/rustc_lint/src/expect.rs @@ -2,8 +2,8 @@ use rustc_data_structures::fx::FxHashSet; use rustc_middle::lint::LintExpectation; use rustc_middle::query::Providers; use rustc_middle::ty::TyCtxt; -use rustc_session::lint::LintExpectationId; use rustc_session::lint::builtin::UNFULFILLED_LINT_EXPECTATIONS; +use rustc_session::lint::{LintExpectationId, StableLintExpectationId}; use rustc_span::Symbol; use crate::lints::{Expectation, ExpectationNote}; @@ -12,7 +12,7 @@ pub(crate) fn provide(providers: &mut Providers) { *providers = Providers { lint_expectations, check_expectations, ..*providers }; } -fn lint_expectations(tcx: TyCtxt<'_>, (): ()) -> Vec<(LintExpectationId, LintExpectation)> { +fn lint_expectations(tcx: TyCtxt<'_>, (): ()) -> Vec<(StableLintExpectationId, LintExpectation)> { let krate = tcx.hir_crate_items(()); let mut expectations = Vec::new(); @@ -31,30 +31,22 @@ fn check_expectations(tcx: TyCtxt<'_>, tool_filter: Option) { // Turn a `LintExpectationId` into a `(AttrId, lint_index)` pair. let canonicalize_id = |expect_id: &LintExpectationId| { - match *expect_id { - LintExpectationId::Unstable { attr_id, lint_index: Some(lint_index) } => { - (attr_id, lint_index) - } - LintExpectationId::Stable { hir_id, attr_index, lint_index: Some(lint_index) } => { + let (attr_id, lint_index) = match *expect_id { + LintExpectationId::Unstable(id) => (id.attr_id, id.lint_index), + LintExpectationId::Stable(id) => { // We are an `eval_always` query, so looking at the attribute's `AttrId` is ok. - let attr_id = tcx.hir_attrs(hir_id)[attr_index as usize].id(); - - (attr_id, lint_index) + (tcx.hir_attrs(id.hir_id)[id.attr_index as usize].id(), id.lint_index) } - _ => panic!("fulfilled expectations must have a lint index"), - } + }; + (attr_id, lint_index.expect("fulfilled expectations must have a lint index")) }; let fulfilled_expectations: FxHashSet<_> = fulfilled_expectations.iter().map(canonicalize_id).collect(); for (expect_id, expectation) in lint_expectations { - // This check will always be true, since `lint_expectations` only holds stable ids - let LintExpectationId::Stable { hir_id, .. } = expect_id else { - unreachable!("at this stage all `LintExpectationId`s are stable"); - }; - - let expect_id = canonicalize_id(expect_id); + let hir_id = expect_id.hir_id; + let expect_id = canonicalize_id(&LintExpectationId::Stable(*expect_id)); if !fulfilled_expectations.contains(&expect_id) && tool_filter.is_none_or(|filter| expectation.lint_tool == Some(filter)) @@ -63,7 +55,7 @@ fn check_expectations(tcx: TyCtxt<'_>, tool_filter: Option) { let note = expectation.is_unfulfilled_lint_expectations; tcx.emit_node_span_lint( UNFULFILLED_LINT_EXPECTATIONS, - *hir_id, + hir_id, expectation.emission_span, Expectation { rationale, note }, ); diff --git a/compiler/rustc_lint/src/levels.rs b/compiler/rustc_lint/src/levels.rs index 25cc788b63bfa..3ac1d0e08af73 100644 --- a/compiler/rustc_lint/src/levels.rs +++ b/compiler/rustc_lint/src/levels.rs @@ -1,3 +1,5 @@ +use std::fmt::Debug; + use rustc_ast as ast; use rustc_ast::attr::AttributeExt; use rustc_ast_pretty::pprust; @@ -11,8 +13,8 @@ use rustc_hir::intravisit::{self, Visitor}; use rustc_index::IndexVec; use rustc_middle::hir::nested_filter; use rustc_middle::lint::{ - LevelSpec, LintExpectation, LintLevelSource, ShallowLintLevelMap, emit_lint_base, - reveal_actual_level_spec, + LevelSpec, LintExpectation, LintLevelSource, ShallowLintLevelMap, StableLevelSpec, + UnstableLevelSpec, emit_lint_base, reveal_actual_level_spec, }; use rustc_middle::query::Providers; use rustc_middle::ty::{RegisteredTools, TyCtxt}; @@ -21,8 +23,10 @@ use rustc_session::lint::builtin::{ self, FORBIDDEN_LINT_GROUPS, RENAMED_AND_REMOVED_LINTS, SINGLE_USE_LIFETIMES, UNFULFILLED_LINT_EXPECTATIONS, UNKNOWN_LINTS, UNUSED_ATTRIBUTES, }; -use rustc_session::lint::{Level, Lint, LintExpectationId, LintId}; -use rustc_span::{DUMMY_SP, Span, Symbol, sym}; +use rustc_session::lint::{ + Level, Lint, LintExpectationId, LintId, StableLintExpectationId, UnstableLintExpectationId, +}; +use rustc_span::{AttrId, DUMMY_SP, Span, Symbol, sym}; use tracing::{debug, instrument}; use crate::builtin::MISSING_DOCS; @@ -64,9 +68,7 @@ rustc_index::newtype_index! { /// to find the specifications for a given lint. #[derive(Debug)] struct LintSet { - // -A,-W,-D flags, a `Symbol` for the flag itself and `LevelSpec` for which - // flag. - specs: FxIndexMap, + specs: FxIndexMap, parent: LintStackIndex, } @@ -79,9 +81,9 @@ impl LintLevelSets { &self, lint: &'static Lint, idx: LintStackIndex, - aux: Option<&FxIndexMap>, + aux: Option<&FxIndexMap>, sess: &Session, - ) -> LevelSpec { + ) -> UnstableLevelSpec { reveal_actual_level_spec(sess, LintId::of(lint), |id| { self.raw_lint_level_spec(id, idx, aux) }) @@ -91,8 +93,8 @@ impl LintLevelSets { &self, id: LintId, mut idx: LintStackIndex, - aux: Option<&FxIndexMap>, - ) -> Option { + aux: Option<&FxIndexMap>, + ) -> Option { if let Some(specs) = aux && let Some(level_spec) = specs.get(&id) { @@ -213,26 +215,53 @@ pub struct TopDown { } pub trait LintLevelsProvider { - fn current_specs(&self) -> &FxIndexMap; - fn insert(&mut self, id: LintId, level_spec: LevelSpec); - fn get_lint_level_spec(&self, lint: &'static Lint, sess: &Session) -> LevelSpec; - fn push_expectation(&mut self, id: LintExpectationId, expectation: LintExpectation); + type LintExpectationId: Copy + Debug + Into; + + fn current_specs(&self) -> &FxIndexMap>; + + fn insert(&mut self, id: LintId, level_spec: LevelSpec); + + fn get_lint_level_spec( + &self, + lint: &'static Lint, + sess: &Session, + ) -> LevelSpec; + + fn push_expectation(&mut self, id: Self::LintExpectationId, expectation: LintExpectation); + + fn mk_lint_expectation_id( + &self, + attr_id: AttrId, + attr_index: usize, + lint_index: Option, + ) -> Self::LintExpectationId; } impl LintLevelsProvider for TopDown { - fn current_specs(&self) -> &FxIndexMap { + type LintExpectationId = UnstableLintExpectationId; + + fn current_specs(&self) -> &FxIndexMap { &self.sets.list[self.cur].specs } - fn insert(&mut self, id: LintId, level_spec: LevelSpec) { + fn insert(&mut self, id: LintId, level_spec: UnstableLevelSpec) { self.sets.list[self.cur].specs.insert(id, level_spec); } - fn get_lint_level_spec(&self, lint: &'static Lint, sess: &Session) -> LevelSpec { + fn get_lint_level_spec(&self, lint: &'static Lint, sess: &Session) -> UnstableLevelSpec { self.sets.get_lint_level_spec(lint, self.cur, Some(self.current_specs()), sess) } - fn push_expectation(&mut self, _: LintExpectationId, _: LintExpectation) {} + fn push_expectation(&mut self, _: Self::LintExpectationId, _: LintExpectation) {} + + fn mk_lint_expectation_id( + &self, + attr_id: AttrId, + _attr_index: usize, + lint_index: Option, + ) -> Self::LintExpectationId { + UnstableLintExpectationId { attr_id, lint_index } + } } struct LintLevelQueryMap<'tcx> { @@ -240,33 +269,44 @@ struct LintLevelQueryMap<'tcx> { cur: HirId, specs: ShallowLintLevelMap, /// Empty hash map to simplify code. - empty: FxIndexMap, + empty: FxIndexMap, attrs: &'tcx hir::AttributeMap<'tcx>, } impl LintLevelsProvider for LintLevelQueryMap<'_> { - fn current_specs(&self) -> &FxIndexMap { + type LintExpectationId = StableLintExpectationId; + + fn current_specs(&self) -> &FxIndexMap { self.specs.specs.get(&self.cur.local_id).unwrap_or(&self.empty) } - fn insert(&mut self, id: LintId, level_spec: LevelSpec) { + + fn insert(&mut self, id: LintId, level_spec: StableLevelSpec) { self.specs.specs.get_mut_or_insert_default(self.cur.local_id).insert(id, level_spec); } - fn get_lint_level_spec(&self, lint: &'static Lint, _: &Session) -> LevelSpec { + + fn get_lint_level_spec(&self, lint: &'static Lint, _: &Session) -> StableLevelSpec { self.specs.lint_level_spec_at_node(self.tcx, LintId::of(lint), self.cur) } - fn push_expectation(&mut self, id: LintExpectationId, expectation: LintExpectation) { + + fn push_expectation(&mut self, id: Self::LintExpectationId, expectation: LintExpectation) { self.specs.expectations.push((id, expectation)) } + + fn mk_lint_expectation_id( + &self, + _attr_id: AttrId, + attr_index: usize, + lint_index: Option, + ) -> Self::LintExpectationId { + let attr_index = attr_index.try_into().unwrap(); + StableLintExpectationId { hir_id: self.cur, attr_index, lint_index } + } } impl<'tcx> LintLevelsBuilder<'_, LintLevelQueryMap<'tcx>> { fn add_id(&mut self, hir_id: HirId) { self.provider.cur = hir_id; - self.add( - self.provider.attrs.get(hir_id.local_id), - hir_id == hir::CRATE_HIR_ID, - Some(hir_id), - ); + self.add(self.provider.attrs.get(hir_id.local_id), hir_id == hir::CRATE_HIR_ID); } } @@ -386,7 +426,7 @@ impl<'s> LintLevelsBuilder<'s, TopDown> { crate_attrs: &[ast::Attribute], ) -> Self { let mut builder = Self::new(sess, features, lint_added_lints, store, registered_tools); - builder.add(crate_attrs, true, None); + builder.add(crate_attrs, true); builder } @@ -413,16 +453,12 @@ impl<'s> LintLevelsBuilder<'s, TopDown> { /// `#[allow]` /// /// Don't forget to call `pop`! - pub(crate) fn push( - &mut self, - attrs: &[ast::Attribute], - is_crate_node: bool, - ) -> BuilderPush { + pub(crate) fn push(&mut self, attrs: &[ast::Attribute], is_crate_node: bool) -> BuilderPush { let prev = self.provider.cur; self.provider.cur = self.provider.sets.list.push(LintSet { specs: FxIndexMap::default(), parent: prev }); - self.add(attrs, is_crate_node, None); + self.add(attrs, is_crate_node); if self.provider.current_specs().is_empty() { self.provider.sets.list.pop(); @@ -446,7 +482,10 @@ impl Drop for BuilderPush { } } -impl<'s, P: LintLevelsProvider> LintLevelsBuilder<'s, P> { +impl<'s, P: LintLevelsProvider> LintLevelsBuilder<'s, P> +where + LevelSpec: Into, +{ pub(crate) fn sess(&self) -> &Session { self.sess } @@ -455,11 +494,11 @@ impl<'s, P: LintLevelsProvider> LintLevelsBuilder<'s, P> { self.features } - fn current_specs(&self) -> &FxIndexMap { + fn current_specs(&self) -> &FxIndexMap> { self.provider.current_specs() } - fn insert(&mut self, id: LintId, level_spec: LevelSpec) { + fn insert(&mut self, id: LintId, level_spec: LevelSpec) { self.provider.insert(id, level_spec) } @@ -536,7 +575,7 @@ impl<'s, P: LintLevelsProvider> LintLevelsBuilder<'s, P> { /// Attempts to insert the `id` to `LevelSpec` map entry. If unsuccessful /// (e.g. if a forbid was already inserted on the same scope), then emits a /// diagnostic with no change to `specs`. - fn insert_spec(&mut self, id: LintId, level_spec: LevelSpec) { + fn insert_spec(&mut self, id: LintId, level_spec: LevelSpec) { let level = level_spec.level(); let lint_id = level_spec.lint_id(); let src = level_spec.src; @@ -561,7 +600,6 @@ impl<'s, P: LintLevelsProvider> LintLevelsBuilder<'s, P> { // as preventing `allow(lint)` for some lint `lint` in // `lint_group`. For now, issue a future-compatibility // warning for this case. - let id_name = id.lint.name_lower(); let fcw_warning = match old_src { LintLevelSource::Default => false, LintLevelSource::Node { name, .. } => self.store.is_lint_group(name), @@ -572,7 +610,7 @@ impl<'s, P: LintLevelsProvider> LintLevelsBuilder<'s, P> { fcw_warning, self.current_specs(), old_src, - id_name + id.lint.name_lower(), ); let sub = match old_src { LintLevelSource::Default => { @@ -637,12 +675,7 @@ impl<'s, P: LintLevelsProvider> LintLevelsBuilder<'s, P> { }; } - fn add( - &mut self, - attrs: &[impl AttributeExt], - is_crate_node: bool, - source_hir_id: Option, - ) { + fn add(&mut self, attrs: &[impl AttributeExt], is_crate_node: bool) { let sess = self.sess; for (attr_index, attr) in attrs.iter().enumerate() { if attr.is_automatically_derived_attr() { @@ -662,23 +695,9 @@ impl<'s, P: LintLevelsProvider> LintLevelsBuilder<'s, P> { continue; } - let (level, lint_id) = match Level::from_opt_symbol(attr.name()) { + let level = match Level::from_opt_symbol(attr.name()) { None => continue, - // `Expect` is the only lint level with a `LintExpectationId` that can be created - // from an attribute. - Some(Level::Expect) => { - let id = if let Some(hir_id) = source_hir_id { - LintExpectationId::Stable { - hir_id, - attr_index: attr_index.try_into().unwrap(), - lint_index: None, - } - } else { - LintExpectationId::Unstable { attr_id: attr.id(), lint_index: None } - }; - (Level::Expect, Some(id)) - } - Some(level) => (level, None), + Some(level) => level, }; let Some(mut metas) = attr.meta_item_list() else { continue }; @@ -726,10 +745,15 @@ impl<'s, P: LintLevelsProvider> LintLevelsBuilder<'s, P> { } for (lint_index, li) in metas.iter_mut().enumerate() { - let mut lint_id = lint_id; - if let Some(id) = &mut lint_id { - id.set_lint_index(Some(lint_index as u16)); - } + // `Expect` is the only lint level with a `LintExpectationId` that can be created + // from an attribute. + let lint_id = (level == Level::Expect).then(|| { + self.provider.mk_lint_expectation_id( + attr.id(), + attr_index, + Some(lint_index as u16), + ) + }); let sp = li.span(); let meta_item = match li { @@ -987,7 +1011,7 @@ impl<'s, P: LintLevelsProvider> LintLevelsBuilder<'s, P> { } /// Find the lint level for a lint. - pub fn lint_level_spec(&self, lint: &'static Lint) -> LevelSpec { + pub fn lint_level_spec(&self, lint: &'static Lint) -> LevelSpec { self.provider.get_lint_level_spec(lint, self.sess) } diff --git a/compiler/rustc_lint_defs/src/lib.rs b/compiler/rustc_lint_defs/src/lib.rs index 2e690c7185f8c..fc8b2b65a8d48 100644 --- a/compiler/rustc_lint_defs/src/lib.rs +++ b/compiler/rustc_lint_defs/src/lib.rs @@ -100,47 +100,48 @@ pub enum Applicability { /// have that amount of lints listed. `u16` values should therefore suffice. #[derive(Clone, Copy, PartialEq, Eq, Debug, Hash, Encodable, Decodable)] pub enum LintExpectationId { - /// Used for lints emitted during the `EarlyLintPass`. This id is not - /// hash stable and should not be cached. - Unstable { attr_id: AttrId, lint_index: Option }, - /// The [`HirId`] that the lint expectation is attached to. This id is - /// stable and can be cached. The additional index ensures that nodes with - /// several expectations can correctly match diagnostics to the individual - /// expectation. - Stable { hir_id: HirId, attr_index: u16, lint_index: Option }, -} - -impl LintExpectationId { - pub fn is_stable(&self) -> bool { - match self { - LintExpectationId::Unstable { .. } => false, - LintExpectationId::Stable { .. } => true, - } - } + Unstable(UnstableLintExpectationId), + Stable(StableLintExpectationId), +} - pub fn set_lint_index(&mut self, new_lint_index: Option) { - let (LintExpectationId::Unstable { lint_index, .. } - | LintExpectationId::Stable { lint_index, .. }) = self; +/// Used for lints emitted during the `EarlyLintPass`. This id is not hash +/// stable and should not be cached. +#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash, Encodable, Decodable)] +pub struct UnstableLintExpectationId { + pub attr_id: AttrId, + pub lint_index: Option, +} - *lint_index = new_lint_index +impl From for LintExpectationId { + fn from(id: UnstableLintExpectationId) -> LintExpectationId { + LintExpectationId::Unstable(id) } } -impl StableHash for LintExpectationId { +/// The [`HirId`] that the lint expectation is attached to. This id is stable +/// and can be cached. The additional index ensures that nodes with several +/// expectations can correctly match diagnostics to the individual expectation. +#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash, Encodable, Decodable)] +pub struct StableLintExpectationId { + pub hir_id: HirId, + pub attr_index: u16, + pub lint_index: Option, +} + +impl StableHash for StableLintExpectationId { #[inline] fn stable_hash(&self, hcx: &mut Hcx, hasher: &mut StableHasher) { - match self { - LintExpectationId::Stable { hir_id, attr_index, lint_index: Some(lint_index) } => { - hir_id.stable_hash(hcx, hasher); - attr_index.stable_hash(hcx, hasher); - lint_index.stable_hash(hcx, hasher); - } - _ => { - unreachable!( - "StableHash should only be called for filled and stable `LintExpectationId`" - ) - } - } + let StableLintExpectationId { hir_id, attr_index, lint_index } = self; + + hir_id.stable_hash(hcx, hasher); + attr_index.stable_hash(hcx, hasher); + lint_index.expect("must be filled to call `stable_hash`").stable_hash(hcx, hasher); + } +} + +impl From for LintExpectationId { + fn from(id: StableLintExpectationId) -> LintExpectationId { + LintExpectationId::Stable(id) } } diff --git a/compiler/rustc_middle/src/lint.rs b/compiler/rustc_middle/src/lint.rs index 41eeb1fc9811f..c1a9c6df72ae3 100644 --- a/compiler/rustc_middle/src/lint.rs +++ b/compiler/rustc_middle/src/lint.rs @@ -8,7 +8,8 @@ use rustc_lint_defs::EditionFcw; use rustc_macros::{Decodable, Encodable, StableHash}; use rustc_session::Session; use rustc_session::lint::{ - FutureIncompatibilityReason, Level, Lint, LintExpectationId, LintId, builtin, + FutureIncompatibilityReason, Level, Lint, LintExpectationId, LintId, StableLintExpectationId, + UnstableLintExpectationId, builtin, }; use rustc_span::{DUMMY_SP, ExpnKind, Span, Symbol, kw}; use tracing::instrument; @@ -55,7 +56,7 @@ impl LintLevelSource { /// Convenience helper for things that are frequently used together. #[derive(Copy, Clone, Debug, StableHash, Encodable, Decodable)] -pub struct LevelSpec { +pub struct LevelSpec { // This field *must* be private. It must be set in tandem with `lint_id`, only in // `LevelSpec::new`, because only certain `level`/`lint_id` combinations are valid. See // `LevelSpec::new` for those combinations. @@ -68,18 +69,17 @@ pub struct LevelSpec { level: Level, // This field *must* be private. See the comment on `level`. - lint_id: Option, + lint_id: Option, pub src: LintLevelSource, } -impl LevelSpec { +pub type UnstableLevelSpec = LevelSpec; +pub type StableLevelSpec = LevelSpec; + +impl LevelSpec { // Panics if an invalid `level`/`lint_id` combination is given. - pub fn new( - level: Level, - lint_id: Option, - src: LintLevelSource, - ) -> LevelSpec { + pub fn new(level: Level, lint_id: Option, src: LintLevelSource) -> LevelSpec { match (level, lint_id) { (Level::Allow | Level::Warn | Level::Deny | Level::Forbid, None) => {} (Level::Expect, Some(_)) => {} @@ -101,29 +101,45 @@ impl LevelSpec { self.level == Level::Expect } - pub fn lint_id(self) -> Option { + pub fn lint_id(self) -> Option { self.lint_id } } +impl From for LevelSpec { + fn from(level: UnstableLevelSpec) -> LevelSpec { + let LevelSpec { level, lint_id, src } = level; + let lint_id = lint_id.map(LintExpectationId::Unstable); + LevelSpec { level, lint_id, src } + } +} + +impl From for LevelSpec { + fn from(level: StableLevelSpec) -> LevelSpec { + let LevelSpec { level, lint_id, src } = level; + let lint_id = lint_id.map(LintExpectationId::Stable); + LevelSpec { level, lint_id, src } + } +} + /// Return type for the `shallow_lint_levels_on` query. /// /// This map represents the set of allowed lints and allowance levels given /// by the attributes for *a single HirId*. #[derive(Default, Debug, StableHash)] pub struct ShallowLintLevelMap { - pub expectations: Vec<(LintExpectationId, LintExpectation)>, - pub specs: SortedMap>, + pub expectations: Vec<(StableLintExpectationId, LintExpectation)>, + pub specs: SortedMap>, } /// Verify the effect of special annotations: `warnings` lint level and lint caps. /// /// The return of this function is suitable for diagnostics. -pub fn reveal_actual_level_spec( +pub fn reveal_actual_level_spec( sess: &Session, lint: LintId, - probe_for_lint_level_spec: impl Fn(LintId) -> Option, -) -> LevelSpec { + probe_for_lint_level_spec: impl Fn(LintId) -> Option>, +) -> LevelSpec { let level_spec = probe_for_lint_level_spec(lint); // If `level` is none then we actually assume the default level for this lint. @@ -185,7 +201,7 @@ impl ShallowLintLevelMap { tcx: TyCtxt<'_>, id: LintId, start: HirId, - ) -> Option { + ) -> Option { if let Some(map) = self.specs.get(&start.local_id) && let Some(level_spec) = map.get(&id) { @@ -212,7 +228,12 @@ impl ShallowLintLevelMap { /// Fetch and return the user-visible lint level spec for the given lint at the given HirId. #[instrument(level = "trace", skip(self, tcx), ret)] - pub fn lint_level_spec_at_node(&self, tcx: TyCtxt<'_>, lint: LintId, cur: HirId) -> LevelSpec { + pub fn lint_level_spec_at_node( + &self, + tcx: TyCtxt<'_>, + lint: LintId, + cur: HirId, + ) -> StableLevelSpec { reveal_actual_level_spec(tcx.sess, lint, |lint| { self.probe_for_lint_level_spec(tcx, lint, cur) }) @@ -221,7 +242,7 @@ impl ShallowLintLevelMap { impl TyCtxt<'_> { /// Fetch and return the user-visible lint level spec for the given lint at the given HirId. - pub fn lint_level_spec_at_node(self, lint: &'static Lint, id: HirId) -> LevelSpec { + pub fn lint_level_spec_at_node(self, lint: &'static Lint, id: HirId) -> StableLevelSpec { self.shallow_lint_levels_on(id.owner).lint_level_spec_at_node(self, LintId::of(lint), id) } } @@ -362,7 +383,7 @@ fn explain_lint_level_source( pub fn emit_lint_base<'a, D: Diagnostic<'a, ()> + 'a>( sess: &'a Session, lint: &'static Lint, - level_spec: LevelSpec, + level_spec: impl Into, span: Option, decorate: D, ) { @@ -556,7 +577,7 @@ pub fn emit_lint_base<'a, D: Diagnostic<'a, ()> + 'a>( emit_lint_base_impl( sess, lint, - level_spec, + level_spec.into(), span, Box::new(move |dcx, level| decorate.into_diag(dcx, level)), ); diff --git a/compiler/rustc_middle/src/queries.rs b/compiler/rustc_middle/src/queries.rs index a9fc5dcac8f29..d62e4ec941d21 100644 --- a/compiler/rustc_middle/src/queries.rs +++ b/compiler/rustc_middle/src/queries.rs @@ -75,7 +75,7 @@ use rustc_session::config::{EntryFnType, OptLevel, OutputFilenames, SymbolMangli use rustc_session::cstore::{ CrateDepKind, CrateSource, ExternCrate, ForeignModule, LinkagePreference, NativeLib, }; -use rustc_session::lint::LintExpectationId; +use rustc_session::lint::StableLintExpectationId; use rustc_span::def_id::LOCAL_CRATE; use rustc_span::{DUMMY_SP, LocalExpnId, Span, Spanned, Symbol}; use rustc_target::spec::PanicStrategy; @@ -558,7 +558,7 @@ rustc_queries! { desc { "looking up lint levels for `{}`", tcx.def_path_str(key) } } - query lint_expectations(_: ()) -> &'tcx Vec<(LintExpectationId, LintExpectation)> { + query lint_expectations(_: ()) -> &'tcx Vec<(StableLintExpectationId, LintExpectation)> { arena_cache desc { "computing `#[expect]`ed lints in this crate" } } diff --git a/compiler/rustc_passes/src/dead.rs b/compiler/rustc_passes/src/dead.rs index 5d3ea7e2c237c..92a0f14f3e94e 100644 --- a/compiler/rustc_passes/src/dead.rs +++ b/compiler/rustc_passes/src/dead.rs @@ -22,7 +22,7 @@ use rustc_middle::ty::{self, AssocTag, TyCtxt}; use rustc_middle::{bug, span_bug}; use rustc_session::config::CrateType; use rustc_session::lint::builtin::{DEAD_CODE, DEAD_CODE_PUB_IN_BINARY}; -use rustc_session::lint::{self, Lint, LintExpectationId}; +use rustc_session::lint::{self, Lint, StableLintExpectationId}; use rustc_span::{Symbol, kw}; use crate::errors::{ @@ -1035,7 +1035,7 @@ fn mark_live_symbols_and_ignored_derived_traits( struct DeadItem { def_id: LocalDefId, name: Symbol, - level_plus: (lint::Level, Option), + level_plus: (lint::Level, Option), } struct DeadVisitor<'tcx> { @@ -1082,7 +1082,10 @@ impl<'tcx> DeadVisitor<'tcx> { ShouldWarnAboutField::Yes } - fn def_lint_level_plus(&self, id: LocalDefId) -> (lint::Level, Option) { + fn def_lint_level_plus( + &self, + id: LocalDefId, + ) -> (lint::Level, Option) { let hir_id = self.tcx.local_def_id_to_hir_id(id); let level_spec = self.tcx.lint_level_spec_at_node(self.target_lint, hir_id); (level_spec.level(), level_spec.lint_id()) @@ -1267,7 +1270,7 @@ impl<'tcx> DeadVisitor<'tcx> { return; } // FIXME: `dead_codes` should probably be morally equivalent to - // `IndexMap<(Level, LintExpectationId), (DefId, Symbol)>` + // `IndexMap<(Level, StableLintExpectationId), (DefId, Symbol)>` dead_codes.sort_by_key(|v| v.level_plus.0); for group in dead_codes.chunk_by(|a, b| a.level_plus == b.level_plus) { self.lint_at_single_level(&group, participle, Some(def_id), report_on); diff --git a/src/tools/clippy/clippy_lints/src/duplicate_mod.rs b/src/tools/clippy/clippy_lints/src/duplicate_mod.rs index cb3cb2479beed..f1837e776e824 100644 --- a/src/tools/clippy/clippy_lints/src/duplicate_mod.rs +++ b/src/tools/clippy/clippy_lints/src/duplicate_mod.rs @@ -2,7 +2,7 @@ use clippy_utils::diagnostics::span_lint_and_help; use rustc_ast::ast::{Crate, Inline, Item, ItemKind, ModKind}; use rustc_errors::MultiSpan; use rustc_lint::{EarlyContext, EarlyLintPass, Level, LintContext}; -use rustc_middle::lint::LevelSpec; +use rustc_middle::lint::UnstableLevelSpec; use rustc_session::impl_lint_pass; use rustc_span::{FileName, Span}; use std::collections::BTreeMap; @@ -51,7 +51,7 @@ impl_lint_pass!(DuplicateMod => [DUPLICATE_MOD]); struct Modules { local_path: PathBuf, spans: Vec, - lint_level_specs: Vec, + lint_level_specs: Vec, } #[derive(Default)] @@ -96,7 +96,7 @@ impl EarlyLintPass for DuplicateMod { .zip(lint_level_specs) .filter_map(|(span, level_spec)| { if let Some(id) = level_spec.lint_id() { - cx.fulfill_expectation(id); + cx.fulfill_expectation(id.into()); } (!matches!(level_spec.level(), Level::Allow | Level::Expect)).then_some(*span) From 36738a1f0ea86192f4c15313271a095a1d9b7e0c Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Fri, 15 May 2026 11:05:48 +1000 Subject: [PATCH 22/29] Remove some low-value method wrappers I find these make the code harder to understand. --- compiler/rustc_lint/src/levels.rs | 26 +++++++++----------------- 1 file changed, 9 insertions(+), 17 deletions(-) diff --git a/compiler/rustc_lint/src/levels.rs b/compiler/rustc_lint/src/levels.rs index 3ac1d0e08af73..b8da46594cfc2 100644 --- a/compiler/rustc_lint/src/levels.rs +++ b/compiler/rustc_lint/src/levels.rs @@ -494,14 +494,6 @@ where self.features } - fn current_specs(&self) -> &FxIndexMap> { - self.provider.current_specs() - } - - fn insert(&mut self, id: LintId, level_spec: LevelSpec) { - self.provider.insert(id, level_spec) - } - fn add_command_line(&mut self) { for &(ref lint_name, level) in &self.sess.opts.lint_opts { // Checks the validity of lint names derived from the command line. @@ -558,7 +550,7 @@ where }; for &id in ids { // ForceWarn and Forbid cannot be overridden - if let Some(level_spec) = self.current_specs().get(&id) + if let Some(level_spec) = self.provider.current_specs().get(&id) && matches!(level_spec.level(), Level::ForceWarn | Level::Forbid) { continue; @@ -566,7 +558,7 @@ where if self.check_gated_lint(id, DUMMY_SP, true) { let src = LintLevelSource::CommandLine(lint_flag_val, level); - self.insert(id, LevelSpec::new(level, None, src)); + self.provider.insert(id, LevelSpec::new(level, None, src)); } } } @@ -608,7 +600,7 @@ where debug!( "fcw_warning={:?}, specs.get(&id) = {:?}, old_src={:?}, id_name={:?}", fcw_warning, - self.current_specs(), + self.provider.current_specs(), old_src, id.lint.name_lower(), ); @@ -664,14 +656,14 @@ where match (old_level, level) { // If the new level is an expectation store it in `ForceWarn` (Level::ForceWarn, Level::Expect) => { - self.insert(id, LevelSpec::new(Level::ForceWarn, lint_id, old_src)) + self.provider.insert(id, LevelSpec::new(Level::ForceWarn, lint_id, old_src)) } // Keep `ForceWarn` level but drop the expectation (Level::ForceWarn, _) => { - self.insert(id, LevelSpec::new(Level::ForceWarn, None, old_src)) + self.provider.insert(id, LevelSpec::new(Level::ForceWarn, None, old_src)) } // Set the lint level as normal - _ => self.insert(id, LevelSpec::new(level, lint_id, src)), + _ => self.provider.insert(id, LevelSpec::new(level, lint_id, src)), }; } @@ -679,7 +671,7 @@ where let sess = self.sess; for (attr_index, attr) in attrs.iter().enumerate() { if attr.is_automatically_derived_attr() { - self.insert( + self.provider.insert( LintId::of(SINGLE_USE_LIFETIMES), LevelSpec::new(Level::Allow, None, LintLevelSource::Default), ); @@ -688,7 +680,7 @@ where // `#[doc(hidden)]` disables missing_docs check. if attr.is_doc_hidden() { - self.insert( + self.provider.insert( LintId::of(MISSING_DOCS), LevelSpec::new(Level::Allow, None, LintLevelSource::Default), ); @@ -925,7 +917,7 @@ where } if self.lint_added_lints && !is_crate_node { - for (id, level_spec) in self.current_specs().iter() { + for (id, level_spec) in self.provider.current_specs().iter() { if !id.lint.crate_level_only { continue; } From 6c9d519d37493f076d9983cf4c8b7fb9f90de8ff Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Fri, 15 May 2026 12:40:44 +1000 Subject: [PATCH 23/29] Add some comments to `ShallowLintLevelMap` Describing things that took me a while to work out. --- compiler/rustc_middle/src/lint.rs | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/compiler/rustc_middle/src/lint.rs b/compiler/rustc_middle/src/lint.rs index c1a9c6df72ae3..aa4b8f1d12c9f 100644 --- a/compiler/rustc_middle/src/lint.rs +++ b/compiler/rustc_middle/src/lint.rs @@ -124,12 +124,15 @@ impl From for LevelSpec { /// Return type for the `shallow_lint_levels_on` query. /// -/// This map represents the set of allowed lints and allowance levels given -/// by the attributes for *a single HirId*. +/// This map represents lints levels given by the attributes for *a single HirId*. #[derive(Default, Debug, StableHash)] pub struct ShallowLintLevelMap { - pub expectations: Vec<(StableLintExpectationId, LintExpectation)>, + // All the specs for this HirId. This is accessed frequently, e.g. for every lint emitted. pub specs: SortedMap>, + + // Additional information about the `expect` specs for this HirId. This is consulted only once + // per compilation session, in `check_expectations`/`lint_expectations`. + pub expectations: Vec<(StableLintExpectationId, LintExpectation)>, } /// Verify the effect of special annotations: `warnings` lint level and lint caps. From e5998316eb12505f14e3236b5df49c15aea2e47f Mon Sep 17 00:00:00 2001 From: Andy Russell Date: Sat, 9 May 2026 17:41:28 -0400 Subject: [PATCH 24/29] suggest hex escapes for C-style escapes --- .../src/lexer/unescape_error_reporting.rs | 42 ++++- tests/ui/parser/byte-literals.stderr | 10 ++ tests/ui/parser/byte-string-literals.stderr | 10 ++ tests/ui/parser/foreign-escapes.rs | 25 +++ tests/ui/parser/foreign-escapes.stderr | 165 ++++++++++++++++++ 5 files changed, 251 insertions(+), 1 deletion(-) create mode 100644 tests/ui/parser/foreign-escapes.rs create mode 100644 tests/ui/parser/foreign-escapes.stderr diff --git a/compiler/rustc_parse/src/lexer/unescape_error_reporting.rs b/compiler/rustc_parse/src/lexer/unescape_error_reporting.rs index 895374ab2cc4b..099bd44e9a065 100644 --- a/compiler/rustc_parse/src/lexer/unescape_error_reporting.rs +++ b/compiler/rustc_parse/src/lexer/unescape_error_reporting.rs @@ -3,7 +3,7 @@ use std::iter::once; use std::ops::Range; -use rustc_errors::{Applicability, DiagCtxtHandle, ErrorGuaranteed}; +use rustc_errors::{Applicability, Diag, DiagCtxtHandle, ErrorGuaranteed}; use rustc_literal_escaper::{EscapeError, Mode}; use rustc_span::{BytePos, Span}; use tracing::debug; @@ -172,6 +172,8 @@ pub(crate) fn emit_unescape_error( "for more information, visit \ ", ); + + foreign_escape_suggestion(&mut diag, (&ec, span), err_span); } diag.emit() } @@ -302,6 +304,44 @@ pub(crate) fn emit_unescape_error( }) } +/// Add additional suggestions for escapes that are supported by C. +fn foreign_escape_suggestion( + diag: &mut Diag<'_>, + (escaped_char, escape_span): (&str, Span), + err_span: Span, +) { + if escaped_char == "?" { + diag.span_suggestion( + err_span, + "if you meant to write a literal question mark, don't escape the character", + "?", + Applicability::MaybeIncorrect, + ); + return; + } + + if u8::from_str_radix(escaped_char, 8).is_ok() { + diag.help(r"if you meant to write an ASCII control code, use a `\xNN` hex escape"); + return; + } + + let (name, hex) = match escaped_char { + "a" => ("an audible bell", "07"), + "b" => ("a backspace", "08"), + "f" => ("a form feed", "0C"), + "v" => ("a vertical tab", "0B"), + "e" => ("an ANSI escape sequence", "1B"), + _ => return, + }; + + diag.span_suggestion( + escape_span, + format!("if you meant to write {name}, use a hex escape"), + format!("x{hex}"), + Applicability::MaybeIncorrect, + ); +} + /// Pushes a character to a message string for error reporting pub(crate) fn escaped_char(c: char) -> String { match c { diff --git a/tests/ui/parser/byte-literals.stderr b/tests/ui/parser/byte-literals.stderr index 1c89e8e2864b6..4df5f764cfe85 100644 --- a/tests/ui/parser/byte-literals.stderr +++ b/tests/ui/parser/byte-literals.stderr @@ -5,6 +5,11 @@ LL | static FOO: u8 = b'\f'; | ^ unknown byte escape | = help: for more information, visit +help: if you meant to write a form feed, use a hex escape + | +LL - static FOO: u8 = b'\f'; +LL + static FOO: u8 = b'\x0C'; + | error: unknown byte escape: `f` --> $DIR/byte-literals.rs:6:8 @@ -13,6 +18,11 @@ LL | b'\f'; | ^ unknown byte escape | = help: for more information, visit +help: if you meant to write a form feed, use a hex escape + | +LL - b'\f'; +LL + b'\x0C'; + | error: invalid character in numeric character escape: `Z` --> $DIR/byte-literals.rs:7:10 diff --git a/tests/ui/parser/byte-string-literals.stderr b/tests/ui/parser/byte-string-literals.stderr index 3e589258d4132..d036fae68ea1f 100644 --- a/tests/ui/parser/byte-string-literals.stderr +++ b/tests/ui/parser/byte-string-literals.stderr @@ -5,6 +5,11 @@ LL | static FOO: &'static [u8] = b"\f"; | ^ unknown byte escape | = help: for more information, visit +help: if you meant to write a form feed, use a hex escape + | +LL - static FOO: &'static [u8] = b"\f"; +LL + static FOO: &'static [u8] = b"\x0C"; + | error: unknown byte escape: `f` --> $DIR/byte-string-literals.rs:4:8 @@ -13,6 +18,11 @@ LL | b"\f"; | ^ unknown byte escape | = help: for more information, visit +help: if you meant to write a form feed, use a hex escape + | +LL - b"\f"; +LL + b"\x0C"; + | error: invalid character in numeric character escape: `Z` --> $DIR/byte-string-literals.rs:5:10 diff --git a/tests/ui/parser/foreign-escapes.rs b/tests/ui/parser/foreign-escapes.rs new file mode 100644 index 0000000000000..d802f858f8e31 --- /dev/null +++ b/tests/ui/parser/foreign-escapes.rs @@ -0,0 +1,25 @@ +// Specified by both C and Rust +pub const SINGLE_QUOTE: char = '\''; +pub const DOUBLE_QUOTE: char = '\"'; +pub const BACKSLASH: char = '\\'; +pub const NEWLINE: char = '\n'; +pub const CARRIAGE_RETURN: char = '\r'; +pub const HORIZONTAL_TAB: char = '\t'; +pub const NULL: char = '\0'; + +// Specified by C, but not Rust +pub const QUESTION_MARK: char = '\?'; //~ ERROR unknown character escape +pub const AUDIBLE_BELL: char = '\a'; //~ ERROR unknown character escape +pub const BACKSPACE: char = '\b'; //~ ERROR unknown character escape +pub const FORM_FEED: char = '\f'; //~ ERROR unknown character escape +pub const VERTICAL_TAB: char = '\v'; //~ ERROR unknown character escape +pub const OCTAL: char = '\1'; //~ ERROR unknown character escape +pub const OCTAL_TWO_DIGIT: char = '\12'; //~ ERROR unknown character escape +pub const OCTAL_THREE_DIGIT: char = '\12'; //~ ERROR unknown character escape +pub const OCTAL_OUT_OF_RANGE: char = '\9'; //~ ERROR unknown character escape + +// Not specified by C, but recognized by GCC as an extension. +// Used for ANSI escape sequences in terminal emulators. +pub const ESCAPE: char = '\e'; //~ ERROR unknown character escape + +fn main() {} diff --git a/tests/ui/parser/foreign-escapes.stderr b/tests/ui/parser/foreign-escapes.stderr new file mode 100644 index 0000000000000..619d7d1e6e8b7 --- /dev/null +++ b/tests/ui/parser/foreign-escapes.stderr @@ -0,0 +1,165 @@ +error: unknown character escape: `?` + --> $DIR/foreign-escapes.rs:11:35 + | +LL | pub const QUESTION_MARK: char = '\?'; + | ^ unknown character escape + | + = help: for more information, visit +help: if you meant to write a literal backslash (perhaps escaping in a regular expression), consider a raw string literal + | +LL - pub const QUESTION_MARK: char = '\?'; +LL + pub const QUESTION_MARK: char = r"\?"; + | +help: if you meant to write a literal question mark, don't escape the character + | +LL - pub const QUESTION_MARK: char = '\?'; +LL + pub const QUESTION_MARK: char = '?'; + | + +error: unknown character escape: `a` + --> $DIR/foreign-escapes.rs:12:34 + | +LL | pub const AUDIBLE_BELL: char = '\a'; + | ^ unknown character escape + | + = help: for more information, visit +help: if you meant to write a literal backslash (perhaps escaping in a regular expression), consider a raw string literal + | +LL - pub const AUDIBLE_BELL: char = '\a'; +LL + pub const AUDIBLE_BELL: char = r"\a"; + | +help: if you meant to write an audible bell, use a hex escape + | +LL - pub const AUDIBLE_BELL: char = '\a'; +LL + pub const AUDIBLE_BELL: char = '\x07'; + | + +error: unknown character escape: `b` + --> $DIR/foreign-escapes.rs:13:31 + | +LL | pub const BACKSPACE: char = '\b'; + | ^ unknown character escape + | + = help: for more information, visit +help: if you meant to write a literal backslash (perhaps escaping in a regular expression), consider a raw string literal + | +LL - pub const BACKSPACE: char = '\b'; +LL + pub const BACKSPACE: char = r"\b"; + | +help: if you meant to write a backspace, use a hex escape + | +LL - pub const BACKSPACE: char = '\b'; +LL + pub const BACKSPACE: char = '\x08'; + | + +error: unknown character escape: `f` + --> $DIR/foreign-escapes.rs:14:31 + | +LL | pub const FORM_FEED: char = '\f'; + | ^ unknown character escape + | + = help: for more information, visit +help: if you meant to write a literal backslash (perhaps escaping in a regular expression), consider a raw string literal + | +LL - pub const FORM_FEED: char = '\f'; +LL + pub const FORM_FEED: char = r"\f"; + | +help: if you meant to write a form feed, use a hex escape + | +LL - pub const FORM_FEED: char = '\f'; +LL + pub const FORM_FEED: char = '\x0C'; + | + +error: unknown character escape: `v` + --> $DIR/foreign-escapes.rs:15:34 + | +LL | pub const VERTICAL_TAB: char = '\v'; + | ^ unknown character escape + | + = help: for more information, visit +help: if you meant to write a literal backslash (perhaps escaping in a regular expression), consider a raw string literal + | +LL - pub const VERTICAL_TAB: char = '\v'; +LL + pub const VERTICAL_TAB: char = r"\v"; + | +help: if you meant to write a vertical tab, use a hex escape + | +LL - pub const VERTICAL_TAB: char = '\v'; +LL + pub const VERTICAL_TAB: char = '\x0B'; + | + +error: unknown character escape: `1` + --> $DIR/foreign-escapes.rs:16:27 + | +LL | pub const OCTAL: char = '\1'; + | ^ unknown character escape + | + = help: for more information, visit + = help: if you meant to write an ASCII control code, use a `\xNN` hex escape +help: if you meant to write a literal backslash (perhaps escaping in a regular expression), consider a raw string literal + | +LL - pub const OCTAL: char = '\1'; +LL + pub const OCTAL: char = r"\1"; + | + +error: unknown character escape: `1` + --> $DIR/foreign-escapes.rs:17:37 + | +LL | pub const OCTAL_TWO_DIGIT: char = '\12'; + | ^ unknown character escape + | + = help: for more information, visit + = help: if you meant to write an ASCII control code, use a `\xNN` hex escape +help: if you meant to write a literal backslash (perhaps escaping in a regular expression), consider a raw string literal + | +LL - pub const OCTAL_TWO_DIGIT: char = '\12'; +LL + pub const OCTAL_TWO_DIGIT: char = r"\12"; + | + +error: unknown character escape: `1` + --> $DIR/foreign-escapes.rs:18:39 + | +LL | pub const OCTAL_THREE_DIGIT: char = '\12'; + | ^ unknown character escape + | + = help: for more information, visit + = help: if you meant to write an ASCII control code, use a `\xNN` hex escape +help: if you meant to write a literal backslash (perhaps escaping in a regular expression), consider a raw string literal + | +LL - pub const OCTAL_THREE_DIGIT: char = '\12'; +LL + pub const OCTAL_THREE_DIGIT: char = r"\12"; + | + +error: unknown character escape: `9` + --> $DIR/foreign-escapes.rs:19:40 + | +LL | pub const OCTAL_OUT_OF_RANGE: char = '\9'; + | ^ unknown character escape + | + = help: for more information, visit +help: if you meant to write a literal backslash (perhaps escaping in a regular expression), consider a raw string literal + | +LL - pub const OCTAL_OUT_OF_RANGE: char = '\9'; +LL + pub const OCTAL_OUT_OF_RANGE: char = r"\9"; + | + +error: unknown character escape: `e` + --> $DIR/foreign-escapes.rs:23:28 + | +LL | pub const ESCAPE: char = '\e'; + | ^ unknown character escape + | + = help: for more information, visit +help: if you meant to write a literal backslash (perhaps escaping in a regular expression), consider a raw string literal + | +LL - pub const ESCAPE: char = '\e'; +LL + pub const ESCAPE: char = r"\e"; + | +help: if you meant to write an ANSI escape sequence, use a hex escape + | +LL - pub const ESCAPE: char = '\e'; +LL + pub const ESCAPE: char = '\x1B'; + | + +error: aborting due to 10 previous errors + From 04c325f16e2b74a1770ff6ba02d8656c66f93fcd Mon Sep 17 00:00:00 2001 From: "Mark Z. Ding" Date: Thu, 14 May 2026 13:54:07 -0400 Subject: [PATCH 25/29] ignore some musttail tests on unsupported LLVM targets --- .../rustc-dev-guide/src/tests/directives.md | 2 +- .../src/directives/directive_names.rs | 3 +++ .../become-indirect-return.rs | 21 +++++++++++++++++++ tests/ui/explicit-tail-calls/indirect.rs | 19 +++++++++++++++++ 4 files changed, 44 insertions(+), 1 deletion(-) diff --git a/src/doc/rustc-dev-guide/src/tests/directives.md b/src/doc/rustc-dev-guide/src/tests/directives.md index 34d25b1d6dbc2..4ae5a4144fb81 100644 --- a/src/doc/rustc-dev-guide/src/tests/directives.md +++ b/src/doc/rustc-dev-guide/src/tests/directives.md @@ -133,7 +133,7 @@ means the test won't be compiled or run. Some examples of `X` in `ignore-X` or `only-X`: - A full target triple: `aarch64-apple-ios` -- Architecture: `aarch64`, `arm`, `mips`, `wasm32`, `x86_64`, `x86`, +- Architecture: `aarch64`, `arm`, `csky`, `mips`, `mips64`, `wasm32`, `x86_64`, `x86`, ... - OS: `android`, `emscripten`, `freebsd`, `ios`, `linux`, `macos`, `windows`, ... diff --git a/src/tools/compiletest/src/directives/directive_names.rs b/src/tools/compiletest/src/directives/directive_names.rs index e1b6e70d90f04..72e9787fe42ec 100644 --- a/src/tools/compiletest/src/directives/directive_names.rs +++ b/src/tools/compiletest/src/directives/directive_names.rs @@ -67,6 +67,7 @@ pub(crate) const KNOWN_DIRECTIVE_NAMES: &[&str] = &[ "ignore-coverage-map", "ignore-coverage-run", "ignore-cross-compile", + "ignore-csky", "ignore-eabi", "ignore-elf", "ignore-emscripten", @@ -91,6 +92,8 @@ pub(crate) const KNOWN_DIRECTIVE_NAMES: &[&str] = &[ "ignore-loongarch64", "ignore-macabi", "ignore-macos", + "ignore-mips", + "ignore-mips64", "ignore-msp430", "ignore-msvc", "ignore-musl", diff --git a/tests/ui/explicit-tail-calls/become-indirect-return.rs b/tests/ui/explicit-tail-calls/become-indirect-return.rs index b1e552bca0293..8cf733dbfdff5 100644 --- a/tests/ui/explicit-tail-calls/become-indirect-return.rs +++ b/tests/ui/explicit-tail-calls/become-indirect-return.rs @@ -2,6 +2,27 @@ //@ ignore-backends: gcc //@ ignore-wasm 'tail-call' feature not enabled in target wasm32-wasip1 //@ ignore-cross-compile +// +// LLVM musttail support is incomplete for these targets. +// See https://github.com/rust-lang/rust/issues/148748 for the target test matrix. +// See https://github.com/llvm/llvm-project/issues/63214 for AIX and PowerPC. +// See https://github.com/llvm/llvm-project/issues/57795 for MIPS and MIPS64. +//@ ignore-aix +//@ ignore-csky +//@ ignore-mips +//@ ignore-mips64 +//@ ignore-powerpc +//@ ignore-powerpc64 +// +// LLVM musttail support is lacking for sret lowering on these targets. +// Returning `[u8; 24]` uses sret lowering here. +// See https://github.com/llvm/llvm-project/issues/157814 for RISC-V. +// See https://github.com/llvm/llvm-project/issues/168152 for LoongArch. +// RISC-V fix: https://github.com/llvm/llvm-project/pull/185094, should be in LLVM 23. +// LoongArch will likely be fixed with similar changes. +//@ ignore-riscv64 +//@ ignore-loongarch32 +//@ ignore-loongarch64 #![expect(incomplete_features)] #![feature(explicit_tail_calls)] diff --git a/tests/ui/explicit-tail-calls/indirect.rs b/tests/ui/explicit-tail-calls/indirect.rs index 537976b7f6f43..b3e2613efad25 100644 --- a/tests/ui/explicit-tail-calls/indirect.rs +++ b/tests/ui/explicit-tail-calls/indirect.rs @@ -2,7 +2,26 @@ //@ ignore-backends: gcc // //@ ignore-wasm +// +// LLVM musttail support is incomplete for these targets. +// See https://github.com/rust-lang/rust/issues/148748 for the target test matrix. +// See https://github.com/llvm/llvm-project/issues/63214 for AIX and PowerPC. +// See https://github.com/llvm/llvm-project/issues/57795 for MIPS and MIPS64. +//@ ignore-aix +//@ ignore-csky +//@ ignore-mips +//@ ignore-mips64 +//@ ignore-powerpc +//@ ignore-powerpc64 +// +// LLVM musttail support is lacking for indirect arguments that do not fit in registers. +// See https://github.com/llvm/llvm-project/issues/157814 for RISC-V. +// See https://github.com/llvm/llvm-project/issues/168152 for LoongArch. +// RISC-V fix: https://github.com/llvm/llvm-project/pull/185094, should be in LLVM 23. +// LoongArch will likely be fixed with similar changes. //@ ignore-riscv64 +//@ ignore-loongarch32 +//@ ignore-loongarch64 #![feature(explicit_tail_calls)] #![expect(incomplete_features)] From 2071c66f19171fbf937fba7cac1976bcc6417195 Mon Sep 17 00:00:00 2001 From: Yuki Okushi Date: Mon, 19 Jan 2026 18:12:38 +0900 Subject: [PATCH 26/29] Add interior-mutability suggestion to `static_mut_refs` --- compiler/rustc_lint/src/lints.rs | 18 +++ compiler/rustc_lint/src/static_mut_refs.rs | 143 ++++++++++++++++-- .../static-mut-refs-interior-mutability.fixed | 13 ++ .../static-mut-refs-interior-mutability.rs | 13 ++ ...static-mut-refs-interior-mutability.stderr | 18 +++ .../static-lazy-init-with-arena-set.stderr | 6 + 6 files changed, 200 insertions(+), 11 deletions(-) create mode 100644 tests/ui/lint/static-mut-refs-interior-mutability.fixed create mode 100644 tests/ui/lint/static-mut-refs-interior-mutability.rs create mode 100644 tests/ui/lint/static-mut-refs-interior-mutability.stderr diff --git a/compiler/rustc_lint/src/lints.rs b/compiler/rustc_lint/src/lints.rs index 6d9f486f627f6..091b7ac228b54 100644 --- a/compiler/rustc_lint/src/lints.rs +++ b/compiler/rustc_lint/src/lints.rs @@ -2669,6 +2669,12 @@ pub(crate) struct RefOfMutStatic<'a> { "mutable references to mutable statics are dangerous; it's undefined behavior if any other pointer to the static is used or if any other reference is created for the static while the mutable reference lives" )] pub mut_note: bool, + #[help( + "use a type that relies on \"interior mutability\" instead; to read more on this, visit " + )] + pub interior_mutability_help: bool, + #[subdiagnostic] + pub interior_mutability_sugg: Option, } #[derive(Subdiagnostic)] @@ -2693,6 +2699,18 @@ pub(crate) enum MutRefSugg { }, } +#[derive(Subdiagnostic)] +#[suggestion( + "this type already provides \"interior mutability\", so its binding doesn't need to be declared as mutable", + style = "verbose", + applicability = "maybe-incorrect", + code = "" +)] +pub(crate) struct StaticMutRefsInteriorMutabilitySugg { + #[primary_span] + pub span: Span, +} + #[derive(Diagnostic)] #[diag("`use` of a local item without leading `self::`, `super::`, or `crate::`")] pub(crate) struct UnqualifiedLocalImportsDiag; diff --git a/compiler/rustc_lint/src/static_mut_refs.rs b/compiler/rustc_lint/src/static_mut_refs.rs index 1decb4b78e61a..64ab1f7535bff 100644 --- a/compiler/rustc_lint/src/static_mut_refs.rs +++ b/compiler/rustc_lint/src/static_mut_refs.rs @@ -1,11 +1,12 @@ use rustc_hir as hir; +use rustc_hir::def_id::DefId; use rustc_hir::{Expr, Stmt}; use rustc_middle::ty::{Mutability, TyKind}; use rustc_session::lint::fcw; use rustc_session::{declare_lint, declare_lint_pass}; use rustc_span::{BytePos, Span}; -use crate::lints::{MutRefSugg, RefOfMutStatic}; +use crate::lints::{MutRefSugg, RefOfMutStatic, StaticMutRefsInteriorMutabilitySugg}; use crate::{LateContext, LateLintPass, LintContext}; declare_lint! { @@ -67,7 +68,7 @@ impl<'tcx> LateLintPass<'tcx> for StaticMutRefs { match expr.kind { hir::ExprKind::AddrOf(borrow_kind, m, ex) if matches!(borrow_kind, hir::BorrowKind::Ref) - && let Some(err_span) = path_is_static_mut(ex, err_span) => + && let Some(static_mut) = path_is_static_mut(ex, err_span) => { let source_map = cx.sess().source_map(); let snippet = source_map.span_to_snippet(err_span); @@ -86,10 +87,17 @@ impl<'tcx> LateLintPass<'tcx> for StaticMutRefs { err_span.with_hi(ex.span.lo()) }; - emit_static_mut_refs(cx, err_span, sugg_span, m, !expr.span.from_expansion()); + emit_static_mut_refs( + cx, + static_mut.err_span, + sugg_span, + m, + !expr.span.from_expansion(), + static_mut.def_id, + ); } hir::ExprKind::MethodCall(_, e, _, _) - if let Some(err_span) = path_is_static_mut(e, expr.span) + if let Some(static_mut) = path_is_static_mut(e, expr.span) && let typeck = cx.typeck_results() && let Some(method_def_id) = typeck.type_dependent_def_id(expr.hir_id) && let inputs = @@ -97,7 +105,14 @@ impl<'tcx> LateLintPass<'tcx> for StaticMutRefs { && let Some(receiver) = inputs.get(0) && let TyKind::Ref(_, _, m) = receiver.kind() => { - emit_static_mut_refs(cx, err_span, err_span.shrink_to_lo(), *m, false); + emit_static_mut_refs( + cx, + static_mut.err_span, + static_mut.err_span.shrink_to_lo(), + *m, + false, + static_mut.def_id, + ); } _ => {} } @@ -108,14 +123,26 @@ impl<'tcx> LateLintPass<'tcx> for StaticMutRefs { && let hir::PatKind::Binding(ba, _, _, _) = loc.pat.kind && let hir::ByRef::Yes(_, m) = ba.0 && let Some(init) = loc.init - && let Some(err_span) = path_is_static_mut(init, init.span) + && let Some(static_mut) = path_is_static_mut(init, init.span) { - emit_static_mut_refs(cx, err_span, err_span.shrink_to_lo(), m, false); + emit_static_mut_refs( + cx, + static_mut.err_span, + static_mut.err_span.shrink_to_lo(), + m, + false, + static_mut.def_id, + ); } } } -fn path_is_static_mut(mut expr: &hir::Expr<'_>, mut err_span: Span) -> Option { +struct StaticMutInfo { + err_span: Span, + def_id: DefId, +} + +fn path_is_static_mut(mut expr: &hir::Expr<'_>, mut err_span: Span) -> Option { if err_span.from_expansion() { err_span = expr.span; } @@ -126,11 +153,11 @@ fn path_is_static_mut(mut expr: &hir::Expr<'_>, mut err_span: Span) -> Option { @@ -155,9 +183,102 @@ fn emit_static_mut_refs( } }; + let (interior_mutability_help, interior_mutability_sugg) = + interior_mutability_suggestion(cx, def_id); + cx.emit_span_lint( STATIC_MUT_REFS, span, - RefOfMutStatic { span, sugg, shared_label, shared_note, mut_note }, + RefOfMutStatic { + span, + sugg, + shared_label, + shared_note, + mut_note, + interior_mutability_help, + interior_mutability_sugg, + }, ); } + +fn interior_mutability_suggestion( + cx: &LateContext<'_>, + def_id: DefId, +) -> (bool, Option) { + let static_ty = cx.tcx.type_of(def_id).skip_binder(); + let has_interior_mutability = !static_ty.is_freeze(cx.tcx, cx.typing_env()); + + if !has_interior_mutability { + return (false, None); + } + + let sugg = + static_mutability_span(cx, def_id).map(|span| StaticMutRefsInteriorMutabilitySugg { span }); + (true, sugg) +} + +fn static_mutability_span(cx: &LateContext<'_>, def_id: DefId) -> Option { + let hir_id = cx.tcx.hir_get_if_local(def_id)?; + let hir::Node::Item(item) = hir_id else { return None }; + let (mutability, ident) = match item.kind { + hir::ItemKind::Static(mutability, ident, _, _) => (mutability, ident), + _ => return None, + }; + if mutability != hir::Mutability::Mut { + return None; + } + + let vis_span = item.vis_span.find_ancestor_inside(item.span)?; + if !item.span.can_be_used_for_suggestions() || !vis_span.can_be_used_for_suggestions() { + return None; + } + + let header_span = vis_span.between(ident.span); + if !header_span.can_be_used_for_suggestions() { + return None; + } + + let source_map = cx.sess().source_map(); + let snippet = source_map.span_to_snippet(header_span).ok()?; + + let (_static_start, static_end) = find_word(&snippet, "static", 0)?; + let (mut_start, mut_end) = find_word(&snippet, "mut", static_end)?; + let mut_end = extend_trailing_space(&snippet, mut_end); + + Some( + header_span + .with_lo(header_span.lo() + BytePos(mut_start as u32)) + .with_hi(header_span.lo() + BytePos(mut_end as u32)), + ) +} + +fn find_word(snippet: &str, word: &str, start: usize) -> Option<(usize, usize)> { + let bytes = snippet.as_bytes(); + let word_bytes = word.as_bytes(); + let mut search = start; + while search <= snippet.len() { + let found = snippet[search..].find(word)?; + let idx = search + found; + let end = idx + word_bytes.len(); + let before_ok = idx == 0 || !is_ident_char(bytes[idx - 1]); + let after_ok = end >= bytes.len() || !is_ident_char(bytes[end]); + if before_ok && after_ok { + return Some((idx, end)); + } + search = end; + } + None +} + +fn is_ident_char(byte: u8) -> bool { + byte.is_ascii_alphanumeric() || byte == b'_' +} + +fn extend_trailing_space(snippet: &str, mut end: usize) -> usize { + if let Some(ch) = snippet[end..].chars().next() + && (ch == ' ' || ch == '\t') + { + end += ch.len_utf8(); + } + end +} diff --git a/tests/ui/lint/static-mut-refs-interior-mutability.fixed b/tests/ui/lint/static-mut-refs-interior-mutability.fixed new file mode 100644 index 0000000000000..d5b096119cce1 --- /dev/null +++ b/tests/ui/lint/static-mut-refs-interior-mutability.fixed @@ -0,0 +1,13 @@ +//@ edition:2024 +//@ run-rustfix + +#![allow(unused_unsafe)] + +use std::sync::Mutex; + +static STDINOUT_MUTEX: Mutex = Mutex::new(false); + +fn main() { + let _lock = unsafe { STDINOUT_MUTEX.lock().unwrap() }; + //~^ ERROR creating a shared reference to mutable static [static_mut_refs] +} diff --git a/tests/ui/lint/static-mut-refs-interior-mutability.rs b/tests/ui/lint/static-mut-refs-interior-mutability.rs new file mode 100644 index 0000000000000..f5d0fca5b45d7 --- /dev/null +++ b/tests/ui/lint/static-mut-refs-interior-mutability.rs @@ -0,0 +1,13 @@ +//@ edition:2024 +//@ run-rustfix + +#![allow(unused_unsafe)] + +use std::sync::Mutex; + +static mut STDINOUT_MUTEX: Mutex = Mutex::new(false); + +fn main() { + let _lock = unsafe { STDINOUT_MUTEX.lock().unwrap() }; + //~^ ERROR creating a shared reference to mutable static [static_mut_refs] +} diff --git a/tests/ui/lint/static-mut-refs-interior-mutability.stderr b/tests/ui/lint/static-mut-refs-interior-mutability.stderr new file mode 100644 index 0000000000000..5fe446cc27b26 --- /dev/null +++ b/tests/ui/lint/static-mut-refs-interior-mutability.stderr @@ -0,0 +1,18 @@ +error: creating a shared reference to mutable static + --> $DIR/static-mut-refs-interior-mutability.rs:11:26 + | +LL | let _lock = unsafe { STDINOUT_MUTEX.lock().unwrap() }; + | ^^^^^^^^^^^^^^^^^^^^^ shared reference to mutable static + | + = note: for more information, see + = note: shared references to mutable statics are dangerous; it's undefined behavior if the static is mutated or if a mutable reference is created for it while the shared reference lives + = help: use a type that relies on "interior mutability" instead; to read more on this, visit + = note: `#[deny(static_mut_refs)]` (part of `#[deny(rust_2024_compatibility)]`) on by default +help: this type already provides "interior mutability", so its binding doesn't need to be declared as mutable + | +LL - static mut STDINOUT_MUTEX: Mutex = Mutex::new(false); +LL + static STDINOUT_MUTEX: Mutex = Mutex::new(false); + | + +error: aborting due to 1 previous error + diff --git a/tests/ui/statics/static-lazy-init-with-arena-set.stderr b/tests/ui/statics/static-lazy-init-with-arena-set.stderr index 134129f814aa7..c1d6861718545 100644 --- a/tests/ui/statics/static-lazy-init-with-arena-set.stderr +++ b/tests/ui/statics/static-lazy-init-with-arena-set.stderr @@ -10,8 +10,14 @@ LL | | }); | |______________^ shared reference to mutable static | = note: shared references to mutable statics are dangerous; it's undefined behavior if the static is mutated or if a mutable reference is created for it while the shared reference lives + = help: use a type that relies on "interior mutability" instead; to read more on this, visit = note: for more information, see = note: `#[warn(static_mut_refs)]` (part of `#[warn(rust_2024_compatibility)]`) on by default +help: this type already provides "interior mutability", so its binding doesn't need to be declared as mutable + | +LL - static mut ONCE: Once = Once::new(); +LL + static ONCE: Once = Once::new(); + | warning: 1 warning emitted From cbaee5df1b1e2b1f2d8a1072af9765fd2cca847d Mon Sep 17 00:00:00 2001 From: Yuki Okushi Date: Fri, 6 Mar 2026 05:49:20 +0900 Subject: [PATCH 27/29] Tweak note condition --- compiler/rustc_lint/src/static_mut_refs.rs | 2 +- tests/ui/lint/static-mut-refs-interior-mutability.stderr | 3 +-- tests/ui/statics/static-lazy-init-with-arena-set.stderr | 1 - 3 files changed, 2 insertions(+), 4 deletions(-) diff --git a/compiler/rustc_lint/src/static_mut_refs.rs b/compiler/rustc_lint/src/static_mut_refs.rs index 64ab1f7535bff..1babe16b35a30 100644 --- a/compiler/rustc_lint/src/static_mut_refs.rs +++ b/compiler/rustc_lint/src/static_mut_refs.rs @@ -214,7 +214,7 @@ fn interior_mutability_suggestion( let sugg = static_mutability_span(cx, def_id).map(|span| StaticMutRefsInteriorMutabilitySugg { span }); - (true, sugg) + (sugg.is_none(), sugg) } fn static_mutability_span(cx: &LateContext<'_>, def_id: DefId) -> Option { diff --git a/tests/ui/lint/static-mut-refs-interior-mutability.stderr b/tests/ui/lint/static-mut-refs-interior-mutability.stderr index 5fe446cc27b26..29ab5a5c404de 100644 --- a/tests/ui/lint/static-mut-refs-interior-mutability.stderr +++ b/tests/ui/lint/static-mut-refs-interior-mutability.stderr @@ -4,9 +4,8 @@ error: creating a shared reference to mutable static LL | let _lock = unsafe { STDINOUT_MUTEX.lock().unwrap() }; | ^^^^^^^^^^^^^^^^^^^^^ shared reference to mutable static | - = note: for more information, see = note: shared references to mutable statics are dangerous; it's undefined behavior if the static is mutated or if a mutable reference is created for it while the shared reference lives - = help: use a type that relies on "interior mutability" instead; to read more on this, visit + = note: for more information, see = note: `#[deny(static_mut_refs)]` (part of `#[deny(rust_2024_compatibility)]`) on by default help: this type already provides "interior mutability", so its binding doesn't need to be declared as mutable | diff --git a/tests/ui/statics/static-lazy-init-with-arena-set.stderr b/tests/ui/statics/static-lazy-init-with-arena-set.stderr index c1d6861718545..43b244607885d 100644 --- a/tests/ui/statics/static-lazy-init-with-arena-set.stderr +++ b/tests/ui/statics/static-lazy-init-with-arena-set.stderr @@ -10,7 +10,6 @@ LL | | }); | |______________^ shared reference to mutable static | = note: shared references to mutable statics are dangerous; it's undefined behavior if the static is mutated or if a mutable reference is created for it while the shared reference lives - = help: use a type that relies on "interior mutability" instead; to read more on this, visit = note: for more information, see = note: `#[warn(static_mut_refs)]` (part of `#[warn(rust_2024_compatibility)]`) on by default help: this type already provides "interior mutability", so its binding doesn't need to be declared as mutable From 33d92f7b52500a1426637bdd19276b7ead1d6d19 Mon Sep 17 00:00:00 2001 From: Yuki Okushi Date: Sun, 17 May 2026 14:58:25 +0900 Subject: [PATCH 28/29] Add test for the case span is unavailable --- ...tic-mut-refs-interior-mutability-no-sugg.rs | 18 ++++++++++++++++++ ...mut-refs-interior-mutability-no-sugg.stderr | 13 +++++++++++++ 2 files changed, 31 insertions(+) create mode 100644 tests/ui/lint/static-mut-refs-interior-mutability-no-sugg.rs create mode 100644 tests/ui/lint/static-mut-refs-interior-mutability-no-sugg.stderr diff --git a/tests/ui/lint/static-mut-refs-interior-mutability-no-sugg.rs b/tests/ui/lint/static-mut-refs-interior-mutability-no-sugg.rs new file mode 100644 index 0000000000000..82c6b55a7623a --- /dev/null +++ b/tests/ui/lint/static-mut-refs-interior-mutability-no-sugg.rs @@ -0,0 +1,18 @@ +//@ edition:2024 +// Ensure that we don't make structured suggestions for interior mutability note +// when span is not available. + +use std::sync::Mutex; + +macro_rules! declare_mutex { + () => { + static mut MACRO_MUTEX: Mutex = Mutex::new(false); + }; +} + +declare_mutex!(); + +fn main() { + let _lock = unsafe { MACRO_MUTEX.lock().unwrap() }; + //~^ ERROR creating a shared reference to mutable static [static_mut_refs] +} diff --git a/tests/ui/lint/static-mut-refs-interior-mutability-no-sugg.stderr b/tests/ui/lint/static-mut-refs-interior-mutability-no-sugg.stderr new file mode 100644 index 0000000000000..5ce69e1a14d83 --- /dev/null +++ b/tests/ui/lint/static-mut-refs-interior-mutability-no-sugg.stderr @@ -0,0 +1,13 @@ +error: creating a shared reference to mutable static + --> $DIR/static-mut-refs-interior-mutability-no-sugg.rs:16:26 + | +LL | let _lock = unsafe { MACRO_MUTEX.lock().unwrap() }; + | ^^^^^^^^^^^^^^^^^^ shared reference to mutable static + | + = note: shared references to mutable statics are dangerous; it's undefined behavior if the static is mutated or if a mutable reference is created for it while the shared reference lives + = help: use a type that relies on "interior mutability" instead; to read more on this, visit + = note: for more information, see + = note: `#[deny(static_mut_refs)]` (part of `#[deny(rust_2024_compatibility)]`) on by default + +error: aborting due to 1 previous error + From ee8949e513313e384a1ab7657eb2dd8f71b09163 Mon Sep 17 00:00:00 2001 From: Yuki Okushi Date: Sun, 17 May 2026 15:03:24 +0900 Subject: [PATCH 29/29] Add FIXME for `interior_mutability_suggestion` --- compiler/rustc_lint/src/static_mut_refs.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/compiler/rustc_lint/src/static_mut_refs.rs b/compiler/rustc_lint/src/static_mut_refs.rs index 1babe16b35a30..67e83d0652c3d 100644 --- a/compiler/rustc_lint/src/static_mut_refs.rs +++ b/compiler/rustc_lint/src/static_mut_refs.rs @@ -201,6 +201,10 @@ fn emit_static_mut_refs( ); } +// FIXME: This builds suggestion spans by handcrafting from source text. +// Replace this with HIR-based handling once we can identify the `mut` token +// in the static declaration that way. +// Context: https://github.com/rust-lang/rust/pull/151362/changes#r3210767018 fn interior_mutability_suggestion( cx: &LateContext<'_>, def_id: DefId,