Skip to content

Commit c75f6c7

Browse files
committed
Move DurationSubsec into Operators lint pass
1 parent 41c6ede commit c75f6c7

File tree

7 files changed

+78
-78
lines changed

7 files changed

+78
-78
lines changed

clippy_lints/src/duration_subsec.rs

Lines changed: 0 additions & 73 deletions
This file was deleted.

clippy_lints/src/lib.register_all.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,6 @@ store.register_group(true, "clippy::all", Some("clippy_all"), vec![
5656
LintId::of(drop_forget_ref::FORGET_REF),
5757
LintId::of(drop_forget_ref::UNDROPPED_MANUALLY_DROPS),
5858
LintId::of(duplicate_mod::DUPLICATE_MOD),
59-
LintId::of(duration_subsec::DURATION_SUBSEC),
6059
LintId::of(entry::MAP_ENTRY),
6160
LintId::of(enum_clike::ENUM_CLIKE_UNPORTABLE_VARIANT),
6261
LintId::of(enum_variants::ENUM_VARIANT_NAMES),
@@ -251,6 +250,7 @@ store.register_group(true, "clippy::all", Some("clippy_all"), vec![
251250
LintId::of(operators::ASSIGN_OP_PATTERN),
252251
LintId::of(operators::BAD_BIT_MASK),
253252
LintId::of(operators::DOUBLE_COMPARISONS),
253+
LintId::of(operators::DURATION_SUBSEC),
254254
LintId::of(operators::INEFFECTIVE_BIT_MASK),
255255
LintId::of(operators::MISREFACTORED_ASSIGN_OP),
256256
LintId::of(option_env_unwrap::OPTION_ENV_UNWRAP),

clippy_lints/src/lib.register_complexity.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ store.register_group(true, "clippy::complexity", Some("clippy_complexity"), vec!
1010
LintId::of(casts::UNNECESSARY_CAST),
1111
LintId::of(derivable_impls::DERIVABLE_IMPLS),
1212
LintId::of(double_parens::DOUBLE_PARENS),
13-
LintId::of(duration_subsec::DURATION_SUBSEC),
1413
LintId::of(explicit_write::EXPLICIT_WRITE),
1514
LintId::of(format::USELESS_FORMAT),
1615
LintId::of(functions::TOO_MANY_ARGUMENTS),
@@ -68,6 +67,7 @@ store.register_group(true, "clippy::complexity", Some("clippy_complexity"), vec!
6867
LintId::of(no_effect::NO_EFFECT),
6968
LintId::of(no_effect::UNNECESSARY_OPERATION),
7069
LintId::of(operators::DOUBLE_COMPARISONS),
70+
LintId::of(operators::DURATION_SUBSEC),
7171
LintId::of(overflow_check_conditional::OVERFLOW_CHECK_CONDITIONAL),
7272
LintId::of(partialeq_ne_impl::PARTIALEQ_NE_IMPL),
7373
LintId::of(precedence::PRECEDENCE),

clippy_lints/src/lib.register_lints.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,6 @@ store.register_lints(&[
127127
drop_forget_ref::FORGET_REF,
128128
drop_forget_ref::UNDROPPED_MANUALLY_DROPS,
129129
duplicate_mod::DUPLICATE_MOD,
130-
duration_subsec::DURATION_SUBSEC,
131130
else_if_without_else::ELSE_IF_WITHOUT_ELSE,
132131
empty_drop::EMPTY_DROP,
133132
empty_enum::EMPTY_ENUM,
@@ -420,6 +419,7 @@ store.register_lints(&[
420419
operators::ASSIGN_OP_PATTERN,
421420
operators::BAD_BIT_MASK,
422421
operators::DOUBLE_COMPARISONS,
422+
operators::DURATION_SUBSEC,
423423
operators::FLOAT_ARITHMETIC,
424424
operators::INEFFECTIVE_BIT_MASK,
425425
operators::INTEGER_ARITHMETIC,

clippy_lints/src/lib.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -209,7 +209,6 @@ mod doc_link_with_quotes;
209209
mod double_parens;
210210
mod drop_forget_ref;
211211
mod duplicate_mod;
212-
mod duration_subsec;
213212
mod else_if_without_else;
214213
mod empty_drop;
215214
mod empty_enum;
@@ -707,7 +706,6 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
707706
store.register_late_pass(|| Box::new(inherent_impl::MultipleInherentImpl));
708707
store.register_late_pass(|| Box::new(neg_cmp_op_on_partial_ord::NoNegCompOpForPartialOrd));
709708
store.register_late_pass(|| Box::new(unwrap::Unwrap));
710-
store.register_late_pass(|| Box::new(duration_subsec::DurationSubsec));
711709
store.register_late_pass(|| Box::new(indexing_slicing::IndexingSlicing));
712710
store.register_late_pass(|| Box::new(non_copy_const::NonCopyConst));
713711
store.register_late_pass(|| Box::new(ptr_offset_with_cast::PtrOffsetWithCast));
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
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 rustc_errors::Applicability;
6+
use rustc_hir::{BinOpKind, Expr, ExprKind};
7+
use rustc_lint::LateContext;
8+
use rustc_span::sym;
9+
10+
use super::DURATION_SUBSEC;
11+
12+
pub(crate) fn check<'tcx>(
13+
cx: &LateContext<'tcx>,
14+
expr: &'tcx Expr<'_>,
15+
op: BinOpKind,
16+
left: &'tcx Expr<'_>,
17+
right: &'tcx Expr<'_>,
18+
) {
19+
if op == BinOpKind::Div
20+
&& let ExprKind::MethodCall(method_path, [self_arg], _) = left.kind
21+
&& is_type_diagnostic_item(cx, cx.typeck_results().expr_ty(self_arg).peel_refs(), sym::Duration)
22+
&& let Some((Constant::Int(divisor), _)) = constant(cx, cx.typeck_results(), right)
23+
{
24+
let suggested_fn = match (method_path.ident.as_str(), divisor) {
25+
("subsec_micros", 1_000) | ("subsec_nanos", 1_000_000) => "subsec_millis",
26+
("subsec_nanos", 1_000) => "subsec_micros",
27+
_ => return,
28+
};
29+
let mut applicability = Applicability::MachineApplicable;
30+
span_lint_and_sugg(
31+
cx,
32+
DURATION_SUBSEC,
33+
expr.span,
34+
&format!("calling `{}()` is more concise than this calculation", suggested_fn),
35+
"try",
36+
format!(
37+
"{}.{}()",
38+
snippet_with_applicability(cx, self_arg.span, "_", &mut applicability),
39+
suggested_fn
40+
),
41+
applicability,
42+
);
43+
}
44+
}

clippy_lints/src/operators/mod.rs

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ mod arithmetic;
77
mod assign_op_pattern;
88
mod bit_mask;
99
mod double_comparison;
10+
mod duration_subsec;
1011
mod misrefactored_assign_op;
1112
mod verbose_bit_mask;
1213

@@ -265,6 +266,34 @@ declare_clippy_lint! {
265266
"unnecessary double comparisons that can be simplified"
266267
}
267268

269+
declare_clippy_lint! {
270+
/// ### What it does
271+
/// Checks for calculation of subsecond microseconds or milliseconds
272+
/// from other `Duration` methods.
273+
///
274+
/// ### Why is this bad?
275+
/// It's more concise to call `Duration::subsec_micros()` or
276+
/// `Duration::subsec_millis()` than to calculate them.
277+
///
278+
/// ### Example
279+
/// ```rust
280+
/// # use std::time::Duration;
281+
/// let dur = Duration::new(5, 0);
282+
///
283+
/// // Bad
284+
/// let _micros = dur.subsec_nanos() / 1_000;
285+
/// let _millis = dur.subsec_nanos() / 1_000_000;
286+
///
287+
/// // Good
288+
/// let _micros = dur.subsec_micros();
289+
/// let _millis = dur.subsec_millis();
290+
/// ```
291+
#[clippy::version = "pre 1.29.0"]
292+
pub DURATION_SUBSEC,
293+
complexity,
294+
"checks for calculation of subsecond microseconds or milliseconds"
295+
}
296+
268297
pub struct Operators {
269298
arithmetic_context: arithmetic::Context,
270299
verbose_bit_mask_threshold: u64,
@@ -279,6 +308,7 @@ impl_lint_pass!(Operators => [
279308
INEFFECTIVE_BIT_MASK,
280309
VERBOSE_BIT_MASK,
281310
DOUBLE_COMPARISONS,
311+
DURATION_SUBSEC,
282312
]);
283313
impl Operators {
284314
pub fn new(verbose_bit_mask_threshold: u64) -> Self {
@@ -299,6 +329,7 @@ impl<'tcx> LateLintPass<'tcx> for Operators {
299329
bit_mask::check(cx, e, op.node, lhs, rhs);
300330
verbose_bit_mask::check(cx, e, op.node, lhs, rhs, self.verbose_bit_mask_threshold);
301331
double_comparison::check(cx, op.node, lhs, rhs, e.span);
332+
duration_subsec::check(cx, e, op.node, lhs, rhs);
302333
},
303334
ExprKind::AssignOp(op, lhs, rhs) => {
304335
self.arithmetic_context.check_binary(cx, e, op.node, lhs, rhs);

0 commit comments

Comments
 (0)