When needing type annotations in local bindings, account for impl Trait and closures
Do not suggest nonsensical types when the type inference is failing on `impl Trait` or anonymous closures.
This commit is contained in:
parent
60960a260f
commit
b8708e2c9a
@ -151,12 +151,22 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
||||
// | the type parameter `E` is specified
|
||||
// ```
|
||||
let (ty_msg, suffix) = match &local_visitor.found_ty {
|
||||
Some(ty) if &ty.to_string() != "_" && name == "_" => {
|
||||
Some(ty) if &ty.to_string() != "_" &&
|
||||
name == "_" &&
|
||||
// FIXME: Remove this check after `impl_trait_in_bindings` is stabilized.
|
||||
(!ty.is_impl_trait() || self.tcx.features().impl_trait_in_bindings) &&
|
||||
!ty.is_closure() => // The suggestion doesn't make sense for closures.
|
||||
{
|
||||
let ty = ty_to_string(ty);
|
||||
(format!(" for `{}`", ty),
|
||||
format!("the explicit type `{}`, with the type parameters specified", ty))
|
||||
}
|
||||
Some(ty) if &ty.to_string() != "_" && ty.to_string() != name => {
|
||||
Some(ty) if &ty.to_string() != "_" &&
|
||||
ty.to_string() != name &&
|
||||
// FIXME: Remove this check after `impl_trait_in_bindings` is stabilized.
|
||||
(!ty.is_impl_trait() || self.tcx.features().impl_trait_in_bindings) &&
|
||||
!ty.is_closure() => // The suggestion doesn't make sense for closures.
|
||||
{
|
||||
let ty = ty_to_string(ty);
|
||||
(format!(" for `{}`", ty),
|
||||
format!(
|
||||
@ -165,6 +175,10 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
||||
name,
|
||||
))
|
||||
}
|
||||
Some(ty) if ty.is_closure() => (
|
||||
" for the closure".to_string(),
|
||||
"a boxed closure type like `Box<Fn() -> _>`".to_string(),
|
||||
),
|
||||
_ => (String::new(), "a type".to_owned()),
|
||||
};
|
||||
let mut labels = vec![(span, InferCtxt::missing_type_msg(&name))];
|
||||
|
@ -0,0 +1,18 @@
|
||||
// edition:2018
|
||||
#![feature(async_await)]
|
||||
#![feature(impl_trait_in_bindings)]
|
||||
//~^ WARN the feature `impl_trait_in_bindings` is incomplete and may cause the compiler to crash
|
||||
|
||||
use std::io::Error;
|
||||
|
||||
fn make_unit() -> Result<(), Error> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let fut = async {
|
||||
make_unit()?; //~ ERROR type annotations needed
|
||||
|
||||
Ok(())
|
||||
};
|
||||
}
|
@ -0,0 +1,19 @@
|
||||
warning: the feature `impl_trait_in_bindings` is incomplete and may cause the compiler to crash
|
||||
--> $DIR/cannot-infer-async-enabled-impl-trait-bindings.rs:3:12
|
||||
|
|
||||
LL | #![feature(impl_trait_in_bindings)]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: `#[warn(incomplete_features)]` on by default
|
||||
|
||||
error[E0282]: type annotations needed for `impl std::future::Future`
|
||||
--> $DIR/cannot-infer-async-enabled-impl-trait-bindings.rs:14:9
|
||||
|
|
||||
LL | let fut = async {
|
||||
| --- consider giving `fut` the explicit type `impl std::future::Future`, with the type parameters specified
|
||||
LL | make_unit()?;
|
||||
| ^^^^^^^^^^^^ cannot infer type
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0282`.
|
16
src/test/ui/inference/cannot-infer-async.rs
Normal file
16
src/test/ui/inference/cannot-infer-async.rs
Normal file
@ -0,0 +1,16 @@
|
||||
// edition:2018
|
||||
#![feature(async_await)]
|
||||
|
||||
use std::io::Error;
|
||||
|
||||
fn make_unit() -> Result<(), Error> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let fut = async {
|
||||
make_unit()?; //~ ERROR type annotations needed
|
||||
|
||||
Ok(())
|
||||
};
|
||||
}
|
11
src/test/ui/inference/cannot-infer-async.stderr
Normal file
11
src/test/ui/inference/cannot-infer-async.stderr
Normal file
@ -0,0 +1,11 @@
|
||||
error[E0282]: type annotations needed
|
||||
--> $DIR/cannot-infer-async.rs:12:9
|
||||
|
|
||||
LL | let fut = async {
|
||||
| --- consider giving `fut` a type
|
||||
LL | make_unit()?;
|
||||
| ^^^^^^^^^^^^ cannot infer type
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0282`.
|
6
src/test/ui/inference/cannot-infer-closure.rs
Normal file
6
src/test/ui/inference/cannot-infer-closure.rs
Normal file
@ -0,0 +1,6 @@
|
||||
fn main() {
|
||||
let x = || {
|
||||
Err(())?; //~ ERROR type annotations needed for the closure
|
||||
Ok(())
|
||||
};
|
||||
}
|
11
src/test/ui/inference/cannot-infer-closure.stderr
Normal file
11
src/test/ui/inference/cannot-infer-closure.stderr
Normal file
@ -0,0 +1,11 @@
|
||||
error[E0282]: type annotations needed for the closure
|
||||
--> $DIR/cannot-infer-closure.rs:3:9
|
||||
|
|
||||
LL | let x = || {
|
||||
| - consider giving `x` a boxed closure type like `Box<Fn() -> _>`
|
||||
LL | Err(())?;
|
||||
| ^^^^^^^^ cannot infer type
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0282`.
|
Loading…
x
Reference in New Issue
Block a user