diff --git a/clippy_lints/src/literal_representation.rs b/clippy_lints/src/literal_representation.rs index 1b93f6bf3f4..8b8d7903fed 100644 --- a/clippy_lints/src/literal_representation.rs +++ b/clippy_lints/src/literal_representation.rs @@ -134,7 +134,7 @@ impl<'a> DigitInfo<'a> { let mut last_d = '\0'; for (d_idx, d) in sans_prefix.char_indices() { - if !float && (d == 'i' || d == 'u') || float && d == 'f' { + if !float && (d == 'i' || d == 'u') || float && (d == 'f' || d == 'e' || d == 'E') { let suffix_start = if last_d == '_' { d_idx - 1 } else { d_idx }; let (digits, suffix) = sans_prefix.split_at(suffix_start); return Self { @@ -285,60 +285,64 @@ impl EarlyLintPass for LiteralDigitGrouping { impl LiteralDigitGrouping { fn check_lit(&self, cx: &EarlyContext, lit: &Lit) { - // Lint integral literals. - if_chain! { - if let LitKind::Int(..) = lit.node; - if let Some(src) = snippet_opt(cx, lit.span); - if let Some(firstch) = src.chars().next(); - if char::to_digit(firstch, 10).is_some(); - then { - let digit_info = DigitInfo::new(&src, false); - let _ = Self::do_lint(digit_info.digits).map_err(|warning_type| { - warning_type.display(&digit_info.grouping_hint(), cx, &lit.span) - }); - } - } + match lit.node { + LitKind::Int(..) => { + // Lint integral literals. + if_chain! { + if let Some(src) = snippet_opt(cx, lit.span); + if let Some(firstch) = src.chars().next(); + if char::to_digit(firstch, 10).is_some(); + then { + let digit_info = DigitInfo::new(&src, false); + let _ = Self::do_lint(digit_info.digits).map_err(|warning_type| { + warning_type.display(&digit_info.grouping_hint(), cx, &lit.span) + }); + } + } + }, + LitKind::Float(..) | LitKind::FloatUnsuffixed(..) => { + // Lint floating-point literals. + if_chain! { + if let Some(src) = snippet_opt(cx, lit.span); + if let Some(firstch) = src.chars().next(); + if char::to_digit(firstch, 10).is_some(); + then { + let digit_info = DigitInfo::new(&src, true); + // Separate digits into integral and fractional parts. + let parts: Vec<&str> = digit_info + .digits + .split_terminator('.') + .collect(); - // Lint floating-point literals. - if_chain! { - if let LitKind::Float(..) = lit.node; - if let Some(src) = snippet_opt(cx, lit.span); - if let Some(firstch) = src.chars().next(); - if char::to_digit(firstch, 10).is_some(); - then { - let digit_info = DigitInfo::new(&src, true); - // Separate digits into integral and fractional parts. - let parts: Vec<&str> = digit_info - .digits - .split_terminator('.') - .collect(); - - // Lint integral and fractional parts separately, and then check consistency of digit - // groups if both pass. - let _ = Self::do_lint(parts[0]) - .map(|integral_group_size| { - if parts.len() > 1 { - // Lint the fractional part of literal just like integral part, but reversed. - let fractional_part = &parts[1].chars().rev().collect::(); - let _ = Self::do_lint(fractional_part) - .map(|fractional_group_size| { - let consistent = Self::parts_consistent(integral_group_size, - fractional_group_size, - parts[0].len(), - parts[1].len()); - if !consistent { - WarningType::InconsistentDigitGrouping.display(&digit_info.grouping_hint(), - cx, - &lit.span); - } - }) - .map_err(|warning_type| warning_type.display(&digit_info.grouping_hint(), - cx, - &lit.span)); - } - }) - .map_err(|warning_type| warning_type.display(&digit_info.grouping_hint(), cx, &lit.span)); - } + // Lint integral and fractional parts separately, and then check consistency of digit + // groups if both pass. + let _ = Self::do_lint(parts[0]) + .map(|integral_group_size| { + if parts.len() > 1 { + // Lint the fractional part of literal just like integral part, but reversed. + let fractional_part = &parts[1].chars().rev().collect::(); + let _ = Self::do_lint(fractional_part) + .map(|fractional_group_size| { + let consistent = Self::parts_consistent(integral_group_size, + fractional_group_size, + parts[0].len(), + parts[1].len()); + if !consistent { + WarningType::InconsistentDigitGrouping.display(&digit_info.grouping_hint(), + cx, + &lit.span); + } + }) + .map_err(|warning_type| warning_type.display(&digit_info.grouping_hint(), + cx, + &lit.span)); + } + }) + .map_err(|warning_type| warning_type.display(&digit_info.grouping_hint(), cx, &lit.span)); + } + } + }, + _ => (), } } diff --git a/tests/ui/approx_const.rs b/tests/ui/approx_const.rs index f2239ecb467..394aa9d1eb3 100644 --- a/tests/ui/approx_const.rs +++ b/tests/ui/approx_const.rs @@ -2,7 +2,7 @@ #[warn(approx_constant)] -#[allow(unused, shadow_unrelated, similar_names)] +#[allow(unused, shadow_unrelated, similar_names, unreadable_literal)] fn main() { let my_e = 2.7182; let almost_e = 2.718; diff --git a/tests/ui/unreadable_literal.rs b/tests/ui/unreadable_literal.rs index 327fea254a8..94b53f80bb2 100644 --- a/tests/ui/unreadable_literal.rs +++ b/tests/ui/unreadable_literal.rs @@ -5,4 +5,6 @@ fn main() { let good = (0b1011_i64, 0o1_234_u32, 0x1_234_567, 1_2345_6789, 1234_f32, 1_234.12_f32, 1_234.123_f32, 1.123_4_f32); let bad = (0b10110_i64, 0x12345678901_usize, 12345_f32, 1.23456_f32); + let good_sci = 1.1234e1; + let bad_sci = 1.12345e1; } diff --git a/tests/ui/unreadable_literal.stderr b/tests/ui/unreadable_literal.stderr index 4fcae9bf725..b16a58ec245 100644 --- a/tests/ui/unreadable_literal.stderr +++ b/tests/ui/unreadable_literal.stderr @@ -24,5 +24,11 @@ error: long literal lacking separators 7 | let bad = (0b10110_i64, 0x12345678901_usize, 12345_f32, 1.23456_f32); | ^^^^^^^^^^^ help: consider: `1.234_56_f32` -error: aborting due to 4 previous errors +error: long literal lacking separators + --> $DIR/unreadable_literal.rs:9:19 + | +9 | let bad_sci = 1.12345e1; + | ^^^^^^^^^ help: consider: `1.123_45e1` + +error: aborting due to 5 previous errors