What version of Go are you using (go version)?
$ go version
go version devel go1.18-8b471db71b Wed Aug 18 08:26:44 2021 +0000 darwin/arm64
Does this issue reproduce with the latest release?
yes
What operating system and processor architecture are you using (go env)?
go env Output
$ go env
GO111MODULE=""
GOARCH="arm64"
GOBIN=""
GOCACHE="/Users/andig/Library/Caches/go-build"
GOENV="/Users/andig/Library/Application Support/go/env"
GOEXE=""
GOEXPERIMENT=""
GOFLAGS=""
GOHOSTARCH="arm64"
GOHOSTOS="darwin"
GOINSECURE=""
GOMODCACHE="/Users/andig/go/pkg/mod"
GONOPROXY=""
GONOSUMDB=""
GOOS="darwin"
GOPATH="/Users/andig/go"
GOPRIVATE=""
GOPROXY="https://proxy.golang.org,direct"
GOROOT="/Users/andig/sdk/gotip"
GOSUMDB="sum.golang.org"
GOTMPDIR=""
GOTOOLDIR="/Users/andig/sdk/gotip/pkg/tool/darwin_arm64"
GOVCS=""
GOVERSION="devel go1.18-8b471db71b Wed Aug 18 08:26:44 2021 +0000"
GCCGO="gccgo"
AR="ar"
CC="clang"
CXX="clang++"
CGO_ENABLED="1"
GOMOD="/Users/andig/htdocs/evcc/go.mod"
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
PKG_CONFIG="pkg-config"
GOGCCFLAGS="-fPIC -arch arm64 -pthread -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -fdebug-prefix-map=/var/folders/sv/rs_453y57xj86xsbz3kw1mbc0000gn/T/go-build98478264=/tmp/go-build -gno-record-gcc-switches -fno-common"
GOROOT/bin/go version: go version devel go1.18-8b471db71b Wed Aug 18 08:26:44 2021 +0000 darwin/arm64
GOROOT/bin/go tool compile -V: compile version devel go1.18-8b471db71b Wed Aug 18 08:26:44 2021 +0000
uname -v: Darwin Kernel Version 20.6.0: Wed Jun 23 00:26:27 PDT 2021; root:xnu-7195.141.2~5/RELEASE_ARM64_T8101
ProductName: macOS
ProductVersion: 11.5
BuildVersion: 20G71
lldb --version: lldb-1205.0.28.2
Apple Swift version 5.4.2 (swiftlang-1205.0.28.2 clang-1205.0.19.57)
What did you do?
Accessing generic function from different module:
// Cached wraps a getter with a cache
type Cached[T any] struct {
mux sync.Mutex
clock clock.Clock
updated time.Time
cache time.Duration
getter func()(T,error) # <--
val T # <--
err error
}
// NewCached wraps a getter with a cache
func NewCached[T any](getter func()(T,error), cache time.Duration) *Cached[T] {
c := &Cached[T]{
clock: clock.New(),
getter: getter,
cache: cache,
}
return c
}
func (c *Cached[T]) mustUpdate() bool {
return c.clock.Since(c.updated) > c.cache || errors.Is(c.err, api.ErrMustRetry)
}
// Get returns cached value, refreshing as necessary
func (c *Cached[T]) Get()(T, error) {
c.mux.Lock()
defer c.mux.Unlock()
if c.mustUpdate() {
c.val, c.err = c.getter()
c.updated = c.clock.Now()
}
return c.val, c.err
}
And use the Get method as:
var statusG func() (Status, error)
statusG = provider.NewCached[Status](func() (Status, error) {
return api.Status(vin)
}, cache).Get,
What did you expect to see?
no compile error
What did you see instead?
internal compiler error: converting shape type to interface
BAD FUNCTION
. DCLFUNC tc(1) Iota:-1 ABI:ABIInternal FUNC-func(uintptr, func() (.shape.struct { Data struct { BatteryStatus "".BatteryStatus; ChargingStatus "".ChargingStatus; ChargingSettings "".ChargingSettings; PlugStatus "".PlugStatus; RangeStatus "".RangeStatus; ClimatisationSettings "".ClimatisationSettings; ClimatisationStatus "".ClimatisationStatus }; Error map[string]"".Error }, error), time.Duration) *provider.Cached[.shape.struct { Data struct { BatteryStatus "".BatteryStatus; ChargingStatus "".ChargingStatus; ChargingSettings "".ChargingSettings; PlugStatus "".PlugStatus; RangeStatus "".RangeStatus; ClimatisationSettings "".ClimatisationSettings; ClimatisationStatus "".ClimatisationStatus }; Error map[string]"".Error }] # cache.go:37:6
. DCLFUNC-Dcl
. . NAME-provider..dict tc(1) Class:PPARAM Offset:0 OnStack uintptr # cache.go:37:6
. . NAME-provider.getter tc(1) Class:PPARAM Offset:0 OnStack FUNC-func() (.shape.struct { Data struct { BatteryStatus "".BatteryStatus; ChargingStatus "".ChargingStatus; ChargingSettings "".ChargingSettings; PlugStatus "".PlugStatus; RangeStatus "".RangeStatus; ClimatisationSettings "".ClimatisationSettings; ClimatisationStatus "".ClimatisationStatus }; Error map[string]"".Error }, error) # cache.go:37:23
. . NAME-provider.cache tc(1) Class:PPARAM Offset:0 OnStack time.Duration # cache.go:37:47
. . NAME-provider.~r0 tc(1) Class:PPARAMOUT Offset:0 OnStack PTR-*provider.Cached[.shape.struct { Data struct { BatteryStatus "".BatteryStatus; ChargingStatus "".ChargingStatus; ChargingSettings "".ChargingSettings; PlugStatus "".PlugStatus; RangeStatus "".RangeStatus; ClimatisationSettings "".ClimatisationSettings; ClimatisationStatus "".ClimatisationStatus }; Error map[string]"".Error }] # cache.go:37:68
. . NAME-provider.c tc(1) Class:PAUTO Offset:0 OnStack Used PTR-*provider.Cached[.shape.struct { Data struct { BatteryStatus "".BatteryStatus; ChargingStatus "".ChargingStatus; ChargingSettings "".ChargingSettings; PlugStatus "".PlugStatus; RangeStatus "".RangeStatus; ClimatisationSettings "".ClimatisationSettings; ClimatisationStatus "".ClimatisationStatus }; Error map[string]"".Error }] # cache.go:38:2
. DCLFUNC-body
. . DCL tc(1) # cache.go:38:2
. . . NAME-provider.c tc(1) Class:PAUTO Offset:0 OnStack Used PTR-*provider.Cached[.shape.struct { Data struct { BatteryStatus "".BatteryStatus; ChargingStatus "".ChargingStatus; ChargingSettings "".ChargingSettings; PlugStatus "".PlugStatus; RangeStatus "".RangeStatus; ClimatisationSettings "".ClimatisationSettings; ClimatisationStatus "".ClimatisationStatus }; Error map[string]"".Error }] # cache.go:38:2
. . AS tc(1) # cache.go:38:2
. . . NAME-provider.c tc(1) Class:PAUTO Offset:0 OnStack Used PTR-*provider.Cached[.shape.struct { Data struct { BatteryStatus "".BatteryStatus; ChargingStatus "".ChargingStatus; ChargingSettings "".ChargingSettings; PlugStatus "".PlugStatus; RangeStatus "".RangeStatus; ClimatisationSettings "".ClimatisationSettings; ClimatisationStatus "".ClimatisationStatus }; Error map[string]"".Error }] # cache.go:38:2
. . AS tc(1) # cache.go:38:4
. . . NAME-provider.c tc(1) Class:PAUTO Offset:0 OnStack Used PTR-*provider.Cached[.shape.struct { Data struct { BatteryStatus "".BatteryStatus; ChargingStatus "".ChargingStatus; ChargingSettings "".ChargingSettings; PlugStatus "".PlugStatus; RangeStatus "".RangeStatus; ClimatisationSettings "".ClimatisationSettings; ClimatisationStatus "".ClimatisationStatus }; Error map[string]"".Error }] # cache.go:38:2
. . . PTRLIT tc(1) PTR-*provider.Cached[.shape.struct { Data struct { BatteryStatus "".BatteryStatus; ChargingStatus "".ChargingStatus; ChargingSettings "".ChargingSettings; PlugStatus "".PlugStatus; RangeStatus "".RangeStatus; ClimatisationSettings "".ClimatisationSettings; ClimatisationStatus "".ClimatisationStatus }; Error map[string]"".Error }] # cache.go:38:7 PTR-*provider.Cached[.shape.struct { Data struct { BatteryStatus "".BatteryStatus; ChargingStatus "".ChargingStatus; ChargingSettings "".ChargingSettings; PlugStatus "".PlugStatus; RangeStatus "".RangeStatus; ClimatisationSettings "".ClimatisationSettings; ClimatisationStatus "".ClimatisationStatus }; Error map[string]"".Error }]
. . . . STRUCTLIT tc(1) provider.Cached[.shape.struct { Data struct { BatteryStatus "".BatteryStatus; ChargingStatus "".ChargingStatus; ChargingSettings "".ChargingSettings; PlugStatus "".PlugStatus; RangeStatus "".RangeStatus; ClimatisationSettings "".ClimatisationSettings; ClimatisationStatus "".ClimatisationStatus }; Error map[string]"".Error }] # cache.go:38:17 provider.Cached[.shape.struct { Data struct { BatteryStatus "".BatteryStatus; ChargingStatus "".ChargingStatus; ChargingSettings "".ChargingSettings; PlugStatus "".PlugStatus; RangeStatus "".RangeStatus; ClimatisationSettings "".ClimatisationSettings; ClimatisationStatus "".ClimatisationStatus }; Error map[string]"".Error }]
. . . . STRUCTLIT-List
. . . . . STRUCTKEY tc(1) # cache.go:39:8 provider.clock
. . . . . . CALLFUNC tc(1) clock.Clock # cache.go:39:20 clock.Clock
. . . . . . . NAME-clock.New tc(1) Class:PFUNC Offset:0 FUNC-func() clock.Clock # clock.go:26:6
. . . . . STRUCTKEY tc(1) # cache.go:40:9 provider.getter
. . . . . . NAME-provider.getter tc(1) Class:PPARAM Offset:0 OnStack FUNC-func() (.shape.struct { Data struct { BatteryStatus "".BatteryStatus; ChargingStatus "".ChargingStatus; ChargingSettings "".ChargingSettings; PlugStatus "".PlugStatus; RangeStatus "".RangeStatus; ClimatisationSettings "".ClimatisationSettings; ClimatisationStatus "".ClimatisationStatus }; Error map[string]"".Error }, error) # cache.go:37:23
. . . . . STRUCTKEY tc(1) # cache.go:41:8 provider.cache
. . . . . . NAME-provider.cache tc(1) Class:PPARAM Offset:0 OnStack time.Duration # cache.go:37:47
. . AS tc(1) # cache.go:44:4
. . . NAME-id._ tc(1) Offset:0 blank
. . . CALLINTER tc(1) error # cache.go:44:19 error
. . . . DOTINTER tc(1) FUNC-method(*struct {}) func(string, interface {}) error # cache.go:44:9 id.Subscribe FUNC-method(*struct {}) func(string, interface {}) error
. . . . . NAME-provider.bus tc(1) Class:PEXTERN Offset:0 EventBus.Bus # cache.go:15:2
. . . CALLINTER-Args
. . . . LITERAL-"reset" tc(1) string # cache.go:44:20
. . . . CONVIFACE tc(1) INTER-interface {} # cache.go:44:28 INTER-interface {}
. . . . . METHVALUE tc(1) FUNC-method(*provider.Cached[.shape.struct { Data struct { BatteryStatus "".BatteryStatus; ChargingStatus "".ChargingStatus; ChargingSettings "".ChargingSettings; PlugStatus "".PlugStatus; RangeStatus "".RangeStatus; ClimatisationSettings "".ClimatisationSettings; ClimatisationStatus "".ClimatisationStatus }; Error map[string]"".Error }]) func() # cache.go:44:28 provider.reset FUNC-method(*provider.Cached[.shape.struct { Data struct { BatteryStatus "".BatteryStatus; ChargingStatus "".ChargingStatus; ChargingSettings "".ChargingSettings; PlugStatus "".PlugStatus; RangeStatus "".RangeStatus; ClimatisationSettings "".ClimatisationSettings; ClimatisationStatus "".ClimatisationStatus }; Error map[string]"".Error }]) func()
. . . . . . NAME-provider.c tc(1) Class:PAUTO Offset:0 OnStack Used PTR-*provider.Cached[.shape.struct { Data struct { BatteryStatus "".BatteryStatus; ChargingStatus "".ChargingStatus; ChargingSettings "".ChargingSettings; PlugStatus "".PlugStatus; RangeStatus "".RangeStatus; ClimatisationSettings "".ClimatisationSettings; ClimatisationStatus "".ClimatisationStatus }; Error map[string]"".Error }] # cache.go:38:2
. . RETURN tc(1) # cache.go:46:2
. . RETURN-Results
. . . NAME-provider.c tc(1) Class:PAUTO Offset:0 OnStack Used PTR-*provider.Cached[.shape.struct { Data struct { BatteryStatus "".BatteryStatus; ChargingStatus "".ChargingStatus; ChargingSettings "".ChargingSettings; PlugStatus "".PlugStatus; RangeStatus "".RangeStatus; ClimatisationSettings "".ClimatisationSettings; ClimatisationStatus "".ClimatisationStatus }; Error map[string]"".Error }] # cache.go:38:2
BAD CONVERSION
. CONVIFACE tc(1) INTER-interface {} # cache.go:44:28 INTER-interface {}
. . METHVALUE tc(1) FUNC-method(*provider.Cached[.shape.struct { Data struct { BatteryStatus "".BatteryStatus; ChargingStatus "".ChargingStatus; ChargingSettings "".ChargingSettings; PlugStatus "".PlugStatus; RangeStatus "".RangeStatus; ClimatisationSettings "".ClimatisationSettings; ClimatisationStatus "".ClimatisationStatus }; Error map[string]"".Error }]) func() # cache.go:44:28 provider.reset FUNC-method(*provider.Cached[.shape.struct { Data struct { BatteryStatus "".BatteryStatus; ChargingStatus "".ChargingStatus; ChargingSettings "".ChargingSettings; PlugStatus "".PlugStatus; RangeStatus "".RangeStatus; ClimatisationSettings "".ClimatisationSettings; ClimatisationStatus "".ClimatisationStatus }; Error map[string]"".Error }]) func()
. . . NAME-provider.c tc(1) Class:PAUTO Offset:0 OnStack Used PTR-*provider.Cached[.shape.struct { Data struct { BatteryStatus "".BatteryStatus; ChargingStatus "".ChargingStatus; ChargingSettings "".ChargingSettings; PlugStatus "".PlugStatus; RangeStatus "".RangeStatus; ClimatisationSettings "".ClimatisationSettings; ClimatisationStatus "".ClimatisationStatus }; Error map[string]"".Error }] # cache.go:38:2
vehicle/id/types.go:22:9: internal compiler error: converting shape type to interface
Reproducer: evcc-io/evcc@326c829. Pretty sure that the problem is when using the generic method as regular function.
FWIW: it compiles with GOEXPERIMENT=unified.
What version of Go are you using (
go version)?Does this issue reproduce with the latest release?
yes
What operating system and processor architecture are you using (
go env)?go envOutputWhat did you do?
Accessing generic function from different module:
And use the
Getmethod as:What did you expect to see?
no compile error
What did you see instead?
Reproducer: evcc-io/evcc@326c829. Pretty sure that the problem is when using the generic method as regular function.
FWIW: it compiles with GOEXPERIMENT=unified.