Skip to content

Commit 6c2645a

Browse files
committed
[docs] LibraryEvolution: make it a little more friendly
- Move the original intro into a "Background" section - Link to SE-0193 (@inlinable) and SE-0260 (@Frozen) - Note (suggested by @Gankra) on why it's safe to add stored properties to a struct - Remove some bits that reference the content removed in earlier commits - Other minor copyediting
1 parent 0b6d0be commit 6c2645a

File tree

1 file changed

+56
-59
lines changed

1 file changed

+56
-59
lines changed

docs/LibraryEvolution.rst

Lines changed: 56 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -3,18 +3,42 @@
33
.. default-role:: term
44
.. title:: Library Evolution Support in Swift ("Resilience")
55

6-
:Author: Jordan Rose
7-
:Author: John McCall
8-
96
.. note::
107

118
This document uses some Sphinx-specific features which are not available on
12-
GitHub. For proper rendering, download and build the docs yourself. Jordan
13-
Rose also posts occasional snapshots at
14-
https://jrose-apple.github.io/swift-library-evolution/.
9+
GitHub. For proper rendering, download and build the docs yourself.
10+
11+
Since Swift 5, ABI-stable platforms have supported `library evolution`_, the
12+
ability to change a library without breaking source or binary compatibility.
13+
This model is intended to serve library designers whose libraries will evolve
14+
over time. Such libraries must be both `backwards-compatible`, meaning that
15+
existing clients should continue to work even when the library is updated, and
16+
`forwards-compatible`, meaning that future clients will be able run using the
17+
current version of the library. In simple terms:
18+
19+
- Last year's apps should work with this year's library.
20+
- Next year's apps should work with this year's library.
1521

16-
One of Swift's primary design goals is to allow efficient execution of code
17-
without sacrificing load-time abstraction of implementation.
22+
This document is intended to be a specification for *which* changes can be made
23+
without breaking binary compatibility. When a library author wants to make a
24+
change, they can jump to the relevant section of this document to see if it's
25+
allowed. Anything *not* listed in this document should be assumed unsafe, i.e.
26+
changing it will break binary compatibility.
27+
28+
Library evolution was formally described in `SE-0260 <SE0260_>`_, but this
29+
document should be kept up to date as new features are added to the language.
30+
31+
.. _library evolution: https://swift.org/blog/abi-stability-and-more/
32+
.. _SE0260: https://github.com/apple/swift-evolution/blob/master/proposals/0260-library-evolution.md
33+
34+
.. contents:: :local:
35+
36+
37+
Background
38+
==========
39+
40+
One of Swift's primary design goals has always been to allow efficient
41+
execution of code without sacrificing load-time abstraction of implementation.
1842

1943
Abstraction of implementation means that code correctly written against a
2044
published interface will correctly function when the underlying implementation
@@ -49,24 +73,14 @@ This last point is a specific case of a general tenet of Swift: **the default
4973
behavior is safe**. Where possible, choices made when an entity is first
5074
published should not limit its evolution in the future.
5175

52-
.. contents:: :local:
53-
5476

5577
Introduction
5678
============
5779

58-
This model is intended to serve library designers whose libraries will evolve
59-
over time. Such libraries must be both `backwards-compatible`, meaning that
60-
existing clients should continue to work even when the library is updated, and
61-
`forwards-compatible`, meaning that future clients will be able run using the
62-
current version of the library. In simple terms:
63-
64-
- Last year's apps should work with this year's library.
65-
- Next year's apps should work with this year's library.
66-
6780
This document will frequently refer to a *library* which vends public APIs, and
6881
a single *client* that uses them. The same principles apply even when multiple
69-
libraries and multiple clients are involved.
82+
libraries and multiple clients are involved. It also uses the term `ABI-public`
83+
introduced in `SE-0193 <SE0193_>`_.
7084

7185
This document is primarily concerned with `binary compatibility`, i.e. what
7286
changes can safely be made to a library between releases that will not break
@@ -94,15 +108,15 @@ with a single app target are not forced to think about access control, anyone
94108
writing a bundled library should (ideally) not be required to use any of the
95109
annotations described below in order to achieve full performance.
96110

111+
.. _SE0193: https://github.com/apple/swift-evolution/blob/master/proposals/0193-cross-module-inlining-and-specialization.md
97112
.. _Swift Package Manager: https://swift.org/package-manager/
98113

99114
.. note::
100115

101116
This model may, however, be useful for library authors that want to
102-
preserve *source* compatibility, and it is hoped that the tool for
103-
`Checking Binary Compatibility`_ described below will also be useful for
104-
this purpose. Additionally, we may decide to use some of these annotations
105-
as performance hints for *non-*\ optimized builds.
117+
preserve *source* compatibility, though this document mostly doesn't
118+
discuss that. Additionally, some of these annotations are useful for
119+
performance today, such as ``@inlinable``.
106120

107121
The term "resilience" comes from the occasional use of "fragile" to describe
108122
certain constructs that have very strict binary compatibility rules. For
@@ -119,9 +133,6 @@ This section describes the various changes that are safe to make when releasing
119133
a new version of a library, i.e. changes that will not break binary
120134
compatibility. They are organized by declaration type.
121135

122-
Anything *not* listed in this document should be assumed unsafe.
123-
124-
125136
Top-Level Functions
126137
~~~~~~~~~~~~~~~~~~~
127138

@@ -155,10 +166,11 @@ No other changes are permitted; the following are particularly of note:
155166
Inlinable Functions
156167
-------------------
157168

158-
Functions are a very common example of resilience: the function's declaration
159-
is published as API, but its body may change between library versions as long
160-
as it upholds the same semantic contracts. This applies to other function-like
161-
constructs as well: initializers, accessors, and deinitializers.
169+
Functions are a very common example of "abstraction of implementation": the
170+
function's declaration is published as API, but its body may change between
171+
library versions as long as it upholds the same semantic contracts. This
172+
applies to other function-like constructs as well: initializers, accessors, and
173+
deinitializers.
162174

163175
However, sometimes it is useful to provide the body to clients as well. There
164176
are a few common reasons for this:
@@ -317,12 +329,6 @@ This restricts changes a fair amount:
317329
- Changing the body of an accessor is a `binary-compatible source-breaking
318330
change`.
319331

320-
.. admonition:: TODO
321-
322-
It Would Be Nice(tm) to allow marking the *getter* of a top-level variable
323-
inlinable while still allowing the setter to change. This would need
324-
syntax, though.
325-
326332
Any inlinable accessors must follow the rules for `inlinable functions`_, as
327333
described above.
328334

@@ -351,7 +357,10 @@ the following changes are permitted:
351357
- Adding ``@dynamicCallable`` to the struct.
352358

353359
The important most aspect of a Swift struct is its value semantics, not its
354-
layout.
360+
layout. Note that adding a stored property to a struct is *not* a breaking
361+
change even with Swift's synthesis of memberwise and no-argument initializers;
362+
these initializers are always ``internal`` and thus not exposed to clients
363+
outside the module.
355364

356365
It is not safe to add or remove ``mutating`` or ``nonmutating`` from a member
357366
or accessor within a struct.
@@ -866,6 +875,8 @@ the compiler must assume that new overrides may eventually appear from outside
866875
the module if the class is marked ``open`` unless the member is marked
867876
``final``.
868877

878+
For more information, see `SE-0193 <SE0193_>`_.
879+
869880

870881
Optimization
871882
============
@@ -897,12 +908,12 @@ current module, since once it's inlined it will be.
897908
Summary
898909
=======
899910

900-
When possible, Swift gives library authors freedom to evolve their code
901-
without breaking binary compatibility. This has implications for both the
902-
semantics and performance of client code, and so library owners also have tools
903-
to waive the ability to make certain future changes. The language guarantees
904-
that client code will never accidentally introduce implicit dependencies on
905-
specific versions of libraries.
911+
When possible, Swift gives library authors freedom to evolve their code without
912+
breaking binary compatibility. This has implications for both the semantics and
913+
performance of client code, and so library owners also have tools to waive the
914+
ability to make certain future changes. When shipping libraries as part of the
915+
OS, the availability model guarantees that client code will never accidentally
916+
introduce implicit dependencies on specific versions of libraries.
906917

907918

908919
Glossary
@@ -918,20 +929,14 @@ Glossary
918929
ABI-public
919930
Describes entities that are part of a library's `ABI`. Marked ``public``,
920931
``open``, ``@usableFromInline``, or ``@inlinable`` in Swift. See
921-
`SE-0193 <SE0193>`_ for more information.
932+
`SE-0193 <SE0193_>`_ for more information.
922933

923934
API
924935
An `entity` in a library that a `client` may use, or the collection of all
925936
such entities in a library. (If contrasting with `SPI`, only those entities
926937
that are available to arbitrary clients.) Marked ``public`` or ``open`` in
927938
Swift. Stands for "Application Programming Interface".
928939

929-
availability context
930-
The collection of library and platform versions that can be assumed, at
931-
minimum, to be present in a certain block of code. Availability contexts
932-
are always properly nested, and the global availability context includes
933-
the module's minimum deployment target and minimum dependency versions.
934-
935940
backwards-compatible
936941
A modification to an API that does not break existing clients. May also
937942
describe the API in question.
@@ -974,14 +979,6 @@ Glossary
974979
The primary unit of code sharing in Swift. Code in a module is always built
975980
together, though it may be spread across several source files.
976981

977-
performance assertion
978-
See `Other Promises About Types`_.
979-
980-
resilience domain
981-
A grouping for code that will always be recompiled and distributed
982-
together, and can thus take advantage of details about a type
983-
even if it changes in the future.
984-
985982
SPI
986983
A subset of `API` that is only available to certain clients. Stands for
987984
"System Programming Interface".

0 commit comments

Comments
 (0)