Skip to content

Commit 3cee52d

Browse files
authored
Rollup merge of rust-lang#98972 - TaKO8Ki:suggest-adding-missing-zero-to-floating-point-number, r=compiler-errors
Suggest adding a missing zero to a floating point number fixes rust-lang#98836
2 parents 9b65832 + e03cb7f commit 3cee52d

6 files changed

+219
-4
lines changed

compiler/rustc_typeck/src/check/expr.rs

+45-4
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ use rustc_middle::ty::{self, AdtKind, DefIdTree, Ty, TypeVisitable};
4848
use rustc_session::parse::feature_err;
4949
use rustc_span::hygiene::DesugaringKind;
5050
use rustc_span::lev_distance::find_best_match_for_name;
51-
use rustc_span::source_map::Span;
51+
use rustc_span::source_map::{Span, Spanned};
5252
use rustc_span::symbol::{kw, sym, Ident, Symbol};
5353
use rustc_span::{BytePos, Pos};
5454
use rustc_target::spec::abi::Abi::RustIntrinsic;
@@ -2162,14 +2162,55 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
21622162
} else if !expr_t.is_primitive_ty() {
21632163
self.ban_nonexisting_field(field, base, expr, expr_t);
21642164
} else {
2165-
type_error_struct!(
2165+
let field_name = field.to_string();
2166+
let mut err = type_error_struct!(
21662167
self.tcx().sess,
21672168
field.span,
21682169
expr_t,
21692170
E0610,
21702171
"`{expr_t}` is a primitive type and therefore doesn't have fields",
2171-
)
2172-
.emit();
2172+
);
2173+
let is_valid_suffix = |field: String| {
2174+
if field == "f32" || field == "f64" {
2175+
return true;
2176+
}
2177+
let mut chars = field.chars().peekable();
2178+
match chars.peek() {
2179+
Some('e') | Some('E') => {
2180+
chars.next();
2181+
if let Some(c) = chars.peek()
2182+
&& !c.is_numeric() && *c != '-' && *c != '+'
2183+
{
2184+
return false;
2185+
}
2186+
while let Some(c) = chars.peek() {
2187+
if !c.is_numeric() {
2188+
break;
2189+
}
2190+
chars.next();
2191+
}
2192+
}
2193+
_ => (),
2194+
}
2195+
let suffix = chars.collect::<String>();
2196+
suffix.is_empty() || suffix == "f32" || suffix == "f64"
2197+
};
2198+
if let ty::Infer(ty::IntVar(_)) = expr_t.kind()
2199+
&& let ExprKind::Lit(Spanned {
2200+
node: ast::LitKind::Int(_, ast::LitIntType::Unsuffixed),
2201+
..
2202+
}) = base.kind
2203+
&& !base.span.from_expansion()
2204+
&& is_valid_suffix(field_name)
2205+
{
2206+
err.span_suggestion_verbose(
2207+
field.span.shrink_to_lo(),
2208+
"If the number is meant to be a floating point number, consider adding a `0` after the period",
2209+
'0',
2210+
Applicability::MaybeIncorrect,
2211+
);
2212+
}
2213+
err.emit();
21732214
}
21742215

21752216
self.tcx().ty_error()
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
macro_rules! num { () => { 1 } }
2+
3+
fn main() {
4+
let x = 1i32;
5+
x.e10; //~ERROR `i32` is a primitive type and therefore doesn't have fields
6+
7+
let y = 1;
8+
y.e10; //~ERROR `{integer}` is a primitive type and therefore doesn't have fields
9+
10+
2u32.e10; //~ERROR `u32` is a primitive type and therefore doesn't have fields
11+
12+
num!().e10; //~ERROR `{integer}` is a primitive type and therefore doesn't have fields
13+
14+
2.e10foo; //~ERROR `{integer}` is a primitive type and therefore doesn't have fields
15+
16+
42._;
17+
//~^ERROR expected identifier, found reserved identifier `_`
18+
//~|ERROR `{integer}` is a primitive type and therefore doesn't have fields
19+
20+
42.a; //~ERROR `{integer}` is a primitive type and therefore doesn't have fields
21+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
error: expected identifier, found reserved identifier `_`
2+
--> $DIR/do-not-suggest-adding-missing-zero-to-floating-point-number.rs:16:8
3+
|
4+
LL | 42._;
5+
| ^ expected identifier, found reserved identifier
6+
7+
error[E0610]: `i32` is a primitive type and therefore doesn't have fields
8+
--> $DIR/do-not-suggest-adding-missing-zero-to-floating-point-number.rs:5:7
9+
|
10+
LL | x.e10;
11+
| ^^^
12+
13+
error[E0610]: `{integer}` is a primitive type and therefore doesn't have fields
14+
--> $DIR/do-not-suggest-adding-missing-zero-to-floating-point-number.rs:8:7
15+
|
16+
LL | y.e10;
17+
| ^^^
18+
19+
error[E0610]: `u32` is a primitive type and therefore doesn't have fields
20+
--> $DIR/do-not-suggest-adding-missing-zero-to-floating-point-number.rs:10:10
21+
|
22+
LL | 2u32.e10;
23+
| ^^^
24+
25+
error[E0610]: `{integer}` is a primitive type and therefore doesn't have fields
26+
--> $DIR/do-not-suggest-adding-missing-zero-to-floating-point-number.rs:12:12
27+
|
28+
LL | num!().e10;
29+
| ^^^
30+
31+
error[E0610]: `{integer}` is a primitive type and therefore doesn't have fields
32+
--> $DIR/do-not-suggest-adding-missing-zero-to-floating-point-number.rs:14:7
33+
|
34+
LL | 2.e10foo;
35+
| ^^^^^^
36+
37+
error[E0610]: `{integer}` is a primitive type and therefore doesn't have fields
38+
--> $DIR/do-not-suggest-adding-missing-zero-to-floating-point-number.rs:16:8
39+
|
40+
LL | 42._;
41+
| ^
42+
43+
error[E0610]: `{integer}` is a primitive type and therefore doesn't have fields
44+
--> $DIR/do-not-suggest-adding-missing-zero-to-floating-point-number.rs:20:8
45+
|
46+
LL | 42.a;
47+
| ^
48+
49+
error: aborting due to 8 previous errors
50+
51+
For more information about this error, try `rustc --explain E0610`.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
// run-rustfix
2+
3+
fn main() {
4+
2.0e1; //~ERROR `{integer}` is a primitive type and therefore doesn't have fields
5+
2.0E1; //~ERROR `{integer}` is a primitive type and therefore doesn't have fields
6+
2.0f32; //~ERROR `{integer}` is a primitive type and therefore doesn't have fields
7+
2.0f64; //~ERROR `{integer}` is a primitive type and therefore doesn't have fields
8+
2.0e+12; //~ERROR `{integer}` is a primitive type and therefore doesn't have fields
9+
2.0e-12; //~ERROR `{integer}` is a primitive type and therefore doesn't have fields
10+
2.0e1f32; //~ERROR `{integer}` is a primitive type and therefore doesn't have fields
11+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
// run-rustfix
2+
3+
fn main() {
4+
2.e1; //~ERROR `{integer}` is a primitive type and therefore doesn't have fields
5+
2.E1; //~ERROR `{integer}` is a primitive type and therefore doesn't have fields
6+
2.f32; //~ERROR `{integer}` is a primitive type and therefore doesn't have fields
7+
2.f64; //~ERROR `{integer}` is a primitive type and therefore doesn't have fields
8+
2.e+12; //~ERROR `{integer}` is a primitive type and therefore doesn't have fields
9+
2.e-12; //~ERROR `{integer}` is a primitive type and therefore doesn't have fields
10+
2.e1f32; //~ERROR `{integer}` is a primitive type and therefore doesn't have fields
11+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
error[E0610]: `{integer}` is a primitive type and therefore doesn't have fields
2+
--> $DIR/suggest-adding-missing-zero-to-floating-point-number.rs:4:7
3+
|
4+
LL | 2.e1;
5+
| ^^
6+
|
7+
help: If the number is meant to be a floating point number, consider adding a `0` after the period
8+
|
9+
LL | 2.0e1;
10+
| +
11+
12+
error[E0610]: `{integer}` is a primitive type and therefore doesn't have fields
13+
--> $DIR/suggest-adding-missing-zero-to-floating-point-number.rs:5:7
14+
|
15+
LL | 2.E1;
16+
| ^^
17+
|
18+
help: If the number is meant to be a floating point number, consider adding a `0` after the period
19+
|
20+
LL | 2.0E1;
21+
| +
22+
23+
error[E0610]: `{integer}` is a primitive type and therefore doesn't have fields
24+
--> $DIR/suggest-adding-missing-zero-to-floating-point-number.rs:6:7
25+
|
26+
LL | 2.f32;
27+
| ^^^
28+
|
29+
help: If the number is meant to be a floating point number, consider adding a `0` after the period
30+
|
31+
LL | 2.0f32;
32+
| +
33+
34+
error[E0610]: `{integer}` is a primitive type and therefore doesn't have fields
35+
--> $DIR/suggest-adding-missing-zero-to-floating-point-number.rs:7:7
36+
|
37+
LL | 2.f64;
38+
| ^^^
39+
|
40+
help: If the number is meant to be a floating point number, consider adding a `0` after the period
41+
|
42+
LL | 2.0f64;
43+
| +
44+
45+
error[E0610]: `{integer}` is a primitive type and therefore doesn't have fields
46+
--> $DIR/suggest-adding-missing-zero-to-floating-point-number.rs:8:7
47+
|
48+
LL | 2.e+12;
49+
| ^
50+
|
51+
help: If the number is meant to be a floating point number, consider adding a `0` after the period
52+
|
53+
LL | 2.0e+12;
54+
| +
55+
56+
error[E0610]: `{integer}` is a primitive type and therefore doesn't have fields
57+
--> $DIR/suggest-adding-missing-zero-to-floating-point-number.rs:9:7
58+
|
59+
LL | 2.e-12;
60+
| ^
61+
|
62+
help: If the number is meant to be a floating point number, consider adding a `0` after the period
63+
|
64+
LL | 2.0e-12;
65+
| +
66+
67+
error[E0610]: `{integer}` is a primitive type and therefore doesn't have fields
68+
--> $DIR/suggest-adding-missing-zero-to-floating-point-number.rs:10:7
69+
|
70+
LL | 2.e1f32;
71+
| ^^^^^
72+
|
73+
help: If the number is meant to be a floating point number, consider adding a `0` after the period
74+
|
75+
LL | 2.0e1f32;
76+
| +
77+
78+
error: aborting due to 7 previous errors
79+
80+
For more information about this error, try `rustc --explain E0610`.

0 commit comments

Comments
 (0)