Skip to content

Commit efe72cf

Browse files
committed
Move NeedlessBitwiseBool into Operators lint pass
1 parent 68056d7 commit efe72cf

File tree

6 files changed

+70
-89
lines changed

6 files changed

+70
-89
lines changed

clippy_lints/src/lib.register_lints.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -376,7 +376,6 @@ store.register_lints(&[
376376
mutex_atomic::MUTEX_ATOMIC,
377377
mutex_atomic::MUTEX_INTEGER,
378378
needless_arbitrary_self_type::NEEDLESS_ARBITRARY_SELF_TYPE,
379-
needless_bitwise_bool::NEEDLESS_BITWISE_BOOL,
380379
needless_bool::BOOL_COMPARISON,
381380
needless_bool::NEEDLESS_BOOL,
382381
needless_borrowed_ref::NEEDLESS_BORROWED_REFERENCE,
@@ -423,6 +422,7 @@ store.register_lints(&[
423422
operators::MISREFACTORED_ASSIGN_OP,
424423
operators::MODULO_ARITHMETIC,
425424
operators::MODULO_ONE,
425+
operators::NEEDLESS_BITWISE_BOOL,
426426
operators::OP_REF,
427427
operators::VERBOSE_BIT_MASK,
428428
option_env_unwrap::OPTION_ENV_UNWRAP,

clippy_lints/src/lib.register_pedantic.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,14 +66,14 @@ store.register_group(true, "clippy::pedantic", Some("clippy_pedantic"), vec![
6666
LintId::of(methods::UNNECESSARY_JOIN),
6767
LintId::of(misc::USED_UNDERSCORE_BINDING),
6868
LintId::of(mut_mut::MUT_MUT),
69-
LintId::of(needless_bitwise_bool::NEEDLESS_BITWISE_BOOL),
7069
LintId::of(needless_continue::NEEDLESS_CONTINUE),
7170
LintId::of(needless_for_each::NEEDLESS_FOR_EACH),
7271
LintId::of(needless_pass_by_value::NEEDLESS_PASS_BY_VALUE),
7372
LintId::of(no_effect::NO_EFFECT_UNDERSCORE_BINDING),
7473
LintId::of(non_expressive_names::MANY_SINGLE_CHAR_NAMES),
7574
LintId::of(non_expressive_names::SIMILAR_NAMES),
7675
LintId::of(operators::FLOAT_CMP),
76+
LintId::of(operators::NEEDLESS_BITWISE_BOOL),
7777
LintId::of(operators::VERBOSE_BIT_MASK),
7878
LintId::of(pass_by_ref_or_value::LARGE_TYPES_PASSED_BY_VALUE),
7979
LintId::of(pass_by_ref_or_value::TRIVIALLY_COPY_PASS_BY_REF),

clippy_lints/src/lib.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -300,7 +300,6 @@ mod mut_reference;
300300
mod mutable_debug_assertion;
301301
mod mutex_atomic;
302302
mod needless_arbitrary_self_type;
303-
mod needless_bitwise_bool;
304303
mod needless_bool;
305304
mod needless_borrowed_ref;
306305
mod needless_continue;
@@ -535,7 +534,6 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
535534
))
536535
});
537536
store.register_late_pass(|| Box::new(booleans::NonminimalBool));
538-
store.register_late_pass(|| Box::new(needless_bitwise_bool::NeedlessBitwiseBool));
539537
store.register_late_pass(|| Box::new(enum_clike::UnportableVariant));
540538
store.register_late_pass(|| Box::new(float_literal::FloatLiteral));
541539
store.register_late_pass(|| Box::new(ptr::Ptr));

clippy_lints/src/needless_bitwise_bool.rs

Lines changed: 0 additions & 85 deletions
This file was deleted.

clippy_lints/src/operators/mod.rs

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ mod integer_division;
1919
mod misrefactored_assign_op;
2020
mod modulo_arithmetic;
2121
mod modulo_one;
22+
mod needless_bitwise_bool;
2223
mod op_ref;
2324
mod verbose_bit_mask;
2425

@@ -626,6 +627,35 @@ declare_clippy_lint! {
626627
"any modulo arithmetic statement"
627628
}
628629

630+
declare_clippy_lint! {
631+
/// ### What it does
632+
/// Checks for uses of bitwise and/or operators between booleans, where performance may be improved by using
633+
/// a lazy and.
634+
///
635+
/// ### Why is this bad?
636+
/// The bitwise operators do not support short-circuiting, so it may hinder code performance.
637+
/// Additionally, boolean logic "masked" as bitwise logic is not caught by lints like `unnecessary_fold`
638+
///
639+
/// ### Known problems
640+
/// This lint evaluates only when the right side is determined to have no side effects. At this time, that
641+
/// determination is quite conservative.
642+
///
643+
/// ### Example
644+
/// ```rust
645+
/// let (x,y) = (true, false);
646+
/// if x & !y {} // where both x and y are booleans
647+
/// ```
648+
/// Use instead:
649+
/// ```rust
650+
/// let (x,y) = (true, false);
651+
/// if x && !y {}
652+
/// ```
653+
#[clippy::version = "1.54.0"]
654+
pub NEEDLESS_BITWISE_BOOL,
655+
pedantic,
656+
"Boolean expressions that use bitwise rather than lazy operators"
657+
}
658+
629659
pub struct Operators {
630660
arithmetic_context: arithmetic::Context,
631661
verbose_bit_mask_threshold: u64,
@@ -653,6 +683,7 @@ impl_lint_pass!(Operators => [
653683
FLOAT_CMP_CONST,
654684
MODULO_ONE,
655685
MODULO_ARITHMETIC,
686+
NEEDLESS_BITWISE_BOOL,
656687
]);
657688
impl Operators {
658689
pub fn new(verbose_bit_mask_threshold: u64) -> Self {
@@ -675,6 +706,7 @@ impl<'tcx> LateLintPass<'tcx> for Operators {
675706
}
676707
erasing_op::check(cx, e, op.node, lhs, rhs);
677708
identity_op::check(cx, e, op.node, lhs, rhs);
709+
needless_bitwise_bool::check(cx, e, op.node, lhs, rhs);
678710
}
679711
self.arithmetic_context.check_binary(cx, e, op.node, lhs, rhs);
680712
bit_mask::check(cx, e, op.node, lhs, rhs);
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
use clippy_utils::diagnostics::span_lint_and_then;
2+
use clippy_utils::source::snippet_opt;
3+
use rustc_errors::Applicability;
4+
use rustc_hir::{BinOpKind, Expr, ExprKind};
5+
use rustc_lint::LateContext;
6+
7+
use super::NEEDLESS_BITWISE_BOOL;
8+
9+
pub(super) fn check(cx: &LateContext<'_>, e: &Expr<'_>, op: BinOpKind, lhs: &Expr<'_>, rhs: &Expr<'_>) {
10+
let op_str = match op {
11+
BinOpKind::BitAnd => "&&",
12+
BinOpKind::BitOr => "||",
13+
_ => return,
14+
};
15+
if matches!(
16+
rhs.kind,
17+
ExprKind::Call(..) | ExprKind::MethodCall(..) | ExprKind::Binary(..) | ExprKind::Unary(..)
18+
) && cx.typeck_results().expr_ty(e).is_bool()
19+
&& !rhs.can_have_side_effects()
20+
{
21+
span_lint_and_then(
22+
cx,
23+
NEEDLESS_BITWISE_BOOL,
24+
e.span,
25+
"use of bitwise operator instead of lazy operator between booleans",
26+
|diag| {
27+
if let Some(lhs_snip) = snippet_opt(cx, lhs.span)
28+
&& let Some(rhs_snip) = snippet_opt(cx, rhs.span)
29+
{
30+
let sugg = format!("{} {} {}", lhs_snip, op_str, rhs_snip);
31+
diag.span_suggestion(e.span, "try", sugg, Applicability::MachineApplicable);
32+
}
33+
},
34+
);
35+
}
36+
}

0 commit comments

Comments
 (0)