-
Notifications
You must be signed in to change notification settings - Fork 17.9k
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: clarify method sets and recursive promotions #15708
Comments
If all three compilers reject it, I think it should remain invalid. Also, if we accept this, then I think a consequence would be that is no longer the case that the method set of |
FWIW, more examples that are rejected by all three: Here we show that it's not just the case that we don't recursively promote
Here we show that even though
|
An extraction and rewrite of the logic from package suggest. In particular, this code now handles many more subtle cases correctly. Writing it also revealed multiple inconsistencies in the Go spec and/or standard implementations: golang/go#15708, golang/go#15721, golang/go#15722.
There is a subtle interplay between the definition of method sets, how they are enlarged via embedding, and the rules for selector lookup. My reading of the spec is that there is a conflict, and that all compilers and go/types consistently decide these programs by looking at a) the basic definition of method sets (https://tip.golang.org/ref/spec#Method_sets), and b) the basic rules for selector lookup (https://tip.golang.org/ref/spec#Selectors), rather then how method sets are extended (which also historically was described later in the development of Go). Specifically, in your first case, In other words, the way method sets are extended by way of embedding is really implicitly defined by way of how method/field lookup works. We may want to be more careful in describing how method sets are extended in https://tip.golang.org/ref/spec#Struct_types. For instance, the notion of depth (as in "the shallowest") is not present there, yet it is crucial for lookup. Thus, I believe the compilers and go/types are correct. |
I agree with Robert and Ian that the compilers and go/types are correct. It would be terribly confusing if (*S1).M and S1.M resolved to different method definitions M. Perhaps some rewording in the spec is needed, perhaps not, but the rules we agree on shouldn't change. |
Bumping to Go 1.9, but feel free to send a CL this week for Go 1.8 if you want. |
Bumping to 1.10. Requires careful spec wording. |
My reading of the Go spec is that this is valid:
Rationale:
func (*S1) M() {}
,M
is a member of*S1
's method set.*S1
embedding intoS2
,M
is also a member ofS2
and*S2
's method sets.*S2
embedding intoS1
,M
should also be a member ofS1
's method set.However, cmd/compile, gccgo, and gotype all reject it.
/cc @griesemer @ianlancetaylor
The text was updated successfully, but these errors were encountered: