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:
parent
b5f55b7e15
commit
01f65afa4a
4 changed files with 37 additions and 5 deletions
|
@ -473,6 +473,18 @@ impl<T> Trait<T> for X {
|
||||||
#traits-as-parameters",
|
#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)) => {
|
(ty::Param(p), _) | (_, ty::Param(p)) => {
|
||||||
let generics = self.generics_of(body_owner_def_id);
|
let generics = self.generics_of(body_owner_def_id);
|
||||||
let p_span = self.def_span(generics.type_param(p, self).def_id);
|
let p_span = self.def_span(generics.type_param(p, self).def_id);
|
||||||
|
|
|
@ -117,11 +117,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
ty
|
ty
|
||||||
}
|
}
|
||||||
|
|
||||||
// Checks that the type of `expr` can be coerced to `expected`.
|
/// Checks that the type of `expr` can be coerced to `expected`.
|
||||||
//
|
///
|
||||||
// N.B., this code relies on `self.diverges` to be accurate. In
|
/// N.B., this code relies on `self.diverges` to be accurate. In particular, assignments to `!`
|
||||||
// particular, assignments to `!` will be permitted if the
|
/// will be permitted if the diverges flag is currently "always".
|
||||||
// diverges flag is currently "always".
|
|
||||||
pub fn demand_coerce_diag(
|
pub fn demand_coerce_diag(
|
||||||
&self,
|
&self,
|
||||||
expr: &hir::Expr<'_>,
|
expr: &hir::Expr<'_>,
|
||||||
|
|
6
src/test/ui/issues/issue-51154.rs
Normal file
6
src/test/ui/issues/issue-51154.rs
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
fn foo<F: FnMut()>() {
|
||||||
|
let _: Box<F> = Box::new(|| ());
|
||||||
|
//~^ ERROR mismatched types
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {}
|
15
src/test/ui/issues/issue-51154.stderr
Normal file
15
src/test/ui/issues/issue-51154.stderr
Normal 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`.
|
Loading…
Add table
Add a link
Reference in a new issue