Skip to content

Commit e9f214d

Browse files
Merge pull request #4538 from swiftwasm/release/5.7
[pull] swiftwasm-release/5.7 from release/5.7
2 parents 8809d71 + c0a4b09 commit e9f214d

31 files changed

+344
-69
lines changed

lib/AST/ASTPrinter.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,7 @@ PrintOptions PrintOptions::printSwiftInterfaceFile(ModuleDecl *ModuleToPrint,
144144
PrintOptions::FunctionRepresentationMode::Full;
145145
result.AlwaysTryPrintParameterLabels = true;
146146
result.PrintSPIs = printSPIs;
147+
result.PrintExplicitAny = true;
147148

148149
// We should print __consuming, __owned, etc for the module interface file.
149150
result.SkipUnderscoredKeywords = false;

lib/Demangling/Remangler.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3327,7 +3327,7 @@ ManglingError Remangler::mangleOpaqueType(Node *node, unsigned depth) {
33273327
if (trySubstitution(node, entry))
33283328
return ManglingError::Success;
33293329

3330-
DEMANGLER_ASSERT(node->getNumChildren() >= 2, node);
3330+
DEMANGLER_ASSERT(node->getNumChildren() >= 3, node);
33313331
RETURN_IF_ERROR(mangle(node->getChild(0), depth + 1));
33323332
auto boundGenerics = node->getChild(2);
33333333
for (unsigned i = 0; i < boundGenerics->getNumChildren(); ++i) {

lib/IDE/SwiftSourceDocInfo.cpp

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -310,10 +310,12 @@ static Expr *extractNameExpr(Expr *Fn) {
310310

311311
std::pair<bool, ArgumentList *>
312312
NameMatcher::walkToArgumentListPre(ArgumentList *ArgList) {
313-
auto Labels = getCallArgLabelRanges(getSourceMgr(), ArgList,
314-
LabelRangeEndAt::BeforeElemStart);
315-
tryResolve(Parent, ArgList->getStartLoc(), LabelRangeType::CallArg,
313+
if (!ArgList->isImplicit()) {
314+
auto Labels = getCallArgLabelRanges(getSourceMgr(), ArgList,
315+
LabelRangeEndAt::BeforeElemStart);
316+
tryResolve(Parent, ArgList->getStartLoc(), LabelRangeType::CallArg,
316317
Labels.first, Labels.second);
318+
}
317319
if (isDone())
318320
return {false, ArgList};
319321

lib/IRGen/GenHeap.cpp

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -534,6 +534,9 @@ llvm::Value *IRGenFunction::emitUnmanagedAlloc(const HeapLayout &layout,
534534
const llvm::Twine &name,
535535
llvm::Constant *captureDescriptor,
536536
const HeapNonFixedOffsets *offsets) {
537+
if (layout.isKnownEmpty())
538+
return IGM.RefCountedNull;
539+
537540
llvm::Value *metadata = layout.getPrivateMetadata(IGM, captureDescriptor);
538541
llvm::Value *size, *alignMask;
539542
if (offsets) {
@@ -1505,7 +1508,10 @@ class FixedBoxTypeInfoBase : public BoxTypeInfo {
15051508
public:
15061509
FixedBoxTypeInfoBase(IRGenModule &IGM, HeapLayout &&layout)
15071510
: BoxTypeInfo(IGM), layout(std::move(layout))
1508-
{}
1511+
{
1512+
// Empty layouts should always use EmptyBoxTypeInfo instead
1513+
assert(!layout.isKnownEmpty());
1514+
}
15091515

15101516
OwnedAddress
15111517
allocate(IRGenFunction &IGF, SILType boxedType, GenericEnvironment *env,

lib/SILGen/SILGenDistributed.cpp

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -64,17 +64,12 @@ static void initializeProperty(SILGenFunction &SGF, SILLocation loc,
6464
SGF.B.createCopyAddr(loc, value, fieldAddr, IsNotTake, IsInitialization);
6565
} else {
6666
if (value->getType().isAddress()) {
67-
value = SGF.B.createTrivialLoadOr(
68-
loc, value, LoadOwnershipQualifier::Take);
67+
SGF.emitSemanticLoadInto(loc, value, SGF.F.getTypeLowering(value->getType()),
68+
fieldAddr, SGF.getTypeLowering(loweredType), IsTake, IsInitialization);
6969
} else {
7070
value = SGF.B.emitCopyValueOperation(loc, value);
71-
}
72-
73-
SGF.B.emitStoreValueOperation(
71+
SGF.B.emitStoreValueOperation(
7472
loc, value, fieldAddr, StoreOwnershipQualifier::Init);
75-
76-
if (value->getType().isAddress()) {
77-
SGF.B.createDestroyAddr(loc, value);
7873
}
7974
}
8075
}

lib/SILOptimizer/Transforms/AccessEnforcementWMO.cpp

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -164,7 +164,7 @@ class GlobalAccessRemoval {
164164
void perform();
165165

166166
protected:
167-
void visitInstruction(SILInstruction *I);
167+
bool visitInstruction(SILInstruction *I);
168168
void recordAccess(SILInstruction *beginAccess, DisjointAccessLocationKey key,
169169
AccessStorage::Kind storageKind, bool hasNoNestedConflict);
170170
void removeNonreentrantAccess();
@@ -180,27 +180,33 @@ void GlobalAccessRemoval::perform() {
180180
continue;
181181

182182
for (auto &BB : F) {
183-
for (auto &I : BB)
184-
visitInstruction(&I);
183+
for (auto &I : BB) {
184+
if (!visitInstruction(&I))
185+
return;
186+
}
185187
}
186188
}
187189
removeNonreentrantAccess();
188190
}
189191

190-
void GlobalAccessRemoval::visitInstruction(SILInstruction *I) {
192+
bool GlobalAccessRemoval::visitInstruction(SILInstruction *I) {
191193
if (auto *BAI = dyn_cast<BeginAccessInst>(I)) {
192194
auto storageAndBase = AccessStorageWithBase::compute(BAI->getSource());
195+
if (!storageAndBase.base)
196+
return false;
193197
auto key = getDisjointAccessLocation(storageAndBase);
194198
recordAccess(BAI, key, storageAndBase.storage.getKind(),
195199
BAI->hasNoNestedConflict());
196-
return;
200+
return true;
197201
}
198202
if (auto *BUAI = dyn_cast<BeginUnpairedAccessInst>(I)) {
199203
auto storageAndBase = AccessStorageWithBase::compute(BUAI->getSource());
204+
if (!storageAndBase.base)
205+
return false;
200206
auto key = getDisjointAccessLocation(storageAndBase);
201207
recordAccess(BUAI, key, storageAndBase.storage.getKind(),
202208
BUAI->hasNoNestedConflict());
203-
return;
209+
return true;
204210
}
205211
if (auto *KPI = dyn_cast<KeyPathInst>(I)) {
206212
for (const KeyPathPatternComponent &component :
@@ -219,8 +225,8 @@ void GlobalAccessRemoval::visitInstruction(SILInstruction *I) {
219225
break;
220226
}
221227
}
222-
return;
223228
}
229+
return true;
224230
}
225231

226232
// Record an access in the disjointAccessMap.

lib/Sema/CSClosure.cpp

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,8 +50,32 @@ class TypeVariableRefFinder : public ASTWalker {
5050

5151
std::pair<bool, Expr *> walkToExprPre(Expr *expr) override {
5252
if (auto *DRE = dyn_cast<DeclRefExpr>(expr)) {
53-
if (auto type = CS.getTypeIfAvailable(DRE->getDecl()))
53+
auto *decl = DRE->getDecl();
54+
55+
if (auto type = CS.getTypeIfAvailable(DRE->getDecl())) {
56+
// If this is not one of the closure parameters which
57+
// is inferrable from the body, let's replace type
58+
// variables with errors to avoid bringing external
59+
// information to the element component.
60+
if (type->hasTypeVariable() && !isa<ParamDecl>(decl)) {
61+
// If there are type variables left in the simplified version,
62+
// it means that this is an invalid external declaration
63+
// relative to this element's context.
64+
if (CS.simplifyType(type)->hasTypeVariable()) {
65+
auto transformedTy = type.transform([&](Type type) {
66+
if (auto *typeVar = type->getAs<TypeVariableType>()) {
67+
return ErrorType::get(CS.getASTContext());
68+
}
69+
return type;
70+
});
71+
72+
CS.setType(decl, transformedTy);
73+
return {true, expr};
74+
}
75+
}
76+
5477
inferVariables(type);
78+
}
5579
}
5680

5781
return {true, expr};

lib/Sema/CSStep.h

Lines changed: 37 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -781,6 +781,9 @@ class ConjunctionStep : public BindingStep<ConjunctionElementProducer> {
781781
class SolverSnapshot {
782782
ConstraintSystem &CS;
783783

784+
/// The conjunction this snapshot belongs to.
785+
Constraint *Conjunction;
786+
784787
Optional<llvm::SaveAndRestore<DeclContext *>> DC = None;
785788

786789
llvm::SetVector<TypeVariableType *> TypeVars;
@@ -794,8 +797,9 @@ class ConjunctionStep : public BindingStep<ConjunctionElementProducer> {
794797

795798
public:
796799
SolverSnapshot(ConstraintSystem &cs, Constraint *conjunction)
797-
: CS(cs), TypeVars(std::move(cs.TypeVariables)) {
798-
auto *locator = conjunction->getLocator();
800+
: CS(cs), Conjunction(conjunction),
801+
TypeVars(std::move(cs.TypeVariables)) {
802+
auto *locator = Conjunction->getLocator();
799803
// If this conjunction represents a closure, we need to
800804
// switch declaration context over to it.
801805
if (locator->directlyAt<ClosureExpr>()) {
@@ -820,7 +824,7 @@ class ConjunctionStep : public BindingStep<ConjunctionElementProducer> {
820824
IsolationScope = std::make_unique<Scope>(CS);
821825

822826
// Apply solution inferred for the conjunction.
823-
CS.applySolution(solution);
827+
applySolution(solution);
824828

825829
// Add constraints to the graph after solution
826830
// has been applied to make sure that all type
@@ -855,6 +859,36 @@ class ConjunctionStep : public BindingStep<ConjunctionElementProducer> {
855859
for (auto &constraint : CS.InactiveConstraints)
856860
CG.addConstraint(&constraint);
857861
}
862+
863+
void applySolution(const Solution &solution) {
864+
CS.applySolution(solution);
865+
866+
if (!CS.shouldAttemptFixes())
867+
return;
868+
869+
// If inference succeeded, we are done.
870+
auto score = solution.getFixedScore();
871+
if (score.Data[SK_Fix] == 0)
872+
return;
873+
874+
// If this conjunction represents a closure and inference
875+
// has failed, let's bind all of unresolved type variables
876+
// in its interface type to holes to avoid extraneous
877+
// fixes produced by outer context.
878+
879+
auto locator = Conjunction->getLocator();
880+
if (locator->directlyAt<ClosureExpr>()) {
881+
auto closureTy =
882+
CS.getClosureType(castToExpr<ClosureExpr>(locator->getAnchor()));
883+
884+
CS.simplifyType(closureTy).visit([&](Type componentTy) {
885+
if (auto *typeVar = componentTy->getAs<TypeVariableType>()) {
886+
CS.assignFixedType(
887+
typeVar, PlaceholderType::get(CS.getASTContext(), typeVar));
888+
}
889+
});
890+
}
891+
}
858892
};
859893

860894
/// Best solution solver reached so far.

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 & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -426,14 +426,12 @@ static FuncDecl *deriveDistributedActorSystem_invokeHandlerOnReturn(
426426
/******************************* PROPERTIES ***********************************/
427427
/******************************************************************************/
428428

429-
// TODO(distributed): make use of this after all, but FORCE it?
430429
static ValueDecl *deriveDistributedActor_id(DerivedConformance &derived) {
431430
assert(derived.Nominal->isDistributedActor());
432431
auto &C = derived.Context;
433432

434433
// ```
435-
// nonisolated
436-
// let id: Self.ID // Self.ActorSystem.ActorID
434+
// nonisolated let id: Self.ID // Self.ActorSystem.ActorID
437435
// ```
438436
auto propertyType = getDistributedActorIDType(derived.Nominal);
439437

@@ -448,7 +446,8 @@ static ValueDecl *deriveDistributedActor_id(DerivedConformance &derived) {
448446
propDecl->getAttrs().add(
449447
new (C) NonisolatedAttr(/*IsImplicit=*/true));
450448

451-
derived.addMembersToConformanceContext({ propDecl, pbDecl });
449+
derived.addMemberToConformanceContext(pbDecl, /*insertAtHead=*/true);
450+
derived.addMemberToConformanceContext(propDecl, /*insertAtHead=*/true);
452451
return propDecl;
453452
}
454453

@@ -460,8 +459,7 @@ static ValueDecl *deriveDistributedActor_actorSystem(
460459
assert(classDecl && derived.Nominal->isDistributedActor());
461460

462461
// ```
463-
// nonisolated
464-
// let actorSystem: ActorSystem
462+
// nonisolated let actorSystem: ActorSystem
465463
// ```
466464
// (no need for @actorIndependent because it is an immutable let)
467465
auto propertyType = getDistributedActorSystemType(classDecl);
@@ -477,7 +475,17 @@ static ValueDecl *deriveDistributedActor_actorSystem(
477475
propDecl->getAttrs().add(
478476
new (C) NonisolatedAttr(/*IsImplicit=*/true));
479477

480-
derived.addMembersToConformanceContext({ propDecl, pbDecl });
478+
// IMPORTANT: `id` MUST be the first field of a distributed actor, and
479+
// `actorSystem` MUST be the second field, because for a remote instance
480+
// we don't allocate memory after those two fields, so their order is very
481+
// important. The `hint` below makes sure the system is inserted right after.
482+
auto id = derived.Nominal->getDistributedActorIDProperty();
483+
assert(id && "id must be synthesized first, so it is the first field of any "
484+
"distributed actor (followed by actorSystem)");
485+
486+
derived.addMemberToConformanceContext(pbDecl, /*hint=*/id);
487+
derived.addMemberToConformanceContext(propDecl, /*hint=*/id);
488+
481489
return propDecl;
482490
}
483491

0 commit comments

Comments
 (0)