Skip to content
This repository was archived by the owner on May 28, 2025. It is now read-only.

Commit 26f5039

Browse files
committed
Add needless_if lint
1 parent d44ea7c commit 26f5039

File tree

107 files changed

+692
-456
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

107 files changed

+692
-456
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5008,6 +5008,7 @@ Released 2018-09-13
50085008
[`needless_doctest_main`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_doctest_main
50095009
[`needless_else`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_else
50105010
[`needless_for_each`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_for_each
5011+
[`needless_if`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_if
50115012
[`needless_late_init`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_late_init
50125013
[`needless_lifetimes`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_lifetimes
50135014
[`needless_match`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_match

clippy_lints/src/declared_lints.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -459,6 +459,7 @@ pub(crate) static LINTS: &[&crate::LintInfo] = &[
459459
crate::needless_continue::NEEDLESS_CONTINUE_INFO,
460460
crate::needless_else::NEEDLESS_ELSE_INFO,
461461
crate::needless_for_each::NEEDLESS_FOR_EACH_INFO,
462+
crate::needless_if::NEEDLESS_IF_INFO,
462463
crate::needless_late_init::NEEDLESS_LATE_INIT_INFO,
463464
crate::needless_parens_on_range_literals::NEEDLESS_PARENS_ON_RANGE_LITERALS_INFO,
464465
crate::needless_pass_by_value::NEEDLESS_PASS_BY_VALUE_INFO,

clippy_lints/src/lib.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -223,6 +223,7 @@ mod needless_borrowed_ref;
223223
mod needless_continue;
224224
mod needless_else;
225225
mod needless_for_each;
226+
mod needless_if;
226227
mod needless_late_init;
227228
mod needless_parens_on_range_literals;
228229
mod needless_pass_by_value;
@@ -1029,6 +1030,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
10291030
store.register_late_pass(|_| Box::new(endian_bytes::EndianBytes));
10301031
store.register_late_pass(|_| Box::new(redundant_type_annotations::RedundantTypeAnnotations));
10311032
store.register_late_pass(|_| Box::new(arc_with_non_send_sync::ArcWithNonSendSync));
1033+
store.register_late_pass(|_| Box::new(needless_if::NeedlessIf));
10321034
// add lints here, do not remove this comment, it's used in `new_lint`
10331035
}
10341036

clippy_lints/src/needless_if.rs

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
use clippy_utils::{diagnostics::span_lint_and_sugg, is_from_proc_macro, source::snippet_with_applicability};
2+
use rustc_errors::Applicability;
3+
use rustc_hir::{Expr, ExprKind, Node};
4+
use rustc_lint::{LateContext, LateLintPass, LintContext};
5+
use rustc_middle::lint::in_external_macro;
6+
use rustc_session::{declare_lint_pass, declare_tool_lint};
7+
8+
declare_clippy_lint! {
9+
/// ### What it does
10+
///
11+
/// ### Why is this bad?
12+
///
13+
/// ### Example
14+
/// ```rust
15+
/// // example code where clippy issues a warning
16+
/// ```
17+
/// Use instead:
18+
/// ```rust
19+
/// // example code which does not raise clippy warning
20+
/// ```
21+
#[clippy::version = "1.72.0"]
22+
pub NEEDLESS_IF,
23+
complexity,
24+
"checks for empty if branches"
25+
}
26+
declare_lint_pass!(NeedlessIf => [NEEDLESS_IF]);
27+
28+
impl LateLintPass<'_> for NeedlessIf {
29+
fn check_expr<'tcx>(&mut self, cx: &LateContext<'tcx>, expr: &Expr<'tcx>) {
30+
if let ExprKind::If(if_expr, block, else_expr) = &expr.kind
31+
&& let ExprKind::Block(block, ..) = block.kind
32+
&& block.stmts.is_empty()
33+
&& block.expr.is_none()
34+
&& else_expr.is_none()
35+
&& !in_external_macro(cx.sess(), expr.span)
36+
{
37+
let mut app = Applicability::MachineApplicable;
38+
let snippet = snippet_with_applicability(cx, if_expr.span, "{ ... }", &mut app);
39+
40+
// Ignore `else if`
41+
if let Some(parent_id) = cx.tcx.hir().opt_parent_id(expr.hir_id)
42+
&& let Some(Node::Expr(Expr {
43+
kind: ExprKind::If(_, _, Some(else_expr)),
44+
..
45+
})) = cx.tcx.hir().find(parent_id)
46+
&& else_expr.hir_id == expr.hir_id
47+
{
48+
return;
49+
}
50+
51+
if is_from_proc_macro(cx, expr) {
52+
return;
53+
}
54+
55+
span_lint_and_sugg(
56+
cx,
57+
NEEDLESS_IF,
58+
expr.span,
59+
"this if branch is empty",
60+
"you can remove it",
61+
format!("{snippet};"),
62+
Applicability::MachineApplicable,
63+
);
64+
}
65+
}
66+
}

lintcheck/lintcheck_crates.toml

Lines changed: 2 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,38 +1,7 @@
11
[crates]
22
# some of these are from cargotest
3-
cargo = {name = "cargo", versions = ['0.64.0']}
4-
iron = {name = "iron", versions = ['0.6.1']}
5-
ripgrep = {name = "ripgrep", versions = ['12.1.1']}
6-
xsv = {name = "xsv", versions = ['0.13.0']}
7-
# commented out because of 173K clippy::match_same_arms msgs in language_type.rs
8-
#tokei = { name = "tokei", versions = ['12.0.4']}
9-
rayon = {name = "rayon", versions = ['1.5.0']}
10-
serde = {name = "serde", versions = ['1.0.118']}
11-
# top 10 crates.io dls
12-
bitflags = {name = "bitflags", versions = ['1.2.1']}
13-
# crash = {name = "clippy_crash", path = "/tmp/clippy_crash"}
14-
libc = {name = "libc", versions = ['0.2.81']}
15-
log = {name = "log", versions = ['0.4.11']}
16-
proc-macro2 = {name = "proc-macro2", versions = ['1.0.24']}
17-
quote = {name = "quote", versions = ['1.0.7']}
18-
rand = {name = "rand", versions = ['0.7.3']}
19-
rand_core = {name = "rand_core", versions = ['0.6.0']}
20-
regex = {name = "regex", versions = ['1.3.2']}
21-
syn = {name = "syn", versions = ['1.0.54']}
22-
unicode-xid = {name = "unicode-xid", versions = ['0.2.1']}
23-
# some more of dtolnays crates
24-
anyhow = {name = "anyhow", versions = ['1.0.38']}
25-
async-trait = {name = "async-trait", versions = ['0.1.42']}
26-
cxx = {name = "cxx", versions = ['1.0.32']}
27-
ryu = {name = "ryu", versions = ['1.0.5']}
28-
serde_yaml = {name = "serde_yaml", versions = ['0.8.17']}
29-
thiserror = {name = "thiserror", versions = ['1.0.24']}
30-
# some embark crates, there are other interesting crates but
31-
# unfortunately adding them increases lintcheck runtime drastically
32-
cfg-expr = {name = "cfg-expr", versions = ['0.7.1']}
33-
puffin = {name = "puffin", git_url = "https://github.com/EmbarkStudios/puffin", git_hash = "02dd4a3"}
34-
rpmalloc = {name = "rpmalloc", versions = ['0.2.0']}
35-
tame-oidc = {name = "tame-oidc", versions = ['0.1.0']}
3+
bevy = {name = "bevy", versions = ['0.10.1']}
4+
deno = {name = "deno", versions = ['1.34.2']}
365

376
[recursive]
387
ignore = [

tests/ui-internal/if_chain_style.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
#![warn(clippy::if_chain_style)]
2-
#![allow(clippy::no_effect, clippy::nonminimal_bool, clippy::missing_clippy_version_attribute)]
2+
#![allow(
3+
clippy::needless_if,
4+
clippy::no_effect,
5+
clippy::nonminimal_bool,
6+
clippy::missing_clippy_version_attribute
7+
)]
38

49
extern crate if_chain;
510

tests/ui-internal/if_chain_style.stderr

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
error: this `if` can be part of the inner `if_chain!`
2-
--> $DIR/if_chain_style.rs:9:5
2+
--> $DIR/if_chain_style.rs:14:5
33
|
44
LL | / if true {
55
LL | | let x = "";
@@ -11,14 +11,14 @@ LL | | }
1111
| |_____^
1212
|
1313
help: this `let` statement can also be in the `if_chain!`
14-
--> $DIR/if_chain_style.rs:10:9
14+
--> $DIR/if_chain_style.rs:15:9
1515
|
1616
LL | let x = "";
1717
| ^^^^^^^^^^^
1818
= note: `-D clippy::if-chain-style` implied by `-D warnings`
1919

2020
error: `if a && b;` should be `if a; if b;`
21-
--> $DIR/if_chain_style.rs:19:12
21+
--> $DIR/if_chain_style.rs:24:12
2222
|
2323
LL | if true
2424
| ____________^
@@ -27,25 +27,25 @@ LL | | && false;
2727
| |____________________^
2828

2929
error: `let` expression should be inside `then { .. }`
30-
--> $DIR/if_chain_style.rs:24:9
30+
--> $DIR/if_chain_style.rs:29:9
3131
|
3232
LL | let x = "";
3333
| ^^^^^^^^^^^
3434

3535
error: this `if` can be part of the outer `if_chain!`
36-
--> $DIR/if_chain_style.rs:35:13
36+
--> $DIR/if_chain_style.rs:40:13
3737
|
3838
LL | if true {}
3939
| ^^^^^^^^^^
4040
|
4141
help: this `let` statement can also be in the `if_chain!`
42-
--> $DIR/if_chain_style.rs:33:13
42+
--> $DIR/if_chain_style.rs:38:13
4343
|
4444
LL | let x = "";
4545
| ^^^^^^^^^^^
4646

4747
error: `if_chain!` only has one `if`
48-
--> $DIR/if_chain_style.rs:29:5
48+
--> $DIR/if_chain_style.rs:34:5
4949
|
5050
LL | / if_chain! {
5151
LL | | // single `if` condition
@@ -59,13 +59,13 @@ LL | | }
5959
= note: this error originates in the macro `__if_chain` which comes from the expansion of the macro `if_chain` (in Nightly builds, run with -Z macro-backtrace for more info)
6060

6161
error: `let` expression should be above the `if_chain!`
62-
--> $DIR/if_chain_style.rs:40:9
62+
--> $DIR/if_chain_style.rs:45:9
6363
|
6464
LL | let x = "";
6565
| ^^^^^^^^^^^
6666

6767
error: this `if_chain!` can be merged with the outer `if_chain!`
68-
--> $DIR/if_chain_style.rs:46:13
68+
--> $DIR/if_chain_style.rs:51:13
6969
|
7070
LL | / if_chain! {
7171
LL | | if true;
@@ -75,7 +75,7 @@ LL | | }
7575
| |_____________^
7676
|
7777
help: these `let` statements can also be in the `if_chain!`
78-
--> $DIR/if_chain_style.rs:43:13
78+
--> $DIR/if_chain_style.rs:48:13
7979
|
8080
LL | / let x = "";
8181
LL | | let x = "";

tests/ui/auxiliary/proc_macros.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
#![crate_type = "proc-macro"]
55
#![feature(let_chains)]
66
#![feature(proc_macro_span)]
7-
#![allow(dead_code)]
7+
#![allow(clippy::needless_if, dead_code)]
88

99
extern crate proc_macro;
1010

tests/ui/blocks_in_if_conditions.fixed

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
//@run-rustfix
22
#![warn(clippy::blocks_in_if_conditions)]
3-
#![allow(unused, clippy::let_and_return)]
3+
#![allow(unused, clippy::let_and_return, clippy::needless_if)]
44
#![warn(clippy::nonminimal_bool)]
55

66
macro_rules! blocky {

tests/ui/blocks_in_if_conditions.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
//@run-rustfix
22
#![warn(clippy::blocks_in_if_conditions)]
3-
#![allow(unused, clippy::let_and_return)]
3+
#![allow(unused, clippy::let_and_return, clippy::needless_if)]
44
#![warn(clippy::nonminimal_bool)]
55

66
macro_rules! blocky {

tests/ui/blocks_in_if_conditions_closure.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
#![warn(clippy::blocks_in_if_conditions)]
2-
#![allow(unused, clippy::let_and_return)]
2+
#![allow(unused, clippy::let_and_return, clippy::needless_if)]
33

44
fn predicate<F: FnOnce(T) -> bool, T>(pfn: F, val: T) -> bool {
55
pfn(val)

tests/ui/bool_comparison.fixed

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
//@run-rustfix
22

3+
#![allow(clippy::needless_if)]
34
#![warn(clippy::bool_comparison)]
45

56
fn main() {

tests/ui/bool_comparison.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
//@run-rustfix
22

3+
#![allow(clippy::needless_if)]
34
#![warn(clippy::bool_comparison)]
45

56
fn main() {

0 commit comments

Comments
 (0)