Hello!
When x/tools/go/ssa is instantiating generic functions, it seems that the type parameter substitution algorithm does not successfully substitute all instances of the function's parameters when there are other parameterized types involved in an expression. This is easier to explain with two examples.
In this example, the panic occurs while processing the expression B[rune](s)
while instantiating S[int].M
. The type argument for B
is unimportant as it's not used, but the presence of the type parameter prevents the type substitution algorithm from rewriting the underlying type of B[rune]
from struct{a T}
to struct{a int}
, and ssa generation for the conversion subsequently panics.
convert.go
package main
type S[T any] struct {
a T
}
func (s S[T]) M() {
type A S[T]
type B[U any] A
_ = B[rune](s)
}
func main() {
S[int]{}.M()
}
$ go install golang.org/x/tools/cmd/ssadump@latest
$ ssadump -build=G convert.go
panic: in (command-line-arguments.S[int]).M[int]: cannot convert term *t0 (command-line-arguments.S[int] [within struct{a int}]) to type command-line-arguments.B[rune] [within struct{a T}]
...
In this second example, the panic occurs while processing the method expression i.M
while instantiating the function foo[int]
. Here golang.org/x/tools/go/ssa.(*subster).typ
panics; it seems that it cannot perform chains of substitutions through a parameterized named type to get from I2[int]
to I1[int]
to interface { M(int) }
.
method-expression.go:
package main
type I1[T any] interface {
M(T)
}
type I2[T any] I1[T]
func foo[T any](i I2[T]) {
_ = i.M
}
type S[T any] struct{}
func (s S[T]) M(t T) {}
func main() {
foo[int](I2[int](S[int]{}))
}
$ ssadump -build=G method-expression.go
panic: type param without replacement encountered
...
Comment From: jcd2
@adonovan @timothy-king
Comment From: cagedmantis
cc @findleyr
Comment From: timothy-king
The first example requires supporting local types with type parameters. This will take some thought.
Related to #58573 and #65152.
Comment From: gopherbot
Change https://go.dev/cl/581835 mentions this issue: go/ssa: fixing Named type substitution