Skip to content

Commit a52eeca

Browse files
committed
Supress excessive_precision when constants are overly precise
1 parent 034136d commit a52eeca

File tree

4 files changed

+80
-2
lines changed

4 files changed

+80
-2
lines changed

clippy_lints/src/float_literal.rs

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ declare_clippy_lint! {
1313
/// Checks for float literals with a precision greater
1414
/// than that supported by the underlying type.
1515
///
16+
/// The lint is suppressed for literals with over 40 digits.
17+
///
1618
/// ### Why is this bad?
1719
/// Rust will truncate the literal silently.
1820
///
@@ -126,13 +128,23 @@ impl<'tcx> LateLintPass<'tcx> for FloatLiteral {
126128
},
127129
);
128130
}
129-
} else if digits > max as usize && count_digits(&float_str) < count_digits(sym_str) {
131+
} else if digits > max as usize && count_digits(&float_str) < digits {
132+
if digits >= 40 && is_const_item(cx, expr) {
133+
// If a big enough number of digits is specified and it's a constant
134+
// we assume the user is definining a constant, and excessive precision is ok
135+
return;
136+
}
130137
span_lint_and_then(
131138
cx,
132139
EXCESSIVE_PRECISION,
133140
expr.span,
134141
"float has excessive precision",
135142
|diag| {
143+
if digits >= 40
144+
&& let Some(let_stmt) = maybe_let_stmt(cx, expr)
145+
{
146+
diag.span_note(let_stmt.span, "consider making it a `const` item");
147+
}
136148
diag.span_suggestion_verbose(
137149
expr.span,
138150
"consider changing the type or truncating it to",
@@ -196,3 +208,19 @@ impl FloatFormat {
196208
}
197209
}
198210
}
211+
212+
fn is_const_item(cx: &LateContext<'_>, expr: &hir::Expr<'_>) -> bool {
213+
let parent = cx.tcx.parent_hir_node(expr.hir_id);
214+
if let hir::Node::Item(itm) = parent {
215+
return matches!(itm.kind, hir::ItemKind::Const(..));
216+
}
217+
false
218+
}
219+
220+
fn maybe_let_stmt<'a>(cx: &LateContext<'a>, expr: &hir::Expr<'_>) -> Option<&'a hir::LetStmt<'a>> {
221+
let parent = cx.tcx.parent_hir_node(expr.hir_id);
222+
match parent {
223+
hir::Node::LetStmt(let_stmt) => Some(let_stmt),
224+
_ => None,
225+
}
226+
}

tests/ui/excessive_precision.fixed

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,4 +101,12 @@ fn main() {
101101
const _: f64 = 3.0;
102102
//~^ excessive_precision
103103
const _: f64 = 3.0000000000000000;
104+
105+
// Overly specified constants
106+
let _: f32 = 1.012_345_7;
107+
//~^ excessive_precision
108+
let _: f64 = 1.012_345_678_901_234_6;
109+
//~^ excessive_precision
110+
const _: f32 = 1.01234567890123456789012345678901234567890;
111+
const _: f64 = 1.01234567890123456789012345678901234567890;
104112
}

tests/ui/excessive_precision.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,4 +101,12 @@ fn main() {
101101
const _: f64 = 3.0000000000000000e+00;
102102
//~^ excessive_precision
103103
const _: f64 = 3.0000000000000000;
104+
105+
// Overly specified constants
106+
let _: f32 = 1.01234567890123456789012345678901234567890;
107+
//~^ excessive_precision
108+
let _: f64 = 1.01234567890123456789012345678901234567890;
109+
//~^ excessive_precision
110+
const _: f32 = 1.01234567890123456789012345678901234567890;
111+
const _: f64 = 1.01234567890123456789012345678901234567890;
104112
}

tests/ui/excessive_precision.stderr

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -192,5 +192,39 @@ LL - const _: f64 = 3.0000000000000000e+00;
192192
LL + const _: f64 = 3.0;
193193
|
194194

195-
error: aborting due to 16 previous errors
195+
error: float has excessive precision
196+
--> tests/ui/excessive_precision.rs:106:18
197+
|
198+
LL | let _: f32 = 1.01234567890123456789012345678901234567890;
199+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
200+
|
201+
note: consider making it a `const` item
202+
--> tests/ui/excessive_precision.rs:106:5
203+
|
204+
LL | let _: f32 = 1.01234567890123456789012345678901234567890;
205+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
206+
help: consider changing the type or truncating it to
207+
|
208+
LL - let _: f32 = 1.01234567890123456789012345678901234567890;
209+
LL + let _: f32 = 1.012_345_7;
210+
|
211+
212+
error: float has excessive precision
213+
--> tests/ui/excessive_precision.rs:108:18
214+
|
215+
LL | let _: f64 = 1.01234567890123456789012345678901234567890;
216+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
217+
|
218+
note: consider making it a `const` item
219+
--> tests/ui/excessive_precision.rs:108:5
220+
|
221+
LL | let _: f64 = 1.01234567890123456789012345678901234567890;
222+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
223+
help: consider changing the type or truncating it to
224+
|
225+
LL - let _: f64 = 1.01234567890123456789012345678901234567890;
226+
LL + let _: f64 = 1.012_345_678_901_234_6;
227+
|
228+
229+
error: aborting due to 18 previous errors
196230

0 commit comments

Comments
 (0)