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
cmd/compile: spurious promotion of methods from embedded aliases of unnamed types #66540
Comments
Personally, I don't find the promotion to be surprising.
Which IMO does say that the method is promoted. OTOH it also says two paragraphs later
Which restricts promoted methods in the method set to those of named types. So, arguably, |
I was surprised to learn that embedding a non-named type was legal at all, so my intuition may not be a good guide here. The specified (as opposed to implemented) behavior of promotion makes more sense to me because I have always thought of aliases as being largely melted away. But surprising or not, the spec disallows it (see below).
That's the definition of promotion, not a description of when it applies. The paragraph that follows explains the mechanism:
and the definition of named types is:
So, an alias for (say) a slice type is not a named type, though it is a legal anonymous field, according to:
|
I believe "named type" should be "type name" here. The "named type` term returned back to spec at Go 1.18. |
Nope. Funnily enough, I proposed the "type name" phrasing. But @griesemer opted for "named type" instead. Maybe he has an opinion. IMO if the spec and implementation have been disagreeing for several Go versions, the spec is wrong. (I also completely forgot that I reported it and I used exactly @adonovan's example to argue for that change) |
The embedding-related wording is really subtle. I still think there are some inaccuracies there: #22005 |
Per this phrase, where we now use "named type" (formerly "defined type"), it seems to me that the implementation is not correct. Per the spec, an alias is only a named type type if it aliases a named type, such as a defined type:
But in this case Can we change (fix) this? Maybe. It seems that the chance that code such exists in the wild is pretty slim; at the very least it's not going to be a lot of code. But we'd need to do a little investigation first. |
@griesemer I'll point out again that in the issue I linked above I observed this behavior of promoted method and prompted that change. So IMO that change was made specifically to bring the spec in line with this behavior. I don't remember if I filed that issue based on a real world example. At the time, I suggested "type name", specifically because it includes aliases that are not named types (and thus to address my example). I'm not sure why you chose "named type" instead; neither the issue description, nor the commit message mention. |
Per the fact that an interface can embed any types, including struct literals, maybe the current implementation is preferred? |
I used this in a project for my job, no source available. It is convenient and makes sense. |
@Merovius I see. The commit message says "The types of embedded fields must be named, but they don't need to be defined types" which implies that I meant any type with a name (i.e., with a type name). Yet, the change mentions named type, which excludes aliases denoting type literals, and - which I believe - was my intention as it simply used the more general term (named type) for the original term (defined type). Sigh. The implementation does something else, the spec says something else in most places, and so maybe this issue is fixed by simply changing "named type" to "type name" in "Given a struct type S and a name type T, ...". (It's really unfortunate, and a mistake in my mind, that we allowed aliases for type literals. There was no need for it, and it needlessly complicates/confuses things.) |
That would solve the inconsistency, but it seems like a pragmatic admission of defeat relative to your original intent, which makes more sense to me.
Inessential they may be, but type aliases for unnamed types are quite useful as documentable abbreviations for verbose types that have no need for declared methods, function types in particular. |
I was surprised to learn yesterday that it is legal to embed an alias type whose underlying type is not a defined type.
This is legal according to the spec; there is supposed to be no promotion of methods from the alias's underlying type.
And yet promotion does occur:
https://go.dev/play/p/_bJZeiZW-cW
I expect go/types has the same issue.
The text was updated successfully, but these errors were encountered: