Skip to content

Commit 9a7c3ce

Browse files
committed
Change name lint min_ident_chars to ident_chars.
Add `max-ident-chars-length` to config and is set to 100 by default.
1 parent 3c54672 commit 9a7c3ce

19 files changed

+316
-198
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5920,6 +5920,7 @@ Released 2018-09-13
59205920
[`get_last_with_len`]: https://rust-lang.github.io/rust-clippy/master/index.html#get_last_with_len
59215921
[`get_unwrap`]: https://rust-lang.github.io/rust-clippy/master/index.html#get_unwrap
59225922
[`host_endian_bytes`]: https://rust-lang.github.io/rust-clippy/master/index.html#host_endian_bytes
5923+
[`ident_chars`]: https://rust-lang.github.io/rust-clippy/master/index.html#ident_chars
59235924
[`identity_conversion`]: https://rust-lang.github.io/rust-clippy/master/index.html#identity_conversion
59245925
[`identity_op`]: https://rust-lang.github.io/rust-clippy/master/index.html#identity_op
59255926
[`if_let_mutex`]: https://rust-lang.github.io/rust-clippy/master/index.html#if_let_mutex
@@ -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: 11 additions & 1 deletion
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+
* [`ident_chars`](https://rust-lang.github.io/rust-clippy/master/index.html#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

@@ -763,7 +773,7 @@ Minimum chars an ident can have, anything below or equal to this will be linted.
763773

764774
---
765775
**Affected lints:**
766-
* [`min_ident_chars`](https://rust-lang.github.io/rust-clippy/master/index.html#min_ident_chars)
776+
* [`ident_chars`](https://rust-lang.github.io/rust-clippy/master/index.html#ident_chars)
767777

768778

769779
## `missing-docs-allow-unused`

clippy_config/src/conf.rs

Lines changed: 4 additions & 1 deletion
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(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,
@@ -697,7 +700,7 @@ define_Conf! {
697700
#[lints(type_repetition_in_bounds)]
698701
max_trait_bounds: u64 = 3,
699702
/// Minimum chars an ident can have, anything below or equal to this will be linted.
700-
#[lints(min_ident_chars)]
703+
#[lints(ident_chars)]
701704
min_ident_chars_threshold: u64 = 1,
702705
/// Whether to allow fields starting with an underscore to skip documentation requirements
703706
#[lints(missing_docs_in_private_items)]

clippy_lints/src/declared_lints.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -198,6 +198,7 @@ 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::IDENT_CHARS_INFO,
201202
crate::if_let_mutex::IF_LET_MUTEX_INFO,
202203
crate::if_not_else::IF_NOT_ELSE_INFO,
203204
crate::if_then_some_else_none::IF_THEN_SOME_ELSE_NONE_INFO,
@@ -497,7 +498,6 @@ pub static LINTS: &[&::declare_clippy_lint::LintInfo] = &[
497498
crate::methods::WAKER_CLONE_WAKE_INFO,
498499
crate::methods::WRONG_SELF_CONVENTION_INFO,
499500
crate::methods::ZST_OFFSET_INFO,
500-
crate::min_ident_chars::MIN_IDENT_CHARS_INFO,
501501
crate::minmax::MIN_MAX_INFO,
502502
crate::misc::SHORT_CIRCUIT_STATEMENT_INFO,
503503
crate::misc::TOPLEVEL_REF_ARG_INFO,

clippy_lints/src/deprecated_lints.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,8 @@ declare_with_version! { RENAMED(RENAMED_VERSION) = [
134134
("clippy::maybe_misused_cfg", "unexpected_cfgs"),
135135
#[clippy::version = ""]
136136
("clippy::mem_discriminant_non_enum", "enum_intrinsics_non_enums"),
137+
#[clippy::version = "1.90.0"]
138+
("clippy::min_ident_chars", "clippy::ident_chars"),
137139
#[clippy::version = "1.80.0"]
138140
("clippy::mismatched_target_os", "unexpected_cfgs"),
139141
#[clippy::version = ""]

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

Lines changed: 60 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -16,15 +16,18 @@ use std::borrow::Cow;
1616

1717
declare_clippy_lint! {
1818
/// ### What it does
19-
/// Checks for identifiers which consist of a single character (or fewer than the configured threshold).
19+
/// Checks for identifiers which are out of bounds, for example to short (lower than the configured
20+
/// threshold) or too long (higher than the configured threshold).
21+
/// which consist of a single character (or fewer than the configured threshold)
2022
///
2123
/// Note: This lint can be very noisy when enabled; it may be desirable to only enable it
2224
/// temporarily.
2325
///
2426
/// ### Why restrict this?
25-
/// To improve readability by requiring that every variable has a name more specific than a single letter can be.
27+
/// To improve readability of code and make it possible to enforce this lint to align a code
28+
/// style on this subject within a team.
2629
///
27-
/// ### Example
30+
/// ### Example of small identifiers
2831
/// ```rust,ignore
2932
/// for m in movies {
3033
/// let title = m.t;
@@ -41,22 +44,24 @@ declare_clippy_lint! {
4144
/// Trait implementations which use the same function or parameter name as the trait declaration will
4245
/// not be warned about, even if the name is below the configured limit.
4346
#[clippy::version = "1.72.0"]
44-
pub MIN_IDENT_CHARS,
47+
pub IDENT_CHARS,
4548
restriction,
46-
"disallows idents that are too short"
49+
"disallows idents which length are out of bounds"
4750
}
48-
impl_lint_pass!(MinIdentChars => [MIN_IDENT_CHARS]);
51+
impl_lint_pass!(MinIdentChars => [IDENT_CHARS]);
4952

5053
pub struct MinIdentChars {
5154
allowed_idents_below_min_chars: FxHashSet<String>,
5255
min_ident_chars_threshold: u64,
56+
max_variable_name_length: u32,
5357
}
5458

5559
impl MinIdentChars {
5660
pub fn new(conf: &'static Conf) -> Self {
5761
Self {
5862
allowed_idents_below_min_chars: conf.allowed_idents_below_min_chars.iter().cloned().collect(),
5963
min_ident_chars_threshold: conf.min_ident_chars_threshold,
64+
max_variable_name_length: conf.max_ident_chars_length,
6065
}
6166
}
6267

@@ -68,6 +73,10 @@ impl MinIdentChars {
6873
&& !str.is_empty()
6974
&& !self.allowed_idents_below_min_chars.contains(str)
7075
}
76+
77+
fn is_ident_too_long(&self, cx: &LateContext<'_>, str: &str, span: Span) -> bool {
78+
!span.in_external_macro(cx.sess().source_map()) && str.len() > self.max_variable_name_length as usize
79+
}
7180
}
7281

7382
impl LateLintPass<'_> for MinIdentChars {
@@ -108,6 +117,13 @@ impl LateLintPass<'_> for MinIdentChars {
108117
{
109118
emit_min_ident_chars(self, cx, str, ident.span);
110119
}
120+
121+
if let PatKind::Binding(_, _, ident, ..) = pat.kind
122+
&& let str = ident.as_str()
123+
&& self.is_ident_too_long(cx, str, ident.span)
124+
{
125+
emit_max_ident_chars(self, cx, str, ident.span);
126+
}
111127
}
112128
}
113129

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

200216
emit_min_ident_chars(conf, cx, str, ident.span);
201217
}
218+
219+
if conf.is_ident_too_long(cx, str, ident.span) {
220+
// Check whether the node is part of a `use` statement. We don't want to emit a warning if the user
221+
// has no control over the type.
222+
let usenode = opt_as_use_node(node).or_else(|| {
223+
cx.tcx
224+
.hir_parent_iter(hir_id)
225+
.find_map(|(_, node)| opt_as_use_node(node))
226+
});
227+
228+
// If the name of the identifier is the same as the one of the imported item, this means that we
229+
// found a `use foo::bar`. We can early-return to not emit the warning.
230+
// If however the identifier is different, this means it is an alias (`use foo::bar as baz`). In
231+
// this case, we need to emit the warning for `baz`.
232+
if let Some(imported_item_path) = usenode
233+
// use `present_items` because it could be in any of type_ns, value_ns, macro_ns
234+
&& let Some(Res::Def(_, imported_item_defid)) = imported_item_path.res.value_ns
235+
&& cx.tcx.item_name(imported_item_defid).as_str() == str
236+
{
237+
return;
238+
}
239+
240+
if is_from_proc_macro(cx, &ident) {
241+
return;
242+
}
243+
244+
emit_min_ident_chars(conf, cx, str, ident.span);
245+
}
202246
}
203247
}
204248

@@ -212,7 +256,16 @@ fn emit_min_ident_chars(conf: &MinIdentChars, cx: &impl LintContext, ident: &str
212256
conf.min_ident_chars_threshold,
213257
))
214258
};
215-
span_lint(cx, MIN_IDENT_CHARS, span, help);
259+
span_lint(cx, IDENT_CHARS, span, help);
260+
}
261+
262+
fn emit_max_ident_chars(conf: &MinIdentChars, cx: &impl LintContext, ident: &str, span: Span) {
263+
let help = Cow::Owned(format!(
264+
"this ident is too long ({} > {})",
265+
ident.len(),
266+
conf.max_variable_name_length,
267+
));
268+
span_lint(cx, IDENT_CHARS, span, help);
216269
}
217270

218271
/// Attempt to convert the node to an [`ItemKind::Use`] node.

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::ident_chars)]
2+
3+
fn a_function(ferris_singlehandedly_refactored_the_monolith_while_juggling_crates_and_lifetimes: &str) {
4+
//~^ 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+
//~^ ident_chars
15+
}

0 commit comments

Comments
 (0)