Skip to content

Commit 9df3811

Browse files
committed
Auto merge of #3877 - rink1969:3842, r=flip1995
casting integer literal to float is unnecessary fix issue #3842
2 parents 7298929 + d9dd008 commit 9df3811

10 files changed

+219
-135
lines changed

clippy_lints/src/types.rs

+29-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ use rustc::hir::intravisit::{walk_body, walk_expr, walk_ty, FnKind, NestedVisito
1010
use rustc::hir::*;
1111
use rustc::lint::{in_external_macro, LateContext, LateLintPass, LintArray, LintContext, LintPass};
1212
use rustc::ty::layout::LayoutOf;
13-
use rustc::ty::{self, Ty, TyCtxt, TypeckTables};
13+
use rustc::ty::{self, InferTy, Ty, TyCtxt, TypeckTables};
1414
use rustc::{declare_tool_lint, lint_array};
1515
use rustc_errors::Applicability;
1616
use rustc_target::spec::abi::Abi;
@@ -1150,13 +1150,41 @@ fn is_c_void(tcx: TyCtxt<'_, '_, '_>, ty: Ty<'_>) -> bool {
11501150
false
11511151
}
11521152

1153+
/// Returns the mantissa bits wide of a fp type.
1154+
/// Will return 0 if the type is not a fp
1155+
fn fp_ty_mantissa_nbits(typ: Ty<'_>) -> u32 {
1156+
match typ.sty {
1157+
ty::Float(FloatTy::F32) => 23,
1158+
ty::Float(FloatTy::F64) | ty::Infer(InferTy::FloatVar(_)) => 52,
1159+
_ => 0,
1160+
}
1161+
}
1162+
11531163
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for CastPass {
11541164
fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr) {
11551165
if let ExprKind::Cast(ref ex, _) = expr.node {
11561166
let (cast_from, cast_to) = (cx.tables.expr_ty(ex), cx.tables.expr_ty(expr));
11571167
lint_fn_to_numeric_cast(cx, expr, ex, cast_from, cast_to);
11581168
if let ExprKind::Lit(ref lit) = ex.node {
11591169
use syntax::ast::{LitIntType, LitKind};
1170+
if let LitKind::Int(n, _) = lit.node {
1171+
if cast_to.is_fp() {
1172+
let from_nbits = 128 - n.leading_zeros();
1173+
let to_nbits = fp_ty_mantissa_nbits(cast_to);
1174+
if from_nbits != 0 && to_nbits != 0 && from_nbits <= to_nbits {
1175+
span_lint_and_sugg(
1176+
cx,
1177+
UNNECESSARY_CAST,
1178+
expr.span,
1179+
&format!("casting integer literal to {} is unnecessary", cast_to),
1180+
"try",
1181+
format!("{}_{}", n, cast_to),
1182+
Applicability::MachineApplicable,
1183+
);
1184+
return;
1185+
}
1186+
}
1187+
}
11601188
match lit.node {
11611189
LitKind::Int(_, LitIntType::Unsuffixed) | LitKind::FloatUnsuffixed(_) => {},
11621190
_ => {

tests/ui/cast.rs

+14-6
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,16 @@
88
#[allow(clippy::no_effect, clippy::unnecessary_operation)]
99
fn main() {
1010
// Test clippy::cast_precision_loss
11-
1i32 as f32;
12-
1i64 as f32;
13-
1i64 as f64;
14-
1u32 as f32;
15-
1u64 as f32;
16-
1u64 as f64;
11+
let x0 = 1i32;
12+
x0 as f32;
13+
let x1 = 1i64;
14+
x1 as f32;
15+
x1 as f64;
16+
let x2 = 1u32;
17+
x2 as f32;
18+
let x3 = 1u64;
19+
x3 as f32;
20+
x3 as f64;
1721
// Test clippy::cast_possible_truncation
1822
1f32 as i32;
1923
1f32 as u32;
@@ -49,6 +53,10 @@ fn main() {
4953
1f32 as f32;
5054
false as bool;
5155
&1i32 as &i32;
56+
// casting integer literal to float is unnecessary
57+
100 as f32;
58+
100 as f64;
59+
100_i32 as f64;
5260
// Should not trigger
5361
#[rustfmt::skip]
5462
let v = vec!(1);

tests/ui/cast.stderr

+58-40
Original file line numberDiff line numberDiff line change
@@ -1,176 +1,194 @@
11
error: casting i32 to f32 causes a loss of precision (i32 is 32 bits wide, but f32's mantissa is only 23 bits wide)
2-
--> $DIR/cast.rs:11:5
2+
--> $DIR/cast.rs:12:5
33
|
4-
LL | 1i32 as f32;
5-
| ^^^^^^^^^^^
4+
LL | x0 as f32;
5+
| ^^^^^^^^^
66
|
77
= note: `-D clippy::cast-precision-loss` implied by `-D warnings`
88

99
error: casting i64 to f32 causes a loss of precision (i64 is 64 bits wide, but f32's mantissa is only 23 bits wide)
10-
--> $DIR/cast.rs:12:5
10+
--> $DIR/cast.rs:14:5
1111
|
12-
LL | 1i64 as f32;
13-
| ^^^^^^^^^^^
12+
LL | x1 as f32;
13+
| ^^^^^^^^^
1414

1515
error: casting i64 to f64 causes a loss of precision (i64 is 64 bits wide, but f64's mantissa is only 52 bits wide)
16-
--> $DIR/cast.rs:13:5
16+
--> $DIR/cast.rs:15:5
1717
|
18-
LL | 1i64 as f64;
19-
| ^^^^^^^^^^^
18+
LL | x1 as f64;
19+
| ^^^^^^^^^
2020

2121
error: casting u32 to f32 causes a loss of precision (u32 is 32 bits wide, but f32's mantissa is only 23 bits wide)
22-
--> $DIR/cast.rs:14:5
22+
--> $DIR/cast.rs:17:5
2323
|
24-
LL | 1u32 as f32;
25-
| ^^^^^^^^^^^
24+
LL | x2 as f32;
25+
| ^^^^^^^^^
2626

2727
error: casting u64 to f32 causes a loss of precision (u64 is 64 bits wide, but f32's mantissa is only 23 bits wide)
28-
--> $DIR/cast.rs:15:5
28+
--> $DIR/cast.rs:19:5
2929
|
30-
LL | 1u64 as f32;
31-
| ^^^^^^^^^^^
30+
LL | x3 as f32;
31+
| ^^^^^^^^^
3232

3333
error: casting u64 to f64 causes a loss of precision (u64 is 64 bits wide, but f64's mantissa is only 52 bits wide)
34-
--> $DIR/cast.rs:16:5
34+
--> $DIR/cast.rs:20:5
3535
|
36-
LL | 1u64 as f64;
37-
| ^^^^^^^^^^^
36+
LL | x3 as f64;
37+
| ^^^^^^^^^
3838

3939
error: casting f32 to i32 may truncate the value
40-
--> $DIR/cast.rs:18:5
40+
--> $DIR/cast.rs:22:5
4141
|
4242
LL | 1f32 as i32;
4343
| ^^^^^^^^^^^
4444
|
4545
= note: `-D clippy::cast-possible-truncation` implied by `-D warnings`
4646

4747
error: casting f32 to u32 may truncate the value
48-
--> $DIR/cast.rs:19:5
48+
--> $DIR/cast.rs:23:5
4949
|
5050
LL | 1f32 as u32;
5151
| ^^^^^^^^^^^
5252

5353
error: casting f32 to u32 may lose the sign of the value
54-
--> $DIR/cast.rs:19:5
54+
--> $DIR/cast.rs:23:5
5555
|
5656
LL | 1f32 as u32;
5757
| ^^^^^^^^^^^
5858
|
5959
= note: `-D clippy::cast-sign-loss` implied by `-D warnings`
6060

6161
error: casting f64 to f32 may truncate the value
62-
--> $DIR/cast.rs:20:5
62+
--> $DIR/cast.rs:24:5
6363
|
6464
LL | 1f64 as f32;
6565
| ^^^^^^^^^^^
6666

6767
error: casting i32 to i8 may truncate the value
68-
--> $DIR/cast.rs:21:5
68+
--> $DIR/cast.rs:25:5
6969
|
7070
LL | 1i32 as i8;
7171
| ^^^^^^^^^^
7272

7373
error: casting i32 to u8 may truncate the value
74-
--> $DIR/cast.rs:22:5
74+
--> $DIR/cast.rs:26:5
7575
|
7676
LL | 1i32 as u8;
7777
| ^^^^^^^^^^
7878

7979
error: casting f64 to isize may truncate the value
80-
--> $DIR/cast.rs:23:5
80+
--> $DIR/cast.rs:27:5
8181
|
8282
LL | 1f64 as isize;
8383
| ^^^^^^^^^^^^^
8484

8585
error: casting f64 to usize may truncate the value
86-
--> $DIR/cast.rs:24:5
86+
--> $DIR/cast.rs:28:5
8787
|
8888
LL | 1f64 as usize;
8989
| ^^^^^^^^^^^^^
9090

9191
error: casting f64 to usize may lose the sign of the value
92-
--> $DIR/cast.rs:24:5
92+
--> $DIR/cast.rs:28:5
9393
|
9494
LL | 1f64 as usize;
9595
| ^^^^^^^^^^^^^
9696

9797
error: casting u8 to i8 may wrap around the value
98-
--> $DIR/cast.rs:26:5
98+
--> $DIR/cast.rs:30:5
9999
|
100100
LL | 1u8 as i8;
101101
| ^^^^^^^^^
102102
|
103103
= note: `-D clippy::cast-possible-wrap` implied by `-D warnings`
104104

105105
error: casting u16 to i16 may wrap around the value
106-
--> $DIR/cast.rs:27:5
106+
--> $DIR/cast.rs:31:5
107107
|
108108
LL | 1u16 as i16;
109109
| ^^^^^^^^^^^
110110

111111
error: casting u32 to i32 may wrap around the value
112-
--> $DIR/cast.rs:28:5
112+
--> $DIR/cast.rs:32:5
113113
|
114114
LL | 1u32 as i32;
115115
| ^^^^^^^^^^^
116116

117117
error: casting u64 to i64 may wrap around the value
118-
--> $DIR/cast.rs:29:5
118+
--> $DIR/cast.rs:33:5
119119
|
120120
LL | 1u64 as i64;
121121
| ^^^^^^^^^^^
122122

123123
error: casting usize to isize may wrap around the value
124-
--> $DIR/cast.rs:30:5
124+
--> $DIR/cast.rs:34:5
125125
|
126126
LL | 1usize as isize;
127127
| ^^^^^^^^^^^^^^^
128128

129129
error: casting f32 to f64 may become silently lossy if types change
130-
--> $DIR/cast.rs:32:5
130+
--> $DIR/cast.rs:36:5
131131
|
132132
LL | 1.0f32 as f64;
133133
| ^^^^^^^^^^^^^ help: try: `f64::from(1.0f32)`
134134
|
135135
= note: `-D clippy::cast-lossless` implied by `-D warnings`
136136

137137
error: casting u8 to u16 may become silently lossy if types change
138-
--> $DIR/cast.rs:34:5
138+
--> $DIR/cast.rs:38:5
139139
|
140140
LL | (1u8 + 1u8) as u16;
141141
| ^^^^^^^^^^^^^^^^^^ help: try: `u16::from(1u8 + 1u8)`
142142

143143
error: casting i32 to u32 may lose the sign of the value
144-
--> $DIR/cast.rs:37:5
144+
--> $DIR/cast.rs:41:5
145145
|
146146
LL | -1i32 as u32;
147147
| ^^^^^^^^^^^^
148148

149149
error: casting isize to usize may lose the sign of the value
150-
--> $DIR/cast.rs:39:5
150+
--> $DIR/cast.rs:43:5
151151
|
152152
LL | -1isize as usize;
153153
| ^^^^^^^^^^^^^^^^
154154

155155
error: casting to the same type is unnecessary (`i32` -> `i32`)
156-
--> $DIR/cast.rs:48:5
156+
--> $DIR/cast.rs:52:5
157157
|
158158
LL | 1i32 as i32;
159159
| ^^^^^^^^^^^
160160
|
161161
= note: `-D clippy::unnecessary-cast` implied by `-D warnings`
162162

163163
error: casting to the same type is unnecessary (`f32` -> `f32`)
164-
--> $DIR/cast.rs:49:5
164+
--> $DIR/cast.rs:53:5
165165
|
166166
LL | 1f32 as f32;
167167
| ^^^^^^^^^^^
168168

169169
error: casting to the same type is unnecessary (`bool` -> `bool`)
170-
--> $DIR/cast.rs:50:5
170+
--> $DIR/cast.rs:54:5
171171
|
172172
LL | false as bool;
173173
| ^^^^^^^^^^^^^
174174

175-
error: aborting due to 27 previous errors
175+
error: casting integer literal to f32 is unnecessary
176+
--> $DIR/cast.rs:57:5
177+
|
178+
LL | 100 as f32;
179+
| ^^^^^^^^^^ help: try: `100_f32`
180+
181+
error: casting integer literal to f64 is unnecessary
182+
--> $DIR/cast.rs:58:5
183+
|
184+
LL | 100 as f64;
185+
| ^^^^^^^^^^ help: try: `100_f64`
186+
187+
error: casting integer literal to f64 is unnecessary
188+
--> $DIR/cast.rs:59:5
189+
|
190+
LL | 100_i32 as f64;
191+
| ^^^^^^^^^^^^^^ help: try: `100_f64`
192+
193+
error: aborting due to 30 previous errors
176194

tests/ui/cast_lossless_float.fixed

+16-10
Original file line numberDiff line numberDiff line change
@@ -5,16 +5,22 @@
55

66
fn main() {
77
// Test clippy::cast_lossless with casts to floating-point types
8-
f32::from(1i8);
9-
f64::from(1i8);
10-
f32::from(1u8);
11-
f64::from(1u8);
12-
f32::from(1i16);
13-
f64::from(1i16);
14-
f32::from(1u16);
15-
f64::from(1u16);
16-
f64::from(1i32);
17-
f64::from(1u32);
8+
let x0 = 1i8;
9+
f32::from(x0);
10+
f64::from(x0);
11+
let x1 = 1u8;
12+
f32::from(x1);
13+
f64::from(x1);
14+
let x2 = 1i16;
15+
f32::from(x2);
16+
f64::from(x2);
17+
let x3 = 1u16;
18+
f32::from(x3);
19+
f64::from(x3);
20+
let x4 = 1i32;
21+
f64::from(x4);
22+
let x5 = 1u32;
23+
f64::from(x5);
1824
}
1925

2026
// The lint would suggest using `f64::from(input)` here but the `XX::from` function is not const,

tests/ui/cast_lossless_float.rs

+16-10
Original file line numberDiff line numberDiff line change
@@ -5,16 +5,22 @@
55

66
fn main() {
77
// Test clippy::cast_lossless with casts to floating-point types
8-
1i8 as f32;
9-
1i8 as f64;
10-
1u8 as f32;
11-
1u8 as f64;
12-
1i16 as f32;
13-
1i16 as f64;
14-
1u16 as f32;
15-
1u16 as f64;
16-
1i32 as f64;
17-
1u32 as f64;
8+
let x0 = 1i8;
9+
x0 as f32;
10+
x0 as f64;
11+
let x1 = 1u8;
12+
x1 as f32;
13+
x1 as f64;
14+
let x2 = 1i16;
15+
x2 as f32;
16+
x2 as f64;
17+
let x3 = 1u16;
18+
x3 as f32;
19+
x3 as f64;
20+
let x4 = 1i32;
21+
x4 as f64;
22+
let x5 = 1u32;
23+
x5 as f64;
1824
}
1925

2026
// The lint would suggest using `f64::from(input)` here but the `XX::from` function is not const,

0 commit comments

Comments
 (0)