From 8ad054c8f7ac3757993fc15394cd69eb8241c938 Mon Sep 17 00:00:00 2001 From: Charlotte Ausel Date: Sat, 23 May 2026 17:45:57 +0200 Subject: [PATCH 1/4] allow repeated repr attributes --- compiler/rustc_passes/src/check_attr.rs | 24 +++++++++++++++++------- 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index f6765d604acb3..c98ecd1b4d339 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -1213,7 +1213,9 @@ impl<'tcx> CheckAttrVisitor<'tcx> { let mut is_explicit_rust = false; let mut is_c = false; let mut is_simd = false; - let mut is_transparent = false; + let mut transparents = 0; + let mut last_int_repr = None; + let mut int_reprs_different = false; for (repr, repr_span) in reprs { match repr { @@ -1284,7 +1286,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { } } ReprAttr::ReprTransparent => { - is_transparent = true; + transparents += 1; match target { Target::Struct | Target::Union | Target::Enum => continue, _ => { @@ -1295,8 +1297,14 @@ impl<'tcx> CheckAttrVisitor<'tcx> { } } } - ReprAttr::ReprInt(_) => { + ReprAttr::ReprInt(int_type) => { int_reprs += 1; + if let Some(previous_int) = last_int_repr + && previous_int != int_type + { + int_reprs_different = true; + } + last_int_repr = Some(int_type); if target != Target::Enum { self.dcx().emit_err(errors::AttrApplication::Enum { hint_span: *repr_span, @@ -1336,8 +1344,9 @@ impl<'tcx> CheckAttrVisitor<'tcx> { // This is not ideal, but tracking precisely which ones are at fault is a huge hassle. let hint_spans = reprs.iter().map(|(_, span)| *span); - // Error on repr(transparent, ). - if is_transparent && reprs.len() > 1 { + // Error if repr(transparent) is combined with any other repr apart from additional + // repr(transparent)s. + if transparents > 0 && reprs.len() != transparents { let hint_spans = hint_spans.clone().collect(); self.dcx().emit_err(errors::TransparentIncompatible { hint_spans, @@ -1346,7 +1355,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { } // Error on `#[repr(transparent)]` in combination with // `#[rustc_pass_indirectly_in_non_rustic_abis]` - if is_transparent + if transparents > 0 && let Some(&pass_indirectly_span) = find_attr!(attrs, RustcPassIndirectlyInNonRusticAbis(span) => span) { @@ -1358,9 +1367,10 @@ impl<'tcx> CheckAttrVisitor<'tcx> { if is_explicit_rust && (int_reprs > 0 || is_c || is_simd) { let hint_spans = hint_spans.clone().collect(); self.dcx().emit_err(errors::ReprConflicting { hint_spans }); + return; } // Warn on repr(u8, u16), repr(C, simd), and c-like-enum-repr(C, u8) - if (int_reprs > 1) + if (int_reprs > 1 && int_reprs_different) || (is_simd && is_c) || (int_reprs == 1 && is_c From 3241896b04250a7c47542fe6bdb0172c47b1857c Mon Sep 17 00:00:00 2001 From: Charlotte Ausel Date: Sat, 23 May 2026 22:19:37 +0200 Subject: [PATCH 2/4] add test for repeated repr attributes --- tests/ui/repr/repr-repeated-attrs.rs | 35 ++++++++++++++++++++++++ tests/ui/repr/repr-repeated-attrs.stderr | 9 ++++++ 2 files changed, 44 insertions(+) create mode 100644 tests/ui/repr/repr-repeated-attrs.rs create mode 100644 tests/ui/repr/repr-repeated-attrs.stderr diff --git a/tests/ui/repr/repr-repeated-attrs.rs b/tests/ui/repr/repr-repeated-attrs.rs new file mode 100644 index 0000000000000..501aa2f97a447 --- /dev/null +++ b/tests/ui/repr/repr-repeated-attrs.rs @@ -0,0 +1,35 @@ +// Tests that repeated attributes are allowed. + +#[repr(transparent, transparent)] +#[repr(transparent)] +struct SeveralTransparentReprs(*mut u8); + +#[repr(transparent)] +#[repr(transparent)] +struct MultilineOnly(*mut u8); + +#[repr(Rust, Rust)] +struct SeveralRustReprs(u8); + +#[repr(C, C)] +#[repr(C, C, C)] +struct SeveralC(u8); + +#[repr(u8, u8)] +enum SeveralPrimitiveRerprs { + Variant, +} + +#[repr(C, C, u8)] +#[repr(C, u8, u8)] +enum SeveralCAndPrims { + Variant(u8), +} + +#[repr(Rust, u8, u8)] +//~^ ERROR conflicting representation hints [E0566] +enum RustAndPrimDisallowed { + Variant(u8), +} + +fn main() {} diff --git a/tests/ui/repr/repr-repeated-attrs.stderr b/tests/ui/repr/repr-repeated-attrs.stderr new file mode 100644 index 0000000000000..cd43080669708 --- /dev/null +++ b/tests/ui/repr/repr-repeated-attrs.stderr @@ -0,0 +1,9 @@ +error[E0566]: conflicting representation hints + --> $DIR/repr-repeated-attrs.rs:29:8 + | +LL | #[repr(Rust, u8, u8)] + | ^^^^ ^^ ^^ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0566`. From 317d6d6ccf3a747087c2b5f26e59100a3048653d Mon Sep 17 00:00:00 2001 From: Charlotte Ausel Date: Sat, 23 May 2026 22:29:48 +0200 Subject: [PATCH 3/4] test conflicting primitive reprs error when repeated --- tests/ui/repr/repr-repeated-attrs.rs | 8 +++++++ tests/ui/repr/repr-repeated-attrs.stderr | 29 +++++++++++++++++++++++- 2 files changed, 36 insertions(+), 1 deletion(-) diff --git a/tests/ui/repr/repr-repeated-attrs.rs b/tests/ui/repr/repr-repeated-attrs.rs index 501aa2f97a447..0759f4b4d6e76 100644 --- a/tests/ui/repr/repr-repeated-attrs.rs +++ b/tests/ui/repr/repr-repeated-attrs.rs @@ -32,4 +32,12 @@ enum RustAndPrimDisallowed { Variant(u8), } +#[repr(u8, u8)] +//~^ ERROR conflicting representation hints [E0566] +//~| WARN: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! +#[repr(u16)] +enum ConflictingPrimReprs { + Variant, +} + fn main() {} diff --git a/tests/ui/repr/repr-repeated-attrs.stderr b/tests/ui/repr/repr-repeated-attrs.stderr index cd43080669708..8e54351e0091e 100644 --- a/tests/ui/repr/repr-repeated-attrs.stderr +++ b/tests/ui/repr/repr-repeated-attrs.stderr @@ -4,6 +4,33 @@ error[E0566]: conflicting representation hints LL | #[repr(Rust, u8, u8)] | ^^^^ ^^ ^^ -error: aborting due to 1 previous error +error[E0566]: conflicting representation hints + --> $DIR/repr-repeated-attrs.rs:35:8 + | +LL | #[repr(u8, u8)] + | ^^ ^^ +... +LL | #[repr(u16)] + | ^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #68585 + = note: `#[deny(conflicting_repr_hints)]` (part of `#[deny(future_incompatible)]`) on by default + +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0566`. +Future incompatibility report: Future breakage diagnostic: +error[E0566]: conflicting representation hints + --> $DIR/repr-repeated-attrs.rs:35:8 + | +LL | #[repr(u8, u8)] + | ^^ ^^ +... +LL | #[repr(u16)] + | ^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #68585 + = note: `#[deny(conflicting_repr_hints)]` (part of `#[deny(future_incompatible)]`) on by default + From 99b94b346004fdb8b32285bb2015e6294c9af873 Mon Sep 17 00:00:00 2001 From: Charlotte Ausel Date: Sun, 24 May 2026 22:21:52 +0200 Subject: [PATCH 4/4] review comments traviscross make sure to check that #[repr(C, u8)] still errors --- compiler/rustc_passes/src/check_attr.rs | 2 +- tests/ui/repr/repr-repeated-attrs.rs | 16 +++++++++ tests/ui/repr/repr-repeated-attrs.stderr | 42 +++++++++++++++++++++++- 3 files changed, 58 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index c98ecd1b4d339..b7e4a449d1ca2 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -1372,7 +1372,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { // Warn on repr(u8, u16), repr(C, simd), and c-like-enum-repr(C, u8) if (int_reprs > 1 && int_reprs_different) || (is_simd && is_c) - || (int_reprs == 1 + || (int_reprs >= 1 && is_c && item.is_some_and(|item| { if let ItemLike::Item(item) = item { is_c_like_enum(item) } else { false } diff --git a/tests/ui/repr/repr-repeated-attrs.rs b/tests/ui/repr/repr-repeated-attrs.rs index 0759f4b4d6e76..691b89e4b0688 100644 --- a/tests/ui/repr/repr-repeated-attrs.rs +++ b/tests/ui/repr/repr-repeated-attrs.rs @@ -40,4 +40,20 @@ enum ConflictingPrimReprs { Variant, } +#[repr(C, u8)] +//~^ ERROR conflicting representation hints [E0566] +//~| WARN: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! +enum CWithIntsCausesFCW1 { + A, + B, +} + +#[repr(C, C, u8, u8, u8)] +//~^ ERROR conflicting representation hints [E0566] +//~| WARN: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! +enum CWithIntsCausesFCW2 { + A, + B, +} + fn main() {} diff --git a/tests/ui/repr/repr-repeated-attrs.stderr b/tests/ui/repr/repr-repeated-attrs.stderr index 8e54351e0091e..711c5bbc8f9c8 100644 --- a/tests/ui/repr/repr-repeated-attrs.stderr +++ b/tests/ui/repr/repr-repeated-attrs.stderr @@ -17,7 +17,25 @@ LL | #[repr(u16)] = note: for more information, see issue #68585 = note: `#[deny(conflicting_repr_hints)]` (part of `#[deny(future_incompatible)]`) on by default -error: aborting due to 2 previous errors +error[E0566]: conflicting representation hints + --> $DIR/repr-repeated-attrs.rs:43:8 + | +LL | #[repr(C, u8)] + | ^ ^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #68585 + +error[E0566]: conflicting representation hints + --> $DIR/repr-repeated-attrs.rs:51:8 + | +LL | #[repr(C, C, u8, u8, u8)] + | ^ ^ ^^ ^^ ^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #68585 + +error: aborting due to 4 previous errors For more information about this error, try `rustc --explain E0566`. Future incompatibility report: Future breakage diagnostic: @@ -34,3 +52,25 @@ LL | #[repr(u16)] = note: for more information, see issue #68585 = note: `#[deny(conflicting_repr_hints)]` (part of `#[deny(future_incompatible)]`) on by default +Future breakage diagnostic: +error[E0566]: conflicting representation hints + --> $DIR/repr-repeated-attrs.rs:43:8 + | +LL | #[repr(C, u8)] + | ^ ^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #68585 + = note: `#[deny(conflicting_repr_hints)]` (part of `#[deny(future_incompatible)]`) on by default + +Future breakage diagnostic: +error[E0566]: conflicting representation hints + --> $DIR/repr-repeated-attrs.rs:51:8 + | +LL | #[repr(C, C, u8, u8, u8)] + | ^ ^ ^^ ^^ ^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #68585 + = note: `#[deny(conflicting_repr_hints)]` (part of `#[deny(future_incompatible)]`) on by default +