-
Notifications
You must be signed in to change notification settings - Fork 17.8k
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
cmd/compile: compiler error for calling function, which is a field reference of a typeparam (which has a structural type) #50690
Comments
Thanks @danscales. Why does this example work though? package main
import (
"fmt"
)
type Printer[T ~string] struct {
PrintFn func(T)
}
func Print[T ~string](s T) {
fmt.Println(s)
}
func PrintWithPrinter[T ~string, S struct{ PrintFn func(T) }](message T, obj S) {
obj.PrintFn(message)
}
func main() {
PrintWithPrinter(
"Hello, world.",
struct{ PrintFn func(string) }{PrintFn: Print[string]},
)
} |
This issue is happening because, given structural types (i.e. you can now have field references on type params), we now have to do more work to distinguish a method call on a type param (what we call a bound call, calling a method that is allow by the constraint) from a call to a function-valued field of a type param (that has a single structural type). I don't know yet why the second case works and the first does not, but we definitely have to put in more checks to distinguish the cases. |
@danscales Thanks, makes sense. If I had to guess, the case that works only has a |
Huh, this still works as well (Golang playground): package main
import (
"fmt"
)
type Printer[T ~string] struct {
PrintFn func(T)
}
func Print[T ~string](s T) {
fmt.Println(s)
}
func PrintWithPrinter[T ~string, S struct {
ID T
PrintFn func(T)
}](message T, obj S) {
obj.PrintFn(message)
}
func main() {
PrintWithPrinter(
"Hello, world.",
struct {
ID string
PrintFn func(string)
}{ID: "fake", PrintFn: Print[string]},
)
} I am going to try it when using a non-anon struct since that is what was used in the original example. If that does not work I will introduce a second generic type since that was also in the original use case. |
Okay, this fails: package main
import (
"fmt"
)
type Printer[T ~string] struct {
PrintFn func(T)
}
func Print[T ~string](s T) {
fmt.Println(s)
}
func PrintWithPrinter[T ~string, S ~struct {
ID T
PrintFn func(T)
}](message T, obj S) {
obj.PrintFn(message)
}
type PrintShop[T ~string] struct {
ID T
PrintFn func(T)
}
func main() {
PrintWithPrinter(
"Hello, world.",
PrintShop[string]{
ID: "fake",
PrintFn: Print[string],
},
)
} It was the use of |
Change https://golang.org/cl/379674 mentions this issue: |
For reasons discussed in #51576, field accesses through type parameters will be disabled for Go 1.18. |
Given we have support for field access to type params with a single structural type, we need to distinguish between methods calls and field access when we have an OXDOT node on an expression which is a typeparam (or correspondingly a shape). We were missing checks in getInstInfo, which figures out the dictionary format, which then caused problems when we generate the dictionaries. We don't need/want dictionary entries for field access, only for bound method calls. Added a new function isBoundMethod() to distinguish OXDOT nodes which are bound calls vs. field accesses on a shape. Removed isShapeDeref() - we can't have field access or method call on a pointer to variable of type param type. Fixes golang#50690 Change-Id: Id692f65e6f427f28cd2cfe474dd30e53c71877a7 Reviewed-on: https://go-review.googlesource.com/c/go/+/379674 Trust: Dan Scales <danscales@google.com> Reviewed-by: Keith Randall <khr@golang.org>
New issue from @akutz for Go 1.18 tip:
This example fails to run with the following error (Golang playground):
The above example compiles as long as I do not call
l.SumFn
, even though it is passed into the struct (Golang playground):Originally posted by @akutz in #50417 (comment)
The text was updated successfully, but these errors were encountered: