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

spec: type inference can't infer types for a generic union of functions #56975

Open
logandavies181 opened this issue Nov 29, 2022 · 3 comments
Open
Labels
generics Issue is related to generics NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. Proposal-Hold TypeInference Issue is related to generic type inference
Milestone

Comments

@logandavies181
Copy link

What version of Go are you using (go version)?

$ go version
go version go1.19.3 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/vagrant/.cache/go-build"
GOENV="/home/vagrant/.config/go/env"
GOEXE=""
GOEXPERIMENT=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GOINSECURE=""
GOMODCACHE="/home/vagrant/go/pkg/mod"
GONOPROXY=""
GONOSUMDB=""
GOOS="linux"
GOPATH="/home/vagrant/go"
GOPRIVATE=""
GOPROXY="https://proxy.golang.org,direct"
GOROOT="/usr/local/go"
GOSUMDB="sum.golang.org"
GOTMPDIR=""
GOTOOLDIR="/usr/local/go/pkg/tool/linux_amd64"
GOVCS=""
GOVERSION="go1.19.3"
GCCGO="gccgo"
GOAMD64="v1"
AR="ar"
CC="gcc"
CXX="g++"
CGO_ENABLED="1"
GOMOD="/home/vagrant/scratch/go.mod"
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 -m64 -pthread -Wl,--no-gc-sections -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build3122928231=/tmp/go-build -gno-record-gcc-switches"

What did you do?

Try to use type inference for a generic interface whose only member is a union of functions

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

What did you expect to see?

Program compiled successfully

What did you see instead?

./prog.go:12:5: cannot infer T (prog.go:7:10)

If the interface doesn't have a union then type inference works as expected:

https://go.dev/play/p/B-yRqxfvaK0

@gopherbot gopherbot added the compiler/runtime Issues related to the Go compiler and/or runtime. label Nov 29, 2022
@ianlancetaylor
Copy link
Contributor

This is expected with the current language spec. There is no type inference rule that permits inferring the type argument for T in funcT[T].

@ianlancetaylor ianlancetaylor added NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. generics Issue is related to generics TypeInference Issue is related to generic type inference and removed compiler/runtime Issues related to the Go compiler and/or runtime. labels Nov 29, 2022
@ianlancetaylor ianlancetaylor added this to the Backlog milestone Nov 29, 2022
@gopherbot gopherbot added the compiler/runtime Issues related to the Go compiler and/or runtime. label Nov 29, 2022
@mknyszek mknyszek changed the title cmd/compile: Type inference can't infer types for a generic union of functions spec: Type inference can't infer types for a generic union of functions Dec 7, 2022
@mknyszek mknyszek changed the title spec: Type inference can't infer types for a generic union of functions spec: type inference can't infer types for a generic union of functions Dec 7, 2022
@mknyszek mknyszek removed the compiler/runtime Issues related to the Go compiler and/or runtime. label Dec 7, 2022
@griesemer
Copy link
Contributor

Putting on hold because we also don't support calling the function in the generic code.

@intangere
Copy link

intangere commented Jun 27, 2024

I also ran into this earlier and would like to see this sort of inference be possible. You can absolutely call the generic function.

package main

import "fmt"

type funcT[T any] interface {
	func(T) | func(T) error
}

func foo[T any, F funcT[T]](f F) {
	switch any(f).(type) {
	case func(T) error:
		any(f).(func(T) error)(*new(T))
	case func(T):
		any(f).(func(T))(*new(T))
	}
}

func bar(i int) {
	fmt.Println("bar called with: ", i)
}

func bar2(i int) error {
	fmt.Println("bar2 called with: ", i)
	return nil
}

func main() {
	foo[int](bar)  // cannot infer here
	foo[int](bar2) // or here
}

Output:

bar called with:  0
bar2 called with:  0

Edit: Removed other example.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
generics Issue is related to generics NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. Proposal-Hold TypeInference Issue is related to generic type inference
Projects
None yet
Development

No branches or pull requests

6 participants