mirror of
https://github.com/golang/go
synced 2024-11-22 20:14:40 -07:00
go/types: define Identical for instances
This is a port of CL 341856 to go/types. It is adjusted to use the NumTArgs/TArg API of go/types, which has not yet been ported to types2. Change-Id: I6faeec027f4ae08634267001f473263703e80c5b Reviewed-on: https://go-review.googlesource.com/c/go/+/342478 Trust: Robert Findley <rfindley@google.com> Run-TryBot: Robert Findley <rfindley@google.com> Reviewed-by: Robert Griesemer <gri@golang.org> TryBot-Result: Go Bot <gobot@golang.org>
This commit is contained in:
parent
ff36d11470
commit
56a919f17f
@ -1861,3 +1861,29 @@ func TestInstantiate(t *testing.T) {
|
|||||||
t.Fatalf("unexpected result type: %s points to %s", res, p)
|
t.Fatalf("unexpected result type: %s points to %s", res, p)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestInstanceIdentity(t *testing.T) {
|
||||||
|
imports := make(testImporter)
|
||||||
|
conf := Config{Importer: imports}
|
||||||
|
makePkg := func(src string) {
|
||||||
|
fset := token.NewFileSet()
|
||||||
|
f, err := parser.ParseFile(fset, "", src, 0)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
name := f.Name.Name
|
||||||
|
pkg, err := conf.Check(name, fset, []*ast.File{f}, nil)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
imports[name] = pkg
|
||||||
|
}
|
||||||
|
makePkg(genericPkg + `lib; type T[P any] struct{}`)
|
||||||
|
makePkg(genericPkg + `a; import "generic_lib"; var A generic_lib.T[int]`)
|
||||||
|
makePkg(genericPkg + `b; import "generic_lib"; var B generic_lib.T[int]`)
|
||||||
|
a := imports["generic_a"].Scope().Lookup("A")
|
||||||
|
b := imports["generic_b"].Scope().Lookup("B")
|
||||||
|
if !Identical(a.Type(), b.Type()) {
|
||||||
|
t.Errorf("mismatching types: a.A: %s, b.B: %s", a.Type(), b.Type())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -304,6 +304,30 @@ func identical(x, y Type, cmpTags bool, p *ifacePair) bool {
|
|||||||
if y, ok := y.(*Named); ok {
|
if y, ok := y.(*Named); ok {
|
||||||
x.expand(nil)
|
x.expand(nil)
|
||||||
y.expand(nil)
|
y.expand(nil)
|
||||||
|
|
||||||
|
// xargs := x.TArgs()
|
||||||
|
// yargs := y.TArgs()
|
||||||
|
|
||||||
|
if x.NumTArgs() != y.NumTArgs() {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
if nargs := x.NumTArgs(); nargs > 0 {
|
||||||
|
// Instances are identical if their original type and type arguments
|
||||||
|
// are identical.
|
||||||
|
if !Identical(x.orig, y.orig) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
for i := 0; i < nargs; i++ {
|
||||||
|
xa := x.TArg(i)
|
||||||
|
ya := y.TArg(i)
|
||||||
|
if !Identical(xa, ya) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
// TODO(gri) Why is x == y not sufficient? And if it is,
|
// TODO(gri) Why is x == y not sufficient? And if it is,
|
||||||
// we can just return false here because x == y
|
// we can just return false here because x == y
|
||||||
// is caught in the very beginning of this function.
|
// is caught in the very beginning of this function.
|
||||||
|
@ -423,11 +423,6 @@ func (u *unifier) nify(x, y Type, p *ifacePair) bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
case *Named:
|
case *Named:
|
||||||
// Two named types are identical if their type names originate
|
|
||||||
// in the same type declaration.
|
|
||||||
// if y, ok := y.(*Named); ok {
|
|
||||||
// return x.obj == y.obj
|
|
||||||
// }
|
|
||||||
if y, ok := y.(*Named); ok {
|
if y, ok := y.(*Named); ok {
|
||||||
x.expand(nil)
|
x.expand(nil)
|
||||||
y.expand(nil)
|
y.expand(nil)
|
||||||
|
Loading…
Reference in New Issue
Block a user