mirror of
https://github.com/golang/go
synced 2024-11-11 23:40:22 -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)
|
||||
}
|
||||
}
|
||||
|
||||
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 {
|
||||
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.
|
||||
|
@ -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)
|
||||
|
Loading…
Reference in New Issue
Block a user