Skip to content

Commit

Permalink
diag: improve closure/generic parameter mismatch
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
davidtwco committed Sep 14, 2020
1 parent b5f55b7 commit 01f65af
Show file tree
Hide file tree
Showing 4 changed files with 37 additions and 5 deletions.
12 changes: 12 additions & 0 deletions compiler/rustc_middle/src/ty/error.rs
Expand Up @@ -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);
Expand Down
9 changes: 4 additions & 5 deletions compiler/rustc_typeck/src/check/demand.rs
Expand Up @@ -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<'_>,
Expand Down
6 changes: 6 additions & 0 deletions src/test/ui/issues/issue-51154.rs
@@ -0,0 +1,6 @@
fn foo<F: FnMut()>() {
let _: Box<F> = Box::new(|| ());
//~^ ERROR mismatched types
}

fn main() {}
15 changes: 15 additions & 0 deletions src/test/ui/issues/issue-51154.stderr
@@ -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`.

0 comments on commit 01f65af

Please sign in to comment.