-
Notifications
You must be signed in to change notification settings - Fork 17.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
spec: interfaces that have different-size method sets never unify (but they possibly could) #57192
Comments
This is expected behavior for the current language spec. Changing this to be a language issue. |
I would not be surprised if fixing #41176 fixes this one as well. |
There are two issues here:
If we do 1) and 2), this example will work. Or putting it differently, two interfaces should unify if one of them can be made (through unification) to implement the other. |
Change https://go.dev/cl/496256 mentions this issue: |
Change https://go.dev/cl/497015 mentions this issue: |
Submitted accidentally, revert in progress. Reopening. |
Change https://go.dev/cl/497656 mentions this issue: |
Change https://go.dev/cl/497657 mentions this issue: |
…faces 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>
Change https://go.dev/cl/499282 mentions this issue: |
For #39661. For #41176. For #51593. For #52397. For #57192. For #58645. For #58650. For #58671. For #59338. For #59750. For #60353. Change-Id: Ib731c9f2879beb541f44cb10e40c36a8677d3ad4 Reviewed-on: https://go-review.googlesource.com/c/go/+/499282 TryBot-Bypass: Robert Griesemer <gri@google.com> Reviewed-by: Ian Lance Taylor <iant@google.com> Reviewed-by: Robert Griesemer <gri@google.com>
What version of Go are you using (
go version
)?Does this issue reproduce with the latest release?
Yes, tested on playground.
What operating system and processor architecture are you using (
go env
)?go env
OutputWhat did you do?
Given
GenericInterface1[T any]
,GenericInterface2[T any] { GenericInterface1[T] }
, and a functionfunc F[T any](GI1 GenericInterface1[T]()
,T
is not inferred if we pass toF
aGenericInterface2
.https://go.dev/play/p/dsZOHq2Y1Au
What did you expect to see?
Type inference to work since
GenericInterface2
is alsoGenericInterface1
, and since passing toF
a declared variable of typeGenericInterface1[T]
works (if it's not explicitly declared, then type inference cannot infer T even forGenericInterface1
).What did you see instead?
Compilation failure.
The text was updated successfully, but these errors were encountered: