From 725e9621d0ea1f07ad75d5f26193dfba72ee73b2 Mon Sep 17 00:00:00 2001 From: Michael Wright Date: Tue, 12 Jun 2018 08:25:10 +0200 Subject: [PATCH] duration_subsec: Add check for `subsec_micros` --- clippy_lints/src/duration_subsec.rs | 17 ++++++++------- tests/ui/duration_subsec.rs | 11 +++++----- tests/ui/duration_subsec.stderr | 32 +++++++++++++++++------------ 3 files changed, 33 insertions(+), 27 deletions(-) diff --git a/clippy_lints/src/duration_subsec.rs b/clippy_lints/src/duration_subsec.rs index fced237b6..5f34803c8 100644 --- a/clippy_lints/src/duration_subsec.rs +++ b/clippy_lints/src/duration_subsec.rs @@ -6,11 +6,11 @@ use crate::consts::{constant, Constant}; use crate::utils::paths; use crate::utils::{match_type, snippet, span_lint_and_sugg, walk_ptrs_ty}; -/// **What it does:** Checks for calculation of subsecond microseconds or milliseconds from -/// `Duration::subsec_nanos()`. +/// **What it does:** Checks for calculation of subsecond microseconds or milliseconds +/// from other `Duration` methods. /// /// **Why is this bad?** It's more concise to call `Duration::subsec_micros()` or -/// `Duration::subsec_millis()`. +/// `Duration::subsec_millis()` than to calculate them. /// /// **Known problems:** None. /// @@ -23,7 +23,7 @@ use crate::utils::{match_type, snippet, span_lint_and_sugg, walk_ptrs_ty}; declare_clippy_lint! { pub DURATION_SUBSEC, complexity, - "checks for `dur.subsec_nanos() / 1_000` or `dur.subsec_nanos() / 1_000_000`" + "checks for calculation of subsecond microseconds or milliseconds" } #[derive(Copy, Clone)] @@ -40,16 +40,15 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for DurationSubsec { if_chain! { if let ExprBinary(Spanned { node: BiDiv, .. }, ref left, ref right) = expr.node; if let ExprMethodCall(ref method_path, _ , ref args) = left.node; - if method_path.name == "subsec_nanos"; if match_type(cx, walk_ptrs_ty(cx.tables.expr_ty(&args[0])), &paths::DURATION); if let Some((Constant::Int(divisor), _)) = constant(cx, cx.tables, right); then { - let suggested_fn = match divisor { - 1_000 => "subsec_micros", - 1_000_000 => "subsec_millis", + let suggested_fn = match (method_path.name.as_str().as_ref(), divisor) { + ("subsec_micros", 1_000) => "subsec_millis", + ("subsec_nanos", 1_000) => "subsec_micros", + ("subsec_nanos", 1_000_000) => "subsec_millis", _ => return, }; - span_lint_and_sugg( cx, DURATION_SUBSEC, diff --git a/tests/ui/duration_subsec.rs b/tests/ui/duration_subsec.rs index 5b87d6964..8c75c5f2f 100644 --- a/tests/ui/duration_subsec.rs +++ b/tests/ui/duration_subsec.rs @@ -5,14 +5,16 @@ use std::time::Duration; fn main() { let dur = Duration::new(5, 0); + let bad_millis_1 = dur.subsec_micros() / 1_000; + let bad_millis_2 = dur.subsec_nanos() / 1_000_000; + let good_millis = dur.subsec_millis(); + assert_eq!(bad_millis_1, good_millis); + assert_eq!(bad_millis_2, good_millis); + let bad_micros = dur.subsec_nanos() / 1_000; let good_micros = dur.subsec_micros(); assert_eq!(bad_micros, good_micros); - let bad_millis = dur.subsec_nanos() / 1_000_000; - let good_millis = dur.subsec_millis(); - assert_eq!(bad_millis, good_millis); - // Handle refs let _ = (&dur).subsec_nanos() / 1_000; @@ -22,5 +24,4 @@ fn main() { // Other literals aren't linted let _ = dur.subsec_nanos() / 699; - } diff --git a/tests/ui/duration_subsec.stderr b/tests/ui/duration_subsec.stderr index f77aa2172..a1aacec3a 100644 --- a/tests/ui/duration_subsec.stderr +++ b/tests/ui/duration_subsec.stderr @@ -1,28 +1,34 @@ -error: Calling `subsec_micros()` is more concise than this calculation - --> $DIR/duration_subsec.rs:8:22 +error: Calling `subsec_millis()` is more concise than this calculation + --> $DIR/duration_subsec.rs:8:24 | -8 | let bad_micros = dur.subsec_nanos() / 1_000; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `dur.subsec_micros()` +8 | let bad_millis_1 = dur.subsec_micros() / 1_000; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `dur.subsec_millis()` | = note: `-D duration-subsec` implied by `-D warnings` error: Calling `subsec_millis()` is more concise than this calculation - --> $DIR/duration_subsec.rs:12:22 - | -12 | let bad_millis = dur.subsec_nanos() / 1_000_000; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `dur.subsec_millis()` + --> $DIR/duration_subsec.rs:9:24 + | +9 | let bad_millis_2 = dur.subsec_nanos() / 1_000_000; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `dur.subsec_millis()` error: Calling `subsec_micros()` is more concise than this calculation - --> $DIR/duration_subsec.rs:17:13 + --> $DIR/duration_subsec.rs:14:22 | -17 | let _ = (&dur).subsec_nanos() / 1_000; +14 | let bad_micros = dur.subsec_nanos() / 1_000; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `dur.subsec_micros()` + +error: Calling `subsec_micros()` is more concise than this calculation + --> $DIR/duration_subsec.rs:19:13 + | +19 | let _ = (&dur).subsec_nanos() / 1_000; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `(&dur).subsec_micros()` error: Calling `subsec_micros()` is more concise than this calculation - --> $DIR/duration_subsec.rs:21:13 + --> $DIR/duration_subsec.rs:23:13 | -21 | let _ = dur.subsec_nanos() / NANOS_IN_MICRO; +23 | let _ = dur.subsec_nanos() / NANOS_IN_MICRO; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `dur.subsec_micros()` -error: aborting due to 4 previous errors +error: aborting due to 5 previous errors