diff options
| author | Esteban Kuber <esteban@kuber.com.ar> | 2021-12-15 22:59:32 +0000 |
|---|---|---|
| committer | Esteban Kuber <esteban@kuber.com.ar> | 2022-03-27 02:20:16 +0000 |
| commit | 474626af50ae9836b56a351edf59c1ca9b104b5c (patch) | |
| tree | 7596f2f21457d46baa99d269313cc4a07a741863 | |
| parent | 3fe3b89cd57229343eeca753fdd8c63d9b03c65c (diff) | |
| download | rust-474626af50ae9836b56a351edf59c1ca9b104b5c.tar.gz rust-474626af50ae9836b56a351edf59c1ca9b104b5c.zip | |
Eagerly replace `{integer}`/`{float}` with `i32`/`f64` for suggestion
| -rw-r--r-- | compiler/rustc_infer/src/infer/mod.rs | 31 | ||||
| -rw-r--r-- | compiler/rustc_typeck/src/check/fn_ctxt/suggestions.rs | 2 | ||||
| -rw-r--r-- | src/test/ui/issues/issue-66706.stderr | 6 | ||||
| -rw-r--r-- | src/test/ui/proc-macro/span-preservation.stderr | 8 | ||||
| -rw-r--r-- | src/test/ui/return/return-type.stderr | 14 |
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 |
