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

cmd/go2go: A type alias that references a parameterized type in another package causes a panic #39792

Closed
firelizzard18 opened this issue Jun 23, 2020 · 2 comments

Comments

@firelizzard18
Copy link
Contributor

firelizzard18 commented Jun 23, 2020

If package x contains a type X that is a parameterized type, and package y contains a type Y = x.X, go tool go2go build will fail with a panic upon attempting to instantiate type Y.

This fails because spec *ast.TypeSpec for an alias has spec.TParams == nil, which causes a panic in *translator.instantiateTypeDecl. A workaround is to modify *translator.findTypeSpec to resolve type aliases to the *ast.TypeSpec of the underlying type:

diff --git a/src/go/go2go/instantiate.go b/src/go/go2go/instantiate.go
index bcb38de64a..2351ee6c13 100644
--- a/src/go/go2go/instantiate.go
+++ b/src/go/go2go/instantiate.go
@@ -232,8 +232,18 @@ func (t *translator) findTypeSpec(qid qualifiedIdent) (*ast.TypeSpec, error) {
                return nil, fmt.Errorf("could not find Object for %q", qid)
        }
        spec, ok := t.importer.lookupTypeSpec(obj)
-       if !ok {
-               return nil, fmt.Errorf("could not find type spec for %q", qid)
+       for {
+               if !ok {
+                       return nil, fmt.Errorf("could not find type spec for %q", qid)
+               }
+               if spec.TParams != nil {
+                       break
+               }
+               named, ok := t.importer.info.TypeOf(spec.Type).(*types.Named)
+               if !ok || named.Obj().IsAlias() {
+                       break
+               }
+               spec, ok = t.importer.lookupTypeSpec(named.Obj())
        }
        return spec, nil
 }

What version of Go are you using (go version)?

$ go version
go version devel +2faeebf4e5 Tue Jun 23 04:54:48 2020 +0000 linux/amd64

What operating system and processor architecture are you using (go env)?

go env Output
$ go env
GOARCH="amd64"
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GOOS="linux"

What did you do?

What did you expect to see?

A successful build

What did you see instead?

panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x8 pc=0x60f161]

goroutine 1 [running]:
go/go2go.(*translator).instantiateTypeDecl(0xc0004f5698, 0x0, 0xc000181620, 0xc000112f30, 0xc000181680, 0x2, 0x2, 0xc000369020, 0x2, 0x2, ...)
        /usr/lib/go-tip/src/go/go2go/instantiate.go:157 +0x81
go/go2go.(*translator).translateTypeInstantiation(0xc0004f5698, 0xc000182380)
        /usr/lib/go-tip/src/go/go2go/rewrite.go:909 +0x4e8
go/go2go.(*translator).translateExpr(0xc0004f5698, 0xc000182380)
        /usr/lib/go-tip/src/go/go2go/rewrite.go:657 +0x385
go/go2go.(*translator).translateExpr(0xc0004f5698, 0xc000177bf0)
        /usr/lib/go-tip/src/go/go2go/rewrite.go:660 +0x365
go/go2go.(*translator).translateExprList(0xc0004f5698, 0xc000177bf0, 0x1, 0x1)
        /usr/lib/go-tip/src/go/go2go/rewrite.go:791 +0x46
go/go2go.(*translator).translateExpr(0xc0004f5698, 0xc000177c00)
        /usr/lib/go-tip/src/go/go2go/rewrite.go:659 +0x349
go/go2go.(*translator).translateExprList(0xc0004f5698, 0xc000177c00, 0x1, 0x1)
        /usr/lib/go-tip/src/go/go2go/rewrite.go:791 +0x46
go/go2go.(*translator).translateStmt(0xc0004f5698, 0xc00012e940)
        /usr/lib/go-tip/src/go/go2go/rewrite.go:559 +0x29d
go/go2go.(*translator).translateBlockStmt(0xc0004f5698, 0xc00017f5c0)
        /usr/lib/go-tip/src/go/go2go/rewrite.go:520 +0x57
go/go2go.(*translator).translateFuncDecl(0xc0004f5698, 0xc00011c970)
        /usr/lib/go-tip/src/go/go2go/rewrite.go:510 +0xc5
go/go2go.(*translator).translate(0xc0004f5698, 0xc00011ca00)
        /usr/lib/go-tip/src/go/go2go/rewrite.go:437 +0x391
go/go2go.rewriteAST(0xc00010a240, 0xc000024420, 0x0, 0x0, 0xc0001847d0, 0xc00011ca00, 0xc0005a2400, 0x0, 0x0)
        /usr/lib/go-tip/src/go/go2go/rewrite.go:241 +0xe5
go/go2go.rewriteFile(0x693853, 0x1, 0xc00010a240, 0xc000024420, 0x0, 0x0, 0xc0001847d0, 0xc000013130, 0xd, 0xc00011ca00, ...)
        /usr/lib/go-tip/src/go/go2go/rewrite.go:205 +0xb8
go/go2go.rewriteFilesInPath(0xc000024420, 0x0, 0x0, 0x693853, 0x1, 0xc000132280, 0x6, 0x13, 0x0, 0x0, ...)
        /usr/lib/go-tip/src/go/go2go/go2go.go:104 +0xc11
go/go2go.rewriteToPkgs(0xc000024420, 0x0, 0x0, 0x693853, 0x1, 0xc00000c200, 0xc0000748d0, 0xc0000748a0, 0xc000074870, 0xc000074840)
        /usr/lib/go-tip/src/go/go2go/go2go.go:46 +0x165
go/go2go.Rewrite(...)
        /usr/lib/go-tip/src/go/go2go/go2go.go:30
main.translate(0xc000024420, 0x693853, 0x1)
        /usr/lib/go-tip/src/cmd/go2go/translate.go:15 +0x47
main.main()
        /usr/lib/go-tip/src/cmd/go2go/main.go:68 +0x9da
@gopherbot
Copy link

Change https://golang.org/cl/239598 mentions this issue: [dev.go2go] go/go2go: resolve type alias of parameterized type

@ianlancetaylor
Copy link
Contributor

Thanks for pointing that out. I wasn't able to recreate the problem using the go-iter package, but I was able to create a small test case based on your description. The problem shown by that test case is now fixed on the dev.go2go branch.

gopherbot pushed a commit that referenced this issue Jun 23, 2020
Fixes #39792

Change-Id: I9eab19a4f516be5a71e71f04b91c4e46b189fba9
Reviewed-on: https://go-review.googlesource.com/c/go/+/239598
Reviewed-by: Ian Lance Taylor <iant@golang.org>
@golang golang locked and limited conversation to collaborators Jun 23, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

3 participants