]> git.proxmox.com Git - rustc.git/blame - src/tools/clippy/clippy_lints/src/zero_div_zero.rs
New upstream version 1.28.0~beta.14+dfsg1
[rustc.git] / src / tools / clippy / clippy_lints / src / zero_div_zero.rs
CommitLineData
0531ce1d 1use consts::{constant_simple, Constant};
ea8adc8c
XL
2use rustc::lint::*;
3use rustc::hir::*;
4use utils::span_help_and_lint;
5
6/// **What it does:** Checks for `0.0 / 0.0`.
7///
8/// **Why is this bad?** It's less readable than `std::f32::NAN` or
9/// `std::f64::NAN`.
10///
11/// **Known problems:** None.
12///
13/// **Example:**
14/// ```rust
15/// 0.0f32 / 0.0
16/// ```
0531ce1d 17declare_clippy_lint! {
ea8adc8c 18 pub ZERO_DIVIDED_BY_ZERO,
0531ce1d 19 complexity,
ea8adc8c
XL
20 "usage of `0.0 / 0.0` to obtain NaN instead of std::f32::NaN or std::f64::NaN"
21}
22
23pub struct Pass;
24
25impl LintPass for Pass {
26 fn get_lints(&self) -> LintArray {
27 lint_array!(ZERO_DIVIDED_BY_ZERO)
28 }
29}
30
31impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass {
32 fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr) {
33 // check for instances of 0.0/0.0
abe05a73
XL
34 if_chain! {
35 if let ExprBinary(ref op, ref left, ref right) = expr.node;
36 if let BinOp_::BiDiv = op.node;
ea8adc8c
XL
37 // TODO - constant_simple does not fold many operations involving floats.
38 // That's probably fine for this lint - it's pretty unlikely that someone would
39 // do something like 0.0/(2.0 - 2.0), but it would be nice to warn on that case too.
94b46f34
XL
40 if let Some(lhs_value) = constant_simple(cx, cx.tables, left);
41 if let Some(rhs_value) = constant_simple(cx, cx.tables, right);
0531ce1d
XL
42 if Constant::F32(0.0) == lhs_value || Constant::F64(0.0) == lhs_value;
43 if Constant::F32(0.0) == rhs_value || Constant::F64(0.0) == rhs_value;
abe05a73
XL
44 then {
45 // since we're about to suggest a use of std::f32::NaN or std::f64::NaN,
46 // match the precision of the literals that are given.
0531ce1d
XL
47 let float_type = match (lhs_value, rhs_value) {
48 (Constant::F64(_), _)
49 | (_, Constant::F64(_)) => "f64",
abe05a73
XL
50 _ => "f32"
51 };
52 span_help_and_lint(
53 cx,
54 ZERO_DIVIDED_BY_ZERO,
55 expr.span,
56 "constant division of 0.0 with 0.0 will always result in NaN",
57 &format!(
58 "Consider using `std::{}::NAN` if you would like a constant representing NaN",
59 float_type,
60 ),
61 );
62 }
63 }
ea8adc8c
XL
64 }
65}