Go version

Go 1.25 (go.dev/play 2025-09-25)

MRE

Attempt compilation of https://go.dev/play/p/WilsJYD63yZ [2025-09-25]:

package main

func hasKey[M ~map[K]V, K comparable, V any](m M, k K) bool {
    _, ok := m[k]
    return ok
}

type Set[T comparable] = map[T]struct{}

func main() {
    type A string
    m := make(Set[A])

    type B string
    //type B = A

    _ = hasKey(m, B(""))
}
./prog.go:17:12: in call to hasKey, M (type Set[A]) does not satisfy ~map[K]V

Go build failed.

Discussion

I get where the compiler's coming from; inferring from the typed constant literal B("") a substitution (M ← map[B]struct{}, K ← B, V ← struct{}) for hasKey, whose first argument then turns out to be of type M ← map[A]struct{} with A ≢ B being non-aliased, distinct types.

However, cmd/compile's error message after the above internal reasoning doesn't telegraph the existence of two K substitutions:

./prog.go:17:12: in call to hasKey, M (type Set[A]) does not satisfy ~map[K]V

It took me a good quarter of an hour to realize how exactly the claim "M (type Set[A]) does not satisfy ~map[K]V" was meant (as on first glance, it reads like blatantly false nonsense).

The crux of the problem is that the compiler withholds inference information it has; a hypothetical error message like the following would alleviate the above-outlined confusion:

((hypothetical Go >1.25.1 error message))
./prog.go:17:12: in call to hasKey, M (type Set[A]) does not satisfy ~map[K]V (where K is B and V is struct{})

I was motivated to ticket the above as an issue due to the apparent interest (issue not closed in over two years) in the similarily non-bug compiler behaviour https://github.com/golang/go/issues/61685 [2025-09-25].

Comment From: jfrech

@griesemer

Comment From: gabyhelp

Related Issues

(Emoji vote if this was helpful or unhelpful; more detailed feedback welcome in this discussion.)

Comment From: JunyangShao

@golang/compiler @mrkfrmn