These are truly interesting examples. I think it's fair to say that this issue is indeed a quirk on literal constants. Thanks everyone for helping answering this question.
On Friday, October 3, 2025 at 7:20:23 PM UTC+8 Axel Wagner wrote: > The problem has to do with the fact that untyped constants are treated > differently in type inference. > Note that `slices.Index(mySlice, int(1))` also does not work. That's > because 1 has no type - it is an untyped integer constant - while int(1) > has the type int. > Untyped constants can be assigned to multiple different types, so they > need to be treated differently. We wouldn't, for example, want this to fail > to compile: > > type MyInt int > var x []MyInt > slices.Index(x, 1) > > On the other hand, a constant of type `int` - or a struct-literal of type > `MyStruct` - can only ever have one type (even if that type is assignable > to interfaces as well). > In order to make type-inference relatively easy to understand and specify, > the compiler doesn't do any backtracking or whatever. So when it sees > `slices.Index(s, x)` and it needs to figure out what `S` (constrained on > `~[]E`) and `E` (constraint on any) is, and it sees that `x` already has a > definitive type, it kind of greedily binds `E` to that type and then just > checks if the rest of the type parameters work out. > With an untyped constant, it *doesn't* immediately see what `E` can be, > but it *does* see that `S` has to be `[]any`, so it binds that, forcing `E` > to be `any. And then it checks if the untyped constant works with that. > > The outcome is a bit confusing, true. But it's a consequence of keeping > inference rules relatively simple. And as inference is optional and it is > always possible to actively specify the constraints you have in mind, the > design is conservative with what it tries to do automatically. > > On Fri, 3 Oct 2025 at 11:04, [email protected] <[email protected]> wrote: > >> Hi fellow generic experts >> >> I'd like to ask why does the last line in the below Snippet 1 fails with >> the error: >> >> ./prog.go:17:26: in call to slices.Index, S (type []interface{}) does >> not satisfy ~[]E >> >> The third line is essentially the same line, but it works! >> >> Snippet 1: Full code in https://go.dev/play/p/PPdIaK08v5A >> ``` >> func main() { >> mySlice := []interface{}{1, "a", MyStruct{A: 2, B: 3}} >> fmt.Println(slices.Index(mySlice, 1)) >> fmt.Println(slices.Index(mySlice, "a")) >> fmt.Println(slices.Index(mySlice, interface{}(MyStruct{A: 2, B: 3}))) >> >> // Below does not work. >> // fmt.Println(slices.Index(mySlice, MyStruct{A: 2, B: 3})) >> } >> ``` >> >> -- >> > You received this message because you are subscribed to the Google Groups >> "golang-nuts" group. >> To unsubscribe from this group and stop receiving emails from it, send an >> email to [email protected]. >> > To view this discussion visit >> https://groups.google.com/d/msgid/golang-nuts/67f5a2c2-636e-43c3-81be-c2ec9098f884n%40googlegroups.com >> >> <https://groups.google.com/d/msgid/golang-nuts/67f5a2c2-636e-43c3-81be-c2ec9098f884n%40googlegroups.com?utm_medium=email&utm_source=footer> >> . >> > -- You received this message because you are subscribed to the Google Groups "golang-nuts" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. To view this discussion visit https://groups.google.com/d/msgid/golang-nuts/24351d18-db47-426a-8b78-218198c67563n%40googlegroups.com.
