Skip to content

Add lint long_variable_names #14818

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5938,6 +5938,7 @@ Released 2018-09-13
[`literal_string_with_formatting_args`]: https://rust-lang.github.io/rust-clippy/master/index.html#literal_string_with_formatting_args
[`little_endian_bytes`]: https://rust-lang.github.io/rust-clippy/master/index.html#little_endian_bytes
[`logic_bug`]: https://rust-lang.github.io/rust-clippy/master/index.html#logic_bug
[`long_variable_names`]: https://rust-lang.github.io/rust-clippy/master/index.html#long_variable_names
[`lossy_float_literal`]: https://rust-lang.github.io/rust-clippy/master/index.html#lossy_float_literal
[`macro_metavars_in_unsafe`]: https://rust-lang.github.io/rust-clippy/master/index.html#macro_metavars_in_unsafe
[`macro_use_imports`]: https://rust-lang.github.io/rust-clippy/master/index.html#macro_use_imports
Expand Down Expand Up @@ -6535,6 +6536,7 @@ Released 2018-09-13
[`max-struct-bools`]: https://doc.rust-lang.org/clippy/lint_configuration.html#max-struct-bools
[`max-suggested-slice-pattern-length`]: https://doc.rust-lang.org/clippy/lint_configuration.html#max-suggested-slice-pattern-length
[`max-trait-bounds`]: https://doc.rust-lang.org/clippy/lint_configuration.html#max-trait-bounds
[`max-variable-name-length`]: https://doc.rust-lang.org/clippy/lint_configuration.html#max-variable-name-length
[`min-ident-chars-threshold`]: https://doc.rust-lang.org/clippy/lint_configuration.html#min-ident-chars-threshold
[`missing-docs-allow-unused`]: https://doc.rust-lang.org/clippy/lint_configuration.html#missing-docs-allow-unused
[`missing-docs-in-crate-items`]: https://doc.rust-lang.org/clippy/lint_configuration.html#missing-docs-in-crate-items
Expand Down
10 changes: 10 additions & 0 deletions book/src/lint_configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -734,6 +734,16 @@ The maximum number of bounds a trait can have to be linted
* [`type_repetition_in_bounds`](https://rust-lang.github.io/rust-clippy/master/index.html#type_repetition_in_bounds)


## `max-variable-name-length`
The maximum length of a variable

**Default Value:** `100`

---
**Affected lints:**
* [`long_variable_names`](https://rust-lang.github.io/rust-clippy/master/index.html#long_variable_names)


## `min-ident-chars-threshold`
Minimum chars an ident can have, anything below or equal to this will be linted.

Expand Down
3 changes: 3 additions & 0 deletions clippy_config/src/conf.rs
Original file line number Diff line number Diff line change
Expand Up @@ -675,6 +675,9 @@ define_Conf! {
/// The maximum number of bounds a trait can have to be linted
#[lints(type_repetition_in_bounds)]
max_trait_bounds: u64 = 3,
/// The maximum length of a variable
#[lints(long_variable_names)]
max_variable_name_length: u32 = 100,
/// Minimum chars an ident can have, anything below or equal to this will be linted.
#[lints(min_ident_chars)]
min_ident_chars_threshold: u64 = 1,
Expand Down
1 change: 1 addition & 0 deletions clippy_lints/src/declared_lints.rs
Original file line number Diff line number Diff line change
Expand Up @@ -260,6 +260,7 @@ pub static LINTS: &[&crate::LintInfo] = &[
crate::literal_representation::UNREADABLE_LITERAL_INFO,
crate::literal_representation::UNUSUAL_BYTE_GROUPINGS_INFO,
crate::literal_string_with_formatting_args::LITERAL_STRING_WITH_FORMATTING_ARGS_INFO,
crate::long_variable_names::LONG_VARIABLE_NAMES_INFO,
crate::loops::CHAR_INDICES_AS_BYTE_INDICES_INFO,
crate::loops::EMPTY_LOOP_INFO,
crate::loops::EXPLICIT_COUNTER_LOOP_INFO,
Expand Down
2 changes: 2 additions & 0 deletions clippy_lints/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,7 @@ mod lifetimes;
mod lines_filter_map_ok;
mod literal_representation;
mod literal_string_with_formatting_args;
mod long_variable_names;
mod loops;
mod macro_metavars_in_unsafe;
mod macro_use;
Expand Down Expand Up @@ -944,5 +945,6 @@ pub fn register_lints(store: &mut rustc_lint::LintStore, conf: &'static Conf) {
store.register_late_pass(|_| Box::new(single_option_map::SingleOptionMap));
store.register_late_pass(move |_| Box::new(redundant_test_prefix::RedundantTestPrefix));
store.register_late_pass(|_| Box::new(cloned_ref_to_slice_refs::ClonedRefToSliceRefs::new(conf)));
store.register_late_pass(move |_| Box::new(long_variable_names::LongVariableNames::new(conf)));
// add lints here, do not remove this comment, it's used in `new_lint`
}
75 changes: 75 additions & 0 deletions clippy_lints/src/long_variable_names.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
use crate::rustc_span::Pos;
use clippy_config::Conf;
use clippy_utils::diagnostics::span_lint_and_help;
use rustc_hir::{Pat, PatKind};
use rustc_lint::{LateContext, LateLintPass};
use rustc_session::impl_lint_pass;

declare_clippy_lint! {
/// ### What it does
/// Checks for variable that exceeds a configurable number characters.
///
/// ### Why is this bad?
/// Long variable names can make code harder to read and thus to maintain.
///
/// ### Example
/// ```no_run
/// let ferris_fixes_more_bugs_than_your_entire_devops_team_does = "content of a string";
/// ```
/// Use instead:
/// ```no_run
/// let ferris_fixes_more_bugs = "content of a string";
/// ```
#[clippy::version = "1.88.0"]
pub LONG_VARIABLE_NAMES,
style,
"usage of a long variable"
}
pub struct LongVariableNames {
pub max_variable_name_length: u32,
}

impl LongVariableNames {
pub fn new(conf: &'static Conf) -> Self {
Self {
max_variable_name_length: conf.max_variable_name_length,
}
}
}

impl_lint_pass!(LongVariableNames => [LONG_VARIABLE_NAMES]);

impl<'tcx> LateLintPass<'tcx> for LongVariableNames {
fn check_pat(&mut self, cx: &LateContext<'tcx>, pat: &'tcx Pat<'_>) {
if let PatKind::Binding(.., ident, _) = pat.kind {
let length_bytes = ident
.span
.hi()
.to_u32()
.checked_sub(ident.span.lo().to_u32())
.expect("length in bytes is overflowing")
+ 1;
if length_bytes > self.max_variable_name_length {
let variable_name_length = u32::try_from(ident.name.to_ident_string().chars().count())
.expect("the variable name length exceeds u32::MAX");
if variable_name_length > self.max_variable_name_length {
let length_diff = variable_name_length
.checked_sub(self.max_variable_name_length)
.expect("the variable name length calculation is overflowing");

span_lint_and_help(
cx,
LONG_VARIABLE_NAMES,
ident.span,
format!(
"use of a long variable name, it is longer than the configured `max-variable-name-length` of {} characters",
self.max_variable_name_length
),
None,
format!("reduce the length of the long variable name with at least {length_diff} characters"),
);
}
}
}
}
}
3 changes: 3 additions & 0 deletions tests/clippy.toml
Original file line number Diff line number Diff line change
@@ -1,2 +1,5 @@
# default config for tests, overrides clippy.toml at the project root
lint-commented-code = false

# override the default length of variables to test the configuration
max-variable-name-length = 50
3 changes: 3 additions & 0 deletions tests/ui-toml/toml_unknown_key/conf_unknown_key.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ error: error reading Clippy's configuration file: unknown field `foobar`, expect
max-struct-bools
max-suggested-slice-pattern-length
max-trait-bounds
max-variable-name-length
min-ident-chars-threshold
missing-docs-allow-unused
missing-docs-in-crate-items
Expand Down Expand Up @@ -151,6 +152,7 @@ error: error reading Clippy's configuration file: unknown field `barfoo`, expect
max-struct-bools
max-suggested-slice-pattern-length
max-trait-bounds
max-variable-name-length
min-ident-chars-threshold
missing-docs-allow-unused
missing-docs-in-crate-items
Expand Down Expand Up @@ -245,6 +247,7 @@ error: error reading Clippy's configuration file: unknown field `allow_mixed_uni
max-struct-bools
max-suggested-slice-pattern-length
max-trait-bounds
max-variable-name-length
min-ident-chars-threshold
missing-docs-allow-unused
missing-docs-in-crate-items
Expand Down
15 changes: 15 additions & 0 deletions tests/ui/long_variable_names.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#![warn(clippy::long_variable_names)]

fn a_function(ferris_singlehandedly_refactored_the_monolith_while_juggling_crates_and_lifetimes: &str) {
//~^ long_variable_names
}

fn another_function(just_a_short_name: &str) {
// should not cause a problem
}

fn main() {
// `ferris_singlehandedly_refactored_the_monolith_while_juggling_crates_and_lifetimes` is too long
let ferris_singlehandedly_refactored_the_monolith_while_juggling_crates_and_lifetimes = "very long indeed";
//~^ long_variable_names
}
20 changes: 20 additions & 0 deletions tests/ui/long_variable_names.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
error: use of a long variable name, it is longer than the configured `max-variable-name-length` of 50 characters
--> tests/ui/long_variable_names.rs:3:15
|
LL | fn a_function(ferris_singlehandedly_refactored_the_monolith_while_juggling_crates_and_lifetimes: &str) {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= help: reduce the length of the long variable name with at least 31 characters
= note: `-D clippy::long-variable-names` implied by `-D warnings`
= help: to override `-D warnings` add `#[allow(clippy::long_variable_names)]`

error: use of a long variable name, it is longer than the configured `max-variable-name-length` of 50 characters
--> tests/ui/long_variable_names.rs:13:9
|
LL | let ferris_singlehandedly_refactored_the_monolith_while_juggling_crates_and_lifetimes = "very long indeed";
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= help: reduce the length of the long variable name with at least 31 characters

error: aborting due to 2 previous errors