Eagerly replace {integer}/{float} with i32/f64 for suggestion

This commit is contained in:
Esteban Kuber 2021-12-15 22:59:32 +00:00
parent 3fe3b89cd5
commit 474626af50
5 changed files with 49 additions and 12 deletions

View File

@ -1434,6 +1434,17 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
value.fold_with(&mut r) 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 /// Returns the first unresolved variable contained in `T`. In the
/// process of visiting `T`, this will resolve (where possible) /// process of visiting `T`, this will resolve (where possible)
/// type variables in `T`, but it never constructs the final, /// 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> { struct ShallowResolver<'a, 'tcx> {
infcx: &'a InferCtxt<'a, 'tcx>, infcx: &'a InferCtxt<'a, 'tcx>,
} }

View File

@ -521,6 +521,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
can_suggest: bool, can_suggest: bool,
fn_id: hir::HirId, fn_id: hir::HirId,
) -> bool { ) -> bool {
let found =
self.resolve_numeric_literals_with_default(self.resolve_vars_if_possible(found));
// Only suggest changing the return type for methods that // 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). // 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()) { match (&fn_decl.output, found.is_suggestable(), can_suggest, expected.is_unit()) {

View File

@ -36,7 +36,7 @@ error[E0308]: mismatched types
--> $DIR/issue-66706.rs:2:5 --> $DIR/issue-66706.rs:2:5
| |
LL | fn a() { LL | fn a() {
| - possibly return type missing here? | - help: try adding a return type: `-> [i32; _]`
LL | [0; [|_: _ &_| ()].len()] LL | [0; [|_: _ &_| ()].len()]
| ^^^^^^^^^^^^^^^^^^^^^^^^^ expected `()`, found array `[{integer}; _]` | ^^^^^^^^^^^^^^^^^^^^^^^^^ expected `()`, found array `[{integer}; _]`
@ -44,7 +44,7 @@ error[E0308]: mismatched types
--> $DIR/issue-66706.rs:14:5 --> $DIR/issue-66706.rs:14:5
| |
LL | fn c() { LL | fn c() {
| - possibly return type missing here? | - help: try adding a return type: `-> [i32; _]`
LL | [0; [|&_: _ &_| {}; 0 ].len()] LL | [0; [|&_: _ &_| {}; 0 ].len()]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `()`, found array `[{integer}; _]` | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `()`, found array `[{integer}; _]`
@ -52,7 +52,7 @@ error[E0308]: mismatched types
--> $DIR/issue-66706.rs:20:5 --> $DIR/issue-66706.rs:20:5
| |
LL | fn d() { LL | fn d() {
| - possibly return type missing here? | - help: try adding a return type: `-> [i32; _]`
LL | [0; match [|f @ &ref _| () ] {} ] LL | [0; match [|f @ &ref _| () ] {} ]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `()`, found array `[{integer}; _]` | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `()`, found array `[{integer}; _]`

View File

@ -38,7 +38,7 @@ error[E0308]: mismatched types
--> $DIR/span-preservation.rs:39:5 --> $DIR/span-preservation.rs:39:5
| |
LL | extern "C" fn bar() { LL | extern "C" fn bar() {
| - possibly return type missing here? | - help: try adding a return type: `-> i32`
LL | 0 LL | 0
| ^ expected `()`, found integer | ^ expected `()`, found integer
@ -46,7 +46,7 @@ error[E0308]: mismatched types
--> $DIR/span-preservation.rs:44:5 --> $DIR/span-preservation.rs:44:5
| |
LL | extern "C" fn baz() { LL | extern "C" fn baz() {
| - possibly return type missing here? | - help: try adding a return type: `-> i32`
LL | 0 LL | 0
| ^ expected `()`, found integer | ^ expected `()`, found integer
@ -54,7 +54,7 @@ error[E0308]: mismatched types
--> $DIR/span-preservation.rs:49:5 --> $DIR/span-preservation.rs:49:5
| |
LL | extern "Rust" fn rust_abi() { LL | extern "Rust" fn rust_abi() {
| - possibly return type missing here? | - help: try adding a return type: `-> i32`
LL | 0 LL | 0
| ^ expected `()`, found integer | ^ expected `()`, found integer
@ -62,7 +62,7 @@ error[E0308]: mismatched types
--> $DIR/span-preservation.rs:54:5 --> $DIR/span-preservation.rs:54:5
| |
LL | extern "\x43" fn c_abi_escaped() { LL | extern "\x43" fn c_abi_escaped() {
| - possibly return type missing here? | - help: try adding a return type: `-> i32`
LL | 0 LL | 0
| ^ expected `()`, found integer | ^ expected `()`, found integer

View File

@ -1,15 +1,19 @@
error[E0308]: mismatched types error[E0308]: mismatched types
--> $DIR/return-type.rs:10:5 --> $DIR/return-type.rs:10:5
| |
LL | fn bar() {
| - possibly return type missing here?
LL | foo(4 as usize) LL | foo(4 as usize)
| ^^^^^^^^^^^^^^^- help: consider using a semicolon here: `;` | ^^^^^^^^^^^^^^^ expected `()`, found struct `S`
| |
| expected `()`, found struct `S`
| |
= note: expected unit type `()` = note: expected unit type `()`
found struct `S<usize>` 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 error: aborting due to previous error