derision-test / go-mockgen

MIT License
57 stars 7 forks source link

nil reference panic when generating mocks using Go 1.22.3 from a source file that references "context" #54

Closed arielshaqed closed 2 weeks ago

arielshaqed commented 2 weeks ago

Setup

Attempting to generate mocks for this interface:

package testdata

import (
    "context"
)

var _ = context.Background()

type Nothing interface {
}

panics on a nil pointer dereference if using go 1.22.3:

❯ go version
go version go1.22.3 linux/amd64
❯ go run github.com/derision-test/go-mockgen/cmd/go-mockgen@latest --force --disable-formatting --dirname=mock --interfaces Nothing ./
go-mockgen: loading data for 1 packages
panic: runtime error: invalid memory address or nil pointer dereference [recovered]
        panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x0 pc=0x6e9b8f]
[... see below for full stacktrace ...]

However using a go 1.21.3 binary everything works:

❯ go version
go version go1.21.3 linux/amd64
❯ go run github.com/derision-test/go-mockgen/cmd/go-mockgen@latest --force --disable-formatting --dirname=mock --interfaces Nothing ./
go-mockgen: loading data for 1 packages
go-mockgen: parsing package '.'
go-mockgen: generating code for interface 'Nothing'
go-mockgen: writing to './mock/nothing_mock.go'

I am willing to work on this issue if a committer would be willing to review and hopefully accept a PR.

THANKS!

go.mod

go.mod can specify a Go version. It crashes for both

module github.com/arielshaqed/foo

go 1.22

and

module github.com/arielshaqed/foo

go 1.21.3

However may need to use the latter version to get go 1.21 to agree to run on it.

Full stacktrace from crash
goroutine 41 [running]:
go/types.(*Checker).handleBailout(0xc0003d1c00, 0xc000041c60)
        /home/ariels/sdk/go1.22.3/src/go/types/check.go:367 +0x88
panic({0x7dbca0?, 0xb123a0?})
        /home/ariels/sdk/go1.22.3/src/runtime/panic.go:770 +0x132
go/types.(*StdSizes).Sizeof(0x0, {0x8c7218, 0xb16440})
        /home/ariels/sdk/go1.22.3/src/go/types/sizes.go:228 +0x30f
go/types.(*Config).sizeof(...)
        /home/ariels/sdk/go1.22.3/src/go/types/sizes.go:333
go/types.representableConst.func1({0x8c7218?, 0xb16440?})
        /home/ariels/sdk/go1.22.3/src/go/types/const.go:76 +0x9e
go/types.representableConst({0x8c9180, 0xb098a0}, 0xc0003d1c00, 0xb16440, 0xc000040078)
        /home/ariels/sdk/go1.22.3/src/go/types/const.go:92 +0x192
go/types.(*Checker).representation(0xc0003d1c00, 0xc0003e5240, 0xb16440)
        /home/ariels/sdk/go1.22.3/src/go/types/const.go:256 +0x65
go/types.(*Checker).implicitTypeAndValue(0xc0003d1c00, 0xc0003e5240, {0x8c7218, 0xb16440})
        /home/ariels/sdk/go1.22.3/src/go/types/expr.go:375 +0x2d7
go/types.(*Checker).convertUntyped(0xc0003d1c00, 0xc0003e5240, {0x8c7218, 0xb16440})
        /home/ariels/sdk/go1.22.3/src/go/types/const.go:289 +0x3f
go/types.(*Checker).matchTypes(0xc0003d1c00, 0xc0003e5200, 0xc0003e5240)
        /home/ariels/sdk/go1.22.3/src/go/types/expr.go:926 +0x79
go/types.(*Checker).binary(0xc0003d1c00, 0xc0003e5200, {0x8c8648, 0xc000111200}, {0x8c8408, 0xc00038b8c0}, {0x8c8c78, 0xc00038b8e0}, 0x28, 0x133)
        /home/ariels/sdk/go1.22.3/src/go/types/expr.go:800 +0x166
go/types.(*Checker).exprInternal(0xc0003d1c00, 0x0, 0xc0003e5200, {0x8c8648, 0xc000111200}, {0x0, 0x0})
        /home/ariels/sdk/go1.22.3/src/go/types/expr.go:1416 +0x206
go/types.(*Checker).rawExpr(0xc0003d1c00, 0x0, 0xc0003e5200, {0x8c8648?, 0xc000111200?}, {0x0?, 0x0?}, 0x0)
        /home/ariels/sdk/go1.22.3/src/go/types/expr.go:979 +0x19e
go/types.(*Checker).expr(0xc0003d1c00, 0x8c7900?, 0xc0003e5200, {0x8c8648?, 0xc000111200?})
        /home/ariels/sdk/go1.22.3/src/go/types/expr.go:1513 +0x30
go/types.(*Checker).stmt(0xc0003d1c00, 0x0, {0x8c8ac8, 0xc0003e44c0})
        /home/ariels/sdk/go1.22.3/src/go/types/stmt.go:570 +0x11f2
go/types.(*Checker).stmtList(0xc0003d1c00, 0x0, {0xc00038ba40?, 0x0?, 0x0?})
        /home/ariels/sdk/go1.22.3/src/go/types/stmt.go:121 +0x85
go/types.(*Checker).funcBody(0xc0003d1c00, 0x8c7218?, {0xc0003bb870?, 0xb16620?}, 0xc0003e4f40, 0xc000111290, {0x0?, 0x0?})
        /home/ariels/sdk/go1.22.3/src/go/types/stmt.go:41 +0x331
go/types.(*Checker).funcDecl.func1()
        /home/ariels/sdk/go1.22.3/src/go/types/decl.go:852 +0x3a
go/types.(*Checker).processDelayed(0xc0003d1c00, 0x0)
        /home/ariels/sdk/go1.22.3/src/go/types/check.go:467 +0x162
go/types.(*Checker).checkFiles(0xc0003d1c00, {0xc000128148, 0x1, 0x1})
        /home/ariels/sdk/go1.22.3/src/go/types/check.go:411 +0x1cc
go/types.(*Checker).Files(...)
        /home/ariels/sdk/go1.22.3/src/go/types/check.go:372
golang.org/x/tools/go/packages.(*loader).loadPackage(0xc0001a8000, 0xc00038b5a0)
        /home/ariels/go/pkg/mod/golang.org/x/tools@v0.1.10/go/packages/packages.go:966 +0x76f
golang.org/x/tools/go/packages.(*loader).loadRecursive.func1()
        /home/ariels/go/pkg/mod/golang.org/x/tools@v0.1.10/go/packages/packages.go:803 +0x1a9
sync.(*Once).doSlow(0x0?, 0x0?)
        /home/ariels/sdk/go1.22.3/src/sync/once.go:74 +0xc2
sync.(*Once).Do(...)
        /home/ariels/sdk/go1.22.3/src/sync/once.go:65
golang.org/x/tools/go/packages.(*loader).loadRecursive(0x0?, 0x0?)
        /home/ariels/go/pkg/mod/golang.org/x/tools@v0.1.10/go/packages/packages.go:791 +0x4a
golang.org/x/tools/go/packages.(*loader).loadRecursive.func1.1(0x0?)
        /home/ariels/go/pkg/mod/golang.org/x/tools@v0.1.10/go/packages/packages.go:798 +0x26
created by golang.org/x/tools/go/packages.(*loader).loadRecursive.func1 in goroutine 32
        /home/ariels/go/pkg/mod/golang.org/x/tools@v0.1.10/go/packages/packages.go:797 +0x94
exit status 2

Apologies for length; I believe this level of detail is required to explain.

arielshaqed commented 2 weeks ago

Possibly the version of gopkg.in/check.v1 needs to match the Go toolchain. Applying this patch and building makes it pass:

diff --git a/go.mod b/go.mod
index a7ee4ab..36ee2ac 100644
--- a/go.mod
+++ b/go.mod
@@ -17,11 +17,12 @@ require (
    github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751 // indirect
    github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137 // indirect
    github.com/davecgh/go-spew v1.1.1 // indirect
-   github.com/kr/pretty v0.1.0 // indirect
+   github.com/kr/pretty v0.2.1 // indirect
+   github.com/kr/text v0.1.0 // indirect
    github.com/pmezard/go-difflib v1.0.0 // indirect
    golang.org/x/mod v0.15.0 // indirect
    golang.org/x/net v0.21.0 // indirect
    golang.org/x/text v0.14.0 // indirect
-   gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 // indirect
+   gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect
    gopkg.in/yaml.v2 v2.4.0 // indirect
 )
diff --git a/go.sum b/go.sum
index 5005274..8cf9bed 100644
--- a/go.sum
+++ b/go.sum
@@ -20,6 +20,8 @@ github.com/dustin/go-humanize v1.0.0 h1:VSnTsYCnlFHaM2/igO1h6X3HA71jcobQuxemgkq4
 github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
 github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
 github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
+github.com/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI=
+github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
 github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
 github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
 github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
@@ -75,6 +77,8 @@ golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8T
 gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
 gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
 gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
+gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
+gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
 gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
 gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
 gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
arielshaqed commented 2 weeks ago

I can use:

So I am closing this: while it forces tying the Go compiler version to go-mockgen, I do understand why the structure of Go releases makes this hard to fix here.

THANKS!