about summary refs log tree commit diff
diff options
context:
space:
mode:
authorEsteban Kuber <esteban@kuber.com.ar>2021-12-15 22:59:32 +0000
committerEsteban Kuber <esteban@kuber.com.ar>2022-03-27 02:20:16 +0000
commit474626af50ae9836b56a351edf59c1ca9b104b5c (patch)
tree7596f2f21457d46baa99d269313cc4a07a741863
parent3fe3b89cd57229343eeca753fdd8c63d9b03c65c (diff)
downloadrust-474626af50ae9836b56a351edf59c1ca9b104b5c.tar.gz
rust-474626af50ae9836b56a351edf59c1ca9b104b5c.zip
Eagerly replace `{integer}`/`{float}` with `i32`/`f64` for suggestion
-rw-r--r--compiler/rustc_infer/src/infer/mod.rs31
-rw-r--r--compiler/rustc_typeck/src/check/fn_ctxt/suggestions.rs2
-rw-r--r--src/test/ui/issues/issue-66706.stderr6
-rw-r--r--src/test/ui/proc-macro/span-preservation.stderr8
-rw-r--r--src/test/ui/return/return-type.stderr14
5 files changed, 49 insertions, 12 deletions
diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs
index 2886d921c70..5878cfdf0b7 100644
--- a/compiler/rustc_infer/src/infer/mod.rs
+++ b/compiler/rustc_infer/src/infer/mod.rs
@@ -1434,6 +1434,17 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
         value.fold_with(&mut r)
     }
 
+    pub fn resolve_numeric_literals_with_default<T>(&self, value: T) -> T
+    where
+        T: TypeFoldable<'tcx>,
+    {
+        if !value.needs_infer() {
+            return value; // Avoid duplicated subst-folding.
+        }
+        let mut r = InferenceLiteralEraser { infcx: self };
+        value.fold_with(&mut r)
+    }
+
     /// Returns the first unresolved variable contained in `T`. In the
     /// process of visiting `T`, this will resolve (where possible)
     /// type variables in `T`, but it never constructs the final,
@@ -1785,6 +1796,26 @@ impl<'tcx> TyOrConstInferVar<'tcx> {
     }
 }
 
+/// Replace `{integer}` with `i32` and `{float}` with `f64`.
+/// Used only for diagnostics.
+struct InferenceLiteralEraser<'a, 'tcx> {
+    infcx: &'a InferCtxt<'a, 'tcx>,
+}
+
+impl<'a, 'tcx> TypeFolder<'tcx> for InferenceLiteralEraser<'a, 'tcx> {
+    fn tcx<'b>(&'b self) -> TyCtxt<'tcx> {
+        self.infcx.tcx
+    }
+
+    fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> {
+        match ty.kind() {
+            ty::Infer(ty::IntVar(_) | ty::FreshIntTy(_)) => self.tcx().types.i32,
+            ty::Infer(ty::FloatVar(_) | ty::FreshFloatTy(_)) => self.tcx().types.f64,
+            _ => ty.super_fold_with(self),
+        }
+    }
+}
+
 struct ShallowResolver<'a, 'tcx> {
     infcx: &'a InferCtxt<'a, 'tcx>,
 }
diff --git a/compiler/rustc_typeck/src/check/fn_ctxt/suggestions.rs b/compiler/rustc_typeck/src/check/fn_ctxt/suggestions.rs
index 67d61668b6d..37014b5eea5 100644
--- a/compiler/rustc_typeck/src/check/fn_ctxt/suggestions.rs
+++ b/compiler/rustc_typeck/src/check/fn_ctxt/suggestions.rs
@@ -521,6 +521,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         can_suggest: bool,
         fn_id: hir::HirId,
     ) -> bool {
+        let found =
+            self.resolve_numeric_literals_with_default(self.resolve_vars_if_possible(found));
         // Only suggest changing the return type for methods that
         // haven't set a return type at all (and aren't `fn main()` or an impl).
         match (&fn_decl.output, found.is_suggestable(), can_suggest, expected.is_unit()) {
diff --git a/src/test/ui/issues/issue-66706.stderr b/src/test/ui/issues/issue-66706.stderr
index 3e933a0f01b..e8cb18f5c1e 100644
--- a/src/test/ui/issues/issue-66706.stderr
+++ b/src/test/ui/issues/issue-66706.stderr
@@ -36,7 +36,7 @@ error[E0308]: mismatched types
   --> $DIR/issue-66706.rs:2:5
    |
 LL | fn a() {
-   |        - possibly return type missing here?
+   |        - help: try adding a return type: `-> [i32; _]`
 LL |     [0; [|_: _ &_| ()].len()]
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^ expected `()`, found array `[{integer}; _]`
 
@@ -44,7 +44,7 @@ error[E0308]: mismatched types
   --> $DIR/issue-66706.rs:14:5
    |
 LL | fn c() {
-   |        - possibly return type missing here?
+   |        - help: try adding a return type: `-> [i32; _]`
 LL |     [0; [|&_: _ &_| {}; 0 ].len()]
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `()`, found array `[{integer}; _]`
 
@@ -52,7 +52,7 @@ error[E0308]: mismatched types
   --> $DIR/issue-66706.rs:20:5
    |
 LL | fn d() {
-   |        - possibly return type missing here?
+   |        - help: try adding a return type: `-> [i32; _]`
 LL |     [0; match [|f @ &ref _| () ] {} ]
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `()`, found array `[{integer}; _]`
 
diff --git a/src/test/ui/proc-macro/span-preservation.stderr b/src/test/ui/proc-macro/span-preservation.stderr
index e9a44ccb12e..66c68be2f09 100644
--- a/src/test/ui/proc-macro/span-preservation.stderr
+++ b/src/test/ui/proc-macro/span-preservation.stderr
@@ -38,7 +38,7 @@ error[E0308]: mismatched types
   --> $DIR/span-preservation.rs:39:5
    |
 LL | extern "C" fn bar() {
-   |                     - possibly return type missing here?
+   |                     - help: try adding a return type: `-> i32`
 LL |     0
    |     ^ expected `()`, found integer
 
@@ -46,7 +46,7 @@ error[E0308]: mismatched types
   --> $DIR/span-preservation.rs:44:5
    |
 LL | extern "C" fn baz() {
-   |                     - possibly return type missing here?
+   |                     - help: try adding a return type: `-> i32`
 LL |     0
    |     ^ expected `()`, found integer
 
@@ -54,7 +54,7 @@ error[E0308]: mismatched types
   --> $DIR/span-preservation.rs:49:5
    |
 LL | extern "Rust" fn rust_abi() {
-   |                             - possibly return type missing here?
+   |                             - help: try adding a return type: `-> i32`
 LL |     0
    |     ^ expected `()`, found integer
 
@@ -62,7 +62,7 @@ error[E0308]: mismatched types
   --> $DIR/span-preservation.rs:54:5
    |
 LL | extern "\x43" fn c_abi_escaped() {
-   |                                  - possibly return type missing here?
+   |                                  - help: try adding a return type: `-> i32`
 LL |     0
    |     ^ expected `()`, found integer
 
diff --git a/src/test/ui/return/return-type.stderr b/src/test/ui/return/return-type.stderr
index f86209a651d..5af136e6011 100644
--- a/src/test/ui/return/return-type.stderr
+++ b/src/test/ui/return/return-type.stderr
@@ -1,15 +1,19 @@
 error[E0308]: mismatched types
   --> $DIR/return-type.rs:10:5
    |
-LL | fn bar() {
-   |          - possibly return type missing here?
 LL |     foo(4 as usize)
-   |     ^^^^^^^^^^^^^^^- help: consider using a semicolon here: `;`
-   |     |
-   |     expected `()`, found struct `S`
+   |     ^^^^^^^^^^^^^^^ expected `()`, found struct `S`
    |
    = note: expected unit type `()`
                  found struct `S<usize>`
+help: consider using a semicolon here
+   |
+LL |     foo(4 as usize);
+   |                    +
+help: try adding a return type
+   |
+LL | fn bar() -> S<usize> {
+   |          +++++++++++
 
 error: aborting due to previous error