This FTP is rejected
However, all concerned felt this was far outweighed by the confusion that introducing ordinals on structs would add, especially when compared to protobufs.
There are other efforts addressing “does this change ABI”, namely:
Name matters for text formats (JSON, FIDLText, etc.), and when messages are used in this context, name changes cannot occur.
Update to Struct Declarations
Field | Value |
---|---|
Status | Rejected |
Authors | pascallouis@google.com |
Submitted | 2019-03-07 |
Reviewed | 2019-03-14 |
To better convey ABI implications of re-ordering and renaming fields, we propose a syntactic change to introduce ordinals for structs fields, with similar syntactic rules then those for tables.
Focusing solely on whether members can be safely renamed or re-ordered in various declarations, we have syntactic differences which have evolved organically, and do not convey anything about ABI implications of possible changes.
Furthermore, the current struct declaration syntax makes it difficult for the compiler to provide help and guidance when changes occur.
Let's look at examples, these are chosen to be small and uniform:
struct Name { table Name { enum Name { T abc; 1: T abc; ABC = 1; U xyz; 2: U xyz; XYZ = 2; }; }; }; protocol Name { xunion Name { bits Name { Abc(T t); T abc; ABC = 1; Xyz(U u); U xyz; XYZ = 2; }; }; };
Some observations from an ABI standpoint:
(From a source compatibility standpoint, most bindings will be source compatible under re-order, and incompatible under rename.)
Informed from these observations, we propose to introduce an ordinal for struct declarations. The example above would now be:
struct Name { 1: T abc; 2: U xyz; };
Specifically:
To exemplify the guidance which the compiler can provide with the proposed syntax, we consider a few examples and compare their handling.
No Ordinals With Ordinals ---------------- ------------- struct Name { struct Name { T abc; 1: T abc; - U def; - 2: U def; V ghi; 3: V ghi; }; }; ---------------- --------------- Breaks ABI, no Breaks ABI, compiler help compiler error
No Ordinals With Ordinals ---------------- ------------- struct Name { struct Name { T abc; 1: T abc; U def; 2: U def; - V ghi; - 3: V ghi; }; }; ---------------- --------------- Breaks ABI, no Breaks ABI, no compiler help compiler help
No Ordinals With Ordinals ---------------- ------------- struct Name { struct Name { T abc; 1: T abc; + U def; + 3: U def; V ghi; 2: V ghi; }; }; ---------------- --------------- Breaks ABI, no Breaks ABI, no compiler help compiler error
No Ordinals With Ordinals ---------------- ------------- struct Name { struct Name { + U def; + 2: U def; T abc; 1: T abc; - U def; - 2: U def; V ghi; 3: V ghi; }; }; ---------------- --------------- Breaks ABI, no Safe compiler warning
Since we are aligning the ordinal rules for structs on that of tables, we could look to also allow the ‘reserved’ keyword.
We should do the exact opposite: properly parse an accidental use of the reserved keyword, and provide a clear compiler error and explanation. For instance “Cannot reserve member in structs. Adding or removing members alters a struct layout, consider instead neutral members manually initialized.”
There are also additional important reasons not to allow the ‘reserved’ keyword:
In order to both support ordering of fields (by ordinal) and ordering for documentation purposes (which should respect declaration order), it would be better to:
TBD
This proposal improves ergonomics by conveying ABI implications to developers through syntax. See an opposing view on this below.
At least:
This is not source level backwards compatible. See Implementation Strategy to soft migrate.
No impact.
No impact.
Unit testing in fidlc
to verify among others:
We also considered using ordinal hashing for tables: the syntactic change would be dropping explicit ordinals, making structs be the only declarations with this syntax (whereas it used to be on protocols and tables).
Firstly, the benefits of having explicit ordinals for structs would remain. Developers could still re-order fields syntactically, and changing an ordinal would indicate ABI breakage.
Secondly, we are unlikely to act on the exploration to remove ordinals from tables since the tradeoff between run-time cost (less performance) outweigh the ergonomic benefits.
With the syntax between struct and tables converging, and the introduction of ordinals, some may confuse structs with tables, and mistakenly believe that removing fields is ABI compatible. While removing a field in the middle of a struct would cause an error due to a gap appearing in the ordinal sequence, removing the field(s) with the largest ordinal(s) would be silent.
TBD