Auto merge of #11496 - jonboh:prefix_postfix_struct, r=y21

add lint for struct field names

changelog: [`struct_field_names`]: lint structs with the same pre/postfix in all fields or with fields that are pre/postfixed with the name of the struct.

fixes #2555

I've followed general structure and naming from the code in [enum_variants](b788addfcc/clippy_lints/src/enum_variants.rs) lint, which implements the same logic for enum variants.
This commit is contained in:
bors 2023-10-18 18:47:27 +00:00
commit fe21991520
38 changed files with 1087 additions and 237 deletions

View file

@ -5463,6 +5463,7 @@ Released 2018-09-13
[`string_to_string`]: https://rust-lang.github.io/rust-clippy/master/index.html#string_to_string
[`strlen_on_c_strings`]: https://rust-lang.github.io/rust-clippy/master/index.html#strlen_on_c_strings
[`struct_excessive_bools`]: https://rust-lang.github.io/rust-clippy/master/index.html#struct_excessive_bools
[`struct_field_names`]: https://rust-lang.github.io/rust-clippy/master/index.html#struct_field_names
[`stutter`]: https://rust-lang.github.io/rust-clippy/master/index.html#stutter
[`suboptimal_flops`]: https://rust-lang.github.io/rust-clippy/master/index.html#suboptimal_flops
[`suspicious_arithmetic_impl`]: https://rust-lang.github.io/rust-clippy/master/index.html#suspicious_arithmetic_impl
@ -5625,6 +5626,7 @@ Released 2018-09-13
[`single-char-binding-names-threshold`]: https://doc.rust-lang.org/clippy/lint_configuration.html#single-char-binding-names-threshold
[`too-large-for-stack`]: https://doc.rust-lang.org/clippy/lint_configuration.html#too-large-for-stack
[`enum-variant-name-threshold`]: https://doc.rust-lang.org/clippy/lint_configuration.html#enum-variant-name-threshold
[`struct-field-name-threshold`]: https://doc.rust-lang.org/clippy/lint_configuration.html#struct-field-name-threshold
[`enum-variant-size-threshold`]: https://doc.rust-lang.org/clippy/lint_configuration.html#enum-variant-size-threshold
[`verbose-bit-mask-threshold`]: https://doc.rust-lang.org/clippy/lint_configuration.html#verbose-bit-mask-threshold
[`literal-representation-threshold`]: https://doc.rust-lang.org/clippy/lint_configuration.html#literal-representation-threshold

View file

@ -273,6 +273,16 @@ The minimum number of enum variants for the lints about variant names to trigger
* [`enum_variant_names`](https://rust-lang.github.io/rust-clippy/master/index.html#enum_variant_names)
## `struct-field-name-threshold`
The minimum number of struct fields for the lints about field names to trigger
**Default Value:** `3` (`u64`)
---
**Affected lints:**
* [`struct_variant_names`](https://rust-lang.github.io/rust-clippy/master/index.html#struct_variant_names)
## `enum-variant-size-threshold`
The maximum size of an enum's variant to avoid box suggestion

View file

@ -154,9 +154,6 @@ pub(crate) static LINTS: &[&crate::LintInfo] = &[
crate::endian_bytes::LITTLE_ENDIAN_BYTES_INFO,
crate::entry::MAP_ENTRY_INFO,
crate::enum_clike::ENUM_CLIKE_UNPORTABLE_VARIANT_INFO,
crate::enum_variants::ENUM_VARIANT_NAMES_INFO,
crate::enum_variants::MODULE_INCEPTION_INFO,
crate::enum_variants::MODULE_NAME_REPETITIONS_INFO,
crate::equatable_if_let::EQUATABLE_IF_LET_INFO,
crate::error_impl_error::ERROR_IMPL_ERROR_INFO,
crate::escape::BOXED_LOCAL_INFO,
@ -226,6 +223,10 @@ pub(crate) static LINTS: &[&crate::LintInfo] = &[
crate::instant_subtraction::UNCHECKED_DURATION_SUBTRACTION_INFO,
crate::int_plus_one::INT_PLUS_ONE_INFO,
crate::invalid_upcast_comparisons::INVALID_UPCAST_COMPARISONS_INFO,
crate::item_name_repetitions::ENUM_VARIANT_NAMES_INFO,
crate::item_name_repetitions::MODULE_INCEPTION_INFO,
crate::item_name_repetitions::MODULE_NAME_REPETITIONS_INFO,
crate::item_name_repetitions::STRUCT_FIELD_NAMES_INFO,
crate::items_after_statements::ITEMS_AFTER_STATEMENTS_INFO,
crate::items_after_test_module::ITEMS_AFTER_TEST_MODULE_INFO,
crate::iter_not_returning_iterator::ITER_NOT_RETURNING_ITERATOR_INFO,

View file

@ -360,6 +360,7 @@ declare_clippy_lint! {
}
#[derive(Copy, Clone)]
#[allow(clippy::struct_field_names)]
pub struct Functions {
too_many_arguments_threshold: u64,
too_many_lines_threshold: u64,

View file

@ -1,9 +1,10 @@
//! lint on enum variants that are prefixed or suffixed by the same characters
use clippy_utils::diagnostics::{span_lint, span_lint_and_help, span_lint_hir};
use clippy_utils::macros::span_is_local;
use clippy_utils::source::is_present_in_source;
use clippy_utils::str_utils::{camel_case_split, count_match_end, count_match_start};
use rustc_hir::{EnumDef, Item, ItemKind, OwnerId, Variant};
use clippy_utils::str_utils::{camel_case_split, count_match_end, count_match_start, to_camel_case, to_snake_case};
use rustc_hir::{EnumDef, FieldDef, Item, ItemKind, OwnerId, Variant, VariantData};
use rustc_lint::{LateContext, LateLintPass};
use rustc_session::{declare_tool_lint, impl_lint_pass};
use rustc_span::source_map::Span;
@ -103,32 +104,184 @@ declare_clippy_lint! {
style,
"modules that have the same name as their parent module"
}
declare_clippy_lint! {
/// ### What it does
/// Detects struct fields that are prefixed or suffixed
/// by the same characters or the name of the struct itself.
///
/// ### Why is this bad?
/// Information common to all struct fields is better represented in the struct name.
///
/// ### Limitations
/// Characters with no casing will be considered when comparing prefixes/suffixes
/// This applies to numbers and non-ascii characters without casing
/// e.g. `foo1` and `foo2` is considered to have different prefixes
/// (the prefixes are `foo1` and `foo2` respectively), as also `bar螃`, `bar蟹`
///
/// ### Example
/// ```rust
/// struct Cake {
/// cake_sugar: u8,
/// cake_flour: u8,
/// cake_eggs: u8
/// }
/// ```
/// Use instead:
/// ```rust
/// struct Cake {
/// sugar: u8,
/// flour: u8,
/// eggs: u8
/// }
/// ```
#[clippy::version = "1.75.0"]
pub STRUCT_FIELD_NAMES,
pedantic,
"structs where all fields share a prefix/postfix or contain the name of the struct"
}
pub struct EnumVariantNames {
pub struct ItemNameRepetitions {
modules: Vec<(Symbol, String, OwnerId)>,
threshold: u64,
enum_threshold: u64,
struct_threshold: u64,
avoid_breaking_exported_api: bool,
allow_private_module_inception: bool,
}
impl EnumVariantNames {
impl ItemNameRepetitions {
#[must_use]
pub fn new(threshold: u64, avoid_breaking_exported_api: bool, allow_private_module_inception: bool) -> Self {
pub fn new(
enum_threshold: u64,
struct_threshold: u64,
avoid_breaking_exported_api: bool,
allow_private_module_inception: bool,
) -> Self {
Self {
modules: Vec::new(),
threshold,
enum_threshold,
struct_threshold,
avoid_breaking_exported_api,
allow_private_module_inception,
}
}
}
impl_lint_pass!(EnumVariantNames => [
impl_lint_pass!(ItemNameRepetitions => [
ENUM_VARIANT_NAMES,
STRUCT_FIELD_NAMES,
MODULE_NAME_REPETITIONS,
MODULE_INCEPTION
]);
#[must_use]
fn have_no_extra_prefix(prefixes: &[&str]) -> bool {
prefixes.iter().all(|p| p == &"" || p == &"_")
}
fn check_fields(cx: &LateContext<'_>, threshold: u64, item: &Item<'_>, fields: &[FieldDef<'_>]) {
if (fields.len() as u64) < threshold {
return;
}
check_struct_name_repetition(cx, item, fields);
// if the SyntaxContext of the identifiers of the fields and struct differ dont lint them.
// this prevents linting in macros in which the location of the field identifier names differ
if !fields.iter().all(|field| item.ident.span.eq_ctxt(field.ident.span)) {
return;
}
let mut pre: Vec<&str> = match fields.first() {
Some(first_field) => first_field.ident.name.as_str().split('_').collect(),
None => return,
};
let mut post = pre.clone();
post.reverse();
for field in fields {
let field_split: Vec<&str> = field.ident.name.as_str().split('_').collect();
if field_split.len() == 1 {
return;
}
pre = pre
.into_iter()
.zip(field_split.iter())
.take_while(|(a, b)| &a == b)
.map(|e| e.0)
.collect();
post = post
.into_iter()
.zip(field_split.iter().rev())
.take_while(|(a, b)| &a == b)
.map(|e| e.0)
.collect();
}
let prefix = pre.join("_");
post.reverse();
let postfix = match post.last() {
Some(&"") => post.join("_") + "_",
Some(_) | None => post.join("_"),
};
if fields.len() > 1 {
let (what, value) = match (
prefix.is_empty() || prefix.chars().all(|c| c == '_'),
postfix.is_empty(),
) {
(true, true) => return,
(false, _) => ("pre", prefix),
(true, false) => ("post", postfix),
};
span_lint_and_help(
cx,
STRUCT_FIELD_NAMES,
item.span,
&format!("all fields have the same {what}fix: `{value}`"),
None,
&format!("remove the {what}fixes"),
);
}
}
fn check_struct_name_repetition(cx: &LateContext<'_>, item: &Item<'_>, fields: &[FieldDef<'_>]) {
let snake_name = to_snake_case(item.ident.name.as_str());
let item_name_words: Vec<&str> = snake_name.split('_').collect();
for field in fields {
if field.ident.span.eq_ctxt(item.ident.span) {
//consider linting only if the field identifier has the same SyntaxContext as the item(struct)
let field_words: Vec<&str> = field.ident.name.as_str().split('_').collect();
if field_words.len() >= item_name_words.len() {
// if the field name is shorter than the struct name it cannot contain it
if field_words.iter().zip(item_name_words.iter()).all(|(a, b)| a == b) {
span_lint_hir(
cx,
STRUCT_FIELD_NAMES,
field.hir_id,
field.span,
"field name starts with the struct's name",
);
}
if field_words.len() > item_name_words.len() {
// lint only if the end is not covered by the start
if field_words
.iter()
.rev()
.zip(item_name_words.iter().rev())
.all(|(a, b)| a == b)
{
span_lint_hir(
cx,
STRUCT_FIELD_NAMES,
field.hir_id,
field.span,
"field name ends with the struct's name",
);
}
}
}
}
}
}
fn check_enum_start(cx: &LateContext<'_>, item_name: &str, variant: &Variant<'_>) {
let name = variant.ident.name.as_str();
let item_name_chars = item_name.chars().count();
@ -218,35 +371,7 @@ fn check_variant(cx: &LateContext<'_>, threshold: u64, def: &EnumDef<'_>, item_n
);
}
#[must_use]
fn have_no_extra_prefix(prefixes: &[&str]) -> bool {
prefixes.iter().all(|p| p == &"" || p == &"_")
}
#[must_use]
fn to_camel_case(item_name: &str) -> String {
let mut s = String::new();
let mut up = true;
for c in item_name.chars() {
if c.is_uppercase() {
// we only turn snake case text into CamelCase
return item_name.to_string();
}
if c == '_' {
up = true;
continue;
}
if up {
up = false;
s.extend(c.to_uppercase());
} else {
s.push(c);
}
}
s
}
impl LateLintPass<'_> for EnumVariantNames {
impl LateLintPass<'_> for ItemNameRepetitions {
fn check_item_post(&mut self, _cx: &LateContext<'_>, _item: &Item<'_>) {
let last = self.modules.pop();
assert!(last.is_some());
@ -303,9 +428,15 @@ impl LateLintPass<'_> for EnumVariantNames {
}
}
}
if let ItemKind::Enum(ref def, _) = item.kind {
if !(self.avoid_breaking_exported_api && cx.effective_visibilities.is_exported(item.owner_id.def_id)) {
check_variant(cx, self.threshold, def, item_name, item.span);
if !(self.avoid_breaking_exported_api && cx.effective_visibilities.is_exported(item.owner_id.def_id))
&& span_is_local(item.span)
{
match item.kind {
ItemKind::Enum(def, _) => check_variant(cx, self.enum_threshold, &def, item_name, item.span),
ItemKind::Struct(VariantData::Struct(fields, _), _) => {
check_fields(cx, self.struct_threshold, item, fields);
},
_ => (),
}
}
self.modules.push((item.ident.name, item_camel, item.owner_id));

View file

@ -121,7 +121,6 @@ mod empty_structs_with_brackets;
mod endian_bytes;
mod entry;
mod enum_clike;
mod enum_variants;
mod equatable_if_let;
mod error_impl_error;
mod escape;
@ -166,6 +165,7 @@ mod inline_fn_without_body;
mod instant_subtraction;
mod int_plus_one;
mod invalid_upcast_comparisons;
mod item_name_repetitions;
mod items_after_statements;
mod items_after_test_module;
mod iter_not_returning_iterator;
@ -852,10 +852,12 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
))
});
let enum_variant_name_threshold = conf.enum_variant_name_threshold;
let struct_field_name_threshold = conf.struct_field_name_threshold;
let allow_private_module_inception = conf.allow_private_module_inception;
store.register_late_pass(move |_| {
Box::new(enum_variants::EnumVariantNames::new(
Box::new(item_name_repetitions::ItemNameRepetitions::new(
enum_variant_name_threshold,
struct_field_name_threshold,
avoid_breaking_exported_api,
allow_private_module_inception,
))

View file

@ -134,6 +134,7 @@ impl Usage {
/// The parameters being checked by the lint, indexed by both the parameter's `HirId` and the
/// `DefId` of the function paired with the parameter's index.
#[derive(Default)]
#[allow(clippy::struct_field_names)]
struct Params {
params: Vec<Param>,
by_id: HirIdMap<usize>,

View file

@ -578,7 +578,7 @@ impl Types {
}
}
#[allow(clippy::struct_excessive_bools)]
#[allow(clippy::struct_excessive_bools, clippy::struct_field_names)]
#[derive(Clone, Copy, Default)]
struct CheckTyContext {
is_in_trait_impl: bool,

View file

@ -360,6 +360,10 @@ define_Conf! {
///
/// The minimum number of enum variants for the lints about variant names to trigger
(enum_variant_name_threshold: u64 = 3),
/// Lint: STRUCT_VARIANT_NAMES.
///
/// The minimum number of struct fields for the lints about field names to trigger
(struct_field_name_threshold: u64 = 3),
/// Lint: LARGE_ENUM_VARIANT.
///
/// The maximum size of an enum's variant to avoid box suggestion

View file

@ -236,6 +236,59 @@ pub fn count_match_end(str1: &str, str2: &str) -> StrCount {
})
}
/// Returns a `snake_case` version of the input
/// ```
/// use clippy_utils::str_utils::to_snake_case;
/// assert_eq!(to_snake_case("AbcDef"), "abc_def");
/// assert_eq!(to_snake_case("ABCD"), "a_b_c_d");
/// assert_eq!(to_snake_case("AbcDD"), "abc_d_d");
/// assert_eq!(to_snake_case("Abc1DD"), "abc1_d_d");
/// ```
pub fn to_snake_case(name: &str) -> String {
let mut s = String::new();
for (i, c) in name.chars().enumerate() {
if c.is_uppercase() {
// characters without capitalization are considered lowercase
if i != 0 {
s.push('_');
}
s.extend(c.to_lowercase());
} else {
s.push(c);
}
}
s
}
/// Returns a `CamelCase` version of the input
/// ```
/// use clippy_utils::str_utils::to_camel_case;
/// assert_eq!(to_camel_case("abc_def"), "AbcDef");
/// assert_eq!(to_camel_case("a_b_c_d"), "ABCD");
/// assert_eq!(to_camel_case("abc_d_d"), "AbcDD");
/// assert_eq!(to_camel_case("abc1_d_d"), "Abc1DD");
/// ```
pub fn to_camel_case(item_name: &str) -> String {
let mut s = String::new();
let mut up = true;
for c in item_name.chars() {
if c.is_uppercase() {
// we only turn snake case text into CamelCase
return item_name.to_string();
}
if c == '_' {
up = true;
continue;
}
if up {
up = false;
s.extend(c.to_uppercase());
} else {
s.push(c);
}
}
s
}
#[cfg(test)]
mod test {
use super::*;

View file

@ -1,16 +0,0 @@
enum Foo {
AFoo,
BFoo,
CFoo,
DFoo,
}
enum Foo2 {
//~^ ERROR: all variants have the same postfix
AFoo,
BFoo,
CFoo,
DFoo,
EFoo,
}
fn main() {}

View file

@ -1,18 +0,0 @@
error: all variants have the same postfix: `Foo`
--> $DIR/enum_variant_names.rs:7:1
|
LL | / enum Foo2 {
LL | |
LL | | AFoo,
LL | | BFoo,
... |
LL | | EFoo,
LL | | }
| |_^
|
= help: remove the postfixes and use full paths to the variants instead of glob imports
= note: `-D clippy::enum-variant-names` implied by `-D warnings`
= help: to override `-D warnings` add `#[allow(clippy::enum_variant_names)]`
error: aborting due to previous error

View file

@ -1 +1,2 @@
struct-field-name-threshold = 0
enum-variant-name-threshold = 0

View file

@ -1 +1,2 @@
enum-variant-name-threshold = 5
struct-field-name-threshold = 5

View file

@ -0,0 +1,32 @@
#![warn(clippy::struct_field_names)]
struct Data {
a_data: u8,
b_data: u8,
c_data: u8,
d_data: u8,
}
struct Data2 {
//~^ ERROR: all fields have the same postfix
a_data: u8,
b_data: u8,
c_data: u8,
d_data: u8,
e_data: u8,
}
enum Foo {
AFoo,
BFoo,
CFoo,
DFoo,
}
enum Foo2 {
//~^ ERROR: all variants have the same postfix
AFoo,
BFoo,
CFoo,
DFoo,
EFoo,
}
fn main() {}

View file

@ -0,0 +1,34 @@
error: all fields have the same postfix: `data`
--> $DIR/item_name_repetitions.rs:9:1
|
LL | / struct Data2 {
LL | |
LL | | a_data: u8,
LL | | b_data: u8,
... |
LL | | e_data: u8,
LL | | }
| |_^
|
= help: remove the postfixes
= note: `-D clippy::struct-field-names` implied by `-D warnings`
= help: to override `-D warnings` add `#[allow(clippy::struct_field_names)]`
error: all variants have the same postfix: `Foo`
--> $DIR/item_name_repetitions.rs:23:1
|
LL | / enum Foo2 {
LL | |
LL | | AFoo,
LL | | BFoo,
... |
LL | | EFoo,
LL | | }
| |_^
|
= help: remove the postfixes and use full paths to the variants instead of glob imports
= note: `-D clippy::enum-variant-names` implied by `-D warnings`
= help: to override `-D warnings` add `#[allow(clippy::enum_variant_names)]`
error: aborting due to 2 previous errors

View file

@ -1,5 +1,6 @@
//! this is crate
#![allow(missing_docs)]
#![allow(clippy::struct_field_names)]
#![warn(clippy::missing_docs_in_private_items)]
/// this is mod

View file

@ -1,5 +1,5 @@
error: missing documentation for a function
--> $DIR/pub_crate_missing_doc.rs:12:5
--> $DIR/pub_crate_missing_doc.rs:13:5
|
LL | pub(crate) fn crate_no_docs() {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@ -8,25 +8,25 @@ LL | pub(crate) fn crate_no_docs() {}
= help: to override `-D warnings` add `#[allow(clippy::missing_docs_in_private_items)]`
error: missing documentation for a function
--> $DIR/pub_crate_missing_doc.rs:15:5
--> $DIR/pub_crate_missing_doc.rs:16:5
|
LL | pub(super) fn super_no_docs() {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: missing documentation for a function
--> $DIR/pub_crate_missing_doc.rs:23:9
--> $DIR/pub_crate_missing_doc.rs:24:9
|
LL | pub(crate) fn sub_crate_no_docs() {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: missing documentation for a struct field
--> $DIR/pub_crate_missing_doc.rs:33:9
--> $DIR/pub_crate_missing_doc.rs:34:9
|
LL | pub(crate) crate_field_no_docs: (),
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: missing documentation for a struct
--> $DIR/pub_crate_missing_doc.rs:39:5
--> $DIR/pub_crate_missing_doc.rs:40:5
|
LL | / pub(crate) struct CrateStructNoDocs {
LL | | /// some docs
@ -38,13 +38,13 @@ LL | | }
| |_____^
error: missing documentation for a struct field
--> $DIR/pub_crate_missing_doc.rs:42:9
--> $DIR/pub_crate_missing_doc.rs:43:9
|
LL | pub(crate) crate_field_no_docs: (),
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: missing documentation for a type alias
--> $DIR/pub_crate_missing_doc.rs:51:1
--> $DIR/pub_crate_missing_doc.rs:52:1
|
LL | type CrateTypedefNoDocs = String;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

View file

@ -53,6 +53,7 @@ error: error reading Clippy's configuration file: unknown field `foobar`, expect
single-char-binding-names-threshold
stack-size-threshold
standard-macro-braces
struct-field-name-threshold
suppress-restriction-lint-in-const
third-party
too-large-for-stack
@ -126,6 +127,7 @@ error: error reading Clippy's configuration file: unknown field `barfoo`, expect
single-char-binding-names-threshold
stack-size-threshold
standard-macro-braces
struct-field-name-threshold
suppress-restriction-lint-in-const
third-party
too-large-for-stack

View file

@ -2,6 +2,7 @@
#![warn(clippy::manual_filter_map)]
#![allow(clippy::redundant_closure)] // FIXME suggestion may have redundant closure
#![allow(clippy::useless_vec)]
#![allow(clippy::struct_field_names)]
fn main() {
// is_some(), unwrap()

View file

@ -2,6 +2,7 @@
#![warn(clippy::manual_filter_map)]
#![allow(clippy::redundant_closure)] // FIXME suggestion may have redundant closure
#![allow(clippy::useless_vec)]
#![allow(clippy::struct_field_names)]
fn main() {
// is_some(), unwrap()

View file

@ -1,11 +1,11 @@
error: `filter(..).map(..)` can be simplified as `filter_map(..)`
--> $DIR/manual_filter_map.rs:8:19
--> $DIR/manual_filter_map.rs:9:19
|
LL | let _ = (0..).filter(|n| to_opt(*n).is_some()).map(|a| to_opt(a).unwrap());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `filter_map(|a| to_opt(a))`
|
note: the suggestion might change the behavior of the program when merging `filter` and `map`, because this expression potentially contains side effects and will only execute once
--> $DIR/manual_filter_map.rs:8:30
--> $DIR/manual_filter_map.rs:9:30
|
LL | let _ = (0..).filter(|n| to_opt(*n).is_some()).map(|a| to_opt(a).unwrap());
| ^^^^^^^^^^
@ -13,31 +13,31 @@ LL | let _ = (0..).filter(|n| to_opt(*n).is_some()).map(|a| to_opt(a).unwrap
= help: to override `-D warnings` add `#[allow(clippy::manual_filter_map)]`
error: `filter(..).map(..)` can be simplified as `filter_map(..)`
--> $DIR/manual_filter_map.rs:11:19
--> $DIR/manual_filter_map.rs:12:19
|
LL | let _ = (0..).filter(|&n| to_opt(n).is_some()).map(|a| to_opt(a).expect("hi"));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `filter_map(|a| to_opt(a))`
|
note: the suggestion might change the behavior of the program when merging `filter` and `map`, because this expression potentially contains side effects and will only execute once
--> $DIR/manual_filter_map.rs:11:31
--> $DIR/manual_filter_map.rs:12:31
|
LL | let _ = (0..).filter(|&n| to_opt(n).is_some()).map(|a| to_opt(a).expect("hi"));
| ^^^^^^^^^
error: `filter(..).map(..)` can be simplified as `filter_map(..)`
--> $DIR/manual_filter_map.rs:14:19
--> $DIR/manual_filter_map.rs:15:19
|
LL | let _ = (0..).filter(|&n| to_res(n).is_ok()).map(|a| to_res(a).unwrap_or(1));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `filter_map(|a| to_res(a).ok())`
|
note: the suggestion might change the behavior of the program when merging `filter` and `map`, because this expression potentially contains side effects and will only execute once
--> $DIR/manual_filter_map.rs:14:31
--> $DIR/manual_filter_map.rs:15:31
|
LL | let _ = (0..).filter(|&n| to_res(n).is_ok()).map(|a| to_res(a).unwrap_or(1));
| ^^^^^^^^^
error: `filter(..).map(..)` can be simplified as `filter_map(..)`
--> $DIR/manual_filter_map.rs:17:10
--> $DIR/manual_filter_map.rs:18:10
|
LL | .filter(|&x| to_ref(to_opt(x)).is_some())
| __________^
@ -45,13 +45,13 @@ LL | | .map(|y| to_ref(to_opt(y)).unwrap());
| |____________________________________________^ help: try: `filter_map(|y| *to_ref(to_opt(y)))`
|
note: the suggestion might change the behavior of the program when merging `filter` and `map`, because this expression potentially contains side effects and will only execute once
--> $DIR/manual_filter_map.rs:17:22
--> $DIR/manual_filter_map.rs:18:22
|
LL | .filter(|&x| to_ref(to_opt(x)).is_some())
| ^^^^^^^^^^^^^^^^^
error: `filter(..).map(..)` can be simplified as `filter_map(..)`
--> $DIR/manual_filter_map.rs:20:10
--> $DIR/manual_filter_map.rs:21:10
|
LL | .filter(|x| to_ref(to_opt(*x)).is_some())
| __________^
@ -59,13 +59,13 @@ LL | | .map(|y| to_ref(to_opt(y)).unwrap());
| |____________________________________________^ help: try: `filter_map(|y| *to_ref(to_opt(y)))`
|
note: the suggestion might change the behavior of the program when merging `filter` and `map`, because this expression potentially contains side effects and will only execute once
--> $DIR/manual_filter_map.rs:20:21
--> $DIR/manual_filter_map.rs:21:21
|
LL | .filter(|x| to_ref(to_opt(*x)).is_some())
| ^^^^^^^^^^^^^^^^^^
error: `filter(..).map(..)` can be simplified as `filter_map(..)`
--> $DIR/manual_filter_map.rs:24:10
--> $DIR/manual_filter_map.rs:25:10
|
LL | .filter(|&x| to_ref(to_res(x)).is_ok())
| __________^
@ -73,13 +73,13 @@ LL | | .map(|y| to_ref(to_res(y)).unwrap());
| |____________________________________________^ help: try: `filter_map(|y| to_ref(to_res(y)).ok())`
|
note: the suggestion might change the behavior of the program when merging `filter` and `map`, because this expression potentially contains side effects and will only execute once
--> $DIR/manual_filter_map.rs:24:22
--> $DIR/manual_filter_map.rs:25:22
|
LL | .filter(|&x| to_ref(to_res(x)).is_ok())
| ^^^^^^^^^^^^^^^^^
error: `filter(..).map(..)` can be simplified as `filter_map(..)`
--> $DIR/manual_filter_map.rs:27:10
--> $DIR/manual_filter_map.rs:28:10
|
LL | .filter(|x| to_ref(to_res(*x)).is_ok())
| __________^
@ -87,13 +87,13 @@ LL | | .map(|y| to_ref(to_res(y)).unwrap());
| |____________________________________________^ help: try: `filter_map(|y| to_ref(to_res(y)).ok())`
|
note: the suggestion might change the behavior of the program when merging `filter` and `map`, because this expression potentially contains side effects and will only execute once
--> $DIR/manual_filter_map.rs:27:21
--> $DIR/manual_filter_map.rs:28:21
|
LL | .filter(|x| to_ref(to_res(*x)).is_ok())
| ^^^^^^^^^^^^^^^^^^
error: `find(..).map(..)` can be simplified as `find_map(..)`
--> $DIR/manual_filter_map.rs:33:27
--> $DIR/manual_filter_map.rs:34:27
|
LL | iter::<Option<&u8>>().find(|x| x.is_some()).map(|x| x.cloned().unwrap());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `find_map(|x| x.cloned())`
@ -102,79 +102,79 @@ LL | iter::<Option<&u8>>().find(|x| x.is_some()).map(|x| x.cloned().unwrap()
= help: to override `-D warnings` add `#[allow(clippy::manual_find_map)]`
error: `find(..).map(..)` can be simplified as `find_map(..)`
--> $DIR/manual_filter_map.rs:34:28
--> $DIR/manual_filter_map.rs:35:28
|
LL | iter::<&Option<&u8>>().find(|x| x.is_some()).map(|x| x.cloned().unwrap());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `find_map(|x| x.cloned())`
error: `find(..).map(..)` can be simplified as `find_map(..)`
--> $DIR/manual_filter_map.rs:35:31
--> $DIR/manual_filter_map.rs:36:31
|
LL | iter::<&Option<String>>().find(|x| x.is_some()).map(|x| x.as_deref().unwrap());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `find_map(|x| x.as_deref())`
error: `find(..).map(..)` can be simplified as `find_map(..)`
--> $DIR/manual_filter_map.rs:36:31
--> $DIR/manual_filter_map.rs:37:31
|
LL | iter::<Option<&String>>().find(|&x| to_ref(x).is_some()).map(|y| to_ref(y).cloned().unwrap());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `find_map(|y| to_ref(y).cloned())`
|
note: the suggestion might change the behavior of the program when merging `filter` and `map`, because this expression potentially contains side effects and will only execute once
--> $DIR/manual_filter_map.rs:36:41
--> $DIR/manual_filter_map.rs:37:41
|
LL | iter::<Option<&String>>().find(|&x| to_ref(x).is_some()).map(|y| to_ref(y).cloned().unwrap());
| ^^^^^^^^^
error: `find(..).map(..)` can be simplified as `find_map(..)`
--> $DIR/manual_filter_map.rs:38:30
--> $DIR/manual_filter_map.rs:39:30
|
LL | iter::<Result<u8, ()>>().find(|x| x.is_ok()).map(|x| x.unwrap());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `find_map(|x| x.ok())`
error: `find(..).map(..)` can be simplified as `find_map(..)`
--> $DIR/manual_filter_map.rs:39:31
--> $DIR/manual_filter_map.rs:40:31
|
LL | iter::<&Result<u8, ()>>().find(|x| x.is_ok()).map(|x| x.unwrap());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `find_map(|x| x.ok())`
error: `find(..).map(..)` can be simplified as `find_map(..)`
--> $DIR/manual_filter_map.rs:40:32
--> $DIR/manual_filter_map.rs:41:32
|
LL | iter::<&&Result<u8, ()>>().find(|x| x.is_ok()).map(|x| x.unwrap());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `find_map(|x| x.ok())`
error: `find(..).map(..)` can be simplified as `find_map(..)`
--> $DIR/manual_filter_map.rs:41:31
--> $DIR/manual_filter_map.rs:42:31
|
LL | iter::<Result<&u8, ()>>().find(|x| x.is_ok()).map(|x| x.cloned().unwrap());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `find_map(|x| x.cloned().ok())`
error: `find(..).map(..)` can be simplified as `find_map(..)`
--> $DIR/manual_filter_map.rs:42:32
--> $DIR/manual_filter_map.rs:43:32
|
LL | iter::<&Result<&u8, ()>>().find(|x| x.is_ok()).map(|x| x.cloned().unwrap());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `find_map(|x| x.cloned().ok())`
error: `find(..).map(..)` can be simplified as `find_map(..)`
--> $DIR/manual_filter_map.rs:43:35
--> $DIR/manual_filter_map.rs:44:35
|
LL | iter::<&Result<String, ()>>().find(|x| x.is_ok()).map(|x| x.as_deref().unwrap());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `find_map(|x| x.as_deref().ok())`
error: `find(..).map(..)` can be simplified as `find_map(..)`
--> $DIR/manual_filter_map.rs:44:35
--> $DIR/manual_filter_map.rs:45:35
|
LL | iter::<Result<&String, ()>>().find(|&x| to_ref(x).is_ok()).map(|y| to_ref(y).cloned().unwrap());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `find_map(|y| to_ref(y).cloned().ok())`
|
note: the suggestion might change the behavior of the program when merging `filter` and `map`, because this expression potentially contains side effects and will only execute once
--> $DIR/manual_filter_map.rs:44:45
--> $DIR/manual_filter_map.rs:45:45
|
LL | iter::<Result<&String, ()>>().find(|&x| to_ref(x).is_ok()).map(|y| to_ref(y).cloned().unwrap());
| ^^^^^^^^^
error: `filter(..).map(..)` can be simplified as `filter_map(..)`
--> $DIR/manual_filter_map.rs:92:10
--> $DIR/manual_filter_map.rs:93:10
|
LL | .filter(|f| f.option_field.is_some())
| __________^
@ -182,7 +182,7 @@ LL | | .map(|f| f.option_field.clone().unwrap());
| |_________________________________________________^ help: try: `filter_map(|f| f.option_field.clone())`
error: `filter(..).map(..)` can be simplified as `filter_map(..)`
--> $DIR/manual_filter_map.rs:97:10
--> $DIR/manual_filter_map.rs:98:10
|
LL | .filter(|f| f.ref_field.is_some())
| __________^
@ -190,7 +190,7 @@ LL | | .map(|f| f.ref_field.cloned().unwrap());
| |_______________________________________________^ help: try: `filter_map(|f| f.ref_field.cloned())`
error: `filter(..).map(..)` can be simplified as `filter_map(..)`
--> $DIR/manual_filter_map.rs:102:10
--> $DIR/manual_filter_map.rs:103:10
|
LL | .filter(|f| f.ref_field.is_some())
| __________^
@ -198,7 +198,7 @@ LL | | .map(|f| f.ref_field.copied().unwrap());
| |_______________________________________________^ help: try: `filter_map(|f| f.ref_field.copied())`
error: `filter(..).map(..)` can be simplified as `filter_map(..)`
--> $DIR/manual_filter_map.rs:107:10
--> $DIR/manual_filter_map.rs:108:10
|
LL | .filter(|f| f.result_field.is_ok())
| __________^
@ -206,7 +206,7 @@ LL | | .map(|f| f.result_field.clone().unwrap());
| |_________________________________________________^ help: try: `filter_map(|f| f.result_field.clone().ok())`
error: `filter(..).map(..)` can be simplified as `filter_map(..)`
--> $DIR/manual_filter_map.rs:112:10
--> $DIR/manual_filter_map.rs:113:10
|
LL | .filter(|f| f.result_field.is_ok())
| __________^
@ -214,7 +214,7 @@ LL | | .map(|f| f.result_field.as_ref().unwrap());
| |__________________________________________________^ help: try: `filter_map(|f| f.result_field.as_ref().ok())`
error: `filter(..).map(..)` can be simplified as `filter_map(..)`
--> $DIR/manual_filter_map.rs:117:10
--> $DIR/manual_filter_map.rs:118:10
|
LL | .filter(|f| f.result_field.is_ok())
| __________^
@ -222,7 +222,7 @@ LL | | .map(|f| f.result_field.as_deref().unwrap());
| |____________________________________________________^ help: try: `filter_map(|f| f.result_field.as_deref().ok())`
error: `filter(..).map(..)` can be simplified as `filter_map(..)`
--> $DIR/manual_filter_map.rs:122:10
--> $DIR/manual_filter_map.rs:123:10
|
LL | .filter(|f| f.result_field.is_ok())
| __________^
@ -230,7 +230,7 @@ LL | | .map(|f| f.result_field.as_mut().unwrap());
| |__________________________________________________^ help: try: `filter_map(|f| f.result_field.as_mut().ok())`
error: `filter(..).map(..)` can be simplified as `filter_map(..)`
--> $DIR/manual_filter_map.rs:127:10
--> $DIR/manual_filter_map.rs:128:10
|
LL | .filter(|f| f.result_field.is_ok())
| __________^
@ -238,7 +238,7 @@ LL | | .map(|f| f.result_field.as_deref_mut().unwrap());
| |________________________________________________________^ help: try: `filter_map(|f| f.result_field.as_deref_mut().ok())`
error: `filter(..).map(..)` can be simplified as `filter_map(..)`
--> $DIR/manual_filter_map.rs:132:10
--> $DIR/manual_filter_map.rs:133:10
|
LL | .filter(|f| f.result_field.is_ok())
| __________^
@ -246,7 +246,7 @@ LL | | .map(|f| f.result_field.to_owned().unwrap());
| |____________________________________________________^ help: try: `filter_map(|f| f.result_field.to_owned().ok())`
error: `filter(..).map(..)` can be simplified as `filter_map(..)`
--> $DIR/manual_filter_map.rs:145:27
--> $DIR/manual_filter_map.rs:146:27
|
LL | let _x = iter.clone().filter(|x| matches!(x, Enum::A(_))).map(|x| match x {
| ___________________________^
@ -256,7 +256,7 @@ LL | | });
| |______^ help: try: `filter_map(|x| match x { Enum::A(s) => Some(s), _ => None })`
error: `filter(..).map(..)` can be simplified as `filter_map(..)`
--> $DIR/manual_filter_map.rs:155:10
--> $DIR/manual_filter_map.rs:156:10
|
LL | .filter(|x| matches!(x, Enum::A(_)))
| __________^

View file

@ -2,6 +2,7 @@
#![warn(clippy::manual_find_map)]
#![allow(clippy::redundant_closure)] // FIXME suggestion may have redundant closure
#![allow(clippy::useless_vec)]
#![allow(clippy::struct_field_names)]
fn main() {
// is_some(), unwrap()

View file

@ -2,6 +2,7 @@
#![warn(clippy::manual_find_map)]
#![allow(clippy::redundant_closure)] // FIXME suggestion may have redundant closure
#![allow(clippy::useless_vec)]
#![allow(clippy::struct_field_names)]
fn main() {
// is_some(), unwrap()

View file

@ -1,11 +1,11 @@
error: `find(..).map(..)` can be simplified as `find_map(..)`
--> $DIR/manual_find_map.rs:8:19
--> $DIR/manual_find_map.rs:9:19
|
LL | let _ = (0..).find(|n| to_opt(*n).is_some()).map(|a| to_opt(a).unwrap());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `find_map(|a| to_opt(a))`
|
note: the suggestion might change the behavior of the program when merging `filter` and `map`, because this expression potentially contains side effects and will only execute once
--> $DIR/manual_find_map.rs:8:28
--> $DIR/manual_find_map.rs:9:28
|
LL | let _ = (0..).find(|n| to_opt(*n).is_some()).map(|a| to_opt(a).unwrap());
| ^^^^^^^^^^
@ -13,31 +13,31 @@ LL | let _ = (0..).find(|n| to_opt(*n).is_some()).map(|a| to_opt(a).unwrap()
= help: to override `-D warnings` add `#[allow(clippy::manual_find_map)]`
error: `find(..).map(..)` can be simplified as `find_map(..)`
--> $DIR/manual_find_map.rs:11:19
--> $DIR/manual_find_map.rs:12:19
|
LL | let _ = (0..).find(|&n| to_opt(n).is_some()).map(|a| to_opt(a).expect("hi"));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `find_map(|a| to_opt(a))`
|
note: the suggestion might change the behavior of the program when merging `filter` and `map`, because this expression potentially contains side effects and will only execute once
--> $DIR/manual_find_map.rs:11:29
--> $DIR/manual_find_map.rs:12:29
|
LL | let _ = (0..).find(|&n| to_opt(n).is_some()).map(|a| to_opt(a).expect("hi"));
| ^^^^^^^^^
error: `find(..).map(..)` can be simplified as `find_map(..)`
--> $DIR/manual_find_map.rs:14:19
--> $DIR/manual_find_map.rs:15:19
|
LL | let _ = (0..).find(|&n| to_res(n).is_ok()).map(|a| to_res(a).unwrap_or(1));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `find_map(|a| to_res(a).ok())`
|
note: the suggestion might change the behavior of the program when merging `filter` and `map`, because this expression potentially contains side effects and will only execute once
--> $DIR/manual_find_map.rs:14:29
--> $DIR/manual_find_map.rs:15:29
|
LL | let _ = (0..).find(|&n| to_res(n).is_ok()).map(|a| to_res(a).unwrap_or(1));
| ^^^^^^^^^
error: `find(..).map(..)` can be simplified as `find_map(..)`
--> $DIR/manual_find_map.rs:17:10
--> $DIR/manual_find_map.rs:18:10
|
LL | .find(|&x| to_ref(to_opt(x)).is_some())
| __________^
@ -45,13 +45,13 @@ LL | | .map(|y| to_ref(to_opt(y)).unwrap());
| |____________________________________________^ help: try: `find_map(|y| *to_ref(to_opt(y)))`
|
note: the suggestion might change the behavior of the program when merging `filter` and `map`, because this expression potentially contains side effects and will only execute once
--> $DIR/manual_find_map.rs:17:20
--> $DIR/manual_find_map.rs:18:20
|
LL | .find(|&x| to_ref(to_opt(x)).is_some())
| ^^^^^^^^^^^^^^^^^
error: `find(..).map(..)` can be simplified as `find_map(..)`
--> $DIR/manual_find_map.rs:20:10
--> $DIR/manual_find_map.rs:21:10
|
LL | .find(|x| to_ref(to_opt(*x)).is_some())
| __________^
@ -59,13 +59,13 @@ LL | | .map(|y| to_ref(to_opt(y)).unwrap());
| |____________________________________________^ help: try: `find_map(|y| *to_ref(to_opt(y)))`
|
note: the suggestion might change the behavior of the program when merging `filter` and `map`, because this expression potentially contains side effects and will only execute once
--> $DIR/manual_find_map.rs:20:19
--> $DIR/manual_find_map.rs:21:19
|
LL | .find(|x| to_ref(to_opt(*x)).is_some())
| ^^^^^^^^^^^^^^^^^^
error: `find(..).map(..)` can be simplified as `find_map(..)`
--> $DIR/manual_find_map.rs:24:10
--> $DIR/manual_find_map.rs:25:10
|
LL | .find(|&x| to_ref(to_res(x)).is_ok())
| __________^
@ -73,13 +73,13 @@ LL | | .map(|y| to_ref(to_res(y)).unwrap());
| |____________________________________________^ help: try: `find_map(|y| to_ref(to_res(y)).ok())`
|
note: the suggestion might change the behavior of the program when merging `filter` and `map`, because this expression potentially contains side effects and will only execute once
--> $DIR/manual_find_map.rs:24:20
--> $DIR/manual_find_map.rs:25:20
|
LL | .find(|&x| to_ref(to_res(x)).is_ok())
| ^^^^^^^^^^^^^^^^^
error: `find(..).map(..)` can be simplified as `find_map(..)`
--> $DIR/manual_find_map.rs:27:10
--> $DIR/manual_find_map.rs:28:10
|
LL | .find(|x| to_ref(to_res(*x)).is_ok())
| __________^
@ -87,109 +87,109 @@ LL | | .map(|y| to_ref(to_res(y)).unwrap());
| |____________________________________________^ help: try: `find_map(|y| to_ref(to_res(y)).ok())`
|
note: the suggestion might change the behavior of the program when merging `filter` and `map`, because this expression potentially contains side effects and will only execute once
--> $DIR/manual_find_map.rs:27:19
--> $DIR/manual_find_map.rs:28:19
|
LL | .find(|x| to_ref(to_res(*x)).is_ok())
| ^^^^^^^^^^^^^^^^^^
error: `find(..).map(..)` can be simplified as `find_map(..)`
--> $DIR/manual_find_map.rs:33:26
--> $DIR/manual_find_map.rs:34:26
|
LL | iter::<Option<u8>>().find(|x| x.is_some()).map(|x| x.unwrap());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `find_map(|x| x)`
error: `find(..).map(..)` can be simplified as `find_map(..)`
--> $DIR/manual_find_map.rs:34:27
--> $DIR/manual_find_map.rs:35:27
|
LL | iter::<&Option<u8>>().find(|x| x.is_some()).map(|x| x.unwrap());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `find_map(|x| *x)`
error: `find(..).map(..)` can be simplified as `find_map(..)`
--> $DIR/manual_find_map.rs:35:28
--> $DIR/manual_find_map.rs:36:28
|
LL | iter::<&&Option<u8>>().find(|x| x.is_some()).map(|x| x.unwrap());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `find_map(|x| **x)`
error: `find(..).map(..)` can be simplified as `find_map(..)`
--> $DIR/manual_find_map.rs:36:27
--> $DIR/manual_find_map.rs:37:27
|
LL | iter::<Option<&u8>>().find(|x| x.is_some()).map(|x| x.cloned().unwrap());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `find_map(|x| x.cloned())`
error: `find(..).map(..)` can be simplified as `find_map(..)`
--> $DIR/manual_find_map.rs:37:28
--> $DIR/manual_find_map.rs:38:28
|
LL | iter::<&Option<&u8>>().find(|x| x.is_some()).map(|x| x.cloned().unwrap());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `find_map(|x| x.cloned())`
error: `find(..).map(..)` can be simplified as `find_map(..)`
--> $DIR/manual_find_map.rs:38:31
--> $DIR/manual_find_map.rs:39:31
|
LL | iter::<&Option<String>>().find(|x| x.is_some()).map(|x| x.as_deref().unwrap());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `find_map(|x| x.as_deref())`
error: `find(..).map(..)` can be simplified as `find_map(..)`
--> $DIR/manual_find_map.rs:39:31
--> $DIR/manual_find_map.rs:40:31
|
LL | iter::<Option<&String>>().find(|&x| to_ref(x).is_some()).map(|y| to_ref(y).cloned().unwrap());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `find_map(|y| to_ref(y).cloned())`
|
note: the suggestion might change the behavior of the program when merging `filter` and `map`, because this expression potentially contains side effects and will only execute once
--> $DIR/manual_find_map.rs:39:41
--> $DIR/manual_find_map.rs:40:41
|
LL | iter::<Option<&String>>().find(|&x| to_ref(x).is_some()).map(|y| to_ref(y).cloned().unwrap());
| ^^^^^^^^^
error: `find(..).map(..)` can be simplified as `find_map(..)`
--> $DIR/manual_find_map.rs:41:30
--> $DIR/manual_find_map.rs:42:30
|
LL | iter::<Result<u8, ()>>().find(|x| x.is_ok()).map(|x| x.unwrap());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `find_map(|x| x.ok())`
error: `find(..).map(..)` can be simplified as `find_map(..)`
--> $DIR/manual_find_map.rs:42:31
--> $DIR/manual_find_map.rs:43:31
|
LL | iter::<&Result<u8, ()>>().find(|x| x.is_ok()).map(|x| x.unwrap());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `find_map(|x| x.ok())`
error: `find(..).map(..)` can be simplified as `find_map(..)`
--> $DIR/manual_find_map.rs:43:32
--> $DIR/manual_find_map.rs:44:32
|
LL | iter::<&&Result<u8, ()>>().find(|x| x.is_ok()).map(|x| x.unwrap());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `find_map(|x| x.ok())`
error: `find(..).map(..)` can be simplified as `find_map(..)`
--> $DIR/manual_find_map.rs:44:31
--> $DIR/manual_find_map.rs:45:31
|
LL | iter::<Result<&u8, ()>>().find(|x| x.is_ok()).map(|x| x.cloned().unwrap());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `find_map(|x| x.cloned().ok())`
error: `find(..).map(..)` can be simplified as `find_map(..)`
--> $DIR/manual_find_map.rs:45:32
--> $DIR/manual_find_map.rs:46:32
|
LL | iter::<&Result<&u8, ()>>().find(|x| x.is_ok()).map(|x| x.cloned().unwrap());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `find_map(|x| x.cloned().ok())`
error: `find(..).map(..)` can be simplified as `find_map(..)`
--> $DIR/manual_find_map.rs:46:35
--> $DIR/manual_find_map.rs:47:35
|
LL | iter::<&Result<String, ()>>().find(|x| x.is_ok()).map(|x| x.as_deref().unwrap());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `find_map(|x| x.as_deref().ok())`
error: `find(..).map(..)` can be simplified as `find_map(..)`
--> $DIR/manual_find_map.rs:47:35
--> $DIR/manual_find_map.rs:48:35
|
LL | iter::<Result<&String, ()>>().find(|&x| to_ref(x).is_ok()).map(|y| to_ref(y).cloned().unwrap());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `find_map(|y| to_ref(y).cloned().ok())`
|
note: the suggestion might change the behavior of the program when merging `filter` and `map`, because this expression potentially contains side effects and will only execute once
--> $DIR/manual_find_map.rs:47:45
--> $DIR/manual_find_map.rs:48:45
|
LL | iter::<Result<&String, ()>>().find(|&x| to_ref(x).is_ok()).map(|y| to_ref(y).cloned().unwrap());
| ^^^^^^^^^
error: `find(..).map(..)` can be simplified as `find_map(..)`
--> $DIR/manual_find_map.rs:95:10
--> $DIR/manual_find_map.rs:96:10
|
LL | .find(|f| f.option_field.is_some())
| __________^
@ -197,7 +197,7 @@ LL | | .map(|f| f.option_field.clone().unwrap());
| |_________________________________________________^ help: try: `find_map(|f| f.option_field.clone())`
error: `find(..).map(..)` can be simplified as `find_map(..)`
--> $DIR/manual_find_map.rs:100:10
--> $DIR/manual_find_map.rs:101:10
|
LL | .find(|f| f.ref_field.is_some())
| __________^
@ -205,7 +205,7 @@ LL | | .map(|f| f.ref_field.cloned().unwrap());
| |_______________________________________________^ help: try: `find_map(|f| f.ref_field.cloned())`
error: `find(..).map(..)` can be simplified as `find_map(..)`
--> $DIR/manual_find_map.rs:105:10
--> $DIR/manual_find_map.rs:106:10
|
LL | .find(|f| f.ref_field.is_some())
| __________^
@ -213,7 +213,7 @@ LL | | .map(|f| f.ref_field.copied().unwrap());
| |_______________________________________________^ help: try: `find_map(|f| f.ref_field.copied())`
error: `find(..).map(..)` can be simplified as `find_map(..)`
--> $DIR/manual_find_map.rs:110:10
--> $DIR/manual_find_map.rs:111:10
|
LL | .find(|f| f.result_field.is_ok())
| __________^
@ -221,7 +221,7 @@ LL | | .map(|f| f.result_field.clone().unwrap());
| |_________________________________________________^ help: try: `find_map(|f| f.result_field.clone().ok())`
error: `find(..).map(..)` can be simplified as `find_map(..)`
--> $DIR/manual_find_map.rs:115:10
--> $DIR/manual_find_map.rs:116:10
|
LL | .find(|f| f.result_field.is_ok())
| __________^
@ -229,7 +229,7 @@ LL | | .map(|f| f.result_field.as_ref().unwrap());
| |__________________________________________________^ help: try: `find_map(|f| f.result_field.as_ref().ok())`
error: `find(..).map(..)` can be simplified as `find_map(..)`
--> $DIR/manual_find_map.rs:120:10
--> $DIR/manual_find_map.rs:121:10
|
LL | .find(|f| f.result_field.is_ok())
| __________^
@ -237,7 +237,7 @@ LL | | .map(|f| f.result_field.as_deref().unwrap());
| |____________________________________________________^ help: try: `find_map(|f| f.result_field.as_deref().ok())`
error: `find(..).map(..)` can be simplified as `find_map(..)`
--> $DIR/manual_find_map.rs:125:10
--> $DIR/manual_find_map.rs:126:10
|
LL | .find(|f| f.result_field.is_ok())
| __________^
@ -245,7 +245,7 @@ LL | | .map(|f| f.result_field.as_mut().unwrap());
| |__________________________________________________^ help: try: `find_map(|f| f.result_field.as_mut().ok())`
error: `find(..).map(..)` can be simplified as `find_map(..)`
--> $DIR/manual_find_map.rs:130:10
--> $DIR/manual_find_map.rs:131:10
|
LL | .find(|f| f.result_field.is_ok())
| __________^
@ -253,7 +253,7 @@ LL | | .map(|f| f.result_field.as_deref_mut().unwrap());
| |________________________________________________________^ help: try: `find_map(|f| f.result_field.as_deref_mut().ok())`
error: `find(..).map(..)` can be simplified as `find_map(..)`
--> $DIR/manual_find_map.rs:135:10
--> $DIR/manual_find_map.rs:136:10
|
LL | .find(|f| f.result_field.is_ok())
| __________^

View file

@ -1,5 +1,6 @@
//@aux-build:proc_macros.rs
#![allow(irrefutable_let_patterns, nonstandard_style, unused)]
#![allow(clippy::struct_field_names)]
#![warn(clippy::min_ident_chars)]
extern crate proc_macros;

View file

@ -1,5 +1,5 @@
error: this ident consists of a single char
--> $DIR/min_ident_chars.rs:8:8
--> $DIR/min_ident_chars.rs:9:8
|
LL | struct A {
| ^
@ -8,169 +8,169 @@ LL | struct A {
= help: to override `-D warnings` add `#[allow(clippy::min_ident_chars)]`
error: this ident consists of a single char
--> $DIR/min_ident_chars.rs:9:5
--> $DIR/min_ident_chars.rs:10:5
|
LL | a: u32,
| ^
error: this ident consists of a single char
--> $DIR/min_ident_chars.rs:11:5
--> $DIR/min_ident_chars.rs:12:5
|
LL | A: u32,
| ^
error: this ident consists of a single char
--> $DIR/min_ident_chars.rs:12:5
--> $DIR/min_ident_chars.rs:13:5
|
LL | I: u32,
| ^
error: this ident consists of a single char
--> $DIR/min_ident_chars.rs:15:8
--> $DIR/min_ident_chars.rs:16:8
|
LL | struct B(u32);
| ^
error: this ident consists of a single char
--> $DIR/min_ident_chars.rs:17:8
--> $DIR/min_ident_chars.rs:18:8
|
LL | struct O {
| ^
error: this ident consists of a single char
--> $DIR/min_ident_chars.rs:18:5
--> $DIR/min_ident_chars.rs:19:5
|
LL | o: u32,
| ^
error: this ident consists of a single char
--> $DIR/min_ident_chars.rs:23:6
--> $DIR/min_ident_chars.rs:24:6
|
LL | enum C {
| ^
error: this ident consists of a single char
--> $DIR/min_ident_chars.rs:24:5
--> $DIR/min_ident_chars.rs:25:5
|
LL | D,
| ^
error: this ident consists of a single char
--> $DIR/min_ident_chars.rs:25:5
--> $DIR/min_ident_chars.rs:26:5
|
LL | E,
| ^
error: this ident consists of a single char
--> $DIR/min_ident_chars.rs:26:5
--> $DIR/min_ident_chars.rs:27:5
|
LL | F,
| ^
error: this ident consists of a single char
--> $DIR/min_ident_chars.rs:50:9
--> $DIR/min_ident_chars.rs:51:9
|
LL | let h = 1;
| ^
error: this ident consists of a single char
--> $DIR/min_ident_chars.rs:51:9
--> $DIR/min_ident_chars.rs:52:9
|
LL | let e = 2;
| ^
error: this ident consists of a single char
--> $DIR/min_ident_chars.rs:52:9
--> $DIR/min_ident_chars.rs:53:9
|
LL | let l = 3;
| ^
error: this ident consists of a single char
--> $DIR/min_ident_chars.rs:53:9
--> $DIR/min_ident_chars.rs:54:9
|
LL | let l = 4;
| ^
error: this ident consists of a single char
--> $DIR/min_ident_chars.rs:54:9
--> $DIR/min_ident_chars.rs:55:9
|
LL | let o = 6;
| ^
error: this ident consists of a single char
--> $DIR/min_ident_chars.rs:58:10
--> $DIR/min_ident_chars.rs:59:10
|
LL | let (h, o, w) = (1, 2, 3);
| ^
error: this ident consists of a single char
--> $DIR/min_ident_chars.rs:58:13
--> $DIR/min_ident_chars.rs:59:13
|
LL | let (h, o, w) = (1, 2, 3);
| ^
error: this ident consists of a single char
--> $DIR/min_ident_chars.rs:59:10
--> $DIR/min_ident_chars.rs:60:10
|
LL | for (a, (r, e)) in (0..1000).enumerate().enumerate() {}
| ^
error: this ident consists of a single char
--> $DIR/min_ident_chars.rs:59:14
--> $DIR/min_ident_chars.rs:60:14
|
LL | for (a, (r, e)) in (0..1000).enumerate().enumerate() {}
| ^
error: this ident consists of a single char
--> $DIR/min_ident_chars.rs:59:17
--> $DIR/min_ident_chars.rs:60:17
|
LL | for (a, (r, e)) in (0..1000).enumerate().enumerate() {}
| ^
error: this ident consists of a single char
--> $DIR/min_ident_chars.rs:61:16
--> $DIR/min_ident_chars.rs:62:16
|
LL | while let (d, o, _i, n, g) = (true, true, false, false, true) {}
| ^
error: this ident consists of a single char
--> $DIR/min_ident_chars.rs:61:19
--> $DIR/min_ident_chars.rs:62:19
|
LL | while let (d, o, _i, n, g) = (true, true, false, false, true) {}
| ^
error: this ident consists of a single char
--> $DIR/min_ident_chars.rs:61:29
--> $DIR/min_ident_chars.rs:62:29
|
LL | while let (d, o, _i, n, g) = (true, true, false, false, true) {}
| ^
error: this ident consists of a single char
--> $DIR/min_ident_chars.rs:65:9
--> $DIR/min_ident_chars.rs:66:9
|
LL | let o = 1;
| ^
error: this ident consists of a single char
--> $DIR/min_ident_chars.rs:66:9
--> $DIR/min_ident_chars.rs:67:9
|
LL | let o = O { o };
| ^
error: this ident consists of a single char
--> $DIR/min_ident_chars.rs:80:4
--> $DIR/min_ident_chars.rs:81:4
|
LL | fn b() {}
| ^
error: this ident consists of a single char
--> $DIR/min_ident_chars.rs:81:21
--> $DIR/min_ident_chars.rs:82:21
|
LL | fn wrong_pythagoras(a: f32, b: f32) -> f32 {
| ^
error: this ident consists of a single char
--> $DIR/min_ident_chars.rs:81:29
--> $DIR/min_ident_chars.rs:82:29
|
LL | fn wrong_pythagoras(a: f32, b: f32) -> f32 {
| ^

View file

@ -1,4 +1,5 @@
#![allow(unused)]
#![allow(clippy::struct_field_names)]
#![warn(clippy::misnamed_getters)]
struct A {

View file

@ -1,4 +1,5 @@
#![allow(unused)]
#![allow(clippy::struct_field_names)]
#![warn(clippy::misnamed_getters)]
struct A {

View file

@ -1,5 +1,5 @@
error: getter function appears to return the wrong field
--> $DIR/misnamed_getters.rs:11:5
--> $DIR/misnamed_getters.rs:12:5
|
LL | / fn a(&self) -> &u8 {
LL | |
@ -13,7 +13,7 @@ LL | | }
= help: to override `-D warnings` add `#[allow(clippy::misnamed_getters)]`
error: getter function appears to return the wrong field
--> $DIR/misnamed_getters.rs:16:5
--> $DIR/misnamed_getters.rs:17:5
|
LL | / fn a_mut(&mut self) -> &mut u8 {
LL | |
@ -23,7 +23,7 @@ LL | | }
| |_____^
error: getter function appears to return the wrong field
--> $DIR/misnamed_getters.rs:21:5
--> $DIR/misnamed_getters.rs:22:5
|
LL | / fn b(self) -> u8 {
LL | |
@ -33,7 +33,7 @@ LL | | }
| |_____^
error: getter function appears to return the wrong field
--> $DIR/misnamed_getters.rs:26:5
--> $DIR/misnamed_getters.rs:27:5
|
LL | / fn b_mut(&mut self) -> &mut u8 {
LL | |
@ -43,7 +43,7 @@ LL | | }
| |_____^
error: getter function appears to return the wrong field
--> $DIR/misnamed_getters.rs:31:5
--> $DIR/misnamed_getters.rs:32:5
|
LL | / fn c(&self) -> &u8 {
LL | |
@ -53,7 +53,7 @@ LL | | }
| |_____^
error: getter function appears to return the wrong field
--> $DIR/misnamed_getters.rs:36:5
--> $DIR/misnamed_getters.rs:37:5
|
LL | / fn c_mut(&mut self) -> &mut u8 {
LL | |
@ -63,7 +63,7 @@ LL | | }
| |_____^
error: getter function appears to return the wrong field
--> $DIR/misnamed_getters.rs:48:5
--> $DIR/misnamed_getters.rs:49:5
|
LL | / unsafe fn a(&self) -> &u8 {
LL | |
@ -73,7 +73,7 @@ LL | | }
| |_____^
error: getter function appears to return the wrong field
--> $DIR/misnamed_getters.rs:52:5
--> $DIR/misnamed_getters.rs:53:5
|
LL | / unsafe fn a_mut(&mut self) -> &mut u8 {
LL | |
@ -83,7 +83,7 @@ LL | | }
| |_____^
error: getter function appears to return the wrong field
--> $DIR/misnamed_getters.rs:57:5
--> $DIR/misnamed_getters.rs:58:5
|
LL | / unsafe fn b(self) -> u8 {
LL | |
@ -93,7 +93,7 @@ LL | | }
| |_____^
error: getter function appears to return the wrong field
--> $DIR/misnamed_getters.rs:62:5
--> $DIR/misnamed_getters.rs:63:5
|
LL | / unsafe fn b_mut(&mut self) -> &mut u8 {
LL | |
@ -103,7 +103,7 @@ LL | | }
| |_____^
error: getter function appears to return the wrong field
--> $DIR/misnamed_getters.rs:75:5
--> $DIR/misnamed_getters.rs:76:5
|
LL | / unsafe fn a_unchecked(&self) -> &u8 {
LL | |
@ -113,7 +113,7 @@ LL | | }
| |_____^
error: getter function appears to return the wrong field
--> $DIR/misnamed_getters.rs:79:5
--> $DIR/misnamed_getters.rs:80:5
|
LL | / unsafe fn a_unchecked_mut(&mut self) -> &mut u8 {
LL | |
@ -123,7 +123,7 @@ LL | | }
| |_____^
error: getter function appears to return the wrong field
--> $DIR/misnamed_getters.rs:84:5
--> $DIR/misnamed_getters.rs:85:5
|
LL | / unsafe fn b_unchecked(self) -> u8 {
LL | |
@ -133,7 +133,7 @@ LL | | }
| |_____^
error: getter function appears to return the wrong field
--> $DIR/misnamed_getters.rs:89:5
--> $DIR/misnamed_getters.rs:90:5
|
LL | / unsafe fn b_unchecked_mut(&mut self) -> &mut u8 {
LL | |
@ -143,7 +143,7 @@ LL | | }
| |_____^
error: getter function appears to return the wrong field
--> $DIR/misnamed_getters.rs:122:5
--> $DIR/misnamed_getters.rs:123:5
|
LL | / fn a(&self) -> &u8 {
LL | |
@ -153,7 +153,7 @@ LL | | }
| |_____^
error: getter function appears to return the wrong field
--> $DIR/misnamed_getters.rs:126:5
--> $DIR/misnamed_getters.rs:127:5
|
LL | / fn a_mut(&mut self) -> &mut u8 {
LL | |
@ -163,7 +163,7 @@ LL | | }
| |_____^
error: getter function appears to return the wrong field
--> $DIR/misnamed_getters.rs:131:5
--> $DIR/misnamed_getters.rs:132:5
|
LL | / fn d(&self) -> &u8 {
LL | |
@ -173,7 +173,7 @@ LL | | }
| |_____^
error: getter function appears to return the wrong field
--> $DIR/misnamed_getters.rs:135:5
--> $DIR/misnamed_getters.rs:136:5
|
LL | / fn d_mut(&mut self) -> &mut u8 {
LL | |

View file

@ -7,7 +7,8 @@
clippy::equatable_if_let,
clippy::needless_if,
clippy::needless_return,
clippy::self_named_constructors
clippy::self_named_constructors,
clippy::struct_field_names
)]
use std::cell::Cell;

View file

@ -7,7 +7,8 @@
clippy::equatable_if_let,
clippy::needless_if,
clippy::needless_return,
clippy::self_named_constructors
clippy::self_named_constructors,
clippy::struct_field_names
)]
use std::cell::Cell;

View file

@ -1,5 +1,5 @@
error: this if-then-else expression returns a bool literal
--> $DIR/fixable.rs:40:5
--> $DIR/fixable.rs:41:5
|
LL | / if x {
LL | | true
@ -12,7 +12,7 @@ LL | | };
= help: to override `-D warnings` add `#[allow(clippy::needless_bool)]`
error: this if-then-else expression returns a bool literal
--> $DIR/fixable.rs:45:5
--> $DIR/fixable.rs:46:5
|
LL | / if x {
LL | | false
@ -22,7 +22,7 @@ LL | | };
| |_____^ help: you can reduce it to: `!x`
error: this if-then-else expression returns a bool literal
--> $DIR/fixable.rs:50:5
--> $DIR/fixable.rs:51:5
|
LL | / if x && y {
LL | | false
@ -32,7 +32,7 @@ LL | | };
| |_____^ help: you can reduce it to: `!(x && y)`
error: this if-then-else expression returns a bool literal
--> $DIR/fixable.rs:58:5
--> $DIR/fixable.rs:59:5
|
LL | / if a == b {
LL | | false
@ -42,7 +42,7 @@ LL | | };
| |_____^ help: you can reduce it to: `a != b`
error: this if-then-else expression returns a bool literal
--> $DIR/fixable.rs:63:5
--> $DIR/fixable.rs:64:5
|
LL | / if a != b {
LL | | false
@ -52,7 +52,7 @@ LL | | };
| |_____^ help: you can reduce it to: `a == b`
error: this if-then-else expression returns a bool literal
--> $DIR/fixable.rs:68:5
--> $DIR/fixable.rs:69:5
|
LL | / if a < b {
LL | | false
@ -62,7 +62,7 @@ LL | | };
| |_____^ help: you can reduce it to: `a >= b`
error: this if-then-else expression returns a bool literal
--> $DIR/fixable.rs:73:5
--> $DIR/fixable.rs:74:5
|
LL | / if a <= b {
LL | | false
@ -72,7 +72,7 @@ LL | | };
| |_____^ help: you can reduce it to: `a > b`
error: this if-then-else expression returns a bool literal
--> $DIR/fixable.rs:78:5
--> $DIR/fixable.rs:79:5
|
LL | / if a > b {
LL | | false
@ -82,7 +82,7 @@ LL | | };
| |_____^ help: you can reduce it to: `a <= b`
error: this if-then-else expression returns a bool literal
--> $DIR/fixable.rs:83:5
--> $DIR/fixable.rs:84:5
|
LL | / if a >= b {
LL | | false
@ -92,7 +92,7 @@ LL | | };
| |_____^ help: you can reduce it to: `a < b`
error: this if-then-else expression returns a bool literal
--> $DIR/fixable.rs:111:5
--> $DIR/fixable.rs:112:5
|
LL | / if x {
LL | | return true;
@ -102,7 +102,7 @@ LL | | };
| |_____^ help: you can reduce it to: `return x`
error: this if-then-else expression returns a bool literal
--> $DIR/fixable.rs:119:5
--> $DIR/fixable.rs:120:5
|
LL | / if x {
LL | | return false;
@ -112,7 +112,7 @@ LL | | };
| |_____^ help: you can reduce it to: `return !x`
error: this if-then-else expression returns a bool literal
--> $DIR/fixable.rs:127:5
--> $DIR/fixable.rs:128:5
|
LL | / if x && y {
LL | | return true;
@ -122,7 +122,7 @@ LL | | };
| |_____^ help: you can reduce it to: `return x && y`
error: this if-then-else expression returns a bool literal
--> $DIR/fixable.rs:135:5
--> $DIR/fixable.rs:136:5
|
LL | / if x && y {
LL | | return false;
@ -132,7 +132,7 @@ LL | | };
| |_____^ help: you can reduce it to: `return !(x && y)`
error: equality checks against true are unnecessary
--> $DIR/fixable.rs:143:8
--> $DIR/fixable.rs:144:8
|
LL | if x == true {};
| ^^^^^^^^^ help: try simplifying it as shown: `x`
@ -141,25 +141,25 @@ LL | if x == true {};
= help: to override `-D warnings` add `#[allow(clippy::bool_comparison)]`
error: equality checks against false can be replaced by a negation
--> $DIR/fixable.rs:147:8
--> $DIR/fixable.rs:148:8
|
LL | if x == false {};
| ^^^^^^^^^^ help: try simplifying it as shown: `!x`
error: equality checks against true are unnecessary
--> $DIR/fixable.rs:157:8
--> $DIR/fixable.rs:158:8
|
LL | if x == true {};
| ^^^^^^^^^ help: try simplifying it as shown: `x`
error: equality checks against false can be replaced by a negation
--> $DIR/fixable.rs:158:8
--> $DIR/fixable.rs:159:8
|
LL | if x == false {};
| ^^^^^^^^^^ help: try simplifying it as shown: `!x`
error: this if-then-else expression returns a bool literal
--> $DIR/fixable.rs:167:12
--> $DIR/fixable.rs:168:12
|
LL | } else if returns_bool() {
| ____________^
@ -170,7 +170,7 @@ LL | | };
| |_____^ help: you can reduce it to: `{ !returns_bool() }`
error: this if-then-else expression returns a bool literal
--> $DIR/fixable.rs:180:5
--> $DIR/fixable.rs:181:5
|
LL | / if unsafe { no(4) } & 1 != 0 {
LL | | true
@ -180,13 +180,13 @@ LL | | };
| |_____^ help: you can reduce it to: `(unsafe { no(4) } & 1 != 0)`
error: this if-then-else expression returns a bool literal
--> $DIR/fixable.rs:185:30
--> $DIR/fixable.rs:186:30
|
LL | let _brackets_unneeded = if unsafe { no(4) } & 1 != 0 { true } else { false };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: you can reduce it to: `unsafe { no(4) } & 1 != 0`
error: this if-then-else expression returns a bool literal
--> $DIR/fixable.rs:188:9
--> $DIR/fixable.rs:189:9
|
LL | if unsafe { no(4) } & 1 != 0 { true } else { false }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: you can reduce it to: `(unsafe { no(4) } & 1 != 0)`

View file

@ -1,4 +1,5 @@
#![warn(clippy::rest_pat_in_fully_bound_structs)]
#![allow(clippy::struct_field_names)]
struct A {
a: i32,

View file

@ -1,5 +1,5 @@
error: unnecessary use of `..` pattern in struct binding. All fields were already bound
--> $DIR/rest_pat_in_fully_bound_structs.rs:22:9
--> $DIR/rest_pat_in_fully_bound_structs.rs:23:9
|
LL | A { a: 5, b: 42, c: "", .. } => {}, // Lint
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@ -9,7 +9,7 @@ LL | A { a: 5, b: 42, c: "", .. } => {}, // Lint
= help: to override `-D warnings` add `#[allow(clippy::rest_pat_in_fully_bound_structs)]`
error: unnecessary use of `..` pattern in struct binding. All fields were already bound
--> $DIR/rest_pat_in_fully_bound_structs.rs:24:9
--> $DIR/rest_pat_in_fully_bound_structs.rs:25:9
|
LL | A { a: 0, b: 0, c: "", .. } => {}, // Lint
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
@ -17,7 +17,7 @@ LL | A { a: 0, b: 0, c: "", .. } => {}, // Lint
= help: consider removing `..` from this binding
error: unnecessary use of `..` pattern in struct binding. All fields were already bound
--> $DIR/rest_pat_in_fully_bound_structs.rs:31:9
--> $DIR/rest_pat_in_fully_bound_structs.rs:32:9
|
LL | A { a: 0, b: 0, c: "", .. } => {}, // Lint
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^

331
tests/ui/struct_fields.rs Normal file
View file

@ -0,0 +1,331 @@
//@aux-build:proc_macros.rs
#![warn(clippy::struct_field_names)]
#![allow(unused)]
#[macro_use]
extern crate proc_macros;
struct Data1 {
field_data1: u8,
//~^ ERROR: field name ends with the struct's name
another: u8,
foo: u8,
bar: u8,
}
struct Data2 {
another: u8,
foo: u8,
data2_field: u8,
//~^ ERROR: field name starts with the struct's name
bar: u8,
}
struct StructData {
//~^ ERROR: all fields have the same postfix: `data`
movable_data: u8,
fixed_data: u8,
invisible_data: u8,
}
struct DataStruct {
//~^ ERROR: all fields have the same prefix: `data`
data_movable: u8,
data_fixed: u8,
data_invisible: u8,
}
struct DoublePrefix {
//~^ ERROR: all fields have the same prefix: `some_data`
some_data_a: bool,
some_data_b: bool,
some_data_c: bool,
}
struct DoublePostfix {
//~^ ERROR: all fields have the same postfix: `some_data`
a_some_data: bool,
b_some_data: bool,
c_some_data: bool,
}
#[allow(non_snake_case)]
struct NotSnakeCase {
//~^ ERROR: all fields have the same postfix: `someData`
a_someData: bool,
b_someData: bool,
c_someData: bool,
}
#[allow(non_snake_case)]
struct NotSnakeCase2 {
//~^ ERROR: all fields have the same prefix: `someData`
someData_c: bool,
someData_b: bool,
someData_a_b: bool,
}
// no error, threshold is 3 fiels by default
struct Fooo {
foo: u8,
bar: u8,
}
struct NonCaps {
//~^ ERROR: all fields have the same prefix: `prefix`
prefix_的: u8,
prefix_tea: u8,
prefix_cake: u8,
}
// should not lint
#[allow(clippy::struct_field_names)]
pub mod allowed {
pub struct PubAllowed {
some_this: u8,
some_that: u8,
some_other_what: u8,
}
}
// should not lint
struct SomeData {
foo: u8,
bar: bool,
path: u8,
answer: u8,
}
// should not lint
pub struct NetworkLayer {
layer1: Vec<u8>,
layer2: Vec<u8>,
layer3: Vec<u8>,
layer4: Vec<u8>,
}
//should not lint
struct North {
normal: u8,
no_left: u8,
no_right: u8,
}
mod issue8324_from_enum_variant_names {
// 8324: enum_variant_names warns even if removing the suffix would leave an empty string
struct Phase {
pre_lookup: u8,
lookup: u8,
post_lookup: u8,
}
}
mod issue9018_from_enum_variant_names {
struct DoLint {
//~^ ERROR: all fields have the same prefix: `_type`
_type_create: u8,
_type_read: u8,
_type_update: u8,
_type_destroy: u8,
}
struct DoLint2 {
//~^ ERROR: all fields have the same prefix: `__type`
__type_create: u8,
__type_read: u8,
__type_update: u8,
__type_destroy: u8,
}
struct DoLint3 {
//~^ ERROR: all fields have the same prefix: `___type`
___type_create: u8,
___type_read: u8,
___type_update: u8,
___type_destroy: u8,
}
struct DoLint4 {
//~^ ERROR: all fields have the same postfix: `_`
create_: u8,
read_: u8,
update_: u8,
destroy_: u8,
}
struct DoLint5 {
//~^ ERROR: all fields have the same postfix: `__`
create__: u8,
read__: u8,
update__: u8,
destroy__: u8,
}
struct DoLint6 {
//~^ ERROR: all fields have the same postfix: `___`
create___: u8,
read___: u8,
update___: u8,
destroy___: u8,
}
struct DoLintToo {
//~^ ERROR: all fields have the same postfix: `type`
_create_type: u8,
_update_type: u8,
_delete_type: u8,
}
struct DoNotLint {
_foo: u8,
_bar: u8,
_baz: u8,
}
struct DoNotLint2 {
__foo: u8,
__bar: u8,
__baz: u8,
}
}
mod allow_attributes_on_fields {
struct Struct {
#[allow(clippy::struct_field_names)]
struct_starts_with: u8,
#[allow(clippy::struct_field_names)]
ends_with_struct: u8,
foo: u8,
}
}
// food field should not lint
struct Foo {
food: i32,
a: i32,
b: i32,
}
struct Proxy {
proxy: i32,
//~^ ERROR: field name starts with the struct's name
unrelated1: bool,
unrelated2: bool,
}
// should not lint
pub struct RegexT {
__buffer: i32,
__allocated: i32,
__used: i32,
}
mod macro_tests {
macro_rules! mk_struct {
() => {
struct MacroStruct {
some_a: i32,
some_b: i32,
some_c: i32,
}
};
}
mk_struct!();
//~^ ERROR: all fields have the same prefix: `some`
macro_rules! mk_struct2 {
() => {
struct Macrobaz {
macrobaz_a: i32,
some_b: i32,
some_c: i32,
}
};
}
mk_struct2!();
//~^ ERROR: field name starts with the struct's name
macro_rules! mk_struct_with_names {
($struct_name:ident, $field:ident) => {
struct $struct_name {
$field: i32,
other_something: i32,
other_field: i32,
}
};
}
// expands to `struct Foo { foo: i32, ... }`
mk_struct_with_names!(Foo, foo);
//~^ ERROR: field name starts with the struct's name
// expands to a struct with all fields starting with `other` but should not
// be linted because some fields come from the macro definition and the other from the input
mk_struct_with_names!(Some, other_data);
// should not lint when names come from different places
macro_rules! mk_struct_with_field_name {
($field_name:ident) => {
struct Baz {
one: i32,
two: i32,
$field_name: i32,
}
};
}
mk_struct_with_field_name!(baz_three);
// should not lint when names come from different places
macro_rules! mk_struct_with_field_name {
($field_name:ident) => {
struct Bazilisk {
baz_one: i32,
baz_two: i32,
$field_name: i32,
}
};
}
mk_struct_with_field_name!(baz_three);
macro_rules! mk_struct_full_def {
($struct_name:ident, $field1:ident, $field2:ident, $field3:ident) => {
struct $struct_name {
$field1: i32,
$field2: i32,
$field3: i32,
}
};
}
mk_struct_full_def!(PrefixData, some_data, some_meta, some_other);
//~^ ERROR: all fields have the same prefix: `some`
}
// should not lint on external code
external! {
struct DataExternal {
field_data1: u8,
another: u8,
foo: u8,
bar: u8,
}
struct NotSnakeCaseExternal {
someData_c: bool,
someData_b: bool,
someData_a_b: bool,
}
struct DoublePrefixExternal {
some_data_a: bool,
some_data_b: bool,
some_data_c: bool,
}
struct StructDataExternal {
movable_data: u8,
fixed_data: u8,
invisible_data: u8,
}
}
fn main() {}

View file

@ -0,0 +1,265 @@
error: field name ends with the struct's name
--> $DIR/struct_fields.rs:10:5
|
LL | field_data1: u8,
| ^^^^^^^^^^^^^^^
|
= note: `-D clippy::struct-field-names` implied by `-D warnings`
= help: to override `-D warnings` add `#[allow(clippy::struct_field_names)]`
error: field name starts with the struct's name
--> $DIR/struct_fields.rs:20:5
|
LL | data2_field: u8,
| ^^^^^^^^^^^^^^^
error: all fields have the same postfix: `data`
--> $DIR/struct_fields.rs:25:1
|
LL | / struct StructData {
LL | |
LL | | movable_data: u8,
LL | | fixed_data: u8,
LL | | invisible_data: u8,
LL | | }
| |_^
|
= help: remove the postfixes
error: all fields have the same prefix: `data`
--> $DIR/struct_fields.rs:32:1
|
LL | / struct DataStruct {
LL | |
LL | | data_movable: u8,
LL | | data_fixed: u8,
LL | | data_invisible: u8,
LL | | }
| |_^
|
= help: remove the prefixes
error: all fields have the same prefix: `some_data`
--> $DIR/struct_fields.rs:39:1
|
LL | / struct DoublePrefix {
LL | |
LL | | some_data_a: bool,
LL | | some_data_b: bool,
LL | | some_data_c: bool,
LL | | }
| |_^
|
= help: remove the prefixes
error: all fields have the same postfix: `some_data`
--> $DIR/struct_fields.rs:46:1
|
LL | / struct DoublePostfix {
LL | |
LL | | a_some_data: bool,
LL | | b_some_data: bool,
LL | | c_some_data: bool,
LL | | }
| |_^
|
= help: remove the postfixes
error: all fields have the same postfix: `someData`
--> $DIR/struct_fields.rs:54:1
|
LL | / struct NotSnakeCase {
LL | |
LL | | a_someData: bool,
LL | | b_someData: bool,
LL | | c_someData: bool,
LL | | }
| |_^
|
= help: remove the postfixes
error: all fields have the same prefix: `someData`
--> $DIR/struct_fields.rs:61:1
|
LL | / struct NotSnakeCase2 {
LL | |
LL | | someData_c: bool,
LL | | someData_b: bool,
LL | | someData_a_b: bool,
LL | | }
| |_^
|
= help: remove the prefixes
error: all fields have the same prefix: `prefix`
--> $DIR/struct_fields.rs:74:1
|
LL | / struct NonCaps {
LL | |
LL | | prefix_的: u8,
LL | | prefix_tea: u8,
LL | | prefix_cake: u8,
LL | | }
| |_^
|
= help: remove the prefixes
error: all fields have the same prefix: `_type`
--> $DIR/struct_fields.rs:124:5
|
LL | / struct DoLint {
LL | |
LL | | _type_create: u8,
LL | | _type_read: u8,
LL | | _type_update: u8,
LL | | _type_destroy: u8,
LL | | }
| |_____^
|
= help: remove the prefixes
error: all fields have the same prefix: `__type`
--> $DIR/struct_fields.rs:132:5
|
LL | / struct DoLint2 {
LL | |
LL | | __type_create: u8,
LL | | __type_read: u8,
LL | | __type_update: u8,
LL | | __type_destroy: u8,
LL | | }
| |_____^
|
= help: remove the prefixes
error: all fields have the same prefix: `___type`
--> $DIR/struct_fields.rs:140:5
|
LL | / struct DoLint3 {
LL | |
LL | | ___type_create: u8,
LL | | ___type_read: u8,
LL | | ___type_update: u8,
LL | | ___type_destroy: u8,
LL | | }
| |_____^
|
= help: remove the prefixes
error: all fields have the same postfix: `_`
--> $DIR/struct_fields.rs:148:5
|
LL | / struct DoLint4 {
LL | |
LL | | create_: u8,
LL | | read_: u8,
LL | | update_: u8,
LL | | destroy_: u8,
LL | | }
| |_____^
|
= help: remove the postfixes
error: all fields have the same postfix: `__`
--> $DIR/struct_fields.rs:156:5
|
LL | / struct DoLint5 {
LL | |
LL | | create__: u8,
LL | | read__: u8,
LL | | update__: u8,
LL | | destroy__: u8,
LL | | }
| |_____^
|
= help: remove the postfixes
error: all fields have the same postfix: `___`
--> $DIR/struct_fields.rs:164:5
|
LL | / struct DoLint6 {
LL | |
LL | | create___: u8,
LL | | read___: u8,
LL | | update___: u8,
LL | | destroy___: u8,
LL | | }
| |_____^
|
= help: remove the postfixes
error: all fields have the same postfix: `type`
--> $DIR/struct_fields.rs:172:5
|
LL | / struct DoLintToo {
LL | |
LL | | _create_type: u8,
LL | | _update_type: u8,
LL | | _delete_type: u8,
LL | | }
| |_____^
|
= help: remove the postfixes
error: field name starts with the struct's name
--> $DIR/struct_fields.rs:210:5
|
LL | proxy: i32,
| ^^^^^^^^^^
error: all fields have the same prefix: `some`
--> $DIR/struct_fields.rs:226:13
|
LL | / struct MacroStruct {
LL | | some_a: i32,
LL | | some_b: i32,
LL | | some_c: i32,
LL | | }
| |_____________^
...
LL | mk_struct!();
| ------------ in this macro invocation
|
= help: remove the prefixes
= note: this error originates in the macro `mk_struct` (in Nightly builds, run with -Z macro-backtrace for more info)
error: field name starts with the struct's name
--> $DIR/struct_fields.rs:239:17
|
LL | macrobaz_a: i32,
| ^^^^^^^^^^^^^^^
...
LL | mk_struct2!();
| ------------- in this macro invocation
|
= note: this error originates in the macro `mk_struct2` (in Nightly builds, run with -Z macro-backtrace for more info)
error: field name starts with the struct's name
--> $DIR/struct_fields.rs:251:17
|
LL | $field: i32,
| ^^^^^^^^^^^
...
LL | mk_struct_with_names!(Foo, foo);
| ------------------------------- in this macro invocation
|
= note: this error originates in the macro `mk_struct_with_names` (in Nightly builds, run with -Z macro-backtrace for more info)
error: all fields have the same prefix: `some`
--> $DIR/struct_fields.rs:291:13
|
LL | / struct $struct_name {
LL | | $field1: i32,
LL | | $field2: i32,
LL | | $field3: i32,
LL | | }
| |_____________^
...
LL | mk_struct_full_def!(PrefixData, some_data, some_meta, some_other);
| ----------------------------------------------------------------- in this macro invocation
|
= help: remove the prefixes
= note: this error originates in the macro `mk_struct_full_def` (in Nightly builds, run with -Z macro-backtrace for more info)
error: aborting due to 21 previous errors