Skip to content

Resolve embedded-interface fields in get() builtin (match member access)#977

Open
greymoth-jp wants to merge 1 commit into
expr-lang:masterfrom
greymoth-jp:fix/get-embedded-interface-field
Open

Resolve embedded-interface fields in get() builtin (match member access)#977
greymoth-jp wants to merge 1 commit into
expr-lang:masterfrom
greymoth-jp:fix/get-embedded-interface-field

Conversation

@greymoth-jp

Copy link
Copy Markdown

The builtin get(obj, "field") doesn't resolve fields on the concrete type behind an embedded interface, while member access (...).field does. So for a value whose static type is unknown at compile time, (cond ? x : y).Value returns the value but get((cond ? x : y), "Value") returns nil — inconsistent access for the same field.

PR #952 added fetchFromEmbeddedInterfaces to runtime.Fetch but left its sibling get() behind; #935 had previously kept the two in lockstep. The fix mirrors #952's logic into get().

Verified both ways with go test: old returns nil, fixed returns the value; a missing field still returns nil (no panic), zero regression across the suite.

runtime.Fetch was taught in expr-lang#952 to resolve a field on the concrete type
held by an embedded interface, but the sibling builtin get() was left on
the old standard-promotion-only lookup. get() is documented to differ from
runtime.Fetch only in returning nil instead of panicking, so the same field
access returned a value through member access (a.field) yet nil through
get(a, "field").

Share the traversal by exporting runtime.FetchFromEmbeddedInterfaces and
calling it from get()'s struct branch, mirroring Fetch. Adds a regression
test under test/issues/952.
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.

1 participant