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.
This commit is contained in:
Smitty 2021-03-15 08:11:02 -04:00
parent 5fe790e3c4
commit 5eae9af193
3 changed files with 133 additions and 0 deletions

View File

@ -563,6 +563,15 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> {
}
}
}
} else if err_code == &rustc_errors::error_code!(E0412) {
if let Some(correct) = Self::likely_rust_type(path) {
err.span_suggestion(
span,
"perhaps you intended to use this type",
correct.to_string(),
Applicability::MaybeIncorrect,
);
}
}
}
@ -1243,6 +1252,23 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> {
}
}
// Returns the name of the Rust type approximately corresponding to
// a type name in another programming language.
fn likely_rust_type(path: &[Segment]) -> Option<Symbol> {
let name = path[path.len() - 1].ident.as_str();
// Common Java types
Some(match &*name {
"byte" => sym::u8, // In Java, bytes are signed, but in practice one almost always wants unsigned bytes.
"short" => sym::i16,
"boolean" => sym::bool,
"int" => sym::i32,
"long" => sym::i64,
"float" => sym::f32,
"double" => sym::f64,
_ => return None,
})
}
/// Only used in a specific case of type ascription suggestions
fn get_colon_suggestion_span(&self, start: Span) -> Span {
let sm = self.r.session.source_map();

View File

@ -0,0 +1,35 @@
type Real = double;
//~^ ERROR cannot find type `double` in this scope
//~| HELP perhaps you intended to use this type
fn main() {
let x: Real = 3.5;
let y: long = 74802374902374923;
//~^ ERROR cannot find type `long` in this scope
//~| HELP perhaps you intended to use this type
}
fn z(a: boolean) {
//~^ ERROR cannot find type `boolean` in this scope
//~| HELP perhaps you intended to use this type
}
fn a() -> byte {
//~^ ERROR cannot find type `byte` in this scope
//~| HELP perhaps you intended to use this type
3
}
struct Data { //~ HELP you might be missing a type parameter
width: float,
//~^ ERROR cannot find type `float` in this scope
//~| HELP perhaps you intended to use this type
depth: Option<int>,
//~^ ERROR cannot find type `int` in this scope
//~| HELP perhaps you intended to use this type
}
trait Stuff {}
impl Stuff for short {}
//~^ ERROR cannot find type `short` in this scope
//~| HELP perhaps you intended to use this type

View File

@ -0,0 +1,72 @@
error[E0412]: cannot find type `double` in this scope
--> $DIR/recommend-literal.rs:1:13
|
LL | type Real = double;
| ^^^^^^
| |
| not found in this scope
| help: perhaps you intended to use this type: `f64`
error[E0412]: cannot find type `long` in this scope
--> $DIR/recommend-literal.rs:7:12
|
LL | let y: long = 74802374902374923;
| ^^^^
| |
| not found in this scope
| help: perhaps you intended to use this type: `i64`
error[E0412]: cannot find type `boolean` in this scope
--> $DIR/recommend-literal.rs:12:9
|
LL | fn z(a: boolean) {
| ^^^^^^^
| |
| not found in this scope
| help: perhaps you intended to use this type: `bool`
error[E0412]: cannot find type `byte` in this scope
--> $DIR/recommend-literal.rs:17:11
|
LL | fn a() -> byte {
| ^^^^
| |
| not found in this scope
| help: perhaps you intended to use this type: `u8`
error[E0412]: cannot find type `float` in this scope
--> $DIR/recommend-literal.rs:24:12
|
LL | width: float,
| ^^^^^
| |
| not found in this scope
| help: perhaps you intended to use this type: `f32`
error[E0412]: cannot find type `int` in this scope
--> $DIR/recommend-literal.rs:27:19
|
LL | depth: Option<int>,
| ^^^ not found in this scope
|
help: perhaps you intended to use this type
|
LL | depth: Option<i32>,
| ^^^
help: you might be missing a type parameter
|
LL | struct Data<int> {
| ^^^^^
error[E0412]: cannot find type `short` in this scope
--> $DIR/recommend-literal.rs:33:16
|
LL | impl Stuff for short {}
| ^^^^^
| |
| not found in this scope
| help: perhaps you intended to use this type: `i16`
error: aborting due to 7 previous errors
For more information about this error, try `rustc --explain E0412`.