about summary refs log tree commit diff
diff options
context:
space:
mode:
authorSmitty <me@smitop.com>2021-03-15 08:11:02 -0400
committerSmitty <me@smitop.com>2021-03-15 08:11:02 -0400
commit5eae9af193efca654a4e20ec0766781c24b7eb87 (patch)
tree4bea9462a10cbfc3b9aeef06a3356a3bdeff34fd
parent5fe790e3c40710ecb95ddaadb98b59a3bb4f8326 (diff)
downloadrust-5eae9af193efca654a4e20ec0766781c24b7eb87.tar.gz
rust-5eae9af193efca654a4e20ec0766781c24b7eb87.zip
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.
-rw-r--r--compiler/rustc_resolve/src/late/diagnostics.rs26
-rw-r--r--src/test/ui/lint/recommend-literal.rs35
-rw-r--r--src/test/ui/lint/recommend-literal.stderr72
3 files changed, 133 insertions, 0 deletions
diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs
index e7b3d459766..e85d78db22c 100644
--- a/compiler/rustc_resolve/src/late/diagnostics.rs
+++ b/compiler/rustc_resolve/src/late/diagnostics.rs
@@ -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();
diff --git a/src/test/ui/lint/recommend-literal.rs b/src/test/ui/lint/recommend-literal.rs
new file mode 100644
index 00000000000..f60d3d10dce
--- /dev/null
+++ b/src/test/ui/lint/recommend-literal.rs
@@ -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
diff --git a/src/test/ui/lint/recommend-literal.stderr b/src/test/ui/lint/recommend-literal.stderr
new file mode 100644
index 00000000000..b01073b42b8
--- /dev/null
+++ b/src/test/ui/lint/recommend-literal.stderr
@@ -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`.