What version of Go are you using (go version
)?
$ go version go version go1.20.6 linux/amd64
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="amd64" GOBIN="" GOCACHE="/home/sz/.cache/go-build" GOENV="/home/sz/.config/go/env" GOEXE="" GOEXPERIMENT="" GOFLAGS="" GOHOSTARCH="amd64" GOHOSTOS="linux" GOINSECURE="" GOMODCACHE="/home/sz/go/pkg/mod" GONOPROXY="" GONOSUMDB="" GOOS="linux" GOPATH="/home/sz/go" GOPRIVATE="" GOPROXY="https://proxy.golang.org,direct" GOROOT="/usr/lib/go" GOSUMDB="sum.golang.org" GOTMPDIR="" GOTOOLDIR="/usr/lib/go/pkg/tool/linux_amd64" GOVCS="" GOVERSION="go1.20.6" GCCGO="gccgo" GOAMD64="v1" AR="ar" CC="gcc" CXX="g++" CGO_ENABLED="1" GOMOD="/dev/null" 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 -fdebug-prefix-map=/tmp/go-build2006396805=/tmp/go-build -gno-record-gcc-switches"
What did you do?
Consider the following code: https://go.dev/play/p/6MPHjq0B5km
It invokes reflect.StructOf
method with two embedded fields, a struct and an interface. The resulting type has three methods, according to reflect.Type.NumMethod()
function. The method list isn't lexicographically sorted and contains duplicates.
reflect.StructOf
has its limitations documented in godoc, but it doesn't explain the observed behavior.
What did you expect to see?
Output:
Method 0: M1
Method 1: M2
What did you see instead?
Output:
Method 0: M1
Method 1: M2
Method 2: M1
Comment From: seankhliao
looks like a known limitation: https://cs.opensource.google/go/go/+/refs/tags/go1.20.6:src/reflect/type.go;l=2685
Comment From: g7r
@seankhliao, kind of yes. reflect.StructOf
is really limited when it comes to embedding fields with methods. Nonetheless, reflect.StructOf
allows me to create types that break contracts.
Comment From: heschi
cc @golang/runtime
Comment From: cherrymui
If we create such a struct in Go, it only has the M2 method: https://go.dev/play/p/wpUZ9HSrQQC . The ambiguous M1 method is not included in the method set of the outer struct. I think the reflect package should do that as well. I.e. the expected output would be just
Method 0: M2
Comment From: cherrymui
As we currently don't support embedding multiple non-interface fields, the duplicates must be from interface fields. I'm curious about your use case. As far as I can tell, calling embedded interface method doesn't seem to work.