Description
Go version
go version go1.25-20250711-RC00 REDACTED +6ebb5f56d9 X:fieldtrack,boringcrypto linux/amd64
Output of go env
in your module/workspace:
AR='ar'
CC='gcc'
CGO_CFLAGS='-O2 -g'
CGO_CPPFLAGS=''
CGO_CXXFLAGS='-O2 -g'
CGO_ENABLED='0'
CGO_FFLAGS='-O2 -g'
CGO_LDFLAGS='-O2 -g'
CXX='g++'
GCCGO='gccgo'
GO111MODULE=''
GOAMD64='v3'
GOARCH='amd64'
GOAUTH='netrc'
GOBIN=''
GOCACHE='REDACTED'
GOCACHEPROG=''
GODEBUG=''
GOENV='REDACTED'
GOEXE=''
GOEXPERIMENT='fieldtrack,boringcrypto'
GOFIPS140='off'
GOFLAGS=''
GOGCCFLAGS='-fPIC -m64 -Wl,--no-gc-sections -fmessage-length=0 -ffile-prefix-map=/tmp/go-build889680920=/tmp/go-build -gno-record-gcc-switches'
GOHOSTARCH='amd64'
GOHOSTOS='linux'
GOINSECURE=''
GOMOD='/dev/null'
GOMODCACHE='REDACTED'
GONOPROXY=''
GONOSUMDB=''
GOOS='linux'
GOPATH='REDACTED'
GOPRIVATE=''
GOPROXY=''
GOROOT='REDACTED'
GOSUMDB=''
GOTELEMETRY='local'
GOTELEMETRYDIR='REDACTED'
GOTMPDIR=''
GOTOOLCHAIN=''
GOTOOLDIR='REDACTED'
GOVCS=''
GOVERSION='go1.25-20250711-RC00 REDACTED +6ebb5f56d9 X:fieldtrack,boringcrypto'
GOWORK=''
PKG_CONFIG='pkg-config'
What did you do?
We use //go:nointerface within a project, and we encountered the following issue:
package missing_method_repro_test
import "testing"
type Fooer interface {
Foo() string
}
type FooImpl struct{}
//go:nointerface
func (FooImpl) Foo() string { return "foo" }
func toInterface[T Fooer](fooer T) Fooer {
return fooer
}
func TestFooer(t *testing.T) {
var iface Fooer = toInterface(FooImpl{})
if iface == nil {
t.Errorf("iface = nil, want non-nil")
}
if iface.Foo == nil {
t.Errorf("iface.Foo = nil, want non-nil")
}
iface.Foo() // panics with nil pointer dereference
}
What did you see happen?
So even though a method is marked as nointerface, it's valid to pass this to function with the interface as a type constraint (and calling the method actually works). It looks like it's also valid to pass this value to an interface (because it passes assignability rules in the generic). And while the interface method even returns non-nil, calling the mehtod results in a nil pointer dereference. Please note that the following workaround works:
type dispatch func() string
func (d dispatch) Foo() string {
return d()
}
func toInterface[T Fooer](fooer T) Fooer {
return dispatch(fooer.Foo)
}
What did you expect to see?
Since the manual dispatch approach works, I guess the compiler could just figure out how to do this kind of dispatching itself.
Metadata
Metadata
Assignees
Labels
Type
Projects
Status