1
0
mirror of https://github.com/golang/go synced 2024-11-22 20:50:05 -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:
Robert Findley 2021-08-16 13:15:47 -04:00
parent ff36d11470
commit 56a919f17f
3 changed files with 50 additions and 5 deletions

View File

@ -1861,3 +1861,29 @@ func TestInstantiate(t *testing.T) {
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())
}
}

View File

@ -304,6 +304,30 @@ func identical(x, y Type, cmpTags bool, p *ifacePair) bool {
if y, ok := y.(*Named); ok {
x.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,
// we can just return false here because x == y
// is caught in the very beginning of this function.

View File

@ -423,11 +423,6 @@ func (u *unifier) nify(x, y Type, p *ifacePair) bool {
}
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 {
x.expand(nil)
y.expand(nil)