Skip to content

runtime: ignore blank fields when comparing structs in interfaces - #5880

Open
davecheney wants to merge 1 commit into
tinygo-org:devfrom
davecheney:fix-blank-field-interface-equal
Open

davecheney wants to merge 1 commit into
tinygo-org:devfrom
davecheney:fix-blank-field-interface-equal

Conversation

@davecheney

@davecheney davecheney commented Oct 14, 2026 •

Copy link
Copy Markdown
Contributor

The Go spec says that two struct values are equal if their corresponding non-blank fields are equal. The compiler already skips blank fields for a direct struct comparison, but the runtime compared all fields when the struct values were held in interfaces. This came from the upstream test/blank.go test, where two struct values that differ only in a blank field compared as not equal.

The struct comparison in the runtime is recursive and gets the name of each field from RawType.Field. Before #5884, TestBuild/AVR/interface.go failed with "goroutine stack overflow" on the 384-byte simavr goroutine stack. #5884 has merged and this PR is rebased on dev.

RawType.Field still allocates its one-element Index slice, so each struct field in an interface comparison causes one allocation. If this is a problem, a separate change can remove it.

@davecheney
davecheney requested a review from jakebailey October 14, 2026 10:30
@davecheney
davecheney marked this pull request as draft October 14, 2026 12:28
davecheney added a commit to davecheney/tinygo that referenced this pull request Oct 14, 2026
…data

The blank-field equality fix in PR tinygo-org#5880 used Field to check each field name. That call returned metadata that the comparison did not need and increased stack use enough to cause a stack overflow on AVR. A field name lookup should not require the same stack space as a full metadata lookup.

Keep this prerequisite separate from the equality fix so each change can be reviewed on its own. This commit does not change interface equality. The runtime caller and its equality regression tests remain separate work.
@davecheney
davecheney force-pushed the fix-blank-field-interface-equal branch from 7833b4d to aaf1cb5 Compare October 14, 2026 14:45
@davecheney
davecheney changed the base branch from dev to dfc/reflectlite-field-stack October 14, 2026 14:48
@davecheney
davecheney force-pushed the fix-blank-field-interface-equal branch from aaf1cb5 to 8e3bc78 Compare October 14, 2026 14:48
@davecheney
davecheney changed the base branch from dfc/reflectlite-field-stack to dev October 14, 2026 14:51
@davecheney
davecheney force-pushed the fix-blank-field-interface-equal branch from 8e3bc78 to e865bdb Compare October 14, 2026 14:56

@dgryski dgryski left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

LGTM

The Go spec says that two struct values are equal if their corresponding non-blank fields are equal. The compiler already skips blank fields for a direct struct comparison, but the runtime compared all fields when the struct values were held in interfaces. This came from the upstream test/blank.go test, where two struct values that differ only in a blank field compared as not equal.
@davecheney
davecheney force-pushed the fix-blank-field-interface-equal branch from e865bdb to bc49622 Compare October 18, 2026 01:38
@davecheney
davecheney marked this pull request as ready for review October 18, 2026 01:39
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants