@@ -92,9 +92,11 @@ impl LateLintPass<'_> for ApproxConstant {
92
92
impl ApproxConstant {
93
93
fn check_known_consts ( & self , cx : & LateContext < ' _ > , span : Span , s : symbol:: Symbol , module : & str ) {
94
94
let s = s. as_str ( ) ;
95
- if s. parse :: < f64 > ( ) . is_ok ( ) {
95
+ if let Ok ( maybe_constant ) = s. parse :: < f64 > ( ) {
96
96
for & ( constant, name, min_digits, msrv) in & KNOWN_CONSTS {
97
- if is_approx_const ( constant, s, min_digits) && msrv. is_none_or ( |msrv| self . msrv . meets ( cx, msrv) ) {
97
+ if is_approx_const ( constant, s, maybe_constant, min_digits)
98
+ && msrv. is_none_or ( |msrv| self . msrv . meets ( cx, msrv) )
99
+ {
98
100
span_lint_and_help (
99
101
cx,
100
102
APPROX_CONSTANT ,
@@ -112,18 +114,35 @@ impl ApproxConstant {
112
114
113
115
impl_lint_pass ! ( ApproxConstant => [ APPROX_CONSTANT ] ) ;
114
116
117
+ fn count_digits_after_dot ( input : & str ) -> usize {
118
+ input
119
+ . char_indices ( )
120
+ . find ( |( _, ch) | * ch == '.' )
121
+ . map_or ( 0 , |( i, _) | input. len ( ) - i - 1 )
122
+ }
123
+
115
124
/// Returns `false` if the number of significant figures in `value` are
116
125
/// less than `min_digits`; otherwise, returns true if `value` is equal
117
- /// to `constant`, rounded to the number of digits present in `value`.
126
+ /// to `constant`, rounded to the number of significant digits present in `value`.
118
127
#[ must_use]
119
- fn is_approx_const ( constant : f64 , value : & str , min_digits : usize ) -> bool {
128
+ fn is_approx_const ( constant : f64 , value : & str , f_value : f64 , min_digits : usize ) -> bool {
120
129
if value. len ( ) <= min_digits {
130
+ // The value is not precise enough
121
131
false
122
- } else if constant. to_string ( ) . starts_with ( value ) {
123
- // The value is a truncated constant
132
+ } else if f_value . to_string ( ) . len ( ) > min_digits && constant. to_string ( ) . starts_with ( & f_value . to_string ( ) ) {
133
+ // The value represents the same value
124
134
true
125
135
} else {
126
- let round_const = format ! ( "{constant:.*}" , value. len( ) - 2 ) ;
136
+ // The value is a truncated constant
137
+
138
+ // Print constant with numeric formatting (`0`), with the length of `value` as minimum width
139
+ // (`value_len$`), and with the same precision as `value` (`.value_prec$`).
140
+ // See https://doc.rust-lang.org/std/fmt/index.html.
141
+ let round_const = format ! (
142
+ "{constant:0value_len$.value_prec$}" ,
143
+ value_len = value. len( ) ,
144
+ value_prec = count_digits_after_dot( value)
145
+ ) ;
127
146
value == round_const
128
147
}
129
148
}
0 commit comments