-
Notifications
You must be signed in to change notification settings - Fork 18.3k
Description
Consider this test case:
package main
import (
"fmt"
"unsafe"
)
func start[S []byte | string](s S) *byte {
switch s := any(s).(type) {
case []byte:
return unsafe.SliceData(s)
case string:
return unsafe.StringData(s)
default:
panic("can't happen")
}
}
func F[S []byte | string](s S) {
fmt.Println(start(s), len(s))
}
func main() {
F("hi")
F([]byte("bye"))
}
This runs fine. It instantiates F
twice: main.F[go.shape.[]uint8]
and main.F[go.shape.string]
. Both versions take a dictionary, and both versions implement the type switch by loading the type descriptor from the dictionary and comparing it to the descriptors for []byte
and string
.
In these instantiations, however, the type descriptor is a constant. We know this because the constraint does not use a ~
. It would be nice if the compiler were able to constant fold the dictionary value and eliminate the type switch.
I came up with this example because of #38776. It would be nice if we could change some of the hash implementations to use generic functions, which largely works until they try to call assembly code. At that point it's necessary to get the pointer to the slice or string data. It would be nice to be able to do that reasonably safely, which is what the above code does, and also efficiently, which the above code is not.
Metadata
Metadata
Assignees
Labels
Type
Projects
Status