Skip to content

Commit dd569f4

Browse files
new lint: single_char_lifetime_names
1 parent 92048f4 commit dd569f4

File tree

7 files changed

+136
-0
lines changed

7 files changed

+136
-0
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3253,6 +3253,7 @@ Released 2018-09-13
32533253
[`should_implement_trait`]: https://rust-lang.github.io/rust-clippy/master/index.html#should_implement_trait
32543254
[`similar_names`]: https://rust-lang.github.io/rust-clippy/master/index.html#similar_names
32553255
[`single_char_add_str`]: https://rust-lang.github.io/rust-clippy/master/index.html#single_char_add_str
3256+
[`single_char_lifetime_names`]: https://rust-lang.github.io/rust-clippy/master/index.html#single_char_lifetime_names
32563257
[`single_char_pattern`]: https://rust-lang.github.io/rust-clippy/master/index.html#single_char_pattern
32573258
[`single_component_path_imports`]: https://rust-lang.github.io/rust-clippy/master/index.html#single_component_path_imports
32583259
[`single_element_loop`]: https://rust-lang.github.io/rust-clippy/master/index.html#single_element_loop

clippy_lints/src/lib.register_lints.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -435,6 +435,7 @@ store.register_lints(&[
435435
shadow::SHADOW_REUSE,
436436
shadow::SHADOW_SAME,
437437
shadow::SHADOW_UNRELATED,
438+
single_char_lifetime_names::SINGLE_CHAR_LIFETIME_NAMES,
438439
single_component_path_imports::SINGLE_COMPONENT_PATH_IMPORTS,
439440
size_of_in_element_count::SIZE_OF_IN_ELEMENT_COUNT,
440441
slow_vector_initialization::SLOW_VECTOR_INITIALIZATION,

clippy_lints/src/lib.register_restriction.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ store.register_group(true, "clippy::restriction", Some("clippy_restriction"), ve
5454
LintId::of(shadow::SHADOW_REUSE),
5555
LintId::of(shadow::SHADOW_SAME),
5656
LintId::of(shadow::SHADOW_UNRELATED),
57+
LintId::of(single_char_lifetime_names::SINGLE_CHAR_LIFETIME_NAMES),
5758
LintId::of(strings::STRING_ADD),
5859
LintId::of(strings::STRING_SLICE),
5960
LintId::of(strings::STRING_TO_STRING),

clippy_lints/src/lib.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -351,6 +351,7 @@ mod self_named_constructors;
351351
mod semicolon_if_nothing_returned;
352352
mod serde_api;
353353
mod shadow;
354+
mod single_char_lifetime_names;
354355
mod single_component_path_imports;
355356
mod size_of_in_element_count;
356357
mod slow_vector_initialization;
@@ -858,6 +859,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
858859
store.register_late_pass(|| Box::new(needless_late_init::NeedlessLateInit));
859860
store.register_late_pass(|| Box::new(return_self_not_must_use::ReturnSelfNotMustUse));
860861
store.register_late_pass(|| Box::new(init_numbered_fields::NumberedFields));
862+
store.register_early_pass(|| Box::new(single_char_lifetime_names::SingleCharLifetimeNames));
861863
// add lints here, do not remove this comment, it's used in `new_lint`
862864
}
863865

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
use clippy_utils::diagnostics::span_lint_and_help;
2+
use rustc_ast::ast::{GenericParam, GenericParamKind};
3+
use rustc_lint::{EarlyContext, EarlyLintPass};
4+
use rustc_middle::lint::in_external_macro;
5+
use rustc_session::{declare_lint_pass, declare_tool_lint};
6+
7+
declare_clippy_lint! {
8+
/// ### What it does
9+
/// Checks for lifetimes with names which are one character
10+
/// long.
11+
///
12+
/// ### Why is this bad?
13+
/// A single character is likely not enough to express the
14+
/// purpose of a lifetime. Using a longer name can make code
15+
/// easier to understand, especially for those who are new to
16+
/// Rust.
17+
///
18+
/// ### Known problems
19+
/// Rust programmers and learning resources tend to use single
20+
/// character lifetimes, so this lint is at odds with the
21+
/// ecosystem at large. In addition, the lifetime's purpose may
22+
/// be obvious or, rarely, expressible in one character.
23+
///
24+
/// ### Example
25+
/// ```rust
26+
/// struct DiagnosticCtx<'a> {
27+
/// source: &'a str,
28+
/// }
29+
/// ```
30+
/// Use instead:
31+
/// ```rust
32+
/// struct DiagnosticCtx<'src> {
33+
/// source: &'src str,
34+
/// }
35+
/// ```
36+
#[clippy::version = "1.59.0"]
37+
pub SINGLE_CHAR_LIFETIME_NAMES,
38+
restriction,
39+
"warns against single-character lifetime names"
40+
}
41+
42+
declare_lint_pass!(SingleCharLifetimeNames => [SINGLE_CHAR_LIFETIME_NAMES]);
43+
44+
impl EarlyLintPass for SingleCharLifetimeNames {
45+
fn check_generic_param(&mut self, ctx: &EarlyContext<'_>, param: &GenericParam) {
46+
if in_external_macro(ctx.sess, param.ident.span) {
47+
return;
48+
}
49+
50+
if let GenericParamKind::Lifetime = param.kind {
51+
if !param.is_placeholder && param.ident.as_str().len() <= 2 {
52+
span_lint_and_help(
53+
ctx,
54+
SINGLE_CHAR_LIFETIME_NAMES,
55+
param.ident.span,
56+
"single-character lifetime names are likely uninformative",
57+
None,
58+
"use a more informative name",
59+
);
60+
}
61+
}
62+
}
63+
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
#![warn(clippy::single_char_lifetime_names)]
2+
3+
struct DiagnosticCtx<'a, 'b>
4+
where
5+
'a: 'b,
6+
{
7+
_source: &'a str,
8+
_unit: &'b (),
9+
}
10+
11+
impl<'a, 'b> DiagnosticCtx<'a, 'b> {
12+
fn new(source: &'a str, unit: &'b ()) -> DiagnosticCtx<'a, 'b> {
13+
Self {
14+
_source: source,
15+
_unit: unit,
16+
}
17+
}
18+
}
19+
20+
impl<'src, 'unit> DiagnosticCtx<'src, 'unit> {
21+
fn new_pass(source: &'src str, unit: &'unit ()) -> DiagnosticCtx<'src, 'unit> {
22+
Self {
23+
_source: source,
24+
_unit: unit,
25+
}
26+
}
27+
}
28+
29+
fn main() {
30+
let src = "loop {}";
31+
let unit = ();
32+
DiagnosticCtx::new(src, &unit);
33+
}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
error: single-character lifetime names are likely uninformative
2+
--> $DIR/single_char_lifetime_names.rs:3:22
3+
|
4+
LL | struct DiagnosticCtx<'a, 'b>
5+
| ^^
6+
|
7+
= note: `-D clippy::single-char-lifetime-names` implied by `-D warnings`
8+
= help: use a more informative name
9+
10+
error: single-character lifetime names are likely uninformative
11+
--> $DIR/single_char_lifetime_names.rs:3:26
12+
|
13+
LL | struct DiagnosticCtx<'a, 'b>
14+
| ^^
15+
|
16+
= help: use a more informative name
17+
18+
error: single-character lifetime names are likely uninformative
19+
--> $DIR/single_char_lifetime_names.rs:11:6
20+
|
21+
LL | impl<'a, 'b> DiagnosticCtx<'a, 'b> {
22+
| ^^
23+
|
24+
= help: use a more informative name
25+
26+
error: single-character lifetime names are likely uninformative
27+
--> $DIR/single_char_lifetime_names.rs:11:10
28+
|
29+
LL | impl<'a, 'b> DiagnosticCtx<'a, 'b> {
30+
| ^^
31+
|
32+
= help: use a more informative name
33+
34+
error: aborting due to 4 previous errors
35+

0 commit comments

Comments
 (0)