Skip to content

cmd/compile: ICE: converting shape type to interface #47775

@andig

Description

@andig

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    FrozenDueToAgeNeedsInvestigationSomeone must examine and confirm this is a valid issue and not a duplicate of an existing one.

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions