1
1
use clippy_config:: msrvs:: { self , Msrv } ;
2
2
use clippy_utils:: consts:: { constant, Constant } ;
3
3
use clippy_utils:: diagnostics:: span_lint_and_sugg;
4
+ use clippy_utils:: is_from_proc_macro;
4
5
use clippy_utils:: source:: snippet_with_applicability;
5
6
use clippy_utils:: ty:: is_type_diagnostic_item;
6
7
use rustc_errors:: Applicability ;
7
8
use rustc_hir:: { BinOpKind , Expr , ExprKind } ;
8
9
use rustc_lint:: { LateContext , LateLintPass , LintContext } ;
9
10
use rustc_middle:: lint:: in_external_macro;
10
11
use rustc_middle:: ty:: { self , FloatTy } ;
12
+ use rustc_session:: impl_lint_pass;
11
13
use rustc_span:: { sym, Span } ;
12
14
13
15
declare_clippy_lint ! {
@@ -16,50 +18,50 @@ declare_clippy_lint! {
16
18
/// precision is lost.
17
19
///
18
20
/// ### 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 .
20
22
///
21
23
/// ### Example
22
24
/// ```no_run
23
25
/// # use std::time::Duration;
24
- /// # let duration = Duration::from_nanos(1234500000);
26
+ /// let duration = Duration::from_nanos(1234500000);
25
27
/// let _ = duration.as_millis() as f64;
26
28
/// ```
27
29
///
28
30
/// Use instead:
29
31
///
30
32
/// ```no_run
31
33
/// # use std::time::Duration;
32
- /// # let duration = Duration::from_nanos(1234500000);
34
+ /// let duration = Duration::from_nanos(1234500000);
33
35
/// let _ = duration.as_secs_f64() * 1000.0;
34
36
/// ```
35
37
///
36
38
/// Another motivating example happens when calculating number of seconds as a float with millisecond precision:
37
39
///
38
40
/// ```no_run
39
41
/// # use std::time::Duration;
40
- /// # let duration = Duration::from_nanos(1234500000);
42
+ /// let duration = Duration::from_nanos(1234500000);
41
43
/// let _ = duration.as_millis() as f64 / 1000.0;
42
44
/// ```
43
45
///
44
46
/// Use instead:
45
47
///
46
48
/// ```no_run
47
49
/// # use std::time::Duration;
48
- /// # let duration = Duration::from_nanos(1234500000);
50
+ /// let duration = Duration::from_nanos(1234500000);
49
51
/// let _ = duration.as_secs_f64();
50
52
/// ```
51
- #[ clippy:: version = "1.78 .0" ]
53
+ #[ clippy:: version = "1.79 .0" ]
52
54
pub DURATION_TO_FLOAT_PRECISION_LOSS ,
53
- nursery ,
55
+ style ,
54
56
"conversion from duration to float that cause loss of precision"
55
57
}
56
58
57
59
/// This struct implements the logic needed to apply the lint
58
60
#[ derive( Debug ) ]
59
61
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
61
63
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
63
65
msrv : Msrv ,
64
66
}
65
67
@@ -84,7 +86,7 @@ impl DurationToFloatPrecisionLoss {
84
86
}
85
87
}
86
88
87
- rustc_session :: impl_lint_pass!( DurationToFloatPrecisionLoss => [ DURATION_TO_FLOAT_PRECISION_LOSS ] ) ;
89
+ impl_lint_pass ! ( DurationToFloatPrecisionLoss => [ DURATION_TO_FLOAT_PRECISION_LOSS ] ) ;
88
90
89
91
impl < ' tcx > LateLintPass < ' tcx > for DurationToFloatPrecisionLoss {
90
92
fn check_expr ( & mut self , cx : & LateContext < ' tcx > , expr : & ' tcx Expr < ' _ > ) {
@@ -211,7 +213,9 @@ fn check_cast<'tcx>(
211
213
expr : & ' tcx Expr < ' _ > ,
212
214
duration_expr : & ' tcx Expr < ' _ > ,
213
215
) -> 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
+ {
215
219
let method_receiver_ty = cx. typeck_results ( ) . expr_ty ( method_receiver_expr) ;
216
220
if is_type_diagnostic_item ( cx, method_receiver_ty. peel_refs ( ) , sym:: Duration ) {
217
221
let cast_expr_ty = cx. typeck_results ( ) . expr_ty ( expr) ;
0 commit comments