Skip to content

Commit 5eae9af

Browse files
committed
Custom error on literal names from other languages
This detects all Java literal types and all single word C data types, and suggests the corresponding Rust literal type.
1 parent 5fe790e commit 5eae9af

File tree

3 files changed

+133
-0
lines changed

3 files changed

+133
-0
lines changed

Diff for: compiler/rustc_resolve/src/late/diagnostics.rs

+26
Original file line numberDiff line numberDiff line change
@@ -563,6 +563,15 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> {
563563
}
564564
}
565565
}
566+
} else if err_code == &rustc_errors::error_code!(E0412) {
567+
if let Some(correct) = Self::likely_rust_type(path) {
568+
err.span_suggestion(
569+
span,
570+
"perhaps you intended to use this type",
571+
correct.to_string(),
572+
Applicability::MaybeIncorrect,
573+
);
574+
}
566575
}
567576
}
568577

@@ -1243,6 +1252,23 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> {
12431252
}
12441253
}
12451254

1255+
// Returns the name of the Rust type approximately corresponding to
1256+
// a type name in another programming language.
1257+
fn likely_rust_type(path: &[Segment]) -> Option<Symbol> {
1258+
let name = path[path.len() - 1].ident.as_str();
1259+
// Common Java types
1260+
Some(match &*name {
1261+
"byte" => sym::u8, // In Java, bytes are signed, but in practice one almost always wants unsigned bytes.
1262+
"short" => sym::i16,
1263+
"boolean" => sym::bool,
1264+
"int" => sym::i32,
1265+
"long" => sym::i64,
1266+
"float" => sym::f32,
1267+
"double" => sym::f64,
1268+
_ => return None,
1269+
})
1270+
}
1271+
12461272
/// Only used in a specific case of type ascription suggestions
12471273
fn get_colon_suggestion_span(&self, start: Span) -> Span {
12481274
let sm = self.r.session.source_map();

Diff for: src/test/ui/lint/recommend-literal.rs

+35
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
type Real = double;
2+
//~^ ERROR cannot find type `double` in this scope
3+
//~| HELP perhaps you intended to use this type
4+
5+
fn main() {
6+
let x: Real = 3.5;
7+
let y: long = 74802374902374923;
8+
//~^ ERROR cannot find type `long` in this scope
9+
//~| HELP perhaps you intended to use this type
10+
}
11+
12+
fn z(a: boolean) {
13+
//~^ ERROR cannot find type `boolean` in this scope
14+
//~| HELP perhaps you intended to use this type
15+
}
16+
17+
fn a() -> byte {
18+
//~^ ERROR cannot find type `byte` in this scope
19+
//~| HELP perhaps you intended to use this type
20+
3
21+
}
22+
23+
struct Data { //~ HELP you might be missing a type parameter
24+
width: float,
25+
//~^ ERROR cannot find type `float` in this scope
26+
//~| HELP perhaps you intended to use this type
27+
depth: Option<int>,
28+
//~^ ERROR cannot find type `int` in this scope
29+
//~| HELP perhaps you intended to use this type
30+
}
31+
32+
trait Stuff {}
33+
impl Stuff for short {}
34+
//~^ ERROR cannot find type `short` in this scope
35+
//~| HELP perhaps you intended to use this type

Diff for: src/test/ui/lint/recommend-literal.stderr

+72
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
error[E0412]: cannot find type `double` in this scope
2+
--> $DIR/recommend-literal.rs:1:13
3+
|
4+
LL | type Real = double;
5+
| ^^^^^^
6+
| |
7+
| not found in this scope
8+
| help: perhaps you intended to use this type: `f64`
9+
10+
error[E0412]: cannot find type `long` in this scope
11+
--> $DIR/recommend-literal.rs:7:12
12+
|
13+
LL | let y: long = 74802374902374923;
14+
| ^^^^
15+
| |
16+
| not found in this scope
17+
| help: perhaps you intended to use this type: `i64`
18+
19+
error[E0412]: cannot find type `boolean` in this scope
20+
--> $DIR/recommend-literal.rs:12:9
21+
|
22+
LL | fn z(a: boolean) {
23+
| ^^^^^^^
24+
| |
25+
| not found in this scope
26+
| help: perhaps you intended to use this type: `bool`
27+
28+
error[E0412]: cannot find type `byte` in this scope
29+
--> $DIR/recommend-literal.rs:17:11
30+
|
31+
LL | fn a() -> byte {
32+
| ^^^^
33+
| |
34+
| not found in this scope
35+
| help: perhaps you intended to use this type: `u8`
36+
37+
error[E0412]: cannot find type `float` in this scope
38+
--> $DIR/recommend-literal.rs:24:12
39+
|
40+
LL | width: float,
41+
| ^^^^^
42+
| |
43+
| not found in this scope
44+
| help: perhaps you intended to use this type: `f32`
45+
46+
error[E0412]: cannot find type `int` in this scope
47+
--> $DIR/recommend-literal.rs:27:19
48+
|
49+
LL | depth: Option<int>,
50+
| ^^^ not found in this scope
51+
|
52+
help: perhaps you intended to use this type
53+
|
54+
LL | depth: Option<i32>,
55+
| ^^^
56+
help: you might be missing a type parameter
57+
|
58+
LL | struct Data<int> {
59+
| ^^^^^
60+
61+
error[E0412]: cannot find type `short` in this scope
62+
--> $DIR/recommend-literal.rs:33:16
63+
|
64+
LL | impl Stuff for short {}
65+
| ^^^^^
66+
| |
67+
| not found in this scope
68+
| help: perhaps you intended to use this type: `i16`
69+
70+
error: aborting due to 7 previous errors
71+
72+
For more information about this error, try `rustc --explain E0412`.

0 commit comments

Comments
 (0)