Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix: infer type of async block with tail return expr #17174

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

Kohei316
Copy link
Contributor

@Kohei316 Kohei316 commented May 2, 2024

Fixes #17106
The infer_async_block method calls the infer_block method internally, which returns the never type without coercion when tail_expr is None and ctx.diverges is Diverges::Always.This is the reason for the bug in this issue.

if this.diverges.is_always() {
// we don't even make an attempt at coercion
this.table.new_maybe_never_var()

This PR solves the bug by adding a process to coerce after calling infer_block method.

This code passes all the tests, including tests I added for this isuue, however, I am not sure if this solution is right. I think that this solution is an ad hoc solution. So, I would appreciate to have your review.
I apologize if I'm off the mark, but infer_async_block method should be rewritten to share code with the process of infering type of expr::Closure instead of the infer_block method. That way it will be closer to the infer process of rustc.

@rustbot rustbot added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label May 2, 2024
@Kohei316 Kohei316 changed the title Fix coercion of async block Fix: infer type of async block with tail return expr May 2, 2024
let (_, inner_ty) = self.with_breakable_ctx(BreakableKind::Border, None, None, |this| {
this.infer_block(tgt_expr, *id, statements, *tail, None, &Expectation::has_type(ret_ty))
let ty = this.infer_block(tgt_expr, *id, statements, *tail, None, expected);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it suffices to merely replace this by self.infer_return(tgt_expr)?

Copy link
Contributor Author

@Kohei316 Kohei316 May 13, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I do not fully understand these functions and may be misunderstanding, but I think that we cannot use this way. First, infer_return method only coerces and does not return a value. (This problem may be solved by changing infer return.) Next, the method internally calls infer_expr_inner, which internally calls infer_async_block. This results in an infinite loop.

@Veykril Veykril added S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels May 13, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

return inside async blocks hints impl Future<Output = !>
3 participants