|
1 | 1 | use clippy_utils::consts::{constant_simple, Constant};
|
2 | 2 | use clippy_utils::diagnostics::span_lint;
|
| 3 | +use clippy_utils::ty::same_type_and_consts; |
| 4 | + |
3 | 5 | use rustc_hir::{BinOpKind, Expr, ExprKind};
|
4 | 6 | use rustc_lint::{LateContext, LateLintPass};
|
| 7 | +use rustc_middle::ty::TypeckResults; |
5 | 8 | use rustc_session::{declare_lint_pass, declare_tool_lint};
|
6 |
| -use rustc_span::source_map::Span; |
7 | 9 |
|
8 | 10 | declare_clippy_lint! {
|
9 | 11 | /// ### What it does
|
@@ -35,24 +37,34 @@ impl<'tcx> LateLintPass<'tcx> for ErasingOp {
|
35 | 37 | return;
|
36 | 38 | }
|
37 | 39 | if let ExprKind::Binary(ref cmp, left, right) = e.kind {
|
| 40 | + let tck = cx.typeck_results(); |
38 | 41 | match cmp.node {
|
39 | 42 | BinOpKind::Mul | BinOpKind::BitAnd => {
|
40 |
| - check(cx, left, e.span); |
41 |
| - check(cx, right, e.span); |
| 43 | + check(cx, tck, left, right, e); |
| 44 | + check(cx, tck, right, left, e); |
42 | 45 | },
|
43 |
| - BinOpKind::Div => check(cx, left, e.span), |
| 46 | + BinOpKind::Div => check(cx, tck, left, right, e), |
44 | 47 | _ => (),
|
45 | 48 | }
|
46 | 49 | }
|
47 | 50 | }
|
48 | 51 | }
|
49 | 52 |
|
50 |
| -fn check(cx: &LateContext<'_>, e: &Expr<'_>, span: Span) { |
51 |
| - if constant_simple(cx, cx.typeck_results(), e) == Some(Constant::Int(0)) { |
| 53 | +fn different_types(tck: &TypeckResults<'tcx>, input: &'tcx Expr<'_>, output: &'tcx Expr<'_>) -> bool { |
| 54 | + let input_ty = tck.expr_ty(input).peel_refs(); |
| 55 | + let output_ty = tck.expr_ty(output).peel_refs(); |
| 56 | + !same_type_and_consts(input_ty, output_ty) |
| 57 | +} |
| 58 | + |
| 59 | +fn check(cx: &LateContext<'cx>, tck: &TypeckResults<'cx>, op: &Expr<'cx>, other: &Expr<'cx>, parent: &Expr<'cx>) { |
| 60 | + if constant_simple(cx, tck, op) == Some(Constant::Int(0)) { |
| 61 | + if different_types(tck, other, parent) { |
| 62 | + return; |
| 63 | + } |
52 | 64 | span_lint(
|
53 | 65 | cx,
|
54 | 66 | ERASING_OP,
|
55 |
| - span, |
| 67 | + parent.span, |
56 | 68 | "this operation will always return zero. This is likely not the intended outcome",
|
57 | 69 | );
|
58 | 70 | }
|
|
0 commit comments