Skip to content

Commit

Permalink
skip all type parameters in recordType
Browse files Browse the repository at this point in the history
We only did this for Container in the type switch, but not for Struct.
The added test case panics otherwise.
Just like in the previous case, we still don't need to recurse
into type parameters for fieldToStruct to be filled correctly.

Fixes #899
  • Loading branch information
lu4p authored and mvdan committed Jan 19, 2025
1 parent e6c0aef commit 6897998
Showing 2 changed files with 17 additions and 11 deletions.
20 changes: 11 additions & 9 deletions main.go
Original file line number Diff line number Diff line change
@@ -1683,21 +1683,23 @@ func computeFieldToStruct(info *types.Info) map[*types.Var]*types.Struct {
// Since types can be recursive, we need a map to avoid cycles.
// We only need to track named types as done, as all cycles must use them.
func recordType(used, origin types.Type, done map[*types.Named]bool, fieldToStruct map[*types.Var]*types.Struct) {
used = types.Unalias(used)
if origin == nil {
origin = used
}
origin = types.Unalias(origin)
used = types.Unalias(used)
type Container interface{ Elem() types.Type }
switch used := used.(type) {
case Container:
// origin may be a *types.TypeParam, which is not a Container.
} else {
origin = types.Unalias(origin)
// origin may be a [*types.TypeParam].
// For now, we haven't found a need to recurse in that case.
// We can edit this code in the future if we find an example,
// because we panic if a field is not in fieldToStruct.
if origin, ok := origin.(Container); ok {
recordType(used.Elem(), origin.Elem(), done, fieldToStruct)
if _, ok := origin.(*types.TypeParam); ok {
return
}
}
type Container interface{ Elem() types.Type }
switch used := used.(type) {
case Container:
recordType(used.Elem(), origin.(Container).Elem(), done, fieldToStruct)
case *types.Named:
if done[used] {
return
8 changes: 6 additions & 2 deletions testdata/script/typeparams.txtar
Original file line number Diff line number Diff line change
@@ -24,7 +24,7 @@ type GenericVector[GenericParamT any] []GenericParamT

type GenericGraph[T any] struct {
Content T
Edges []GenericGraph[T]
Edges []GenericGraph[T]
}

type PredeclaredSignedInteger interface {
@@ -40,7 +40,7 @@ type StringableSignedInteger interface {
type CombineEmbeds interface {
string | int

interface { EmbeddedMethod() }
interface{ EmbeddedMethod() }
RegularMethod()
}

@@ -49,3 +49,7 @@ type Slice[T any] []T
func sliceOfPointer() Slice[*any] {
return []*any{}
}

type Map[K, V comparable] map[K]V

var _ = Map[string, struct{}]{}

0 comments on commit 6897998

Please sign in to comment.