-
Notifications
You must be signed in to change notification settings - Fork 18.4k
Description
Go version
go version go1.21.6 linux/amd64
Output of go env
in your module/workspace:
GO111MODULE=''
GOARCH='amd64'
GOBIN=''
GOCACHE='/home/jcarmichael/.cache/go-build'
GOENV='/home/jcarmichael/.config/go/env'
GOEXE=''
GOEXPERIMENT=''
GOFLAGS=''
GOHOSTARCH='amd64'
GOHOSTOS='linux'
GOINSECURE=''
GOMODCACHE='/home/jcarmichael/go/pkg/mod'
GONOPROXY=''
GONOSUMDB=''
GOOS='linux'
GOPATH='/home/jcarmichael/go'
GOPRIVATE=''
GOPROXY='https://proxy.golang.org,direct'
GOROOT='/usr/local/go'
GOSUMDB='sum.golang.org'
GOTMPDIR=''
GOTOOLCHAIN='auto'
GOTOOLDIR='/usr/local/go/pkg/tool/linux_amd64'
GOVCS=''
GOVERSION='go1.21.6'
GCCGO='gccgo'
GOAMD64='v1'
AR='ar'
CC='gcc'
CXX='g++'
CGO_ENABLED='1'
GOMOD='/mnt/c/Users/Lenovo/Documents/Programming/util/go.mod'
GOWORK=''
CGO_CFLAGS='-O2 -g'
CGO_CPPFLAGS=''
CGO_CXXFLAGS='-O2 -g'
CGO_FFLAGS='-O2 -g'
CGO_LDFLAGS='-O2 -g'
PKG_CONFIG='pkg-config'
GOGCCFLAGS='-fPIC -m64 -pthread -Wl,--no-gc-sections -fmessage-length=0 -ffile-prefix-map=/tmp/go-build1952531264=/tmp/go-build -gno-record-gcc-switches'
What did you do?
I wrote the code shown below and in the following playground link: https://go.dev/play/p/d8XxoEklO6D
package main
import "fmt"
type Comparisons[OI any, OIR any, K any, V any] interface {
Difference(other OIR) OI
}
// An interface that only allows read operations on a vector.
type ReadVector[V any] interface {
Comparisons[Vector[V], ReadVector[V], int, V]
}
// An interface that only allows write operations on a vector.
type WriteVector[V any] interface {
otherMethods()
}
// An interface that represents a vector with no restrictions on reading or
// writing.
type Vector[V any] interface {
ReadVector[V]
WriteVector[V]
}
type VectorImpl[T any] struct{}
func (v *VectorImpl[T]) otherMethods() {}
func (v *VectorImpl[T]) Difference(other ReadVector[T]) Vector[T] {
rv := VectorImpl[T]{}
return &rv
}
func main() {
v := VectorImpl[int]{}
v2 := VectorImpl[int]{}
var v2Interface Vector[int] = &v2
fmt.Println(v.Difference(v2Interface))
}
What did you see happen?
The compiler produced the following error:
./prog.go:38:27: cannot use v2Interface (type ReadVector[int]) as type ReadVector[go.shape.int] in argument to (*VectorImpl[go.shape.int]).Difference:
ReadVector[int] does not implement ReadVector[go.shape.int] (wrong type for Difference method)
have Difference(ReadVector[int]) Vector[int]
want Difference(ReadVector[go.shape.int]) go.shape.interface { main.otherMethods() }
Go build failed.
What did you expect to see?
I expected the program to compile and print the empty Vector[int] structure value.
Of note is if you change the second generic parameter on line 11 to Vector[int]
as well as the corresponding type on the Difference method on line then the compiler successfully finishes, and the program works as intended.
I am not sure if this is relevant, but the compiler error does not list the difference method on the Vector return type of the Difference method in the error it produces. It prints this:
want Difference(ReadVector[go.shape.int]) go.shape.interface { main.otherMethods() }
when I think it should print something like this (formatting added for readability):
want Difference(ReadVector[go.shape.int]) go.shape.interface {
main.otherMethods()
main.Difference(
ReadVector[go.shape.int]
) go.shape.interface{ main.otherMethods(); ReadVector[go.shape.int]}
}
I am guessing on the syntax of the output shown above, I am just saying what would make sense to see based on what I am already seeing, I am sure the correct output is different.
I am not sure what the rules are regarding recursive interface type definitions as shown in the example, and the issue is only compounded by the added generics.