mirror of
https://github.com/rust-lang/rust-clippy
synced 2024-11-26 06:30:32 +00:00
Add field_scoped_visibility_modifiers lint
This commit is contained in:
parent
a2c9782128
commit
3405ce3bca
6 changed files with 128 additions and 0 deletions
|
@ -5362,6 +5362,7 @@ Released 2018-09-13
|
||||||
[`extra_unused_type_parameters`]: https://rust-lang.github.io/rust-clippy/master/index.html#extra_unused_type_parameters
|
[`extra_unused_type_parameters`]: https://rust-lang.github.io/rust-clippy/master/index.html#extra_unused_type_parameters
|
||||||
[`fallible_impl_from`]: https://rust-lang.github.io/rust-clippy/master/index.html#fallible_impl_from
|
[`fallible_impl_from`]: https://rust-lang.github.io/rust-clippy/master/index.html#fallible_impl_from
|
||||||
[`field_reassign_with_default`]: https://rust-lang.github.io/rust-clippy/master/index.html#field_reassign_with_default
|
[`field_reassign_with_default`]: https://rust-lang.github.io/rust-clippy/master/index.html#field_reassign_with_default
|
||||||
|
[`field_scoped_visibility_modifiers`]: https://rust-lang.github.io/rust-clippy/master/index.html#field_scoped_visibility_modifiers
|
||||||
[`filetype_is_file`]: https://rust-lang.github.io/rust-clippy/master/index.html#filetype_is_file
|
[`filetype_is_file`]: https://rust-lang.github.io/rust-clippy/master/index.html#filetype_is_file
|
||||||
[`filter_map`]: https://rust-lang.github.io/rust-clippy/master/index.html#filter_map
|
[`filter_map`]: https://rust-lang.github.io/rust-clippy/master/index.html#filter_map
|
||||||
[`filter_map_bool_then`]: https://rust-lang.github.io/rust-clippy/master/index.html#filter_map_bool_then
|
[`filter_map_bool_then`]: https://rust-lang.github.io/rust-clippy/master/index.html#filter_map_bool_then
|
||||||
|
|
|
@ -178,6 +178,7 @@ pub(crate) static LINTS: &[&crate::LintInfo] = &[
|
||||||
crate::explicit_write::EXPLICIT_WRITE_INFO,
|
crate::explicit_write::EXPLICIT_WRITE_INFO,
|
||||||
crate::extra_unused_type_parameters::EXTRA_UNUSED_TYPE_PARAMETERS_INFO,
|
crate::extra_unused_type_parameters::EXTRA_UNUSED_TYPE_PARAMETERS_INFO,
|
||||||
crate::fallible_impl_from::FALLIBLE_IMPL_FROM_INFO,
|
crate::fallible_impl_from::FALLIBLE_IMPL_FROM_INFO,
|
||||||
|
crate::field_scoped_visibility_modifiers::FIELD_SCOPED_VISIBILITY_MODIFIERS_INFO,
|
||||||
crate::float_literal::EXCESSIVE_PRECISION_INFO,
|
crate::float_literal::EXCESSIVE_PRECISION_INFO,
|
||||||
crate::float_literal::LOSSY_FLOAT_LITERAL_INFO,
|
crate::float_literal::LOSSY_FLOAT_LITERAL_INFO,
|
||||||
crate::floating_point_arithmetic::IMPRECISE_FLOPS_INFO,
|
crate::floating_point_arithmetic::IMPRECISE_FLOPS_INFO,
|
||||||
|
|
75
clippy_lints/src/field_scoped_visibility_modifiers.rs
Normal file
75
clippy_lints/src/field_scoped_visibility_modifiers.rs
Normal file
|
@ -0,0 +1,75 @@
|
||||||
|
use clippy_utils::diagnostics::span_lint_and_help;
|
||||||
|
use rustc_ast::ast::{Item, ItemKind, VisibilityKind};
|
||||||
|
use rustc_lint::{EarlyContext, EarlyLintPass};
|
||||||
|
use rustc_session::declare_lint_pass;
|
||||||
|
|
||||||
|
declare_clippy_lint! {
|
||||||
|
/// ### What it does
|
||||||
|
/// Checks for usage of scoped visibility modifiers, like `pub(crate)`, on fields. These
|
||||||
|
/// make a field visible within a scope between public and private.
|
||||||
|
///
|
||||||
|
/// ### Why restrict this?
|
||||||
|
/// Scoped visibility modifiers cause a field to be accessible within some scope between
|
||||||
|
/// public and private, potentially within an entire crate. This allows for fields to be
|
||||||
|
/// non-private while upholding internal invariants, but can be a code smell. Scoped visibility
|
||||||
|
/// requires checking a greater area, potentially an entire crate, to verify that an invariant
|
||||||
|
/// is upheld, and global analysis requires a lot of effort.
|
||||||
|
///
|
||||||
|
/// ### Example
|
||||||
|
/// ```no_run
|
||||||
|
/// pub mod public_module {
|
||||||
|
/// struct MyStruct {
|
||||||
|
/// pub(crate) first_field: bool,
|
||||||
|
/// pub(super) second_field: bool
|
||||||
|
/// }
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
/// Use instead:
|
||||||
|
/// ```no_run
|
||||||
|
/// pub mod public_module {
|
||||||
|
/// struct MyStruct {
|
||||||
|
/// first_field: bool,
|
||||||
|
/// second_field: bool
|
||||||
|
/// }
|
||||||
|
/// impl MyStruct {
|
||||||
|
/// pub(crate) fn get_first_field(&self) -> bool {
|
||||||
|
/// self.first_field
|
||||||
|
/// }
|
||||||
|
/// pub(super) fn get_second_field(&self) -> bool {
|
||||||
|
/// self.second_field
|
||||||
|
/// }
|
||||||
|
/// }
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
#[clippy::version = "1.78.0"]
|
||||||
|
pub FIELD_SCOPED_VISIBILITY_MODIFIERS,
|
||||||
|
restriction,
|
||||||
|
"checks for usage of a scoped visibility modifier, like `pub(crate)`, on fields"
|
||||||
|
}
|
||||||
|
|
||||||
|
declare_lint_pass!(FieldScopedVisibilityModifiers => [FIELD_SCOPED_VISIBILITY_MODIFIERS]);
|
||||||
|
|
||||||
|
impl EarlyLintPass for FieldScopedVisibilityModifiers {
|
||||||
|
fn check_item(&mut self, cx: &EarlyContext<'_>, item: &Item) {
|
||||||
|
let ItemKind::Struct(ref st, _) = item.kind else {
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
for field in st.fields() {
|
||||||
|
let VisibilityKind::Restricted { path, .. } = &field.vis.kind else {
|
||||||
|
continue;
|
||||||
|
};
|
||||||
|
if !path.segments.is_empty() && path.segments[0].ident.name == rustc_span::symbol::kw::SelfLower {
|
||||||
|
// pub(self) is equivalent to not using pub at all, so we ignore it
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
span_lint_and_help(
|
||||||
|
cx,
|
||||||
|
FIELD_SCOPED_VISIBILITY_MODIFIERS,
|
||||||
|
field.vis.span,
|
||||||
|
"scoped visibility modifier on a field",
|
||||||
|
None,
|
||||||
|
"consider making the field private and adding a scoped visibility method for it",
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -136,6 +136,7 @@ mod exit;
|
||||||
mod explicit_write;
|
mod explicit_write;
|
||||||
mod extra_unused_type_parameters;
|
mod extra_unused_type_parameters;
|
||||||
mod fallible_impl_from;
|
mod fallible_impl_from;
|
||||||
|
mod field_scoped_visibility_modifiers;
|
||||||
mod float_literal;
|
mod float_literal;
|
||||||
mod floating_point_arithmetic;
|
mod floating_point_arithmetic;
|
||||||
mod format;
|
mod format;
|
||||||
|
@ -1169,6 +1170,7 @@ pub fn register_lints(store: &mut rustc_lint::LintStore, conf: &'static Conf) {
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
store.register_late_pass(move |_| Box::new(string_patterns::StringPatterns::new(msrv())));
|
store.register_late_pass(move |_| Box::new(string_patterns::StringPatterns::new(msrv())));
|
||||||
|
store.register_early_pass(|| Box::new(field_scoped_visibility_modifiers::FieldScopedVisibilityModifiers));
|
||||||
// add lints here, do not remove this comment, it's used in `new_lint`
|
// add lints here, do not remove this comment, it's used in `new_lint`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
21
tests/ui/field_scoped_visibility_modifiers.rs
Normal file
21
tests/ui/field_scoped_visibility_modifiers.rs
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
#![warn(clippy::field_scoped_visibility_modifiers)]
|
||||||
|
|
||||||
|
pub mod pub_module {
|
||||||
|
pub(in crate::pub_module) mod pub_in_path_module {}
|
||||||
|
pub(super) mod pub_super_module {}
|
||||||
|
struct MyStruct {
|
||||||
|
private_field: bool,
|
||||||
|
pub pub_field: bool,
|
||||||
|
pub(crate) pub_crate_field: bool,
|
||||||
|
pub(in crate::pub_module) pub_in_path_field: bool,
|
||||||
|
pub(super) pub_super_field: bool,
|
||||||
|
#[allow(clippy::needless_pub_self)]
|
||||||
|
pub(self) pub_self_field: bool,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pub(crate) mod pub_crate_module {}
|
||||||
|
|
||||||
|
#[allow(clippy::needless_pub_self)]
|
||||||
|
pub(self) mod pub_self_module {}
|
||||||
|
|
||||||
|
fn main() {}
|
28
tests/ui/field_scoped_visibility_modifiers.stderr
Normal file
28
tests/ui/field_scoped_visibility_modifiers.stderr
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
error: scoped visibility modifier on a field
|
||||||
|
--> tests/ui/field_scoped_visibility_modifiers.rs:9:9
|
||||||
|
|
|
||||||
|
LL | pub(crate) pub_crate_field: bool,
|
||||||
|
| ^^^^^^^^^^
|
||||||
|
|
|
||||||
|
= help: consider making the field private and adding a scoped visibility method for it
|
||||||
|
= note: `-D clippy::field-scoped-visibility-modifiers` implied by `-D warnings`
|
||||||
|
= help: to override `-D warnings` add `#[allow(clippy::field_scoped_visibility_modifiers)]`
|
||||||
|
|
||||||
|
error: scoped visibility modifier on a field
|
||||||
|
--> tests/ui/field_scoped_visibility_modifiers.rs:10:9
|
||||||
|
|
|
||||||
|
LL | pub(in crate::pub_module) pub_in_path_field: bool,
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
= help: consider making the field private and adding a scoped visibility method for it
|
||||||
|
|
||||||
|
error: scoped visibility modifier on a field
|
||||||
|
--> tests/ui/field_scoped_visibility_modifiers.rs:11:9
|
||||||
|
|
|
||||||
|
LL | pub(super) pub_super_field: bool,
|
||||||
|
| ^^^^^^^^^^
|
||||||
|
|
|
||||||
|
= help: consider making the field private and adding a scoped visibility method for it
|
||||||
|
|
||||||
|
error: aborting due to 3 previous errors
|
||||||
|
|
Loading…
Reference in a new issue