1 use clippy_utils
::consts
::{constant, Constant}
;
2 use clippy_utils
::diagnostics
::span_lint_and_sugg
;
3 use clippy_utils
::source
::snippet_with_applicability
;
4 use clippy_utils
::ty
::is_type_diagnostic_item
;
5 use if_chain
::if_chain
;
6 use rustc_errors
::Applicability
;
7 use rustc_hir
::{BinOpKind, Expr, ExprKind}
;
8 use rustc_lint
::{LateContext, LateLintPass}
;
9 use rustc_session
::{declare_lint_pass, declare_tool_lint}
;
10 use rustc_span
::source_map
::Spanned
;
13 declare_clippy_lint
! {
15 /// Checks for calculation of subsecond microseconds or milliseconds
16 /// from other `Duration` methods.
18 /// ### Why is this bad?
19 /// It's more concise to call `Duration::subsec_micros()` or
20 /// `Duration::subsec_millis()` than to calculate them.
24 /// # use std::time::Duration;
25 /// let dur = Duration::new(5, 0);
28 /// let _micros = dur.subsec_nanos() / 1_000;
29 /// let _millis = dur.subsec_nanos() / 1_000_000;
32 /// let _micros = dur.subsec_micros();
33 /// let _millis = dur.subsec_millis();
35 #[clippy::version = "pre 1.29.0"]
38 "checks for calculation of subsecond microseconds or milliseconds"
41 declare_lint_pass
!(DurationSubsec
=> [DURATION_SUBSEC
]);
43 impl<'tcx
> LateLintPass
<'tcx
> for DurationSubsec
{
44 fn check_expr(&mut self, cx
: &LateContext
<'tcx
>, expr
: &'tcx Expr
<'_
>) {
46 if let ExprKind
::Binary(Spanned { node: BinOpKind::Div, .. }
, left
, right
) = expr
.kind
;
47 if let ExprKind
::MethodCall(method_path
, args
, _
) = left
.kind
;
48 if is_type_diagnostic_item(cx
, cx
.typeck_results().expr_ty(&args
[0]).peel_refs(), sym
::Duration
);
49 if let Some((Constant
::Int(divisor
), _
)) = constant(cx
, cx
.typeck_results(), right
);
51 let suggested_fn
= match (method_path
.ident
.as_str(), divisor
) {
52 ("subsec_micros", 1_000) | ("subsec_nanos", 1_000_000) => "subsec_millis",
53 ("subsec_nanos", 1_000) => "subsec_micros",
56 let mut applicability
= Applicability
::MachineApplicable
;
61 &format
!("calling `{}()` is more concise than this calculation", suggested_fn
),
65 snippet_with_applicability(cx
, args
[0].span
, "_", &mut applicability
),