Skip to content

Commit 9df9ee9

Browse files
committed
[docs] LibraryEvolution: Weaken "fixed-layout" structs to "fixed-contents".
This drops the requirement that a fixed-layout struct only contain fixed-size things (which wasn't specified correctly anyway). Slava and Dmitri both pointed out that the previous definition had several flaws, including not really scaling to generics. This reduced version only promises that stored instance properties won't be added, removed, or modified, which is still enough to do useful optimizations. And in most cases, we'll be able to infer the full "fixed-size" property of a type from this attribute anyway. The name "fixed-contents" was chosen to force us to pick a better name later. The next commit will bring back the "fixed-size" property as a performance assertion.
1 parent 812dbbb commit 9df9ee9

File tree

1 file changed

+44
-52
lines changed

1 file changed

+44
-52
lines changed

docs/LibraryEvolution.rst

Lines changed: 44 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -274,7 +274,7 @@ are a few common reasons for this:
274274
save the overhead of a cross-library function call and allow further
275275
optimization of callers.
276276

277-
- The function accesses a fixed-layout struct with non-public members; this
277+
- The function accesses a fixed-contents struct with non-public members; this
278278
allows the library author to preserve invariants while still allowing
279279
efficient access to the struct.
280280

@@ -472,7 +472,7 @@ layout.
472472

473473
.. admonition:: TODO
474474

475-
We need to pin down how this, and the ``@fixed_layout`` attribute below,
475+
We need to pin down how this, and the ``@fixed_contents`` attribute below,
476476
interacts with the "Behaviors" proposal. Behaviors that just change the
477477
accessors of a property are fine, but those that provide new entry points
478478
are trickier.
@@ -522,45 +522,43 @@ declare themselves to be either more or less available than what the extension
522522
provides.
523523

524524

525-
Fixed-layout Structs
526-
--------------------
525+
Fixed-Contents Structs
526+
----------------------
527527

528-
To opt out of this flexibility, a struct may be marked ``@fixed_layout``. This
529-
promises that no stored properties will be added to or removed from the struct,
530-
even ``private`` or ``internal`` ones. In effect:
528+
To opt out of this flexibility, a struct may be marked ``@fixed_contents``.
529+
This promises that no stored properties will be added to or removed from the
530+
struct, even ``private`` or ``internal`` ones. Additionally, all versioned
531+
stored properties in a ``@fixed_contents`` struct are implicitly declared
532+
``@inlineable`` (as described above for top-level variables). In effect:
531533

532534
- Reordering stored instance properties relative to one another is not
533535
permitted. Reordering all other members is still permitted.
534536
- Adding new stored instance properties (public or non-public) is not permitted.
535537
Adding any other new members is still permitted.
536538
- Existing instance properties may not be changed from stored to computed or
537539
vice versa.
538-
- Changing the body of any *existing* methods, initializers, or computed
539-
property accessors is permitted. Changing the body of a stored property
540-
observing accessor is *not* permitted; more discussion below.
541-
- Adding or removing observing accessors from any stored properties (public or
542-
non-public) is not permitted; more discussion below.
540+
- Changing the body of any *existing* methods, initializers, computed property
541+
accessors, or non-instance stored property accessors is permitted. Changing
542+
the body of a stored instance property observing accessor is only permitted
543+
if the property is not `versioned <versioned entity>`.
544+
- Adding or removing observing accessors from any
545+
`versioned <versioned entity>` stored instance properties (public or
546+
non-public) is not permitted.
543547
- Removing stored instance properties is not permitted. Removing any other
544548
non-public, non-versioned members is still permitted.
545549
- Adding a new protocol conformance is still permitted.
546550
- Removing conformances to non-public protocols is still permitted.
547551

548-
In addition, all fields of a ``@fixed_layout`` struct must have types that are
549-
*fixed-layout-compatible*, as described below:
550-
551-
- A reference to a class instance.
552-
- A protocol or protocol composition, including ``Any``.
553-
- A metatype.
554-
- A function.
555-
- A tuple of fixed-layout-compatible types, including the empty tuple.
556-
- Another fixed-layout struct, which must be `versioned <versioned entity>`.
557-
- A `closed enum <#closed-enums>`_, which must be
558-
`versioned <versioned entity>`.
559-
- (advanced) A struct or enum that is `versioned <versioned entity>`,
560-
guaranteed `trivial`, and has a maximum size. See `Other Promises About
561-
Types`_ below.
562-
563-
A ``@fixed_layout`` struct is *not* guaranteed to use the same layout as a C
552+
Additionally, if the type of any stored instance property includes a struct or
553+
enum, that struct or enum must be `versioned <versioned entity>`. This includes
554+
generic parameters and members of tuples.
555+
556+
.. note::
557+
558+
This name is intentionally awful to encourage us to come up with a better
559+
one.
560+
561+
A ``@fixed_contents`` struct is *not* guaranteed to use the same layout as a C
564562
struct with a similar "shape". If such a struct is necessary, it should be
565563
defined in a C header and imported into Swift.
566564

@@ -570,34 +568,28 @@ defined in a C header and imported into Swift.
570568
equivalent, but this feature should not restrict Swift from doing useful
571569
things like minimizing member padding.
572570

573-
All versioned stored properties in a fixed-layout struct are implicitly
574-
declared ``@inlineable`` (as described above for top-level variables).
575-
Non-versioned stored properties may be accessed from inlineable functions only
576-
if they do not have observing accessors. These rules are the source of the
577-
restrictions on modifying accessors described above.
578-
579571
.. note::
580572

581-
It would be possible to say that a ``@fixed_layout`` struct only guarantees
582-
the struct's total allocation size and how to copy it, while leaving all
583-
property accesses to go through function calls. This would allow stored
584-
properties to change their accessors, or (with the Behaviors proposal) to
585-
change a behavior's implementation, or change from one behavior to another.
586-
However, the *most common case* here is probably just a simple C-like
587-
struct that groups together simple values, with only public stored
588-
properties and no observing accessors, and having to opt into direct access
589-
to those properties seems unnecessarily burdensome. The struct is being
590-
declared ``@fixed_layout`` for a reason, after all: it's been discovered
591-
that its use is causing performance issues.
573+
It would be possible to say that a ``@fixed_contents`` struct only
574+
guarantees the "shape" of the struct, so to speak, while
575+
leaving all property accesses to go through function calls. This would
576+
allow stored properties to change their accessors, or (with the Behaviors
577+
proposal) to change a behavior's implementation, or change from one
578+
behavior to another. However, the *most common case* here is probably just
579+
a simple C-like struct that groups together simple values, with only public
580+
stored properties and no observing accessors, and having to opt into direct
581+
access to those properties seems unnecessarily burdensome. The struct is
582+
being declared ``@fixed_contents`` for a reason, after all: it's been
583+
discovered that its use is causing performance issues.
592584

593585
Consequently, as a first pass we may just require all stored properties in
594-
a ``@fixed_layout`` struct, public or non-public, to have trivial
586+
a ``@fixed_contents`` struct, public or non-public, to have trivial
595587
accessors, i.e. no observing accessors and no behaviors.
596588

597-
The ``@fixed_layout`` attribute takes a version number, just like
589+
The ``@fixed_contents`` attribute takes a version number, just like
598590
``@available``. This is so that clients can deploy against older versions of
599591
the library, which may have a different layout for the struct. (In this case
600-
the client must manipulate the struct as if the ``@fixed_layout`` attribute
592+
the client must manipulate the struct as if the ``@fixed_contents`` attribute
601593
were absent.)
602594

603595
.. admonition:: TODO
@@ -788,7 +780,7 @@ Possible Restrictions on Classes
788780
--------------------------------
789781

790782
In addition to ``final``, it may be useful to restrict the size of a class
791-
instance (like a struct's ``@fixed_layout``) or the number of overridable
783+
instance (like a struct's ``@fixed_contents``) or the number of overridable
792784
members in its virtual dispatch table. These annotations have not been designed.
793785

794786

@@ -842,7 +834,7 @@ A Unifying Theme
842834

843835
So far this proposal has talked about ways to give up flexibility for several
844836
different kinds of declarations: ``@inlineable`` for functions,
845-
``@fixed_layout`` for structs, etc. Each of these has a different set of
837+
``@fixed_contents`` for structs, etc. Each of these has a different set of
846838
constraints it enforces on the library author and promises it makes to clients.
847839
However, they all follow a common theme of giving up the flexibility of future
848840
changes in exchange for improved performance and perhaps some semantic
@@ -898,7 +890,7 @@ code is reorganized, which is unacceptable.
898890
keep things simple we'll stick with the basics.
899891

900892
We could do away with the entire feature if we restricted inlineable functions
901-
and fixed-layout structs to only refer to public entities. However, this
893+
and fixed-contents structs to only refer to public entities. However, this
902894
removes one of the primary reasons to make something inlineable: to allow
903895
efficient access to a type while still protecting its invariants.
904896

@@ -1048,7 +1040,7 @@ for verification. Important cases include but are not limited to:
10481040
Flexibility`_ section.
10491041

10501042
- Unsafe modifications to entities marked with the "fragile" attributes, such as
1051-
adding a stored property to a ``@fixed_layout`` struct.
1043+
adding a stored property to a ``@fixed_contents`` struct.
10521044

10531045

10541046
Automatic Versioning

0 commit comments

Comments
 (0)