]> Cypherpunks repositories - gostls13.git/commit
go/types, types2: consider shared methods when unifying against interfaces
authorRobert Griesemer <gri@golang.org>
Tue, 23 May 2023 21:29:12 +0000 (14:29 -0700)
committerGopher Robot <gobot@golang.org>
Tue, 23 May 2023 22:13:25 +0000 (22:13 +0000)
commit948f11b8a83a7c7762f43b3dac513d7311a4bb71
treeaafa6f576d10701ec1f84f318ee32aa6c0b169e4
parent26f25692b8107f06a16dd103672ba4b5c3e4571f
go/types, types2: consider shared methods when unifying against interfaces

When unifying two types A and B where one or both of them are
interfaces, consider the shared method signatures in unification.

1) If a defined interface (an interface with a type name) is unified
   with another (defined) interface, currently they must originate
   in the same type declaration (same origin) for unification to
   succeed. This is more restrictive than necessary for assignments:
   when interfaces are assigned to each other, corresponding methods
   must match, but the interfaces don't have to be identical.
   In unification, we don't know which direction the assignment is
   happening (or if we have an assignment in the first place), but
   in any case one interface must implement the other. Thus, we
   check that one interface has a subset of the methods of the other
   and that corresponding method signatures unify.
   The assignment or instantiation may still not be possible but that
   will be checked when instantiation and parameter passing is checked.
   If two interfaces are compared as part of another type during
   unification, the types must be equal. If they are not, unifying
   a method subset may still succeed (and possibly produce more type
   arguments), but that is ok: again, subsequent instantiation and
   assignment will fail if the types are indeed not identical.

2) In a non-interface type is unified with an interface, currently
   unification fails. If this unification is a consequence of an
   assignment (parameter passing), this is again too restrictive:
   the non-interface type must only implement the interface (possibly
   among other type set requirements). In any case, all methods of the
   interface type must be present in the non-interface type and unify
   with the corresponding interface methods. If they don't, unification
   will fail either way. If they do, we may infer additional type
   arguments. Again, the resulting types may still not be correct but
   that will be determined by the instantiation and parameter passing
   or assignment checks. If the non-interface type and the interface
   type appear as component of another type, unification may now
   produce additional type arguments. But that is again ok because the
   respective types won't pass instantiation or assignment checks since
   they are different types.

This CL introduces a new unifier flag, enableInterfaceInference, to
enable this new behavior. It is currently disabled.

For #60353.
For #41176.
For #57192.

Change-Id: I983d0ad5f043c7fe9d377dbb95f6b9342f36f45f
Reviewed-on: https://go-review.googlesource.com/c/go/+/497656
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Robert Griesemer <gri@google.com>
Reviewed-by: Robert Findley <rfindley@google.com>
Run-TryBot: Robert Griesemer <gri@google.com>
Auto-Submit: Robert Griesemer <gri@google.com>
src/cmd/compile/internal/types2/unify.go
src/go/types/unify.go
src/internal/types/testdata/fixedbugs/issue41176.go [new file with mode: 0644]
src/internal/types/testdata/fixedbugs/issue57192.go [new file with mode: 0644]