Skip to content

Commit 16273eb

Browse files
committed
Improve suggestions for closure parameters
1 parent 07e7b43 commit 16273eb

11 files changed

+97
-0
lines changed

compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs

+26
Original file line numberDiff line numberDiff line change
@@ -617,6 +617,32 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
617617
});
618618

619619
if let Some((decl, body_id)) = closure_decl_and_body_id {
620+
for arg in fn_sig.inputs().skip_binder().iter() {
621+
if let Some((ty, ty_span)) = self.unresolved_type_vars(arg) {
622+
let ty_span = match ty_span {
623+
Some(ty_span) => ty_span,
624+
None => match ty.ty_vid() {
625+
Some(ty_vid) => {
626+
self.inner
627+
.borrow_mut()
628+
.type_variables()
629+
.var_origin(ty_vid)
630+
.span
631+
}
632+
None => continue,
633+
},
634+
};
635+
err.span_label(
636+
ty_span,
637+
"give this closure parameter an explicit type instead of `_`",
638+
);
639+
// We don't want to give the other suggestions when the problem is
640+
// a closure parameter type.
641+
return err;
642+
}
643+
}
644+
645+
// Parameters were all fine, assume there was an issue with the return type
620646
closure_return_type_suggestion(
621647
&mut err,
622648
&decl.output,
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
fn main() {
2+
let a = |a: i32, b: &i32| Vec::new(); //~ ERROR E0282
3+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
error[E0282]: type annotations needed for the closure `fn(i32, &i32) -> Vec<_>`
2+
--> $DIR/unspecified-output.rs:2:31
3+
|
4+
LL | let a = |a: i32, b: &i32| Vec::new();
5+
| ^^^^^^^^ cannot infer type for type parameter `T`
6+
|
7+
help: give this closure an explicit return type without `_` placeholders
8+
|
9+
LL | let a = |a: i32, b: &i32| -> Vec<_> { Vec::new() };
10+
| +++++++++++ +
11+
12+
error: aborting due to previous error
13+
14+
For more information about this error, try `rustc --explain E0282`.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
fn main() {
2+
let a = |a: i32, b: fn(i32) -> _| -> Vec<i32> { Vec::new() }; //~ ERROR E0282
3+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
error[E0282]: type annotations needed for the closure `fn(i32, fn(i32) -> _) -> Vec<i32>`
2+
--> $DIR/unspecified-parameter-fn.rs:2:13
3+
|
4+
LL | let a = |a: i32, b: fn(i32) -> _| -> Vec<i32> { Vec::new() };
5+
| ^^^^^^^^^^^^^^^^^^^^^^^-^^^^^^^^^^^^^^^^^^^^^^^^^^^^
6+
| |
7+
| give this closure parameter an explicit type instead of `_`
8+
9+
error: aborting due to previous error
10+
11+
For more information about this error, try `rustc --explain E0282`.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
fn main() {
2+
let a = |a: i32, b: &_| -> Vec<i32> { Vec::new() }; //~ ERROR E0282
3+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
error[E0282]: type annotations needed for the closure `fn(i32, &_) -> Vec<i32>`
2+
--> $DIR/unspecified-parameter-ref.rs:2:13
3+
|
4+
LL | let a = |a: i32, b: &_| -> Vec<i32> { Vec::new() };
5+
| ^^^^^^^^^^^^^-^^^^^^^^^^^^^^^^^^^^^^^^^^^^
6+
| |
7+
| give this closure parameter an explicit type instead of `_`
8+
9+
error: aborting due to previous error
10+
11+
For more information about this error, try `rustc --explain E0282`.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
fn main() {
2+
let a = |a: i32, b: Vec<_>| -> Vec<i32> { Vec::new() }; //~ ERROR E0282
3+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
error[E0282]: type annotations needed for the closure `fn(i32, Vec<_>) -> Vec<i32>`
2+
--> $DIR/unspecified-parameter-type-param.rs:2:13
3+
|
4+
LL | let a = |a: i32, b: Vec<_>| -> Vec<i32> { Vec::new() };
5+
| ^^^^^^^^^^^^^^^^-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
6+
| |
7+
| give this closure parameter an explicit type instead of `_`
8+
9+
error: aborting due to previous error
10+
11+
For more information about this error, try `rustc --explain E0282`.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
fn main() {
2+
let a = |a: _, b: &i32| -> Vec<i32> { Vec::new() }; //~ ERROR E0282
3+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
error[E0282]: type annotations needed
2+
--> $DIR/unspecified-parameter.rs:2:14
3+
|
4+
LL | let a = |a: _, b: &i32| -> Vec<i32> { Vec::new() };
5+
| ^ consider giving this closure parameter a type
6+
7+
error: aborting due to previous error
8+
9+
For more information about this error, try `rustc --explain E0282`.

0 commit comments

Comments
 (0)