|
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