Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

go/types, cmd/compile/internal/types2: type parameter inference fails for constraints that succeed individually #66751

Closed
firelizzard18 opened this issue Apr 9, 2024 · 4 comments
Assignees
Labels
compiler/runtime Issues related to the Go compiler and/or runtime. NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. TypeInference Issue is related to generic type inference
Milestone

Comments

@firelizzard18
Copy link
Contributor

Go version

go version go1.22.1 linux/amd64

Output of go env in your module/workspace:

GO111MODULE=''
GOARCH='amd64'
GOBIN=''
GOCACHE='/home/firelizzard/.cache/go-build'
GOENV='/home/firelizzard/.config/go/env'
GOEXE=''
GOEXPERIMENT=''
GOFLAGS=''
GOHOSTARCH='amd64'
GOHOSTOS='linux'
GOINSECURE=''
GOMODCACHE='/home/firelizzard/go/pkg/mod'
GONOPROXY=''
GONOSUMDB=''
GOOS='linux'
GOPATH='/home/firelizzard/go'
GOPRIVATE=''
GOPROXY='https://proxy.golang.org,direct'
GOROOT='/usr/lib/go'
GOSUMDB='sum.golang.org'
GOTMPDIR=''
GOTOOLCHAIN='local'
GOTOOLDIR='/usr/lib/go/pkg/tool/linux_amd64'
GOVCS=''
GOVERSION='go1.22.1'
GCCGO='/usr/bin/gccgo'
GOAMD64='v1'
AR='ar'
CC='x86_64-pc-linux-gnu-gcc'
CXX='x86_64-pc-linux-gnu-g++'
CGO_ENABLED='1'
GOMOD='/home/firelizzard/src/yaegi/go-script/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-build3476193043=/tmp/go-build -gno-record-gcc-switches'

What did you do?

https://go.dev/play/p/fVSkvTEgYx_1

package main

type ptrTo[A any] interface{ ~*A }
type hasFoo[A any] interface{ foo(A) }
type both[A, B any] interface {
	ptrTo[A]
	hasFoo[B]
}

type fooer[A any] struct{}

func (f *fooer[A]) foo(A) {}

func withPtr[A ptrTo[B], B any]()       {}
func withFoo[A hasFoo[B], B any]()      {}
func withBoth[A both[B, C], B, C any]() {}

func main() {
	withPtr[*fooer[int]]()  // Ok
	withFoo[*fooer[int]]()  // Ok
	withBoth[*fooer[int]]() // Error: cannot infer C
}

What did you see happen?

Inference succeeds on all three calls.

What did you expect to see?

Inference succeeds on the first two but fails on the third. If inference of B for withPtr or withFoo failed, it would make sense. But inference succeeds on both of those so it's surprising and confusing that it fails for withBoth.

@findleyr findleyr changed the title Type parameter inference fails for constraints that succeed individually go/types, types2: type parameter inference fails for constraints that succeed individually Apr 9, 2024
@findleyr
Copy link
Member

findleyr commented Apr 9, 2024

CC @griesemer

@cagedmantis cagedmantis added the NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. label Apr 10, 2024
@cagedmantis cagedmantis added this to the Backlog milestone Apr 10, 2024
@ianlancetaylor ianlancetaylor added the TypeInference Issue is related to generic type inference label Apr 10, 2024
@Garciat
Copy link

Garciat commented May 4, 2024

I ran into an inference issue that is very similar to OP's issue:

type X struct {}
func (x X) M() int { return 42 }

func CallM1[T interface{M() R}, R any](t T) R {
	return t.M()
}

func CallM2[T interface{X; M() R}, R any](t T) R {
	return t.M()
}

func main() {
	CallM1(X{}) // OK
	CallM2(X{}) // cannot infer R
}

I wasn't expecting CallM2 to fail inference on R because of the added T=X constraint.

@dmitshur dmitshur changed the title go/types, types2: type parameter inference fails for constraints that succeed individually go/types, cmd/compile/internal/types2: type parameter inference fails for constraints that succeed individually May 17, 2024
@gopherbot gopherbot added the compiler/runtime Issues related to the Go compiler and/or runtime. label May 17, 2024
@griesemer griesemer self-assigned this Sep 18, 2024
@griesemer griesemer modified the milestones: Backlog, Go1.24 Sep 18, 2024
@griesemer
Copy link
Contributor

griesemer commented Oct 3, 2024

Simplified reproducer for original example:

package p

type S struct{}

func (*S) m(int) {}

func f[A interface {
	~*B
	m(C)
}, B, C any]() {
}

var _ = f[*S] // error: cannot infer C

@gopherbot
Copy link
Contributor

Change https://go.dev/cl/617896 mentions this issue: go/types, types2: always try inference over methods when possible

@griesemer griesemer moved this from Todo to In Progress in Go Compiler / Runtime Oct 3, 2024
@github-project-automation github-project-automation bot moved this from In Progress to Done in Go Compiler / Runtime Oct 3, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
compiler/runtime Issues related to the Go compiler and/or runtime. NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. TypeInference Issue is related to generic type inference
Projects
Development

No branches or pull requests

7 participants