Skip to content

Commit

Permalink
make it work for locals as well
Browse files Browse the repository at this point in the history
oopos
  • Loading branch information
Centri3 committed Jun 10, 2023
1 parent 3defd38 commit 3d0adf9
Show file tree
Hide file tree
Showing 7 changed files with 216 additions and 23 deletions.
20 changes: 20 additions & 0 deletions book/src/lint_configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -643,3 +643,23 @@ The byte size a `T` in `Box<T>` can have, below which it triggers the `clippy::u
* [`unnecessary_box_returns`](https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_box_returns)


## `allowed-idents-below-min-chars`
Allowed names below the minimum allowed characters.

**Default Value:** `{"j", "z", "i", "y", "n", "x", "w"}` (`rustc_data_structures::fx::FxHashSet<String>`)

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


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

**Default Value:** `1` (`u64`)

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


31 changes: 27 additions & 4 deletions clippy_lints/src/min_ident_chars.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use rustc_data_structures::fx::FxHashSet;
use rustc_hir::{
def::{DefKind, Res},
intravisit::{walk_item, Visitor},
GenericParamKind, HirId, Item, ItemKind, ItemLocalId, Node,
GenericParamKind, HirId, Item, ItemKind, ItemLocalId, Node, Pat, PatKind,
};
use rustc_lint::{LateContext, LateLintPass, LintContext};
use rustc_middle::lint::in_external_macro;
Expand Down Expand Up @@ -55,15 +55,38 @@ impl LateLintPass<'_> for MinIdentChars {

walk_item(&mut IdentVisitor { conf: self, cx }, item);
}

// This is necessary as bindings are not visited in `visit_id`. :/
#[expect(clippy::cast_possible_truncation)]
fn check_pat(&mut self, cx: &LateContext<'_>, pat: &Pat<'_>) {
if let PatKind::Binding(_, _, ident, ..) = pat.kind
&& let str = ident.as_str()
&& !in_external_macro(cx.sess(), ident.span)
&& str.len() <= self.min_ident_chars_threshold as usize
&& !str.is_empty()
&& self.allowed_idents_below_min_chars.get(&str.to_owned()).is_none()
{
let help = if self.min_ident_chars_threshold == 1 {
Cow::Borrowed("this ident consists of a single char")
} else {
Cow::Owned(format!(
"this ident is too short ({} <= {})",
str.len(),
self.min_ident_chars_threshold,
))
};
span_lint(cx, MIN_IDENT_CHARS, ident.span, &help);
}
}
}

struct IdentVisitor<'cx, 'tcx> {
conf: &'cx MinIdentChars,
cx: &'cx LateContext<'tcx>,
}

#[expect(clippy::cast_possible_truncation)]
impl Visitor<'_> for IdentVisitor<'_, '_> {
#[expect(clippy::cast_possible_truncation)]
fn visit_id(&mut self, hir_id: HirId) {
let Self { conf, cx } = *self;
// Reimplementation of `find`, as it uses indexing, which can (and will in async functions) panic.
Expand Down Expand Up @@ -122,9 +145,9 @@ impl Visitor<'_> for IdentVisitor<'_, '_> {
Cow::Borrowed("this ident consists of a single char")
} else {
Cow::Owned(format!(
"this ident is too short ({} <= {}) ",
"this ident is too short ({} <= {})",
str.len(),
conf.min_ident_chars_threshold
conf.min_ident_chars_threshold,
))
};
span_lint(cx, MIN_IDENT_CHARS, ident.span, &help);
Expand Down
2 changes: 1 addition & 1 deletion clippy_lints/src/utils/conf.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ const DEFAULT_DOC_VALID_IDENTS: &[&str] = &[
"CamelCase",
];
const DEFAULT_DISALLOWED_NAMES: &[&str] = &["foo", "baz", "quux"];
const DEFAULT_ALLOWED_IDENTS_BELOW_MIN_CHARS: &[&str] = &["i", "j", "x", "y", "z", "n"];
const DEFAULT_ALLOWED_IDENTS_BELOW_MIN_CHARS: &[&str] = &["i", "j", "x", "y", "z", "w", "n"];

/// Holds information used by `MISSING_ENFORCED_IMPORT_RENAMES` lint.
#[derive(Clone, Debug, Deserialize)]
Expand Down
2 changes: 2 additions & 0 deletions tests/ui-toml/min_ident_chars/min_ident_chars.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,6 @@ fn main() {
let wha = 1;
let vvv = 1;
let uuu = 1;
let (mut a, mut b) = (1, 2);
for i in 0..1000 {}
}
36 changes: 33 additions & 3 deletions tests/ui-toml/min_ident_chars/min_ident_chars.stderr
Original file line number Diff line number Diff line change
@@ -1,16 +1,46 @@
error: this ident is too short (3 <= 3)
error: this ident is too short (3 <= 3)
--> $DIR/min_ident_chars.rs:6:19
|
LL | use extern_types::Aaa;
| ^^^
|
= note: `-D clippy::min-ident-chars` implied by `-D warnings`

error: this ident is too short (3 <= 3)
error: this ident is too short (3 <= 3)
--> $DIR/min_ident_chars.rs:10:5
|
LL | aaa: Aaa,
| ^^^

error: aborting due to 2 previous errors
error: this ident is too short (3 <= 3)
--> $DIR/min_ident_chars.rs:15:9
|
LL | let vvv = 1;
| ^^^

error: this ident is too short (3 <= 3)
--> $DIR/min_ident_chars.rs:16:9
|
LL | let uuu = 1;
| ^^^

error: this ident is too short (1 <= 3)
--> $DIR/min_ident_chars.rs:17:14
|
LL | let (mut a, mut b) = (1, 2);
| ^

error: this ident is too short (1 <= 3)
--> $DIR/min_ident_chars.rs:17:21
|
LL | let (mut a, mut b) = (1, 2);
| ^

error: this ident is too short (1 <= 3)
--> $DIR/min_ident_chars.rs:18:9
|
LL | for i in 0..1000 {}
| ^

error: aborting due to 7 previous errors

34 changes: 28 additions & 6 deletions tests/ui/min_ident_chars.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
//@aux-build:proc_macros.rs
#![allow(nonstandard_style, unused)]
#![allow(irrefutable_let_patterns, nonstandard_style, unused)]
#![warn(clippy::min_ident_chars)]

extern crate proc_macros;
Expand All @@ -15,6 +15,10 @@ struct A {

struct B(u32);

struct O {
o: u32,
}

struct i;

enum C {
Expand All @@ -38,11 +42,29 @@ fn main() {
let w = 1;
// Ok, not this one
// let i = 1;
let jz = 1;
let nz = 1;
let zx = 1;
let yz = 1;
let zz = 1;
let j = 1;
let n = 1;
let z = 1;
let y = 1;
let z = 1;
// Implicitly disallowed idents
let h = 1;
let e = 2;
let l = 3;
let l = 4;
let o = 6;
// 2 len does not lint
let hi = 0;
// Lint
let (h, o, w) = (1, 2, 3);
for (a, (r, e)) in (0..1000).enumerate().enumerate() {}
let you = Vec4 { x: 1, y: 2, z: 3, w: 4 };
while let (d, o, _i, n, g) = (true, true, false, false, true) {}
let today = true;
// Ideally this wouldn't lint, but this would (likely) require global analysis, outta scope
// of this lint regardless
let o = 1;
let o = O { o };

for j in 0..1000 {}

Expand Down
114 changes: 105 additions & 9 deletions tests/ui/min_ident_chars.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -31,40 +31,136 @@ LL | struct B(u32);
| ^

error: this ident consists of a single char
--> $DIR/min_ident_chars.rs:20:6
--> $DIR/min_ident_chars.rs:18:8
|
LL | struct O {
| ^

error: this ident consists of a single char
--> $DIR/min_ident_chars.rs:19:5
|
LL | o: u32,
| ^

error: this ident consists of a single char
--> $DIR/min_ident_chars.rs:24:6
|
LL | enum C {
| ^

error: this ident consists of a single char
--> $DIR/min_ident_chars.rs:21:5
--> $DIR/min_ident_chars.rs:25:5
|
LL | D,
| ^

error: this ident consists of a single char
--> $DIR/min_ident_chars.rs:22:5
--> $DIR/min_ident_chars.rs:26:5
|
LL | E,
| ^

error: this ident consists of a single char
--> $DIR/min_ident_chars.rs:23:5
--> $DIR/min_ident_chars.rs:27:5
|
LL | F,
| ^

error: this ident consists of a single char
--> $DIR/min_ident_chars.rs:31:5
--> $DIR/min_ident_chars.rs:51:9
|
LL | w: u32,
| ^
LL | let h = 1;
| ^

error: this ident consists of a single char
--> $DIR/min_ident_chars.rs:52:9
|
LL | let e = 2;
| ^

error: this ident consists of a single char
--> $DIR/min_ident_chars.rs:53:9
|
LL | let l = 3;
| ^

error: this ident consists of a single char
--> $DIR/min_ident_chars.rs:54:9
|
LL | let l = 4;
| ^

error: this ident consists of a single char
--> $DIR/min_ident_chars.rs:55:9
|
LL | let o = 6;
| ^

error: this ident consists of a single char
--> $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:59:13
|
LL | let (h, o, w) = (1, 2, 3);
| ^

error: this ident consists of a single char
--> $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: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: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: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: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: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:66:9
|
LL | let o = 1;
| ^

error: this ident consists of a single char
--> $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:58:4
--> $DIR/min_ident_chars.rs:80:4
|
LL | fn b() {}
| ^

error: aborting due to 11 previous errors
error: aborting due to 27 previous errors

0 comments on commit 3d0adf9

Please sign in to comment.