Question about when a type is satisfying a generic slice constraint?

101 views
Skip to first unread message

awaw...@gmail.com

unread,
Oct 3, 2025, 5:04:07 AM (4 days ago) Oct 3
to golang-nuts
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}))
}
```

Brian Candler

unread,
Oct 3, 2025, 5:58:53 AM (4 days ago) Oct 3
to golang-nuts
I note that the following *does* work:

fmt.Println(slices.Index[[]interface{}, interface{}](mySlice, MyStruct{A: 2, B: 3}))

So I think it's something to do with how type inference works. But the details of this are beyond my comprehension.

Def Ceb

unread,
Oct 3, 2025, 6:35:45 AM (4 days ago) Oct 3
to golang-nuts
I think the fact that literals rather than concretely typed variables is significant. With variables, the slice creation continues to work, as does a search call with a literal, but searches with variables with the same value do not. 

--
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 golang-nuts...@googlegroups.com.
To view this discussion visit https://groups.google.com/d/msgid/golang-nuts/23fd70c7-67a6-428e-81bf-22ccafe2feccn%40googlegroups.com.

Axel Wagner

unread,
Oct 3, 2025, 7:20:23 AM (4 days ago) Oct 3
to awaw...@gmail.com, golang-nuts
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.

--
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 golang-nuts...@googlegroups.com.

awaw...@gmail.com

unread,
Oct 3, 2025, 9:23:58 AM (4 days ago) Oct 3
to golang-nuts
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.
Reply all
Reply to author
Forward
0 new messages