Skip to content

Commit ed0c921

Browse files
committed
Directional commit for ifs-as-logical-ops
1 parent 954034b commit ed0c921

File tree

6 files changed

+174
-0
lines changed

6 files changed

+174
-0
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5838,6 +5838,7 @@ Released 2018-09-13
58385838
[`if_not_else`]: https://rust-lang.github.io/rust-clippy/master/index.html#if_not_else
58395839
[`if_same_then_else`]: https://rust-lang.github.io/rust-clippy/master/index.html#if_same_then_else
58405840
[`if_then_some_else_none`]: https://rust-lang.github.io/rust-clippy/master/index.html#if_then_some_else_none
5841+
[`ifs_as_logical_ops`]: https://rust-lang.github.io/rust-clippy/master/index.html#ifs_as_logical_ops
58415842
[`ifs_same_cond`]: https://rust-lang.github.io/rust-clippy/master/index.html#ifs_same_cond
58425843
[`ignore_without_reason`]: https://rust-lang.github.io/rust-clippy/master/index.html#ignore_without_reason
58435844
[`ignored_unit_patterns`]: https://rust-lang.github.io/rust-clippy/master/index.html#ignored_unit_patterns

clippy_lints/src/declared_lints.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,7 @@ pub static LINTS: &[&crate::LintInfo] = &[
197197
crate::if_let_mutex::IF_LET_MUTEX_INFO,
198198
crate::if_not_else::IF_NOT_ELSE_INFO,
199199
crate::if_then_some_else_none::IF_THEN_SOME_ELSE_NONE_INFO,
200+
crate::ifs_as_logical_ops::IFS_AS_LOGICAL_OPS_INFO,
200201
crate::ignored_unit_patterns::IGNORED_UNIT_PATTERNS_INFO,
201202
crate::impl_hash_with_borrow_str_and_bytes::IMPL_HASH_BORROW_WITH_STR_AND_BYTES_INFO,
202203
crate::implicit_hasher::IMPLICIT_HASHER_INFO,
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
use clippy_utils::diagnostics::span_lint_and_sugg;
2+
use clippy_utils::source::snippet;
3+
use rustc_ast::ast::*;
4+
use rustc_ast::token::LitKind;
5+
use rustc_errors::Applicability;
6+
use rustc_lint::{EarlyContext, EarlyLintPass};
7+
use rustc_session::declare_lint_pass;
8+
use rustc_span::kw;
9+
10+
declare_clippy_lint! {
11+
/// ### What it does
12+
///
13+
/// ### Why is this bad?
14+
///
15+
/// ### Example
16+
/// ```no_run
17+
/// // example code where clippy issues a warning
18+
/// ```
19+
/// Use instead:
20+
/// ```no_run
21+
/// // example code which does not raise clippy warning
22+
/// ```
23+
#[clippy::version = "1.89.0"]
24+
pub IFS_AS_LOGICAL_OPS,
25+
nursery,
26+
"default lint description"
27+
}
28+
declare_lint_pass!(IfsAsLogicalOps => [IFS_AS_LOGICAL_OPS]);
29+
30+
impl EarlyLintPass for IfsAsLogicalOps {
31+
fn check_expr(&mut self, cx: &EarlyContext<'_>, e: &Expr) {
32+
if let ExprKind::If(cond, cond_inner, Some(els)) = &e.kind
33+
&& let Some(inner_if_stmt) = cond_inner.stmts.first()
34+
&& let ExprKind::Block(inner_block, _label) = &els.kind
35+
&& let Some(stmt) = inner_block.stmts.first()
36+
&& let StmtKind::Expr(els_expr) = &stmt.kind
37+
&& let ExprKind::Lit(lit) = &els_expr.kind
38+
&& let LitKind::Bool = &lit.kind
39+
&& lit.symbol == kw::False
40+
{
41+
let if_cond_snippet = snippet(cx, cond.span, "..");
42+
let conjunction_snippet = " && ";
43+
let inner_snippet = snippet(cx, inner_if_stmt.span, "..");
44+
let final_snippet = if_cond_snippet + conjunction_snippet + inner_snippet;
45+
46+
span_lint_and_sugg(
47+
cx,
48+
IFS_AS_LOGICAL_OPS,
49+
e.span,
50+
"Logical operations are clearer than if conditions in this instance",
51+
"try",
52+
final_snippet.to_string(),
53+
Applicability::MachineApplicable,
54+
)
55+
}
56+
}
57+
}

clippy_lints/src/lib.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,7 @@ mod future_not_send;
157157
mod if_let_mutex;
158158
mod if_not_else;
159159
mod if_then_some_else_none;
160+
mod ifs_as_logical_ops;
160161
mod ignored_unit_patterns;
161162
mod impl_hash_with_borrow_str_and_bytes;
162163
mod implicit_hasher;
@@ -946,5 +947,6 @@ pub fn register_lints(store: &mut rustc_lint::LintStore, conf: &'static Conf) {
946947
store.register_late_pass(|_| Box::new(single_option_map::SingleOptionMap));
947948
store.register_late_pass(move |_| Box::new(redundant_test_prefix::RedundantTestPrefix));
948949
store.register_late_pass(|_| Box::new(cloned_ref_to_slice_refs::ClonedRefToSliceRefs::new(conf)));
950+
store.register_early_pass(|| Box::new(ifs_as_logical_ops::IfsAsLogicalOps));
949951
// add lints here, do not remove this comment, it's used in `new_lint`
950952
}

output.txt

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.01s
2+
Running `target/debug/clippy_dev lint /Users/barun511/open_source/clippy-examples/src/main.rs`
3+
Compiling clippy_lints v0.1.89 (/Users/barun511/open_source/rust-clippy/clippy_lints)
4+
error[E0423]: expected function, tuple struct or tuple variant, found enum `Option`
5+
--> clippy_lints/src/ifs_as_logical_ops.rs:41:17
6+
|
7+
41 | Option(cond.span),
8+
| ^^^^^^
9+
|
10+
= help: you might have meant to construct the enum's non-tuple variant
11+
note: these items exist but are inaccessible
12+
--> clippy_lints/src/len_zero.rs:321:5
13+
|
14+
321 | Option(DefId),
15+
| ^^^^^^^^^^^^^ `crate::len_zero::LenOutput::Option`: not accessible
16+
|
17+
::: clippy_lints/src/question_mark.rs:320:5
18+
|
19+
320 | Option,
20+
| ^^^^^^ `crate::question_mark::TryMode::Option`: not accessible
21+
|
22+
::: clippy_lints/src/unwrap.rs:84:5
23+
|
24+
84 | Option,
25+
| ^^^^^^ `crate::unwrap::UnwrappableKind::Option`: not accessible
26+
help: try to construct one of the enum's variants
27+
|
28+
41 - Option(cond.span),
29+
41 + std::option::Option::Some(cond.span),
30+
|
31+
help: consider importing one of these items instead
32+
|
33+
1 + use clippy_utils::sym::Option;
34+
|
35+
1 + use rustc_hir::LangItem::Option;
36+
|
37+
1 + use rustc_middle::ty::lang_items::TraitSolverLangItem::Option;
38+
|
39+
1 + use rustc_span::sym::Option;
40+
|
41+
and 1 other candidate
42+
43+
warning: unnecessary qualification
44+
--> clippy_lints/src/ifs_as_logical_ops.rs:27:57
45+
|
46+
27 | fn check_expr(&mut self, cx: &EarlyContext<'_>, e: &rustc_ast::Expr) {
47+
| ^^^^^^^^^^^^^^^
48+
|
49+
note: the lint level is defined here
50+
--> clippy_lints/src/lib.rs:27:5
51+
|
52+
27 | unused_qualifications,
53+
| ^^^^^^^^^^^^^^^^^^^^^
54+
help: remove the unnecessary path segments
55+
|
56+
27 - fn check_expr(&mut self, cx: &EarlyContext<'_>, e: &rustc_ast::Expr) {
57+
27 + fn check_expr(&mut self, cx: &EarlyContext<'_>, e: &Expr) {
58+
|
59+
60+
error[E0308]: mismatched types
61+
--> clippy_lints/src/ifs_as_logical_ops.rs:31:20
62+
|
63+
31 | && let StmtKind::Expr(els_expr) = stmt
64+
| ^^^^^^^^^^^^^^^^^^^^^^^^ ---- this expression has type `&rustc_ast::Stmt`
65+
| |
66+
| expected `Stmt`, found `StmtKind`
67+
68+
error[E0308]: mismatched types
69+
--> clippy_lints/src/ifs_as_logical_ops.rs:32:20
70+
|
71+
32 | && let ExprKind::Lit(lit) = els_expr
72+
| ^^^^^^^^^^^^^^^^^^ -------- this expression has type `&P<rustc_ast::Expr>`
73+
| |
74+
| expected `P<Expr>`, found `ExprKind`
75+
|
76+
= note: expected struct `P<rustc_ast::Expr>`
77+
found enum `rustc_ast::ExprKind`
78+
79+
error[E0308]: mismatched types
80+
--> clippy_lints/src/ifs_as_logical_ops.rs:33:20
81+
|
82+
33 | && let LitKind::Bool(value) = lit
83+
| ^^^^^^^^^^^^^^^^^^^^ --- this expression has type `&rustc_ast::token::Lit`
84+
| |
85+
| expected `Lit`, found `LitKind`
86+
87+
error[E0277]: can't compare `&bool` with `bool`
88+
--> clippy_lints/src/ifs_as_logical_ops.rs:34:22
89+
|
90+
34 | && value == false
91+
| ^^ no implementation for `&bool == bool`
92+
|
93+
= help: the trait `std::cmp::PartialEq<bool>` is not implemented for `&bool`
94+
help: consider dereferencing here
95+
|
96+
34 | && *value == false
97+
| +
98+
99+
Some errors have detailed explanations: E0277, E0308, E0423.
100+
For more information about an error, try `rustc --explain E0277`.
101+
warning: `clippy_lints` (lib) generated 1 warning
102+
error: could not compile `clippy_lints` (lib) due to 5 previous errors; 1 warning emitted

tests/ui/ifs_as_logical_ops.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
#![allow(unused)]
2+
#![warn(clippy::ifs_as_logical_ops)]
3+
4+
fn main() {
5+
// test code goes here
6+
}
7+
8+
fn john(b1: bool, b2: bool) -> bool {
9+
if b1 { b2 } else { false }
10+
//~^ ifs_as_logical_ops
11+
}

0 commit comments

Comments
 (0)