diff --git a/src/cmd/compile/internal/types2/unify.go b/src/cmd/compile/internal/types2/unify.go index 433d31b302..a48f745cb4 100644 --- a/src/cmd/compile/internal/types2/unify.go +++ b/src/cmd/compile/internal/types2/unify.go @@ -500,7 +500,7 @@ func (u *unifier) nify(x, y Type, mode unifyMode, p *ifacePair) (result bool) { } // All xmethods must exist in ymethods and corresponding signatures must unify. for _, xm := range xmethods { - if ym := ymap[xm.Id()]; ym == nil || !u.nify(xm.typ, ym.typ, emode, p) { + if ym := ymap[xm.Id()]; ym == nil || !u.nify(xm.typ, ym.typ, exact, p) { return false } } @@ -521,7 +521,7 @@ func (u *unifier) nify(x, y Type, mode unifyMode, p *ifacePair) (result bool) { xmethods := xi.typeSet().methods for _, xm := range xmethods { obj, _, _ := LookupFieldOrMethod(y, false, xm.pkg, xm.name) - if ym, _ := obj.(*Func); ym == nil || !u.nify(xm.typ, ym.typ, emode, p) { + if ym, _ := obj.(*Func); ym == nil || !u.nify(xm.typ, ym.typ, exact, p) { return false } } @@ -680,7 +680,7 @@ func (u *unifier) nify(x, y Type, mode unifyMode, p *ifacePair) (result bool) { } for i, f := range a { g := b[i] - if f.Id() != g.Id() || !u.nify(f.typ, g.typ, emode, q) { + if f.Id() != g.Id() || !u.nify(f.typ, g.typ, exact, q) { return false } } diff --git a/src/go/types/unify.go b/src/go/types/unify.go index 4d97e119bf..619459b1ee 100644 --- a/src/go/types/unify.go +++ b/src/go/types/unify.go @@ -502,7 +502,7 @@ func (u *unifier) nify(x, y Type, mode unifyMode, p *ifacePair) (result bool) { } // All xmethods must exist in ymethods and corresponding signatures must unify. for _, xm := range xmethods { - if ym := ymap[xm.Id()]; ym == nil || !u.nify(xm.typ, ym.typ, emode, p) { + if ym := ymap[xm.Id()]; ym == nil || !u.nify(xm.typ, ym.typ, exact, p) { return false } } @@ -523,7 +523,7 @@ func (u *unifier) nify(x, y Type, mode unifyMode, p *ifacePair) (result bool) { xmethods := xi.typeSet().methods for _, xm := range xmethods { obj, _, _ := LookupFieldOrMethod(y, false, xm.pkg, xm.name) - if ym, _ := obj.(*Func); ym == nil || !u.nify(xm.typ, ym.typ, emode, p) { + if ym, _ := obj.(*Func); ym == nil || !u.nify(xm.typ, ym.typ, exact, p) { return false } } @@ -682,7 +682,7 @@ func (u *unifier) nify(x, y Type, mode unifyMode, p *ifacePair) (result bool) { } for i, f := range a { g := b[i] - if f.Id() != g.Id() || !u.nify(f.typ, g.typ, emode, q) { + if f.Id() != g.Id() || !u.nify(f.typ, g.typ, exact, q) { return false } } diff --git a/src/internal/types/testdata/fixedbugs/issue61879.go b/src/internal/types/testdata/fixedbugs/issue61879.go new file mode 100644 index 0000000000..542bc2d68a --- /dev/null +++ b/src/internal/types/testdata/fixedbugs/issue61879.go @@ -0,0 +1,57 @@ +// Copyright 2023 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package p + +import "fmt" + +type Interface[T any] interface { + m(Interface[T]) +} + +func f[S []Interface[T], T any](S) {} + +func _() { + var s []Interface[int] + f(s) // panic here +} + +// Larger example from issue + +type InterfaceA[T comparable] interface { + setData(string) InterfaceA[T] +} + +type ImplA[T comparable] struct { + data string + args []any +} + +func NewInterfaceA[T comparable](args ...any) InterfaceA[T] { + return &ImplA[T]{ + data: fmt.Sprintf("%v", args...), + args: args, + } +} + +func (k *ImplA[T]) setData(data string) InterfaceA[T] { + k.data = data + return k +} + +func Foo[M ~map[InterfaceA[T]]V, T comparable, V any](m M) { + // DO SOMETHING HERE + return +} + +func Bar() { + keys := make([]InterfaceA[int], 0, 10) + m := make(map[InterfaceA[int]]int) + for i := 0; i < 10; i++ { + keys = append(keys, NewInterfaceA[int](i)) + m[keys[i]] = i + } + + Foo(m) // panic here +}