Skip to content

Commit 8abab55

Browse files
author
Michael Wright
committed
Fix hidden variant suggestion on single variant
Fixes rust-lang#6984
1 parent 0b76719 commit 8abab55

File tree

7 files changed

+54
-23
lines changed

7 files changed

+54
-23
lines changed

clippy_lints/src/lib.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@
2121
// (Currently there is no way to opt into sysroot crates without `extern crate`.)
2222
extern crate rustc_ast;
2323
extern crate rustc_ast_pretty;
24-
extern crate rustc_attr;
2524
extern crate rustc_data_structures;
2625
extern crate rustc_driver;
2726
extern crate rustc_errors;

clippy_lints/src/manual_non_exhaustive.rs

Lines changed: 3 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
1+
use clippy_utils::attrs::is_doc_hidden;
12
use clippy_utils::diagnostics::span_lint_and_then;
23
use clippy_utils::meets_msrv;
34
use clippy_utils::source::snippet_opt;
45
use if_chain::if_chain;
5-
use rustc_ast::ast::{Attribute, FieldDef, Item, ItemKind, Variant, VariantData, VisibilityKind};
6-
use rustc_attr as attr;
6+
use rustc_ast::ast::{FieldDef, Item, ItemKind, Variant, VariantData, VisibilityKind};
77
use rustc_errors::Applicability;
88
use rustc_lint::{EarlyContext, EarlyLintPass};
99
use rustc_semver::RustcVersion;
@@ -102,15 +102,7 @@ fn check_manual_non_exhaustive_enum(cx: &EarlyContext<'_>, item: &Item, variants
102102
fn is_non_exhaustive_marker(variant: &Variant) -> bool {
103103
matches!(variant.data, VariantData::Unit(_))
104104
&& variant.ident.as_str().starts_with('_')
105-
&& variant.attrs.iter().any(|a| is_doc_hidden(a))
106-
}
107-
108-
fn is_doc_hidden(attr: &Attribute) -> bool {
109-
attr.has_name(sym::doc)
110-
&& match attr.meta_item_list() {
111-
Some(l) => attr::list_contains_name(&l, sym::hidden),
112-
None => false,
113-
}
105+
&& is_doc_hidden(&variant.attrs)
114106
}
115107

116108
if_chain! {

clippy_lints/src/matches.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -983,6 +983,11 @@ impl CommonPrefixSearcher<'a> {
983983
}
984984
}
985985

986+
fn is_doc_hidden(cx: &LateContext<'_>, variant_def: &VariantDef) -> bool {
987+
let attrs = cx.tcx.get_attrs(variant_def.def_id);
988+
clippy_utils::attrs::is_doc_hidden(attrs)
989+
}
990+
986991
#[allow(clippy::too_many_lines)]
987992
fn check_wild_enum_match(cx: &LateContext<'_>, ex: &Expr<'_>, arms: &[Arm<'_>]) {
988993
let ty = cx.typeck_results().expr_ty(ex).peel_refs();
@@ -1102,7 +1107,7 @@ fn check_wild_enum_match(cx: &LateContext<'_>, ex: &Expr<'_>, arms: &[Arm<'_>])
11021107

11031108
match missing_variants.as_slice() {
11041109
[] => (),
1105-
[x] if !adt_def.is_variant_list_non_exhaustive() => span_lint_and_sugg(
1110+
[x] if !adt_def.is_variant_list_non_exhaustive() && !is_doc_hidden(cx, x) => span_lint_and_sugg(
11061111
cx,
11071112
MATCH_WILDCARD_FOR_SINGLE_VARIANTS,
11081113
wildcard_span,

clippy_lints/src/missing_doc.rs

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,10 @@
55
// [`missing_doc`]: https://github.com/rust-lang/rust/blob/cf9cf7c923eb01146971429044f216a3ca905e06/compiler/rustc_lint/src/builtin.rs#L415
66
//
77

8+
use clippy_utils::attrs::is_doc_hidden;
89
use clippy_utils::diagnostics::span_lint;
910
use if_chain::if_chain;
1011
use rustc_ast::ast::{self, MetaItem, MetaItemKind};
11-
use rustc_ast::attr;
1212
use rustc_hir as hir;
1313
use rustc_lint::{LateContext, LateLintPass, LintContext};
1414
use rustc_middle::ty;
@@ -111,14 +111,7 @@ impl_lint_pass!(MissingDoc => [MISSING_DOCS_IN_PRIVATE_ITEMS]);
111111

112112
impl<'tcx> LateLintPass<'tcx> for MissingDoc {
113113
fn enter_lint_attrs(&mut self, _: &LateContext<'tcx>, attrs: &'tcx [ast::Attribute]) {
114-
let doc_hidden = self.doc_hidden()
115-
|| attrs.iter().any(|attr| {
116-
attr.has_name(sym::doc)
117-
&& match attr.meta_item_list() {
118-
None => false,
119-
Some(l) => attr::list_contains_name(&l[..], sym::hidden),
120-
}
121-
});
114+
let doc_hidden = self.doc_hidden() || is_doc_hidden(attrs);
122115
self.doc_hidden_stack.push(doc_hidden);
123116
}
124117

clippy_utils/src/attrs.rs

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use rustc_ast::ast;
1+
use rustc_ast::{ast, attr};
22
use rustc_errors::Applicability;
33
use rustc_session::Session;
44
use rustc_span::sym;
@@ -148,3 +148,13 @@ pub fn get_unique_inner_attr(sess: &Session, attrs: &[ast::Attribute], name: &'s
148148
pub fn is_proc_macro(sess: &Session, attrs: &[ast::Attribute]) -> bool {
149149
attrs.iter().any(|attr| sess.is_proc_macro_attr(attr))
150150
}
151+
152+
/// Return true if the attributes contain `#[doc(hidden)]`
153+
pub fn is_doc_hidden(attrs: &[ast::Attribute]) -> bool {
154+
#[allow(clippy::filter_map)]
155+
attrs
156+
.iter()
157+
.filter(|attr| attr.has_name(sym::doc))
158+
.flat_map(ast::Attribute::meta_item_list)
159+
.any(|l| attr::list_contains_name(&l, sym::hidden))
160+
}

tests/ui/match_wildcard_for_single_variants.fixed

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,4 +108,20 @@ fn main() {
108108
Bar::B => (),
109109
_ => (),
110110
};
111+
112+
//#6984
113+
{
114+
#![allow(clippy::manual_non_exhaustive)]
115+
pub enum Enum {
116+
A,
117+
B,
118+
#[doc(hidden)]
119+
__Private,
120+
}
121+
match Enum::A {
122+
Enum::A => (),
123+
Enum::B => (),
124+
_ => (),
125+
}
126+
}
111127
}

tests/ui/match_wildcard_for_single_variants.rs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,4 +108,20 @@ fn main() {
108108
Bar::B => (),
109109
_ => (),
110110
};
111+
112+
//#6984
113+
{
114+
#![allow(clippy::manual_non_exhaustive)]
115+
pub enum Enum {
116+
A,
117+
B,
118+
#[doc(hidden)]
119+
__Private,
120+
}
121+
match Enum::A {
122+
Enum::A => (),
123+
Enum::B => (),
124+
_ => (),
125+
}
126+
}
111127
}

0 commit comments

Comments
 (0)