Skip to content

Commit d58858a

Browse files
committed
Add max-ident-chars-length to config and is set to 100 by default.
1 parent 3c54672 commit d58858a

File tree

15 files changed

+195
-57
lines changed

15 files changed

+195
-57
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6109,6 +6109,7 @@ Released 2018-09-13
61096109
[`match_str_case_mismatch`]: https://rust-lang.github.io/rust-clippy/master/index.html#match_str_case_mismatch
61106110
[`match_wild_err_arm`]: https://rust-lang.github.io/rust-clippy/master/index.html#match_wild_err_arm
61116111
[`match_wildcard_for_single_variants`]: https://rust-lang.github.io/rust-clippy/master/index.html#match_wildcard_for_single_variants
6112+
[`max_ident_chars`]: https://rust-lang.github.io/rust-clippy/master/index.html#max_ident_chars
61126113
[`maybe_infinite_iter`]: https://rust-lang.github.io/rust-clippy/master/index.html#maybe_infinite_iter
61136114
[`maybe_misused_cfg`]: https://rust-lang.github.io/rust-clippy/master/index.html#maybe_misused_cfg
61146115
[`mem_discriminant_non_enum`]: https://rust-lang.github.io/rust-clippy/master/index.html#mem_discriminant_non_enum
@@ -6626,6 +6627,7 @@ Released 2018-09-13
66266627
[`literal-representation-threshold`]: https://doc.rust-lang.org/clippy/lint_configuration.html#literal-representation-threshold
66276628
[`matches-for-let-else`]: https://doc.rust-lang.org/clippy/lint_configuration.html#matches-for-let-else
66286629
[`max-fn-params-bools`]: https://doc.rust-lang.org/clippy/lint_configuration.html#max-fn-params-bools
6630+
[`max-ident-chars-length`]: https://doc.rust-lang.org/clippy/lint_configuration.html#max-ident-chars-length
66296631
[`max-include-file-size`]: https://doc.rust-lang.org/clippy/lint_configuration.html#max-include-file-size
66306632
[`max-struct-bools`]: https://doc.rust-lang.org/clippy/lint_configuration.html#max-struct-bools
66316633
[`max-suggested-slice-pattern-length`]: https://doc.rust-lang.org/clippy/lint_configuration.html#max-suggested-slice-pattern-length

book/src/lint_configuration.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -714,6 +714,16 @@ The maximum number of bool parameters a function can have
714714
* [`fn_params_excessive_bools`](https://rust-lang.github.io/rust-clippy/master/index.html#fn_params_excessive_bools)
715715

716716

717+
## `max-ident-chars-length`
718+
The maximum length of an identifier
719+
720+
**Default Value:** `100`
721+
722+
---
723+
**Affected lints:**
724+
* [`max_ident_chars`](https://rust-lang.github.io/rust-clippy/master/index.html#max_ident_chars)
725+
726+
717727
## `max-include-file-size`
718728
The maximum size of a file included via `include_bytes!()` or `include_str!()`, in bytes
719729

clippy_config/src/conf.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -682,6 +682,9 @@ define_Conf! {
682682
/// The maximum number of bool parameters a function can have
683683
#[lints(fn_params_excessive_bools)]
684684
max_fn_params_bools: u64 = 3,
685+
/// The maximum length of an identifier
686+
#[lints(max_ident_chars)]
687+
max_ident_chars_length: u32 = 100,
685688
/// The maximum size of a file included via `include_bytes!()` or `include_str!()`, in bytes
686689
#[lints(large_include_file)]
687690
max_include_file_size: u64 = 1_000_000,

clippy_lints/src/declared_lints.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -198,6 +198,8 @@ pub static LINTS: &[&::declare_clippy_lint::LintInfo] = &[
198198
crate::functions::TOO_MANY_ARGUMENTS_INFO,
199199
crate::functions::TOO_MANY_LINES_INFO,
200200
crate::future_not_send::FUTURE_NOT_SEND_INFO,
201+
crate::ident_chars::MAX_IDENT_CHARS_INFO,
202+
crate::ident_chars::MIN_IDENT_CHARS_INFO,
201203
crate::if_let_mutex::IF_LET_MUTEX_INFO,
202204
crate::if_not_else::IF_NOT_ELSE_INFO,
203205
crate::if_then_some_else_none::IF_THEN_SOME_ELSE_NONE_INFO,
@@ -497,7 +499,6 @@ pub static LINTS: &[&::declare_clippy_lint::LintInfo] = &[
497499
crate::methods::WAKER_CLONE_WAKE_INFO,
498500
crate::methods::WRONG_SELF_CONVENTION_INFO,
499501
crate::methods::ZST_OFFSET_INFO,
500-
crate::min_ident_chars::MIN_IDENT_CHARS_INFO,
501502
crate::minmax::MIN_MAX_INFO,
502503
crate::misc::SHORT_CIRCUIT_STATEMENT_INFO,
503504
crate::misc::TOPLEVEL_REF_ARG_INFO,

clippy_lints/src/min_ident_chars.rs renamed to clippy_lints/src/ident_chars.rs

Lines changed: 85 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,18 +45,54 @@ declare_clippy_lint! {
4545
restriction,
4646
"disallows idents that are too short"
4747
}
48-
impl_lint_pass!(MinIdentChars => [MIN_IDENT_CHARS]);
4948

49+
declare_clippy_lint! {
50+
/// ### What it does
51+
/// Checks for identifiers which are too long (higher than the configured threshold).
52+
/// Note: This lint can be very noisy when enabled; it may be desirable to only enable it
53+
/// temporarily.
54+
///
55+
/// ### Why restrict this?
56+
/// To improve readability of code and make it possible to enforce this lint to align a code
57+
/// style on this subject within a team.
58+
///
59+
/// ### Example of long identifiers
60+
/// ```rust,ignore
61+
/// for from_a_long_list_of_movies_which_might_contain_ferris_or_not_you_never_know in movies {
62+
/// let title = from_a_long_list_of_movies_which_might_contain_ferris_or_not_you_never_know.title;
63+
/// }
64+
/// ```
65+
/// Use instead:
66+
/// ```rust,ignore
67+
/// for movie in movies {
68+
/// let title = movie.title;
69+
/// }
70+
/// ```
71+
///
72+
/// ### Limitations
73+
/// Trait implementations which use the same function or parameter name as the trait declaration will
74+
/// not be warned about, even if the name is longer than the configured limit.
75+
#[clippy::version = "1.92.0"]
76+
pub MAX_IDENT_CHARS,
77+
restriction,
78+
"disallows idents which exceeding the max ident length"
79+
}
80+
81+
impl_lint_pass!(MinIdentChars => [MIN_IDENT_CHARS, MAX_IDENT_CHARS]);
82+
83+
#[allow(clippy::struct_field_names)]
5084
pub struct MinIdentChars {
5185
allowed_idents_below_min_chars: FxHashSet<String>,
5286
min_ident_chars_threshold: u64,
87+
max_variable_name_length: u32,
5388
}
5489

5590
impl MinIdentChars {
5691
pub fn new(conf: &'static Conf) -> Self {
5792
Self {
5893
allowed_idents_below_min_chars: conf.allowed_idents_below_min_chars.iter().cloned().collect(),
5994
min_ident_chars_threshold: conf.min_ident_chars_threshold,
95+
max_variable_name_length: conf.max_ident_chars_length,
6096
}
6197
}
6298

@@ -68,6 +104,10 @@ impl MinIdentChars {
68104
&& !str.is_empty()
69105
&& !self.allowed_idents_below_min_chars.contains(str)
70106
}
107+
108+
fn is_ident_too_long(&self, cx: &LateContext<'_>, str: &str, span: Span) -> bool {
109+
!span.in_external_macro(cx.sess().source_map()) && str.len() > self.max_variable_name_length as usize
110+
}
71111
}
72112

73113
impl LateLintPass<'_> for MinIdentChars {
@@ -108,6 +148,13 @@ impl LateLintPass<'_> for MinIdentChars {
108148
{
109149
emit_min_ident_chars(self, cx, str, ident.span);
110150
}
151+
152+
if let PatKind::Binding(_, _, ident, ..) = pat.kind
153+
&& let str = ident.as_str()
154+
&& self.is_ident_too_long(cx, str, ident.span)
155+
{
156+
emit_max_ident_chars(self, cx, str, ident.span);
157+
}
111158
}
112159
}
113160

@@ -199,6 +246,34 @@ impl Visitor<'_> for IdentVisitor<'_, '_> {
199246

200247
emit_min_ident_chars(conf, cx, str, ident.span);
201248
}
249+
250+
if conf.is_ident_too_long(cx, str, ident.span) {
251+
// Check whether the node is part of a `use` statement. We don't want to emit a warning if the user
252+
// has no control over the type.
253+
let usenode = opt_as_use_node(node).or_else(|| {
254+
cx.tcx
255+
.hir_parent_iter(hir_id)
256+
.find_map(|(_, node)| opt_as_use_node(node))
257+
});
258+
259+
// If the name of the identifier is the same as the one of the imported item, this means that we
260+
// found a `use foo::bar`. We can early-return to not emit the warning.
261+
// If however the identifier is different, this means it is an alias (`use foo::bar as baz`). In
262+
// this case, we need to emit the warning for `baz`.
263+
if let Some(imported_item_path) = usenode
264+
// use `present_items` because it could be in any of type_ns, value_ns, macro_ns
265+
&& let Some(Res::Def(_, imported_item_defid)) = imported_item_path.res.value_ns
266+
&& cx.tcx.item_name(imported_item_defid).as_str() == str
267+
{
268+
return;
269+
}
270+
271+
if is_from_proc_macro(cx, &ident) {
272+
return;
273+
}
274+
275+
emit_min_ident_chars(conf, cx, str, ident.span);
276+
}
202277
}
203278
}
204279

@@ -215,6 +290,15 @@ fn emit_min_ident_chars(conf: &MinIdentChars, cx: &impl LintContext, ident: &str
215290
span_lint(cx, MIN_IDENT_CHARS, span, help);
216291
}
217292

293+
fn emit_max_ident_chars(conf: &MinIdentChars, cx: &impl LintContext, ident: &str, span: Span) {
294+
let help = Cow::Owned(format!(
295+
"this ident is too long ({} > {})",
296+
ident.len(),
297+
conf.max_variable_name_length,
298+
));
299+
span_lint(cx, MAX_IDENT_CHARS, span, help);
300+
}
301+
218302
/// Attempt to convert the node to an [`ItemKind::Use`] node.
219303
///
220304
/// If it is, return the [`UsePath`] contained within.

clippy_lints/src/lib.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,7 @@ mod from_raw_with_void_ptr;
155155
mod from_str_radix_10;
156156
mod functions;
157157
mod future_not_send;
158+
mod ident_chars;
158159
mod if_let_mutex;
159160
mod if_not_else;
160161
mod if_then_some_else_none;
@@ -232,7 +233,6 @@ mod match_result_ok;
232233
mod matches;
233234
mod mem_replace;
234235
mod methods;
235-
mod min_ident_chars;
236236
mod minmax;
237237
mod misc;
238238
mod misc_early;
@@ -761,7 +761,7 @@ pub fn register_lint_passes(store: &mut rustc_lint::LintStore, conf: &'static Co
761761
store.register_late_pass(|_| Box::new(redundant_type_annotations::RedundantTypeAnnotations));
762762
store.register_late_pass(|_| Box::new(arc_with_non_send_sync::ArcWithNonSendSync));
763763
store.register_late_pass(|_| Box::new(needless_if::NeedlessIf));
764-
store.register_late_pass(move |_| Box::new(min_ident_chars::MinIdentChars::new(conf)));
764+
store.register_late_pass(move |_| Box::new(ident_chars::MinIdentChars::new(conf)));
765765
store.register_late_pass(move |_| Box::new(large_stack_frames::LargeStackFrames::new(conf)));
766766
store.register_late_pass(|_| Box::new(single_range_in_vec_init::SingleRangeInVecInit));
767767
store.register_late_pass(move |_| Box::new(needless_pass_by_ref_mut::NeedlessPassByRefMut::new(conf)));
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,5 @@
11
allowed-idents-below-min-chars = ["Owo", "Uwu", "wha", "t_e", "lse", "_do", "_i_", "put", "her", "_e"]
22
min-ident-chars-threshold = 3
3+
4+
# override the default length of variables to test the configuration
5+
max-ident-chars-length = 50
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
#![warn(clippy::max_ident_chars)]
2+
3+
fn a_function(ferris_singlehandedly_refactored_the_monolith_while_juggling_crates_and_lifetimes: &str) {
4+
//~^ max_ident_chars
5+
}
6+
7+
fn another_function(just_a_short_name: &str) {
8+
// should not cause a problem
9+
}
10+
11+
fn main() {
12+
// `ferris_singlehandedly_refactored_the_monolith_while_juggling_crates_and_lifetimes` is too long
13+
let ferris_singlehandedly_refactored_the_monolith_while_juggling_crates_and_lifetimes = "very long indeed";
14+
//~^ max_ident_chars
15+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
error: this ident is too long (81 > 50)
2+
--> tests/ui-toml/ident_chars/max_ident_chars.rs:3:15
3+
|
4+
LL | fn a_function(ferris_singlehandedly_refactored_the_monolith_while_juggling_crates_and_lifetimes: &str) {
5+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
6+
|
7+
= note: `-D clippy::max-ident-chars` implied by `-D warnings`
8+
= help: to override `-D warnings` add `#[allow(clippy::max_ident_chars)]`
9+
10+
error: this ident is too long (81 > 50)
11+
--> tests/ui-toml/ident_chars/max_ident_chars.rs:13:9
12+
|
13+
LL | let ferris_singlehandedly_refactored_the_monolith_while_juggling_crates_and_lifetimes = "very long indeed";
14+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
15+
16+
error: aborting due to 2 previous errors
17+

0 commit comments

Comments
 (0)