fix fieldToStruct for generics instantiated across package boundaries (#1028)

When compiling a package that instantiates a generic type from another
package, info.Types only contains the instantiated *types.Named. The
*types.Struct case in recordFieldToStruct returns early on instantiated
structs (field != field.Origin()), so the origin struct was never
recorded in fieldToStruct. At rewrite time, looking up the origin field
then failed with "could not find struct for field X".

Fix by also recursing into typ.Origin() for instantiated named types,
so the uninstantiated struct is visited and its fields are recorded.

Fixes #1027.
This commit is contained in:
Golo Roden
2026-04-16 01:03:37 +02:00
committed by GitHub
parent 28c2fd54c0
commit cdc4b23ac5
2 changed files with 46 additions and 1 deletions
+45
View File
@@ -7,6 +7,15 @@ go 1.23
-- garble_main.go --
package main
import "test/main/lib"
type Blob []byte
func (b Blob) MarshalBinary() ([]byte, error) { return b, nil }
func (b *Blob) UnmarshalBinary(d []byte) error { *b = append((*b)[:0], d...); return nil }
type Name string
func main() {
GenericFunc[int, int](1, 2)
var _ GenericVector[int]
@@ -21,6 +30,11 @@ func main() {
ga.list = nil
var gan genericAliasNamed
gan.list = nil
e := lib.Entry[Name, Blob, *Blob]{Key: "k", Data: Blob("v")}
r := lib.Load[Name, Blob, *Blob](e)
_ = r.Data.Key
_ = r.Data.Value
}
func GenericFunc[GenericParamA, B any](x GenericParamA, y B) {}
@@ -97,3 +111,34 @@ func byKeys[T any](m map[string]T) []struct {
}
var _ = byKeys(map[string]int{"one": 1})
-- lib/lib.go --
package lib
import "encoding"
type Pair[Key, Value any] struct {
Key Key
Value Value
}
type Result[TData any] struct {
Data TData
Err error
}
type Entry[TKey ~string, TData encoding.BinaryMarshaler, TPtr interface {
*TData
encoding.BinaryUnmarshaler
}] struct {
Key TKey
Data TData
}
func Load[TKey ~string, TData encoding.BinaryMarshaler, TPtr interface {
*TData
encoding.BinaryUnmarshaler
}](e Entry[TKey, TData, TPtr]) Result[Pair[TKey, TData]] {
return Result[Pair[TKey, TData]]{
Data: Pair[TKey, TData]{Key: e.Key, Value: e.Data},
}
}
+1 -1
View File
@@ -137,7 +137,7 @@ func recordFieldToStruct(typ types.Type, done map[*types.Named]bool, fieldToStru
return
}
done[typ] = true
recordFieldToStruct(typ.Underlying(), done, fieldToStruct)
recordFieldToStruct(typ.Origin().Underlying(), done, fieldToStruct)
case *types.Struct:
for field := range typ.Fields() {
if field != field.Origin() {