mirror of
https://github.com/rust-lang/rust-clippy
synced 2025-02-17 06:28:42 +00:00
Fix 1x..x.0 false positive, pretty suggestion
This commit is contained in:
parent
0557359ecd
commit
d4b536f540
4 changed files with 112 additions and 72 deletions
|
@ -69,13 +69,16 @@ impl ExcessivePrecision {
|
|||
fn check(&self, sym: &Symbol, fty: &FloatTy) -> Option<String> {
|
||||
let max = max_digits(fty);
|
||||
let sym_str = sym.as_str();
|
||||
let formatter = FloatFormat::new(&sym_str);
|
||||
let digits = count_digits(&sym_str);
|
||||
if dot_zero_exclusion(&sym_str) {
|
||||
return None
|
||||
}
|
||||
// Try to bail out if the float is for sure fine.
|
||||
// If its within the 2 decimal digits of being out of precision we
|
||||
// check if the parsed representation is the same as the string
|
||||
// since we'll need the truncated string anyway.
|
||||
let digits = count_digits(&sym_str);
|
||||
if digits > max as usize {
|
||||
let formatter = FloatFormat::new(&sym_str);
|
||||
let sr = match *fty {
|
||||
FloatTy::F32 => sym_str.parse::<f32>().map(|f| formatter.format(f)),
|
||||
FloatTy::F64 => sym_str.parse::<f64>().map(|f| formatter.format(f)),
|
||||
|
@ -86,7 +89,8 @@ impl ExcessivePrecision {
|
|||
if sym_str == s {
|
||||
None
|
||||
} else {
|
||||
Some(s)
|
||||
let di = super::literal_representation::DigitInfo::new(&s, true);
|
||||
Some(di.grouping_hint())
|
||||
}
|
||||
} else {
|
||||
None
|
||||
|
@ -94,6 +98,23 @@ impl ExcessivePrecision {
|
|||
}
|
||||
}
|
||||
|
||||
/// Should we exclude the float because it has a .0 suffix
|
||||
/// Ex 1_000_000_000.0
|
||||
fn dot_zero_exclusion(s: &str) -> bool {
|
||||
if let Some(after_dec) = s.split('.').nth(1) {
|
||||
let mut decpart = after_dec
|
||||
.chars()
|
||||
.take_while(|c| *c != 'e' || *c != 'E');
|
||||
|
||||
match decpart.next() {
|
||||
Some('0') => decpart.count() == 0,
|
||||
_ => false,
|
||||
}
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
fn max_digits(fty: &FloatTy) -> u32 {
|
||||
match fty {
|
||||
FloatTy::F32 => f32::DIGITS,
|
||||
|
@ -101,7 +122,9 @@ fn max_digits(fty: &FloatTy) -> u32 {
|
|||
}
|
||||
}
|
||||
|
||||
/// Counts the digits excluding leading zeros
|
||||
fn count_digits(s: &str) -> usize {
|
||||
// Note that s does not contain the f32/64 suffix
|
||||
s.chars()
|
||||
.filter(|c| *c != '-' || *c != '.')
|
||||
.take_while(|c| *c != 'e' || *c != 'E')
|
||||
|
|
|
@ -81,7 +81,7 @@ declare_clippy_lint! {
|
|||
}
|
||||
|
||||
#[derive(Debug, PartialEq)]
|
||||
enum Radix {
|
||||
pub(super) enum Radix {
|
||||
Binary,
|
||||
Octal,
|
||||
Decimal,
|
||||
|
@ -99,7 +99,7 @@ impl Radix {
|
|||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
struct DigitInfo<'a> {
|
||||
pub(super) struct DigitInfo<'a> {
|
||||
/// Characters of a literal between the radix prefix and type suffix.
|
||||
pub digits: &'a str,
|
||||
/// Which radix the literal was represented in.
|
||||
|
@ -160,7 +160,7 @@ impl<'a> DigitInfo<'a> {
|
|||
}
|
||||
|
||||
/// Returns digits grouped in a sensible way.
|
||||
fn grouping_hint(&self) -> String {
|
||||
pub fn grouping_hint(&self) -> String {
|
||||
let group_size = self.radix.suggest_grouping();
|
||||
if self.digits.contains('.') {
|
||||
let mut parts = self.digits.split('.');
|
||||
|
|
|
@ -3,45 +3,50 @@
|
|||
#![allow(print_literal)]
|
||||
|
||||
fn main() {
|
||||
// TODO add prefix tests
|
||||
// Consts
|
||||
const GOOD32_SUF: f32 = 0.123_456_f32;
|
||||
const GOOD32: f32 = 0.123_456;
|
||||
const GOOD32_SM: f32 = 0.000_000_000_1;
|
||||
const GOOD32_DOT: f32 = 10_000_000_000.0;
|
||||
const GOOD32_EDGE: f32 = 1.000_000_8;
|
||||
const GOOD64: f64 = 0.123_456_789_012;
|
||||
const GOOD64_SM: f32 = 0.000_000_000_000_000_1;
|
||||
const GOOD64_DOT: f32 = 10_000_000_000_000_000.0;
|
||||
|
||||
const BAD32_1: f32 = 0.123_456_789_f32;
|
||||
const BAD32_2: f32 = 0.123_456_789;
|
||||
const BAD32_3: f32 = 0.100_000_000_000_1;
|
||||
const BAD32_EDGE: f32 = 1.000_000_9;
|
||||
|
||||
const BAD64_1: f64 = 0.123_456_789_012_345_67f64;
|
||||
const BAD64_2: f64 = 0.123_456_789_012_345_67;
|
||||
const BAD64_3: f64 = 0.100_000_000_000_000_000_1;
|
||||
|
||||
// Literal
|
||||
// Literal as param
|
||||
println!("{}", 8.888_888_888_888_888_888_888);
|
||||
|
||||
// TODO add inferred type tests for f32
|
||||
// TODO add tests cases exactly on the edge
|
||||
// // TODO add inferred type tests for f32
|
||||
// Locals
|
||||
let good32: f32 = 0.123_456_f32;
|
||||
let good32_2: f32 = 0.123_456;
|
||||
|
||||
let good64: f64 = 0.123_456_789_012f64;
|
||||
let good64: f64 = 0.123_456_789_012;
|
||||
let good64_2 = 0.123_456_789_012;
|
||||
let good64_suf: f64 = 0.123_456_789_012f64;
|
||||
let good64_inf = 0.123_456_789_012;
|
||||
|
||||
let bad32_1: f32 = 1.123_456_789_f32;
|
||||
let bad32_2: f32 = 1.123_456_789;
|
||||
let bad32: f32 = 1.123_456_789;
|
||||
let bad32_suf: f32 = 1.123_456_789_f32;
|
||||
let bad32_inf = 1.123_456_789_f32;
|
||||
|
||||
let bad64_1: f64 = 0.123_456_789_012_345_67f64;
|
||||
let bad64_2: f64 = 0.123_456_789_012_345_67;
|
||||
let bad64_3 = 0.123_456_789_012_345_67;
|
||||
let bad64: f64 = 0.123_456_789_012_345_67;
|
||||
let bad64_suf: f64 = 0.123_456_789_012_345_67f64;
|
||||
let bad64_inf = 0.123_456_789_012_345_67;
|
||||
|
||||
// TODO Vectors / nested vectors
|
||||
let vec32: Vec<f32> = vec![0.123_456_789];
|
||||
let vec64: Vec<f64> = vec![0.123_456_789_123_456_789];
|
||||
// Vectors
|
||||
let good_vec32: Vec<f32> = vec![0.123_456];
|
||||
let good_vec64: Vec<f64> = vec![0.123_456_789];
|
||||
|
||||
let bad_vec32: Vec<f32> = vec![0.123_456_789];
|
||||
let bad_vec64: Vec<f64> = vec![0.123_456_789_123_456_789];
|
||||
|
||||
// Exponential float notation
|
||||
let good_e32: f32 = 1e-10;
|
||||
|
|
|
@ -1,100 +1,112 @@
|
|||
error: float has excessive precision
|
||||
--> $DIR/excessive_precision.rs:14:26
|
||||
--> $DIR/excessive_precision.rs:15:26
|
||||
|
|
||||
14 | const BAD32_1: f32 = 0.123_456_789_f32;
|
||||
| ^^^^^^^^^^^^^^^^^ help: consider changing the type or truncating it to: `0.12345679`
|
||||
15 | const BAD32_1: f32 = 0.123_456_789_f32;
|
||||
| ^^^^^^^^^^^^^^^^^ help: consider changing the type or truncating it to: `0.123_456_79`
|
||||
|
|
||||
= note: `-D excessive-precision` implied by `-D warnings`
|
||||
|
||||
error: float has excessive precision
|
||||
--> $DIR/excessive_precision.rs:15:26
|
||||
|
|
||||
15 | const BAD32_2: f32 = 0.123_456_789;
|
||||
| ^^^^^^^^^^^^^ help: consider changing the type or truncating it to: `0.12345679`
|
||||
|
||||
error: float has excessive precision
|
||||
--> $DIR/excessive_precision.rs:16:26
|
||||
|
|
||||
16 | const BAD32_3: f32 = 0.100_000_000_000_1;
|
||||
16 | const BAD32_2: f32 = 0.123_456_789;
|
||||
| ^^^^^^^^^^^^^ help: consider changing the type or truncating it to: `0.123_456_79`
|
||||
|
||||
error: float has excessive precision
|
||||
--> $DIR/excessive_precision.rs:17:26
|
||||
|
|
||||
17 | const BAD32_3: f32 = 0.100_000_000_000_1;
|
||||
| ^^^^^^^^^^^^^^^^^^^ help: consider changing the type or truncating it to: `0.1`
|
||||
|
||||
error: float has excessive precision
|
||||
--> $DIR/excessive_precision.rs:18:26
|
||||
--> $DIR/excessive_precision.rs:18:29
|
||||
|
|
||||
18 | const BAD64_1: f64 = 0.123_456_789_012_345_67f64;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider changing the type or truncating it to: `0.12345678901234566`
|
||||
|
||||
error: float has excessive precision
|
||||
--> $DIR/excessive_precision.rs:19:26
|
||||
|
|
||||
19 | const BAD64_2: f64 = 0.123_456_789_012_345_67;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider changing the type or truncating it to: `0.12345678901234566`
|
||||
18 | const BAD32_EDGE: f32 = 1.000_000_9;
|
||||
| ^^^^^^^^^^^ help: consider changing the type or truncating it to: `1.000_001`
|
||||
|
||||
error: float has excessive precision
|
||||
--> $DIR/excessive_precision.rs:20:26
|
||||
|
|
||||
20 | const BAD64_3: f64 = 0.100_000_000_000_000_000_1;
|
||||
20 | const BAD64_1: f64 = 0.123_456_789_012_345_67f64;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider changing the type or truncating it to: `0.123_456_789_012_345_66`
|
||||
|
||||
error: float has excessive precision
|
||||
--> $DIR/excessive_precision.rs:21:26
|
||||
|
|
||||
21 | const BAD64_2: f64 = 0.123_456_789_012_345_67;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider changing the type or truncating it to: `0.123_456_789_012_345_66`
|
||||
|
||||
error: float has excessive precision
|
||||
--> $DIR/excessive_precision.rs:22:26
|
||||
|
|
||||
22 | const BAD64_3: f64 = 0.100_000_000_000_000_000_1;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider changing the type or truncating it to: `0.1`
|
||||
|
||||
error: float has excessive precision
|
||||
--> $DIR/excessive_precision.rs:23:20
|
||||
--> $DIR/excessive_precision.rs:25:20
|
||||
|
|
||||
23 | println!("{}", 8.888_888_888_888_888_888_888);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider changing the type or truncating it to: `8.88888888888889`
|
||||
25 | println!("{}", 8.888_888_888_888_888_888_888);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider changing the type or truncating it to: `8.888_888_888_888_89`
|
||||
|
||||
error: float has excessive precision
|
||||
--> $DIR/excessive_precision.rs:35:24
|
||||
--> $DIR/excessive_precision.rs:36:22
|
||||
|
|
||||
35 | let bad32_1: f32 = 1.123_456_789_f32;
|
||||
| ^^^^^^^^^^^^^^^^^ help: consider changing the type or truncating it to: `1.1234568`
|
||||
36 | let bad32: f32 = 1.123_456_789;
|
||||
| ^^^^^^^^^^^^^ help: consider changing the type or truncating it to: `1.123_456_8`
|
||||
|
||||
error: float has excessive precision
|
||||
--> $DIR/excessive_precision.rs:36:24
|
||||
--> $DIR/excessive_precision.rs:37:26
|
||||
|
|
||||
36 | let bad32_2: f32 = 1.123_456_789;
|
||||
| ^^^^^^^^^^^^^ help: consider changing the type or truncating it to: `1.1234568`
|
||||
37 | let bad32_suf: f32 = 1.123_456_789_f32;
|
||||
| ^^^^^^^^^^^^^^^^^ help: consider changing the type or truncating it to: `1.123_456_8`
|
||||
|
||||
error: float has excessive precision
|
||||
--> $DIR/excessive_precision.rs:38:24
|
||||
--> $DIR/excessive_precision.rs:38:21
|
||||
|
|
||||
38 | let bad64_1: f64 = 0.123_456_789_012_345_67f64;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider changing the type or truncating it to: `0.12345678901234566`
|
||||
38 | let bad32_inf = 1.123_456_789_f32;
|
||||
| ^^^^^^^^^^^^^^^^^ help: consider changing the type or truncating it to: `1.123_456_8`
|
||||
|
||||
error: float has excessive precision
|
||||
--> $DIR/excessive_precision.rs:39:24
|
||||
--> $DIR/excessive_precision.rs:40:22
|
||||
|
|
||||
39 | let bad64_2: f64 = 0.123_456_789_012_345_67;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider changing the type or truncating it to: `0.12345678901234566`
|
||||
40 | let bad64: f64 = 0.123_456_789_012_345_67;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider changing the type or truncating it to: `0.123_456_789_012_345_66`
|
||||
|
||||
error: float has excessive precision
|
||||
--> $DIR/excessive_precision.rs:40:19
|
||||
--> $DIR/excessive_precision.rs:41:26
|
||||
|
|
||||
40 | let bad64_3 = 0.123_456_789_012_345_67;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider changing the type or truncating it to: `0.12345678901234566`
|
||||
41 | let bad64_suf: f64 = 0.123_456_789_012_345_67f64;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider changing the type or truncating it to: `0.123_456_789_012_345_66`
|
||||
|
||||
error: float has excessive precision
|
||||
--> $DIR/excessive_precision.rs:43:32
|
||||
--> $DIR/excessive_precision.rs:42:21
|
||||
|
|
||||
43 | let vec32: Vec<f32> = vec![0.123_456_789];
|
||||
| ^^^^^^^^^^^^^ help: consider changing the type or truncating it to: `0.12345679`
|
||||
42 | let bad64_inf = 0.123_456_789_012_345_67;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider changing the type or truncating it to: `0.123_456_789_012_345_66`
|
||||
|
||||
error: float has excessive precision
|
||||
--> $DIR/excessive_precision.rs:44:32
|
||||
--> $DIR/excessive_precision.rs:48:36
|
||||
|
|
||||
44 | let vec64: Vec<f64> = vec![0.123_456_789_123_456_789];
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider changing the type or truncating it to: `0.12345678912345678`
|
||||
48 | let bad_vec32: Vec<f32> = vec![0.123_456_789];
|
||||
| ^^^^^^^^^^^^^ help: consider changing the type or truncating it to: `0.123_456_79`
|
||||
|
||||
error: float has excessive precision
|
||||
--> $DIR/excessive_precision.rs:48:24
|
||||
--> $DIR/excessive_precision.rs:49:36
|
||||
|
|
||||
48 | let bad_e32: f32 = 1.123_456_788_888e-10;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^ help: consider changing the type or truncating it to: `1.1234568e-10`
|
||||
49 | let bad_vec64: Vec<f64> = vec![0.123_456_789_123_456_789];
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider changing the type or truncating it to: `0.123_456_789_123_456_78`
|
||||
|
||||
error: float has excessive precision
|
||||
--> $DIR/excessive_precision.rs:51:27
|
||||
--> $DIR/excessive_precision.rs:53:24
|
||||
|
|
||||
51 | let bad_bige32: f32 = 1.123_456_788_888E-10;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^ help: consider changing the type or truncating it to: `1.1234568E-10`
|
||||
53 | let bad_e32: f32 = 1.123_456_788_888e-10;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^ help: consider changing the type or truncating it to: `1.123_456_8e-10`
|
||||
|
||||
error: aborting due to 16 previous errors
|
||||
error: float has excessive precision
|
||||
--> $DIR/excessive_precision.rs:56:27
|
||||
|
|
||||
56 | let bad_bige32: f32 = 1.123_456_788_888E-10;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^ help: consider changing the type or truncating it to: `1.123_456_8E-10`
|
||||
|
||||
error: aborting due to 18 previous errors
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue