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())
+ }
+}
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.
}
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)