From dae85db951c412d45f6ae86cfa7f7fa386e5d482 Mon Sep 17 00:00:00 2001 From: Roland Xu Date: Tue, 11 Aug 2026 23:19:28 +0800 Subject: [PATCH 1/3] Lint unused #[non_exhaustive] --- compiler/rustc_passes/src/check_attr.rs | 62 ++++++++++++++++------ compiler/rustc_passes/src/diagnostics.rs | 11 ++++ tests/ui/lint/unused-non-exhaustive.rs | 47 ++++++++++++++++ tests/ui/lint/unused-non-exhaustive.stderr | 54 +++++++++++++++++++ 4 files changed, 158 insertions(+), 16 deletions(-) create mode 100644 tests/ui/lint/unused-non-exhaustive.rs create mode 100644 tests/ui/lint/unused-non-exhaustive.stderr diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index 44c34a2abddd1..103e244c88625 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -200,7 +200,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { } AttributeKind::Naked(..) => self.check_naked(hir_id, target), AttributeKind::NonExhaustive(attr_span) => { - self.check_non_exhaustive(*attr_span, span, target, item) + self.check_non_exhaustive(hir_id, *attr_span, span, target, item) } AttributeKind::MayDangle(attr_span) => self.check_may_dangle(hir_id, *attr_span), AttributeKind::Link(_, attr_span) => self.check_link(hir_id, *attr_span, target), @@ -802,30 +802,60 @@ impl<'tcx> CheckAttrVisitor<'tcx> { } } - /// Checks if the `#[non_exhaustive]` attribute on an `item` is valid. + /// Checks if the `#[non_exhaustive]` attribute on an `item` is valid and effective. fn check_non_exhaustive( &self, + hir_id: HirId, attr_span: Span, span: Span, target: Target, item: Option<&'tcx Item<'tcx>>, ) { - match target { - Target::Struct => { - if let hir::Item { - kind: hir::ItemKind::Struct(_, _, hir::VariantData::Struct { fields, .. }), - .. - } = item.unwrap() - && !fields.is_empty() - && fields.iter().any(|f| f.default.is_some()) - { - self.dcx().emit_err(diagnostics::NonExhaustiveWithDefaultFieldValues { - attr_span, - defn_span: span, - }); + if matches!(target, Target::Enum | Target::Variant) + && !self.tcx.effective_visibilities(()).is_reachable(hir_id.owner.def_id) + { + self.tcx.emit_node_span_lint( + UNUSED_ATTRIBUTES, + hir_id, + attr_span, + diagnostics::UnusedNonExhaustive::Unreachable, + ); + } else if target == Target::Struct { + let (_, _, data) = item.unwrap().expect_struct(); + let fields = data.fields(); + + if !fields.is_empty() && fields.iter().any(|f| f.default.is_some()) { + self.dcx().emit_err(diagnostics::NonExhaustiveWithDefaultFieldValues { + attr_span, + defn_span: span, + }); + } + + if !self.tcx.effective_visibilities(()).is_reachable(hir_id.owner.def_id) { + self.tcx.emit_node_span_lint( + UNUSED_ATTRIBUTES, + hir_id, + attr_span, + diagnostics::UnusedNonExhaustive::Unreachable, + ); + return; + } + + let mut spans = MultiSpan::from_span(attr_span); + for field in fields.iter() { + if !self.tcx.visibility(field.def_id).is_public() { + spans.push_primary_span(field.span); } } - _ => {} + + if spans.primary_spans().len() > 1 { + self.tcx.emit_node_span_lint( + UNUSED_ATTRIBUTES, + hir_id, + spans, + diagnostics::UnusedNonExhaustive::StructWithNonPublicField, + ); + } } } diff --git a/compiler/rustc_passes/src/diagnostics.rs b/compiler/rustc_passes/src/diagnostics.rs index 59b393fc8e68b..d09028e2397d4 100644 --- a/compiler/rustc_passes/src/diagnostics.rs +++ b/compiler/rustc_passes/src/diagnostics.rs @@ -56,6 +56,17 @@ pub(crate) struct NonExhaustiveWithDefaultFieldValues { pub defn_span: Span, } +#[derive(Diagnostic)] +pub(crate) enum UnusedNonExhaustive { + #[diag("`#[non_exhaustive]` has no effect on an unreachable item")] + Unreachable, + #[diag("`#[non_exhaustive]` has no effect on a struct with non-public fields")] + #[note( + "non-public fields already prevent the struct from being constructed or exhaustively matched by downstream crates" + )] + StructWithNonPublicField, +} + #[derive(Diagnostic)] #[diag("`#[doc(alias = \"...\")]` isn't allowed on {$location}")] pub(crate) struct DocAliasBadLocation<'a> { diff --git a/tests/ui/lint/unused-non-exhaustive.rs b/tests/ui/lint/unused-non-exhaustive.rs new file mode 100644 index 0000000000000..3dae3b41584dd --- /dev/null +++ b/tests/ui/lint/unused-non-exhaustive.rs @@ -0,0 +1,47 @@ +#![deny(unused_attributes)] + +#[non_exhaustive] +//~^ ERROR `#[non_exhaustive]` has no effect on an unreachable item +struct PrivateUnitStruct; + +#[non_exhaustive] +//~^ ERROR `#[non_exhaustive]` has no effect on an unreachable item +struct PrivateStructWithPrivateField { + field: (), +} + +#[non_exhaustive] +//~^ ERROR `#[non_exhaustive]` has no effect on an unreachable item +enum PrivateEnum { + Variant { field: () }, +} + +enum PrivateVariant { + #[non_exhaustive] + //~^ ERROR `#[non_exhaustive]` has no effect on an unreachable item + Variant { field: () }, +} + +#[non_exhaustive] +//~^ ERROR `#[non_exhaustive]` has no effect on a struct with non-public fields +pub struct PublicStructWithPrivateField { + pub public: (), + private: (), +} + +#[non_exhaustive] +//~^ ERROR `#[non_exhaustive]` has no effect on a struct with non-public fields +pub struct PublicTupleStructWithPrivateField(pub (), ()); + +#[non_exhaustive] +pub struct PublicStructWithPublicField { + pub field: (), +} + +#[non_exhaustive] +pub enum PublicEnum { + #[non_exhaustive] + Variant { field: () }, +} + +fn main() {} diff --git a/tests/ui/lint/unused-non-exhaustive.stderr b/tests/ui/lint/unused-non-exhaustive.stderr new file mode 100644 index 0000000000000..32d6c0f2c5552 --- /dev/null +++ b/tests/ui/lint/unused-non-exhaustive.stderr @@ -0,0 +1,54 @@ +error: `#[non_exhaustive]` has no effect on an unreachable item + --> $DIR/unused-non-exhaustive.rs:3:1 + | +LL | #[non_exhaustive] + | ^^^^^^^^^^^^^^^^^ + | +note: the lint level is defined here + --> $DIR/unused-non-exhaustive.rs:1:9 + | +LL | #![deny(unused_attributes)] + | ^^^^^^^^^^^^^^^^^ + +error: `#[non_exhaustive]` has no effect on an unreachable item + --> $DIR/unused-non-exhaustive.rs:7:1 + | +LL | #[non_exhaustive] + | ^^^^^^^^^^^^^^^^^ + +error: `#[non_exhaustive]` has no effect on an unreachable item + --> $DIR/unused-non-exhaustive.rs:13:1 + | +LL | #[non_exhaustive] + | ^^^^^^^^^^^^^^^^^ + +error: `#[non_exhaustive]` has no effect on an unreachable item + --> $DIR/unused-non-exhaustive.rs:20:5 + | +LL | #[non_exhaustive] + | ^^^^^^^^^^^^^^^^^ + +error: `#[non_exhaustive]` has no effect on a struct with non-public fields + --> $DIR/unused-non-exhaustive.rs:25:1 + | +LL | #[non_exhaustive] + | ^^^^^^^^^^^^^^^^^ +... +LL | private: (), + | ^^^^^^^^^^^ + | + = note: non-public fields already prevent the struct from being constructed or exhaustively matched by downstream crates + +error: `#[non_exhaustive]` has no effect on a struct with non-public fields + --> $DIR/unused-non-exhaustive.rs:32:1 + | +LL | #[non_exhaustive] + | ^^^^^^^^^^^^^^^^^ +LL | +LL | pub struct PublicTupleStructWithPrivateField(pub (), ()); + | ^^ + | + = note: non-public fields already prevent the struct from being constructed or exhaustively matched by downstream crates + +error: aborting due to 6 previous errors + From 7a0e7b8cca945490fa2706f41fb9a3b280e65cc7 Mon Sep 17 00:00:00 2001 From: Roland Xu Date: Tue, 11 Aug 2026 23:19:42 +0800 Subject: [PATCH 2/3] Remove unused #[non_exhaustive] in library --- library/core/src/escape.rs | 2 -- library/core/src/mem/type_info.rs | 1 - library/proc_macro/src/lib.rs | 1 - library/std/src/sys/process/unsupported.rs | 1 - 4 files changed, 5 deletions(-) diff --git a/library/core/src/escape.rs b/library/core/src/escape.rs index f459c58270818..940daeee7184c 100644 --- a/library/core/src/escape.rs +++ b/library/core/src/escape.rs @@ -167,13 +167,11 @@ union MaybeEscapedCharacter { /// Marker type to indicate that the character is always escaped, /// used to optimize the iterator implementation. #[derive(Clone, Copy)] -#[non_exhaustive] pub(crate) struct AlwaysEscaped; /// Marker type to indicate that the character may be escaped, /// used to optimize the iterator implementation. #[derive(Clone, Copy)] -#[non_exhaustive] pub(crate) struct MaybeEscaped; /// An iterator over a possibly escaped character. diff --git a/library/core/src/mem/type_info.rs b/library/core/src/mem/type_info.rs index 66f85dab7b6c9..51ad9bfed050e 100644 --- a/library/core/src/mem/type_info.rs +++ b/library/core/src/mem/type_info.rs @@ -20,7 +20,6 @@ pub struct Type { /// Info of a trait implementation, you can retrieve the vtable with [Self::get_vtable] #[derive(Debug, PartialEq, Eq)] #[unstable(feature = "type_info", issue = "146922")] -#[non_exhaustive] pub struct TraitImpl { pub(crate) vtable: DynMetadata, } diff --git a/library/proc_macro/src/lib.rs b/library/proc_macro/src/lib.rs index 2cba4b52fc276..2f026fb81ee1b 100644 --- a/library/proc_macro/src/lib.rs +++ b/library/proc_macro/src/lib.rs @@ -245,7 +245,6 @@ impl !Sync for TokenStream {} /// The contained error message is explicitly not guaranteed to be stable in any way, /// and may change between Rust versions or across compilations. #[stable(feature = "proc_macro_lib", since = "1.15.0")] -#[non_exhaustive] #[derive(Debug)] pub struct LexError(String); diff --git a/library/std/src/sys/process/unsupported.rs b/library/std/src/sys/process/unsupported.rs index 114f0001b7faf..f7d7f489ec079 100644 --- a/library/std/src/sys/process/unsupported.rs +++ b/library/std/src/sys/process/unsupported.rs @@ -199,7 +199,6 @@ impl fmt::Debug for Command { } #[derive(PartialEq, Eq, Clone, Copy, Debug, Default)] -#[non_exhaustive] pub struct ExitStatus(); impl ExitStatus { From 321fb2b7d6994bd84d5aacf42d61146ac713447f Mon Sep 17 00:00:00 2001 From: Roland Xu Date: Tue, 11 Aug 2026 23:22:47 +0800 Subject: [PATCH 3/3] Update other tests --- library/coretests/tests/mem/type_info.rs | 2 + .../miri/tests/fail/match/single_variant.rs | 2 +- .../tests/fail/match/single_variant_uninit.rs | 2 +- tests/ui/attributes/malformed-attrs.rs | 1 + tests/ui/attributes/malformed-attrs.stderr | 29 ++++++++----- .../match/non-exhaustive-match.rs | 2 + .../match/non-exhaustive-match.stderr | 12 +++--- .../feature-gate-cfg-target-compact.rs | 1 + .../feature-gate-cfg-target-compact.stderr | 14 +++++-- tests/ui/lint/improper-ctypes/lint-enum.rs | 1 + .../ui/lint/improper-ctypes/lint-enum.stderr | 42 +++++++++---------- ...ing-copy-implementations-non-exhaustive.rs | 1 + tests/ui/macros/macros-nonfatal-errors.rs | 2 + tests/ui/macros/macros-nonfatal-errors.stderr | 30 ++++++------- tests/ui/match/match_non_exhaustive.rs | 1 + tests/ui/match/match_non_exhaustive.stderr | 8 ++-- .../borrowck-non-exhaustive.rs | 1 + .../borrowck-non-exhaustive.stderr | 4 +- .../invalid-attribute.rs | 1 + .../invalid-attribute.stderr | 6 +-- .../omitted-patterns.rs | 1 + .../omitted-patterns.stderr | 40 +++++++++--------- .../uninhabited/coercions_same_crate.rs | 2 + .../uninhabited/coercions_same_crate.stderr | 8 ++-- .../uninhabited/indirect_match_same_crate.rs | 2 + ...tch_with_exhaustive_patterns_same_crate.rs | 2 + .../uninhabited/match_same_crate.rs | 2 + ...tch_with_exhaustive_patterns_same_crate.rs | 1 + .../uninhabited/patterns_same_crate.rs | 1 + .../uninhabited/patterns_same_crate.stderr | 10 ++--- .../default-field-values-non_exhaustive.rs | 2 + ...default-field-values-non_exhaustive.stderr | 4 +- 32 files changed, 139 insertions(+), 98 deletions(-) diff --git a/library/coretests/tests/mem/type_info.rs b/library/coretests/tests/mem/type_info.rs index 095419b8792b1..995fdb7980b2a 100644 --- a/library/coretests/tests/mem/type_info.rs +++ b/library/coretests/tests/mem/type_info.rs @@ -123,6 +123,7 @@ fn test_structs() { } const { + #[expect(unused_attributes)] #[non_exhaustive] struct NonExhaustive { a: u8, @@ -224,6 +225,7 @@ fn test_enums() { enum E { Some(u32), None, + #[expect(unused_attributes)] #[non_exhaustive] Foomp { a: (), diff --git a/src/tools/miri/tests/fail/match/single_variant.rs b/src/tools/miri/tests/fail/match/single_variant.rs index 35bb63620ea23..66f1d6af11bf8 100644 --- a/src/tools/miri/tests/fail/match/single_variant.rs +++ b/src/tools/miri/tests/fail/match/single_variant.rs @@ -2,7 +2,7 @@ // at least the semantics don't depend on the crate you're in. // // See: rust-lang/rust#147722 -#![allow(dead_code)] +#![allow(dead_code, unused_attributes)] #[repr(u8)] enum Exhaustive { diff --git a/src/tools/miri/tests/fail/match/single_variant_uninit.rs b/src/tools/miri/tests/fail/match/single_variant_uninit.rs index e04947f996288..18e13cd566e51 100644 --- a/src/tools/miri/tests/fail/match/single_variant_uninit.rs +++ b/src/tools/miri/tests/fail/match/single_variant_uninit.rs @@ -2,7 +2,7 @@ // at least the semantics don't depend on the crate you're in. // // See: rust-lang/rust#147722 -#![allow(dead_code)] +#![allow(dead_code, unused_attributes)] #![allow(unreachable_patterns)] #[repr(u8)] diff --git a/tests/ui/attributes/malformed-attrs.rs b/tests/ui/attributes/malformed-attrs.rs index d5f663020f3e0..5e96ef2cfb58e 100644 --- a/tests/ui/attributes/malformed-attrs.rs +++ b/tests/ui/attributes/malformed-attrs.rs @@ -198,6 +198,7 @@ mod yooo { #[non_exhaustive = 1] //~^ ERROR malformed +//~^^ WARN `#[non_exhaustive]` has no effect on an unreachable item enum Slenum { } diff --git a/tests/ui/attributes/malformed-attrs.stderr b/tests/ui/attributes/malformed-attrs.stderr index 213e017a6be4d..40b7875cf8e74 100644 --- a/tests/ui/attributes/malformed-attrs.stderr +++ b/tests/ui/attributes/malformed-attrs.stderr @@ -23,7 +23,7 @@ LL | #[cfg_attr(predicate, attr1, attr2, ...)] | ++++++++++++++++++++++++++++++ error[E0463]: can't find crate for `wloop` - --> $DIR/malformed-attrs.rs:213:1 + --> $DIR/malformed-attrs.rs:214:1 | LL | extern crate wloop; | ^^^^^^^^^^^^^^^^^^^ can't find crate @@ -755,7 +755,7 @@ LL + #[non_exhaustive] | error[E0565]: malformed `thread_local` attribute input - --> $DIR/malformed-attrs.rs:205:3 + --> $DIR/malformed-attrs.rs:206:3 | LL | #[thread_local()] | ^^^^^^^^^^^^-- @@ -769,7 +769,7 @@ LL + #[thread_local] | error[E0565]: malformed `no_link` attribute input - --> $DIR/malformed-attrs.rs:209:3 + --> $DIR/malformed-attrs.rs:210:3 | LL | #[no_link()] | ^^^^^^^-- @@ -783,7 +783,7 @@ LL + #[no_link] | error[E0539]: malformed `macro_use` attribute input - --> $DIR/malformed-attrs.rs:211:3 + --> $DIR/malformed-attrs.rs:212:3 | LL | #[macro_use = 1] | ^^^^^^^^^^--- @@ -801,7 +801,7 @@ LL + #[macro_use(name1, name2, ...)] | error[E0539]: malformed `macro_export` attribute input - --> $DIR/malformed-attrs.rs:216:3 + --> $DIR/malformed-attrs.rs:217:3 | LL | #[macro_export = 18] | ^^^^^^^^^^^^^---- @@ -818,7 +818,7 @@ LL + #[macro_export(local_inner_macros)] | error[E0658]: the `allow_internal_unsafe` attribute side-steps the `unsafe_code` lint - --> $DIR/malformed-attrs.rs:218:3 + --> $DIR/malformed-attrs.rs:219:3 | LL | #[allow_internal_unsafe = 1] | ^^^^^^^^^^^^^^^^^^^^^ @@ -827,7 +827,7 @@ LL | #[allow_internal_unsafe = 1] = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0565]: malformed `allow_internal_unsafe` attribute input - --> $DIR/malformed-attrs.rs:218:3 + --> $DIR/malformed-attrs.rs:219:3 | LL | #[allow_internal_unsafe = 1] | ^^^^^^^^^^^^^^^^^^^^^^--- @@ -852,6 +852,14 @@ LL | | #[coroutine = 63] || {} LL | | } | |_- not a `const fn` +warning: `#[non_exhaustive]` has no effect on an unreachable item + --> $DIR/malformed-attrs.rs:199:1 + | +LL | #[non_exhaustive = 1] + | ^^^^^^^^^^^^^^^^^^^^^ + | + = note: requested on the command line with `-W unused-attributes` + error: valid forms for the attribute are `doc = "string"`, `doc(alias)`, `doc(attribute)`, `doc(auto_cfg)`, `doc(cfg)`, `doc(fake_variadic)`, `doc(hidden)`, `doc(html_favicon_url)`, `doc(html_logo_url)`, `doc(html_no_source)`, `doc(html_playground_url)`, `doc(html_root_url)`, `doc(include)`, `doc(inline)`, `doc(issue_tracker_base_url)`, `doc(keyword)`, `doc(masked)`, `doc(no_default_passes)`, `doc(no_inline)`, `doc(notable_trait)`, `doc(passes)`, `doc(plugins)`, `doc(rust_logo)`, `doc(search_unbox)`, `doc(spotlight)`, and `doc(test)` --> $DIR/malformed-attrs.rs:41:3 | @@ -888,7 +896,6 @@ LL | | #[coroutine = 63] || {} ... | LL | | } | |_^ - = note: requested on the command line with `-W unused-attributes` error: valid forms for the attribute are `doc = "string"`, `doc(alias)`, `doc(attribute)`, `doc(auto_cfg)`, `doc(cfg)`, `doc(fake_variadic)`, `doc(hidden)`, `doc(html_favicon_url)`, `doc(html_logo_url)`, `doc(html_no_source)`, `doc(html_playground_url)`, `doc(html_root_url)`, `doc(include)`, `doc(inline)`, `doc(issue_tracker_base_url)`, `doc(keyword)`, `doc(masked)`, `doc(no_default_passes)`, `doc(no_inline)`, `doc(notable_trait)`, `doc(passes)`, `doc(plugins)`, `doc(rust_logo)`, `doc(search_unbox)`, `doc(spotlight)`, and `doc(test)` --> $DIR/malformed-attrs.rs:79:3 @@ -965,7 +972,7 @@ LL | #[automatically_derived = 18] = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! error: valid forms for the attribute are `ignore` and `ignore = "reason"` - --> $DIR/malformed-attrs.rs:225:3 + --> $DIR/malformed-attrs.rs:226:3 | LL | #[ignore = 1] | ^^^^^^^^^^ @@ -984,7 +991,7 @@ LL | #[coroutine = 63] || {} = note: expected unit type `()` found coroutine `{coroutine@$DIR/malformed-attrs.rs:118:23: 118:25}` -error: aborting due to 74 previous errors; 8 warnings emitted +error: aborting due to 74 previous errors; 9 warnings emitted Some errors have detailed explanations: E0308, E0463, E0539, E0565, E0658, E0805. For more information about an error, try `rustc --explain E0308`. @@ -1012,7 +1019,7 @@ LL | #[ignore()] Future breakage diagnostic: error: valid forms for the attribute are `ignore` and `ignore = "reason"` - --> $DIR/malformed-attrs.rs:225:3 + --> $DIR/malformed-attrs.rs:226:3 | LL | #[ignore = 1] | ^^^^^^^^^^ diff --git a/tests/ui/closures/2229_closure_analysis/match/non-exhaustive-match.rs b/tests/ui/closures/2229_closure_analysis/match/non-exhaustive-match.rs index f47d70b52f200..0b520679c460f 100644 --- a/tests/ui/closures/2229_closure_analysis/match/non-exhaustive-match.rs +++ b/tests/ui/closures/2229_closure_analysis/match/non-exhaustive-match.rs @@ -8,9 +8,11 @@ */ // Ignore non_exhaustive in the same crate +#[expect(unused_attributes)] #[non_exhaustive] enum L1 { A, B } +#[expect(unused_attributes)] #[non_exhaustive] enum L2 { C } diff --git a/tests/ui/closures/2229_closure_analysis/match/non-exhaustive-match.stderr b/tests/ui/closures/2229_closure_analysis/match/non-exhaustive-match.stderr index e34d1889803a9..5ade05be3cf33 100644 --- a/tests/ui/closures/2229_closure_analysis/match/non-exhaustive-match.stderr +++ b/tests/ui/closures/2229_closure_analysis/match/non-exhaustive-match.stderr @@ -1,11 +1,11 @@ error[E0004]: non-exhaustive patterns: `L1::B` not covered - --> $DIR/non-exhaustive-match.rs:28:25 + --> $DIR/non-exhaustive-match.rs:30:25 | LL | let _b = || { match l1 { L1::A => () } }; | ^^ pattern `L1::B` not covered | note: `L1` defined here - --> $DIR/non-exhaustive-match.rs:12:6 + --> $DIR/non-exhaustive-match.rs:13:6 | LL | enum L1 { A, B } | ^^ - not covered @@ -16,7 +16,7 @@ LL | let _b = || { match l1 { L1::A => (), L1::B => todo!() } }; | ++++++++++++++++++ error[E0004]: non-exhaustive patterns: type `E1` is non-empty - --> $DIR/non-exhaustive-match.rs:33:25 + --> $DIR/non-exhaustive-match.rs:35:25 | LL | let _d = || { match e1 {} }; | ^^ @@ -35,7 +35,7 @@ LL ~ } }; | error[E0004]: non-exhaustive patterns: `_` not covered - --> $DIR/non-exhaustive-match.rs:35:25 + --> $DIR/non-exhaustive-match.rs:37:25 | LL | let _e = || { match e2 { E2::A => (), E2::B => () } }; | ^^ pattern `_` not covered @@ -53,7 +53,7 @@ LL | let _e = || { match e2 { E2::A => (), E2::B => (), _ => todo!() } }; | ++++++++++++++ error[E0505]: cannot move out of `l2` because it is borrowed - --> $DIR/non-exhaustive-match.rs:42:22 + --> $DIR/non-exhaustive-match.rs:44:22 | LL | let _c = || { match l2 { L2::C => (), _ => () } }; | -- -- borrow occurs due to use in closure @@ -66,7 +66,7 @@ LL | _c(); | -- borrow later used here error[E0505]: cannot move out of `e3` because it is borrowed - --> $DIR/non-exhaustive-match.rs:48:22 + --> $DIR/non-exhaustive-match.rs:50:22 | LL | let _g = || { match e3 { E3::C => (), _ => () } }; | -- -- borrow occurs due to use in closure diff --git a/tests/ui/feature-gates/feature-gate-cfg-target-compact.rs b/tests/ui/feature-gates/feature-gate-cfg-target-compact.rs index e9dd81cea1bfd..7362508a020a2 100644 --- a/tests/ui/feature-gates/feature-gate-cfg-target-compact.rs +++ b/tests/ui/feature-gates/feature-gate-cfg-target-compact.rs @@ -2,6 +2,7 @@ struct Foo(u64, u64); #[cfg_attr(target(os = "linux"), non_exhaustive)] //~ ERROR compact `cfg(target(..))` is experimental +//~^ WARN `#[non_exhaustive]` has no effect on an unreachable item struct Bar(u64, u64); #[cfg(not(any(all(target(os = "linux")))))] //~ ERROR compact `cfg(target(..))` is experimental diff --git a/tests/ui/feature-gates/feature-gate-cfg-target-compact.stderr b/tests/ui/feature-gates/feature-gate-cfg-target-compact.stderr index 75c5ab37a4dce..a06adc02d8422 100644 --- a/tests/ui/feature-gates/feature-gate-cfg-target-compact.stderr +++ b/tests/ui/feature-gates/feature-gate-cfg-target-compact.stderr @@ -19,7 +19,7 @@ LL | #[cfg_attr(target(os = "linux"), non_exhaustive)] = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: compact `cfg(target(..))` is experimental and subject to change - --> $DIR/feature-gate-cfg-target-compact.rs:7:19 + --> $DIR/feature-gate-cfg-target-compact.rs:8:19 | LL | #[cfg(not(any(all(target(os = "linux")))))] | ^^^^^^^^^^^^^^^^^^^^ @@ -29,7 +29,7 @@ LL | #[cfg(not(any(all(target(os = "linux")))))] = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: compact `cfg(target(..))` is experimental and subject to change - --> $DIR/feature-gate-cfg-target-compact.rs:11:10 + --> $DIR/feature-gate-cfg-target-compact.rs:12:10 | LL | cfg!(target(os = "linux")); | ^^^^^^^^^^^^^^^^^^^^ @@ -38,6 +38,14 @@ LL | cfg!(target(os = "linux")); = help: add `#![feature(cfg_target_compact)]` to the crate attributes to enable = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date -error: aborting due to 4 previous errors +warning: `#[non_exhaustive]` has no effect on an unreachable item + --> $DIR/feature-gate-cfg-target-compact.rs:4:34 + | +LL | #[cfg_attr(target(os = "linux"), non_exhaustive)] + | ^^^^^^^^^^^^^^ + | + = note: requested on the command line with `-W unused-attributes` + +error: aborting due to 4 previous errors; 1 warning emitted For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/lint/improper-ctypes/lint-enum.rs b/tests/ui/lint/improper-ctypes/lint-enum.rs index f900f998d06cb..e6151c9e8880e 100644 --- a/tests/ui/lint/improper-ctypes/lint-enum.rs +++ b/tests/ui/lint/improper-ctypes/lint-enum.rs @@ -74,6 +74,7 @@ struct NoField; #[repr(transparent)] struct Field(()); +#[expect(unused_attributes)] #[non_exhaustive] enum NonExhaustive {} diff --git a/tests/ui/lint/improper-ctypes/lint-enum.stderr b/tests/ui/lint/improper-ctypes/lint-enum.stderr index 35d1dcb87fd82..7b2da369532e3 100644 --- a/tests/ui/lint/improper-ctypes/lint-enum.stderr +++ b/tests/ui/lint/improper-ctypes/lint-enum.stderr @@ -1,5 +1,5 @@ error: `extern` block uses type `U`, which is not FFI-safe - --> $DIR/lint-enum.rs:82:14 + --> $DIR/lint-enum.rs:83:14 | LL | fn uf(x: U); | ^ not FFI-safe @@ -18,7 +18,7 @@ LL | #![deny(improper_ctypes)] | ^^^^^^^^^^^^^^^ error: `extern` block uses type `B`, which is not FFI-safe - --> $DIR/lint-enum.rs:83:14 + --> $DIR/lint-enum.rs:84:14 | LL | fn bf(x: B); | ^ not FFI-safe @@ -32,7 +32,7 @@ LL | enum B { | ^^^^^^ error: `extern` block uses type `T`, which is not FFI-safe - --> $DIR/lint-enum.rs:84:14 + --> $DIR/lint-enum.rs:85:14 | LL | fn tf(x: T); | ^ not FFI-safe @@ -46,7 +46,7 @@ LL | enum T { | ^^^^^^ error: `extern` block uses type `Option>>`, which is not FFI-safe - --> $DIR/lint-enum.rs:108:36 + --> $DIR/lint-enum.rs:109:36 | LL | fn option_transparent_union(x: Option>>); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe @@ -55,7 +55,7 @@ LL | fn option_transparent_union(x: Option = note: enum has no representation hint error: `extern` block uses type `Option>>`, which is not FFI-safe - --> $DIR/lint-enum.rs:110:28 + --> $DIR/lint-enum.rs:111:28 | LL | fn option_repr_rust(x: Option>>); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe @@ -64,7 +64,7 @@ LL | fn option_repr_rust(x: Option>>); = note: enum has no representation hint error: `extern` block uses type `Option`, which is not FFI-safe - --> $DIR/lint-enum.rs:111:21 + --> $DIR/lint-enum.rs:112:21 | LL | fn option_u8(x: Option); | ^^^^^^^^^^ not FFI-safe @@ -73,7 +73,7 @@ LL | fn option_u8(x: Option); = note: enum has no representation hint error: `extern` block uses type `Result>, ()>`, which is not FFI-safe - --> $DIR/lint-enum.rs:131:38 + --> $DIR/lint-enum.rs:132:38 | LL | fn result_transparent_union_t(x: Result>, ()>); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe @@ -82,7 +82,7 @@ LL | fn result_transparent_union_t(x: Result>, ()>`, which is not FFI-safe - --> $DIR/lint-enum.rs:133:30 + --> $DIR/lint-enum.rs:134:30 | LL | fn result_repr_rust_t(x: Result>, ()>); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe @@ -91,7 +91,7 @@ LL | fn result_repr_rust_t(x: Result>, ()>); = note: enum has no representation hint error: `extern` block uses type `Result, U>`, which is not FFI-safe - --> $DIR/lint-enum.rs:137:51 + --> $DIR/lint-enum.rs:138:51 | LL | fn result_1zst_exhaustive_single_variant_t(x: Result, U>); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe @@ -100,7 +100,7 @@ LL | fn result_1zst_exhaustive_single_variant_t(x: Result, = note: enum has no representation hint error: `extern` block uses type `Result, B>`, which is not FFI-safe - --> $DIR/lint-enum.rs:139:53 + --> $DIR/lint-enum.rs:140:53 | LL | fn result_1zst_exhaustive_multiple_variant_t(x: Result, B>); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe @@ -109,7 +109,7 @@ LL | fn result_1zst_exhaustive_multiple_variant_t(x: Result = note: enum has no representation hint error: `extern` block uses type `Result, NonExhaustive>`, which is not FFI-safe - --> $DIR/lint-enum.rs:141:51 + --> $DIR/lint-enum.rs:142:51 | LL | fn result_1zst_non_exhaustive_no_variant_t(x: Result, NonExhaustive>); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe @@ -118,7 +118,7 @@ LL | fn result_1zst_non_exhaustive_no_variant_t(x: Result, = note: enum has no representation hint error: `extern` block uses type `Result, Field>`, which is not FFI-safe - --> $DIR/lint-enum.rs:144:49 + --> $DIR/lint-enum.rs:145:49 | LL | fn result_1zst_exhaustive_single_field_t(x: Result, Field>); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe @@ -127,7 +127,7 @@ LL | fn result_1zst_exhaustive_single_field_t(x: Result, Fi = note: enum has no representation hint error: `extern` block uses type `Result>, ()>`, which is not FFI-safe - --> $DIR/lint-enum.rs:146:30 + --> $DIR/lint-enum.rs:147:30 | LL | fn result_cascading_t(x: Result>, ()>); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe @@ -136,7 +136,7 @@ LL | fn result_cascading_t(x: Result>, ()>); = note: enum has no representation hint error: `extern` block uses type `Result<(), TransparentUnion>>`, which is not FFI-safe - --> $DIR/lint-enum.rs:167:38 + --> $DIR/lint-enum.rs:168:38 | LL | fn result_transparent_union_e(x: Result<(), TransparentUnion>>); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe @@ -145,7 +145,7 @@ LL | fn result_transparent_union_e(x: Result<(), TransparentUnion>>`, which is not FFI-safe - --> $DIR/lint-enum.rs:169:30 + --> $DIR/lint-enum.rs:170:30 | LL | fn result_repr_rust_e(x: Result<(), Rust>>); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe @@ -154,7 +154,7 @@ LL | fn result_repr_rust_e(x: Result<(), Rust>>); = note: enum has no representation hint error: `extern` block uses type `Result>`, which is not FFI-safe - --> $DIR/lint-enum.rs:173:51 + --> $DIR/lint-enum.rs:174:51 | LL | fn result_1zst_exhaustive_single_variant_e(x: Result>); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe @@ -163,7 +163,7 @@ LL | fn result_1zst_exhaustive_single_variant_e(x: Result>`, which is not FFI-safe - --> $DIR/lint-enum.rs:175:53 + --> $DIR/lint-enum.rs:176:53 | LL | fn result_1zst_exhaustive_multiple_variant_e(x: Result>); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe @@ -172,7 +172,7 @@ LL | fn result_1zst_exhaustive_multiple_variant_e(x: Result>`, which is not FFI-safe - --> $DIR/lint-enum.rs:177:51 + --> $DIR/lint-enum.rs:178:51 | LL | fn result_1zst_non_exhaustive_no_variant_e(x: Result>); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe @@ -181,7 +181,7 @@ LL | fn result_1zst_non_exhaustive_no_variant_e(x: Result>`, which is not FFI-safe - --> $DIR/lint-enum.rs:180:49 + --> $DIR/lint-enum.rs:181:49 | LL | fn result_1zst_exhaustive_single_field_e(x: Result>); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe @@ -190,7 +190,7 @@ LL | fn result_1zst_exhaustive_single_field_e(x: Result>>`, which is not FFI-safe - --> $DIR/lint-enum.rs:182:30 + --> $DIR/lint-enum.rs:183:30 | LL | fn result_cascading_e(x: Result<(), Result<(), num::NonZero>>); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe @@ -199,7 +199,7 @@ LL | fn result_cascading_e(x: Result<(), Result<(), num::NonZero>>); = note: enum has no representation hint error: `extern` block uses type `Result<(), ()>`, which is not FFI-safe - --> $DIR/lint-enum.rs:184:27 + --> $DIR/lint-enum.rs:185:27 | LL | fn result_unit_t_e(x: Result<(), ()>); | ^^^^^^^^^^^^^^ not FFI-safe diff --git a/tests/ui/lint/missing-copy-implementations-non-exhaustive.rs b/tests/ui/lint/missing-copy-implementations-non-exhaustive.rs index 16f448674b29a..3bdef9c20033d 100644 --- a/tests/ui/lint/missing-copy-implementations-non-exhaustive.rs +++ b/tests/ui/lint/missing-copy-implementations-non-exhaustive.rs @@ -11,6 +11,7 @@ pub enum MyEnum { A, } +#[expect(unused_attributes)] #[non_exhaustive] pub struct MyStruct { foo: usize, diff --git a/tests/ui/macros/macros-nonfatal-errors.rs b/tests/ui/macros/macros-nonfatal-errors.rs index 1349d7415105b..83d8c4635aaf9 100644 --- a/tests/ui/macros/macros-nonfatal-errors.rs +++ b/tests/ui/macros/macros-nonfatal-errors.rs @@ -95,6 +95,7 @@ enum DefaultHasFields { #[derive(Default)] enum NonExhaustiveDefault { #[default] + #[expect(unused_attributes)] #[non_exhaustive] Foo, //~ ERROR default variant must be exhaustive Bar, @@ -127,6 +128,7 @@ const _: () = { #[derive(Default)] enum NonExhaustiveDefaultGeneric { #[default] + #[expect(unused_attributes)] #[non_exhaustive] Foo, //~ ERROR default variant must be exhaustive Bar(T), diff --git a/tests/ui/macros/macros-nonfatal-errors.stderr b/tests/ui/macros/macros-nonfatal-errors.stderr index bc34bd1c8ec8f..0612d25651aca 100644 --- a/tests/ui/macros/macros-nonfatal-errors.stderr +++ b/tests/ui/macros/macros-nonfatal-errors.stderr @@ -150,7 +150,7 @@ LL | Foo {}, = help: consider a manual implementation of `Default` error: default variant must be exhaustive - --> $DIR/macros-nonfatal-errors.rs:99:5 + --> $DIR/macros-nonfatal-errors.rs:100:5 | LL | #[non_exhaustive] | ----------------- declared `#[non_exhaustive]` here @@ -160,31 +160,31 @@ LL | Foo, = help: consider a manual implementation of `Default` error: asm template must be a string literal - --> $DIR/macros-nonfatal-errors.rs:104:10 + --> $DIR/macros-nonfatal-errors.rs:105:10 | LL | asm!(invalid); | ^^^^^^^ error: argument must be a string literal - --> $DIR/macros-nonfatal-errors.rs:107:17 + --> $DIR/macros-nonfatal-errors.rs:108:17 | LL | option_env!(invalid); | ^^^^^^^ error: expected string literal - --> $DIR/macros-nonfatal-errors.rs:108:10 + --> $DIR/macros-nonfatal-errors.rs:109:10 | LL | env!(invalid); | ^^^^^^^ error: `env!()` takes 1 or 2 arguments - --> $DIR/macros-nonfatal-errors.rs:109:5 + --> $DIR/macros-nonfatal-errors.rs:110:5 | LL | env!(foo, abr, baz); | ^^^^^^^^^^^^^^^^^^^ error: environment variable `RUST_HOPEFULLY_THIS_DOESNT_EXIST` not defined at compile time - --> $DIR/macros-nonfatal-errors.rs:110:5 + --> $DIR/macros-nonfatal-errors.rs:111:5 | LL | env!("RUST_HOPEFULLY_THIS_DOESNT_EXIST"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -192,7 +192,7 @@ LL | env!("RUST_HOPEFULLY_THIS_DOESNT_EXIST"); = help: use `std::env::var("RUST_HOPEFULLY_THIS_DOESNT_EXIST")` to read the variable at run time error: format argument must be a string literal - --> $DIR/macros-nonfatal-errors.rs:112:13 + --> $DIR/macros-nonfatal-errors.rs:113:13 | LL | format!(invalid); | ^^^^^^^ @@ -203,43 +203,43 @@ LL | format!("{}", invalid); | +++++ error: argument must be a string literal - --> $DIR/macros-nonfatal-errors.rs:114:14 + --> $DIR/macros-nonfatal-errors.rs:115:14 | LL | include!(invalid); | ^^^^^^^ error: argument must be a string literal - --> $DIR/macros-nonfatal-errors.rs:116:18 + --> $DIR/macros-nonfatal-errors.rs:117:18 | LL | include_str!(invalid); | ^^^^^^^ error: couldn't read `$DIR/i'd be quite surprised if a file with this name existed`: $FILE_NOT_FOUND_MSG - --> $DIR/macros-nonfatal-errors.rs:117:5 + --> $DIR/macros-nonfatal-errors.rs:118:5 | LL | include_str!("i'd be quite surprised if a file with this name existed"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: argument must be a string literal - --> $DIR/macros-nonfatal-errors.rs:118:20 + --> $DIR/macros-nonfatal-errors.rs:119:20 | LL | include_bytes!(invalid); | ^^^^^^^ error: couldn't read `$DIR/i'd be quite surprised if a file with this name existed`: $FILE_NOT_FOUND_MSG - --> $DIR/macros-nonfatal-errors.rs:119:5 + --> $DIR/macros-nonfatal-errors.rs:120:5 | LL | include_bytes!("i'd be quite surprised if a file with this name existed"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: trace_macros! accepts only `true` or `false` - --> $DIR/macros-nonfatal-errors.rs:121:5 + --> $DIR/macros-nonfatal-errors.rs:122:5 | LL | trace_macros!(invalid); | ^^^^^^^^^^^^^^^^^^^^^^ error: default variant must be exhaustive - --> $DIR/macros-nonfatal-errors.rs:131:9 + --> $DIR/macros-nonfatal-errors.rs:133:9 | LL | #[non_exhaustive] | ----------------- declared `#[non_exhaustive]` here @@ -249,7 +249,7 @@ LL | Foo, = help: consider a manual implementation of `Default` error: cannot find macro `llvm_asm` in this scope - --> $DIR/macros-nonfatal-errors.rs:105:5 + --> $DIR/macros-nonfatal-errors.rs:106:5 | LL | llvm_asm!(invalid); | ^^^^^^^^ diff --git a/tests/ui/match/match_non_exhaustive.rs b/tests/ui/match/match_non_exhaustive.rs index 25ff0942833fe..35df586e9e128 100644 --- a/tests/ui/match/match_non_exhaustive.rs +++ b/tests/ui/match/match_non_exhaustive.rs @@ -6,6 +6,7 @@ */ // Ignore non_exhaustive in the same crate +#[expect(unused_attributes)] #[non_exhaustive] enum L { A, B } diff --git a/tests/ui/match/match_non_exhaustive.stderr b/tests/ui/match/match_non_exhaustive.stderr index 40be39ec07747..f60575f8c9ba0 100644 --- a/tests/ui/match/match_non_exhaustive.stderr +++ b/tests/ui/match/match_non_exhaustive.stderr @@ -1,11 +1,11 @@ error[E0004]: non-exhaustive patterns: `L::B` not covered - --> $DIR/match_non_exhaustive.rs:23:11 + --> $DIR/match_non_exhaustive.rs:24:11 | LL | match l { L::A => () }; | ^ pattern `L::B` not covered | note: `L` defined here - --> $DIR/match_non_exhaustive.rs:10:6 + --> $DIR/match_non_exhaustive.rs:11:6 | LL | enum L { A, B } | ^ - not covered @@ -16,7 +16,7 @@ LL | match l { L::A => (), L::B => todo!() }; | +++++++++++++++++ error[E0004]: non-exhaustive patterns: type `E1` is non-empty - --> $DIR/match_non_exhaustive.rs:28:11 + --> $DIR/match_non_exhaustive.rs:29:11 | LL | match e1 {}; | ^^ @@ -35,7 +35,7 @@ LL ~ }; | error[E0004]: non-exhaustive patterns: `_` not covered - --> $DIR/match_non_exhaustive.rs:30:11 + --> $DIR/match_non_exhaustive.rs:31:11 | LL | match e2 { E2::A => (), E2::B => () }; | ^^ pattern `_` not covered diff --git a/tests/ui/rfcs/rfc-2008-non-exhaustive/borrowck-non-exhaustive.rs b/tests/ui/rfcs/rfc-2008-non-exhaustive/borrowck-non-exhaustive.rs index a6a369e92a6c4..cbe41fcafd960 100644 --- a/tests/ui/rfcs/rfc-2008-non-exhaustive/borrowck-non-exhaustive.rs +++ b/tests/ui/rfcs/rfc-2008-non-exhaustive/borrowck-non-exhaustive.rs @@ -6,6 +6,7 @@ extern crate monovariants; use monovariants::NonExhaustiveMonovariant; +#[expect(unused_attributes)] #[non_exhaustive] enum LocalNonExhaustive { Variant(u32), diff --git a/tests/ui/rfcs/rfc-2008-non-exhaustive/borrowck-non-exhaustive.stderr b/tests/ui/rfcs/rfc-2008-non-exhaustive/borrowck-non-exhaustive.stderr index d6225adc95cb5..eceafb90564d2 100644 --- a/tests/ui/rfcs/rfc-2008-non-exhaustive/borrowck-non-exhaustive.stderr +++ b/tests/ui/rfcs/rfc-2008-non-exhaustive/borrowck-non-exhaustive.stderr @@ -1,5 +1,5 @@ error[E0503]: cannot use `x` because it was mutably borrowed - --> $DIR/borrowck-non-exhaustive.rs:17:11 + --> $DIR/borrowck-non-exhaustive.rs:18:11 | LL | let y = &mut x; | ------ `x` is borrowed here @@ -10,7 +10,7 @@ LL | drop(y); | - borrow later used here error[E0503]: cannot use `x` because it was mutably borrowed - --> $DIR/borrowck-non-exhaustive.rs:25:11 + --> $DIR/borrowck-non-exhaustive.rs:26:11 | LL | let y = &mut x; | ------ `x` is borrowed here diff --git a/tests/ui/rfcs/rfc-2008-non-exhaustive/invalid-attribute.rs b/tests/ui/rfcs/rfc-2008-non-exhaustive/invalid-attribute.rs index b538a97280d5c..208f0f6779df7 100644 --- a/tests/ui/rfcs/rfc-2008-non-exhaustive/invalid-attribute.rs +++ b/tests/ui/rfcs/rfc-2008-non-exhaustive/invalid-attribute.rs @@ -1,3 +1,4 @@ +#[expect(unused_attributes)] #[non_exhaustive(anything)] //~^ ERROR malformed `non_exhaustive` attribute struct Foo; diff --git a/tests/ui/rfcs/rfc-2008-non-exhaustive/invalid-attribute.stderr b/tests/ui/rfcs/rfc-2008-non-exhaustive/invalid-attribute.stderr index 09a6d30a0d9f1..9e01f1224e83a 100644 --- a/tests/ui/rfcs/rfc-2008-non-exhaustive/invalid-attribute.stderr +++ b/tests/ui/rfcs/rfc-2008-non-exhaustive/invalid-attribute.stderr @@ -1,5 +1,5 @@ error[E0565]: malformed `non_exhaustive` attribute input - --> $DIR/invalid-attribute.rs:1:3 + --> $DIR/invalid-attribute.rs:2:3 | LL | #[non_exhaustive(anything)] | ^^^^^^^^^^^^^^---------- @@ -13,7 +13,7 @@ LL + #[non_exhaustive] | error: the `non_exhaustive` attribute cannot be used on traits - --> $DIR/invalid-attribute.rs:5:3 + --> $DIR/invalid-attribute.rs:6:3 | LL | #[non_exhaustive] | ^^^^^^^^^^^^^^ @@ -21,7 +21,7 @@ LL | #[non_exhaustive] = help: the `non_exhaustive` attribute can be applied to data types and enum variants error: the `non_exhaustive` attribute cannot be used on unions - --> $DIR/invalid-attribute.rs:9:3 + --> $DIR/invalid-attribute.rs:10:3 | LL | #[non_exhaustive] | ^^^^^^^^^^^^^^ diff --git a/tests/ui/rfcs/rfc-2008-non-exhaustive/omitted-patterns.rs b/tests/ui/rfcs/rfc-2008-non-exhaustive/omitted-patterns.rs index 1e746fdbbeaa5..f6aecb91b8c48 100644 --- a/tests/ui/rfcs/rfc-2008-non-exhaustive/omitted-patterns.rs +++ b/tests/ui/rfcs/rfc-2008-non-exhaustive/omitted-patterns.rs @@ -19,6 +19,7 @@ use enums::{ use structs::{FunctionalRecord, MixedVisFields, NestedStruct, NormalStruct}; use unstable::{OnlyUnstableEnum, OnlyUnstableStruct, UnstableEnum, UnstableStruct}; +#[expect(unused_attributes)] #[non_exhaustive] #[derive(Default)] pub struct Foo { diff --git a/tests/ui/rfcs/rfc-2008-non-exhaustive/omitted-patterns.stderr b/tests/ui/rfcs/rfc-2008-non-exhaustive/omitted-patterns.stderr index f8bf6f8cb28bc..650d693805512 100644 --- a/tests/ui/rfcs/rfc-2008-non-exhaustive/omitted-patterns.stderr +++ b/tests/ui/rfcs/rfc-2008-non-exhaustive/omitted-patterns.stderr @@ -1,5 +1,5 @@ error: some fields are not explicitly listed - --> $DIR/omitted-patterns.rs:141:9 + --> $DIR/omitted-patterns.rs:142:9 | LL | VariantNonExhaustive::Bar { x, .. } => {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ field `y` not listed @@ -7,13 +7,13 @@ LL | VariantNonExhaustive::Bar { x, .. } => {} = help: ensure that all fields are mentioned explicitly by adding the suggested fields = note: the pattern is of type `VariantNonExhaustive` and the `non_exhaustive_omitted_patterns` attribute was found note: the lint level is defined here - --> $DIR/omitted-patterns.rs:47:8 + --> $DIR/omitted-patterns.rs:48:8 | LL | #[deny(non_exhaustive_omitted_patterns)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: some fields are not explicitly listed - --> $DIR/omitted-patterns.rs:145:9 + --> $DIR/omitted-patterns.rs:146:9 | LL | let FunctionalRecord { first_field, second_field, .. } = FunctionalRecord::default(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ field `third_field` not listed @@ -22,7 +22,7 @@ LL | let FunctionalRecord { first_field, second_field, .. } = FunctionalReco = note: the pattern is of type `FunctionalRecord` and the `non_exhaustive_omitted_patterns` attribute was found error: some fields are not explicitly listed - --> $DIR/omitted-patterns.rs:151:29 + --> $DIR/omitted-patterns.rs:152:29 | LL | let NestedStruct { bar: NormalStruct { first_field, .. }, .. } = NestedStruct::default(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ field `second_field` not listed @@ -31,7 +31,7 @@ LL | let NestedStruct { bar: NormalStruct { first_field, .. }, .. } = Nested = note: the pattern is of type `NormalStruct` and the `non_exhaustive_omitted_patterns` attribute was found error: some fields are not explicitly listed - --> $DIR/omitted-patterns.rs:151:9 + --> $DIR/omitted-patterns.rs:152:9 | LL | let NestedStruct { bar: NormalStruct { first_field, .. }, .. } = NestedStruct::default(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ field `foo` not listed @@ -40,7 +40,7 @@ LL | let NestedStruct { bar: NormalStruct { first_field, .. }, .. } = Nested = note: the pattern is of type `NestedStruct` and the `non_exhaustive_omitted_patterns` attribute was found error: some fields are not explicitly listed - --> $DIR/omitted-patterns.rs:214:9 + --> $DIR/omitted-patterns.rs:215:9 | LL | let OnlyUnstableStruct { unstable, .. } = OnlyUnstableStruct::new(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ field `unstable2` not listed @@ -49,7 +49,7 @@ LL | let OnlyUnstableStruct { unstable, .. } = OnlyUnstableStruct::new(); = note: the pattern is of type `OnlyUnstableStruct` and the `non_exhaustive_omitted_patterns` attribute was found error: some fields are not explicitly listed - --> $DIR/omitted-patterns.rs:220:9 + --> $DIR/omitted-patterns.rs:221:9 | LL | let UnstableStruct { stable, stable2, .. } = UnstableStruct::default(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ field `unstable` not listed @@ -58,7 +58,7 @@ LL | let UnstableStruct { stable, stable2, .. } = UnstableStruct::default(); = note: the pattern is of type `UnstableStruct` and the `non_exhaustive_omitted_patterns` attribute was found error: some variants are not matched explicitly - --> $DIR/omitted-patterns.rs:67:11 + --> $DIR/omitted-patterns.rs:68:11 | LL | match non_enum { | ^^^^^^^^ pattern `NonExhaustiveEnum::Struct { .. }` not covered @@ -67,7 +67,7 @@ LL | match non_enum { = note: the matched value is of type `NonExhaustiveEnum` and the `non_exhaustive_omitted_patterns` attribute was found error: some variants are not matched explicitly - --> $DIR/omitted-patterns.rs:74:11 + --> $DIR/omitted-patterns.rs:75:11 | LL | match non_enum { | ^^^^^^^^ pattern `NonExhaustiveEnum::Tuple(_)` not covered @@ -76,7 +76,7 @@ LL | match non_enum { = note: the matched value is of type `NonExhaustiveEnum` and the `non_exhaustive_omitted_patterns` attribute was found error: some variants are not matched explicitly - --> $DIR/omitted-patterns.rs:95:11 + --> $DIR/omitted-patterns.rs:96:11 | LL | match (non_enum, true) { | ^^^^^^^^^^^^^^^^ pattern `(NonExhaustiveEnum::Struct { .. }, _)` not covered @@ -85,7 +85,7 @@ LL | match (non_enum, true) { = note: the matched value is of type `(NonExhaustiveEnum, bool)` and the `non_exhaustive_omitted_patterns` attribute was found error: some variants are not matched explicitly - --> $DIR/omitted-patterns.rs:108:11 + --> $DIR/omitted-patterns.rs:109:11 | LL | match (true, non_enum) { | ^^^^^^^^^^^^^^^^ pattern `(_, NonExhaustiveEnum::Struct { .. })` not covered @@ -94,7 +94,7 @@ LL | match (true, non_enum) { = note: the matched value is of type `(bool, NonExhaustiveEnum)` and the `non_exhaustive_omitted_patterns` attribute was found error: some variants are not matched explicitly - --> $DIR/omitted-patterns.rs:115:11 + --> $DIR/omitted-patterns.rs:116:11 | LL | match Some(non_enum) { | ^^^^^^^^^^^^^^ pattern `Some(NonExhaustiveEnum::Struct { .. })` not covered @@ -103,7 +103,7 @@ LL | match Some(non_enum) { = note: the matched value is of type `Option` and the `non_exhaustive_omitted_patterns` attribute was found error: some variants are not matched explicitly - --> $DIR/omitted-patterns.rs:131:11 + --> $DIR/omitted-patterns.rs:132:11 | LL | match NestedNonExhaustive::B { | ^^^^^^^^^^^^^^^^^^^^^^ patterns `NestedNonExhaustive::C`, `NestedNonExhaustive::A(NonExhaustiveEnum::Tuple(_))` and `NestedNonExhaustive::A(NonExhaustiveEnum::Struct { .. })` not covered @@ -112,7 +112,7 @@ LL | match NestedNonExhaustive::B { = note: the matched value is of type `NestedNonExhaustive` and the `non_exhaustive_omitted_patterns` attribute was found error: some variants are not matched explicitly - --> $DIR/omitted-patterns.rs:186:11 + --> $DIR/omitted-patterns.rs:187:11 | LL | match UnstableEnum::Stable { | ^^^^^^^^^^^^^^^^^^^^ pattern `UnstableEnum::Unstable` not covered @@ -121,7 +121,7 @@ LL | match UnstableEnum::Stable { = note: the matched value is of type `UnstableEnum` and the `non_exhaustive_omitted_patterns` attribute was found error: some variants are not matched explicitly - --> $DIR/omitted-patterns.rs:208:11 + --> $DIR/omitted-patterns.rs:209:11 | LL | match OnlyUnstableEnum::Unstable { | ^^^^^^^^^^^^^^^^^^^^^^^^^^ pattern `OnlyUnstableEnum::Unstable2` not covered @@ -130,7 +130,7 @@ LL | match OnlyUnstableEnum::Unstable { = note: the matched value is of type `OnlyUnstableEnum` and the `non_exhaustive_omitted_patterns` attribute was found error[E0005]: refutable pattern in local binding - --> $DIR/omitted-patterns.rs:230:9 + --> $DIR/omitted-patterns.rs:231:9 | LL | let local_refutable @ NonExhaustiveEnum::Unit = NonExhaustiveEnum::Unit; | ^^^^^^^^^^^^^^^ pattern `_` not covered @@ -144,7 +144,7 @@ LL | let local_refutable @ NonExhaustiveEnum::Unit = NonExhaustiveEnum::Unit | ++++++++++++++++ error: some variants are not matched explicitly - --> $DIR/omitted-patterns.rs:234:11 + --> $DIR/omitted-patterns.rs:235:11 | LL | match &non_enum { | ^^^^^^^^^ pattern `&NonExhaustiveEnum::Struct { .. }` not covered @@ -153,7 +153,7 @@ LL | match &non_enum { = note: the matched value is of type `&NonExhaustiveEnum` and the `non_exhaustive_omitted_patterns` attribute was found error: some variants are not matched explicitly - --> $DIR/omitted-patterns.rs:242:11 + --> $DIR/omitted-patterns.rs:243:11 | LL | match (true, &non_enum) { | ^^^^^^^^^^^^^^^^^ patterns `(_, &NonExhaustiveEnum::Tuple(_))` and `(_, &NonExhaustiveEnum::Struct { .. })` not covered @@ -162,7 +162,7 @@ LL | match (true, &non_enum) { = note: the matched value is of type `(bool, &NonExhaustiveEnum)` and the `non_exhaustive_omitted_patterns` attribute was found error: some variants are not matched explicitly - --> $DIR/omitted-patterns.rs:249:11 + --> $DIR/omitted-patterns.rs:250:11 | LL | match (&non_enum, true) { | ^^^^^^^^^^^^^^^^^ patterns `(&NonExhaustiveEnum::Tuple(_), _)` and `(&NonExhaustiveEnum::Struct { .. }, _)` not covered @@ -171,7 +171,7 @@ LL | match (&non_enum, true) { = note: the matched value is of type `(&NonExhaustiveEnum, bool)` and the `non_exhaustive_omitted_patterns` attribute was found error: some variants are not matched explicitly - --> $DIR/omitted-patterns.rs:256:11 + --> $DIR/omitted-patterns.rs:257:11 | LL | match Some(&non_enum) { | ^^^^^^^^^^^^^^^ pattern `Some(&NonExhaustiveEnum::Struct { .. })` not covered diff --git a/tests/ui/rfcs/rfc-2008-non-exhaustive/uninhabited/coercions_same_crate.rs b/tests/ui/rfcs/rfc-2008-non-exhaustive/uninhabited/coercions_same_crate.rs index 6b911dd989cc5..14b861c8231de 100644 --- a/tests/ui/rfcs/rfc-2008-non-exhaustive/uninhabited/coercions_same_crate.rs +++ b/tests/ui/rfcs/rfc-2008-non-exhaustive/uninhabited/coercions_same_crate.rs @@ -4,9 +4,11 @@ pub enum UninhabitedEnum { } +#[expect(unused_attributes)] #[non_exhaustive] pub struct UninhabitedTupleStruct(!); +#[expect(unused_attributes)] #[non_exhaustive] pub struct UninhabitedStruct { _priv: !, diff --git a/tests/ui/rfcs/rfc-2008-non-exhaustive/uninhabited/coercions_same_crate.stderr b/tests/ui/rfcs/rfc-2008-non-exhaustive/uninhabited/coercions_same_crate.stderr index 289433edf6292..6cae22cd776d8 100644 --- a/tests/ui/rfcs/rfc-2008-non-exhaustive/uninhabited/coercions_same_crate.stderr +++ b/tests/ui/rfcs/rfc-2008-non-exhaustive/uninhabited/coercions_same_crate.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched types - --> $DIR/coercions_same_crate.rs:30:5 + --> $DIR/coercions_same_crate.rs:32:5 | LL | fn cannot_coerce_empty_enum_to_anything(x: UninhabitedEnum) -> A { | - expected `A` because of return type @@ -7,7 +7,7 @@ LL | x | ^ expected `A`, found `UninhabitedEnum` error[E0308]: mismatched types - --> $DIR/coercions_same_crate.rs:34:5 + --> $DIR/coercions_same_crate.rs:36:5 | LL | fn cannot_coerce_empty_tuple_struct_to_anything(x: UninhabitedTupleStruct) -> A { | - expected `A` because of return type @@ -15,7 +15,7 @@ LL | x | ^ expected `A`, found `UninhabitedTupleStruct` error[E0308]: mismatched types - --> $DIR/coercions_same_crate.rs:38:5 + --> $DIR/coercions_same_crate.rs:40:5 | LL | fn cannot_coerce_empty_struct_to_anything(x: UninhabitedStruct) -> A { | - expected `A` because of return type @@ -23,7 +23,7 @@ LL | x | ^ expected `A`, found `UninhabitedStruct` error[E0308]: mismatched types - --> $DIR/coercions_same_crate.rs:42:5 + --> $DIR/coercions_same_crate.rs:44:5 | LL | fn cannot_coerce_enum_with_empty_variants_to_anything(x: UninhabitedVariants) -> A { | - expected `A` because of return type diff --git a/tests/ui/rfcs/rfc-2008-non-exhaustive/uninhabited/indirect_match_same_crate.rs b/tests/ui/rfcs/rfc-2008-non-exhaustive/uninhabited/indirect_match_same_crate.rs index d81896eba1956..b4e9599ca1238 100644 --- a/tests/ui/rfcs/rfc-2008-non-exhaustive/uninhabited/indirect_match_same_crate.rs +++ b/tests/ui/rfcs/rfc-2008-non-exhaustive/uninhabited/indirect_match_same_crate.rs @@ -5,11 +5,13 @@ pub enum UninhabitedEnum { } +#[expect(unused_attributes)] #[non_exhaustive] pub struct UninhabitedStruct { _priv: !, } +#[expect(unused_attributes)] #[non_exhaustive] pub struct UninhabitedTupleStruct(!); diff --git a/tests/ui/rfcs/rfc-2008-non-exhaustive/uninhabited/indirect_match_with_exhaustive_patterns_same_crate.rs b/tests/ui/rfcs/rfc-2008-non-exhaustive/uninhabited/indirect_match_with_exhaustive_patterns_same_crate.rs index 32f5f504136ab..0032986af73a7 100644 --- a/tests/ui/rfcs/rfc-2008-non-exhaustive/uninhabited/indirect_match_with_exhaustive_patterns_same_crate.rs +++ b/tests/ui/rfcs/rfc-2008-non-exhaustive/uninhabited/indirect_match_with_exhaustive_patterns_same_crate.rs @@ -7,11 +7,13 @@ pub enum UninhabitedEnum { } +#[expect(unused_attributes)] #[non_exhaustive] pub struct UninhabitedStruct { _priv: !, } +#[expect(unused_attributes)] #[non_exhaustive] pub struct UninhabitedTupleStruct(!); diff --git a/tests/ui/rfcs/rfc-2008-non-exhaustive/uninhabited/match_same_crate.rs b/tests/ui/rfcs/rfc-2008-non-exhaustive/uninhabited/match_same_crate.rs index 04f7fe26b5ae1..3b28beed6886a 100644 --- a/tests/ui/rfcs/rfc-2008-non-exhaustive/uninhabited/match_same_crate.rs +++ b/tests/ui/rfcs/rfc-2008-non-exhaustive/uninhabited/match_same_crate.rs @@ -5,11 +5,13 @@ pub enum UninhabitedEnum { } +#[expect(unused_attributes)] #[non_exhaustive] pub struct UninhabitedStruct { _priv: !, } +#[expect(unused_attributes)] #[non_exhaustive] pub struct UninhabitedTupleStruct(!); diff --git a/tests/ui/rfcs/rfc-2008-non-exhaustive/uninhabited/match_with_exhaustive_patterns_same_crate.rs b/tests/ui/rfcs/rfc-2008-non-exhaustive/uninhabited/match_with_exhaustive_patterns_same_crate.rs index 9662016221278..7e6e0d2d4857d 100644 --- a/tests/ui/rfcs/rfc-2008-non-exhaustive/uninhabited/match_with_exhaustive_patterns_same_crate.rs +++ b/tests/ui/rfcs/rfc-2008-non-exhaustive/uninhabited/match_with_exhaustive_patterns_same_crate.rs @@ -6,6 +6,7 @@ pub enum UninhabitedEnum { } +#[expect(unused_attributes)] #[non_exhaustive] pub struct UninhabitedStruct { pub never: !, diff --git a/tests/ui/rfcs/rfc-2008-non-exhaustive/uninhabited/patterns_same_crate.rs b/tests/ui/rfcs/rfc-2008-non-exhaustive/uninhabited/patterns_same_crate.rs index 3d89ca15d3778..8ee409973ac71 100644 --- a/tests/ui/rfcs/rfc-2008-non-exhaustive/uninhabited/patterns_same_crate.rs +++ b/tests/ui/rfcs/rfc-2008-non-exhaustive/uninhabited/patterns_same_crate.rs @@ -9,6 +9,7 @@ pub enum UninhabitedEnum { #[non_exhaustive] pub struct UninhabitedTupleStruct(pub !); +#[expect(unused_attributes)] #[non_exhaustive] pub struct UninhabitedStruct { pub never: !, diff --git a/tests/ui/rfcs/rfc-2008-non-exhaustive/uninhabited/patterns_same_crate.stderr b/tests/ui/rfcs/rfc-2008-non-exhaustive/uninhabited/patterns_same_crate.stderr index bd70a7b409149..b7795f0270b9b 100644 --- a/tests/ui/rfcs/rfc-2008-non-exhaustive/uninhabited/patterns_same_crate.stderr +++ b/tests/ui/rfcs/rfc-2008-non-exhaustive/uninhabited/patterns_same_crate.stderr @@ -1,5 +1,5 @@ error: unreachable pattern - --> $DIR/patterns_same_crate.rs:53:9 + --> $DIR/patterns_same_crate.rs:54:9 | LL | Some(_x) => (), | ^^^^^^^^------- @@ -15,7 +15,7 @@ LL | #![deny(unreachable_patterns)] | ^^^^^^^^^^^^^^^^^^^^ error: unreachable pattern - --> $DIR/patterns_same_crate.rs:58:9 + --> $DIR/patterns_same_crate.rs:59:9 | LL | Some(_x) => (), | ^^^^^^^^------- @@ -26,7 +26,7 @@ LL | Some(_x) => (), = note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types error: unreachable pattern - --> $DIR/patterns_same_crate.rs:62:15 + --> $DIR/patterns_same_crate.rs:63:15 | LL | while let PartiallyInhabitedVariants::Struct { x } = partially_inhabited_variant() { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ matches no values because `!` is uninhabited @@ -34,7 +34,7 @@ LL | while let PartiallyInhabitedVariants::Struct { x } = partially_inhabite = note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types error: unreachable pattern - --> $DIR/patterns_same_crate.rs:66:15 + --> $DIR/patterns_same_crate.rs:67:15 | LL | while let Some(_x) = uninhabited_struct() { | ^^^^^^^^ matches no values because `UninhabitedStruct` is uninhabited @@ -42,7 +42,7 @@ LL | while let Some(_x) = uninhabited_struct() { = note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types error: unreachable pattern - --> $DIR/patterns_same_crate.rs:69:15 + --> $DIR/patterns_same_crate.rs:70:15 | LL | while let Some(_x) = uninhabited_tuple_struct() { | ^^^^^^^^ matches no values because `UninhabitedTupleStruct` is uninhabited diff --git a/tests/ui/structs/default-field-values-non_exhaustive.rs b/tests/ui/structs/default-field-values-non_exhaustive.rs index 0ad2b0766a772..1290911d8e5ea 100644 --- a/tests/ui/structs/default-field-values-non_exhaustive.rs +++ b/tests/ui/structs/default-field-values-non_exhaustive.rs @@ -1,6 +1,7 @@ #![feature(default_field_values)] #[derive(Default)] +#[expect(unused_attributes)] #[non_exhaustive] //~ ERROR `#[non_exhaustive]` can't be used to annotate items with default field values struct Foo { x: i32 = 42 + 3, @@ -8,6 +9,7 @@ struct Foo { #[derive(Default)] enum Bar { + #[expect(unused_attributes)] #[non_exhaustive] #[default] Baz { //~ ERROR default variant must be exhaustive diff --git a/tests/ui/structs/default-field-values-non_exhaustive.stderr b/tests/ui/structs/default-field-values-non_exhaustive.stderr index 13013bebe83d9..15a6dde76765e 100644 --- a/tests/ui/structs/default-field-values-non_exhaustive.stderr +++ b/tests/ui/structs/default-field-values-non_exhaustive.stderr @@ -1,5 +1,5 @@ error: default variant must be exhaustive - --> $DIR/default-field-values-non_exhaustive.rs:13:5 + --> $DIR/default-field-values-non_exhaustive.rs:15:5 | LL | #[non_exhaustive] | ----------------- declared `#[non_exhaustive]` here @@ -10,7 +10,7 @@ LL | Baz { = help: consider a manual implementation of `Default` error: `#[non_exhaustive]` can't be used to annotate items with default field values - --> $DIR/default-field-values-non_exhaustive.rs:4:1 + --> $DIR/default-field-values-non_exhaustive.rs:5:1 | LL | #[non_exhaustive] | ^^^^^^^^^^^^^^^^^