From 7ac97b69fc81fcd5cbd2a7c862187f6a6c6ea354 Mon Sep 17 00:00:00 2001 From: TennyZhuang Date: Sun, 16 Oct 2022 16:02:23 +0800 Subject: Add new lint `partial_pub_fields` Signed-off-by: TennyZhuang --- clippy_lints/src/partial_pub_fields.rs | 81 ++++++++++++++++++++++++++++++++++ 1 file changed, 81 insertions(+) create mode 100644 clippy_lints/src/partial_pub_fields.rs (limited to 'clippy_lints/src/partial_pub_fields.rs') diff --git a/clippy_lints/src/partial_pub_fields.rs b/clippy_lints/src/partial_pub_fields.rs new file mode 100644 index 00000000000..085ee08afca --- /dev/null +++ b/clippy_lints/src/partial_pub_fields.rs @@ -0,0 +1,81 @@ +use clippy_utils::diagnostics::span_lint_and_help; +use rustc_ast::ast::*; +use rustc_lint::{EarlyContext, EarlyLintPass}; +use rustc_session::{declare_lint_pass, declare_tool_lint}; + +declare_clippy_lint! { + /// ### What it does + /// Checks whether partial fields of a struct are public. + /// + /// Either make all fields of a type public, or make none of them public + /// + /// ### Why is this bad? + /// Most types should either be: + /// * Abstract data types: complex objects with opaque implementation which guard + /// interior invariants and expose intentionally limited API to the outside world. + /// * Data: relatively simple objects which group a bunch of related attributes together. + /// + /// ### Example + /// ```rust + /// pub struct Color { + /// pub r, + /// pub g, + /// b, + /// } + /// ``` + /// Use instead: + /// ```rust + /// pub struct Color { + /// pub r, + /// pub g, + /// pub b, + /// } + /// ``` + #[clippy::version = "1.66.0"] + pub PARTIAL_PUB_FIELDS, + restriction, + "partial fields of a struct are public" +} +declare_lint_pass!(PartialPubFields => [PARTIAL_PUB_FIELDS]); + +impl EarlyLintPass for PartialPubFields { + fn check_item(&mut self, cx: &EarlyContext<'_>, item: &Item) { + let ItemKind::Struct(ref st, _) = item.kind else { + return; + }; + + let mut fields = st.fields().iter(); + let Some(first_field) = fields.next() else { + // Empty struct. + return; + }; + let all_pub = first_field.vis.kind.is_pub(); + let all_priv = !all_pub; + + let msg = "mixed usage of pub and non-pub fields"; + + for field in fields { + if all_priv && field.vis.kind.is_pub() { + span_lint_and_help( + cx, + &PARTIAL_PUB_FIELDS, + field.vis.span, + msg, + None, + "consider using private field here", + ); + return; + } else if all_pub && !field.vis.kind.is_pub() { + span_lint_and_help( + cx, + &PARTIAL_PUB_FIELDS, + field.vis.span, + msg, + None, + "consider using public field here", + ); + return; + } + } + } +} -- cgit 1.4.1-3-g733a5 From b10882ab9153733249f95d63150724aa5f50ce59 Mon Sep 17 00:00:00 2001 From: TennyZhuang Date: Sun, 16 Oct 2022 16:21:48 +0800 Subject: fix dogfood Signed-off-by: TennyZhuang --- clippy_lints/src/partial_pub_fields.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'clippy_lints/src/partial_pub_fields.rs') diff --git a/clippy_lints/src/partial_pub_fields.rs b/clippy_lints/src/partial_pub_fields.rs index 085ee08afca..42f892e3652 100644 --- a/clippy_lints/src/partial_pub_fields.rs +++ b/clippy_lints/src/partial_pub_fields.rs @@ -1,5 +1,5 @@ use clippy_utils::diagnostics::span_lint_and_help; -use rustc_ast::ast::*; +use rustc_ast::ast::{Item, ItemKind}; use rustc_lint::{EarlyContext, EarlyLintPass}; use rustc_session::{declare_lint_pass, declare_tool_lint}; @@ -58,7 +58,7 @@ impl EarlyLintPass for PartialPubFields { if all_priv && field.vis.kind.is_pub() { span_lint_and_help( cx, - &PARTIAL_PUB_FIELDS, + PARTIAL_PUB_FIELDS, field.vis.span, msg, None, @@ -68,7 +68,7 @@ impl EarlyLintPass for PartialPubFields { } else if all_pub && !field.vis.kind.is_pub() { span_lint_and_help( cx, - &PARTIAL_PUB_FIELDS, + PARTIAL_PUB_FIELDS, field.vis.span, msg, None, -- cgit 1.4.1-3-g733a5 From 360b48b1ab97471c0d122732a027b65f46980447 Mon Sep 17 00:00:00 2001 From: TennyZhuang Date: Sun, 16 Oct 2022 17:10:27 +0800 Subject: fix a doctest Signed-off-by: TennyZhuang --- clippy_lints/src/partial_pub_fields.rs | 12 ++++++------ src/docs/partial_pub_fields.txt | 12 ++++++------ 2 files changed, 12 insertions(+), 12 deletions(-) (limited to 'clippy_lints/src/partial_pub_fields.rs') diff --git a/clippy_lints/src/partial_pub_fields.rs b/clippy_lints/src/partial_pub_fields.rs index 42f892e3652..f60d9d65b12 100644 --- a/clippy_lints/src/partial_pub_fields.rs +++ b/clippy_lints/src/partial_pub_fields.rs @@ -18,17 +18,17 @@ declare_clippy_lint! { /// ### Example /// ```rust /// pub struct Color { - /// pub r, - /// pub g, - /// b, + /// pub r: u8, + /// pub g: u8, + /// b: u8, /// } /// ``` /// Use instead: /// ```rust /// pub struct Color { - /// pub r, - /// pub g, - /// pub b, + /// pub r: u8, + /// pub g: u8, + /// pub b: u8, /// } /// ``` #[clippy::version = "1.66.0"] diff --git a/src/docs/partial_pub_fields.txt b/src/docs/partial_pub_fields.txt index a332ec8c28a..b529adf1547 100644 --- a/src/docs/partial_pub_fields.txt +++ b/src/docs/partial_pub_fields.txt @@ -12,16 +12,16 @@ interior invariants and expose intentionally limited API to the outside world. ### Example ``` pub struct Color { - pub r, - pub g, - b, + pub r: u8, + pub g: u8, + b: u8, } ``` Use instead: ``` pub struct Color { - pub r, - pub g, - pub b, + pub r: u8, + pub g: u8, + pub b: u8, } ``` \ No newline at end of file -- cgit 1.4.1-3-g733a5