Go 1.23: Mock generation fails with alias types
Description
In the latest version of go, a change was made to the generation of Alias types. From the release notes:
By default, go/types now produces Alias type nodes for type aliases. This behavior can be controlled by the GODEBUG gotypesalias flag. Its default has changed from 0 in Go 1.22 to 1 in Go 1.23.
This means that the latest version of Mockery fails to generate mocks which include alias types in the interface.
Mockery Version
Latest at time of writing (v2.44.1)
Go Version
Latest at time of writing (v1.23.0)
Installation Method
- [ ] Binary Distribution
- [ ] Docker
- [ ] brew
- [x] go install
- [ ] Other: [specify]
Steps to Reproduce
- Write an interface that contains an alias type in a function signature
- Try to generate mocks on it
- See panic
Minimum-reproducible code:
package mypackage
import (
"os"
)
// Where os.DirEntry is an alias for the fs.DirEntry type
type MyInterface interface {
GetFiles() []os.DirEntry
}
.mockery/yml:
[...]/mypackage:
config:
inpackage: true
dir: "{{.InterfaceDir}}"
interfaces:
MyInterface:
Expected Behavior
Mocks to generate
Actual Behavior
This panic + stacktrace:
13 Aug 24 14:53 MDT INF generating mocks for interface dry-run=false interface=MyInterface qualified-name=github.com/[...]/mypackage version=v2.44.1
panic: un-namable type: &types.Alias{obj:(*types.TypeName)(0x14001677400), orig:(*types.Alias)(0x14001747400), tparams:(*types.TypeParamList)(nil), targs:(*types.TypeList)(nil), fromRHS:(*types.Named)(0x14001678070), actual:(*types.Named)(0x14001678070)} (*types.Alias)
goroutine 1 [running]:
github.com/vektra/mockery/v2/pkg.(*Generator).renderType(0x14000c46100?, {0x100fdf888?, 0x140035887e0?}, {0x100fddb40?, 0x14001747400?})
[$GOPATH]/go/pkg/mod/github.com/vektra/mockery/[email protected]/pkg/generator.go:627 +0x890
github.com/vektra/mockery/v2/pkg.(*Generator).renderType(0x14000c46100, {0x100fdf888, 0x140035887e0}, {0x100fdca38?, 0x14001760b00})
[$GOPATH]/go/pkg/mod/github.com/vektra/mockery/[email protected]/pkg/generator.go:542 +0x64c
github.com/vektra/mockery/v2/pkg.(*Generator).addImportsFromTuple(0x14000c46100, {0x100fdf888, 0x140035887e0}, 0x1400176acf0)
[$GOPATH]/go/pkg/mod/github.com/vektra/mockery/[email protected]/pkg/generator.go:152 +0x54
github.com/vektra/mockery/v2/pkg.(*Generator).populateImports(0x14000c46100, {0x100fdf888, 0x140035887e0})
[$GOPATH]/go/pkg/mod/github.com/vektra/mockery/[email protected]/pkg/generator.go:142 +0x134
github.com/vektra/mockery/v2/pkg.(*Generator).GeneratePrologue(0x14000c46100, {0x100fdf888, 0x140035887e0}, {0x14000800fc0, 0x57})
[$GOPATH]/go/pkg/mod/github.com/vektra/mockery/[email protected]/pkg/generator.go:420 +0x30
github.com/vektra/mockery/v2/pkg.(*Generator).GenerateAll(0x14000c46100, {0x100fdf888, 0x140035887e0})
[$GOPATH]/go/pkg/mod/github.com/vektra/mockery/[email protected]/pkg/generator.go:116 +0xfc
github.com/vektra/mockery/v2/pkg.(*Outputter).Generate(0x140138d1c08, {0x100fdf888, 0x140035887b0}, 0x1400aec3650)
[$GOPATH]/go/pkg/mod/github.com/vektra/mockery/[email protected]/pkg/outputter.go:352 +0x554
github.com/vektra/mockery/v2/cmd.(*RootApp).Run(0x140000f12c0)
[$GOPATH]/go/pkg/mod/github.com/vektra/mockery/[email protected]/cmd/mockery.go:268 +0x1728
github.com/vektra/mockery/v2/cmd.NewRootCmd.func1(0x140001b6a00?, {0x100ddd23a?, 0x4?, 0x100ddd23e?})
[$GOPATH]/go/pkg/mod/github.com/vektra/mockery/[email protected]/cmd/mockery.go:46 +0x48
github.com/spf13/cobra.(*Command).execute(0x140000fe608, {0x140000a8010, 0x0, 0x0})
[$GOPATH]/go/pkg/mod/github.com/spf13/[email protected]/command.go:987 +0x81c
github.com/spf13/cobra.(*Command).ExecuteC(0x140000fe608)
[$GOPATH]/go/pkg/mod/github.com/spf13/[email protected]/command.go:1115 +0x344
github.com/spf13/cobra.(*Command).Execute(...)
[$GOPATH]/go/pkg/mod/github.com/spf13/[email protected]/command.go:1039
github.com/vektra/mockery/v2/cmd.Execute()
[$GOPATH]/go/pkg/mod/github.com/vektra/mockery/[email protected]/cmd/mockery.go:105 +0x20
main.main()
[$GOPATH]/go/pkg/mod/github.com/vektra/mockery/[email protected]/main.go:8 +0x1c
Temporary Workarounds
- Option 1: Use the underlying type of the aliased type (so in the above example, using
fs.DirEntryworks fine - Option 2: Set the
GODEBUGgotypesaliasflag back to 0- Helpful clarification to Option 2 from @yurishkuro:
Clarification for workaround (2) above:
generate the mockery binary as usual but run it with GODEBUG=gotypesalias=0 $(MOCKERY)
Clarification for workaround (2) above:
- generate the
mockerybinary as usual - but run it with
GODEBUG=gotypesalias=0 $(MOCKERY)
I believe gotypealias being enabled would help solve some outstanding problems, like with mockery incorrectly following a type alias back to its underlying type (which is the reason replace-types exists).
I would be of the opinion that we just fix mockery to support this and check to see how it behaves now with aliases, particularly in the test cases that exercise replace-types. Like, can we just completely disregard replace-types now? That would be cool.
This is a high priority bug to fix. I'll solicit takers for this one. If not, maybe I can get to it in a few weeks.
I believe gotypealias being enabled would help solve some outstanding problems, like with mockery incorrectly following a type alias back to its underlying type (which is the reason replace-types exists).
I think this was made exactly to fix the replace-types problem, with this, it would be possible to remove replace-types (once Go 1.23 is the last supported version.
I'll see if I can find some time to look at it this week.
Another quick temporary fix is adding this to a Go 1.23 go.mod file:
godebug (
gotypesalias=0
)
Created fix PR.
Thanks for the fix! Confirmed it's working https://github.com/jaegertracing/jaeger/pull/6025 without gotypesalias=0