-
-
Notifications
You must be signed in to change notification settings - Fork 403
Description
In go/types, instantiated functions do not have an associated types.Object. For
func Fn1[T any](x T) {}
func Fn2() {
Fn1[int](0)
}
in Fn2, info.ObjectOf(Fn1) will return the parameterized Fn1. info.Instances[Fn1] will give us the type argument (int) and the resulting signature (func(int)) but no types.Object for this instantiation. It is essentially an anonymous function.
This is problematic for unused, because unused's graph consists of values from the go/types type system (so that we can serialize it and only need type information, not the IR).
Consider this example, which leads to a false negative:
type c1 struct{}
func Fn[T any]() {}
func uncalled() {
Fn[c1]()
}
In go/ir, we have three functions: Fn, uncalled, and a wrapper that calls Fn generically, with the type argument c1. But because we have no types.Object for the instance, the wrapper's Object is Fn. Thus, when we analyze the wrapper and see the use of c1, we associate that use with Fn, not with the wrapper. Thus, even though uncalled is unused, and Fn is never instantiated with c1, we still consider c1 used, because Fn is exported, and thus used.
We end up with the following graph, where the node (*types.Func) func command-line-arguments.Fn6[T any]() contains edges for both Fn and the wrapper representing Fn[c1].
graph TD
n1("Root")
n1 -->|edgeExportedFunction| n2
n2("(*types.Func) func command-line-arguments.Fn6[T any]()")
n2 -->|edgeFunctionArgument| n6
n2 -->|edgeType| n6
n2 -->|edgeInstructionOperand| n2
n2 -->|edgeTypeArg| n5
n3("(*types.Func) func command-line-arguments.uncalled()")
n3 -->|edgeInstructionOperand| n2
n4("(*types.TypeName) type command-line-arguments.c8 struct{}")
n4 -->|edgeNamedType| n5
n7("(*types.TypeName) type parameter T any")
n7 -->|edgeNamedType| n6
n6("(*types.TypeParam) T")
n6 -->|edgeTypeName| n7
n5("(*types.Named) command-line-arguments.c8")
n5 -->|edgeTypeName| n4
style n2 stroke:lime
style n4 stroke:lime
style n7 stroke:lime
style n5 stroke:lime
style n3 stroke:red