Skip to content

Commit

Permalink
Custom error on literal names from other languages
Browse files Browse the repository at this point in the history
This detects all Java literal types and all single word C data types,
and suggests the corresponding Rust literal type.
  • Loading branch information
syvb committed Mar 15, 2021
1 parent 5fe790e commit 5eae9af
Show file tree
Hide file tree
Showing 3 changed files with 133 additions and 0 deletions.
26 changes: 26 additions & 0 deletions compiler/rustc_resolve/src/late/diagnostics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
);
}
}
}

Expand Down Expand Up @@ -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();
Expand Down
35 changes: 35 additions & 0 deletions src/test/ui/lint/recommend-literal.rs
Original file line number Diff line number Diff line change
@@ -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
72 changes: 72 additions & 0 deletions src/test/ui/lint/recommend-literal.stderr
Original file line number Diff line number Diff line change
@@ -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`.

0 comments on commit 5eae9af

Please sign in to comment.