Skip to content

Commit f3c073d

Browse files
committed
Track 'release/5.5' to resolve merge conflicts.
2 parents 2af42d7 + a6346f8 commit f3c073d

File tree

231 files changed

+4720
-1802
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

231 files changed

+4720
-1802
lines changed

CHANGELOG.md

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,69 @@ CHANGELOG
2929
Swift 5.5
3030
---------
3131

32+
* [SE-0310][]:
33+
34+
Read-only computed properties and subscripts can now define their `get` accessor to be `async` and/or `throws`, by writing one or both of those keywords between the `get` and `{`. Thus, these members can now make asynchronous calls or throw errors in the process of producing a value:
35+
```swift
36+
class BankAccount: FinancialAccount {
37+
var manager: AccountManager?
38+
39+
var lastTransaction: Transaction {
40+
get async throws {
41+
guard manager != nil else { throw BankError.notInYourFavor }
42+
return await manager!.getLastTransaction()
43+
}
44+
}
45+
46+
subscript(_ day: Date) -> [Transaction] {
47+
get async {
48+
return await manager?.getTransactions(onDay: day) ?? []
49+
}
50+
}
51+
}
52+
53+
protocol FinancialAccount {
54+
associatedtype T
55+
var lastTransaction: T { get async throws }
56+
subscript(_ day: Date) -> [T] { get async }
57+
}
58+
```
59+
Accesses to such members, like `lastTransaction` above, will require appropriate marking with `await` and/or `try`:
60+
```swift
61+
extension BankAccount {
62+
func meetsTransactionLimit(_ limit: Amount) async -> Bool {
63+
return try! await self.lastTransaction.amount < limit
64+
// ^~~~~~~~~~~~~~~~ this access is async & throws
65+
}
66+
}
67+
68+
69+
func hadWithdrawlOn(_ day: Date, from acct: BankAccount) async -> Bool {
70+
return await !acct[day].allSatisfy { $0.amount >= Amount.zero }
71+
// ^~~~~~~~~ this access is async
72+
}
73+
```
74+
75+
76+
* [SE-0306][]:
77+
78+
Swift 5.5 includes support for actors, a new kind of type that isolates its instance data to protect it from concurrent access. Accesses to an actor's instance declarations from outside the must be asynchronous:
79+
80+
```swift
81+
actor Counter {
82+
var value = 0
83+
84+
func increment() {
85+
value = value + 1
86+
}
87+
}
88+
89+
func useCounter(counter: Counter) async {
90+
print(await counter.value) // interaction must be async
91+
await counter.increment() // interaction must be async
92+
}
93+
```
94+
3295
* The determination of whether a call to a `rethrows` function can throw now considers default arguments of `Optional` type.
3396

3497
In Swift 5.4, such default arguments were ignored entirely by `rethrows` checking. This meant that the following example was accepted:
@@ -8434,6 +8497,8 @@ Swift 1.0
84348497
[SE-0297]: <https://github.com/apple/swift-evolution/blob/main/proposals/0297-concurrency-objc.md>
84358498
[SE-0298]: <https://github.com/apple/swift-evolution/blob/main/proposals/0298-asyncsequence.md>
84368499
[SE-0299]: <https://github.com/apple/swift-evolution/blob/main/proposals/0299-extend-generic-static-member-lookup.md>
8500+
[SE-0306]: <https://github.com/apple/swift-evolution/blob/main/proposals/0306-actors.md>
8501+
[SE-0310]: <https://github.com/apple/swift-evolution/blob/main/proposals/0310-effectful-readonly-properties.md>
84378502

84388503
[SR-75]: <https://bugs.swift.org/browse/SR-75>
84398504
[SR-106]: <https://bugs.swift.org/browse/SR-106>

CODEOWNERS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
* @apple/swift5-branch-managers

include/swift/ABI/Metadata.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4290,6 +4290,10 @@ class TargetClassDescriptor final
42904290
return FieldOffsetVectorOffset;
42914291
}
42924292

4293+
bool isActor() const {
4294+
return this->getTypeContextDescriptorFlags().class_isActor();
4295+
}
4296+
42934297
bool isDefaultActor() const {
42944298
return this->getTypeContextDescriptorFlags().class_isDefaultActor();
42954299
}

include/swift/ABI/MetadataValues.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1389,6 +1389,11 @@ class TypeContextDescriptorFlags : public FlagSet<uint16_t> {
13891389

13901390
// Type-specific flags:
13911391

1392+
/// Set if the class is an actor.
1393+
///
1394+
/// Only meaningful for class descriptors.
1395+
Class_IsActor = 7,
1396+
13921397
/// Set if the class is a default actor class. Note that this is
13931398
/// based on the best knowledge available to the class; actor
13941399
/// classes with resilient superclassess might be default actors
@@ -1479,6 +1484,9 @@ class TypeContextDescriptorFlags : public FlagSet<uint16_t> {
14791484
FLAGSET_DEFINE_FLAG_ACCESSORS(Class_IsDefaultActor,
14801485
class_isDefaultActor,
14811486
class_setIsDefaultActor)
1487+
FLAGSET_DEFINE_FLAG_ACCESSORS(Class_IsActor,
1488+
class_isActor,
1489+
class_setIsActor)
14821490

14831491
FLAGSET_DEFINE_FIELD_ACCESSORS(Class_ResilientSuperclassReferenceKind,
14841492
Class_ResilientSuperclassReferenceKind_width,
@@ -2001,6 +2009,7 @@ class JobFlags : public FlagSet<size_t> {
20012009
Task_IsChildTask = 24,
20022010
Task_IsFuture = 25,
20032011
Task_IsGroupChildTask = 26,
2012+
Task_IsContinuingAsyncTask = 27,
20042013
};
20052014

20062015
explicit JobFlags(size_t bits) : FlagSet(bits) {}
@@ -2030,6 +2039,9 @@ class JobFlags : public FlagSet<size_t> {
20302039
FLAGSET_DEFINE_FLAG_ACCESSORS(Task_IsGroupChildTask,
20312040
task_isGroupChildTask,
20322041
task_setIsGroupChildTask)
2042+
FLAGSET_DEFINE_FLAG_ACCESSORS(Task_IsContinuingAsyncTask,
2043+
task_isContinuingAsyncTask,
2044+
task_setIsContinuingAsyncTask)
20332045
};
20342046

20352047
/// Kinds of task status record.

include/swift/ABI/Task.h

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ class alignas(2 * alignof(void*)) Job : public HeapObject {
4747
NextWaitingTaskIndex = 0,
4848

4949
// The Dispatch object header is one pointer and two ints, which is
50-
// equvialent to three pointers on 32-bit and two pointers 64-bit. Set the
50+
// equivalent to three pointers on 32-bit and two pointers 64-bit. Set the
5151
// indexes accordingly so that DispatchLinkageIndex points to where Dispatch
5252
// expects.
5353
DispatchHasLongObjectHeader = sizeof(void *) == sizeof(int),
@@ -217,14 +217,13 @@ class AsyncTask : public Job {
217217

218218
// ==== Task Local Values ----------------------------------------------------
219219

220-
void localValuePush(const Metadata *keyType,
220+
void localValuePush(const HeapObject *key,
221221
/* +1 */ OpaqueValue *value, const Metadata *valueType) {
222-
Local.pushValue(this, keyType, value, valueType);
222+
Local.pushValue(this, key, value, valueType);
223223
}
224224

225-
OpaqueValue* localValueGet(const Metadata *keyType,
226-
TaskLocal::TaskLocalInheritance inherit) {
227-
return Local.getValue(this, keyType, inherit);
225+
OpaqueValue* localValueGet(const HeapObject *key) {
226+
return Local.getValue(this, key);
228227
}
229228

230229
void localValuePop() {

include/swift/ABI/TaskLocal.h

Lines changed: 20 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -34,73 +34,50 @@ class TaskLocal {
3434
public:
3535
/// Type of the pointed at `next` task local item.
3636
enum class NextLinkType : uintptr_t {
37-
/// This task is known to be a "terminal" node in the lookup of task locals.
38-
/// In other words, even if it had a parent, the parent (and its parents)
39-
/// are known to not contain any any more task locals, and thus any further
40-
/// search beyond this task.
41-
IsTerminal = 0b00,
4237
/// The storage pointer points at the next TaskLocal::Item in this task.
43-
IsNext = 0b01,
38+
IsNext = 0b00,
4439
/// The storage pointer points at a item stored by another AsyncTask.
4540
///
4641
/// Note that this may not necessarily be the same as the task's parent
4742
/// task -- we may point to a super-parent if we know / that the parent
4843
/// does not "contribute" any task local values. This is to speed up
4944
/// lookups by skipping empty parent tasks during get(), and explained
5045
/// in depth in `createParentLink`.
51-
IsParent = 0b11
52-
};
53-
54-
/// Values must match `TaskLocalInheritance` declared in `TaskLocal.swift`.
55-
enum class TaskLocalInheritance : uint8_t {
56-
/// Default task local value behavior
57-
///
58-
/// Values declared with a default-inherited key are accessible from:
59-
/// - the current task that has bound the value,
60-
/// - any child task of the current task (e.g. created by async let or groups)
61-
///
62-
/// Such values are *not* carried through detached tasks.
63-
Default = 0,
64-
65-
/// Special semantics which confine a task's local value to *only* the current
66-
/// task. In other words, they ave never inherited by any child task created
67-
/// by the current task.
68-
///
69-
/// Values declared with a never-inherited key only accessible:
70-
/// - specifically from the current task itself
71-
///
72-
/// Such values are *not* accessible from child tasks or detached tasks.
73-
Never = 1
46+
IsParent = 0b01,
7447
};
7548

7649
class Item {
7750
private:
7851
/// Mask used for the low status bits in a task local chain item.
7952
static const uintptr_t statusMask = 0x03;
8053

81-
/// Pointer to the next task local item; be it in this task or in a parent.
82-
/// Low bits encode `NextLinkType`.
83-
/// Item *next = nullptr;
54+
/// Pointer to one of the following:
55+
/// - next task local item as OpaqueValue* if it is task-local allocated
56+
/// - next task local item as HeapObject* if it is heap allocated "heavy"
57+
/// - the parent task's TaskLocal::Storage
58+
///
59+
/// Low bits encode `NextLinkType`, based on which the type of the pointer
60+
/// is determined.
8461
uintptr_t next;
8562

8663
public:
8764
/// The type of the key with which this value is associated.
88-
const Metadata *keyType;
65+
const HeapObject *key;
8966
/// The type of the value stored by this item.
9067
const Metadata *valueType;
9168

9269
// Trailing storage for the value itself. The storage will be
9370
// uninitialized or contain an instance of \c valueType.
9471

95-
private:
72+
protected:
9673
explicit Item()
9774
: next(0),
98-
keyType(nullptr),
75+
key(nullptr),
9976
valueType(nullptr) {}
10077

101-
explicit Item(const Metadata *keyType, const Metadata *valueType)
78+
explicit Item(const HeapObject *key, const Metadata *valueType)
10279
: next(0),
103-
keyType(keyType),
80+
key(key),
10481
valueType(valueType) {}
10582

10683
public:
@@ -116,7 +93,7 @@ class TaskLocal {
11693
static Item *createParentLink(AsyncTask *task, AsyncTask *parent);
11794

11895
static Item *createLink(AsyncTask *task,
119-
const Metadata *keyType,
96+
const HeapObject *key,
12097
const Metadata *valueType);
12198

12299
void destroy(AsyncTask *task);
@@ -125,13 +102,13 @@ class TaskLocal {
125102
return reinterpret_cast<Item *>(next & ~statusMask);
126103
}
127104

128-
NextLinkType getNextLinkType() {
105+
NextLinkType getNextLinkType() const {
129106
return static_cast<NextLinkType>(next & statusMask);
130107
}
131108

132109
/// Item does not contain any actual value, and is only used to point at
133110
/// a specific parent item.
134-
bool isEmpty() {
111+
bool isEmpty() const {
135112
return !valueType;
136113
}
137114

@@ -144,6 +121,7 @@ class TaskLocal {
144121
/// Compute the offset of the storage from the base of the item.
145122
static size_t storageOffset(const Metadata *valueType) {
146123
size_t offset = sizeof(Item);
124+
147125
if (valueType) {
148126
size_t alignment = valueType->vw_alignment();
149127
return (offset + alignment - 1) & ~(alignment - 1);
@@ -162,7 +140,6 @@ class TaskLocal {
162140
}
163141
};
164142

165-
166143
class Storage {
167144
friend class TaskLocal::Item;
168145
private:
@@ -202,12 +179,10 @@ class TaskLocal {
202179
void initializeLinkParent(AsyncTask *task, AsyncTask *parent);
203180

204181
void pushValue(AsyncTask *task,
205-
const Metadata *keyType,
182+
const HeapObject *key,
206183
/* +1 */ OpaqueValue *value, const Metadata *valueType);
207184

208-
OpaqueValue* getValue(AsyncTask *task,
209-
const Metadata *keyType,
210-
TaskLocalInheritance inheritance);
185+
OpaqueValue* getValue(AsyncTask *task, const HeapObject *key);
211186

212187
void popValue(AsyncTask *task);
213188

include/swift/AST/ASTContext.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@ namespace swift {
7373
class DerivativeAttr;
7474
class DifferentiableAttr;
7575
class ExtensionDecl;
76+
struct ExternalSourceLocs;
7677
class ForeignRepresentationInfo;
7778
class FuncDecl;
7879
class GenericContext;
@@ -1170,6 +1171,10 @@ class ASTContext final {
11701171

11711172
private:
11721173
friend Decl;
1174+
1175+
Optional<ExternalSourceLocs *> getExternalSourceLocs(const Decl *D);
1176+
void setExternalSourceLocs(const Decl *D, ExternalSourceLocs *Locs);
1177+
11731178
Optional<std::pair<RawComment, bool>> getRawComment(const Decl *D);
11741179
void setRawComment(const Decl *D, RawComment RC, bool FromSerialized);
11751180

include/swift/AST/Attr.def

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -657,6 +657,12 @@ SIMPLE_DECL_ATTR(_inheritActorContext, InheritActorContext,
657657
ABIStableToAdd | ABIStableToRemove | APIBreakingToAdd | APIBreakingToRemove,
658658
116)
659659

660+
CONTEXTUAL_SIMPLE_DECL_ATTR(spawn, Spawn,
661+
DeclModifier | OnVar | ConcurrencyOnly |
662+
ABIBreakingToAdd | ABIBreakingToRemove |
663+
APIBreakingToAdd | APIBreakingToRemove,
664+
117)
665+
660666
#undef TYPE_ATTR
661667
#undef DECL_ATTR_ALIAS
662668
#undef CONTEXTUAL_DECL_ATTR_ALIAS

include/swift/AST/Attr.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2077,9 +2077,10 @@ class CompletionHandlerAsyncAttr final : public DeclAttribute {
20772077
CompletionHandlerAsyncAttr(AbstractFunctionDecl &asyncFunctionDecl,
20782078
size_t completionHandlerIndex,
20792079
SourceLoc completionHandlerIndexLoc,
2080-
SourceLoc atLoc, SourceRange range)
2080+
SourceLoc atLoc, SourceRange range,
2081+
bool implicit)
20812082
: DeclAttribute(DAK_CompletionHandlerAsync, atLoc, range,
2082-
/*implicit*/ false),
2083+
implicit),
20832084
AsyncFunctionDecl(&asyncFunctionDecl) ,
20842085
CompletionHandlerIndex(completionHandlerIndex),
20852086
CompletionHandlerIndexLoc(completionHandlerIndexLoc) {}

include/swift/AST/Decl.h

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ namespace swift {
6262
class DynamicSelfType;
6363
class Type;
6464
class Expr;
65+
struct ExternalSourceLocs;
6566
class CaptureListExpr;
6667
class DeclRefExpr;
6768
class ForeignAsyncConvention;
@@ -688,14 +689,12 @@ class alignas(1 << DeclAlignInBits) Decl {
688689
void operator=(const Decl&) = delete;
689690
SourceLoc getLocFromSource() const;
690691

691-
struct CachedExternalSourceLocs {
692-
SourceLoc Loc;
693-
SourceLoc StartLoc;
694-
SourceLoc EndLoc;
695-
SmallVector<CharSourceRange, 4> DocRanges;
696-
};
697-
mutable CachedExternalSourceLocs const *CachedSerializedLocs = nullptr;
698-
const CachedExternalSourceLocs *getSerializedLocs() const;
692+
/// Returns the serialized locations of this declaration from the
693+
/// corresponding .swiftsourceinfo file. "Empty" (ie. \c BufferID of 0, an
694+
/// invalid \c Loc, and empty \c DocRanges) if either there is no
695+
/// .swiftsourceinfo or the buffer could not be created, eg. if the file
696+
/// no longer exists.
697+
const ExternalSourceLocs *getSerializedLocs() const;
699698

700699
/// Directly set the invalid bit
701700
void setInvalidBit();
@@ -1863,7 +1862,7 @@ class PatternBindingDecl final : public Decl,
18631862
bool isComputingPatternBindingEntry(const VarDecl *vd) const;
18641863

18651864
/// Is this an "async let" declaration?
1866-
bool isAsyncLet() const;
1865+
bool isSpawnLet() const;
18671866

18681867
/// Gets the text of the initializer expression for the pattern entry at the
18691868
/// given index, stripping out inactive branches of any #ifs inside the
@@ -4943,7 +4942,7 @@ class VarDecl : public AbstractStorageDecl {
49434942
bool isLet() const { return getIntroducer() == Introducer::Let; }
49444943

49454944
/// Is this an "async let" property?
4946-
bool isAsyncLet() const;
4945+
bool isSpawnLet() const;
49474946

49484947
Introducer getIntroducer() const {
49494948
return Introducer(Bits.VarDecl.Introducer);

0 commit comments

Comments
 (0)