@@ -92,9 +92,11 @@ impl LateLintPass<'_> for ApproxConstant {
9292impl ApproxConstant {
9393 fn check_known_consts ( & self , cx : & LateContext < ' _ > , span : Span , s : symbol:: Symbol , module : & str ) {
9494 let s = s. as_str ( ) ;
95- if s. parse :: < f64 > ( ) . is_ok ( ) {
95+ if let Ok ( maybe_constant ) = s. parse :: < f64 > ( ) {
9696 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+ {
98100 span_lint_and_help (
99101 cx,
100102 APPROX_CONSTANT ,
@@ -112,18 +114,35 @@ impl ApproxConstant {
112114
113115impl_lint_pass ! ( ApproxConstant => [ APPROX_CONSTANT ] ) ;
114116
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+
115124/// Returns `false` if the number of significant figures in `value` are
116125/// 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`.
118127#[ 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 {
120129 if value. len ( ) <= min_digits {
130+ // The value is not precise enough
121131 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
124134 true
125135 } 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+ ) ;
127146 value == round_const
128147 }
129148}
0 commit comments