Repository navigation
return in a generator finishes it - #428
Merged
Merged
Conversation
…orresponding tests
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
returnin afunction*was not rewritten by the generator transform:The body is pasted into the generated
next(), whereyield esets the resume step and returns{value: e, done: false}. A userreturnstayed a plain return, so it returned the bare value, and it didn't advance the step, so every laternext()resumed at the lastyield.Change
buildGeneratorWrapperDeclarationflags the body's ownreturnstatements withInternalFlags::GeneratorReturn(new bit).FilterVisitorSkipFuncsASTleaves thereturns of nested functions, arrows and classes alone.mlirGen(ReturnStatement)turns a flaggedreturn eintostep = -1; return {value: e, done: true}; a barereturngivesvalue: undefined.next()starts withif (this.step < 0) return {value: undefined, done: true}, so every call after areturnis done. It's a sentinel rather than a final state label because labels are numbered in program order, so a final label's number isn't known yet at an earlierreturn.Not changed (exists on
main)The finished
valueis wrong even without a userreturn:function* g() { yield "a"; }, and after the lastnext(),r.value === undefinedis false. It reads as the text"undefined"for a string generator and0for a number one (warningusing casting to undefined value). This is return-type inference droppingundefinedfromnext()'s value type. The new test assertsdoneand real values only.Tests
00generator_return.ts(compile + jit): value + done onreturn, done after it,for...ofstopping, an early barereturn, areturninside a loop, a nested arrow'sreturn, and a method generator.-mm=own.🤖 Generated with Claude Code