Skip to content

Commit bf8aca5

Browse files
authored
Unrolled build for rust-lang#130820
Rollup merge of rust-lang#130820 - 91khr:fix-coroutine-unit-arg, r=compiler-errors Fix diagnostics for coroutines with () as input. This may be a more real-life example to trigger the diagnostic: ```rust #![features(try_blocks, coroutine_trait, coroutines)] use std::ops::Coroutine; struct Request; struct Response; fn get_args() -> Result<String, String> { todo!() } fn build_request(_arg: String) -> Request { todo!() } fn work() -> impl Coroutine<Option<Response>, Yield = Request> { #[coroutine] |_| { let r: Result<(), String> = try { let req = get_args()?; yield build_request(req) }; if let Err(msg) = r { eprintln!("Error: {msg}"); } } } ```
2 parents 2bd1e89 + 986e20d commit bf8aca5

File tree

3 files changed

+61
-37
lines changed

3 files changed

+61
-37
lines changed

Diff for: compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs

+35-37
Original file line numberDiff line numberDiff line change
@@ -2635,49 +2635,47 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
26352635
// This shouldn't be common unless manually implementing one of the
26362636
// traits manually, but don't make it more confusing when it does
26372637
// happen.
2638-
Ok(
2639-
if Some(expected_trait_ref.def_id) != self.tcx.lang_items().coroutine_trait()
2640-
&& not_tupled
2641-
{
2642-
self.report_and_explain_type_error(
2643-
TypeTrace::trait_refs(
2644-
&obligation.cause,
2645-
true,
2646-
expected_trait_ref,
2647-
found_trait_ref,
2648-
),
2649-
ty::error::TypeError::Mismatch,
2650-
)
2651-
} else if found.len() == expected.len() {
2652-
self.report_closure_arg_mismatch(
2653-
span,
2654-
found_span,
2655-
found_trait_ref,
2656-
expected_trait_ref,
2657-
obligation.cause.code(),
2658-
found_node,
2659-
obligation.param_env,
2660-
)
2661-
} else {
2662-
let (closure_span, closure_arg_span, found) = found_did
2663-
.and_then(|did| {
2664-
let node = self.tcx.hir().get_if_local(did)?;
2665-
let (found_span, closure_arg_span, found) =
2666-
self.get_fn_like_arguments(node)?;
2667-
Some((Some(found_span), closure_arg_span, found))
2668-
})
2669-
.unwrap_or((found_span, None, found));
2670-
2671-
self.report_arg_count_mismatch(
2638+
if Some(expected_trait_ref.def_id) != self.tcx.lang_items().coroutine_trait() && not_tupled
2639+
{
2640+
return Ok(self.report_and_explain_type_error(
2641+
TypeTrace::trait_refs(&obligation.cause, true, expected_trait_ref, found_trait_ref),
2642+
ty::error::TypeError::Mismatch,
2643+
));
2644+
}
2645+
if found.len() != expected.len() {
2646+
let (closure_span, closure_arg_span, found) = found_did
2647+
.and_then(|did| {
2648+
let node = self.tcx.hir().get_if_local(did)?;
2649+
let (found_span, closure_arg_span, found) = self.get_fn_like_arguments(node)?;
2650+
Some((Some(found_span), closure_arg_span, found))
2651+
})
2652+
.unwrap_or((found_span, None, found));
2653+
2654+
// If the coroutine take a single () as its argument,
2655+
// the trait argument would found the coroutine take 0 arguments,
2656+
// but get_fn_like_arguments would give 1 argument.
2657+
// This would result in "Expected to take 1 argument, but it takes 1 argument".
2658+
// Check again to avoid this.
2659+
if found.len() != expected.len() {
2660+
return Ok(self.report_arg_count_mismatch(
26722661
span,
26732662
closure_span,
26742663
expected,
26752664
found,
26762665
found_trait_ty.is_closure(),
26772666
closure_arg_span,
2678-
)
2679-
},
2680-
)
2667+
));
2668+
}
2669+
}
2670+
Ok(self.report_closure_arg_mismatch(
2671+
span,
2672+
found_span,
2673+
found_trait_ref,
2674+
expected_trait_ref,
2675+
obligation.cause.code(),
2676+
found_node,
2677+
obligation.param_env,
2678+
))
26812679
}
26822680

26832681
/// Given some node representing a fn-like thing in the HIR map,
+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
#![feature(coroutines, coroutine_trait, stmt_expr_attributes)]
2+
3+
use std::ops::Coroutine;
4+
5+
fn foo() -> impl Coroutine<u8> {
6+
//~^ ERROR type mismatch in coroutine arguments
7+
#[coroutine]
8+
|_: ()| {}
9+
}
10+
11+
fn main() { }
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
error[E0631]: type mismatch in coroutine arguments
2+
--> $DIR/arg-count-mismatch-on-unit-input.rs:5:13
3+
|
4+
LL | fn foo() -> impl Coroutine<u8> {
5+
| ^^^^^^^^^^^^^^^^^^ expected due to this
6+
...
7+
LL | |_: ()| {}
8+
| ------- found signature defined here
9+
|
10+
= note: expected coroutine signature `fn(u8) -> _`
11+
found coroutine signature `fn(()) -> _`
12+
13+
error: aborting due to 1 previous error
14+
15+
For more information about this error, try `rustc --explain E0631`.

0 commit comments

Comments
 (0)