Skip to content

Commit cbd7983

Browse files
committed
Improve error message for type mismatch in generator arguments
1 parent c7dbe7a commit cbd7983

File tree

4 files changed

+55
-14
lines changed

4 files changed

+55
-14
lines changed

compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs

+4-1
Original file line numberDiff line numberDiff line change
@@ -730,7 +730,10 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
730730
};
731731

732732
let found_did = match *found_trait_ty.kind() {
733-
ty::Closure(did, _) | ty::Foreign(did) | ty::FnDef(did, _) => Some(did),
733+
ty::Closure(did, _)
734+
| ty::Foreign(did)
735+
| ty::FnDef(did, _)
736+
| ty::Generator(did, ..) => Some(did),
734737
ty::Adt(def, _) => Some(def.did),
735738
_ => None,
736739
};

compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs

+20-13
Original file line numberDiff line numberDiff line change
@@ -1250,33 +1250,40 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
12501250
trait_ref: ty::PolyTraitRef<'tcx>,
12511251
) -> String {
12521252
let inputs = trait_ref.skip_binder().substs.type_at(1);
1253-
let sig = if let ty::Tuple(inputs) = inputs.kind() {
1254-
tcx.mk_fn_sig(
1255-
inputs.iter().map(|k| k.expect_ty()),
1256-
tcx.mk_ty_infer(ty::TyVar(ty::TyVid::from_u32(0))),
1257-
false,
1258-
hir::Unsafety::Normal,
1259-
abi::Abi::Rust,
1260-
)
1261-
} else {
1262-
tcx.mk_fn_sig(
1253+
let sig = match inputs.kind() {
1254+
ty::Tuple(inputs)
1255+
if tcx.fn_trait_kind_from_lang_item(trait_ref.def_id()).is_some() =>
1256+
{
1257+
tcx.mk_fn_sig(
1258+
inputs.iter().map(|k| k.expect_ty()),
1259+
tcx.mk_ty_infer(ty::TyVar(ty::TyVid::from_u32(0))),
1260+
false,
1261+
hir::Unsafety::Normal,
1262+
abi::Abi::Rust,
1263+
)
1264+
}
1265+
_ => tcx.mk_fn_sig(
12631266
std::iter::once(inputs),
12641267
tcx.mk_ty_infer(ty::TyVar(ty::TyVid::from_u32(0))),
12651268
false,
12661269
hir::Unsafety::Normal,
12671270
abi::Abi::Rust,
1268-
)
1271+
),
12691272
};
12701273
trait_ref.rebind(sig).to_string()
12711274
}
12721275

1273-
let argument_is_closure = expected_ref.skip_binder().substs.type_at(0).is_closure();
1276+
let argument_kind = match expected_ref.skip_binder().substs.type_at(0) {
1277+
t if t.is_closure() => "closure",
1278+
t if t.is_generator() => "generator",
1279+
_ => "function",
1280+
};
12741281
let mut err = struct_span_err!(
12751282
self.tcx.sess,
12761283
span,
12771284
E0631,
12781285
"type mismatch in {} arguments",
1279-
if argument_is_closure { "closure" } else { "function" }
1286+
argument_kind
12801287
);
12811288

12821289
let found_str = format!("expected signature of `{}`", build_fn_sig_string(self.tcx, found));

src/test/ui/generator/issue-88653.rs

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
// Regression test for #88653, where a confusing warning about a
2+
// type mismatch in generator arguments was issued.
3+
4+
#![feature(generators, generator_trait)]
5+
6+
use std::ops::Generator;
7+
8+
fn foo(bar: bool) -> impl Generator<(bool,)> {
9+
//~^ ERROR: type mismatch in generator arguments [E0631]
10+
//~| NOTE: expected signature of `fn((bool,)) -> _`
11+
|bar| {
12+
//~^ NOTE: found signature of `fn(bool) -> _`
13+
if bar {
14+
yield bar;
15+
}
16+
}
17+
}
18+
19+
fn main() {}
+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
error[E0631]: type mismatch in generator arguments
2+
--> $DIR/issue-88653.rs:8:22
3+
|
4+
LL | fn foo(bar: bool) -> impl Generator<(bool,)> {
5+
| ^^^^^^^^^^^^^^^^^^^^^^^ expected signature of `fn((bool,)) -> _`
6+
...
7+
LL | |bar| {
8+
| ----- found signature of `fn(bool) -> _`
9+
10+
error: aborting due to previous error
11+
12+
For more information about this error, try `rustc --explain E0631`.

0 commit comments

Comments
 (0)