fix: #776 — implicit-return functions now produce undefined, not 0#786
Merged
Conversation
A function that falls off the end without an explicit `return` was emitting `ret double 0.0`, which under NaN-boxing is the number 0 — not `undefined` (TAG_UNDEFINED = 0x7FFC_0000_0000_0001). Code like `f() === undefined` or `typeof f()` therefore disagreed with JS semantics. Replace every implicit-return / bare-`return;` site with the NaN-boxed TAG_UNDEFINED literal (sync + async, regular functions, closures, methods, static methods). Async epilogues also resolve the promise with `undefined` instead of `0`. With the bug fixed, the class-decorator return-value guard added in PR #754 can be tightened from `typeof ret === "function"` to `ret !== undefined`, catching primitive and plain-object replacement returns as well. Workaround comment dropped, error message generalized, parity expectation updated to match.
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.
Summary
returnwere emittingret double 0.0in LLVM IR. In Perry's NaN-boxing scheme,0.0is the number 0, notundefined(TAG_UNDEFINED = 0x7FFC_0000_0000_0001). User code that didf() === undefined,typeof f(), orconsole.log(f())against an implicit-return function gotfalse/"number"/0instead of the JS-correcttrue/"undefined"/undefined.return;site: regular functions, closures, methods, static methods (sync + async). Async paths also now resolve the promise withundefined, not0.typeof ret === "function"toret !== undefined, removed the workaround comment, and updated the error message. The previous narrow check only caught function/class replacements; primitive or object returns were silently discarded.Test plan
function bare() {} ; console.log(bare() === undefined, typeof bare(), bare())→true undefined undefined@Injectable(no-return decorator) still works@ReturnsFn/@ReturnsObjdecorators now throw TypeErrormainbaseline at 331)