Skip to content

Commit f071d19

Browse files
authored
Merge pull request #2504 from flip1995/lit_float_repr
Fix unreadable_literal lint for scientific float notation
2 parents 3138c7a + 86ce897 commit f071d19

File tree

4 files changed

+69
-57
lines changed

4 files changed

+69
-57
lines changed

clippy_lints/src/literal_representation.rs

Lines changed: 59 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,7 @@ impl<'a> DigitInfo<'a> {
134134

135135
let mut last_d = '\0';
136136
for (d_idx, d) in sans_prefix.char_indices() {
137-
if !float && (d == 'i' || d == 'u') || float && d == 'f' {
137+
if !float && (d == 'i' || d == 'u') || float && (d == 'f' || d == 'e' || d == 'E') {
138138
let suffix_start = if last_d == '_' { d_idx - 1 } else { d_idx };
139139
let (digits, suffix) = sans_prefix.split_at(suffix_start);
140140
return Self {
@@ -285,60 +285,64 @@ impl EarlyLintPass for LiteralDigitGrouping {
285285

286286
impl LiteralDigitGrouping {
287287
fn check_lit(&self, cx: &EarlyContext, lit: &Lit) {
288-
// Lint integral literals.
289-
if_chain! {
290-
if let LitKind::Int(..) = lit.node;
291-
if let Some(src) = snippet_opt(cx, lit.span);
292-
if let Some(firstch) = src.chars().next();
293-
if char::to_digit(firstch, 10).is_some();
294-
then {
295-
let digit_info = DigitInfo::new(&src, false);
296-
let _ = Self::do_lint(digit_info.digits).map_err(|warning_type| {
297-
warning_type.display(&digit_info.grouping_hint(), cx, &lit.span)
298-
});
299-
}
300-
}
301-
302-
// Lint floating-point literals.
303-
if_chain! {
304-
if let LitKind::Float(..) = lit.node;
305-
if let Some(src) = snippet_opt(cx, lit.span);
306-
if let Some(firstch) = src.chars().next();
307-
if char::to_digit(firstch, 10).is_some();
308-
then {
309-
let digit_info = DigitInfo::new(&src, true);
310-
// Separate digits into integral and fractional parts.
311-
let parts: Vec<&str> = digit_info
312-
.digits
313-
.split_terminator('.')
314-
.collect();
315-
316-
// Lint integral and fractional parts separately, and then check consistency of digit
317-
// groups if both pass.
318-
let _ = Self::do_lint(parts[0])
319-
.map(|integral_group_size| {
320-
if parts.len() > 1 {
321-
// Lint the fractional part of literal just like integral part, but reversed.
322-
let fractional_part = &parts[1].chars().rev().collect::<String>();
323-
let _ = Self::do_lint(fractional_part)
324-
.map(|fractional_group_size| {
325-
let consistent = Self::parts_consistent(integral_group_size,
326-
fractional_group_size,
327-
parts[0].len(),
328-
parts[1].len());
329-
if !consistent {
330-
WarningType::InconsistentDigitGrouping.display(&digit_info.grouping_hint(),
331-
cx,
332-
&lit.span);
333-
}
334-
})
335-
.map_err(|warning_type| warning_type.display(&digit_info.grouping_hint(),
336-
cx,
337-
&lit.span));
338-
}
339-
})
340-
.map_err(|warning_type| warning_type.display(&digit_info.grouping_hint(), cx, &lit.span));
341-
}
288+
match lit.node {
289+
LitKind::Int(..) => {
290+
// Lint integral literals.
291+
if_chain! {
292+
if let Some(src) = snippet_opt(cx, lit.span);
293+
if let Some(firstch) = src.chars().next();
294+
if char::to_digit(firstch, 10).is_some();
295+
then {
296+
let digit_info = DigitInfo::new(&src, false);
297+
let _ = Self::do_lint(digit_info.digits).map_err(|warning_type| {
298+
warning_type.display(&digit_info.grouping_hint(), cx, &lit.span)
299+
});
300+
}
301+
}
302+
},
303+
LitKind::Float(..) | LitKind::FloatUnsuffixed(..) => {
304+
// Lint floating-point literals.
305+
if_chain! {
306+
if let Some(src) = snippet_opt(cx, lit.span);
307+
if let Some(firstch) = src.chars().next();
308+
if char::to_digit(firstch, 10).is_some();
309+
then {
310+
let digit_info = DigitInfo::new(&src, true);
311+
// Separate digits into integral and fractional parts.
312+
let parts: Vec<&str> = digit_info
313+
.digits
314+
.split_terminator('.')
315+
.collect();
316+
317+
// Lint integral and fractional parts separately, and then check consistency of digit
318+
// groups if both pass.
319+
let _ = Self::do_lint(parts[0])
320+
.map(|integral_group_size| {
321+
if parts.len() > 1 {
322+
// Lint the fractional part of literal just like integral part, but reversed.
323+
let fractional_part = &parts[1].chars().rev().collect::<String>();
324+
let _ = Self::do_lint(fractional_part)
325+
.map(|fractional_group_size| {
326+
let consistent = Self::parts_consistent(integral_group_size,
327+
fractional_group_size,
328+
parts[0].len(),
329+
parts[1].len());
330+
if !consistent {
331+
WarningType::InconsistentDigitGrouping.display(&digit_info.grouping_hint(),
332+
cx,
333+
&lit.span);
334+
}
335+
})
336+
.map_err(|warning_type| warning_type.display(&digit_info.grouping_hint(),
337+
cx,
338+
&lit.span));
339+
}
340+
})
341+
.map_err(|warning_type| warning_type.display(&digit_info.grouping_hint(), cx, &lit.span));
342+
}
343+
}
344+
},
345+
_ => (),
342346
}
343347
}
344348

tests/ui/approx_const.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33

44
#[warn(approx_constant)]
5-
#[allow(unused, shadow_unrelated, similar_names)]
5+
#[allow(unused, shadow_unrelated, similar_names, unreadable_literal)]
66
fn main() {
77
let my_e = 2.7182;
88
let almost_e = 2.718;

tests/ui/unreadable_literal.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,6 @@
55
fn main() {
66
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);
77
let bad = (0b10110_i64, 0x12345678901_usize, 12345_f32, 1.23456_f32);
8+
let good_sci = 1.1234e1;
9+
let bad_sci = 1.12345e1;
810
}

tests/ui/unreadable_literal.stderr

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,5 +24,11 @@ error: long literal lacking separators
2424
7 | let bad = (0b10110_i64, 0x12345678901_usize, 12345_f32, 1.23456_f32);
2525
| ^^^^^^^^^^^ help: consider: `1.234_56_f32`
2626

27-
error: aborting due to 4 previous errors
27+
error: long literal lacking separators
28+
--> $DIR/unreadable_literal.rs:9:19
29+
|
30+
9 | let bad_sci = 1.12345e1;
31+
| ^^^^^^^^^ help: consider: `1.123_45e1`
32+
33+
error: aborting due to 5 previous errors
2834

0 commit comments

Comments
 (0)