What version of Go are you using (go version)?
$ go version
go version go1.18.3 darwin/arm64
Does this issue reproduce with the latest release?
Yes, including tip as of today
What operating system and processor architecture are you using (go env)?
go env Output
$ go env
GO111MODULE="on"
GOARCH="arm64"
GOBIN=""
GOCACHE="/Users/sethvargo/Library/Caches/go-build"
GOENV="/Users/sethvargo/Library/Application Support/go/env"
GOEXE=""
GOEXPERIMENT=""
GOFLAGS=""
GOHOSTARCH="arm64"
GOHOSTOS="darwin"
GOINSECURE=""
GOMODCACHE="/Users/sethvargo/Development/go/pkg/mod"
GONOPROXY=""
GONOSUMDB=""
GOOS="darwin"
GOPATH="/Users/sethvargo/Development/go"
GOPRIVATE=""
GOPROXY="https://proxy.golang.org,direct"
GOROOT="/opt/homebrew/Cellar/go/1.18.3/libexec"
GOSUMDB="sum.golang.org"
GOTMPDIR=""
GOTOOLDIR="/opt/homebrew/Cellar/go/1.18.3/libexec/pkg/tool/darwin_arm64"
GOVCS=""
GOVERSION="go1.18.3"
GCCGO="gccgo"
AR="ar"
CC="clang"
CXX="clang++"
CGO_ENABLED="1"
GOMOD="/dev/null"
GOWORK=""
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/cp/qb9vbbkx4w36f6dclng481br00gy5b/T/go-build4094322222=/tmp/go-build -gno-record-gcc-switches -fno-common"
What did you do?
I suspect the root cause of my actual issue is #41176, but it would be great if @ianlancetaylor can confirm for me 😄.
Playground link for the code: https://go.dev/play/p/RqzqQxNapkw. Note this code does not compile.
Code:
package main
// Cache is a generic cache implementation.
type Cache[K comparable, V any] interface {
Get(K)
Set(K, V)
}
// LRU is a cache.
type LRU[K comparable, V any] struct{}
func (l *LRU[K, V]) Get(key K) {}
func (l *LRU[K, V]) Set(key K, val V) {}
// WithLocking1 returns a cache that wraps operations in a mutex.
func WithLocking1[K comparable, V any, C Cache[K, V]](cache C) {}
// WithLocking2 returns a cache that wraps operations in a mutex.
func WithLocking2[K comparable, V any](cache Cache[K, V]) {}
// WithLocking3 returns a cache that wraps operations in a mutex.
func WithLocking3[K comparable](cache Cache[K, any]) {}
func main() {
var lru LRU[string, int]
WithLocking1[string, int](&lru) // ok
WithLocking1[string](&lru) // nok: cannot infer V
WithLocking1(&lru) // nok: cannot infer K
WithLocking2[string, int](&lru) // ok
WithLocking2[string](&lru) // nok: does not match Cache[string, V]
WithLocking2(&lru) // nok: cannot infer K and V
WithLocking3[string](&lru) // nok: does not implement Cache[string, any] (wrong type for method Set)
// have Set(key string, val int)
// want Set(string, any)
WithLocking3(&lru) // nok: cannot infer K
}
What did you expect to see?
As shown in the comments, the error messages are all subtly different depending on the type declarations on the function. I would expect the same error messages here.
What did you see instead?
Different error messages.
Aside
As an aside, it's unclear to me what the "correct" authorship is here. I really appreciate Go's "do one thing", but there seems to be multiple ways to define generics, all of which are subtly different with unknown consequences.
What version of Go are you using (
go version)?Does this issue reproduce with the latest release?
Yes, including tip as of today
What operating system and processor architecture are you using (
go env)?go envOutputWhat did you do?
I suspect the root cause of my actual issue is #41176, but it would be great if @ianlancetaylor can confirm for me 😄.
Playground link for the code: https://go.dev/play/p/RqzqQxNapkw. Note this code does not compile.
Code:
What did you expect to see?
As shown in the comments, the error messages are all subtly different depending on the type declarations on the function. I would expect the same error messages here.
What did you see instead?
Different error messages.
Aside
As an aside, it's unclear to me what the "correct" authorship is here. I really appreciate Go's "do one thing", but there seems to be multiple ways to define generics, all of which are subtly different with unknown consequences.