Skip to content

Commit b8708e2

Browse files
committed
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.
1 parent 60960a2 commit b8708e2

7 files changed

+97
-2
lines changed

src/librustc/infer/error_reporting/need_type_info.rs

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -151,12 +151,22 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
151151
// | the type parameter `E` is specified
152152
// ```
153153
let (ty_msg, suffix) = match &local_visitor.found_ty {
154-
Some(ty) if &ty.to_string() != "_" && name == "_" => {
154+
Some(ty) if &ty.to_string() != "_" &&
155+
name == "_" &&
156+
// FIXME: Remove this check after `impl_trait_in_bindings` is stabilized.
157+
(!ty.is_impl_trait() || self.tcx.features().impl_trait_in_bindings) &&
158+
!ty.is_closure() => // The suggestion doesn't make sense for closures.
159+
{
155160
let ty = ty_to_string(ty);
156161
(format!(" for `{}`", ty),
157162
format!("the explicit type `{}`, with the type parameters specified", ty))
158163
}
159-
Some(ty) if &ty.to_string() != "_" && ty.to_string() != name => {
164+
Some(ty) if &ty.to_string() != "_" &&
165+
ty.to_string() != name &&
166+
// FIXME: Remove this check after `impl_trait_in_bindings` is stabilized.
167+
(!ty.is_impl_trait() || self.tcx.features().impl_trait_in_bindings) &&
168+
!ty.is_closure() => // The suggestion doesn't make sense for closures.
169+
{
160170
let ty = ty_to_string(ty);
161171
(format!(" for `{}`", ty),
162172
format!(
@@ -165,6 +175,10 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
165175
name,
166176
))
167177
}
178+
Some(ty) if ty.is_closure() => (
179+
" for the closure".to_string(),
180+
"a boxed closure type like `Box<Fn() -> _>`".to_string(),
181+
),
168182
_ => (String::new(), "a type".to_owned()),
169183
};
170184
let mut labels = vec![(span, InferCtxt::missing_type_msg(&name))];
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
// edition:2018
2+
#![feature(async_await)]
3+
#![feature(impl_trait_in_bindings)]
4+
//~^ WARN the feature `impl_trait_in_bindings` is incomplete and may cause the compiler to crash
5+
6+
use std::io::Error;
7+
8+
fn make_unit() -> Result<(), Error> {
9+
Ok(())
10+
}
11+
12+
fn main() {
13+
let fut = async {
14+
make_unit()?; //~ ERROR type annotations needed
15+
16+
Ok(())
17+
};
18+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
warning: the feature `impl_trait_in_bindings` is incomplete and may cause the compiler to crash
2+
--> $DIR/cannot-infer-async-enabled-impl-trait-bindings.rs:3:12
3+
|
4+
LL | #![feature(impl_trait_in_bindings)]
5+
| ^^^^^^^^^^^^^^^^^^^^^^
6+
|
7+
= note: `#[warn(incomplete_features)]` on by default
8+
9+
error[E0282]: type annotations needed for `impl std::future::Future`
10+
--> $DIR/cannot-infer-async-enabled-impl-trait-bindings.rs:14:9
11+
|
12+
LL | let fut = async {
13+
| --- consider giving `fut` the explicit type `impl std::future::Future`, with the type parameters specified
14+
LL | make_unit()?;
15+
| ^^^^^^^^^^^^ cannot infer type
16+
17+
error: aborting due to previous error
18+
19+
For more information about this error, try `rustc --explain E0282`.
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
// edition:2018
2+
#![feature(async_await)]
3+
4+
use std::io::Error;
5+
6+
fn make_unit() -> Result<(), Error> {
7+
Ok(())
8+
}
9+
10+
fn main() {
11+
let fut = async {
12+
make_unit()?; //~ ERROR type annotations needed
13+
14+
Ok(())
15+
};
16+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
error[E0282]: type annotations needed
2+
--> $DIR/cannot-infer-async.rs:12:9
3+
|
4+
LL | let fut = async {
5+
| --- consider giving `fut` a type
6+
LL | make_unit()?;
7+
| ^^^^^^^^^^^^ cannot infer type
8+
9+
error: aborting due to previous error
10+
11+
For more information about this error, try `rustc --explain E0282`.
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
fn main() {
2+
let x = || {
3+
Err(())?; //~ ERROR type annotations needed for the closure
4+
Ok(())
5+
};
6+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
error[E0282]: type annotations needed for the closure
2+
--> $DIR/cannot-infer-closure.rs:3:9
3+
|
4+
LL | let x = || {
5+
| - consider giving `x` a boxed closure type like `Box<Fn() -> _>`
6+
LL | Err(())?;
7+
| ^^^^^^^^ cannot infer type
8+
9+
error: aborting due to previous error
10+
11+
For more information about this error, try `rustc --explain E0282`.

0 commit comments

Comments
 (0)