diag: improve closure/generic parameter mismatch

This commit improves the diagnostic when a type parameter is expected
and a closure is found, noting that each closure has a distinct type and
therefore could not always match the caller-chosen type of the
parameter.

Signed-off-by: David Wood <david@davidtw.co>
This commit is contained in:
David Wood 2020-09-14 15:21:38 +01:00
parent b5f55b7e15
commit 01f65afa4a
No known key found for this signature in database
GPG Key ID: 2592E76C87381FD9
4 changed files with 37 additions and 5 deletions

View File

@ -473,6 +473,18 @@ impl<T> Trait<T> for X {
#traits-as-parameters",
);
}
(ty::Param(p), ty::Closure(..) | ty::Generator(..)) => {
let generics = self.generics_of(body_owner_def_id);
let p_span = self.def_span(generics.type_param(p, self).def_id);
if !sp.contains(p_span) {
db.span_label(p_span, "this type parameter");
}
db.help(&format!(
"every closure has a distinct type and so could not always match the \
caller-chosen type of parameter `{}`",
p
));
}
(ty::Param(p), _) | (_, ty::Param(p)) => {
let generics = self.generics_of(body_owner_def_id);
let p_span = self.def_span(generics.type_param(p, self).def_id);

View File

@ -117,11 +117,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
ty
}
// Checks that the type of `expr` can be coerced to `expected`.
//
// N.B., this code relies on `self.diverges` to be accurate. In
// particular, assignments to `!` will be permitted if the
// diverges flag is currently "always".
/// Checks that the type of `expr` can be coerced to `expected`.
///
/// N.B., this code relies on `self.diverges` to be accurate. In particular, assignments to `!`
/// will be permitted if the diverges flag is currently "always".
pub fn demand_coerce_diag(
&self,
expr: &hir::Expr<'_>,

View File

@ -0,0 +1,6 @@
fn foo<F: FnMut()>() {
let _: Box<F> = Box::new(|| ());
//~^ ERROR mismatched types
}
fn main() {}

View File

@ -0,0 +1,15 @@
error[E0308]: mismatched types
--> $DIR/issue-51154.rs:2:30
|
LL | fn foo<F: FnMut()>() {
| - this type parameter
LL | let _: Box<F> = Box::new(|| ());
| ^^^^^ expected type parameter `F`, found closure
|
= note: expected type parameter `F`
found closure `[closure@$DIR/issue-51154.rs:2:30: 2:35]`
= help: every closure has a distinct type and so could not always match the caller-chosen type of parameter `F`
error: aborting due to previous error
For more information about this error, try `rustc --explain E0308`.