Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

x/tools/go/ssa: incomplete type parameter substitution causing panics #66783

Open
jcd2 opened this issue Apr 11, 2024 · 4 comments
Open

x/tools/go/ssa: incomplete type parameter substitution causing panics #66783

jcd2 opened this issue Apr 11, 2024 · 4 comments
Assignees
Labels
NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. Tools This label describes issues relating to any tools in the x/tools repository.
Milestone

Comments

@jcd2
Copy link

jcd2 commented Apr 11, 2024

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
...
@gopherbot gopherbot added the Tools This label describes issues relating to any tools in the x/tools repository. label Apr 11, 2024
@gopherbot gopherbot added this to the Unreleased milestone Apr 11, 2024
@jcd2
Copy link
Author

jcd2 commented Apr 11, 2024

@adonovan @timothy-king

@cagedmantis cagedmantis added the NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. label Apr 11, 2024
@cagedmantis
Copy link
Contributor

cc @findleyr

@timothy-king
Copy link
Contributor

The first example requires supporting local types with type parameters. This will take some thought.

Related to #58573 and #65152.

@gopherbot
Copy link

Change https://go.dev/cl/581835 mentions this issue: go/ssa: fixing Named type substitution

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. Tools This label describes issues relating to any tools in the x/tools repository.
Projects
None yet
Development

No branches or pull requests

4 participants