Resolve types when suggesting boxed closure
This commit is contained in:
parent
b8708e2c9a
commit
3b6d46c640
4 changed files with 30 additions and 11 deletions
|
@ -175,10 +175,26 @@ 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(),
|
||||
),
|
||||
Some(ty::TyS { sty: ty::TyKind::Closure(def_id, substs), .. }) => {
|
||||
let msg = " for the closure".to_string();
|
||||
let fn_sig = substs.closure_sig(*def_id, self.tcx);
|
||||
let args = fn_sig.inputs()
|
||||
.skip_binder()
|
||||
.iter()
|
||||
.next()
|
||||
.map(|args| args.tuple_fields()
|
||||
.map(|arg| arg.to_string())
|
||||
.collect::<Vec<_>>().join(", "))
|
||||
.unwrap_or_else(String::new);
|
||||
// This suggestion is incomplete, as the user will get further type inference
|
||||
// errors due to the `_` placeholders and the introduction of `Box`, but it does
|
||||
// nudge them in the right direction.
|
||||
(msg, format!(
|
||||
"a boxed closure type like `Box<Fn({}) -> {}>`",
|
||||
args,
|
||||
fn_sig.output().skip_binder().to_string(),
|
||||
))
|
||||
}
|
||||
_ => (String::new(), "a type".to_owned()),
|
||||
};
|
||||
let mut labels = vec![(span, InferCtxt::missing_type_msg(&name))];
|
||||
|
|
|
@ -2068,6 +2068,9 @@ impl<'tcx> TyS<'tcx> {
|
|||
Error => { // ignore errors (#54954)
|
||||
ty::Binder::dummy(FnSig::fake())
|
||||
}
|
||||
Closure(..) => bug!(
|
||||
"to get the signature of a closure, use `closure_sig()` not `fn_sig()`",
|
||||
),
|
||||
_ => bug!("Ty::fn_sig() called on non-fn type: {:?}", self)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
fn main() {
|
||||
let x = || {
|
||||
Err(())?; //~ ERROR type annotations needed for the closure
|
||||
Ok(())
|
||||
let x = |a: (), b: ()| {
|
||||
Err(a)?; //~ ERROR type annotations needed for the closure
|
||||
Ok(b)
|
||||
};
|
||||
}
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
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
|
||||
LL | let x = |a: (), b: ()| {
|
||||
| - consider giving `x` a boxed closure type like `Box<Fn((), ()) -> std::result::Result<(), _>>`
|
||||
LL | Err(a)?;
|
||||
| ^^^^^^^ cannot infer type
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue