feat(vm): reflect proxy boxes multi-return funcs as vectors - #776
Merged
Merged
Conversation
abogoyavlensky
force-pushed
the
interop/p3-reflect-multireturn
branch
from
August 23, 2026 21:33
6fd9d66 to
bd110da
Compare
nooga
approved these changes
Sep 1, 2026
nooga
left a comment
Owner
There was a problem hiding this comment.
LGTM. Small, correct, tested (strings.Cut-style 3-return). Build/vet/tests/check-generated pass locally. Merging.
Collaborator
|
Queue update: #758 has merged and advanced |
The proxy assumed at most two results and silently dropped the rest. The drop happened on the Go side, before boxing, so a .lg veneer could never recover the lost values and a wrapper library has no Go of its own to shim with — nothing downstream could work around it. (a, b, ok) and (a, b, err) are ordinary modern Go; strings.Cut returns three. Peel a trailing error, then box what remains as nil, a single value, or a vector. One judgment call, because the plan for this change contradicted itself: its design said a trailing error is peeled as a throw, its task steps said existing 0/1/2-shape behavior is unchanged, and those disagree about func() error — which today returns the error as a VALUE and never throws. Every reflect-boxed Close/Write/Flush has that shape, so peeling there would quietly turn (if (.Close f) ...) into a throw across a lot of working interop. The peel therefore applies only when a non-error result remains: from (T, error) upward, exactly where it already did. func() error is pinned by its own test. The only intended behavior change is the one the design asked for: func() (A, B) now yields [a b] instead of a alone. The type test stays on the DECLARED result type, so a function returning a concrete *MyError returns a value rather than signalling failure, and an error anywhere but last is an ordinary value. The TinyGo stub is a separate build-tagged file and is untouched. Known limitation, pinned by a test rather than fixed: BoxValue does not support Go arrays. Its slice/array case calls IsNil, invalid for arrays, and the branches under it assume []int64 or Bytes(). This predates multi-return — func() [1]int panics identically and always has — and multi-return only makes the existing hole reachable through one more shape, turning a silent wrong answer into a visible error. Fixing BoxValue is out of scope here. docs/guide/go-interop.md gains the full result-mapping table; there was no written rule for this before. Baseline: main a665761. Independent of the other interop branches.
nooga
force-pushed
the
interop/p3-reflect-multireturn
branch
from
September 6, 2026 22:14
aed5ea0 to
16a9776
Compare
10 tasks
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.
Resolves: #775
Same goal as #773: letting lgx projects depend on Go libraries. That only pays off if calling those libraries works, and the reflect proxy assumed at most two results, silently dropping the rest. Any
(a, b, ok)or(a, b, err)function came back wrong, andstrings.Cutreturns three. The values were dropped on the Go side before boxing, so no.lgwrapper could recover them.Independent of #773 and can land in any order.