-
Notifications
You must be signed in to change notification settings - Fork 18.4k
Description
go version devel +c26aedbdde Fri Sep 15 11:28:52 2017 -0400 linux/amd64
Motivation
In #13467, I am attempting to use aliases of struct types to define mutually-assignable struct types in separate packages.
Because those struct types must match the layout of C structs, they use blank-named struct fields for padding and alignment. The spec mostly supports usage of blank-fields-as-padding (emphasis mine):
- “Two struct values are equal if their corresponding non-blank fields are equal.”
- “Within a struct, non-blank field names must be unique.”
The spec even gives an example of this padding use-case:
// A struct with 6 fields.
struct {
x, y int
u float32
_ float32 // padding
A *[]int
F func()
}
Unfortunately, the rule for type identity does not respect the padding use-case (emphasis mine):
“Two struct types are identical if they have the same sequence of fields, and if corresponding fields have the same names, and identical types, and identical tags. Non-exported field names from different packages are always different.”
That implies that otherwise-identical structs with blank fields for alignment are treated as non-identical. For example, if two different packages define this type alias:
type S = struct {
X byte
_ [7]byte // padding
Y int32
}
it will result in types that are not mutually-assignable, despite sharing the same layout and accessible fields and producing otherwise-equal values.
Proposal
To remedy this problem, I propose a minor change to the rule for type identity:
“Two struct types are identical if they have the same sequence of fields, and if corresponding fields have the same names, and identical types, and identical tags. Non-exported, non-blank field names from different packages are always different.”