Go: cmd/compile: improve compiler error on embedded structs

Created on 30 Jan 2018  Â·  22Comments  Â·  Source: golang/go

Please answer these questions before submitting your issue. Thanks!

What version of Go are you using (go version)?

1.9.2

Does this issue reproduce with the latest release?

Yes

What operating system and processor architecture are you using (go env)?

Linux amd64

What did you do?

package main

type Foo struct {
    A string
}

type Bar struct {
    Foo
}

func main() {
    a := Bar{
       A: "bar",
    }
}

https://play.golang.org/p/6LDcycp9lPB

What did you expect to see?

An error like:
"The field 'A' doesn't exist in 'Bar' but is instead embedded in 'Foo'

What did you see instead?

"unknown field 'A' in struct literal of type Bar"

The motivation for this is often you will see encode:

var b Bar
...

Bar.A

Unless you go and actually pull the struct definition (which often is unnecessary) you can't tell that 'A' was embedded. If you try to create your own Bar then you get the error above, which is confusing since it's the same as if you misspelled the field name, or just got something wrong.

It's not hard to scan any embedded structs and see if there is a matching field. It's still legit to give an error, but you could definitely reduce confusion by having a better one.

FrozenDueToAge NeedsFix help wanted

Most helpful comment

even if it is more precise, I don't think that using the word 'promoted' will help with understandability.

I've been programming Go for > 4 years, and I've never heard of 'promoted' until today.

I'd recommend favoring understandability over precision here.

All 22 comments

/cc @mdempsky @griesemer @odeke-em

This is definitely doable. I think the main issue is coming up with agreeable wording.

It's also worth noting that the promoted field might have been promoted through multiple field embeddings. For example:

type A struct { a int }
type B struct { A }
type C struct { B }

var _ = C{ a: 0 }

The error should probably properly mention that field a in C is promoted via B.A or something. I'm not sure how best to explain that to the user.

@mdempsky Error message suggestion (for your specific case): "cannot set embedded field C.B.A.a directly in composite literal C".

@brendandburns, thanks for filing. I hit this myself not too long ago.

I like @griesemer's suggestion with two nits:

  1. I think compiler error messages should try to match Go spec terminology when possible. For example, I'd suggest "initialize" or "assign" instead of the more informal "set". Also, B and A are embedded fields, but a itself is a promoted field. (Bonus: Searching the Go spec for "promoted field" finds "Promoted fields act like ordinary fields of a struct except that they cannot be used as field names in composite literals of the struct.")

  2. I don't think we need to repeat C. in the field description when it's already mentioned as the composite literal type.

I'd suggest:

cannot initialize promoted field B.A.a in struct literal of type C

or maybe:

cannot use promoted field B.A.a as key in struct literal of type C

even if it is more precise, I don't think that using the word 'promoted' will help with understandability.

I've been programming Go for > 4 years, and I've never heard of 'promoted' until today.

I'd recommend favoring understandability over precision here.

Thanks for that data point and input.

I think using a more precise, even if less common, term aids accessibility. As pointed out, searching the Go spec for "promoted field" explains what it means. Google searches for "golang promoted field" also turn up accessible explanations about embedding and promotion. Over time, I'd expect "promoted field" to become more commonly understood because of its use in this error message, and search results to be more helpful to new users in how to fix the error.

Also, I think today's users who may be unfamiliar with the term "promoted field" will still understand the rest of the error. I think that's better than using an incorrect term like "embedded field" which will increase misunderstanding.

Agree with @brendandburns - never heard of it either. Perhaps the error should make the meaning of "promoted" obvious, at least until the term is more widely known and understood.

Any suggestions for wording that's more understandable or that makes the meaning of "promoted field" more obvious?

On second thought, I agree with the point that using "embedded field" will make everything more confusing in the long run. I can't come up with a reasonably sized error message that would make the meaning of "promoted field" more obvious, so I take that back.

Hrm, the answer to 'making an error useful' is 'go use a search engine'?

That feels like a usability fail. I don't really care about understanding the language spec. I want to fix my code and move on. Asking me to switch from an editor to a browser isn't a great experience imho.

--brendan

From: Daniel Martí
Sent: Wednesday, January 31, 4:30 AM
Subject: Re: [golang/go] cmd/compile: improve compiler error on embedded structs (#23609)
To: golang/go
Cc: Brendan Burns, Mention

On second thought, I agree with the point that using "embedded field" will make everything more confusing in the long run. I can't come up with a reasonably sized error message that would make the meaning of "promoted field" more obvious, so I take that back.
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHubhttps://na01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2Fgolang%2Fgo%2Fissues%2F23609%23issuecomment-361918010&data=02%7C01%7Cbburns%40microsoft.com%7Ca1ac1f7d177c44e7ce6008d568a65ec3%7Cee3303d7fb734b0c8589bcd847f1c277%7C1%7C0%7C636529986124512443&sdata=dsTpBxCuaL22T9dsuvxXXGJndj1QfMjr%2BCVicEX1Nw4%3D&reserved=0, or mute the threadhttps://na01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2Fnotifications%2Funsubscribe-auth%2FAFfDgtiG-pstzp0zu9MVoFOOkfq9TR-Qks5tQFzPgaJpZM4RxknP&data=02%7C01%7Cbburns%40microsoft.com%7Ca1ac1f7d177c44e7ce6008d568a65ec3%7Cee3303d7fb734b0c8589bcd847f1c277%7C1%7C0%7C636529986124512443&sdata=wB4cbJvuwazf0zwg6K4%2FMNIIOGqY%2FsU%2F9RNZCe92VQ4%3D&reserved=0.

I don't really care about understanding the language spec.

:man_facepalming:

Hrm, the answer to 'making an error useful' is 'go use a search engine'?

I see largely two classes of users without a priori familiarity with the term "promoted field" who might see this error message:

  1. New users who do not understand the issue with using promoted fields in struct literals. Whether we say "promoted field" or something else, they're unlikely to immediately understand the problem. Further, it's out of the scope of the compiler to explain this to them in an error message. The best we can do for these users is to give a precise error message that they can search for or ask experienced users about.

  2. Experienced users who generally understand embedding and that promoted fields cannot be used in struct literals, but aren't familiar with the term "promoted field". However, I expect many of these users are going to find the B.A.a text by itself sufficient to understand the error and how to fix it. Moreover, I expect some of these users to learn from context that B.A.a is properly termed a "promoted field", or maybe to show interest in learning about that term and looking it up in the spec or elsewhere, though I don't think that's vital to them resolving the error.

I don't see using less precise language as substantially improving either class of users' experience in resolving their issue. If you think otherwise, it would help me understand your point of view if you could describe a user (or group thereof) with certain familiarities with Go, and how and why you think they would react to different error messages.

Let's not bike-shed the actual choice of words here. We can fine-tune the message in an actual CL. The direction seems clear: If the code indeed attempts to assign to a promoted field, the error message should probably mention the explicit path to that field (e.g., B.A.a).

I guess my only feedback is that as a developer who used golang as my primary language for the last 4 years, I was familiar with the term "embedded" and not with the term "promoted"

I have one more suggestion and then I will stop the bikeshedding...

"The field c is not present in the struct A, instead it is present in the embedded struct A.B.C"

Ok, I'm done, any message is going to be better than the current one, I'm looking forward to the PR, thanks!


From: Matthew Dempsky notifications@github.com
Sent: Wednesday, January 31, 2018 1:13 PM
To: golang/go
Cc: Brendan Burns; Mention
Subject: Re: [golang/go] cmd/compile: improve compiler error on embedded structs (#23609)

Hrm, the answer to 'making an error useful' is 'go use a search engine'?

I see largely two classes of users without a priori familiarity with the term "promoted field" who might see this error message:

  1. New users who do not understand the issue with using promoted fields in struct literals. Whether we say "promoted field" or something else, they're unlikely to immediately understand the problem. Further, it's out of the scope of the compiler to explain this to them in an error message. The best we can do for these users is to give a precise error message that they can search for or ask experienced users about.

  2. Experienced users who generally understand embedding and that promoted fields cannot be used in struct literals, but aren't familiar with the term "promoted field". However, I expect many of these users are going to find the B.A.a text by itself sufficient to understand the error and how to fix it. Moreover, I expect some of these users to learn from context that B.A.a is properly termed a "promoted field", or maybe to show interest in learning about that term and looking it up in the spec or elsewhere, though I don't think that's vital to them resolving the error.

I don't see using less precise language as substantially improving either class of users' experience in resolving their issue. If you think otherwise, it would help me understand your point of view if you could describe a user (or group thereof) with certain familiarities with Go, and how and why you think they would react to different error messages.

—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHubhttps://na01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2Fgolang%2Fgo%2Fissues%2F23609%23issuecomment-362063948&data=02%7C01%7Cbburns%40microsoft.com%7Cc7697f9d820148ed9ea308d568ef8a32%7Cee3303d7fb734b0c8589bcd847f1c277%7C1%7C0%7C636530300381226727&sdata=Ff%2B10dQFI9DKqEzyVs7C7UNTIlepokz2qBHdDhuO0OQ%3D&reserved=0, or mute the threadhttps://na01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2Fnotifications%2Funsubscribe-auth%2FAFfDgtkjd-PB_lQSAdIVb_bkQY7-757Rks5tQNBXgaJpZM4RxknP&data=02%7C01%7Cbburns%40microsoft.com%7Cc7697f9d820148ed9ea308d568ef8a32%7Cee3303d7fb734b0c8589bcd847f1c277%7C1%7C0%7C636530300381226727&sdata=QuQKKpU2UPb1joJHVbEOvMoC2O1Ah5HJzryl1nBLKis%3D&reserved=0.

I'd like to have a look at this if no one else is working on it.

Whoops - now I see it's assigned.

@ChrisALiles oh, not a problem at all, thank you for upcoming contribution, this is great! I'll yield to you and unassign myself, all yours :)

OK thanks (I think).

Change https://golang.org/cl/97076 mentions this issue: cmd/compile: improve compiler error on embedded structs

I sent change 97076 through yesterday.

On 16 Feb 2018, at 12:37 am, Emmanuel T Odeke notifications@github.com wrote:

@ChrisALiles https://github.com/chrisaliles oh, not a problem at all, thank you for upcoming contribution, this is great! I'll yield to you and unassign myself, all yours :)

—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub https://github.com/golang/go/issues/23609#issuecomment-365928860, or mute the thread https://github.com/notifications/unsubscribe-auth/AeohTqcphj8Vcb4pTrxCfWzX2qUH2jv9ks5tVDMBgaJpZM4RxknP.

For the record, the submitted change produces errors of the form

cannot use promoted field B.A.a as key in struct literal of type C

Was this page helpful?
0 / 5 - 0 ratings