New lint: manual_is_multiple_of (#14292)
~~I've added a `min_divisor` configuration option, default to 4, to not trigger on smaller divisibility operations. I would prefer not to lint `if a & 1 == 0` as `if a.is_multiple_of(2)` by default because the former is very idiomatic in systems (and embedded) programming.~~ ~~A `min_and_mask_size` option, defaulting to 3, sets the default bits to be and-masked before this lint triggers; that would be `n` in `v & ((1 << n) - 1) == 0`. The form `v % 10 == 0` is always linted.~~ ~~This PR will stay in draft mode until the next rustup which will mark `unsigned_is_multiple_of` stable for Rust 1.87.0, and the feature flags will be removed.~~ What should its category be? I've used "complexity", but "pedantic" might be suitable as well. Close rust-lang/rust-clippy#14289 changelog: [`manual_is_multiple_of`]: new lint r? ghost
This commit is contained in:
commit
2c1c746ebd
30 changed files with 303 additions and 89 deletions
|
|
@ -5968,6 +5968,7 @@ Released 2018-09-13
|
|||
[`manual_is_ascii_check`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_is_ascii_check
|
||||
[`manual_is_finite`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_is_finite
|
||||
[`manual_is_infinite`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_is_infinite
|
||||
[`manual_is_multiple_of`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_is_multiple_of
|
||||
[`manual_is_power_of_two`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_is_power_of_two
|
||||
[`manual_is_variant_and`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_is_variant_and
|
||||
[`manual_let_else`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_let_else
|
||||
|
|
|
|||
|
|
@ -168,7 +168,7 @@ fn pow_call_result_sign(cx: &LateContext<'_>, base: &Expr<'_>, exponent: &Expr<'
|
|||
|
||||
// Rust's integer pow() functions take an unsigned exponent.
|
||||
let exponent_val = get_const_unsigned_int_eval(cx, exponent, None);
|
||||
let exponent_is_even = exponent_val.map(|val| val % 2 == 0);
|
||||
let exponent_is_even = exponent_val.map(|val| val.is_multiple_of(2));
|
||||
|
||||
match (base_sign, exponent_is_even) {
|
||||
// Non-negative bases always return non-negative results, ignoring overflow.
|
||||
|
|
|
|||
|
|
@ -591,6 +591,7 @@ pub static LINTS: &[&::declare_clippy_lint::LintInfo] = &[
|
|||
crate::operators::IMPOSSIBLE_COMPARISONS_INFO,
|
||||
crate::operators::INEFFECTIVE_BIT_MASK_INFO,
|
||||
crate::operators::INTEGER_DIVISION_INFO,
|
||||
crate::operators::MANUAL_IS_MULTIPLE_OF_INFO,
|
||||
crate::operators::MANUAL_MIDPOINT_INFO,
|
||||
crate::operators::MISREFACTORED_ASSIGN_OP_INFO,
|
||||
crate::operators::MODULO_ARITHMETIC_INFO,
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
use clippy_utils::consts::{ConstEvalCtxt, Constant};
|
||||
use clippy_utils::consts::is_zero_integer_const;
|
||||
use clippy_utils::diagnostics::{span_lint_and_help, span_lint_and_sugg};
|
||||
use clippy_utils::is_else_clause;
|
||||
use clippy_utils::source::{HasSession, indent_of, reindent_multiline, snippet};
|
||||
|
|
@ -48,13 +48,6 @@ declare_clippy_lint! {
|
|||
|
||||
declare_lint_pass!(IfNotElse => [IF_NOT_ELSE]);
|
||||
|
||||
fn is_zero_const(expr: &Expr<'_>, cx: &LateContext<'_>) -> bool {
|
||||
if let Some(value) = ConstEvalCtxt::new(cx).eval_simple(expr) {
|
||||
return Constant::Int(0) == value;
|
||||
}
|
||||
false
|
||||
}
|
||||
|
||||
impl LateLintPass<'_> for IfNotElse {
|
||||
fn check_expr(&mut self, cx: &LateContext<'_>, e: &Expr<'_>) {
|
||||
if let ExprKind::If(cond, cond_inner, Some(els)) = e.kind
|
||||
|
|
@ -68,7 +61,7 @@ impl LateLintPass<'_> for IfNotElse {
|
|||
),
|
||||
// Don't lint on `… != 0`, as these are likely to be bit tests.
|
||||
// For example, `if foo & 0x0F00 != 0 { … } else { … }` is already in the "proper" order.
|
||||
ExprKind::Binary(op, _, rhs) if op.node == BinOpKind::Ne && !is_zero_const(rhs, cx) => (
|
||||
ExprKind::Binary(op, _, rhs) if op.node == BinOpKind::Ne && !is_zero_integer_const(cx, rhs) => (
|
||||
"unnecessary `!=` operation",
|
||||
"change to `==` and swap the blocks of the `if`/`else`",
|
||||
),
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
use clippy_utils::consts::{ConstEvalCtxt, Constant, FullInt};
|
||||
use clippy_utils::consts::{ConstEvalCtxt, Constant, FullInt, integer_const, is_zero_integer_const};
|
||||
use clippy_utils::diagnostics::span_lint_and_sugg;
|
||||
use clippy_utils::source::snippet_with_applicability;
|
||||
use clippy_utils::{ExprUseNode, clip, expr_use_ctxt, peel_hir_expr_refs, unsext};
|
||||
|
|
@ -186,9 +186,7 @@ fn is_allowed<'tcx>(
|
|||
cx.typeck_results().expr_ty(left).peel_refs().is_integral()
|
||||
&& cx.typeck_results().expr_ty(right).peel_refs().is_integral()
|
||||
// `1 << 0` is a common pattern in bit manipulation code
|
||||
&& !(cmp == BinOpKind::Shl
|
||||
&& ConstEvalCtxt::new(cx).eval_simple(right) == Some(Constant::Int(0))
|
||||
&& ConstEvalCtxt::new(cx).eval_simple(left) == Some(Constant::Int(1)))
|
||||
&& !(cmp == BinOpKind::Shl && is_zero_integer_const(cx, right) && integer_const(cx, left) == Some(1))
|
||||
}
|
||||
|
||||
fn check_remainder(cx: &LateContext<'_>, left: &Expr<'_>, right: &Expr<'_>, span: Span, arg: Span) {
|
||||
|
|
|
|||
66
clippy_lints/src/operators/manual_is_multiple_of.rs
Normal file
66
clippy_lints/src/operators/manual_is_multiple_of.rs
Normal file
|
|
@ -0,0 +1,66 @@
|
|||
use clippy_utils::consts::is_zero_integer_const;
|
||||
use clippy_utils::diagnostics::span_lint_and_sugg;
|
||||
use clippy_utils::msrvs::{self, Msrv};
|
||||
use clippy_utils::sugg::Sugg;
|
||||
use rustc_ast::BinOpKind;
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_hir::{Expr, ExprKind};
|
||||
use rustc_lint::LateContext;
|
||||
use rustc_middle::ty;
|
||||
|
||||
use super::MANUAL_IS_MULTIPLE_OF;
|
||||
|
||||
pub(super) fn check<'tcx>(
|
||||
cx: &LateContext<'tcx>,
|
||||
expr: &Expr<'_>,
|
||||
op: BinOpKind,
|
||||
lhs: &'tcx Expr<'tcx>,
|
||||
rhs: &'tcx Expr<'tcx>,
|
||||
msrv: Msrv,
|
||||
) {
|
||||
if msrv.meets(cx, msrvs::UNSIGNED_IS_MULTIPLE_OF)
|
||||
&& let Some(operand) = uint_compare_to_zero(cx, op, lhs, rhs)
|
||||
&& let ExprKind::Binary(operand_op, operand_left, operand_right) = operand.kind
|
||||
&& operand_op.node == BinOpKind::Rem
|
||||
{
|
||||
let mut app = Applicability::MachineApplicable;
|
||||
let divisor = Sugg::hir_with_applicability(cx, operand_right, "_", &mut app);
|
||||
span_lint_and_sugg(
|
||||
cx,
|
||||
MANUAL_IS_MULTIPLE_OF,
|
||||
expr.span,
|
||||
"manual implementation of `.is_multiple_of()`",
|
||||
"replace with",
|
||||
format!(
|
||||
"{}{}.is_multiple_of({divisor})",
|
||||
if op == BinOpKind::Eq { "" } else { "!" },
|
||||
Sugg::hir_with_applicability(cx, operand_left, "_", &mut app).maybe_paren()
|
||||
),
|
||||
app,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// If we have a `x == 0`, `x != 0` or `x > 0` (or the reverted ones), return the non-zero operand
|
||||
fn uint_compare_to_zero<'tcx>(
|
||||
cx: &LateContext<'tcx>,
|
||||
op: BinOpKind,
|
||||
lhs: &'tcx Expr<'tcx>,
|
||||
rhs: &'tcx Expr<'tcx>,
|
||||
) -> Option<&'tcx Expr<'tcx>> {
|
||||
let operand = if matches!(lhs.kind, ExprKind::Binary(..))
|
||||
&& matches!(op, BinOpKind::Eq | BinOpKind::Ne | BinOpKind::Gt)
|
||||
&& is_zero_integer_const(cx, rhs)
|
||||
{
|
||||
lhs
|
||||
} else if matches!(rhs.kind, ExprKind::Binary(..))
|
||||
&& matches!(op, BinOpKind::Eq | BinOpKind::Ne | BinOpKind::Lt)
|
||||
&& is_zero_integer_const(cx, lhs)
|
||||
{
|
||||
rhs
|
||||
} else {
|
||||
return None;
|
||||
};
|
||||
|
||||
matches!(cx.typeck_results().expr_ty_adjusted(operand).kind(), ty::Uint(_)).then_some(operand)
|
||||
}
|
||||
|
|
@ -11,6 +11,7 @@ mod float_cmp;
|
|||
mod float_equality_without_abs;
|
||||
mod identity_op;
|
||||
mod integer_division;
|
||||
mod manual_is_multiple_of;
|
||||
mod manual_midpoint;
|
||||
mod misrefactored_assign_op;
|
||||
mod modulo_arithmetic;
|
||||
|
|
@ -830,12 +831,42 @@ declare_clippy_lint! {
|
|||
"manual implementation of `midpoint` which can overflow"
|
||||
}
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// ### What it does
|
||||
/// Checks for manual implementation of `.is_multiple_of()` on
|
||||
/// unsigned integer types.
|
||||
///
|
||||
/// ### Why is this bad?
|
||||
/// `a.is_multiple_of(b)` is a clearer way to check for divisibility
|
||||
/// of `a` by `b`. This expression can never panic.
|
||||
///
|
||||
/// ### Example
|
||||
/// ```no_run
|
||||
/// # let (a, b) = (3u64, 4u64);
|
||||
/// if a % b == 0 {
|
||||
/// println!("{a} is divisible by {b}");
|
||||
/// }
|
||||
/// ```
|
||||
/// Use instead:
|
||||
/// ```no_run
|
||||
/// # let (a, b) = (3u64, 4u64);
|
||||
/// if a.is_multiple_of(b) {
|
||||
/// println!("{a} is divisible by {b}");
|
||||
/// }
|
||||
/// ```
|
||||
#[clippy::version = "1.89.0"]
|
||||
pub MANUAL_IS_MULTIPLE_OF,
|
||||
complexity,
|
||||
"manual implementation of `.is_multiple_of()`"
|
||||
}
|
||||
|
||||
pub struct Operators {
|
||||
arithmetic_context: numeric_arithmetic::Context,
|
||||
verbose_bit_mask_threshold: u64,
|
||||
modulo_arithmetic_allow_comparison_to_zero: bool,
|
||||
msrv: Msrv,
|
||||
}
|
||||
|
||||
impl Operators {
|
||||
pub fn new(conf: &'static Conf) -> Self {
|
||||
Self {
|
||||
|
|
@ -874,6 +905,7 @@ impl_lint_pass!(Operators => [
|
|||
NEEDLESS_BITWISE_BOOL,
|
||||
SELF_ASSIGNMENT,
|
||||
MANUAL_MIDPOINT,
|
||||
MANUAL_IS_MULTIPLE_OF,
|
||||
]);
|
||||
|
||||
impl<'tcx> LateLintPass<'tcx> for Operators {
|
||||
|
|
@ -891,6 +923,7 @@ impl<'tcx> LateLintPass<'tcx> for Operators {
|
|||
identity_op::check(cx, e, op.node, lhs, rhs);
|
||||
needless_bitwise_bool::check(cx, e, op.node, lhs, rhs);
|
||||
manual_midpoint::check(cx, e, op.node, lhs, rhs, self.msrv);
|
||||
manual_is_multiple_of::check(cx, e, op.node, lhs, rhs, self.msrv);
|
||||
}
|
||||
self.arithmetic_context.check_binary(cx, e, op.node, lhs, rhs);
|
||||
bit_mask::check(cx, e, op.node, lhs, rhs);
|
||||
|
|
|
|||
|
|
@ -958,3 +958,18 @@ fn field_of_struct<'tcx>(
|
|||
None
|
||||
}
|
||||
}
|
||||
|
||||
/// If `expr` evaluates to an integer constant, return its value.
|
||||
pub fn integer_const(cx: &LateContext<'_>, expr: &Expr<'_>) -> Option<u128> {
|
||||
if let Some(Constant::Int(value)) = ConstEvalCtxt::new(cx).eval_simple(expr) {
|
||||
Some(value)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
/// Check if `expr` evaluates to an integer constant of 0.
|
||||
#[inline]
|
||||
pub fn is_zero_integer_const(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {
|
||||
integer_const(cx, expr) == Some(0)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ macro_rules! msrv_aliases {
|
|||
// names may refer to stabilized feature flags or library items
|
||||
msrv_aliases! {
|
||||
1,88,0 { LET_CHAINS }
|
||||
1,87,0 { OS_STR_DISPLAY, INT_MIDPOINT, CONST_CHAR_IS_DIGIT }
|
||||
1,87,0 { OS_STR_DISPLAY, INT_MIDPOINT, CONST_CHAR_IS_DIGIT, UNSIGNED_IS_MULTIPLE_OF }
|
||||
1,85,0 { UINT_FLOAT_MIDPOINT, CONST_SIZE_OF_VAL }
|
||||
1,84,0 { CONST_OPTION_AS_SLICE, MANUAL_DANGLING_PTR }
|
||||
1,83,0 { CONST_EXTERN_FN, CONST_FLOAT_BITS_CONV, CONST_FLOAT_CLASSIFY, CONST_MUT_REFS, CONST_UNWRAP }
|
||||
|
|
|
|||
|
|
@ -126,7 +126,7 @@ fn issue_10381() {
|
|||
impl Bar for Foo {}
|
||||
|
||||
fn maybe_get_bar(i: u32) -> Option<Box<dyn Bar>> {
|
||||
if i % 2 == 0 {
|
||||
if i.is_multiple_of(2) {
|
||||
Some(Box::new(Foo::default()))
|
||||
} else {
|
||||
None
|
||||
|
|
|
|||
|
|
@ -126,7 +126,7 @@ fn issue_10381() {
|
|||
impl Bar for Foo {}
|
||||
|
||||
fn maybe_get_bar(i: u32) -> Option<Box<dyn Bar>> {
|
||||
if i % 2 == 0 {
|
||||
if i.is_multiple_of(2) {
|
||||
Some(Box::new(Foo::default()))
|
||||
} else {
|
||||
None
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@ fn infinite_iters() {
|
|||
//~^ infinite_iter
|
||||
|
||||
// infinite iter
|
||||
(0_u64..).filter(|x| x % 2 == 0).last();
|
||||
(0_u64..).filter(|x| x.is_multiple_of(2)).last();
|
||||
//~^ infinite_iter
|
||||
|
||||
// not an infinite, because ranges are double-ended
|
||||
|
|
|
|||
|
|
@ -42,8 +42,8 @@ LL | (0_usize..).flat_map(|x| 0..x).product::<usize>();
|
|||
error: infinite iteration detected
|
||||
--> tests/ui/infinite_iter.rs:41:5
|
||||
|
|
||||
LL | (0_u64..).filter(|x| x % 2 == 0).last();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
LL | (0_u64..).filter(|x| x.is_multiple_of(2)).last();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: possible infinite iteration detected
|
||||
--> tests/ui/infinite_iter.rs:53:5
|
||||
|
|
|
|||
|
|
@ -30,15 +30,19 @@ fn main() {
|
|||
|
||||
let _ = map.clone().values().collect::<Vec<_>>();
|
||||
//~^ iter_kv_map
|
||||
let _ = map.keys().filter(|x| *x % 2 == 0).count();
|
||||
let _ = map.keys().filter(|x| x.is_multiple_of(2)).count();
|
||||
//~^ iter_kv_map
|
||||
|
||||
// Don't lint
|
||||
let _ = map.iter().filter(|(_, val)| *val % 2 == 0).map(|(key, _)| key).count();
|
||||
let _ = map
|
||||
.iter()
|
||||
.filter(|(_, val)| val.is_multiple_of(2))
|
||||
.map(|(key, _)| key)
|
||||
.count();
|
||||
let _ = map.iter().map(get_key).collect::<Vec<_>>();
|
||||
|
||||
// Linting the following could be an improvement to the lint
|
||||
// map.iter().filter_map(|(_, val)| (val % 2 == 0).then(val * 17)).count();
|
||||
// map.iter().filter_map(|(_, val)| (val.is_multiple_of(2)).then(val * 17)).count();
|
||||
|
||||
// Lint
|
||||
let _ = map.keys().map(|key| key * 9).count();
|
||||
|
|
@ -84,15 +88,19 @@ fn main() {
|
|||
|
||||
let _ = map.clone().values().collect::<Vec<_>>();
|
||||
//~^ iter_kv_map
|
||||
let _ = map.keys().filter(|x| *x % 2 == 0).count();
|
||||
let _ = map.keys().filter(|x| x.is_multiple_of(2)).count();
|
||||
//~^ iter_kv_map
|
||||
|
||||
// Don't lint
|
||||
let _ = map.iter().filter(|(_, val)| *val % 2 == 0).map(|(key, _)| key).count();
|
||||
let _ = map
|
||||
.iter()
|
||||
.filter(|(_, val)| val.is_multiple_of(2))
|
||||
.map(|(key, _)| key)
|
||||
.count();
|
||||
let _ = map.iter().map(get_key).collect::<Vec<_>>();
|
||||
|
||||
// Linting the following could be an improvement to the lint
|
||||
// map.iter().filter_map(|(_, val)| (val % 2 == 0).then(val * 17)).count();
|
||||
// map.iter().filter_map(|(_, val)| (val.is_multiple_of(2)).then(val * 17)).count();
|
||||
|
||||
// Lint
|
||||
let _ = map.keys().map(|key| key * 9).count();
|
||||
|
|
|
|||
|
|
@ -30,15 +30,19 @@ fn main() {
|
|||
|
||||
let _ = map.clone().iter().map(|(_, val)| val).collect::<Vec<_>>();
|
||||
//~^ iter_kv_map
|
||||
let _ = map.iter().map(|(key, _)| key).filter(|x| *x % 2 == 0).count();
|
||||
let _ = map.iter().map(|(key, _)| key).filter(|x| x.is_multiple_of(2)).count();
|
||||
//~^ iter_kv_map
|
||||
|
||||
// Don't lint
|
||||
let _ = map.iter().filter(|(_, val)| *val % 2 == 0).map(|(key, _)| key).count();
|
||||
let _ = map
|
||||
.iter()
|
||||
.filter(|(_, val)| val.is_multiple_of(2))
|
||||
.map(|(key, _)| key)
|
||||
.count();
|
||||
let _ = map.iter().map(get_key).collect::<Vec<_>>();
|
||||
|
||||
// Linting the following could be an improvement to the lint
|
||||
// map.iter().filter_map(|(_, val)| (val % 2 == 0).then(val * 17)).count();
|
||||
// map.iter().filter_map(|(_, val)| (val.is_multiple_of(2)).then(val * 17)).count();
|
||||
|
||||
// Lint
|
||||
let _ = map.iter().map(|(key, _value)| key * 9).count();
|
||||
|
|
@ -86,15 +90,19 @@ fn main() {
|
|||
|
||||
let _ = map.clone().iter().map(|(_, val)| val).collect::<Vec<_>>();
|
||||
//~^ iter_kv_map
|
||||
let _ = map.iter().map(|(key, _)| key).filter(|x| *x % 2 == 0).count();
|
||||
let _ = map.iter().map(|(key, _)| key).filter(|x| x.is_multiple_of(2)).count();
|
||||
//~^ iter_kv_map
|
||||
|
||||
// Don't lint
|
||||
let _ = map.iter().filter(|(_, val)| *val % 2 == 0).map(|(key, _)| key).count();
|
||||
let _ = map
|
||||
.iter()
|
||||
.filter(|(_, val)| val.is_multiple_of(2))
|
||||
.map(|(key, _)| key)
|
||||
.count();
|
||||
let _ = map.iter().map(get_key).collect::<Vec<_>>();
|
||||
|
||||
// Linting the following could be an improvement to the lint
|
||||
// map.iter().filter_map(|(_, val)| (val % 2 == 0).then(val * 17)).count();
|
||||
// map.iter().filter_map(|(_, val)| (val.is_multiple_of(2)).then(val * 17)).count();
|
||||
|
||||
// Lint
|
||||
let _ = map.iter().map(|(key, _value)| key * 9).count();
|
||||
|
|
|
|||
|
|
@ -52,29 +52,29 @@ LL | let _ = map.clone().iter().map(|(_, val)| val).collect::<Vec<_>>();
|
|||
error: iterating on a map's keys
|
||||
--> tests/ui/iter_kv_map.rs:33:13
|
||||
|
|
||||
LL | let _ = map.iter().map(|(key, _)| key).filter(|x| *x % 2 == 0).count();
|
||||
LL | let _ = map.iter().map(|(key, _)| key).filter(|x| x.is_multiple_of(2)).count();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `map.keys()`
|
||||
|
||||
error: iterating on a map's keys
|
||||
--> tests/ui/iter_kv_map.rs:44:13
|
||||
--> tests/ui/iter_kv_map.rs:48:13
|
||||
|
|
||||
LL | let _ = map.iter().map(|(key, _value)| key * 9).count();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `map.keys().map(|key| key * 9)`
|
||||
|
||||
error: iterating on a map's values
|
||||
--> tests/ui/iter_kv_map.rs:46:13
|
||||
--> tests/ui/iter_kv_map.rs:50:13
|
||||
|
|
||||
LL | let _ = map.iter().map(|(_key, value)| value * 17).count();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `map.values().map(|value| value * 17)`
|
||||
|
||||
error: iterating on a map's values
|
||||
--> tests/ui/iter_kv_map.rs:50:13
|
||||
--> tests/ui/iter_kv_map.rs:54:13
|
||||
|
|
||||
LL | let _ = map.clone().into_iter().map(|(_, ref val)| ref_acceptor(val)).count();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `map.clone().into_values().map(|ref val| ref_acceptor(val))`
|
||||
|
||||
error: iterating on a map's values
|
||||
--> tests/ui/iter_kv_map.rs:54:13
|
||||
--> tests/ui/iter_kv_map.rs:58:13
|
||||
|
|
||||
LL | let _ = map
|
||||
| _____________^
|
||||
|
|
@ -97,85 +97,85 @@ LL + })
|
|||
|
|
||||
|
||||
error: iterating on a map's values
|
||||
--> tests/ui/iter_kv_map.rs:65:13
|
||||
--> tests/ui/iter_kv_map.rs:69:13
|
||||
|
|
||||
LL | let _ = map.clone().into_iter().map(|(_, mut val)| val).count();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `map.clone().into_values()`
|
||||
|
||||
error: iterating on a map's keys
|
||||
--> tests/ui/iter_kv_map.rs:70:13
|
||||
--> tests/ui/iter_kv_map.rs:74:13
|
||||
|
|
||||
LL | let _ = map.iter().map(|(key, _)| key).collect::<Vec<_>>();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `map.keys()`
|
||||
|
||||
error: iterating on a map's values
|
||||
--> tests/ui/iter_kv_map.rs:72:13
|
||||
--> tests/ui/iter_kv_map.rs:76:13
|
||||
|
|
||||
LL | let _ = map.iter().map(|(_, value)| value).collect::<Vec<_>>();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `map.values()`
|
||||
|
||||
error: iterating on a map's values
|
||||
--> tests/ui/iter_kv_map.rs:74:13
|
||||
--> tests/ui/iter_kv_map.rs:78:13
|
||||
|
|
||||
LL | let _ = map.iter().map(|(_, v)| v + 2).collect::<Vec<_>>();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `map.values().map(|v| v + 2)`
|
||||
|
||||
error: iterating on a map's keys
|
||||
--> tests/ui/iter_kv_map.rs:77:13
|
||||
--> tests/ui/iter_kv_map.rs:81:13
|
||||
|
|
||||
LL | let _ = map.clone().into_iter().map(|(key, _)| key).collect::<Vec<_>>();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `map.clone().into_keys()`
|
||||
|
||||
error: iterating on a map's keys
|
||||
--> tests/ui/iter_kv_map.rs:79:13
|
||||
--> tests/ui/iter_kv_map.rs:83:13
|
||||
|
|
||||
LL | let _ = map.clone().into_iter().map(|(key, _)| key + 2).collect::<Vec<_>>();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `map.clone().into_keys().map(|key| key + 2)`
|
||||
|
||||
error: iterating on a map's values
|
||||
--> tests/ui/iter_kv_map.rs:82:13
|
||||
--> tests/ui/iter_kv_map.rs:86:13
|
||||
|
|
||||
LL | let _ = map.clone().into_iter().map(|(_, val)| val).collect::<Vec<_>>();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `map.clone().into_values()`
|
||||
|
||||
error: iterating on a map's values
|
||||
--> tests/ui/iter_kv_map.rs:84:13
|
||||
--> tests/ui/iter_kv_map.rs:88:13
|
||||
|
|
||||
LL | let _ = map.clone().into_iter().map(|(_, val)| val + 2).collect::<Vec<_>>();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `map.clone().into_values().map(|val| val + 2)`
|
||||
|
||||
error: iterating on a map's values
|
||||
--> tests/ui/iter_kv_map.rs:87:13
|
||||
--> tests/ui/iter_kv_map.rs:91:13
|
||||
|
|
||||
LL | let _ = map.clone().iter().map(|(_, val)| val).collect::<Vec<_>>();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `map.clone().values()`
|
||||
|
||||
error: iterating on a map's keys
|
||||
--> tests/ui/iter_kv_map.rs:89:13
|
||||
--> tests/ui/iter_kv_map.rs:93:13
|
||||
|
|
||||
LL | let _ = map.iter().map(|(key, _)| key).filter(|x| *x % 2 == 0).count();
|
||||
LL | let _ = map.iter().map(|(key, _)| key).filter(|x| x.is_multiple_of(2)).count();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `map.keys()`
|
||||
|
||||
error: iterating on a map's keys
|
||||
--> tests/ui/iter_kv_map.rs:100:13
|
||||
--> tests/ui/iter_kv_map.rs:108:13
|
||||
|
|
||||
LL | let _ = map.iter().map(|(key, _value)| key * 9).count();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `map.keys().map(|key| key * 9)`
|
||||
|
||||
error: iterating on a map's values
|
||||
--> tests/ui/iter_kv_map.rs:102:13
|
||||
--> tests/ui/iter_kv_map.rs:110:13
|
||||
|
|
||||
LL | let _ = map.iter().map(|(_key, value)| value * 17).count();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `map.values().map(|value| value * 17)`
|
||||
|
||||
error: iterating on a map's values
|
||||
--> tests/ui/iter_kv_map.rs:106:13
|
||||
--> tests/ui/iter_kv_map.rs:114:13
|
||||
|
|
||||
LL | let _ = map.clone().into_iter().map(|(_, ref val)| ref_acceptor(val)).count();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `map.clone().into_values().map(|ref val| ref_acceptor(val))`
|
||||
|
||||
error: iterating on a map's values
|
||||
--> tests/ui/iter_kv_map.rs:110:13
|
||||
--> tests/ui/iter_kv_map.rs:118:13
|
||||
|
|
||||
LL | let _ = map
|
||||
| _____________^
|
||||
|
|
@ -198,73 +198,73 @@ LL + })
|
|||
|
|
||||
|
||||
error: iterating on a map's values
|
||||
--> tests/ui/iter_kv_map.rs:121:13
|
||||
--> tests/ui/iter_kv_map.rs:129:13
|
||||
|
|
||||
LL | let _ = map.clone().into_iter().map(|(_, mut val)| val).count();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `map.clone().into_values()`
|
||||
|
||||
error: iterating on a map's keys
|
||||
--> tests/ui/iter_kv_map.rs:137:13
|
||||
--> tests/ui/iter_kv_map.rs:145:13
|
||||
|
|
||||
LL | let _ = map.iter().map(|(key, _)| key).collect::<Vec<_>>();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `map.keys()`
|
||||
|
||||
error: iterating on a map's values
|
||||
--> tests/ui/iter_kv_map.rs:140:13
|
||||
--> tests/ui/iter_kv_map.rs:148:13
|
||||
|
|
||||
LL | let _ = map.iter().map(|(_, value)| value).collect::<Vec<_>>();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `map.values()`
|
||||
|
||||
error: iterating on a map's values
|
||||
--> tests/ui/iter_kv_map.rs:143:13
|
||||
--> tests/ui/iter_kv_map.rs:151:13
|
||||
|
|
||||
LL | let _ = map.iter().map(|(_, v)| v + 2).collect::<Vec<_>>();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `map.values().map(|v| v + 2)`
|
||||
|
||||
error: iterating on a map's keys
|
||||
--> tests/ui/iter_kv_map.rs:152:13
|
||||
--> tests/ui/iter_kv_map.rs:160:13
|
||||
|
|
||||
LL | let _ = map.clone().into_iter().map(|(key, _)| key).collect::<Vec<_>>();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `map.clone().into_keys()`
|
||||
|
||||
error: iterating on a map's keys
|
||||
--> tests/ui/iter_kv_map.rs:155:13
|
||||
--> tests/ui/iter_kv_map.rs:163:13
|
||||
|
|
||||
LL | let _ = map.clone().into_iter().map(|(key, _)| key + 2).collect::<Vec<_>>();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `map.clone().into_keys().map(|key| key + 2)`
|
||||
|
||||
error: iterating on a map's values
|
||||
--> tests/ui/iter_kv_map.rs:158:13
|
||||
--> tests/ui/iter_kv_map.rs:166:13
|
||||
|
|
||||
LL | let _ = map.clone().into_iter().map(|(_, val)| val).collect::<Vec<_>>();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `map.clone().into_values()`
|
||||
|
||||
error: iterating on a map's values
|
||||
--> tests/ui/iter_kv_map.rs:161:13
|
||||
--> tests/ui/iter_kv_map.rs:169:13
|
||||
|
|
||||
LL | let _ = map.clone().into_iter().map(|(_, val)| val + 2).collect::<Vec<_>>();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `map.clone().into_values().map(|val| val + 2)`
|
||||
|
||||
error: iterating on a map's keys
|
||||
--> tests/ui/iter_kv_map.rs:164:13
|
||||
--> tests/ui/iter_kv_map.rs:172:13
|
||||
|
|
||||
LL | let _ = map.iter().map(|(key, _)| key).collect::<Vec<_>>();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `map.keys()`
|
||||
|
||||
error: iterating on a map's values
|
||||
--> tests/ui/iter_kv_map.rs:167:13
|
||||
--> tests/ui/iter_kv_map.rs:175:13
|
||||
|
|
||||
LL | let _ = map.iter().map(|(_, value)| value).collect::<Vec<_>>();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `map.values()`
|
||||
|
||||
error: iterating on a map's values
|
||||
--> tests/ui/iter_kv_map.rs:170:13
|
||||
--> tests/ui/iter_kv_map.rs:178:13
|
||||
|
|
||||
LL | let _ = map.iter().map(|(_, v)| v + 2).collect::<Vec<_>>();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `map.values().map(|v| v + 2)`
|
||||
|
||||
error: iterating on a map's values
|
||||
--> tests/ui/iter_kv_map.rs:185:13
|
||||
--> tests/ui/iter_kv_map.rs:193:13
|
||||
|
|
||||
LL | let _ = map.as_ref().iter().map(|(_, v)| v).copied().collect::<Vec<_>>();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `map.as_ref().values()`
|
||||
|
|
|
|||
|
|
@ -61,7 +61,7 @@ fn multiline_sugg() {
|
|||
//~^ let_unit_value
|
||||
.into_iter()
|
||||
.map(|i| i * 2)
|
||||
.filter(|i| i % 2 == 0)
|
||||
.filter(|i| i.is_multiple_of(2))
|
||||
.map(|_| ())
|
||||
.next()
|
||||
.unwrap();
|
||||
|
|
|
|||
|
|
@ -61,7 +61,7 @@ fn multiline_sugg() {
|
|||
//~^ let_unit_value
|
||||
.into_iter()
|
||||
.map(|i| i * 2)
|
||||
.filter(|i| i % 2 == 0)
|
||||
.filter(|i| i.is_multiple_of(2))
|
||||
.map(|_| ())
|
||||
.next()
|
||||
.unwrap();
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ LL ~ v
|
|||
LL +
|
||||
LL + .into_iter()
|
||||
LL + .map(|i| i * 2)
|
||||
LL + .filter(|i| i % 2 == 0)
|
||||
LL + .filter(|i| i.is_multiple_of(2))
|
||||
LL + .map(|_| ())
|
||||
LL + .next()
|
||||
LL + .unwrap();
|
||||
|
|
|
|||
|
|
@ -58,7 +58,7 @@ fn should_not_lint() {
|
|||
|
||||
let vec: Vec<u32> = vec![1, 2, 3, 4, 5, 6];
|
||||
let values = &vec[..];
|
||||
let _ = values.iter().any(|&v| v % 2 == 0);
|
||||
let _ = values.iter().any(|&v| v.is_multiple_of(2));
|
||||
let _ = values.iter().any(|&v| v * 2 == 6);
|
||||
let _ = values.iter().any(|&v| v == v);
|
||||
let _ = values.iter().any(|&v| 4 == 4);
|
||||
|
|
|
|||
|
|
@ -58,7 +58,7 @@ fn should_not_lint() {
|
|||
|
||||
let vec: Vec<u32> = vec![1, 2, 3, 4, 5, 6];
|
||||
let values = &vec[..];
|
||||
let _ = values.iter().any(|&v| v % 2 == 0);
|
||||
let _ = values.iter().any(|&v| v.is_multiple_of(2));
|
||||
let _ = values.iter().any(|&v| v * 2 == 6);
|
||||
let _ = values.iter().any(|&v| v == v);
|
||||
let _ = values.iter().any(|&v| 4 == 4);
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ fn lookup(n: u32) -> Option<u32> {
|
|||
}
|
||||
|
||||
fn with_pat(arr: Vec<(u32, u32)>) -> Option<u32> {
|
||||
arr.into_iter().map(|(a, _)| a).find(|&a| a % 2 == 0)
|
||||
arr.into_iter().map(|(a, _)| a).find(|&a| a.is_multiple_of(2))
|
||||
}
|
||||
|
||||
struct Data {
|
||||
|
|
@ -63,7 +63,7 @@ fn with_side_effects(arr: Vec<u32>) -> Option<u32> {
|
|||
|
||||
fn with_else(arr: Vec<u32>) -> Option<u32> {
|
||||
for el in arr {
|
||||
if el % 2 == 0 {
|
||||
if el.is_multiple_of(2) {
|
||||
return Some(el);
|
||||
} else {
|
||||
println!("{}", el);
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ fn lookup(n: u32) -> Option<u32> {
|
|||
fn with_pat(arr: Vec<(u32, u32)>) -> Option<u32> {
|
||||
for (a, _) in arr {
|
||||
//~^ manual_find
|
||||
if a % 2 == 0 {
|
||||
if a.is_multiple_of(2) {
|
||||
return Some(a);
|
||||
}
|
||||
}
|
||||
|
|
@ -111,7 +111,7 @@ fn with_side_effects(arr: Vec<u32>) -> Option<u32> {
|
|||
|
||||
fn with_else(arr: Vec<u32>) -> Option<u32> {
|
||||
for el in arr {
|
||||
if el % 2 == 0 {
|
||||
if el.is_multiple_of(2) {
|
||||
return Some(el);
|
||||
} else {
|
||||
println!("{}", el);
|
||||
|
|
|
|||
|
|
@ -17,11 +17,11 @@ error: manual implementation of `Iterator::find`
|
|||
|
|
||||
LL | / for (a, _) in arr {
|
||||
LL | |
|
||||
LL | | if a % 2 == 0 {
|
||||
LL | | if a.is_multiple_of(2) {
|
||||
LL | | return Some(a);
|
||||
... |
|
||||
LL | | None
|
||||
| |________^ help: replace with an iterator: `arr.into_iter().map(|(a, _)| a).find(|&a| a % 2 == 0)`
|
||||
| |________^ help: replace with an iterator: `arr.into_iter().map(|(a, _)| a).find(|&a| a.is_multiple_of(2))`
|
||||
|
||||
error: manual implementation of `Iterator::find`
|
||||
--> tests/ui/manual_find_fixable.rs:34:5
|
||||
|
|
|
|||
25
tests/ui/manual_is_multiple_of.fixed
Normal file
25
tests/ui/manual_is_multiple_of.fixed
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
//@aux-build: proc_macros.rs
|
||||
#![warn(clippy::manual_is_multiple_of)]
|
||||
|
||||
fn main() {}
|
||||
|
||||
#[clippy::msrv = "1.87"]
|
||||
fn f(a: u64, b: u64) {
|
||||
let _ = a.is_multiple_of(b); //~ manual_is_multiple_of
|
||||
let _ = (a + 1).is_multiple_of(b + 1); //~ manual_is_multiple_of
|
||||
let _ = !a.is_multiple_of(b); //~ manual_is_multiple_of
|
||||
let _ = !(a + 1).is_multiple_of(b + 1); //~ manual_is_multiple_of
|
||||
|
||||
let _ = !a.is_multiple_of(b); //~ manual_is_multiple_of
|
||||
let _ = !a.is_multiple_of(b); //~ manual_is_multiple_of
|
||||
|
||||
proc_macros::external! {
|
||||
let a: u64 = 23424;
|
||||
let _ = a % 4096 == 0;
|
||||
}
|
||||
}
|
||||
|
||||
#[clippy::msrv = "1.86"]
|
||||
fn g(a: u64, b: u64) {
|
||||
let _ = a % b == 0;
|
||||
}
|
||||
25
tests/ui/manual_is_multiple_of.rs
Normal file
25
tests/ui/manual_is_multiple_of.rs
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
//@aux-build: proc_macros.rs
|
||||
#![warn(clippy::manual_is_multiple_of)]
|
||||
|
||||
fn main() {}
|
||||
|
||||
#[clippy::msrv = "1.87"]
|
||||
fn f(a: u64, b: u64) {
|
||||
let _ = a % b == 0; //~ manual_is_multiple_of
|
||||
let _ = (a + 1) % (b + 1) == 0; //~ manual_is_multiple_of
|
||||
let _ = a % b != 0; //~ manual_is_multiple_of
|
||||
let _ = (a + 1) % (b + 1) != 0; //~ manual_is_multiple_of
|
||||
|
||||
let _ = a % b > 0; //~ manual_is_multiple_of
|
||||
let _ = 0 < a % b; //~ manual_is_multiple_of
|
||||
|
||||
proc_macros::external! {
|
||||
let a: u64 = 23424;
|
||||
let _ = a % 4096 == 0;
|
||||
}
|
||||
}
|
||||
|
||||
#[clippy::msrv = "1.86"]
|
||||
fn g(a: u64, b: u64) {
|
||||
let _ = a % b == 0;
|
||||
}
|
||||
41
tests/ui/manual_is_multiple_of.stderr
Normal file
41
tests/ui/manual_is_multiple_of.stderr
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
error: manual implementation of `.is_multiple_of()`
|
||||
--> tests/ui/manual_is_multiple_of.rs:8:13
|
||||
|
|
||||
LL | let _ = a % b == 0;
|
||||
| ^^^^^^^^^^ help: replace with: `a.is_multiple_of(b)`
|
||||
|
|
||||
= note: `-D clippy::manual-is-multiple-of` implied by `-D warnings`
|
||||
= help: to override `-D warnings` add `#[allow(clippy::manual_is_multiple_of)]`
|
||||
|
||||
error: manual implementation of `.is_multiple_of()`
|
||||
--> tests/ui/manual_is_multiple_of.rs:9:13
|
||||
|
|
||||
LL | let _ = (a + 1) % (b + 1) == 0;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `(a + 1).is_multiple_of(b + 1)`
|
||||
|
||||
error: manual implementation of `.is_multiple_of()`
|
||||
--> tests/ui/manual_is_multiple_of.rs:10:13
|
||||
|
|
||||
LL | let _ = a % b != 0;
|
||||
| ^^^^^^^^^^ help: replace with: `!a.is_multiple_of(b)`
|
||||
|
||||
error: manual implementation of `.is_multiple_of()`
|
||||
--> tests/ui/manual_is_multiple_of.rs:11:13
|
||||
|
|
||||
LL | let _ = (a + 1) % (b + 1) != 0;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `!(a + 1).is_multiple_of(b + 1)`
|
||||
|
||||
error: manual implementation of `.is_multiple_of()`
|
||||
--> tests/ui/manual_is_multiple_of.rs:13:13
|
||||
|
|
||||
LL | let _ = a % b > 0;
|
||||
| ^^^^^^^^^ help: replace with: `!a.is_multiple_of(b)`
|
||||
|
||||
error: manual implementation of `.is_multiple_of()`
|
||||
--> tests/ui/manual_is_multiple_of.rs:14:13
|
||||
|
|
||||
LL | let _ = 0 < a % b;
|
||||
| ^^^^^^^^^ help: replace with: `!a.is_multiple_of(b)`
|
||||
|
||||
error: aborting due to 6 previous errors
|
||||
|
||||
|
|
@ -77,7 +77,7 @@ fn option_methods() {
|
|||
let _ = opt_map!(opt2, |x| x == 'a').unwrap_or_default(); // should not lint
|
||||
|
||||
// Should not lint.
|
||||
let _ = Foo::<u32>(0).map(|x| x % 2 == 0) == Some(true);
|
||||
let _ = Foo::<u32>(0).map(|x| x.is_multiple_of(2)) == Some(true);
|
||||
let _ = Some(2).map(|x| x % 2 == 0) != foo();
|
||||
let _ = mac!(eq Some(2).map(|x| x % 2 == 0), Some(true));
|
||||
let _ = mac!(some 2).map(|x| x % 2 == 0) == Some(true);
|
||||
|
|
@ -96,11 +96,11 @@ fn result_methods() {
|
|||
});
|
||||
let _ = res.is_ok_and(|x| x > 1);
|
||||
|
||||
let _ = Ok::<usize, ()>(2).is_ok_and(|x| x % 2 == 0);
|
||||
let _ = Ok::<usize, ()>(2).is_ok_and(|x| x.is_multiple_of(2));
|
||||
//~^ manual_is_variant_and
|
||||
let _ = !Ok::<usize, ()>(2).is_ok_and(|x| x % 2 == 0);
|
||||
let _ = !Ok::<usize, ()>(2).is_ok_and(|x| x.is_multiple_of(2));
|
||||
//~^ manual_is_variant_and
|
||||
let _ = !Ok::<usize, ()>(2).is_ok_and(|x| x % 2 == 0);
|
||||
let _ = !Ok::<usize, ()>(2).is_ok_and(|x| x.is_multiple_of(2));
|
||||
//~^ manual_is_variant_and
|
||||
|
||||
// won't fix because the return type of the closure is not `bool`
|
||||
|
|
|
|||
|
|
@ -83,7 +83,7 @@ fn option_methods() {
|
|||
let _ = opt_map!(opt2, |x| x == 'a').unwrap_or_default(); // should not lint
|
||||
|
||||
// Should not lint.
|
||||
let _ = Foo::<u32>(0).map(|x| x % 2 == 0) == Some(true);
|
||||
let _ = Foo::<u32>(0).map(|x| x.is_multiple_of(2)) == Some(true);
|
||||
let _ = Some(2).map(|x| x % 2 == 0) != foo();
|
||||
let _ = mac!(eq Some(2).map(|x| x % 2 == 0), Some(true));
|
||||
let _ = mac!(some 2).map(|x| x % 2 == 0) == Some(true);
|
||||
|
|
@ -105,11 +105,11 @@ fn result_methods() {
|
|||
//~^ manual_is_variant_and
|
||||
.unwrap_or_default();
|
||||
|
||||
let _ = Ok::<usize, ()>(2).map(|x| x % 2 == 0) == Ok(true);
|
||||
let _ = Ok::<usize, ()>(2).map(|x| x.is_multiple_of(2)) == Ok(true);
|
||||
//~^ manual_is_variant_and
|
||||
let _ = Ok::<usize, ()>(2).map(|x| x % 2 == 0) != Ok(true);
|
||||
let _ = Ok::<usize, ()>(2).map(|x| x.is_multiple_of(2)) != Ok(true);
|
||||
//~^ manual_is_variant_and
|
||||
let _ = Ok::<usize, ()>(2).map(|x| x % 2 == 0) != Ok(true);
|
||||
let _ = Ok::<usize, ()>(2).map(|x| x.is_multiple_of(2)) != Ok(true);
|
||||
//~^ manual_is_variant_and
|
||||
|
||||
// won't fix because the return type of the closure is not `bool`
|
||||
|
|
|
|||
|
|
@ -105,20 +105,20 @@ LL | | .unwrap_or_default();
|
|||
error: called `.map() == Ok()`
|
||||
--> tests/ui/manual_is_variant_and.rs:108:13
|
||||
|
|
||||
LL | let _ = Ok::<usize, ()>(2).map(|x| x % 2 == 0) == Ok(true);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `Ok::<usize, ()>(2).is_ok_and(|x| x % 2 == 0)`
|
||||
LL | let _ = Ok::<usize, ()>(2).map(|x| x.is_multiple_of(2)) == Ok(true);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `Ok::<usize, ()>(2).is_ok_and(|x| x.is_multiple_of(2))`
|
||||
|
||||
error: called `.map() != Ok()`
|
||||
--> tests/ui/manual_is_variant_and.rs:110:13
|
||||
|
|
||||
LL | let _ = Ok::<usize, ()>(2).map(|x| x % 2 == 0) != Ok(true);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `!Ok::<usize, ()>(2).is_ok_and(|x| x % 2 == 0)`
|
||||
LL | let _ = Ok::<usize, ()>(2).map(|x| x.is_multiple_of(2)) != Ok(true);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `!Ok::<usize, ()>(2).is_ok_and(|x| x.is_multiple_of(2))`
|
||||
|
||||
error: called `.map() != Ok()`
|
||||
--> tests/ui/manual_is_variant_and.rs:112:13
|
||||
|
|
||||
LL | let _ = Ok::<usize, ()>(2).map(|x| x % 2 == 0) != Ok(true);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `!Ok::<usize, ()>(2).is_ok_and(|x| x % 2 == 0)`
|
||||
LL | let _ = Ok::<usize, ()>(2).map(|x| x.is_multiple_of(2)) != Ok(true);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `!Ok::<usize, ()>(2).is_ok_and(|x| x.is_multiple_of(2))`
|
||||
|
||||
error: called `map(<f>).unwrap_or_default()` on a `Result` value
|
||||
--> tests/ui/manual_is_variant_and.rs:119:18
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue