Skip to content

Commit 01f65af

Browse files
committed
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>
1 parent b5f55b7 commit 01f65af

File tree

4 files changed

+37
-5
lines changed

4 files changed

+37
-5
lines changed

Diff for: compiler/rustc_middle/src/ty/error.rs

+12
Original file line numberDiff line numberDiff line change
@@ -473,6 +473,18 @@ impl<T> Trait<T> for X {
473473
#traits-as-parameters",
474474
);
475475
}
476+
(ty::Param(p), ty::Closure(..) | ty::Generator(..)) => {
477+
let generics = self.generics_of(body_owner_def_id);
478+
let p_span = self.def_span(generics.type_param(p, self).def_id);
479+
if !sp.contains(p_span) {
480+
db.span_label(p_span, "this type parameter");
481+
}
482+
db.help(&format!(
483+
"every closure has a distinct type and so could not always match the \
484+
caller-chosen type of parameter `{}`",
485+
p
486+
));
487+
}
476488
(ty::Param(p), _) | (_, ty::Param(p)) => {
477489
let generics = self.generics_of(body_owner_def_id);
478490
let p_span = self.def_span(generics.type_param(p, self).def_id);

Diff for: compiler/rustc_typeck/src/check/demand.rs

+4-5
Original file line numberDiff line numberDiff line change
@@ -117,11 +117,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
117117
ty
118118
}
119119

120-
// Checks that the type of `expr` can be coerced to `expected`.
121-
//
122-
// N.B., this code relies on `self.diverges` to be accurate. In
123-
// particular, assignments to `!` will be permitted if the
124-
// diverges flag is currently "always".
120+
/// Checks that the type of `expr` can be coerced to `expected`.
121+
///
122+
/// N.B., this code relies on `self.diverges` to be accurate. In particular, assignments to `!`
123+
/// will be permitted if the diverges flag is currently "always".
125124
pub fn demand_coerce_diag(
126125
&self,
127126
expr: &hir::Expr<'_>,

Diff for: src/test/ui/issues/issue-51154.rs

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
fn foo<F: FnMut()>() {
2+
let _: Box<F> = Box::new(|| ());
3+
//~^ ERROR mismatched types
4+
}
5+
6+
fn main() {}

Diff for: src/test/ui/issues/issue-51154.stderr

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

0 commit comments

Comments
 (0)