Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
68 changes: 24 additions & 44 deletions clippy_lints/src/time_subtraction.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use clippy_config::Conf;
use clippy_utils::diagnostics::{span_lint, span_lint_and_sugg};
use clippy_utils::diagnostics::{span_lint_and_sugg, span_lint_and_then};
use clippy_utils::msrvs::{self, Msrv};
use clippy_utils::res::{MaybeDef, MaybeTypeckRes};
use clippy_utils::sugg::Sugg;
Expand Down Expand Up @@ -109,36 +109,16 @@ impl LateLintPass<'_> for UncheckedTimeSubtraction {
&& !expr.span.from_expansion()
&& self.msrv.meets(cx, msrvs::TRY_FROM)
{
// For chained subtraction like (instant - dur1) - dur2, avoid suggestions
if is_chained_time_subtraction(cx, lhs) {
span_lint(
cx,
UNCHECKED_TIME_SUBTRACTION,
expr.span,
"unchecked subtraction of a 'Duration' from an 'Instant'",
);
} else {
// instant - duration
print_unchecked_duration_subtraction_sugg(cx, lhs, rhs, expr);
}
print_unchecked_duration_subtraction_sugg(cx, lhs, rhs, expr);
}
} else if lhs_ty.is_diag_item(cx, sym::Duration)
}
// duration - duration
else if lhs_ty.is_diag_item(cx, sym::Duration)
&& rhs_ty.is_diag_item(cx, sym::Duration)
&& !expr.span.from_expansion()
&& self.msrv.meets(cx, msrvs::TRY_FROM)
{
// For chained subtraction like (dur1 - dur2) - dur3, avoid suggestions
if is_chained_time_subtraction(cx, lhs) {
span_lint(
cx,
UNCHECKED_TIME_SUBTRACTION,
expr.span,
"unchecked subtraction between 'Duration' values",
);
} else {
// duration - duration
print_unchecked_duration_subtraction_sugg(cx, lhs, rhs, expr);
}
print_unchecked_duration_subtraction_sugg(cx, lhs, rhs, expr);
}
}
}
Expand Down Expand Up @@ -191,26 +171,26 @@ fn print_unchecked_duration_subtraction_sugg(
right_expr: &Expr<'_>,
expr: &Expr<'_>,
) {
let typeck = cx.typeck_results();
let left_ty = typeck.expr_ty(left_expr);

let lint_msg = if left_ty.is_diag_item(cx, sym::Instant) {
"unchecked subtraction of a 'Duration' from an 'Instant'"
} else {
"unchecked subtraction between 'Duration' values"
};

let mut applicability = Applicability::MachineApplicable;
let left_sugg = Sugg::hir_with_applicability(cx, left_expr, "<left>", &mut applicability);
let right_sugg = Sugg::hir_with_applicability(cx, right_expr, "<right>", &mut applicability);

span_lint_and_sugg(
span_lint_and_then(
cx,
UNCHECKED_TIME_SUBTRACTION,
expr.span,
lint_msg,
"try",
format!("{}.checked_sub({}).unwrap()", left_sugg.maybe_paren(), right_sugg),
applicability,
"unchecked subtraction of a `Duration`",
|diag| {
// For chained subtraction, like `(dur1 - dur2) - dur3` or `(instant - dur1) - dur2`,
// avoid suggestions
if !is_chained_time_subtraction(cx, left_expr) {
let mut applicability = Applicability::MachineApplicable;
let left_sugg = Sugg::hir_with_applicability(cx, left_expr, "<left>", &mut applicability);
let right_sugg = Sugg::hir_with_applicability(cx, right_expr, "<right>", &mut applicability);

diag.span_suggestion(
expr.span,
"try",
format!("{}.checked_sub({}).unwrap()", left_sugg.maybe_paren(), right_sugg),
applicability,
);
}
},
);
}
16 changes: 8 additions & 8 deletions tests/ui/unchecked_time_subtraction.stderr
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
error: unchecked subtraction of a 'Duration' from an 'Instant'
error: unchecked subtraction of a `Duration`
--> tests/ui/unchecked_time_subtraction.rs:9:13
|
LL | let _ = _first - second;
Expand All @@ -7,43 +7,43 @@ LL | let _ = _first - second;
= note: `-D clippy::unchecked-time-subtraction` implied by `-D warnings`
= help: to override `-D warnings` add `#[allow(clippy::unchecked_time_subtraction)]`

error: unchecked subtraction of a 'Duration' from an 'Instant'
error: unchecked subtraction of a `Duration`
--> tests/ui/unchecked_time_subtraction.rs:12:13
|
LL | let _ = Instant::now() - Duration::from_secs(5);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Instant::now().checked_sub(Duration::from_secs(5)).unwrap()`

error: unchecked subtraction of a 'Duration' from an 'Instant'
error: unchecked subtraction of a `Duration`
--> tests/ui/unchecked_time_subtraction.rs:15:13
|
LL | let _ = _first - Duration::from_secs(5);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `_first.checked_sub(Duration::from_secs(5)).unwrap()`

error: unchecked subtraction of a 'Duration' from an 'Instant'
error: unchecked subtraction of a `Duration`
--> tests/ui/unchecked_time_subtraction.rs:18:13
|
LL | let _ = Instant::now() - second;
| ^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Instant::now().checked_sub(second).unwrap()`

error: unchecked subtraction between 'Duration' values
error: unchecked subtraction of a `Duration`
--> tests/ui/unchecked_time_subtraction.rs:25:13
|
LL | let _ = dur1 - dur2;
| ^^^^^^^^^^^ help: try: `dur1.checked_sub(dur2).unwrap()`

error: unchecked subtraction between 'Duration' values
error: unchecked subtraction of a `Duration`
--> tests/ui/unchecked_time_subtraction.rs:28:13
|
LL | let _ = Duration::from_secs(10) - Duration::from_secs(5);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Duration::from_secs(10).checked_sub(Duration::from_secs(5)).unwrap()`

error: unchecked subtraction between 'Duration' values
error: unchecked subtraction of a `Duration`
--> tests/ui/unchecked_time_subtraction.rs:31:13
|
LL | let _ = second - dur1;
| ^^^^^^^^^^^^^ help: try: `second.checked_sub(dur1).unwrap()`

error: unchecked subtraction between 'Duration' values
error: unchecked subtraction of a `Duration`
--> tests/ui/unchecked_time_subtraction.rs:35:13
|
LL | let _ = 2 * dur1 - dur2;
Expand Down
8 changes: 4 additions & 4 deletions tests/ui/unchecked_time_subtraction_unfixable.stderr
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
error: unchecked subtraction between 'Duration' values
error: unchecked subtraction of a `Duration`
--> tests/ui/unchecked_time_subtraction_unfixable.rs:12:13
|
LL | let _ = dur1 - dur2 - dur3;
Expand All @@ -7,19 +7,19 @@ LL | let _ = dur1 - dur2 - dur3;
= note: `-D clippy::unchecked-time-subtraction` implied by `-D warnings`
= help: to override `-D warnings` add `#[allow(clippy::unchecked_time_subtraction)]`

error: unchecked subtraction between 'Duration' values
error: unchecked subtraction of a `Duration`
--> tests/ui/unchecked_time_subtraction_unfixable.rs:12:13
|
LL | let _ = dur1 - dur2 - dur3;
| ^^^^^^^^^^^ help: try: `dur1.checked_sub(dur2).unwrap()`

error: unchecked subtraction of a 'Duration' from an 'Instant'
error: unchecked subtraction of a `Duration`
--> tests/ui/unchecked_time_subtraction_unfixable.rs:19:13
|
LL | let _ = instant1 - dur2 - dur3;
| ^^^^^^^^^^^^^^^^^^^^^^

error: unchecked subtraction of a 'Duration' from an 'Instant'
error: unchecked subtraction of a `Duration`
--> tests/ui/unchecked_time_subtraction_unfixable.rs:19:13
|
LL | let _ = instant1 - dur2 - dur3;
Expand Down