Skip to content

Commit 475f28e

Browse files
declanvkblyxyas
andcommitted
Apply suggestions from code review
- I applied about half of these from the UI - Made more parts of the example code visible - Added test on duration ref - Rebased over conflict - Moved to the `style` lint group Co-authored-by: Alejandra González <[email protected]>
1 parent e5fd746 commit 475f28e

4 files changed

+33
-13
lines changed

clippy_lints/src/duration_to_float_precision_loss.rs

+15-11
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,15 @@
11
use clippy_config::msrvs::{self, Msrv};
22
use clippy_utils::consts::{constant, Constant};
33
use clippy_utils::diagnostics::span_lint_and_sugg;
4+
use clippy_utils::is_from_proc_macro;
45
use clippy_utils::source::snippet_with_applicability;
56
use clippy_utils::ty::is_type_diagnostic_item;
67
use rustc_errors::Applicability;
78
use rustc_hir::{BinOpKind, Expr, ExprKind};
89
use rustc_lint::{LateContext, LateLintPass, LintContext};
910
use rustc_middle::lint::in_external_macro;
1011
use rustc_middle::ty::{self, FloatTy};
12+
use rustc_session::impl_lint_pass;
1113
use rustc_span::{sym, Span};
1214

1315
declare_clippy_lint! {
@@ -16,50 +18,50 @@ declare_clippy_lint! {
1618
/// precision is lost.
1719
///
1820
/// ### Why is this bad?
19-
/// This can be bad if the user wanted to retain the full precision of the duration.
21+
/// Retaining the full precision of a duration is usually desired.
2022
///
2123
/// ### Example
2224
/// ```no_run
2325
/// # use std::time::Duration;
24-
/// # let duration = Duration::from_nanos(1234500000);
26+
/// let duration = Duration::from_nanos(1234500000);
2527
/// let _ = duration.as_millis() as f64;
2628
/// ```
2729
///
2830
/// Use instead:
2931
///
3032
/// ```no_run
3133
/// # use std::time::Duration;
32-
/// # let duration = Duration::from_nanos(1234500000);
34+
/// let duration = Duration::from_nanos(1234500000);
3335
/// let _ = duration.as_secs_f64() * 1000.0;
3436
/// ```
3537
///
3638
/// Another motivating example happens when calculating number of seconds as a float with millisecond precision:
3739
///
3840
/// ```no_run
3941
/// # use std::time::Duration;
40-
/// # let duration = Duration::from_nanos(1234500000);
42+
/// let duration = Duration::from_nanos(1234500000);
4143
/// let _ = duration.as_millis() as f64 / 1000.0;
4244
/// ```
4345
///
4446
/// Use instead:
4547
///
4648
/// ```no_run
4749
/// # use std::time::Duration;
48-
/// # let duration = Duration::from_nanos(1234500000);
50+
/// let duration = Duration::from_nanos(1234500000);
4951
/// let _ = duration.as_secs_f64();
5052
/// ```
51-
#[clippy::version = "1.78.0"]
53+
#[clippy::version = "1.79.0"]
5254
pub DURATION_TO_FLOAT_PRECISION_LOSS,
53-
nursery,
55+
style,
5456
"conversion from duration to float that cause loss of precision"
5557
}
5658

5759
/// This struct implements the logic needed to apply the lint
5860
#[derive(Debug)]
5961
pub struct DurationToFloatPrecisionLoss {
60-
// This vector is used to prevent applying the lint to a sub-expression
62+
/// This vector is used to prevent applying the lint to a sub-expression
6163
lint_applications: Vec<Span>,
62-
// `as_secs_f64` isn't applicable until 1.38.0
64+
/// `as_secs_f64` isn't applicable until 1.38.0
6365
msrv: Msrv,
6466
}
6567

@@ -84,7 +86,7 @@ impl DurationToFloatPrecisionLoss {
8486
}
8587
}
8688

87-
rustc_session::impl_lint_pass!(DurationToFloatPrecisionLoss => [DURATION_TO_FLOAT_PRECISION_LOSS]);
89+
impl_lint_pass!(DurationToFloatPrecisionLoss => [DURATION_TO_FLOAT_PRECISION_LOSS]);
8890

8991
impl<'tcx> LateLintPass<'tcx> for DurationToFloatPrecisionLoss {
9092
fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
@@ -211,7 +213,9 @@ fn check_cast<'tcx>(
211213
expr: &'tcx Expr<'_>,
212214
duration_expr: &'tcx Expr<'_>,
213215
) -> Option<LintApplicableSite> {
214-
if let ExprKind::MethodCall(method_path, method_receiver_expr, [], _) = duration_expr.kind {
216+
if let ExprKind::MethodCall(method_path, method_receiver_expr, [], _) = duration_expr.kind
217+
&& !is_from_proc_macro(cx, expr)
218+
{
215219
let method_receiver_ty = cx.typeck_results().expr_ty(method_receiver_expr);
216220
if is_type_diagnostic_item(cx, method_receiver_ty.peel_refs(), sym::Duration) {
217221
let cast_expr_ty = cx.typeck_results().expr_ty(expr);

tests/ui/duration_to_float_precision_loss.fixed

+5
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,11 @@ fn main() {
3535
let float_micros = DURATION.as_nanos() as f64 / 1_000.0;
3636

3737
let float_millis = DURATION.as_nanos() as f64 / 1_000_000.0;
38+
39+
{
40+
let dur = &&DURATION;
41+
let float_millis = dur.as_secs_f64();
42+
}
3843
}
3944

4045
#[clippy::msrv = "1.37"]

tests/ui/duration_to_float_precision_loss.rs

+5
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,11 @@ fn main() {
3535
let float_micros = DURATION.as_nanos() as f64 / 1_000.0;
3636

3737
let float_millis = DURATION.as_nanos() as f64 / 1_000_000.0;
38+
39+
{
40+
let dur = &&DURATION;
41+
let float_millis = dur.as_millis() as f64 / 1_000.0;
42+
}
3843
}
3944

4045
#[clippy::msrv = "1.37"]

tests/ui/duration_to_float_precision_loss.stderr

+8-2
Original file line numberDiff line numberDiff line change
@@ -50,10 +50,16 @@ LL | let float_micros = DURATION.as_micros() as f64;
5050
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `DURATION.as_secs_f64() * 1e6`
5151

5252
error: calling `as_secs_f64()` is more precise than this calculation
53-
--> tests/ui/duration_to_float_precision_loss.rs:47:22
53+
--> tests/ui/duration_to_float_precision_loss.rs:41:28
54+
|
55+
LL | let float_millis = dur.as_millis() as f64 / 1_000.0;
56+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `dur.as_secs_f64()`
57+
58+
error: calling `as_secs_f64()` is more precise than this calculation
59+
--> tests/ui/duration_to_float_precision_loss.rs:52:22
5460
|
5561
LL | let float_secs = DURATION.as_secs() as f64; // should trigger lint because MSRV is satisfied
5662
| ^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `DURATION.as_secs_f64()`
5763

58-
error: aborting due to 9 previous errors
64+
error: aborting due to 10 previous errors
5965

0 commit comments

Comments
 (0)