Skip to content

Commit 3b6d46c

Browse files
committed
Resolve types when suggesting boxed closure
1 parent b8708e2 commit 3b6d46c

File tree

4 files changed

+30
-11
lines changed

4 files changed

+30
-11
lines changed

src/librustc/infer/error_reporting/need_type_info.rs

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -175,10 +175,26 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
175175
name,
176176
))
177177
}
178-
Some(ty) if ty.is_closure() => (
179-
" for the closure".to_string(),
180-
"a boxed closure type like `Box<Fn() -> _>`".to_string(),
181-
),
178+
Some(ty::TyS { sty: ty::TyKind::Closure(def_id, substs), .. }) => {
179+
let msg = " for the closure".to_string();
180+
let fn_sig = substs.closure_sig(*def_id, self.tcx);
181+
let args = fn_sig.inputs()
182+
.skip_binder()
183+
.iter()
184+
.next()
185+
.map(|args| args.tuple_fields()
186+
.map(|arg| arg.to_string())
187+
.collect::<Vec<_>>().join(", "))
188+
.unwrap_or_else(String::new);
189+
// This suggestion is incomplete, as the user will get further type inference
190+
// errors due to the `_` placeholders and the introduction of `Box`, but it does
191+
// nudge them in the right direction.
192+
(msg, format!(
193+
"a boxed closure type like `Box<Fn({}) -> {}>`",
194+
args,
195+
fn_sig.output().skip_binder().to_string(),
196+
))
197+
}
182198
_ => (String::new(), "a type".to_owned()),
183199
};
184200
let mut labels = vec![(span, InferCtxt::missing_type_msg(&name))];

src/librustc/ty/sty.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2068,6 +2068,9 @@ impl<'tcx> TyS<'tcx> {
20682068
Error => { // ignore errors (#54954)
20692069
ty::Binder::dummy(FnSig::fake())
20702070
}
2071+
Closure(..) => bug!(
2072+
"to get the signature of a closure, use `closure_sig()` not `fn_sig()`",
2073+
),
20712074
_ => bug!("Ty::fn_sig() called on non-fn type: {:?}", self)
20722075
}
20732076
}
Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
fn main() {
2-
let x = || {
3-
Err(())?; //~ ERROR type annotations needed for the closure
4-
Ok(())
2+
let x = |a: (), b: ()| {
3+
Err(a)?; //~ ERROR type annotations needed for the closure
4+
Ok(b)
55
};
66
}

src/test/ui/inference/cannot-infer-closure.stderr

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
error[E0282]: type annotations needed for the closure
22
--> $DIR/cannot-infer-closure.rs:3:9
33
|
4-
LL | let x = || {
5-
| - consider giving `x` a boxed closure type like `Box<Fn() -> _>`
6-
LL | Err(())?;
7-
| ^^^^^^^^ cannot infer type
4+
LL | let x = |a: (), b: ()| {
5+
| - consider giving `x` a boxed closure type like `Box<Fn((), ()) -> std::result::Result<(), _>>`
6+
LL | Err(a)?;
7+
| ^^^^^^^ cannot infer type
88

99
error: aborting due to previous error
1010

0 commit comments

Comments
 (0)