Skip to content

Generic type does not match when the type should match #68210

Closed as not planned
Closed as not planned
@intangere

Description

@intangere

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

$ go version
go version go1.21.5 linux/amd64

Does this issue reproduce with the latest release?

What operating system and processor architecture are you using (go env)?

go env Output
$ go env
GO111MODULE='on'
GOARCH='amd64'
GOBIN=''
GOCACHE='/home/phi/.cache/go-build'
GOENV='/home/phi/.config/go/env'
GOEXE=''
GOEXPERIMENT=''
GOFLAGS=''
GOHOSTARCH='amd64'
GOHOSTOS='linux'
GOINSECURE=''
GOMODCACHE='/home/phi/go/pkg/mod'
GONOPROXY=''
GONOSUMDB=''
GOOS='linux'
GOPATH='/home/phi/go'
GOPRIVATE=''
GOPROXY='https://proxy.golang.org,direct'
GOROOT='/usr/lib/go'
GOSUMDB='sum.golang.org'
GOTMPDIR=''
GOTOOLCHAIN='auto'
GOTOOLDIR='/usr/lib/go/pkg/tool/linux_amd64'
GOVCS=''
GOVERSION='go1.21.5'
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 -ffile-prefix-map=/tmp/go-build3804273348=/tmp/go-build -gno-record-gcc-switches'
uname -sr: Linux 6.1.68-1-MANJARO
LSB Version:	n/a
Distributor ID:	ManjaroLinux
Description:	Manjaro Linux
Release:	23.1.0
Codename:	Vulcan
/usr/lib/libc.so.6: GNU C Library (GNU libc) stable release version 2.38.
gdb --version: GNU gdb (GDB) 13.2

What did you do?

package main

import "fmt"

func CallOneArg[T1 any](f func(T1), args []any) {
	f(args[0].(T1))
}

func CallTwoArgs[T1, T2 any](f func(T1, T2), args []any) {
	f(args[0].(T1), args[1].(T2))
}

func Caller[F any](f F, args []any) {
	switch len(args) {
		case 1:
			CallOneArg(f, args) // type F of f does not match func(T1) (cannot infer T1)
		case 2:
			CallTwoArgs(f, args) // type F of f does not match func(T1, T2) (cannot infer T1 and T2)
	}
}

func MyFunc1(arg1 string) {
	fmt.Println(arg1)
}

func MyFunc2(arg1 string, arg2 string) {
	fmt.Println(arg1, arg2)
}

func main() {
	Caller(MyFunc1, []any{"Hello World!"})
	Caller(MyFunc2, []any{"Hello World!", "Bye World!"})
}

What did you expect to see?

The program to compile because type F does match func(T1) in the first case, and func(T1, T2) in the second case.
If you explicitly type assert such as CallOneArg(any(f).(func(string)) and CallTwoArgs(any(f).(func(string, string)), args) it will compile, but that defeats the entire purpose of the code. I'm not sure if this is a bug or a case of type inference not being implemented but it makes sense for this to work.

What did you see instead?

./compile.go:16:15: type F of f does not match func(T1) (cannot infer T1)
./compile.go:18:16: type F of f does not match func(T1, T2) (cannot infer T1 and T2)

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions