go/internal/gcimporter: add more assertions for generic import/export
Add additional assertions when comparing objects in imported packages.
In particular, cmpObj was skipping many assertions about top-level named
types that were not reachable from other declarations.
Change-Id: If8f6bee452d921b72550aed4e7ac1b31fa859f5e
Reviewed-on: https://go-review.googlesource.com/c/tools/+/376114
Trust: Robert Findley <rfindley@google.com>
Run-TryBot: Robert Findley <rfindley@google.com>
gopls-CI: kokoro <noreply+kokoro@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Robert Griesemer <gri@golang.org>
diff --git a/go/internal/gcimporter/bexport_test.go b/go/internal/gcimporter/bexport_test.go
index 526e91e..f20cec4 100644
--- a/go/internal/gcimporter/bexport_test.go
+++ b/go/internal/gcimporter/bexport_test.go
@@ -254,40 +254,7 @@
}
case *types.Named:
y := y.(*types.Named)
- xOrig := typeparams.NamedTypeOrigin(x)
- yOrig := typeparams.NamedTypeOrigin(y)
- if sanitizeName(xOrig.String()) != sanitizeName(yOrig.String()) {
- return fmt.Errorf("unequal named types: %s vs %s", x, y)
- }
- if err := equalTypeArgs(typeparams.NamedTypeArgs(x), typeparams.NamedTypeArgs(y)); err != nil {
- return fmt.Errorf("type arguments: %s", err)
- }
- if x.NumMethods() != y.NumMethods() {
- return fmt.Errorf("unequal methods: %d vs %d",
- x.NumMethods(), y.NumMethods())
- }
- // Unfortunately method sorting is not canonical, so sort before comparing.
- var xms, yms []*types.Func
- for i := 0; i < x.NumMethods(); i++ {
- xms = append(xms, x.Method(i))
- yms = append(yms, y.Method(i))
- }
- for _, ms := range [][]*types.Func{xms, yms} {
- sort.Slice(ms, func(i, j int) bool {
- return ms[i].Name() < ms[j].Name()
- })
- }
- for i, xm := range xms {
- ym := yms[i]
- if xm.Name() != ym.Name() {
- return fmt.Errorf("mismatched %dth method: %s vs %s", i, xm, ym)
- }
- // Calling equalType here leads to infinite recursion, so just compare
- // strings.
- if sanitizeName(xm.String()) != sanitizeName(ym.String()) {
- return fmt.Errorf("unequal methods: %s vs %s", x, y)
- }
- }
+ return cmpNamed(x, y)
case *types.Pointer:
y := y.(*types.Pointer)
if err := equalType(x.Elem(), y.Elem()); err != nil {
@@ -380,6 +347,49 @@
return nil
}
+// cmpNamed compares two named types x and y, returning an error for any
+// discrepancies. It does not compare their underlying types.
+func cmpNamed(x, y *types.Named) error {
+ xOrig := typeparams.NamedTypeOrigin(x)
+ yOrig := typeparams.NamedTypeOrigin(y)
+ if sanitizeName(xOrig.String()) != sanitizeName(yOrig.String()) {
+ return fmt.Errorf("unequal named types: %s vs %s", x, y)
+ }
+ if err := equalTypeParams(typeparams.ForNamed(x), typeparams.ForNamed(y)); err != nil {
+ return fmt.Errorf("type parameters: %s", err)
+ }
+ if err := equalTypeArgs(typeparams.NamedTypeArgs(x), typeparams.NamedTypeArgs(y)); err != nil {
+ return fmt.Errorf("type arguments: %s", err)
+ }
+ if x.NumMethods() != y.NumMethods() {
+ return fmt.Errorf("unequal methods: %d vs %d",
+ x.NumMethods(), y.NumMethods())
+ }
+ // Unfortunately method sorting is not canonical, so sort before comparing.
+ var xms, yms []*types.Func
+ for i := 0; i < x.NumMethods(); i++ {
+ xms = append(xms, x.Method(i))
+ yms = append(yms, y.Method(i))
+ }
+ for _, ms := range [][]*types.Func{xms, yms} {
+ sort.Slice(ms, func(i, j int) bool {
+ return ms[i].Name() < ms[j].Name()
+ })
+ }
+ for i, xm := range xms {
+ ym := yms[i]
+ if xm.Name() != ym.Name() {
+ return fmt.Errorf("mismatched %dth method: %s vs %s", i, xm, ym)
+ }
+ // Calling equalType here leads to infinite recursion, so just compare
+ // strings.
+ if sanitizeName(xm.String()) != sanitizeName(ym.String()) {
+ return fmt.Errorf("unequal methods: %s vs %s", x, y)
+ }
+ }
+ return nil
+}
+
// makeExplicit returns an explicit version of typ, if typ is an implicit
// interface. Otherwise it returns typ unmodified.
func makeExplicit(typ types.Type) types.Type {