diff --git a/clippy_lints/src/suspicious_xor_used_as_pow.rs b/clippy_lints/src/suspicious_xor_used_as_pow.rs index 6fa49afe0ecd..8e156b8829b9 100644 --- a/clippy_lints/src/suspicious_xor_used_as_pow.rs +++ b/clippy_lints/src/suspicious_xor_used_as_pow.rs @@ -1,5 +1,7 @@ +use clippy_utils::diagnostics::span_lint_and_sugg; use clippy_utils::numeric_literal::NumericLiteral; -use clippy_utils::source::snippet_with_context; +use clippy_utils::source::snippet; +use rustc_ast::LitKind; use rustc_errors::Applicability; use rustc_hir::{BinOpKind, Expr, ExprKind}; use rustc_lint::{LateContext, LateLintPass, LintContext}; @@ -28,27 +30,29 @@ declare_lint_pass!(ConfusingXorAndPow => [SUSPICIOUS_XOR_USED_AS_POW]); impl LateLintPass<'_> for ConfusingXorAndPow { fn check_expr(&mut self, cx: &LateContext<'_>, expr: &Expr<'_>) { - if !in_external_macro(cx.sess(), expr.span) && - let ExprKind::Binary(op, left, right) = &expr.kind && - op.node == BinOpKind::BitXor && - left.span.ctxt() == right.span.ctxt() && - let ExprKind::Lit(lit_left) = &left.kind && - let ExprKind::Lit(lit_right) = &right.kind && - let snip_left = snippet_with_context(cx, lit_left.span, lit_left.span.ctxt(), "..", &mut Applicability::MaybeIncorrect) && - let snip_right = snippet_with_context(cx, lit_right.span, lit_right.span.ctxt(), "..", &mut Applicability::MaybeIncorrect) && - let Some(left_val) = NumericLiteral::from_lit_kind(&snip_left.0, &lit_left.node) && - let Some(right_val) = NumericLiteral::from_lit_kind(&snip_right.0, &lit_right.node) && - left_val.is_decimal() && - right_val.is_decimal() { - clippy_utils::diagnostics::span_lint_and_sugg( - cx, - SUSPICIOUS_XOR_USED_AS_POW, - expr.span, - "`^` is not the exponentiation operator", - "did you mean to write", - format!("{}.pow({})", left_val.format(), right_val.format()), - Applicability::MaybeIncorrect, - ); + if !in_external_macro(cx.sess(), expr.span) + && let ExprKind::Binary(op, left, right) = &expr.kind + && op.node == BinOpKind::BitXor + && left.span.ctxt() == right.span.ctxt() + && let ExprKind::Lit(lit_left) = &left.kind + && let ExprKind::Lit(lit_right) = &right.kind + && matches!(lit_right.node, LitKind::Int(..) | LitKind::Float(..)) + && matches!(lit_left.node, LitKind::Int(..) | LitKind::Float(..)) + && NumericLiteral::from_lit_kind(&snippet(cx, lit_right.span, ".."), &lit_right.node).is_some_and(|x| x.is_decimal()) + { + span_lint_and_sugg( + cx, + SUSPICIOUS_XOR_USED_AS_POW, + expr.span, + "`^` is not the exponentiation operator", + "did you mean to write", + format!( + "{}.pow({})", + lit_left.node, + lit_right.node + ), + Applicability::MaybeIncorrect, + ); } } } diff --git a/tests/ui/suspicious_xor_used_as_pow.stderr b/tests/ui/suspicious_xor_used_as_pow.stderr index 8bb3c8fbeebd..d93a55ba9065 100644 --- a/tests/ui/suspicious_xor_used_as_pow.stderr +++ b/tests/ui/suspicious_xor_used_as_pow.stderr @@ -10,31 +10,31 @@ error: `^` is not the exponentiation operator --> $DIR/suspicious_xor_used_as_pow.rs:20:13 | LL | let _ = 2i32 ^ 9i32; - | ^^^^^^^^^^^ help: did you mean to write: `2_i32.pow(9_i32)` + | ^^^^^^^^^^^ help: did you mean to write: `2i32.pow(9i32)` error: `^` is not the exponentiation operator --> $DIR/suspicious_xor_used_as_pow.rs:21:13 | LL | let _ = 2i32 ^ 2i32; - | ^^^^^^^^^^^ help: did you mean to write: `2_i32.pow(2_i32)` + | ^^^^^^^^^^^ help: did you mean to write: `2i32.pow(2i32)` error: `^` is not the exponentiation operator --> $DIR/suspicious_xor_used_as_pow.rs:22:13 | LL | let _ = 50i32 ^ 3i32; - | ^^^^^^^^^^^^ help: did you mean to write: `50_i32.pow(3_i32)` + | ^^^^^^^^^^^^ help: did you mean to write: `50i32.pow(3i32)` error: `^` is not the exponentiation operator --> $DIR/suspicious_xor_used_as_pow.rs:23:13 | LL | let _ = 5i32 ^ 8i32; - | ^^^^^^^^^^^ help: did you mean to write: `5_i32.pow(8_i32)` + | ^^^^^^^^^^^ help: did you mean to write: `5i32.pow(8i32)` error: `^` is not the exponentiation operator --> $DIR/suspicious_xor_used_as_pow.rs:24:13 | LL | let _ = 2i32 ^ 32i32; - | ^^^^^^^^^^^^ help: did you mean to write: `2_i32.pow(32_i32)` + | ^^^^^^^^^^^^ help: did you mean to write: `2i32.pow(32i32)` error: `^` is not the exponentiation operator --> $DIR/suspicious_xor_used_as_pow.rs:13:9