From efff18c213085cfa9f1a9192ddc7b762264e5827 Mon Sep 17 00:00:00 2001 From: Charlotte Ausel Date: Tue, 28 Jul 2026 11:15:21 +0100 Subject: [PATCH 01/15] lint against repeated repr attributes --- compiler/rustc_lint_defs/src/builtin.rs | 15 ++++++++ compiler/rustc_passes/src/check_attr.rs | 46 ++++++++++++++++++++++-- compiler/rustc_passes/src/diagnostics.rs | 5 +++ 3 files changed, 63 insertions(+), 3 deletions(-) diff --git a/compiler/rustc_lint_defs/src/builtin.rs b/compiler/rustc_lint_defs/src/builtin.rs index 2d9d7f337e004..32f51683cb1d3 100644 --- a/compiler/rustc_lint_defs/src/builtin.rs +++ b/compiler/rustc_lint_defs/src/builtin.rs @@ -274,6 +274,21 @@ declare_lint! { }; } +declare_lint! { + /// Todo: explain this. + /// + /// ### Example + /// + /// TODO + /// + /// ### Explanation + /// + /// TODO + pub REPEATED_REPRS, + Warn, + "repeated `#[repr(..)]` attributes were inconsistently rejected before", +} + declare_lint! { /// The `meta_variable_misuse` lint detects possible meta-variable misuse /// in macro definitions. diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index 572d9cd1da957..5b2dda065181a 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -41,7 +41,8 @@ use rustc_session::diagnostics::feature_err; use rustc_session::lint; use rustc_session::lint::builtin::{ CONFLICTING_REPR_HINTS, INVALID_DOC_ATTRIBUTES, MALFORMED_DIAGNOSTIC_ATTRIBUTES, - MALFORMED_DIAGNOSTIC_FORMAT_LITERALS, MISPLACED_DIAGNOSTIC_ATTRIBUTES, UNUSED_ATTRIBUTES, + MALFORMED_DIAGNOSTIC_FORMAT_LITERALS, MISPLACED_DIAGNOSTIC_ATTRIBUTES, REPEATED_REPRS, + UNUSED_ATTRIBUTES, }; use rustc_span::edition::Edition; use rustc_span::{DUMMY_SP, Ident, Span, Symbol, sym}; @@ -1223,21 +1224,46 @@ impl<'tcx> CheckAttrVisitor<'tcx> { let mut is_c = false; let mut is_simd = false; let mut is_transparent = false; + let mut is_align = false; + let mut is_packed = false; + let mut repeated_repr = false; for (repr, _repr_span) in reprs { match repr { ReprAttr::ReprRust => { + if is_explicit_rust { + repeated_repr = true + } is_explicit_rust = true; } ReprAttr::ReprC => { + if is_c { + repeated_repr = true; + } is_c = true; } - ReprAttr::ReprAlign(..) => {} - ReprAttr::ReprPacked(_) => {} + ReprAttr::ReprAlign(..) => { + if is_align { + repeated_repr = true; + } + is_align = true; + } + ReprAttr::ReprPacked(..) => { + if is_packed { + repeated_repr = true; + } + is_packed = true; + } ReprAttr::ReprSimd => { + if is_simd { + repeated_repr = true; + } is_simd = true; } ReprAttr::ReprTransparent => { + if is_transparent { + repeated_repr = true; + } is_transparent = true; } ReprAttr::ReprInt(_) => { @@ -1281,8 +1307,22 @@ impl<'tcx> CheckAttrVisitor<'tcx> { self.tcx.emit_node_span_lint( CONFLICTING_REPR_HINTS, hir_id, +<<<<<<< HEAD hint_spans.collect::>(), diagnostics::ReprConflictingLint, +======= + hint_spans.clone().collect::>(), + errors::ReprConflictingLint, +>>>>>>> d71bc523ed8 (lint against repeated repr attributes) + ); + } + + if repeated_repr { + self.tcx.emit_node_span_lint( + REPEATED_REPRS, + hir_id, + hint_spans.collect::>(), + errors::RepeatedRepr, ); } } diff --git a/compiler/rustc_passes/src/diagnostics.rs b/compiler/rustc_passes/src/diagnostics.rs index cdb14737ad90d..c06954931f9e3 100644 --- a/compiler/rustc_passes/src/diagnostics.rs +++ b/compiler/rustc_passes/src/diagnostics.rs @@ -653,6 +653,11 @@ pub(crate) struct TransparentIncompatible { pub target: String, } +#[derive(Diagnostic)] +#[diag("attribute is specified more than once")] +#[note("will become a hard error soon. todo: wording")] +pub(crate) struct RepeatedRepr; + #[derive(Diagnostic)] #[diag("deprecated attribute must be paired with either stable or unstable attribute", code = E0549)] pub(crate) struct DeprecatedAttribute { From 6e29a8f61dda56119ad3990d2ed6f99f563beb12 Mon Sep 17 00:00:00 2001 From: Charlotte Ausel Date: Tue, 28 Jul 2026 11:15:31 +0100 Subject: [PATCH 02/15] fmt --- compiler/rustc_passes/src/check_attr.rs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index 5b2dda065181a..92410c4eacce4 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -40,9 +40,8 @@ use rustc_session::config::CrateType; use rustc_session::diagnostics::feature_err; use rustc_session::lint; use rustc_session::lint::builtin::{ - CONFLICTING_REPR_HINTS, INVALID_DOC_ATTRIBUTES, MALFORMED_DIAGNOSTIC_ATTRIBUTES, - MALFORMED_DIAGNOSTIC_FORMAT_LITERALS, MISPLACED_DIAGNOSTIC_ATTRIBUTES, REPEATED_REPRS, - UNUSED_ATTRIBUTES, + CONFLICTING_REPR_HINTS, INVALID_DOC_ATTRIBUTES, MALFORMED_DIAGNOSTIC_FORMAT_LITERALS, + MISPLACED_DIAGNOSTIC_ATTRIBUTES, REPEATED_REPRS, UNUSED_ATTRIBUTES, }; use rustc_span::edition::Edition; use rustc_span::{DUMMY_SP, Ident, Span, Symbol, sym}; From 9d69a04a4a49ff8cb3bc2394900f020dac5880be Mon Sep 17 00:00:00 2001 From: Charlotte Ausel Date: Tue, 28 Jul 2026 11:15:36 +0100 Subject: [PATCH 03/15] bring back warns for repeated reprs, update tests had to update several tests which used repeated aligns and packeds. they now produce both a warning and an error where appropriate (e.g. when using conflicting packeds) which i think is correct. --- compiler/rustc_passes/src/check_attr.rs | 5 +- tests/ui/attributes/issue-100631.rs | 1 + tests/ui/attributes/issue-100631.stderr | 16 ++++- tests/ui/lint/unused/unused-attr-duplicate.rs | 3 +- .../lint/unused/unused-attr-duplicate.stderr | 62 +++++++++++++------ tests/ui/repr/conflicting-repr-hints.rs | 6 +- tests/ui/repr/conflicting-repr-hints.stderr | 29 ++++++++- tests/ui/structs-enums/align-enum.rs | 2 +- tests/ui/structs-enums/align-enum.stderr | 15 +++++ tests/ui/structs-enums/align-struct.rs | 2 +- tests/ui/structs-enums/align-struct.stderr | 15 +++++ 11 files changed, 124 insertions(+), 32 deletions(-) create mode 100644 tests/ui/structs-enums/align-enum.stderr create mode 100644 tests/ui/structs-enums/align-struct.stderr diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index 92410c4eacce4..35be2043691bb 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -1260,9 +1260,8 @@ impl<'tcx> CheckAttrVisitor<'tcx> { is_simd = true; } ReprAttr::ReprTransparent => { - if is_transparent { - repeated_repr = true; - } + // No need to check for repeated transparent because that is already checked + // hen checking for any other attribute together with transparent. is_transparent = true; } ReprAttr::ReprInt(_) => { diff --git a/tests/ui/attributes/issue-100631.rs b/tests/ui/attributes/issue-100631.rs index 0fefcf83fd516..0f0eb235aae78 100644 --- a/tests/ui/attributes/issue-100631.rs +++ b/tests/ui/attributes/issue-100631.rs @@ -2,6 +2,7 @@ // can reasonably deal with multiple attributes. // `repr` will use `TyCtxt::get_attrs` since it's `DuplicatesOk`. #[repr(C)] //~ ERROR: unsupported representation for zero-variant enum [E0084] +//~^ WARN attribute is specified more than once #[repr(C)] enum Foo {} diff --git a/tests/ui/attributes/issue-100631.stderr b/tests/ui/attributes/issue-100631.stderr index b2bd0a9632513..8f9cc9defcde0 100644 --- a/tests/ui/attributes/issue-100631.stderr +++ b/tests/ui/attributes/issue-100631.stderr @@ -1,12 +1,24 @@ -error[E0084]: unsupported representation for zero-variant enum +warning: attribute is specified more than once --> $DIR/issue-100631.rs:4:8 | LL | #[repr(C)] | ^ +LL | LL | #[repr(C)] + | ^ + | + = note: will become a hard error soon. todo: wording + = note: `#[warn(repeated_reprs)]` on by default + +error[E0084]: unsupported representation for zero-variant enum + --> $DIR/issue-100631.rs:4:8 + | +LL | #[repr(C)] + | ^ +... LL | enum Foo {} | -------- zero-variant enum -error: aborting due to 1 previous error +error: aborting due to 1 previous error; 1 warning emitted For more information about this error, try `rustc --explain E0084`. diff --git a/tests/ui/lint/unused/unused-attr-duplicate.rs b/tests/ui/lint/unused/unused-attr-duplicate.rs index 54c040f4bcac4..6a1dfd702cf06 100644 --- a/tests/ui/lint/unused/unused-attr-duplicate.rs +++ b/tests/ui/lint/unused/unused-attr-duplicate.rs @@ -64,8 +64,7 @@ fn t1() {} #[must_use = "some message"] //~^ ERROR unused attribute //~| WARN this was previously accepted -// No warnings for #[repr], would require more logic. -#[repr(C)] +#[repr(C)] //~ WARN attribute is specified more than once #[repr(C)] #[non_exhaustive] #[non_exhaustive] //~ ERROR unused attribute diff --git a/tests/ui/lint/unused/unused-attr-duplicate.stderr b/tests/ui/lint/unused/unused-attr-duplicate.stderr index 3e4cb99a09e34..10a674cc03325 100644 --- a/tests/ui/lint/unused/unused-attr-duplicate.stderr +++ b/tests/ui/lint/unused/unused-attr-duplicate.stderr @@ -16,6 +16,17 @@ note: the lint level is defined here LL | #![deny(unused_attributes)] | ^^^^^^^^^^^^^^^^^ +warning: attribute is specified more than once + --> $DIR/unused-attr-duplicate.rs:67:8 + | +LL | #[repr(C)] + | ^ +LL | #[repr(C)] + | ^ + | + = note: will become a hard error soon. todo: wording + = note: `#[warn(repeated_reprs)]` on by default + error: unused attribute --> $DIR/unused-attr-duplicate.rs:14:1 | @@ -193,111 +204,124 @@ LL | #[must_use] = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! error: unused attribute - --> $DIR/unused-attr-duplicate.rs:71:1 + --> $DIR/unused-attr-duplicate.rs:70:1 | LL | #[non_exhaustive] | ^^^^^^^^^^^^^^^^^ help: remove this attribute | note: attribute also specified here - --> $DIR/unused-attr-duplicate.rs:70:1 + --> $DIR/unused-attr-duplicate.rs:69:1 | LL | #[non_exhaustive] | ^^^^^^^^^^^^^^^^^ error: unused attribute - --> $DIR/unused-attr-duplicate.rs:77:1 + --> $DIR/unused-attr-duplicate.rs:76:1 | LL | #[automatically_derived] | ^^^^^^^^^^^^^^^^^^^^^^^^ help: remove this attribute | note: attribute also specified here - --> $DIR/unused-attr-duplicate.rs:76:1 + --> $DIR/unused-attr-duplicate.rs:75:1 | LL | #[automatically_derived] | ^^^^^^^^^^^^^^^^^^^^^^^^ error: unused attribute - --> $DIR/unused-attr-duplicate.rs:81:1 + --> $DIR/unused-attr-duplicate.rs:80:1 | LL | #[inline(never)] | ^^^^^^^^^^^^^^^^ help: remove this attribute | note: attribute also specified here - --> $DIR/unused-attr-duplicate.rs:80:1 + --> $DIR/unused-attr-duplicate.rs:79:1 | LL | #[inline(always)] | ^^^^^^^^^^^^^^^^^ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! error: unused attribute - --> $DIR/unused-attr-duplicate.rs:84:1 + --> $DIR/unused-attr-duplicate.rs:83:1 | LL | #[cold] | ^^^^^^^ help: remove this attribute | note: attribute also specified here - --> $DIR/unused-attr-duplicate.rs:83:1 + --> $DIR/unused-attr-duplicate.rs:82:1 | LL | #[cold] | ^^^^^^^ error: unused attribute - --> $DIR/unused-attr-duplicate.rs:86:1 + --> $DIR/unused-attr-duplicate.rs:85:1 | LL | #[track_caller] | ^^^^^^^^^^^^^^^ help: remove this attribute | note: attribute also specified here - --> $DIR/unused-attr-duplicate.rs:85:1 + --> $DIR/unused-attr-duplicate.rs:84:1 | LL | #[track_caller] | ^^^^^^^^^^^^^^^ error: unused attribute - --> $DIR/unused-attr-duplicate.rs:100:1 + --> $DIR/unused-attr-duplicate.rs:93:5 + | +LL | #[link_name = "rust_dbg_extern_identity_u32"] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove this attribute + | +note: attribute also specified here + --> $DIR/unused-attr-duplicate.rs:92:5 + | +LL | #[link_name = "this_does_not_exist"] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + +error: unused attribute + --> $DIR/unused-attr-duplicate.rs:99:1 | LL | #[export_name = "exported_symbol_name2"] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove this attribute | note: attribute also specified here - --> $DIR/unused-attr-duplicate.rs:99:1 + --> $DIR/unused-attr-duplicate.rs:98:1 | LL | #[export_name = "exported_symbol_name"] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! error: unused attribute - --> $DIR/unused-attr-duplicate.rs:105:1 + --> $DIR/unused-attr-duplicate.rs:104:1 | LL | #[no_mangle] | ^^^^^^^^^^^^ help: remove this attribute | note: attribute also specified here - --> $DIR/unused-attr-duplicate.rs:104:1 + --> $DIR/unused-attr-duplicate.rs:103:1 | LL | #[no_mangle] | ^^^^^^^^^^^^ error: unused attribute - --> $DIR/unused-attr-duplicate.rs:109:1 + --> $DIR/unused-attr-duplicate.rs:108:1 | LL | #[used] | ^^^^^^^ help: remove this attribute | note: attribute also specified here - --> $DIR/unused-attr-duplicate.rs:108:1 + --> $DIR/unused-attr-duplicate.rs:107:1 | LL | #[used] | ^^^^^^^ error: unused attribute - --> $DIR/unused-attr-duplicate.rs:113:1 + --> $DIR/unused-attr-duplicate.rs:112:1 | LL | #[link_section = "__DATA,__mod_init_func"] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove this attribute | note: attribute also specified here - --> $DIR/unused-attr-duplicate.rs:112:1 + --> $DIR/unused-attr-duplicate.rs:111:1 | LL | #[link_section = "__TEXT,__text"] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -316,5 +340,5 @@ LL | #[link_name = "this_does_not_exist"] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! -error: aborting due to 25 previous errors +error: aborting due to 25 previous errors; 1 warning emitted diff --git a/tests/ui/repr/conflicting-repr-hints.rs b/tests/ui/repr/conflicting-repr-hints.rs index ed82b6a742c8d..0ddcabef67972 100644 --- a/tests/ui/repr/conflicting-repr-hints.rs +++ b/tests/ui/repr/conflicting-repr-hints.rs @@ -36,14 +36,14 @@ struct G(i32); //~ ERROR type has conflicting packed and align representation hi #[repr(packed)] struct H(i32); //~ ERROR type has conflicting packed and align representation hints -#[repr(packed, packed(2))] +#[repr(packed, packed(2))] //~ WARN attribute is specified more than once struct I(i32); //~ ERROR type has conflicting packed representation hints -#[repr(packed(2))] +#[repr(packed(2))] //~ WARN attribute is specified more than once #[repr(packed)] struct J(i32); //~ ERROR type has conflicting packed representation hints -#[repr(packed, packed(1))] +#[repr(packed, packed(1))] //~ WARN attribute is specified more than once struct K(i32); #[repr(packed, align(8))] diff --git a/tests/ui/repr/conflicting-repr-hints.stderr b/tests/ui/repr/conflicting-repr-hints.stderr index 4da3d454e037d..77ff01a22caa5 100644 --- a/tests/ui/repr/conflicting-repr-hints.stderr +++ b/tests/ui/repr/conflicting-repr-hints.stderr @@ -17,6 +17,33 @@ LL | #[repr(u32, u64)] = 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 +warning: attribute is specified more than once + --> $DIR/conflicting-repr-hints.rs:39:8 + | +LL | #[repr(packed, packed(2))] + | ^^^^^^ ^^^^^^^^^ + | + = note: will become a hard error soon. todo: wording + = note: `#[warn(repeated_reprs)]` on by default + +warning: attribute is specified more than once + --> $DIR/conflicting-repr-hints.rs:42:8 + | +LL | #[repr(packed(2))] + | ^^^^^^^^^ +LL | #[repr(packed)] + | ^^^^^^ + | + = note: will become a hard error soon. todo: wording + +warning: attribute is specified more than once + --> $DIR/conflicting-repr-hints.rs:46:8 + | +LL | #[repr(packed, packed(1))] + | ^^^^^^ ^^^^^^^^^ + | + = note: will become a hard error soon. todo: wording + error[E0587]: type has conflicting packed and align representation hints --> $DIR/conflicting-repr-hints.rs:29:1 | @@ -77,7 +104,7 @@ error[E0587]: type has conflicting packed and align representation hints LL | pub union U { | ^^^^^^^^^^^ -error: aborting due to 12 previous errors +error: aborting due to 12 previous errors; 3 warnings emitted Some errors have detailed explanations: E0566, E0587, E0634. For more information about an error, try `rustc --explain E0566`. diff --git a/tests/ui/structs-enums/align-enum.rs b/tests/ui/structs-enums/align-enum.rs index ff80a19211cda..c9652ac84db47 100644 --- a/tests/ui/structs-enums/align-enum.rs +++ b/tests/ui/structs-enums/align-enum.rs @@ -11,7 +11,7 @@ enum Align16 { } // Raise alignment by maximum -#[repr(align(1), align(16))] +#[repr(align(1), align(16))] //~ WARN attribute is specified more than once #[repr(align(32))] #[repr(align(4))] enum Align32 { diff --git a/tests/ui/structs-enums/align-enum.stderr b/tests/ui/structs-enums/align-enum.stderr new file mode 100644 index 0000000000000..25fec15cf2a12 --- /dev/null +++ b/tests/ui/structs-enums/align-enum.stderr @@ -0,0 +1,15 @@ +warning: attribute is specified more than once + --> $DIR/align-enum.rs:14:8 + | +LL | #[repr(align(1), align(16))] + | ^^^^^^^^ ^^^^^^^^^ +LL | #[repr(align(32))] + | ^^^^^^^^^ +LL | #[repr(align(4))] + | ^^^^^^^^ + | + = note: will become a hard error soon. todo: wording + = note: `#[warn(repeated_reprs)]` on by default + +warning: 1 warning emitted + diff --git a/tests/ui/structs-enums/align-struct.rs b/tests/ui/structs-enums/align-struct.rs index 3d8dad6e324e3..1b6d4dfa49755 100644 --- a/tests/ui/structs-enums/align-struct.rs +++ b/tests/ui/structs-enums/align-struct.rs @@ -13,7 +13,7 @@ struct Align16(i32); struct Align1(i32); // Multiple attributes take the max -#[repr(align(4))] +#[repr(align(4))] //~ WARN attribute is specified more than once #[repr(align(16))] #[repr(align(8))] struct AlignMany(i32); diff --git a/tests/ui/structs-enums/align-struct.stderr b/tests/ui/structs-enums/align-struct.stderr new file mode 100644 index 0000000000000..6aaafc8c7753d --- /dev/null +++ b/tests/ui/structs-enums/align-struct.stderr @@ -0,0 +1,15 @@ +warning: attribute is specified more than once + --> $DIR/align-struct.rs:16:8 + | +LL | #[repr(align(4))] + | ^^^^^^^^ +LL | #[repr(align(16))] + | ^^^^^^^^^ +LL | #[repr(align(8))] + | ^^^^^^^^ + | + = note: will become a hard error soon. todo: wording + = note: `#[warn(repeated_reprs)]` on by default + +warning: 1 warning emitted + From 502bfbd67d800bd9f7d8de3eac1361cf567ca4b6 Mon Sep 17 00:00:00 2001 From: Charlotte Ausel Date: Tue, 28 Jul 2026 11:15:42 +0100 Subject: [PATCH 04/15] typo --- compiler/rustc_passes/src/check_attr.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index 35be2043691bb..23e020787addf 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -1261,7 +1261,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { } ReprAttr::ReprTransparent => { // No need to check for repeated transparent because that is already checked - // hen checking for any other attribute together with transparent. + // when checking for any other attribute together with transparent. is_transparent = true; } ReprAttr::ReprInt(_) => { From 3e27ca2197e2c5d9e1cc3c3f5056edd16d281e1a Mon Sep 17 00:00:00 2001 From: Charlotte Ausel Date: Tue, 28 Jul 2026 11:15:47 +0100 Subject: [PATCH 05/15] another typo --- compiler/rustc_passes/src/check_attr.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index 23e020787addf..5afb1af065acd 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -1231,7 +1231,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { match repr { ReprAttr::ReprRust => { if is_explicit_rust { - repeated_repr = true + repeated_repr = true; } is_explicit_rust = true; } From 55058fe4a08cfeb7d0cc91364847c3486ce7373c Mon Sep 17 00:00:00 2001 From: Charlotte Ausel Date: Tue, 28 Jul 2026 11:15:52 +0100 Subject: [PATCH 06/15] finish rewording lint messages --- compiler/rustc_lint_defs/src/builtin.rs | 15 +++++++++++---- compiler/rustc_passes/src/diagnostics.rs | 4 ++-- tests/ui/attributes/issue-100631.rs | 2 +- tests/ui/attributes/issue-100631.stderr | 4 ++-- tests/ui/lint/unused/unused-attr-duplicate.rs | 2 +- tests/ui/lint/unused/unused-attr-duplicate.stderr | 4 ++-- tests/ui/repr/conflicting-repr-hints.rs | 4 ++-- tests/ui/repr/conflicting-repr-hints.stderr | 12 ++++++------ tests/ui/structs-enums/align-enum.rs | 2 +- tests/ui/structs-enums/align-enum.stderr | 4 ++-- tests/ui/structs-enums/align-struct.rs | 2 +- tests/ui/structs-enums/align-struct.stderr | 4 ++-- 12 files changed, 33 insertions(+), 26 deletions(-) diff --git a/compiler/rustc_lint_defs/src/builtin.rs b/compiler/rustc_lint_defs/src/builtin.rs index 32f51683cb1d3..78720145c917e 100644 --- a/compiler/rustc_lint_defs/src/builtin.rs +++ b/compiler/rustc_lint_defs/src/builtin.rs @@ -275,18 +275,25 @@ declare_lint! { } declare_lint! { - /// Todo: explain this. + /// The `repeated_reprs` lint detects when the same representation is + /// specified more than once in a `#[repr(..)]` attribute. /// /// ### Example /// - /// TODO + /// ```rust + /// #[repr(C)] + /// #[repr(C)] + /// enum Foo { A } + /// ``` /// /// ### Explanation /// - /// TODO + /// While some representations may be specified more than once, the compiler + /// will reject repeated uses of some others. For consistency, prefer to + /// only specify the representation once. pub REPEATED_REPRS, Warn, - "repeated `#[repr(..)]` attributes were inconsistently rejected before", + "detects repeated representations in `#[repr(..)]` attributes", } declare_lint! { diff --git a/compiler/rustc_passes/src/diagnostics.rs b/compiler/rustc_passes/src/diagnostics.rs index c06954931f9e3..111c223122919 100644 --- a/compiler/rustc_passes/src/diagnostics.rs +++ b/compiler/rustc_passes/src/diagnostics.rs @@ -654,8 +654,8 @@ pub(crate) struct TransparentIncompatible { } #[derive(Diagnostic)] -#[diag("attribute is specified more than once")] -#[note("will become a hard error soon. todo: wording")] +#[diag("representation attribute is specified more than once")] +#[note("for consistency, only specify the representation once")] pub(crate) struct RepeatedRepr; #[derive(Diagnostic)] diff --git a/tests/ui/attributes/issue-100631.rs b/tests/ui/attributes/issue-100631.rs index 0f0eb235aae78..d496231c73026 100644 --- a/tests/ui/attributes/issue-100631.rs +++ b/tests/ui/attributes/issue-100631.rs @@ -2,7 +2,7 @@ // can reasonably deal with multiple attributes. // `repr` will use `TyCtxt::get_attrs` since it's `DuplicatesOk`. #[repr(C)] //~ ERROR: unsupported representation for zero-variant enum [E0084] -//~^ WARN attribute is specified more than once +//~^ WARN representation attribute is specified more than once #[repr(C)] enum Foo {} diff --git a/tests/ui/attributes/issue-100631.stderr b/tests/ui/attributes/issue-100631.stderr index 8f9cc9defcde0..66e08738eb02c 100644 --- a/tests/ui/attributes/issue-100631.stderr +++ b/tests/ui/attributes/issue-100631.stderr @@ -1,4 +1,4 @@ -warning: attribute is specified more than once +warning: representation attribute is specified more than once --> $DIR/issue-100631.rs:4:8 | LL | #[repr(C)] @@ -7,7 +7,7 @@ LL | LL | #[repr(C)] | ^ | - = note: will become a hard error soon. todo: wording + = note: for consistency, only specify the representation once = note: `#[warn(repeated_reprs)]` on by default error[E0084]: unsupported representation for zero-variant enum diff --git a/tests/ui/lint/unused/unused-attr-duplicate.rs b/tests/ui/lint/unused/unused-attr-duplicate.rs index 6a1dfd702cf06..348c9590e8b27 100644 --- a/tests/ui/lint/unused/unused-attr-duplicate.rs +++ b/tests/ui/lint/unused/unused-attr-duplicate.rs @@ -64,7 +64,7 @@ fn t1() {} #[must_use = "some message"] //~^ ERROR unused attribute //~| WARN this was previously accepted -#[repr(C)] //~ WARN attribute is specified more than once +#[repr(C)] //~ WARN representation attribute is specified more than once #[repr(C)] #[non_exhaustive] #[non_exhaustive] //~ ERROR unused attribute diff --git a/tests/ui/lint/unused/unused-attr-duplicate.stderr b/tests/ui/lint/unused/unused-attr-duplicate.stderr index 10a674cc03325..93f7a4791188f 100644 --- a/tests/ui/lint/unused/unused-attr-duplicate.stderr +++ b/tests/ui/lint/unused/unused-attr-duplicate.stderr @@ -16,7 +16,7 @@ note: the lint level is defined here LL | #![deny(unused_attributes)] | ^^^^^^^^^^^^^^^^^ -warning: attribute is specified more than once +warning: representation attribute is specified more than once --> $DIR/unused-attr-duplicate.rs:67:8 | LL | #[repr(C)] @@ -24,7 +24,7 @@ LL | #[repr(C)] LL | #[repr(C)] | ^ | - = note: will become a hard error soon. todo: wording + = note: for consistency, only specify the representation once = note: `#[warn(repeated_reprs)]` on by default error: unused attribute diff --git a/tests/ui/repr/conflicting-repr-hints.rs b/tests/ui/repr/conflicting-repr-hints.rs index 0ddcabef67972..032f2b2e6c608 100644 --- a/tests/ui/repr/conflicting-repr-hints.rs +++ b/tests/ui/repr/conflicting-repr-hints.rs @@ -36,10 +36,10 @@ struct G(i32); //~ ERROR type has conflicting packed and align representation hi #[repr(packed)] struct H(i32); //~ ERROR type has conflicting packed and align representation hints -#[repr(packed, packed(2))] //~ WARN attribute is specified more than once +#[repr(packed, packed(2))] //~ WARN representation attribute is specified more than once struct I(i32); //~ ERROR type has conflicting packed representation hints -#[repr(packed(2))] //~ WARN attribute is specified more than once +#[repr(packed(2))] //~ WARN representation attribute is specified more than once #[repr(packed)] struct J(i32); //~ ERROR type has conflicting packed representation hints diff --git a/tests/ui/repr/conflicting-repr-hints.stderr b/tests/ui/repr/conflicting-repr-hints.stderr index 77ff01a22caa5..a99546b754785 100644 --- a/tests/ui/repr/conflicting-repr-hints.stderr +++ b/tests/ui/repr/conflicting-repr-hints.stderr @@ -17,16 +17,16 @@ LL | #[repr(u32, u64)] = 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 -warning: attribute is specified more than once +warning: representation attribute is specified more than once --> $DIR/conflicting-repr-hints.rs:39:8 | LL | #[repr(packed, packed(2))] | ^^^^^^ ^^^^^^^^^ | - = note: will become a hard error soon. todo: wording + = note: for consistency, only specify the representation once = note: `#[warn(repeated_reprs)]` on by default -warning: attribute is specified more than once +warning: representation attribute is specified more than once --> $DIR/conflicting-repr-hints.rs:42:8 | LL | #[repr(packed(2))] @@ -34,15 +34,15 @@ LL | #[repr(packed(2))] LL | #[repr(packed)] | ^^^^^^ | - = note: will become a hard error soon. todo: wording + = note: for consistency, only specify the representation once -warning: attribute is specified more than once +warning: representation attribute is specified more than once --> $DIR/conflicting-repr-hints.rs:46:8 | LL | #[repr(packed, packed(1))] | ^^^^^^ ^^^^^^^^^ | - = note: will become a hard error soon. todo: wording + = note: for consistency, only specify the representation once error[E0587]: type has conflicting packed and align representation hints --> $DIR/conflicting-repr-hints.rs:29:1 diff --git a/tests/ui/structs-enums/align-enum.rs b/tests/ui/structs-enums/align-enum.rs index c9652ac84db47..a635af7352afe 100644 --- a/tests/ui/structs-enums/align-enum.rs +++ b/tests/ui/structs-enums/align-enum.rs @@ -11,7 +11,7 @@ enum Align16 { } // Raise alignment by maximum -#[repr(align(1), align(16))] //~ WARN attribute is specified more than once +#[repr(align(1), align(16))] //~ WARN representation attribute is specified more than once #[repr(align(32))] #[repr(align(4))] enum Align32 { diff --git a/tests/ui/structs-enums/align-enum.stderr b/tests/ui/structs-enums/align-enum.stderr index 25fec15cf2a12..9b8c9842f81df 100644 --- a/tests/ui/structs-enums/align-enum.stderr +++ b/tests/ui/structs-enums/align-enum.stderr @@ -1,4 +1,4 @@ -warning: attribute is specified more than once +warning: representation attribute is specified more than once --> $DIR/align-enum.rs:14:8 | LL | #[repr(align(1), align(16))] @@ -8,7 +8,7 @@ LL | #[repr(align(32))] LL | #[repr(align(4))] | ^^^^^^^^ | - = note: will become a hard error soon. todo: wording + = note: for consistency, only specify the representation once = note: `#[warn(repeated_reprs)]` on by default warning: 1 warning emitted diff --git a/tests/ui/structs-enums/align-struct.rs b/tests/ui/structs-enums/align-struct.rs index 1b6d4dfa49755..2d1ebf6731a62 100644 --- a/tests/ui/structs-enums/align-struct.rs +++ b/tests/ui/structs-enums/align-struct.rs @@ -13,7 +13,7 @@ struct Align16(i32); struct Align1(i32); // Multiple attributes take the max -#[repr(align(4))] //~ WARN attribute is specified more than once +#[repr(align(4))] //~ WARN representation attribute is specified more than once #[repr(align(16))] #[repr(align(8))] struct AlignMany(i32); diff --git a/tests/ui/structs-enums/align-struct.stderr b/tests/ui/structs-enums/align-struct.stderr index 6aaafc8c7753d..f54e9cd14cd8b 100644 --- a/tests/ui/structs-enums/align-struct.stderr +++ b/tests/ui/structs-enums/align-struct.stderr @@ -1,4 +1,4 @@ -warning: attribute is specified more than once +warning: representation attribute is specified more than once --> $DIR/align-struct.rs:16:8 | LL | #[repr(align(4))] @@ -8,7 +8,7 @@ LL | #[repr(align(16))] LL | #[repr(align(8))] | ^^^^^^^^ | - = note: will become a hard error soon. todo: wording + = note: for consistency, only specify the representation once = note: `#[warn(repeated_reprs)]` on by default warning: 1 warning emitted From 7e4c5c9551fddf5226361bc42581ce8626f998e3 Mon Sep 17 00:00:00 2001 From: Charlotte Ausel Date: Tue, 28 Jul 2026 11:15:59 +0100 Subject: [PATCH 07/15] add another test --- tests/ui/repr/repr-repeated-attrs.rs | 68 ++++++++ tests/ui/repr/repr-repeated-attrs.stderr | 200 +++++++++++++++++++++++ 2 files changed, 268 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..a6dd3fb6e8b15 --- /dev/null +++ b/tests/ui/repr/repr-repeated-attrs.rs @@ -0,0 +1,68 @@ +// Tests to ensure we warn on repeated `#[repr(..)]` attributes. + +#[repr(transparent, transparent)] +//~^ ERROR transparent struct cannot have other repr hints +#[repr(transparent)] +struct SeveralTransparentReprs(*mut u8); + +#[repr(transparent)] +//~^ ERROR transparent struct cannot have other repr hints +#[repr(transparent)] +struct MultilineOnly(*mut u8); + +#[repr(Rust, Rust)] +//~^ WARN representation attribute is specified more than once +struct SeveralRustReprs(u8); + +#[repr(C, C)] +//~^ WARN representation attribute is specified more than once +#[repr(C, C, C)] +struct SeveralC(u8); + +#[repr(u8, u8)] +//~^ ERROR conflicting representation hints +//~| WARN this was previously accepted +enum SeveralPrimitiveRerprs { + Variant, +} + +#[repr(C, C, u8)] //~ WARN representation attribute is specified more than once +//~^ ERROR conflicting representation hints +//~| WARN this was previously accepted +#[repr(C, u8, u8)] +enum SeveralCAndPrims { + Variant(u8), +} + +#[repr(Rust, u8, u8)] +//~^ ERROR conflicting representation hints +//~^^ ERROR conflicting representation hints +//~| WARN this was previously accepted +enum RustAndPrimDisallowed { + Variant(u8), +} + +#[repr(u8, u8)] //~ ERROR conflicting representation hints +//~^ WARN this was previously accepted +#[repr(u16)] +enum ConflictingPrimReprs { + Variant, +} + +#[repr(C, u8)] +//~^ ERROR conflicting representation hints +//~| WARN this was previously accepted +enum CWithIntsCausesFCW1 { + A, + B, +} + +#[repr(C, C, u8, u8, u8)] //~ WARN representation attribute is specified more than once +//~^ ERROR conflicting representation hints +//~| WARN this was previously accepted +enum CWithIntsCausesFCW2 { + A, + B, +} + +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..72c312a13ea11 --- /dev/null +++ b/tests/ui/repr/repr-repeated-attrs.stderr @@ -0,0 +1,200 @@ +error[E0692]: transparent struct cannot have other repr hints + --> $DIR/repr-repeated-attrs.rs:3:8 + | +LL | #[repr(transparent, transparent)] + | ^^^^^^^^^^^ ^^^^^^^^^^^ +LL | +LL | #[repr(transparent)] + | ^^^^^^^^^^^ + +error[E0692]: transparent struct cannot have other repr hints + --> $DIR/repr-repeated-attrs.rs:8:8 + | +LL | #[repr(transparent)] + | ^^^^^^^^^^^ +LL | +LL | #[repr(transparent)] + | ^^^^^^^^^^^ + +warning: representation attribute is specified more than once + --> $DIR/repr-repeated-attrs.rs:13:8 + | +LL | #[repr(Rust, Rust)] + | ^^^^ ^^^^ + | + = note: for consistency, only specify the representation once + = note: `#[warn(repeated_reprs)]` on by default + +warning: representation attribute is specified more than once + --> $DIR/repr-repeated-attrs.rs:17:8 + | +LL | #[repr(C, C)] + | ^ ^ +LL | +LL | #[repr(C, C, C)] + | ^ ^ ^ + | + = note: for consistency, only specify the representation once + +error[E0566]: conflicting representation hints + --> $DIR/repr-repeated-attrs.rs:22:8 + | +LL | #[repr(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 + +error[E0566]: conflicting representation hints + --> $DIR/repr-repeated-attrs.rs:29:8 + | +LL | #[repr(C, C, u8)] + | ^ ^ ^^ +... +LL | #[repr(C, 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 + +warning: representation attribute is specified more than once + --> $DIR/repr-repeated-attrs.rs:29:8 + | +LL | #[repr(C, C, u8)] + | ^ ^ ^^ +... +LL | #[repr(C, u8, u8)] + | ^ ^^ ^^ + | + = note: for consistency, only specify the representation once + +error[E0566]: conflicting representation hints + --> $DIR/repr-repeated-attrs.rs:37:8 + | +LL | #[repr(Rust, u8, u8)] + | ^^^^ ^^ ^^ + +error[E0566]: conflicting representation hints + --> $DIR/repr-repeated-attrs.rs:37:8 + | +LL | #[repr(Rust, 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[E0566]: conflicting representation hints + --> $DIR/repr-repeated-attrs.rs:44:8 + | +LL | #[repr(u8, u8)] + | ^^ ^^ +LL | +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 + +error[E0566]: conflicting representation hints + --> $DIR/repr-repeated-attrs.rs:51: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:59: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 + +warning: representation attribute is specified more than once + --> $DIR/repr-repeated-attrs.rs:59:8 + | +LL | #[repr(C, C, u8, u8, u8)] + | ^ ^ ^^ ^^ ^^ + | + = note: for consistency, only specify the representation once + +error: aborting due to 9 previous errors; 4 warnings emitted + +Some errors have detailed explanations: E0566, E0692. +For more information about an error, try `rustc --explain E0566`. +Future incompatibility report: Future breakage diagnostic: +error[E0566]: conflicting representation hints + --> $DIR/repr-repeated-attrs.rs:22:8 + | +LL | #[repr(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 + +Future breakage diagnostic: +error[E0566]: conflicting representation hints + --> $DIR/repr-repeated-attrs.rs:29:8 + | +LL | #[repr(C, C, u8)] + | ^ ^ ^^ +... +LL | #[repr(C, 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 + +Future breakage diagnostic: +error[E0566]: conflicting representation hints + --> $DIR/repr-repeated-attrs.rs:37:8 + | +LL | #[repr(Rust, 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 + +Future breakage diagnostic: +error[E0566]: conflicting representation hints + --> $DIR/repr-repeated-attrs.rs:44:8 + | +LL | #[repr(u8, u8)] + | ^^ ^^ +LL | +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 + +Future breakage diagnostic: +error[E0566]: conflicting representation hints + --> $DIR/repr-repeated-attrs.rs:51: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:59: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 + From f0719ea0704ac01a29104e00cf17e800f6c6c349 Mon Sep 17 00:00:00 2001 From: Charlotte Ausel Date: Tue, 28 Jul 2026 11:16:07 +0100 Subject: [PATCH 08/15] fix CI by adding forgotten {{produced}} --- compiler/rustc_lint_defs/src/builtin.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/compiler/rustc_lint_defs/src/builtin.rs b/compiler/rustc_lint_defs/src/builtin.rs index 78720145c917e..ffbaeef9ff525 100644 --- a/compiler/rustc_lint_defs/src/builtin.rs +++ b/compiler/rustc_lint_defs/src/builtin.rs @@ -286,6 +286,8 @@ declare_lint! { /// enum Foo { A } /// ``` /// + /// {{produces}} + /// /// ### Explanation /// /// While some representations may be specified more than once, the compiler From 11e7263c614082e632550748d9685ea97e19d2f2 Mon Sep 17 00:00:00 2001 From: Charlotte Ausel Date: Tue, 28 Jul 2026 11:16:13 +0100 Subject: [PATCH 09/15] also warn on repeated int reprs --- compiler/rustc_passes/src/check_attr.rs | 11 +++++- tests/ui/repr/repr-repeated-attrs.rs | 9 +++-- tests/ui/repr/repr-repeated-attrs.stderr | 47 +++++++++++++++++++----- 3 files changed, 52 insertions(+), 15 deletions(-) diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index 5afb1af065acd..b19e102ed1ee6 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -1226,6 +1226,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { let mut is_align = false; let mut is_packed = false; let mut repeated_repr = false; + let mut maybe_last_int_type = None; for (repr, _repr_span) in reprs { match repr { @@ -1264,7 +1265,15 @@ impl<'tcx> CheckAttrVisitor<'tcx> { // when checking for any other attribute together with transparent. is_transparent = true; } - ReprAttr::ReprInt(_) => { + ReprAttr::ReprInt(int_type) => { + if let Some(last_int_type) = maybe_last_int_type && last_int_type == int_type { + // We'll "miss" detecting repeated int reprs if the user specifies + // #[repr(u8, u64, u8)] for example. But that's okay because we've got + // conflicting reprs anyway so it's not worth the effort to do more precise + // tracking. + repeated_repr = true; + } + maybe_last_int_type = Some(int_type); int_reprs += 1; } }; diff --git a/tests/ui/repr/repr-repeated-attrs.rs b/tests/ui/repr/repr-repeated-attrs.rs index a6dd3fb6e8b15..61e3ba05625d8 100644 --- a/tests/ui/repr/repr-repeated-attrs.rs +++ b/tests/ui/repr/repr-repeated-attrs.rs @@ -19,7 +19,7 @@ struct SeveralRustReprs(u8); #[repr(C, C, C)] struct SeveralC(u8); -#[repr(u8, u8)] +#[repr(u8, u8)] //~ WARN representation attribute is specified more than once //~^ ERROR conflicting representation hints //~| WARN this was previously accepted enum SeveralPrimitiveRerprs { @@ -34,7 +34,7 @@ enum SeveralCAndPrims { Variant(u8), } -#[repr(Rust, u8, u8)] +#[repr(Rust, u8, u8)] //~ WARN representation attribute is specified more than once //~^ ERROR conflicting representation hints //~^^ ERROR conflicting representation hints //~| WARN this was previously accepted @@ -42,8 +42,9 @@ enum RustAndPrimDisallowed { Variant(u8), } -#[repr(u8, u8)] //~ ERROR conflicting representation hints -//~^ WARN this was previously accepted +#[repr(u8, u8)] //~ WARN representation attribute is specified more than once +//~^ ERROR conflicting representation hints +//~| WARN this was previously accepted #[repr(u16)] enum ConflictingPrimReprs { Variant, diff --git a/tests/ui/repr/repr-repeated-attrs.stderr b/tests/ui/repr/repr-repeated-attrs.stderr index 72c312a13ea11..57af8ec804d76 100644 --- a/tests/ui/repr/repr-repeated-attrs.stderr +++ b/tests/ui/repr/repr-repeated-attrs.stderr @@ -46,6 +46,14 @@ LL | #[repr(u8, u8)] = note: for more information, see issue #68585 = note: `#[deny(conflicting_repr_hints)]` (part of `#[deny(future_incompatible)]`) on by default +warning: representation attribute is specified more than once + --> $DIR/repr-repeated-attrs.rs:22:8 + | +LL | #[repr(u8, u8)] + | ^^ ^^ + | + = note: for consistency, only specify the representation once + error[E0566]: conflicting representation hints --> $DIR/repr-repeated-attrs.rs:29:8 | @@ -84,20 +92,39 @@ LL | #[repr(Rust, 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 +warning: representation attribute is specified more than once + --> $DIR/repr-repeated-attrs.rs:37:8 + | +LL | #[repr(Rust, u8, u8)] + | ^^^^ ^^ ^^ + | + = note: for consistency, only specify the representation once + error[E0566]: conflicting representation hints - --> $DIR/repr-repeated-attrs.rs:44:8 + --> $DIR/repr-repeated-attrs.rs:45:8 | LL | #[repr(u8, u8)] | ^^ ^^ -LL | +... 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 +warning: representation attribute is specified more than once + --> $DIR/repr-repeated-attrs.rs:45:8 + | +LL | #[repr(u8, u8)] + | ^^ ^^ +... +LL | #[repr(u16)] + | ^^^ + | + = note: for consistency, only specify the representation once + error[E0566]: conflicting representation hints - --> $DIR/repr-repeated-attrs.rs:51:8 + --> $DIR/repr-repeated-attrs.rs:53:8 | LL | #[repr(C, u8)] | ^ ^^ @@ -106,7 +133,7 @@ LL | #[repr(C, u8)] = note: for more information, see issue #68585 error[E0566]: conflicting representation hints - --> $DIR/repr-repeated-attrs.rs:59:8 + --> $DIR/repr-repeated-attrs.rs:61:8 | LL | #[repr(C, C, u8, u8, u8)] | ^ ^ ^^ ^^ ^^ @@ -115,14 +142,14 @@ LL | #[repr(C, C, u8, u8, u8)] = note: for more information, see issue #68585 warning: representation attribute is specified more than once - --> $DIR/repr-repeated-attrs.rs:59:8 + --> $DIR/repr-repeated-attrs.rs:61:8 | LL | #[repr(C, C, u8, u8, u8)] | ^ ^ ^^ ^^ ^^ | = note: for consistency, only specify the representation once -error: aborting due to 9 previous errors; 4 warnings emitted +error: aborting due to 9 previous errors; 7 warnings emitted Some errors have detailed explanations: E0566, E0692. For more information about an error, try `rustc --explain E0566`. @@ -164,11 +191,11 @@ LL | #[repr(Rust, u8, u8)] Future breakage diagnostic: error[E0566]: conflicting representation hints - --> $DIR/repr-repeated-attrs.rs:44:8 + --> $DIR/repr-repeated-attrs.rs:45:8 | LL | #[repr(u8, u8)] | ^^ ^^ -LL | +... LL | #[repr(u16)] | ^^^ | @@ -178,7 +205,7 @@ LL | #[repr(u16)] Future breakage diagnostic: error[E0566]: conflicting representation hints - --> $DIR/repr-repeated-attrs.rs:51:8 + --> $DIR/repr-repeated-attrs.rs:53:8 | LL | #[repr(C, u8)] | ^ ^^ @@ -189,7 +216,7 @@ LL | #[repr(C, u8)] Future breakage diagnostic: error[E0566]: conflicting representation hints - --> $DIR/repr-repeated-attrs.rs:59:8 + --> $DIR/repr-repeated-attrs.rs:61:8 | LL | #[repr(C, C, u8, u8, u8)] | ^ ^ ^^ ^^ ^^ From d72e695b2ed61a6fe6af9dd044bc1981ceb31b45 Mon Sep 17 00:00:00 2001 From: Charlotte Ausel Date: Tue, 28 Jul 2026 11:16:17 +0100 Subject: [PATCH 10/15] format --- compiler/rustc_passes/src/check_attr.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index b19e102ed1ee6..34e1f5caf202c 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -1266,7 +1266,9 @@ impl<'tcx> CheckAttrVisitor<'tcx> { is_transparent = true; } ReprAttr::ReprInt(int_type) => { - if let Some(last_int_type) = maybe_last_int_type && last_int_type == int_type { + if let Some(last_int_type) = maybe_last_int_type + && last_int_type == int_type + { // We'll "miss" detecting repeated int reprs if the user specifies // #[repr(u8, u64, u8)] for example. But that's okay because we've got // conflicting reprs anyway so it's not worth the effort to do more precise From eb04bbdd49470888342ad5af789b745cadc24275 Mon Sep 17 00:00:00 2001 From: Charlotte Ausel Date: Tue, 28 Jul 2026 11:16:21 +0100 Subject: [PATCH 11/15] use sort/chunk_by to find repeated reprs --- .../rustc_hir/src/attrs/data_structures.rs | 16 +++- compiler/rustc_passes/src/check_attr.rs | 75 ++++++---------- compiler/rustc_passes/src/diagnostics.rs | 2 +- tests/ui/attributes/issue-100631.rs | 2 +- tests/ui/attributes/issue-100631.stderr | 2 +- tests/ui/lint/unused/unused-attr-duplicate.rs | 2 +- .../lint/unused/unused-attr-duplicate.stderr | 2 +- tests/ui/repr/conflicting-repr-hints.rs | 4 +- tests/ui/repr/conflicting-repr-hints.stderr | 24 +---- tests/ui/repr/repr-repeated-attrs.rs | 18 ++-- tests/ui/repr/repr-repeated-attrs.stderr | 87 +++++++++++-------- tests/ui/structs-enums/align-enum.rs | 2 +- tests/ui/structs-enums/align-enum.stderr | 15 ---- tests/ui/structs-enums/align-struct.rs | 2 +- tests/ui/structs-enums/align-struct.stderr | 15 ---- 15 files changed, 116 insertions(+), 152 deletions(-) delete mode 100644 tests/ui/structs-enums/align-enum.stderr delete mode 100644 tests/ui/structs-enums/align-struct.stderr diff --git a/compiler/rustc_hir/src/attrs/data_structures.rs b/compiler/rustc_hir/src/attrs/data_structures.rs index ff2e06eaca1d7..102a0060ba094 100644 --- a/compiler/rustc_hir/src/attrs/data_structures.rs +++ b/compiler/rustc_hir/src/attrs/data_structures.rs @@ -172,7 +172,19 @@ impl OptimizeAttr { } } -#[derive(PartialEq, Debug, Encodable, Decodable, Copy, Clone, StableHash, PrintAttribute)] +#[derive( + PartialEq, + Eq, + Debug, + PartialOrd, + Ord, + Encodable, + Decodable, + Copy, + Clone, + StableHash, + PrintAttribute +)] pub enum ReprAttr { ReprInt(IntType), ReprRust, @@ -188,7 +200,7 @@ pub enum TransparencyError { MultipleTransparencyAttrs(Span, Span), } -#[derive(Eq, PartialEq, Debug, Copy, Clone)] +#[derive(Eq, PartialEq, Debug, Copy, Clone, PartialOrd, Ord)] #[derive(Encodable, Decodable, StableHash, PrintAttribute)] pub enum IntType { SignedInt(ast::IntTy), diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index 34e1f5caf202c..d6325f2499300 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -1223,64 +1223,54 @@ impl<'tcx> CheckAttrVisitor<'tcx> { let mut is_c = false; let mut is_simd = false; let mut is_transparent = false; - let mut is_align = false; - let mut is_packed = false; - let mut repeated_repr = false; - let mut maybe_last_int_type = None; for (repr, _repr_span) in reprs { match repr { ReprAttr::ReprRust => { - if is_explicit_rust { - repeated_repr = true; - } is_explicit_rust = true; } ReprAttr::ReprC => { - if is_c { - repeated_repr = true; - } is_c = true; } - ReprAttr::ReprAlign(..) => { - if is_align { - repeated_repr = true; - } - is_align = true; - } - ReprAttr::ReprPacked(..) => { - if is_packed { - repeated_repr = true; - } - is_packed = true; - } + ReprAttr::ReprAlign(..) => (), + ReprAttr::ReprPacked(..) => (), ReprAttr::ReprSimd => { - if is_simd { - repeated_repr = true; - } is_simd = true; } ReprAttr::ReprTransparent => { - // No need to check for repeated transparent because that is already checked - // when checking for any other attribute together with transparent. is_transparent = true; } - ReprAttr::ReprInt(int_type) => { - if let Some(last_int_type) = maybe_last_int_type - && last_int_type == int_type - { - // We'll "miss" detecting repeated int reprs if the user specifies - // #[repr(u8, u64, u8)] for example. But that's okay because we've got - // conflicting reprs anyway so it's not worth the effort to do more precise - // tracking. - repeated_repr = true; - } - maybe_last_int_type = Some(int_type); + ReprAttr::ReprInt(..) => { int_reprs += 1; } }; } + if !reprs.is_empty() { + let sorted_reprs = { + let mut to_sort = reprs.to_owned(); + to_sort.sort(); + to_sort + }; + + // We don't just want to know whether there are any duplicates, but also what those + // duplicates are. Thus, we get subslices where all of the elements of the subslice are + // equal, then filter out all those whose length is not 1. we could return warnings for + // each of them, but that's annoyingly excessive. So we instead collect all spans in one + // big Vec. + let spans: Vec = sorted_reprs + .chunk_by(|(a, _), (b, _)| a == b) + .map(ToOwned::to_owned) + .filter(|slice| slice.len() != 1) + .flatten() + .map(|(_, span)| span) + .collect(); + + if !spans.is_empty() { + self.tcx.emit_node_span_lint(REPEATED_REPRS, hir_id, spans, errors::RepeatedRepr); + } + } + // Just point at all repr hints if there are any incompatibilities. // This is not ideal, but tracking precisely which ones are at fault is a huge hassle. let hint_spans = reprs.iter().map(|(_, span)| *span); @@ -1325,15 +1315,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> { >>>>>>> d71bc523ed8 (lint against repeated repr attributes) ); } - - if repeated_repr { - self.tcx.emit_node_span_lint( - REPEATED_REPRS, - hir_id, - hint_spans.collect::>(), - errors::RepeatedRepr, - ); - } } /// Outputs an error for attributes that can only be applied to macros, such as diff --git a/compiler/rustc_passes/src/diagnostics.rs b/compiler/rustc_passes/src/diagnostics.rs index 111c223122919..e7eef602d4f0c 100644 --- a/compiler/rustc_passes/src/diagnostics.rs +++ b/compiler/rustc_passes/src/diagnostics.rs @@ -654,7 +654,7 @@ pub(crate) struct TransparentIncompatible { } #[derive(Diagnostic)] -#[diag("representation attribute is specified more than once")] +#[diag("`#[repr(..)]` attribute is specified more than once")] #[note("for consistency, only specify the representation once")] pub(crate) struct RepeatedRepr; diff --git a/tests/ui/attributes/issue-100631.rs b/tests/ui/attributes/issue-100631.rs index d496231c73026..9a30691a39ec3 100644 --- a/tests/ui/attributes/issue-100631.rs +++ b/tests/ui/attributes/issue-100631.rs @@ -2,7 +2,7 @@ // can reasonably deal with multiple attributes. // `repr` will use `TyCtxt::get_attrs` since it's `DuplicatesOk`. #[repr(C)] //~ ERROR: unsupported representation for zero-variant enum [E0084] -//~^ WARN representation attribute is specified more than once +//~^ WARN `#[repr(..)]` attribute is specified more than once [repeated_reprs] #[repr(C)] enum Foo {} diff --git a/tests/ui/attributes/issue-100631.stderr b/tests/ui/attributes/issue-100631.stderr index 66e08738eb02c..0ecc19ae85b3d 100644 --- a/tests/ui/attributes/issue-100631.stderr +++ b/tests/ui/attributes/issue-100631.stderr @@ -1,4 +1,4 @@ -warning: representation attribute is specified more than once +warning: `#[repr(..)]` attribute is specified more than once --> $DIR/issue-100631.rs:4:8 | LL | #[repr(C)] diff --git a/tests/ui/lint/unused/unused-attr-duplicate.rs b/tests/ui/lint/unused/unused-attr-duplicate.rs index 348c9590e8b27..c013041ed4159 100644 --- a/tests/ui/lint/unused/unused-attr-duplicate.rs +++ b/tests/ui/lint/unused/unused-attr-duplicate.rs @@ -64,7 +64,7 @@ fn t1() {} #[must_use = "some message"] //~^ ERROR unused attribute //~| WARN this was previously accepted -#[repr(C)] //~ WARN representation attribute is specified more than once +#[repr(C)] //~ WARN `#[repr(..)]` attribute is specified more than once [repeated_reprs] #[repr(C)] #[non_exhaustive] #[non_exhaustive] //~ ERROR unused attribute diff --git a/tests/ui/lint/unused/unused-attr-duplicate.stderr b/tests/ui/lint/unused/unused-attr-duplicate.stderr index 93f7a4791188f..dc6fd5b3d35b5 100644 --- a/tests/ui/lint/unused/unused-attr-duplicate.stderr +++ b/tests/ui/lint/unused/unused-attr-duplicate.stderr @@ -16,7 +16,7 @@ note: the lint level is defined here LL | #![deny(unused_attributes)] | ^^^^^^^^^^^^^^^^^ -warning: representation attribute is specified more than once +warning: `#[repr(..)]` attribute is specified more than once --> $DIR/unused-attr-duplicate.rs:67:8 | LL | #[repr(C)] diff --git a/tests/ui/repr/conflicting-repr-hints.rs b/tests/ui/repr/conflicting-repr-hints.rs index 032f2b2e6c608..81a94aad78ff6 100644 --- a/tests/ui/repr/conflicting-repr-hints.rs +++ b/tests/ui/repr/conflicting-repr-hints.rs @@ -36,10 +36,10 @@ struct G(i32); //~ ERROR type has conflicting packed and align representation hi #[repr(packed)] struct H(i32); //~ ERROR type has conflicting packed and align representation hints -#[repr(packed, packed(2))] //~ WARN representation attribute is specified more than once +#[repr(packed, packed(2))] struct I(i32); //~ ERROR type has conflicting packed representation hints -#[repr(packed(2))] //~ WARN representation attribute is specified more than once +#[repr(packed(2))] #[repr(packed)] struct J(i32); //~ ERROR type has conflicting packed representation hints diff --git a/tests/ui/repr/conflicting-repr-hints.stderr b/tests/ui/repr/conflicting-repr-hints.stderr index a99546b754785..8f2655fd716f1 100644 --- a/tests/ui/repr/conflicting-repr-hints.stderr +++ b/tests/ui/repr/conflicting-repr-hints.stderr @@ -17,32 +17,14 @@ LL | #[repr(u32, u64)] = 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 -warning: representation attribute is specified more than once - --> $DIR/conflicting-repr-hints.rs:39:8 - | -LL | #[repr(packed, packed(2))] - | ^^^^^^ ^^^^^^^^^ - | - = note: for consistency, only specify the representation once - = note: `#[warn(repeated_reprs)]` on by default - -warning: representation attribute is specified more than once - --> $DIR/conflicting-repr-hints.rs:42:8 - | -LL | #[repr(packed(2))] - | ^^^^^^^^^ -LL | #[repr(packed)] - | ^^^^^^ - | - = note: for consistency, only specify the representation once - -warning: representation attribute is specified more than once +warning: `#[repr(..)]` attribute is specified more than once --> $DIR/conflicting-repr-hints.rs:46:8 | LL | #[repr(packed, packed(1))] | ^^^^^^ ^^^^^^^^^ | = note: for consistency, only specify the representation once + = note: `#[warn(repeated_reprs)]` on by default error[E0587]: type has conflicting packed and align representation hints --> $DIR/conflicting-repr-hints.rs:29:1 @@ -104,7 +86,7 @@ error[E0587]: type has conflicting packed and align representation hints LL | pub union U { | ^^^^^^^^^^^ -error: aborting due to 12 previous errors; 3 warnings emitted +error: aborting due to 12 previous errors; 1 warning emitted Some errors have detailed explanations: E0566, E0587, E0634. For more information about an error, try `rustc --explain E0566`. diff --git a/tests/ui/repr/repr-repeated-attrs.rs b/tests/ui/repr/repr-repeated-attrs.rs index 61e3ba05625d8..7306b9192f09e 100644 --- a/tests/ui/repr/repr-repeated-attrs.rs +++ b/tests/ui/repr/repr-repeated-attrs.rs @@ -1,32 +1,32 @@ // Tests to ensure we warn on repeated `#[repr(..)]` attributes. -#[repr(transparent, transparent)] +#[repr(transparent, transparent)] //~ WARN `#[repr(..)]` attribute is specified more than once [repeated_reprs] //~^ ERROR transparent struct cannot have other repr hints #[repr(transparent)] struct SeveralTransparentReprs(*mut u8); -#[repr(transparent)] +#[repr(transparent)] //~ WARN `#[repr(..)]` attribute is specified more than once [repeated_reprs] //~^ ERROR transparent struct cannot have other repr hints #[repr(transparent)] struct MultilineOnly(*mut u8); #[repr(Rust, Rust)] -//~^ WARN representation attribute is specified more than once +//~^ WARN `#[repr(..)]` attribute is specified more than once [repeated_reprs] struct SeveralRustReprs(u8); #[repr(C, C)] -//~^ WARN representation attribute is specified more than once +//~^ WARN `#[repr(..)]` attribute is specified more than once [repeated_reprs] #[repr(C, C, C)] struct SeveralC(u8); -#[repr(u8, u8)] //~ WARN representation attribute is specified more than once +#[repr(u8, u8)] //~ WARN `#[repr(..)]` attribute is specified more than once [repeated_reprs] //~^ ERROR conflicting representation hints //~| WARN this was previously accepted enum SeveralPrimitiveRerprs { Variant, } -#[repr(C, C, u8)] //~ WARN representation attribute is specified more than once +#[repr(C, C, u8)] //~ WARN `#[repr(..)]` attribute is specified more than once [repeated_reprs] //~^ ERROR conflicting representation hints //~| WARN this was previously accepted #[repr(C, u8, u8)] @@ -34,7 +34,7 @@ enum SeveralCAndPrims { Variant(u8), } -#[repr(Rust, u8, u8)] //~ WARN representation attribute is specified more than once +#[repr(Rust, u8, u8)] //~ WARN `#[repr(..)]` attribute is specified more than once [repeated_reprs] //~^ ERROR conflicting representation hints //~^^ ERROR conflicting representation hints //~| WARN this was previously accepted @@ -42,7 +42,7 @@ enum RustAndPrimDisallowed { Variant(u8), } -#[repr(u8, u8)] //~ WARN representation attribute is specified more than once +#[repr(u8, u8)] //~ WARN `#[repr(..)]` attribute is specified more than once [repeated_reprs] //~^ ERROR conflicting representation hints //~| WARN this was previously accepted #[repr(u16)] @@ -58,7 +58,7 @@ enum CWithIntsCausesFCW1 { B, } -#[repr(C, C, u8, u8, u8)] //~ WARN representation attribute is specified more than once +#[repr(C, C, u8, u8, u8)] //~ WARN `#[repr(..)]` attribute is specified more than once [repeated_reprs] //~^ ERROR conflicting representation hints //~| WARN this was previously accepted enum CWithIntsCausesFCW2 { diff --git a/tests/ui/repr/repr-repeated-attrs.stderr b/tests/ui/repr/repr-repeated-attrs.stderr index 57af8ec804d76..a0b8b1d7da3cc 100644 --- a/tests/ui/repr/repr-repeated-attrs.stderr +++ b/tests/ui/repr/repr-repeated-attrs.stderr @@ -1,3 +1,15 @@ +warning: `#[repr(..)]` attribute is specified more than once + --> $DIR/repr-repeated-attrs.rs:3:8 + | +LL | #[repr(transparent, transparent)] + | ^^^^^^^^^^^ ^^^^^^^^^^^ +LL | +LL | #[repr(transparent)] + | ^^^^^^^^^^^ + | + = note: for consistency, only specify the representation once + = note: `#[warn(repeated_reprs)]` on by default + error[E0692]: transparent struct cannot have other repr hints --> $DIR/repr-repeated-attrs.rs:3:8 | @@ -7,6 +19,17 @@ LL | LL | #[repr(transparent)] | ^^^^^^^^^^^ +warning: `#[repr(..)]` attribute is specified more than once + --> $DIR/repr-repeated-attrs.rs:8:8 + | +LL | #[repr(transparent)] + | ^^^^^^^^^^^ +LL | +LL | #[repr(transparent)] + | ^^^^^^^^^^^ + | + = note: for consistency, only specify the representation once + error[E0692]: transparent struct cannot have other repr hints --> $DIR/repr-repeated-attrs.rs:8:8 | @@ -16,16 +39,15 @@ LL | LL | #[repr(transparent)] | ^^^^^^^^^^^ -warning: representation attribute is specified more than once +warning: `#[repr(..)]` attribute is specified more than once --> $DIR/repr-repeated-attrs.rs:13:8 | LL | #[repr(Rust, Rust)] | ^^^^ ^^^^ | = note: for consistency, only specify the representation once - = note: `#[warn(repeated_reprs)]` on by default -warning: representation attribute is specified more than once +warning: `#[repr(..)]` attribute is specified more than once --> $DIR/repr-repeated-attrs.rs:17:8 | LL | #[repr(C, C)] @@ -36,25 +58,25 @@ LL | #[repr(C, C, C)] | = note: for consistency, only specify the representation once -error[E0566]: conflicting representation hints +warning: `#[repr(..)]` attribute is specified more than once --> $DIR/repr-repeated-attrs.rs:22:8 | LL | #[repr(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 + = note: for consistency, only specify the representation once -warning: representation attribute is specified more than once +error[E0566]: conflicting representation hints --> $DIR/repr-repeated-attrs.rs:22:8 | LL | #[repr(u8, u8)] | ^^ ^^ | - = note: for consistency, only specify the representation once + = 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[E0566]: conflicting representation hints +warning: `#[repr(..)]` attribute is specified more than once --> $DIR/repr-repeated-attrs.rs:29:8 | LL | #[repr(C, C, u8)] @@ -63,10 +85,9 @@ LL | #[repr(C, C, u8)] LL | #[repr(C, 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: for consistency, only specify the representation once -warning: representation attribute is specified more than once +error[E0566]: conflicting representation hints --> $DIR/repr-repeated-attrs.rs:29:8 | LL | #[repr(C, C, u8)] @@ -75,6 +96,15 @@ LL | #[repr(C, C, u8)] LL | #[repr(C, 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 + +warning: `#[repr(..)]` attribute is specified more than once + --> $DIR/repr-repeated-attrs.rs:37:14 + | +LL | #[repr(Rust, u8, u8)] + | ^^ ^^ + | = note: for consistency, only specify the representation once error[E0566]: conflicting representation hints @@ -92,11 +122,11 @@ LL | #[repr(Rust, 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 -warning: representation attribute is specified more than once - --> $DIR/repr-repeated-attrs.rs:37:8 +warning: `#[repr(..)]` attribute is specified more than once + --> $DIR/repr-repeated-attrs.rs:45:8 | -LL | #[repr(Rust, u8, u8)] - | ^^^^ ^^ ^^ +LL | #[repr(u8, u8)] + | ^^ ^^ | = note: for consistency, only specify the representation once @@ -112,17 +142,6 @@ 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 -warning: representation attribute is specified more than once - --> $DIR/repr-repeated-attrs.rs:45:8 - | -LL | #[repr(u8, u8)] - | ^^ ^^ -... -LL | #[repr(u16)] - | ^^^ - | - = note: for consistency, only specify the representation once - error[E0566]: conflicting representation hints --> $DIR/repr-repeated-attrs.rs:53:8 | @@ -132,24 +151,24 @@ 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 +warning: `#[repr(..)]` attribute is specified more than once --> $DIR/repr-repeated-attrs.rs:61: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: for consistency, only specify the representation once -warning: representation attribute is specified more than once +error[E0566]: conflicting representation hints --> $DIR/repr-repeated-attrs.rs:61:8 | LL | #[repr(C, C, u8, u8, u8)] | ^ ^ ^^ ^^ ^^ | - = note: for consistency, only specify the representation once + = 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 9 previous errors; 7 warnings emitted +error: aborting due to 9 previous errors; 9 warnings emitted Some errors have detailed explanations: E0566, E0692. For more information about an error, try `rustc --explain E0566`. diff --git a/tests/ui/structs-enums/align-enum.rs b/tests/ui/structs-enums/align-enum.rs index a635af7352afe..ff80a19211cda 100644 --- a/tests/ui/structs-enums/align-enum.rs +++ b/tests/ui/structs-enums/align-enum.rs @@ -11,7 +11,7 @@ enum Align16 { } // Raise alignment by maximum -#[repr(align(1), align(16))] //~ WARN representation attribute is specified more than once +#[repr(align(1), align(16))] #[repr(align(32))] #[repr(align(4))] enum Align32 { diff --git a/tests/ui/structs-enums/align-enum.stderr b/tests/ui/structs-enums/align-enum.stderr deleted file mode 100644 index 9b8c9842f81df..0000000000000 --- a/tests/ui/structs-enums/align-enum.stderr +++ /dev/null @@ -1,15 +0,0 @@ -warning: representation attribute is specified more than once - --> $DIR/align-enum.rs:14:8 - | -LL | #[repr(align(1), align(16))] - | ^^^^^^^^ ^^^^^^^^^ -LL | #[repr(align(32))] - | ^^^^^^^^^ -LL | #[repr(align(4))] - | ^^^^^^^^ - | - = note: for consistency, only specify the representation once - = note: `#[warn(repeated_reprs)]` on by default - -warning: 1 warning emitted - diff --git a/tests/ui/structs-enums/align-struct.rs b/tests/ui/structs-enums/align-struct.rs index 2d1ebf6731a62..3d8dad6e324e3 100644 --- a/tests/ui/structs-enums/align-struct.rs +++ b/tests/ui/structs-enums/align-struct.rs @@ -13,7 +13,7 @@ struct Align16(i32); struct Align1(i32); // Multiple attributes take the max -#[repr(align(4))] //~ WARN representation attribute is specified more than once +#[repr(align(4))] #[repr(align(16))] #[repr(align(8))] struct AlignMany(i32); diff --git a/tests/ui/structs-enums/align-struct.stderr b/tests/ui/structs-enums/align-struct.stderr deleted file mode 100644 index f54e9cd14cd8b..0000000000000 --- a/tests/ui/structs-enums/align-struct.stderr +++ /dev/null @@ -1,15 +0,0 @@ -warning: representation attribute is specified more than once - --> $DIR/align-struct.rs:16:8 - | -LL | #[repr(align(4))] - | ^^^^^^^^ -LL | #[repr(align(16))] - | ^^^^^^^^^ -LL | #[repr(align(8))] - | ^^^^^^^^ - | - = note: for consistency, only specify the representation once - = note: `#[warn(repeated_reprs)]` on by default - -warning: 1 warning emitted - From fff1df4093008bd561ceb4f887ecbcdebdcb8c10 Mon Sep 17 00:00:00 2001 From: Charlotte Ausel Date: Tue, 28 Jul 2026 11:16:25 +0100 Subject: [PATCH 12/15] fix merge conflict that slipped by --- compiler/rustc_passes/src/check_attr.rs | 5 ----- 1 file changed, 5 deletions(-) diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index d6325f2499300..edba3604b03ef 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -1306,13 +1306,8 @@ impl<'tcx> CheckAttrVisitor<'tcx> { self.tcx.emit_node_span_lint( CONFLICTING_REPR_HINTS, hir_id, -<<<<<<< HEAD hint_spans.collect::>(), diagnostics::ReprConflictingLint, -======= - hint_spans.clone().collect::>(), - errors::ReprConflictingLint, ->>>>>>> d71bc523ed8 (lint against repeated repr attributes) ); } } From f275cec7a2beecfeae51c018792673cb4dfbe792 Mon Sep 17 00:00:00 2001 From: Charlotte Ausel Date: Tue, 28 Jul 2026 11:16:30 +0100 Subject: [PATCH 13/15] fix other err after rebase --- compiler/rustc_passes/src/check_attr.rs | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index edba3604b03ef..3106d89a17f03 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -40,8 +40,9 @@ use rustc_session::config::CrateType; use rustc_session::diagnostics::feature_err; use rustc_session::lint; use rustc_session::lint::builtin::{ - CONFLICTING_REPR_HINTS, INVALID_DOC_ATTRIBUTES, MALFORMED_DIAGNOSTIC_FORMAT_LITERALS, - MISPLACED_DIAGNOSTIC_ATTRIBUTES, REPEATED_REPRS, UNUSED_ATTRIBUTES, + CONFLICTING_REPR_HINTS, INVALID_DOC_ATTRIBUTES, MALFORMED_DIAGNOSTIC_ATTRIBUTES, + MALFORMED_DIAGNOSTIC_FORMAT_LITERALS, MISPLACED_DIAGNOSTIC_ATTRIBUTES, REPEATED_REPRS, + UNUSED_ATTRIBUTES, }; use rustc_span::edition::Edition; use rustc_span::{DUMMY_SP, Ident, Span, Symbol, sym}; @@ -1253,11 +1254,10 @@ impl<'tcx> CheckAttrVisitor<'tcx> { to_sort }; - // We don't just want to know whether there are any duplicates, but also what those - // duplicates are. Thus, we get subslices where all of the elements of the subslice are - // equal, then filter out all those whose length is not 1. we could return warnings for - // each of them, but that's annoyingly excessive. So we instead collect all spans in one - // big Vec. + // To collect all duplicates, get subslices where all of the elements of the subslice + // are equal, then filter out all those whose length is not 1. We could return warnings + // for each of them, but that's annoyingly excessive. So we instead collect all spans in + // one big Vec. let spans: Vec = sorted_reprs .chunk_by(|(a, _), (b, _)| a == b) .map(ToOwned::to_owned) @@ -1267,7 +1267,12 @@ impl<'tcx> CheckAttrVisitor<'tcx> { .collect(); if !spans.is_empty() { - self.tcx.emit_node_span_lint(REPEATED_REPRS, hir_id, spans, errors::RepeatedRepr); + self.tcx.emit_node_span_lint( + REPEATED_REPRS, + hir_id, + spans, + diagnostics::RepeatedRepr, + ); } } From c5d92321e90b665495d8721f53a52bced1f859bd Mon Sep 17 00:00:00 2001 From: Charlotte Ausel Date: Tue, 28 Jul 2026 11:16:34 +0100 Subject: [PATCH 14/15] rebless test --- .../ui/lint/unused/unused-attr-duplicate.stderr | 17 ++--------------- 1 file changed, 2 insertions(+), 15 deletions(-) diff --git a/tests/ui/lint/unused/unused-attr-duplicate.stderr b/tests/ui/lint/unused/unused-attr-duplicate.stderr index dc6fd5b3d35b5..6e4f7d23604c2 100644 --- a/tests/ui/lint/unused/unused-attr-duplicate.stderr +++ b/tests/ui/lint/unused/unused-attr-duplicate.stderr @@ -264,19 +264,6 @@ note: attribute also specified here LL | #[track_caller] | ^^^^^^^^^^^^^^^ -error: unused attribute - --> $DIR/unused-attr-duplicate.rs:93:5 - | -LL | #[link_name = "rust_dbg_extern_identity_u32"] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove this attribute - | -note: attribute also specified here - --> $DIR/unused-attr-duplicate.rs:92:5 - | -LL | #[link_name = "this_does_not_exist"] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - error: unused attribute --> $DIR/unused-attr-duplicate.rs:99:1 | @@ -328,13 +315,13 @@ LL | #[link_section = "__TEXT,__text"] = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! error: unused attribute - --> $DIR/unused-attr-duplicate.rs:94:5 + --> $DIR/unused-attr-duplicate.rs:93:5 | LL | #[link_name = "rust_dbg_extern_identity_u32"] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove this attribute | note: attribute also specified here - --> $DIR/unused-attr-duplicate.rs:93:5 + --> $DIR/unused-attr-duplicate.rs:92:5 | LL | #[link_name = "this_does_not_exist"] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ From 224a10132238b098ca3c2a31ddbfd4fa919b4e91 Mon Sep 17 00:00:00 2001 From: Charlotte Ausel Date: Tue, 28 Jul 2026 11:10:12 +0100 Subject: [PATCH 15/15] replace .sort() with .sort_unstable() because that's been nagging me for weeks now. --- compiler/rustc_passes/src/check_attr.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index 3106d89a17f03..a57b606776058 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -1250,7 +1250,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { if !reprs.is_empty() { let sorted_reprs = { let mut to_sort = reprs.to_owned(); - to_sort.sort(); + to_sort.sort_unstable(); to_sort };