mistyped_literal_suffixes: improve suggestions for integer types

Instead of just always suggesting signed suffixes regardless of size
of the value, it now suggests an unsigned suffix when the value wouldn't
fit into the corresponding signed type, and ignores the literal entirely
if it is too big for the unsigned type as well.
This commit is contained in:
goth-turtle 2022-04-23 22:20:50 +02:00
parent cef882cc9d
commit f290249461
4 changed files with 101 additions and 27 deletions

View File

@ -42,17 +42,12 @@
/// This is most probably a typo
///
/// ### Known problems
/// - Recommends a signed suffix, even though the number might be too big and an unsigned
/// suffix is required
/// - Does not match on integers too large to fit in the corresponding unsigned type
/// - Does not match on `_127` since that is a valid grouping for decimal and octal numbers
///
/// ### Example
/// ```rust
/// // Probably mistyped
/// 2_32;
///
/// // Good
/// 2_i32;
/// `2_32` => `2_i32`
/// `250_8 => `250_u8`
/// ```
#[clippy::version = "1.30.0"]
pub MISTYPED_LITERAL_SUFFIXES,
@ -310,18 +305,47 @@ fn check_for_mistyped_suffix(
return true;
}
let (part, mistyped_suffixes, missing_char) = if let Some((_, exponent)) = &mut num_lit.exponent {
(exponent, &["32", "64"][..], 'f')
let (part, mistyped_suffixes, is_float) = if let Some((_, exponent)) = &mut num_lit.exponent {
(exponent, &["32", "64"][..], true)
} else if num_lit.fraction.is_some() {
(&mut num_lit.integer, &["32", "64"][..], 'f')
(&mut num_lit.integer, &["32", "64"][..], true)
} else {
(&mut num_lit.integer, &["8", "16", "32", "64"][..], 'i')
(&mut num_lit.integer, &["8", "16", "32", "64"][..], false)
};
let mut split = part.rsplit('_');
let last_group = split.next().expect("At least one group");
if split.next().is_some() && mistyped_suffixes.contains(&last_group) {
*part = &part[..part.len() - last_group.len()];
let main_part = &part[..part.len() - last_group.len()];
let missing_char;
if is_float {
missing_char = 'f';
} else {
let radix = match num_lit.radix {
Radix::Binary => 2,
Radix::Octal => 8,
Radix::Decimal => 10,
Radix::Hexadecimal => 16,
};
if let Ok(int) = u64::from_str_radix(&main_part.replace('_', ""), radix) {
missing_char = match (last_group, int) {
("8", i) if i8::try_from(i).is_ok() => 'i',
("16", i) if i16::try_from(i).is_ok() => 'i',
("32", i) if i32::try_from(i).is_ok() => 'i',
("64", i) if i64::try_from(i).is_ok() => 'i',
("8", u) if u8::try_from(u).is_ok() => 'u',
("16", u) if u16::try_from(u).is_ok() => 'u',
("32", u) if u32::try_from(u).is_ok() => 'u',
("64", _) => 'u',
_ => {
return true;
},
}
} else {
return true;
}
}
*part = main_part;
let mut sugg = num_lit.format();
sugg.push('_');
sugg.push(missing_char);

View File

@ -5,7 +5,8 @@
unused_variables,
overflowing_literals,
clippy::excessive_precision,
clippy::inconsistent_digit_grouping
clippy::inconsistent_digit_grouping,
clippy::unusual_byte_groupings
)]
fn main() {
@ -25,5 +26,14 @@ fn main() {
let fail28 = 241_251_235E723_f64;
let ok29 = 42279.911_32;
// testing that the suggestion actually fits in its type
let fail30 = 127_i8; // should be i8
let fail31 = 240_u8; // should be u8
let ok32 = 360_8; // doesnt fit in either, should be ignored
let fail33 = 0x1234_i16;
let fail34 = 0xABCD_u16;
let ok35 = 0x12345_16;
let fail36 = 0xFFFF_FFFF_FFFF_FFFF_u64; // u64
let _ = 1.123_45E1_f32;
}

View File

@ -5,7 +5,8 @@
unused_variables,
overflowing_literals,
clippy::excessive_precision,
clippy::inconsistent_digit_grouping
clippy::inconsistent_digit_grouping,
clippy::unusual_byte_groupings
)]
fn main() {
@ -25,5 +26,14 @@ fn main() {
let fail28 = 241251235E723_64;
let ok29 = 42279.911_32;
// testing that the suggestion actually fits in its type
let fail30 = 127_8; // should be i8
let fail31 = 240_8; // should be u8
let ok32 = 360_8; // doesnt fit in either, should be ignored
let fail33 = 0x1234_16;
let fail34 = 0xABCD_16;
let ok35 = 0x12345_16;
let fail36 = 0xFFFF_FFFF_FFFF_FFFF_64; // u64
let _ = 1.12345E1_32;
}

View File

@ -1,5 +1,5 @@
error: mistyped literal suffix
--> $DIR/mistyped_literal_suffix.rs:12:18
--> $DIR/mistyped_literal_suffix.rs:13:18
|
LL | let fail14 = 2_32;
| ^^^^ help: did you mean to write: `2_i32`
@ -7,64 +7,94 @@ LL | let fail14 = 2_32;
= note: `#[deny(clippy::mistyped_literal_suffixes)]` on by default
error: mistyped literal suffix
--> $DIR/mistyped_literal_suffix.rs:13:18
--> $DIR/mistyped_literal_suffix.rs:14:18
|
LL | let fail15 = 4_64;
| ^^^^ help: did you mean to write: `4_i64`
error: mistyped literal suffix
--> $DIR/mistyped_literal_suffix.rs:14:18
--> $DIR/mistyped_literal_suffix.rs:15:18
|
LL | let fail16 = 7_8; //
| ^^^ help: did you mean to write: `7_i8`
error: mistyped literal suffix
--> $DIR/mistyped_literal_suffix.rs:15:18
--> $DIR/mistyped_literal_suffix.rs:16:18
|
LL | let fail17 = 23_16; //
| ^^^^^ help: did you mean to write: `23_i16`
error: mistyped literal suffix
--> $DIR/mistyped_literal_suffix.rs:18:18
--> $DIR/mistyped_literal_suffix.rs:19:18
|
LL | let fail20 = 2__8; //
| ^^^^ help: did you mean to write: `2_i8`
error: mistyped literal suffix
--> $DIR/mistyped_literal_suffix.rs:19:18
--> $DIR/mistyped_literal_suffix.rs:20:18
|
LL | let fail21 = 4___16; //
| ^^^^^^ help: did you mean to write: `4_i16`
error: mistyped literal suffix
--> $DIR/mistyped_literal_suffix.rs:22:18
--> $DIR/mistyped_literal_suffix.rs:23:18
|
LL | let fail25 = 1E2_32;
| ^^^^^^ help: did you mean to write: `1E2_f32`
error: mistyped literal suffix
--> $DIR/mistyped_literal_suffix.rs:23:18
--> $DIR/mistyped_literal_suffix.rs:24:18
|
LL | let fail26 = 43E7_64;
| ^^^^^^^ help: did you mean to write: `43E7_f64`
error: mistyped literal suffix
--> $DIR/mistyped_literal_suffix.rs:24:18
--> $DIR/mistyped_literal_suffix.rs:25:18
|
LL | let fail27 = 243E17_32;
| ^^^^^^^^^ help: did you mean to write: `243E17_f32`
error: mistyped literal suffix
--> $DIR/mistyped_literal_suffix.rs:25:18
--> $DIR/mistyped_literal_suffix.rs:26:18
|
LL | let fail28 = 241251235E723_64;
| ^^^^^^^^^^^^^^^^ help: did you mean to write: `241_251_235E723_f64`
error: mistyped literal suffix
--> $DIR/mistyped_literal_suffix.rs:28:13
--> $DIR/mistyped_literal_suffix.rs:30:18
|
LL | let fail30 = 127_8; // should be i8
| ^^^^^ help: did you mean to write: `127_i8`
error: mistyped literal suffix
--> $DIR/mistyped_literal_suffix.rs:31:18
|
LL | let fail31 = 240_8; // should be u8
| ^^^^^ help: did you mean to write: `240_u8`
error: mistyped literal suffix
--> $DIR/mistyped_literal_suffix.rs:33:18
|
LL | let fail33 = 0x1234_16;
| ^^^^^^^^^ help: did you mean to write: `0x1234_i16`
error: mistyped literal suffix
--> $DIR/mistyped_literal_suffix.rs:34:18
|
LL | let fail34 = 0xABCD_16;
| ^^^^^^^^^ help: did you mean to write: `0xABCD_u16`
error: mistyped literal suffix
--> $DIR/mistyped_literal_suffix.rs:36:18
|
LL | let fail36 = 0xFFFF_FFFF_FFFF_FFFF_64; // u64
| ^^^^^^^^^^^^^^^^^^^^^^^^ help: did you mean to write: `0xFFFF_FFFF_FFFF_FFFF_u64`
error: mistyped literal suffix
--> $DIR/mistyped_literal_suffix.rs:38:13
|
LL | let _ = 1.12345E1_32;
| ^^^^^^^^^^^^ help: did you mean to write: `1.123_45E1_f32`
error: aborting due to 11 previous errors
error: aborting due to 16 previous errors