mirror of
https://github.com/burrowers/garble.git
synced 2026-04-22 15:47:04 +08:00
cdc4b23ac5
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.
145 lines
2.7 KiB
Plaintext
145 lines
2.7 KiB
Plaintext
exec garble build
|
|
! binsubstr main$exe ${WORK} 'garble_main.go' 'GenericFunc' 'GenericVector' 'PredeclaredSignedInteger' 'StringableSignedInteger' 'CombineEmbeds' 'GenericParam'
|
|
-- go.mod --
|
|
module test/main
|
|
|
|
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]
|
|
|
|
g1 := GenericGraph[string]{Content: "Foo"}
|
|
g1.Edges = make([]GenericGraph[string], 1)
|
|
|
|
g2 := GenericGraph[*[]byte]{Content: new([]byte)}
|
|
g2.Edges = make([]GenericGraph[*[]byte], 1)
|
|
|
|
var ga genericAlias
|
|
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) {}
|
|
|
|
type GenericVector[GenericParamT any] []GenericParamT
|
|
|
|
type GenericGraph[T any] struct {
|
|
Content T
|
|
Edges []GenericGraph[T]
|
|
}
|
|
|
|
type PredeclaredSignedInteger interface {
|
|
int | int8 | int16 | int32 | int64
|
|
}
|
|
|
|
type StringableSignedInteger interface {
|
|
~int | ~int8 | ~int16 | ~int32 | ~int64
|
|
|
|
String() string
|
|
}
|
|
|
|
type CombineEmbeds interface {
|
|
string | int
|
|
|
|
interface{ EmbeddedMethod() }
|
|
RegularMethod()
|
|
}
|
|
|
|
type Slice[T any] []T
|
|
|
|
func sliceOfPointer() Slice[*any] {
|
|
return []*any{}
|
|
}
|
|
|
|
type Map[K, V comparable] map[K]V
|
|
|
|
var _ = Map[string, struct{}]{}
|
|
|
|
type Result[T any] interface {
|
|
AsResult() Result[T]
|
|
Redirect(struct { ret T })
|
|
}
|
|
|
|
type AsyncResult[oldT, newT any] struct {}
|
|
|
|
func (w *AsyncResult[oldT, newT]) AsResult() Result[newT] {
|
|
return w
|
|
}
|
|
|
|
func (w *AsyncResult[oldT, newT]) Redirect(struct {ret newT}) {}
|
|
|
|
type genericAlias = generic[int]
|
|
type generic[T any] struct {
|
|
list *T
|
|
}
|
|
|
|
type genericAliasNamed genericAlias
|
|
|
|
func byKeys[T any](m map[string]T) []struct {
|
|
K string
|
|
V T
|
|
} {
|
|
vs := make([]struct {
|
|
K string
|
|
V T
|
|
}, 0, len(m))
|
|
for k, v := range m {
|
|
vs = append(vs, struct {
|
|
K string
|
|
V T
|
|
}{k, v})
|
|
}
|
|
return vs
|
|
}
|
|
|
|
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},
|
|
}
|
|
}
|