Skip to content

Commit 9c1e14e

Browse files
committed
change to a LatePass lint, ignore doc_hidden and PhantomData fields
1 parent 3d16f47 commit 9c1e14e

File tree

2 files changed

+37
-16
lines changed

2 files changed

+37
-16
lines changed

clippy_lints/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1124,7 +1124,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
11241124
});
11251125
store.register_late_pass(move |_| Box::new(manual_hash_one::ManualHashOne::new(msrv())));
11261126
store.register_late_pass(|_| Box::new(iter_without_into_iter::IterWithoutIntoIter));
1127-
store.register_early_pass(|| Box::new(pub_underscore_fields::PubUnderscoreFields));
1127+
store.register_late_pass(|_| Box::new(pub_underscore_fields::PubUnderscoreFields));
11281128
// add lints here, do not remove this comment, it's used in `new_lint`
11291129
}
11301130

clippy_lints/src/pub_underscore_fields.rs

Lines changed: 36 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
1+
use clippy_utils::attrs::is_doc_hidden;
12
use clippy_utils::diagnostics::span_lint_and_help;
2-
use rustc_ast::ast::{Item, ItemKind, VisibilityKind};
3-
use rustc_lint::{EarlyContext, EarlyLintPass};
3+
use clippy_utils::is_path_lang_item;
4+
// use rustc_ast::ast::{Item, ItemKind, VisibilityKind};
5+
use rustc_hir::{FieldDef, Item, ItemKind, LangItem};
6+
use rustc_lint::{LateContext, LateLintPass};
7+
use rustc_middle::ty::Visibility;
48
use rustc_session::{declare_lint_pass, declare_tool_lint};
59

610
declare_clippy_lint! {
@@ -20,13 +24,15 @@ declare_clippy_lint! {
2024
/// ```
2125
/// Use instead:
2226
/// ```rust
23-
/// struct FileHandle_Foo {
27+
/// struct FileHandle {
2428
/// _descriptor: usize,
2529
/// }
26-
///
30+
/// ```
31+
///
2732
/// // OR
28-
///
29-
/// struct FileHandle_Bar {
33+
///
34+
/// ```
35+
/// struct FileHandle {
3036
/// pub descriptor: usize,
3137
/// }
3238
/// ```
@@ -37,21 +43,36 @@ declare_clippy_lint! {
3743
}
3844
declare_lint_pass!(PubUnderscoreFields => [PUB_UNDERSCORE_FIELDS]);
3945

40-
impl EarlyLintPass for PubUnderscoreFields {
41-
fn check_item(&mut self, cx: &EarlyContext<'_>, item: &Item) {
42-
// this only pertains to structs
43-
let ItemKind::Struct(ref st, _) = item.kind else {
46+
impl<'tcx> LateLintPass<'tcx> for PubUnderscoreFields {
47+
fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'_>) {
48+
// This lint only pertains to structs.
49+
let ItemKind::Struct(var, _) = &item.kind else {
4450
return;
4551
};
4652

47-
for field in st.fields() {
48-
if let Some(ident) = field.ident.as_ref()
49-
&& ident.as_str().starts_with('_')
50-
&& !matches!(field.vis.kind, VisibilityKind::Inherited) {
53+
let is_visible = |field: &FieldDef<'_>| {
54+
let parent = cx.tcx.parent_module_from_def_id(field.def_id);
55+
let grandparent = cx.tcx.parent_module_from_def_id(parent.into());
56+
let visibility = cx.tcx.visibility(field.def_id);
57+
58+
let case_1 = parent == grandparent && !field.vis_span.is_empty();
59+
let case_2 = visibility != Visibility::Restricted(parent.to_def_id());
60+
61+
case_1 || case_2
62+
};
63+
64+
for field in var.fields() {
65+
// Only pertains to fields that start with an underscore, and are visible publically.
66+
if field.ident.as_str().starts_with('_') && is_visible(&field)
67+
// We ignore fields that have `#[doc(hidden)]`.
68+
&& !is_doc_hidden(cx.tcx.hir().attrs(field.hir_id))
69+
// We ignore fields that are `PhantomData`.
70+
&& !is_path_lang_item(cx, field.ty, LangItem::PhantomData)
71+
{
5172
span_lint_and_help(
5273
cx,
5374
PUB_UNDERSCORE_FIELDS,
54-
field.vis.span.to(ident.span),
75+
field.vis_span.to(field.ident.span),
5576
"field marked as public but also inferred as unused because it's prefixed with `_`",
5677
None,
5778
"consider removing the underscore, or making the field private",

0 commit comments

Comments
 (0)