Files
garble/testdata/script/typeparams.txtar
T
Daniel Martí e693cd0632 stabilize generic type param hashing for anonymous struct fields
Avoid hashing free type parameters by object/name identity in type
hashing and use traversal-local canonical IDs instead.
This keeps obfuscated field names stable across alpha-renamed generic
signatures (e.g. T vs newT), fixing interface/method mismatches.

The added test case fails without the fix:

    > exec garble build
    [stderr]
    # test/main
    YiaBFlNH.go:48: cannot use bT6psGs5O (variable of type *QdwRyqV[aEqmF4M, zpotHfQdnNB]) as E_OKfdHoPH[zpotHfQdnNB] value in return statement: *QdwRyqV[aEqmF4M, zpotHfQdnNB] does not implement E_OKfdHoPH[zpotHfQdnNB] (wrong type for method Redirect)
    		have Redirect(struct{palTavb zpotHfQdnNB})
    		want Redirect(struct{g3N8A_R zpotHfQdnNB})

The fix is Paul's; this is rebased on an updated version of typeutil,
and the test is now part of typeparams.txtar and much smaller.

Fixes #991.

Co-authored-by: Paul Scheduikat <lu4p@pm.me>
2026-02-28 01:22:11 +01:00

69 lines
1.4 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
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)
}
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}) {}