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

feature(gen_blocks): cannot use the ? operator in a gen block that returns () #117486

Open
kanashimia opened this issue Nov 1, 2023 · 6 comments
Labels
C-bug Category: This is a bug. F-gen_blocks `gen {}` expressions that produce `Iterator`s T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@kanashimia
Copy link

As per gen_blocks RFC:

Even when ? is used within a gen block, the block must return a value of type unit or !. That is, it does not return a value of Some(..), Ok(..), or Continue(..) as other such blocks might.

But currently upon using ? an error occurs: cannot use the ? operator in a gen block that returns ()

To reproduce: https://godbolt.org/z/4fGT9EM8q

@kanashimia kanashimia added the C-bug Category: This is a bug. label Nov 1, 2023
@rustbot rustbot added the needs-triage This issue may need triage. Remove it if it has been sufficiently triaged. label Nov 1, 2023
@kanashimia
Copy link
Author

CC: @oli-obk

@oli-obk oli-obk removed the needs-triage This issue may need triage. Remove it if it has been sufficiently triaged. label Nov 1, 2023
@Noratrieb Noratrieb added the T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. label Nov 1, 2023
@oli-obk oli-obk added the F-gen_blocks `gen {}` expressions that produce `Iterator`s label Nov 1, 2023
@compiler-errors
Copy link
Member

This is kind of expected given the desugaring for expr? being something like match expr { Ok(t) => t, Err(e) => return e.into() } (that's not exactly the desugaring, but it illuminates the problem) ,since gen blocks have no return type, just a yield type.

I guess we could make ? aware of the gen block and instead desugar to a return; when it's given an error type that can be converted to () or something... though this is the first time we'd be giving a special meaning to ? based on its context.

@jrandolf
Copy link

jrandolf commented May 1, 2024

Making ? aware of generator blocks is a little awkward. Already ? performs an Into call (through the residual work), so adding more functionality may be adding a bit too many eggs in the basket.

The problem with this issue is the semantics of a theoretical '?' in a generator is not necessarily the canonical extension. For example, what is expected if '?' is used in a for block? Should it just return? Or perhaps break/continue? In a non-gen situation, these question don't exist because the function ends at the decision to return.

A solution could be to have a user-crate with a few macros that perform the necessary functionality. For example, it could have "or_yield", "or_yield_continue", and "or_yield_break". Note the "or_yield_break" would accept 1-2 arguments. Names would need to be bikeshed.

@oli-obk
Copy link
Contributor

oli-obk commented May 1, 2024

For example, what is expected if '?' is used in a for block? Should it just return? Or perhaps break/continue? In a non-gen situation, these question don't exist because the function ends at the decision to return.

So would the generator. My expected desugaring of the Err case is

yield Err(e);
return;

Forcing the generator to be Iterator<Item = Result<T, E>>.

If you want the generator to continue yieldig items after an Err, you need to manually yield. This short circuiting behaviour matches what you get from .collect<Result<Vec<T>, E>>() on an iterator of Result<T, E>s

@jrandolf
Copy link

jrandolf commented May 1, 2024

The comment was just to express all PoVs. IMO, I'd also lean toward making ? short-circuit. For the most part, it seems the other cases aren't used, however there is a bias here since collect made the choice not to collect errors as well.

But is it the case gen will never implement return values? For example, JavaScript generators allow return values separate from yielded values.

@Kolsky
Copy link

Kolsky commented May 1, 2024

It would be surprising if ? didn't short circuit. And there are no examples where ? doing anything else would be useful.

Returning values from generator other than () isn't blocked on this proposal either, since it should be forward-compatible by explicitly requiring return to be of unit type.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
C-bug Category: This is a bug. F-gen_blocks `gen {}` expressions that produce `Iterator`s T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

No branches or pull requests

7 participants