Skip to content

Commit 5cbd8df

Browse files
authored
Merge pull request rust-lang#1 from kraktus/pr-9506
Suggestions for rust-lang#9506
2 parents 0a32643 + c349d8a commit 5cbd8df

File tree

3 files changed

+42
-70
lines changed

3 files changed

+42
-70
lines changed

clippy_lints/src/suspicious_xor.rs

Lines changed: 22 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
use clippy_utils::{numeric_literal::NumericLiteral, source::snippet};
2-
use rustc_ast::LitKind;
32
use rustc_errors::Applicability;
43
use rustc_hir::{BinOpKind, Expr, ExprKind, Lit};
5-
use rustc_lint::{LateContext, LateLintPass};
4+
use rustc_lint::{LateContext, LateLintPass, LintContext};
5+
use rustc_middle::lint::in_external_macro;
66
use rustc_session::{declare_lint_pass, declare_tool_lint};
77

88
declare_clippy_lint! {
@@ -27,61 +27,26 @@ declare_lint_pass!(ConfusingXorAndPow => [SUSPICIOUS_XOR]);
2727

2828
impl LateLintPass<'_> for ConfusingXorAndPow {
2929
fn check_expr(&mut self, cx: &LateContext<'_>, expr: &Expr<'_>) {
30-
if_chain! {
31-
if let ExprKind::Binary(op, left, right) = &expr.kind;
32-
if op.node == BinOpKind::BitXor;
33-
if let ExprKind::Lit(litr) = &right.kind;
34-
if let ExprKind::Lit(litl) = &left.kind;
35-
if let snip_left = snippet(cx, litl.span, "..");
36-
if let snip_right = snippet(cx, litr.span, "..");
37-
if get_numlit(litr, &snip_right)
38-
.zip(get_numlit(litl, &snip_left))
39-
.map_or(false, |(a,b)| a.is_decimal() && b.is_decimal());
40-
if let left_val = unwrap_lit_to_dec(left).unwrap_or(0);
41-
if let right_val = unwrap_lit_to_dec(right).unwrap_or(0);
42-
if let suffix = get_numlit(litr, &snip_right).unwrap().suffix.unwrap_or("");
43-
then {
44-
45-
if left_val == 2 &&
46-
(right_val == 8 ||
47-
right_val == 16 ||
48-
right_val == 32 ||
49-
right_val == 64 || right_val == 128)
50-
{
51-
clippy_utils::diagnostics::span_lint_and_sugg(
52-
cx,
53-
SUSPICIOUS_XOR,
54-
expr.span,
55-
"it appears that you are trying to get the maximum value of an integer, but '^' is not exponentiation operator",
56-
"try with",
57-
format!("u{right_val}::MAX"),
58-
Applicability::MaybeIncorrect,
59-
);
60-
} else {
61-
// Even then, warn always.
62-
clippy_utils::diagnostics::span_lint_and_sugg(
63-
cx,
64-
SUSPICIOUS_XOR,
65-
expr.span,
66-
"'^' is not the exponentiation operator",
67-
"did you mean to write",
68-
format!("{left_val}{suffix}.pow({right_val})"),
69-
Applicability::MaybeIncorrect,
70-
);
71-
}
72-
73-
}
74-
}
75-
}
76-
}
77-
78-
fn unwrap_lit_to_dec(expr: &Expr<'_>) -> Option<u128> {
79-
match &expr.kind {
80-
ExprKind::Lit(lit) => match lit.node {
81-
LitKind::Int(num, _) => Some(num),
82-
_ => None,
83-
},
84-
_ => None,
30+
if !in_external_macro(cx.sess(), expr.span) &&
31+
let ExprKind::Binary(op, left, right) = &expr.kind &&
32+
op.node == BinOpKind::BitXor &&
33+
let ExprKind::Lit(lit_left) = &left.kind &&
34+
let ExprKind::Lit(lit_right) = &right.kind &&
35+
let snip_left = snippet(cx, lit_left.span, "..") &&
36+
let snip_right = snippet(cx, lit_right.span, "..") &&
37+
let Some(left_val) = get_numlit(lit_left, &snip_left) &&
38+
let Some(right_val) = get_numlit(lit_right, &snip_right) &&
39+
left_val.is_decimal() && right_val.is_decimal() {
40+
clippy_utils::diagnostics::span_lint_and_sugg(
41+
cx,
42+
SUSPICIOUS_XOR,
43+
expr.span,
44+
"'^' is not the exponentiation operator",
45+
"did you mean to write",
46+
format!("{}.pow({})", left_val.format(), right_val.format()),
47+
Applicability::MaybeIncorrect,
48+
);
49+
}
8550
}
8651
}
8752

tests/ui/suspicious_xor.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ macro_rules! macro_test {
1010

1111
fn main() {
1212
// Should warn:
13+
let _ = 2 ^ 5;
1314
let _ = 2i32 ^ 9i32;
1415
let _ = 2i32 ^ 2i32;
1516
let _ = 50i32 ^ 3i32;

tests/ui/suspicious_xor.stderr

Lines changed: 19 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,40 +1,46 @@
11
error: '^' is not the exponentiation operator
22
--> $DIR/suspicious_xor.rs:13:13
33
|
4-
LL | let _ = 2i32 ^ 9i32;
5-
| ^^^^^^^^^^^ help: did you mean to write: `2i32.pow(9)`
4+
LL | let _ = 2 ^ 5;
5+
| ^^^^^ help: did you mean to write: `2.pow(5)`
66
|
77
= note: `-D clippy::suspicious-xor` implied by `-D warnings`
88

99
error: '^' is not the exponentiation operator
1010
--> $DIR/suspicious_xor.rs:14:13
1111
|
12-
LL | let _ = 2i32 ^ 2i32;
13-
| ^^^^^^^^^^^ help: did you mean to write: `2i32.pow(2)`
12+
LL | let _ = 2i32 ^ 9i32;
13+
| ^^^^^^^^^^^ help: did you mean to write: `2_i32.pow(9_i32)`
1414

1515
error: '^' is not the exponentiation operator
1616
--> $DIR/suspicious_xor.rs:15:13
1717
|
18-
LL | let _ = 50i32 ^ 3i32;
19-
| ^^^^^^^^^^^^ help: did you mean to write: `50i32.pow(3)`
18+
LL | let _ = 2i32 ^ 2i32;
19+
| ^^^^^^^^^^^ help: did you mean to write: `2_i32.pow(2_i32)`
2020

2121
error: '^' is not the exponentiation operator
2222
--> $DIR/suspicious_xor.rs:16:13
2323
|
24-
LL | let _ = 5i32 ^ 8i32;
25-
| ^^^^^^^^^^^ help: did you mean to write: `5i32.pow(8)`
24+
LL | let _ = 50i32 ^ 3i32;
25+
| ^^^^^^^^^^^^ help: did you mean to write: `50_i32.pow(3_i32)`
2626

27-
error: it appears that you are trying to get the maximum value of an integer, but '^' is not exponentiation operator
27+
error: '^' is not the exponentiation operator
2828
--> $DIR/suspicious_xor.rs:17:13
2929
|
30-
LL | let _ = 2i32 ^ 32i32;
31-
| ^^^^^^^^^^^^ help: try with: `u32::MAX`
30+
LL | let _ = 5i32 ^ 8i32;
31+
| ^^^^^^^^^^^ help: did you mean to write: `5_i32.pow(8_i32)`
3232

3333
error: '^' is not the exponentiation operator
3434
--> $DIR/suspicious_xor.rs:18:13
3535
|
36+
LL | let _ = 2i32 ^ 32i32;
37+
| ^^^^^^^^^^^^ help: did you mean to write: `2_i32.pow(32_i32)`
38+
39+
error: '^' is not the exponentiation operator
40+
--> $DIR/suspicious_xor.rs:19:13
41+
|
3642
LL | let _ = 2i32 ^ macro_test!();
37-
| ^^^^^^^^^^^^^^^^^^^^ help: did you mean to write: `2.pow(13)`
43+
| ^^^^^^^^^^^^^^^^^^^^ help: did you mean to write: `2_i32.pow(13)`
3844

39-
error: aborting due to 6 previous errors
45+
error: aborting due to 7 previous errors
4046

0 commit comments

Comments
 (0)