Fixed diagnostics for coroutines with () as input.
This commit is contained in:
parent
7042c269c1
commit
986e20d5bb
3 changed files with 60 additions and 36 deletions
|
@ -2635,49 +2635,47 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
|
||||||
// This shouldn't be common unless manually implementing one of the
|
// This shouldn't be common unless manually implementing one of the
|
||||||
// traits manually, but don't make it more confusing when it does
|
// traits manually, but don't make it more confusing when it does
|
||||||
// happen.
|
// happen.
|
||||||
Ok(
|
if Some(expected_trait_ref.def_id) != self.tcx.lang_items().coroutine_trait() && not_tupled
|
||||||
if Some(expected_trait_ref.def_id) != self.tcx.lang_items().coroutine_trait()
|
{
|
||||||
&& not_tupled
|
return Ok(self.report_and_explain_type_error(
|
||||||
{
|
TypeTrace::trait_refs(&obligation.cause, true, expected_trait_ref, found_trait_ref),
|
||||||
self.report_and_explain_type_error(
|
ty::error::TypeError::Mismatch,
|
||||||
TypeTrace::trait_refs(
|
));
|
||||||
&obligation.cause,
|
}
|
||||||
true,
|
if found.len() != expected.len() {
|
||||||
expected_trait_ref,
|
let (closure_span, closure_arg_span, found) = found_did
|
||||||
found_trait_ref,
|
.and_then(|did| {
|
||||||
),
|
let node = self.tcx.hir().get_if_local(did)?;
|
||||||
ty::error::TypeError::Mismatch,
|
let (found_span, closure_arg_span, found) = self.get_fn_like_arguments(node)?;
|
||||||
)
|
Some((Some(found_span), closure_arg_span, found))
|
||||||
} else if found.len() == expected.len() {
|
})
|
||||||
self.report_closure_arg_mismatch(
|
.unwrap_or((found_span, None, found));
|
||||||
span,
|
|
||||||
found_span,
|
|
||||||
found_trait_ref,
|
|
||||||
expected_trait_ref,
|
|
||||||
obligation.cause.code(),
|
|
||||||
found_node,
|
|
||||||
obligation.param_env,
|
|
||||||
)
|
|
||||||
} else {
|
|
||||||
let (closure_span, closure_arg_span, found) = found_did
|
|
||||||
.and_then(|did| {
|
|
||||||
let node = self.tcx.hir().get_if_local(did)?;
|
|
||||||
let (found_span, closure_arg_span, found) =
|
|
||||||
self.get_fn_like_arguments(node)?;
|
|
||||||
Some((Some(found_span), closure_arg_span, found))
|
|
||||||
})
|
|
||||||
.unwrap_or((found_span, None, found));
|
|
||||||
|
|
||||||
self.report_arg_count_mismatch(
|
// If the coroutine take a single () as its argument,
|
||||||
|
// the trait argument would found the coroutine take 0 arguments,
|
||||||
|
// but get_fn_like_arguments would give 1 argument.
|
||||||
|
// This would result in "Expected to take 1 argument, but it takes 1 argument".
|
||||||
|
// Check again to avoid this.
|
||||||
|
if found.len() != expected.len() {
|
||||||
|
return Ok(self.report_arg_count_mismatch(
|
||||||
span,
|
span,
|
||||||
closure_span,
|
closure_span,
|
||||||
expected,
|
expected,
|
||||||
found,
|
found,
|
||||||
found_trait_ty.is_closure(),
|
found_trait_ty.is_closure(),
|
||||||
closure_arg_span,
|
closure_arg_span,
|
||||||
)
|
));
|
||||||
},
|
}
|
||||||
)
|
}
|
||||||
|
Ok(self.report_closure_arg_mismatch(
|
||||||
|
span,
|
||||||
|
found_span,
|
||||||
|
found_trait_ref,
|
||||||
|
expected_trait_ref,
|
||||||
|
obligation.cause.code(),
|
||||||
|
found_node,
|
||||||
|
obligation.param_env,
|
||||||
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Given some node representing a fn-like thing in the HIR map,
|
/// Given some node representing a fn-like thing in the HIR map,
|
||||||
|
|
11
tests/ui/coroutine/arg-count-mismatch-on-unit-input.rs
Normal file
11
tests/ui/coroutine/arg-count-mismatch-on-unit-input.rs
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
#![feature(coroutines, coroutine_trait, stmt_expr_attributes)]
|
||||||
|
|
||||||
|
use std::ops::Coroutine;
|
||||||
|
|
||||||
|
fn foo() -> impl Coroutine<u8> {
|
||||||
|
//~^ ERROR type mismatch in coroutine arguments
|
||||||
|
#[coroutine]
|
||||||
|
|_: ()| {}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() { }
|
15
tests/ui/coroutine/arg-count-mismatch-on-unit-input.stderr
Normal file
15
tests/ui/coroutine/arg-count-mismatch-on-unit-input.stderr
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
error[E0631]: type mismatch in coroutine arguments
|
||||||
|
--> $DIR/arg-count-mismatch-on-unit-input.rs:5:13
|
||||||
|
|
|
||||||
|
LL | fn foo() -> impl Coroutine<u8> {
|
||||||
|
| ^^^^^^^^^^^^^^^^^^ expected due to this
|
||||||
|
...
|
||||||
|
LL | |_: ()| {}
|
||||||
|
| ------- found signature defined here
|
||||||
|
|
|
||||||
|
= note: expected coroutine signature `fn(u8) -> _`
|
||||||
|
found coroutine signature `fn(()) -> _`
|
||||||
|
|
||||||
|
error: aborting due to 1 previous error
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0631`.
|
Loading…
Add table
Add a link
Reference in a new issue