11use clippy_config:: msrvs:: { self , Msrv } ;
22use clippy_utils:: consts:: { constant, Constant } ;
33use clippy_utils:: diagnostics:: span_lint_and_sugg;
4+ use clippy_utils:: is_from_proc_macro;
45use clippy_utils:: source:: snippet_with_applicability;
56use clippy_utils:: ty:: is_type_diagnostic_item;
67use rustc_errors:: Applicability ;
78use rustc_hir:: { BinOpKind , Expr , ExprKind } ;
89use rustc_lint:: { LateContext , LateLintPass , LintContext } ;
910use rustc_middle:: lint:: in_external_macro;
1011use rustc_middle:: ty:: { self , FloatTy } ;
12+ use rustc_session:: impl_lint_pass;
1113use rustc_span:: { sym, Span } ;
1214
1315declare_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 ) ]
5961pub 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
8991impl < ' 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) ;
0 commit comments