Skip to content

Commit 0ffe741

Browse files
Merge remote-tracking branch 'apple/main' into swiftwasm
2 parents 81a52f5 + 199c90e commit 0ffe741

20 files changed

+833
-841
lines changed

docs/AndroidBuild.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ git clone https://github.com/apple/swift-corelibs-xctest swift-corelibs-xctest
3434
git clone https://github.com/compnerd/swift-build swift-build
3535
```
3636

37-
## 1. Acquire the lastest toolchain and dependencies
37+
## 1. Acquire the latest toolchain and dependencies
3838

3939
1. Download the toolchain, ICU, libxml2, and curl for android from
4040
[Azure](https://dev.azure.com/compnerd/swift-build) into `S:\b\a\Library`.

docs/CppInteroperability/CppInteroperabilityManifesto.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -500,7 +500,7 @@ accepts an address.
500500
501501
C++ has complex overload resolution rules, in part to support certain API design
502502
patterns. Some API design patterns appeared as a consequence of overload
503-
resolution rules. Therefore, in C++ an "API atom" is an an overload set, not an
503+
resolution rules. Therefore, in C++ an "API atom" is an overload set, not an
504504
individual function ([CppCon 2018: Titus Winters "Modern C++ Design (part 1 of
505505
2)"](https://www.youtube.com/watch?v=xTdeZ4MxbKo)). The same is also the case in
506506
Swift, so, fundamentally, there is no impedance mismatch here.
@@ -938,7 +938,7 @@ be handled in Swift.
938938

939939
While it is possible to [propagate C++ exceptions](#exceptions) thrown by normal
940940
member functions to Swift code, special member functions are different as they
941-
used used to implement value witnesses, which are called by the compiler
941+
used to implement value witnesses, which are called by the compiler
942942
implicitly. Therefore, either such exceptions have to be mapped to fatal errors
943943
(as we do for other unhandled C++ exceptions), or calls to such special member
944944
functions must be prevented statically.
@@ -2337,7 +2337,7 @@ different APIs across specializations of the same class. All instantiations of a
23372337
generic type in Swift have the API described in the generic declaration (with
23382338
type parameters substituted), plus applicable conditional extensions.
23392339

2340-
C++ templates support non-type template parameters, template template
2340+
C++ templates support non-type template parameters, template
23412341
parameters, and parameter packs (variadic generics), all of which are not
23422342
supported in Swift.
23432343

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,23 @@
11
# C++ Interoperability Oddities
22

3-
C++ APIs may have slightly different behavior than other C++ APIs. This is a general catch-all document where these
3+
C++ APIs may have slightly different behavior than other C++ APIs. This is a general catch-all document where these
44
oddities are recorded along with a few other things that are good to know when using C++ interop.
55

66
**Parameters with reference types**
77

8-
Parameters that have mutable reference types are bridged as inout. Parameters with immutable reference types (const ref)
9-
are bridged as value types. ⚠️ This will change as soon as Swift has a way to represent immutable borrows. ⚠️
8+
Parameters that have mutable reference types are bridged as inout. Parameters with immutable reference types (const ref)
9+
are bridged as value types. ⚠️ This will change as soon as Swift has a way to represent immutable borrows. ⚠️
1010

1111
**Lifetimes**
1212

13-
Currently, lifetimes are extended to the end of the lexical scope if any unsafe pointers are used in that scope. TODO:
14-
this should be updated to extend lifetimes whenever a C++ type is used in that scope. Currently, if there is no
15-
unsafe pointer used in the scope, then normal Swift lifetime rules apply.
13+
Currently, lifetimes are extended to the end of the lexical scope if any unsafe pointers are used in that scope. TODO:
14+
this should be updated to extend lifetimes whenever a C++ type is used in that scope. Currently, if there is no
15+
unsafe pointer used in the scope, then normal Swift lifetime rules apply.
1616

1717
**Borrowing Self**
1818

19-
For mutating methods, self is borrowed and the access to self lasts for the duration of the call. For non-mutating
20-
methods, the access to self is currently instantanious. ⚠️ In the very near future we plan to borrow self in both cases.
19+
For mutating methods, self is borrowed and the access to self lasts for the duration of the call. For non-mutating
20+
methods, the access to self is currently instantaneous. ⚠️ In the very near future we plan to borrow self in both cases.
2121
This will be a source breaking change from what native Swift methods do. ⚠️
2222

23-
_More to come soon :)_
23+
_More to come soon :)_

docs/SILMemoryAccess.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -293,7 +293,7 @@ scope:
293293
end_access %access : $*S
294294
```
295295

296-
Note that is is possible to have a nested access scope on the address
296+
Note that it is possible to have a nested access scope on the address
297297
of a struct field, which may show up as an access of
298298
struct_element_addr after inlining. The rule is that access
299299
projections cannot occur outside of the outermost access scope within
@@ -396,7 +396,7 @@ instructions may reference the same variable. To find all global uses,
396396
the client must independently find all global variable references
397397
within the function. Clients that need to know which SILValue base was
398398
discovered during use-def traversal in all cases can make use of
399-
`AccessStorageWithBase` or `AccessPathWithBase`.
399+
`AccessStorageWithBase` or `AccessPathWithBase`.
400400

401401
### AccessPath
402402

include/swift/AST/TypeRefinementContext.h

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -58,11 +58,11 @@ class TypeRefinementContext : public ASTAllocated<TypeRefinementContext> {
5858
/// function declaration or the contents of a class declaration).
5959
Decl,
6060

61-
/// The context was introduced by a resilience boundary; that is, we are in
61+
/// The context was introduced by an API boundary; that is, we are in
6262
/// a module with library evolution enabled and the parent context's
6363
/// contents can be visible to the module's clients, but this context's
6464
/// contents are not.
65-
ResilienceBoundary,
65+
APIBoundary,
6666

6767
/// The context was introduced for the Then branch of an IfStmt.
6868
IfStmtThenBranch,
@@ -131,8 +131,7 @@ class TypeRefinementContext : public ASTAllocated<TypeRefinementContext> {
131131
}
132132

133133
Decl *getAsDecl() const {
134-
assert(IntroReason == Reason::Decl ||
135-
IntroReason == Reason::ResilienceBoundary);
134+
assert(IntroReason == Reason::Decl || IntroReason == Reason::APIBoundary);
136135
return D;
137136
}
138137

@@ -195,10 +194,8 @@ class TypeRefinementContext : public ASTAllocated<TypeRefinementContext> {
195194

196195
/// Create a refinement context for the given declaration.
197196
static TypeRefinementContext *
198-
createForResilienceBoundary(ASTContext &Ctx, Decl *D,
199-
TypeRefinementContext *Parent,
200-
const AvailabilityContext &Info,
201-
SourceRange SrcRange);
197+
createForAPIBoundary(ASTContext &Ctx, Decl *D, TypeRefinementContext *Parent,
198+
const AvailabilityContext &Info, SourceRange SrcRange);
202199

203200
/// Create a refinement context for the Then branch of the given IfStmt.
204201
static TypeRefinementContext *

lib/AST/DistributedDecl.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -472,6 +472,7 @@ bool AbstractFunctionDecl::isDistributedActorSystemRemoteCall(bool isVoidReturn)
472472
if (!invocationParam->isInOut()) {
473473
return false;
474474
}
475+
475476
// --- Check parameter: throwing: Err.Type
476477
auto thrownTypeParam = params->get(3);
477478
if (thrownTypeParam->getArgumentName() != C.Id_throwing) {

lib/AST/TypeRefinementContext.cpp

Lines changed: 11 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -64,18 +64,14 @@ TypeRefinementContext::createForDecl(ASTContext &Ctx, Decl *D,
6464
TypeRefinementContext(Ctx, D, Parent, SrcRange, Info, ExplicitInfo);
6565
}
6666

67-
TypeRefinementContext *
68-
TypeRefinementContext::createForResilienceBoundary(ASTContext &Ctx, Decl *D,
69-
TypeRefinementContext *Parent,
70-
const AvailabilityContext &Info,
71-
SourceRange SrcRange) {
67+
TypeRefinementContext *TypeRefinementContext::createForAPIBoundary(
68+
ASTContext &Ctx, Decl *D, TypeRefinementContext *Parent,
69+
const AvailabilityContext &Info, SourceRange SrcRange) {
7270
assert(D);
7371
assert(Parent);
74-
return new (Ctx)
75-
TypeRefinementContext(Ctx, IntroNode(D, Reason::ResilienceBoundary),
76-
Parent, SrcRange, Info,
77-
AvailabilityContext::alwaysAvailable());
78-
72+
return new (Ctx) TypeRefinementContext(
73+
Ctx, IntroNode(D, Reason::APIBoundary), Parent, SrcRange, Info,
74+
AvailabilityContext::alwaysAvailable());
7975
}
8076

8177
TypeRefinementContext *
@@ -184,7 +180,7 @@ void TypeRefinementContext::dump(raw_ostream &OS, SourceManager &SrcMgr) const {
184180
SourceLoc TypeRefinementContext::getIntroductionLoc() const {
185181
switch (getReason()) {
186182
case Reason::Decl:
187-
case Reason::ResilienceBoundary:
183+
case Reason::APIBoundary:
188184
return Node.getAsDecl()->getLoc();
189185

190186
case Reason::IfStmtThenBranch:
@@ -298,7 +294,7 @@ TypeRefinementContext::getAvailabilityConditionVersionSourceRange(
298294
Node.getAsWhileStmt()->getCond(), Platform, Version);
299295

300296
case Reason::Root:
301-
case Reason::ResilienceBoundary:
297+
case Reason::APIBoundary:
302298
return SourceRange();
303299
}
304300

@@ -312,8 +308,7 @@ void TypeRefinementContext::print(raw_ostream &OS, SourceManager &SrcMgr,
312308

313309
OS << " versions=" << AvailabilityInfo.getOSVersion().getAsString();
314310

315-
if (getReason() == Reason::Decl
316-
|| getReason() == Reason::ResilienceBoundary) {
311+
if (getReason() == Reason::Decl || getReason() == Reason::APIBoundary) {
317312
Decl *D = Node.getAsDecl();
318313
OS << " decl=";
319314
if (auto VD = dyn_cast<ValueDecl>(D)) {
@@ -355,8 +350,8 @@ StringRef TypeRefinementContext::getReasonName(Reason R) {
355350
case Reason::Decl:
356351
return "decl";
357352

358-
case Reason::ResilienceBoundary:
359-
return "resilience_boundary";
353+
case Reason::APIBoundary:
354+
return "api_boundary";
360355

361356
case Reason::IfStmtThenBranch:
362357
return "if_then";

lib/Sema/CodeSynthesisDistributedActor.cpp

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -117,9 +117,17 @@ static VarDecl *addImplicitDistributedActorIDProperty(
117117
propDecl->getAttrs().add(
118118
new (C) CompilerInitializedAttr(/*IsImplicit=*/true));
119119

120-
nominal->addMember(propDecl);
121-
nominal->addMember(pbDecl);
122-
120+
// IMPORTANT: The `id` MUST be the first field of any distributed actor,
121+
// because when we allocate remote proxy instances, we don't allocate memory
122+
// for anything except the first two fields: id and actorSystem, so they
123+
// MUST be those fields.
124+
//
125+
// Their specific order also matters, because it is enforced this way in IRGen
126+
// and how we emit them in AST MUST match what IRGen expects or cross-module
127+
// things could be using wrong offsets and manifest as reading trash memory on
128+
// id or system accesses.
129+
nominal->addMember(propDecl, /*hint=*/nullptr, /*insertAtHead=*/true);
130+
nominal->addMember(pbDecl, /*hint=*/nullptr, /*insertAtHead=*/true);
123131
return propDecl;
124132
}
125133

lib/Sema/DerivedConformanceDistributedActor.cpp

Lines changed: 15 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -426,32 +426,6 @@ static FuncDecl *deriveDistributedActorSystem_invokeHandlerOnReturn(
426426
/******************************* PROPERTIES ***********************************/
427427
/******************************************************************************/
428428

429-
// TODO(distributed): make use of this after all, but FORCE it?
430-
static ValueDecl *deriveDistributedActor_id(DerivedConformance &derived) {
431-
assert(derived.Nominal->isDistributedActor());
432-
auto &C = derived.Context;
433-
434-
// ```
435-
// nonisolated
436-
// let id: Self.ID // Self.ActorSystem.ActorID
437-
// ```
438-
auto propertyType = getDistributedActorIDType(derived.Nominal);
439-
440-
VarDecl *propDecl;
441-
PatternBindingDecl *pbDecl;
442-
std::tie(propDecl, pbDecl) = derived.declareDerivedProperty(
443-
DerivedConformance::SynthesizedIntroducer::Let, C.Id_id, propertyType,
444-
propertyType,
445-
/*isStatic=*/false, /*isFinal=*/true);
446-
447-
// mark as nonisolated, allowing access to it from everywhere
448-
propDecl->getAttrs().add(
449-
new (C) NonisolatedAttr(/*IsImplicit=*/true));
450-
451-
derived.addMembersToConformanceContext({ propDecl, pbDecl });
452-
return propDecl;
453-
}
454-
455429
static ValueDecl *deriveDistributedActor_actorSystem(
456430
DerivedConformance &derived) {
457431
auto &C = derived.Context;
@@ -460,8 +434,7 @@ static ValueDecl *deriveDistributedActor_actorSystem(
460434
assert(classDecl && derived.Nominal->isDistributedActor());
461435

462436
// ```
463-
// nonisolated
464-
// let actorSystem: ActorSystem
437+
// nonisolated let actorSystem: ActorSystem
465438
// ```
466439
// (no need for @actorIndependent because it is an immutable let)
467440
auto propertyType = getDistributedActorSystemType(classDecl);
@@ -477,7 +450,14 @@ static ValueDecl *deriveDistributedActor_actorSystem(
477450
propDecl->getAttrs().add(
478451
new (C) NonisolatedAttr(/*IsImplicit=*/true));
479452

480-
derived.addMembersToConformanceContext({ propDecl, pbDecl });
453+
// IMPORTANT: `id` MUST be the first field of a distributed actor, and
454+
// `actorSystem` MUST be the second field, because for a remote instance
455+
// we don't allocate memory after those two fields, so their order is very
456+
// important. The `hint` below makes sure the system is inserted right after.
457+
auto id = derived.Nominal->getDistributedActorIDProperty();
458+
derived.addMemberToConformanceContext(pbDecl, /*hint=*/id);
459+
derived.addMemberToConformanceContext(propDecl, /*hint=*/id);
460+
481461
return propDecl;
482462
}
483463

@@ -571,11 +551,14 @@ deriveDistributedActorType_SerializationRequirement(
571551

572552
ValueDecl *DerivedConformance::deriveDistributedActor(ValueDecl *requirement) {
573553
if (auto var = dyn_cast<VarDecl>(requirement)) {
574-
if (var->getName() == Context.Id_id)
575-
return deriveDistributedActor_id(*this);
576-
577554
if (var->getName() == Context.Id_actorSystem)
578555
return deriveDistributedActor_actorSystem(*this);
556+
557+
if (var->getName() == Context.Id_id)
558+
llvm_unreachable("DistributedActor.id MUST be synthesized earlier, "
559+
"because it is forced by the Identifiable conformance. "
560+
"If we attempted to do synthesis here, the earlier phase "
561+
"failed and something is wrong: please report a bug.");
579562
}
580563

581564
if (auto func = dyn_cast<FuncDecl>(requirement)) {

lib/Sema/DerivedConformances.cpp

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,18 @@ void DerivedConformance::addMembersToConformanceContext(
5151
IDC->addMember(child);
5252
}
5353

54+
void DerivedConformance::addMemberToConformanceContext(
55+
Decl *member, Decl *hint) {
56+
auto IDC = cast<IterableDeclContext>(ConformanceDecl);
57+
IDC->addMember(member, hint, /*insertAtHead=*/false);
58+
}
59+
60+
void DerivedConformance::addMemberToConformanceContext(
61+
Decl *member, bool insertAtHead) {
62+
auto IDC = cast<IterableDeclContext>(ConformanceDecl);
63+
IDC->addMember(member, /*hint=*/nullptr, insertAtHead);
64+
}
65+
5466
Type DerivedConformance::getProtocolType() const {
5567
return Protocol->getDeclaredInterfaceType();
5668
}
@@ -325,10 +337,6 @@ ValueDecl *DerivedConformance::getDerivableRequirement(NominalTypeDecl *nominal,
325337
if (name.isSimpleName(ctx.Id_unownedExecutor))
326338
return getRequirement(KnownProtocolKind::Actor);
327339

328-
// DistributedActor.id
329-
if(name.isSimpleName(ctx.Id_id))
330-
return getRequirement(KnownProtocolKind::DistributedActor);
331-
332340
// DistributedActor.actorSystem
333341
if(name.isSimpleName(ctx.Id_actorSystem))
334342
return getRequirement(KnownProtocolKind::DistributedActor);

0 commit comments

Comments
 (0)