Skip to content

Commit cbe67bc

Browse files
committed
Auto merge of rust-lang#11590 - Tyrubias:non_ex_false_positive, r=Alexendoo
Don't lint `manual_non_exhaustive` when enum is `#[non_exhaustive]` Fixes rust-lang#11583 changelog: Fix [`manual_non_exhaustive`] false positive for unit enum variants when enum is explicitly `non_exhaustive`.
2 parents 0e43a04 + 9dfd60c commit cbe67bc

File tree

3 files changed

+13
-32
lines changed

3 files changed

+13
-32
lines changed

clippy_lints/src/manual_non_exhaustive.rs

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ use clippy_utils::is_doc_hidden;
33
use clippy_utils::msrvs::{self, Msrv};
44
use clippy_utils::source::snippet_opt;
55
use rustc_ast::ast::{self, VisibilityKind};
6+
use rustc_ast::attr;
67
use rustc_data_structures::fx::FxHashSet;
78
use rustc_errors::Applicability;
89
use rustc_hir::def::{CtorKind, CtorOf, DefKind, Res};
@@ -158,7 +159,8 @@ impl<'tcx> LateLintPass<'tcx> for ManualNonExhaustiveEnum {
158159
let mut iter = def.variants.iter().filter_map(|v| {
159160
(matches!(v.data, hir::VariantData::Unit(_, _))
160161
&& v.ident.as_str().starts_with('_')
161-
&& is_doc_hidden(cx.tcx.hir().attrs(v.hir_id)))
162+
&& is_doc_hidden(cx.tcx.hir().attrs(v.hir_id))
163+
&& !attr::contains_name(cx.tcx.hir().attrs(item.hir_id()), sym::non_exhaustive))
162164
.then_some((v.def_id, v.span))
163165
});
164166
if let Some((id, span)) = iter.next()
@@ -198,16 +200,14 @@ impl<'tcx> LateLintPass<'tcx> for ManualNonExhaustiveEnum {
198200
enum_span,
199201
"this seems like a manual implementation of the non-exhaustive pattern",
200202
|diag| {
201-
if !cx.tcx.adt_def(enum_id).is_variant_list_non_exhaustive()
202-
&& let header_span = cx.sess().source_map().span_until_char(enum_span, '{')
203-
&& let Some(snippet) = snippet_opt(cx, header_span)
204-
{
205-
diag.span_suggestion(
206-
header_span,
207-
"add the attribute",
208-
format!("#[non_exhaustive] {snippet}"),
209-
Applicability::Unspecified,
210-
);
203+
let header_span = cx.sess().source_map().span_until_char(enum_span, '{');
204+
if let Some(snippet) = snippet_opt(cx, header_span) {
205+
diag.span_suggestion(
206+
header_span,
207+
"add the attribute",
208+
format!("#[non_exhaustive] {snippet}"),
209+
Applicability::Unspecified,
210+
);
211211
}
212212
diag.span_help(variant_span, "remove this variant");
213213
},

tests/ui/manual_non_exhaustive_enum.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,9 @@ enum E {
1010
_C,
1111
}
1212

13-
// user forgot to remove the marker
13+
// if the user explicitly marks as nonexhaustive we shouldn't warn them
1414
#[non_exhaustive]
1515
enum Ep {
16-
//~^ ERROR: this seems like a manual implementation of the non-exhaustive pattern
1716
A,
1817
B,
1918
#[doc(hidden)]

tests/ui/manual_non_exhaustive_enum.stderr

Lines changed: 1 addition & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -22,23 +22,5 @@ LL | _C,
2222
= note: `-D clippy::manual-non-exhaustive` implied by `-D warnings`
2323
= help: to override `-D warnings` add `#[allow(clippy::manual_non_exhaustive)]`
2424

25-
error: this seems like a manual implementation of the non-exhaustive pattern
26-
--> $DIR/manual_non_exhaustive_enum.rs:15:1
27-
|
28-
LL | / enum Ep {
29-
LL | |
30-
LL | | A,
31-
LL | | B,
32-
LL | | #[doc(hidden)]
33-
LL | | _C,
34-
LL | | }
35-
| |_^
36-
|
37-
help: remove this variant
38-
--> $DIR/manual_non_exhaustive_enum.rs:20:5
39-
|
40-
LL | _C,
41-
| ^^
42-
43-
error: aborting due to 2 previous errors
25+
error: aborting due to previous error
4426

0 commit comments

Comments
 (0)