Go version
go version go1.23.0 darwin/arm64
Output of go env in your module/workspace:
GO111MODULE=''
GOARCH='arm64'
GOBIN=''
GOCACHE='/Users/varun/Library/Caches/go-build'
GOENV='/Users/varun/Library/Application Support/go/env'
GOEXE=''
GOEXPERIMENT=''
GOFLAGS=''
GOHOSTARCH='arm64'
GOHOSTOS='darwin'
GOINSECURE=''
GOMODCACHE='/Users/varun/.asdf/installs/golang/1.23.0/packages/pkg/mod'
GONOPROXY=''
GONOSUMDB=''
GOOS='darwin'
GOPATH='/Users/varun/.asdf/installs/golang/1.23.0/packages'
GOPRIVATE=''
GOPROXY='https://proxy.golang.org,direct'
GOROOT='/Users/varun/.asdf/installs/golang/1.23.0/go'
GOSUMDB='sum.golang.org'
GOTMPDIR=''
GOTOOLCHAIN='auto'
GOTOOLDIR='/Users/varun/.asdf/installs/golang/1.23.0/go/pkg/tool/darwin_arm64'
GOVCS=''
GOVERSION='go1.23.0'
GODEBUG=''
GOTELEMETRY='local'
GOTELEMETRYDIR='/Users/varun/Library/Application Support/go/telemetry'
GCCGO='gccgo'
GOARM64='v8.0'
AR='ar'
CC='clang'
CXX='clang++'
CGO_ENABLED='1'
GOMOD='/Users/varun/Code/play/go/underpanic/go.mod'
GOWORK=''
CGO_CFLAGS='-O2 -g'
CGO_CPPFLAGS=''
CGO_CXXFLAGS='-O2 -g'
CGO_FFLAGS='-O2 -g'
CGO_LDFLAGS='-O2 -g'
PKG_CONFIG='pkg-config'
GOGCCFLAGS='-fPIC -arch arm64 -pthread -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -ffile-prefix-map=/var/folders/tr/gylnxkts3bn0gyhhlrv8z9_m0000gn/T/go-build2694439591=/tmp/go-build -gno-record-gcc-switches -fno-common'
What did you do?
Minimal example: https://github.com/varungandhi-src/underpanic
I had some code using using APIs like String on *types.Named, as well as functions like types.NewMethodSet.
I upgraded that from Go 1.22.4 to Go 1.23.0
What did you see happen?
go/types.(*Named).under(0x140001a6850)
/Users/varun/.asdf/installs/golang/1.23.0/go/src/go/types/named.go:548 +0x38c
go/types.under({0x1007ca020, 0x140001a6850})
/Users/varun/.asdf/installs/golang/1.23.0/go/src/go/types/under.go:16 +0x2c
go/types.writeObject(0x14000467890, {0x1007cdb38, 0x140001a4780}, 0x0)
/Users/varun/.asdf/installs/golang/1.23.0/go/src/go/types/object.go:576 +0x734
go/types.ObjectString({0x1007cdb38, 0x140001a4780}, 0x0)
/Users/varun/.asdf/installs/golang/1.23.0/go/src/go/types/object.go:613 +0x44
go/types.(*TypeName).String(...)
/Users/varun/.asdf/installs/golang/1.23.0/go/src/go/types/object.go:619
main.main()
/Users/varun/Code/play/go/underpanic/main.go:33 +0x164
What did you expect to see?
Functions like NewMethodSet and methods like String should continue to work in the presence of CGo.
Comment From: gabyhelp
Related Issues and Documentation
- cmd/compile/internal/types2, go/types: don't panic when calling under/underlying #65344
- go/internal/gcimporter: untyped interface type parameter causes "panic: nil underlying" during testing #57015 (closed)
- cmd/go2go: panic with an embedded type param #43759
- cmd/compile: ICE compiling rangefunc for \< 1.23 in combination with Cgo #67497 (closed)
- cmd/compile/internal/types2: unify.go:449: assertion failed, panic #67872 (closed)
- cmd/go: bootstrap with Go 1.21.x fail at tip, panic: godebug: Value of name not listed in godebugs.All: gotypesalias #64106 (closed)
- go/types, types2: stack overflow results after naming type parameter after interface name. #50517 (closed)
- cmd/compile: panic when using typeparams #46353 (closed)
- x/tools/go/packages: panic loading with LoadTypes #31163 (closed)
- cmd/cgo: go 1.3 panics on recursive use of typedef #8368 (closed)
(Emoji vote if this was helpful or unhelpful; more detailed feedback welcome in this discussion.)
Comment From: ianlancetaylor
CC @griesemer @findleyr
Comment From: adonovan
Many thanks for the very helpful bug report. The input program that reproduces the problem can be reduced to the following, which does not use cgo:
package main
type (
T struct{}
U = T
S U
)
Loading it using this reduced main program:
package main
import (
"go/types"
"log"
"golang.org/x/tools/go/packages"
)
func main() {
cfg := &packages.Config{Mode: packages.NeedTypes}
pkgs, err := packages.Load(cfg, ".")
if err != nil {
log.Fatal(err)
}
obj := pkgs[0].Types.Scope().Lookup("S").(*types.TypeName)
_ = obj.String() // panics
}
produces the same crash:
processing type: type golang.org/x/tools/issue68877.T struct{}
panic: Named.check == nil but type is incomplete
goroutine 1 [running]:
go/types.(*Named).under(0x140000c0b60)
/Users/adonovan/w/goroot/src/go/types/named.go:548 +0x38c
go/types.under({0x1029e9bc0, 0x140000c0b60})
/Users/adonovan/w/goroot/src/go/types/under.go:16 +0x2c
go/types.writeObject(0x140002910b0, {0x1029ed7d8, 0x140005304b0}, 0x0)
/Users/adonovan/w/goroot/src/go/types/object.go:576 +0x734
go/types.ObjectString({0x1029ed7d8, 0x140005304b0}, 0x0)
/Users/adonovan/w/goroot/src/go/types/object.go:613 +0x44
go/types.(*TypeName).String(...)
/Users/adonovan/w/goroot/src/go/types/object.go:619
main.main()
/Users/adonovan/w/xtools/issue68877/main.go:33 +0x164
exit status 2
Comment From: adonovan
Reducing again to eliminate packages.Load:
func TestIssue68877(t *testing.T) {
setGotypesalias(t, true)
const src = `package main
type (
T struct{}
U = T
S U
)`
pkg := mustTypecheck(src, nil, nil)
S := pkg.Scope().Lookup("S").(*TypeName)
_ = S.String()
}
Comment From: griesemer
cc: @timothy-king for visibility
Comment From: griesemer
Analysis so far: The underlying problem (no pun intended) is that Named.Underlying may end up calling Unalias which may return a Named type which is not the actual underlying type. We can follow that chain to the end which addresses this particular issue ~but causes other tests to loop endlessly, for not yet fully understood reasons~.
The endless seem to be caused by invalid code (alias cycles). Should have a tentative CL later today.
Comment From: gopherbot
Change https://go.dev/cl/605757 mentions this issue: go/types, types2: fix Named.Underlying in the presence of Alias types
Comment From: griesemer
Gopherbot, please create a backport issue for Go 1.23.
Comment From: callthingsoff
Gopherbot, please create a backport issue for Go 1.23.
We need ‘@‘ the bot.
Comment From: findleyr
@gopherbot, please create a backport issue for Go 1.23: this is a regression in the type checker when run with GODEBUG=gotypesalias=1, the new default.
Comment From: gopherbot
Backport issue(s) opened: #68894 (for 1.23).
Remember to create the cherry-pick CL(s) as soon as the patch is submitted to master, according to https://go.dev/wiki/MinorReleases.
Comment From: gopherbot
Change https://go.dev/cl/605977 mentions this issue: go/types, types2: Named.cleanup must also handle *Alias types