Skip to content

Commit 90a3456

Browse files
committed
unused: don't get stuck chasing mutually recursive type instantiations
Closes gh-1247 (cherry picked from commit 6dbb73d)
1 parent 3dfe275 commit 90a3456

File tree

2 files changed

+28
-3
lines changed

2 files changed

+28
-3
lines changed

unused/testdata/src/typeparams/typeparams.go

+14
Original file line numberDiff line numberDiff line change
@@ -70,3 +70,17 @@ func Fn9[T struct { // used
7070
type s2 struct{} // used
7171

7272
func fn10[E any](x []E) {} // unused
73+
74+
type Tree[T any] struct { // used
75+
Root *Node[T] // used
76+
}
77+
78+
type Node[T any] struct { // used
79+
Tree *Tree[T] // used
80+
}
81+
82+
type foo struct{} // used
83+
84+
type Bar *Node[foo] // used
85+
86+
func (n Node[T]) anyMethod() {} // unused

unused/unused.go

+14-3
Original file line numberDiff line numberDiff line change
@@ -832,6 +832,9 @@ func (g *graph) see(obj interface{}) *node {
832832
if fn, ok := obj.(*types.Func); ok {
833833
obj = typeparams.OriginMethod(fn)
834834
}
835+
if t, ok := obj.(*types.Named); ok {
836+
obj = typeparams.NamedTypeOrigin(t)
837+
}
835838

836839
// add new node to graph
837840
node, _ := g.node(obj)
@@ -871,6 +874,13 @@ func (g *graph) use(used, by interface{}, kind edgeKind) {
871874
by = typeparams.OriginMethod(fn)
872875
}
873876

877+
if t, ok := used.(*types.Named); ok {
878+
used = typeparams.NamedTypeOrigin(t)
879+
}
880+
if t, ok := by.(*types.Named); ok {
881+
by = typeparams.NamedTypeOrigin(t)
882+
}
883+
874884
usedNode, new := g.node(used)
875885
assert(!new)
876886
if by == nil {
@@ -1427,13 +1437,14 @@ func (g *graph) typ(t types.Type, parent types.Type) {
14271437
// Nothing to do
14281438
case *types.Named:
14291439
// (9.3) types use their underlying and element types
1430-
g.seeAndUse(t.Underlying(), t, edgeUnderlyingType)
1440+
origin := typeparams.NamedTypeOrigin(t)
1441+
g.seeAndUse(origin.Underlying(), t, edgeUnderlyingType)
14311442
g.seeAndUse(t.Obj(), t, edgeTypeName)
14321443
g.seeAndUse(t, t.Obj(), edgeNamedType)
14331444

14341445
// (2.4) named types use the pointer type
14351446
if _, ok := t.Underlying().(*types.Interface); !ok && t.NumMethods() > 0 {
1436-
g.seeAndUse(g.newPointer(t), t, edgePointerType)
1447+
g.seeAndUse(g.newPointer(origin), t, edgePointerType)
14371448
}
14381449

14391450
// (2.5) named types use their type parameters
@@ -1462,7 +1473,7 @@ func (g *graph) typ(t types.Type, parent types.Type) {
14621473
g.function(g.pkg.IR.Prog.FuncValue(t.Method(i)))
14631474
}
14641475

1465-
g.typ(t.Underlying(), t)
1476+
g.typ(origin.Underlying(), t)
14661477
case *types.Slice:
14671478
// (9.3) types use their underlying and element types
14681479
g.seeAndUse(t.Elem(), t, edgeElementType)

0 commit comments

Comments
 (0)