Skip to content

Commit a747906

Browse files
Merge pull request #4851 from swiftwasm/release/5.7
[pull] swiftwasm-release/5.7 from release/5.7
2 parents c3caf7c + d02afa0 commit a747906

File tree

10 files changed

+245
-38
lines changed

10 files changed

+245
-38
lines changed

include/swift/IDE/CodeCompletionCache.h

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,8 @@ class CodeCompletionCache {
4545
bool ResultsHaveLeadingDot;
4646
bool ForTestableLookup;
4747
bool ForPrivateImportLookup;
48+
/// Must be sorted alphabetically for stable identity.
49+
llvm::SmallVector<std::string, 2> SpiGroups;
4850
bool AddInitsInToplevel;
4951
bool AddCallWithNoDefaultArgs;
5052
bool Annotated;
@@ -56,6 +58,7 @@ class CodeCompletionCache {
5658
LHS.ResultsHaveLeadingDot == RHS.ResultsHaveLeadingDot &&
5759
LHS.ForTestableLookup == RHS.ForTestableLookup &&
5860
LHS.ForPrivateImportLookup == RHS.ForPrivateImportLookup &&
61+
LHS.SpiGroups == RHS.SpiGroups &&
5962
LHS.AddInitsInToplevel == RHS.AddInitsInToplevel &&
6063
LHS.AddCallWithNoDefaultArgs == RHS.AddCallWithNoDefaultArgs &&
6164
LHS.Annotated == RHS.Annotated;
@@ -125,16 +128,35 @@ template<>
125128
struct DenseMapInfo<swift::ide::CodeCompletionCache::Key> {
126129
using KeyTy = swift::ide::CodeCompletionCache::Key;
127130
static inline KeyTy getEmptyKey() {
128-
return KeyTy{"", "", {}, false, false, false, false, false, false};
131+
return KeyTy{/*ModuleFilename=*/"",
132+
/*ModuleName=*/"",
133+
/*AccessPath=*/{},
134+
/*ResultsHaveLeadingDot=*/false,
135+
/*ForTestableLookup=*/false,
136+
/*ForPrivateImportLookup=*/false,
137+
/*SpiGroups=*/{},
138+
/*AddInitsInToplevel=*/false,
139+
/*AddCallWithNoDefaultArgs=*/false,
140+
/*Annotated=*/false};
129141
}
130142
static inline KeyTy getTombstoneKey() {
131-
return KeyTy{"", "", {}, true, false, false, false, false, false};
143+
return KeyTy{/*ModuleFilename=*/"",
144+
/*ModuleName=*/"",
145+
/*AccessPath=*/{},
146+
/*ResultsHaveLeadingDot=*/true,
147+
/*ForTestableLookup=*/false,
148+
/*ForPrivateImportLookup=*/false,
149+
/*SpiGroups=*/{},
150+
/*AddInitsInToplevel=*/false,
151+
/*AddCallWithNoDefaultArgs=*/false,
152+
/*Annotated=*/false};
132153
}
133154
static unsigned getHashValue(const KeyTy &Val) {
134155
return llvm::hash_combine(
135156
Val.ModuleFilename, Val.ModuleName,
136157
llvm::hash_combine_range(Val.AccessPath.begin(), Val.AccessPath.end()),
137158
Val.ResultsHaveLeadingDot, Val.ForTestableLookup,
159+
llvm::hash_combine_range(Val.SpiGroups.begin(), Val.SpiGroups.end()),
138160
Val.ForPrivateImportLookup, Val.AddInitsInToplevel,
139161
Val.AddCallWithNoDefaultArgs, Val.Annotated);
140162
}

lib/AST/Decl.cpp

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -9140,14 +9140,20 @@ ActorIsolation swift::getActorIsolation(ValueDecl *value) {
91409140
}
91419141

91429142
ActorIsolation swift::getActorIsolationOfContext(DeclContext *dc) {
9143-
if (auto *vd = dyn_cast_or_null<ValueDecl>(dc->getAsDecl()))
9143+
auto dcToUse = dc;
9144+
// Defer bodies share actor isolation of their enclosing context.
9145+
if (auto FD = dyn_cast<FuncDecl>(dcToUse)) {
9146+
if (FD->isDeferBody()) {
9147+
dcToUse = FD->getDeclContext();
9148+
}
9149+
}
9150+
if (auto *vd = dyn_cast_or_null<ValueDecl>(dcToUse->getAsDecl()))
91449151
return getActorIsolation(vd);
91459152

9146-
if (auto *var = dc->getNonLocalVarDecl())
9147-
return getActorIsolation(var);
9148-
9153+
if (auto *var = dcToUse->getNonLocalVarDecl())
9154+
return getActorIsolation(var);
91499155

9150-
if (auto *closure = dyn_cast<AbstractClosureExpr>(dc)) {
9156+
if (auto *closure = dyn_cast<AbstractClosureExpr>(dcToUse)) {
91519157
switch (auto isolation = closure->getActorIsolation()) {
91529158
case ClosureActorIsolation::Independent:
91539159
return ActorIsolation::forIndependent()
@@ -9170,14 +9176,14 @@ ActorIsolation swift::getActorIsolationOfContext(DeclContext *dc) {
91709176
}
91719177
}
91729178

9173-
if (auto *tld = dyn_cast<TopLevelCodeDecl>(dc)) {
9174-
if (dc->isAsyncContext() ||
9175-
dc->getASTContext().LangOpts.StrictConcurrencyLevel
9176-
>= StrictConcurrency::Complete) {
9177-
if (Type mainActor = dc->getASTContext().getMainActorType())
9179+
if (auto *tld = dyn_cast<TopLevelCodeDecl>(dcToUse)) {
9180+
if (dcToUse->isAsyncContext() ||
9181+
dcToUse->getASTContext().LangOpts.StrictConcurrencyLevel >=
9182+
StrictConcurrency::Complete) {
9183+
if (Type mainActor = dcToUse->getASTContext().getMainActorType())
91789184
return ActorIsolation::forGlobalActor(
91799185
mainActor,
9180-
/*unsafe=*/!dc->getASTContext().isSwiftVersionAtLeast(6));
9186+
/*unsafe=*/!dcToUse->getASTContext().isSwiftVersionAtLeast(6));
91819187
}
91829188
}
91839189

lib/IDE/CodeCompletion.cpp

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1291,6 +1291,16 @@ void swift::ide::deliverCompletionResults(
12911291
// ModuleFilename can be empty if something strange happened during
12921292
// module loading, for example, the module file is corrupted.
12931293
if (!ModuleFilename.empty()) {
1294+
llvm::SmallVector<std::string, 2> spiGroups;
1295+
for (auto Import : SF.getImports()) {
1296+
if (Import.module.importedModule == TheModule) {
1297+
for (auto SpiGroup : Import.spiGroups) {
1298+
spiGroups.push_back(SpiGroup.str().str());
1299+
}
1300+
break;
1301+
}
1302+
}
1303+
llvm::sort(spiGroups);
12941304
CodeCompletionCache::Key K{
12951305
ModuleFilename.str(),
12961306
std::string(TheModule->getName()),
@@ -1302,6 +1312,7 @@ void swift::ide::deliverCompletionResults(
13021312
SF.hasTestableOrPrivateImport(
13031313
AccessLevel::Internal, TheModule,
13041314
SourceFile::ImportQueryKind::PrivateOnly),
1315+
spiGroups,
13051316
CompletionContext.getAddInitsToTopLevel(),
13061317
CompletionContext.addCallWithNoDefaultArgs(),
13071318
CompletionContext.getAnnotateResult()};
@@ -1341,9 +1352,12 @@ void swift::ide::deliverCompletionResults(
13411352
// Add results for all imported modules.
13421353
SmallVector<ImportedModule, 4> Imports;
13431354
SF.getImportedModules(
1344-
Imports, {ModuleDecl::ImportFilterKind::Exported,
1345-
ModuleDecl::ImportFilterKind::Default,
1346-
ModuleDecl::ImportFilterKind::ImplementationOnly});
1355+
Imports, {
1356+
ModuleDecl::ImportFilterKind::Exported,
1357+
ModuleDecl::ImportFilterKind::Default,
1358+
ModuleDecl::ImportFilterKind::ImplementationOnly,
1359+
ModuleDecl::ImportFilterKind::SPIAccessControl,
1360+
});
13471361

13481362
for (auto Imported : Imports) {
13491363
for (auto Import : namelookup::getAllImports(Imported.importedModule))

lib/IDE/CodeCompletionCache.cpp

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -475,6 +475,12 @@ static std::string getName(StringRef cacheDirectory,
475475
<< (K.AddInitsInToplevel ? "-inits" : "")
476476
<< (K.AddCallWithNoDefaultArgs ? "-nodefaults" : "")
477477
<< (K.Annotated ? "-annotated" : "");
478+
if (K.SpiGroups.size() > 0) {
479+
OSS << "-spi";
480+
for (auto SpiGroup : K.SpiGroups) {
481+
OSS << "-" << SpiGroup;
482+
}
483+
}
478484

479485
// name[-access-path-components]
480486
for (StringRef component : K.AccessPath)
@@ -539,9 +545,16 @@ OnDiskCodeCompletionCache::getFromFile(StringRef filename) {
539545
return None;
540546

541547
// Make up a key for readCachedModule.
542-
CodeCompletionCache::Key K{filename.str(), "<module-name>", {},
543-
false, false, false,
544-
false, false, false};
548+
CodeCompletionCache::Key K{/*ModuleFilename=*/filename.str(),
549+
/*ModuleName=*/"<module-name>",
550+
/*AccessPath=*/{},
551+
/*ResultsHaveLeadingDot=*/false,
552+
/*ForTestableLookup=*/false,
553+
/*ForPrivateImportLookup=*/false,
554+
/*SpiGroups=*/{},
555+
/*AddInitsInToplevel=*/false,
556+
/*AddCallWithNoDefaultArgs=*/false,
557+
/*Annotated=*/false};
545558

546559
// Read the cached results.
547560
auto V = CodeCompletionCache::createValue();

lib/SILGen/SILGenProlog.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -733,7 +733,7 @@ void SILGenFunction::emitPrologGlobalActorHop(SILLocation loc,
733733
}
734734

735735
SILValue SILGenFunction::emitLoadGlobalActorExecutor(Type globalActor) {
736-
CanType actorType = CanType(globalActor);
736+
CanType actorType = globalActor->getCanonicalType();
737737
NominalTypeDecl *nominal = actorType->getNominalOrBoundGenericNominal();
738738
VarDecl *sharedInstanceDecl = nominal->getGlobalActorInstance();
739739
assert(sharedInstanceDecl && "no shared actor field in global actor");

lib/Sema/TypeCheckConcurrency.cpp

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -124,10 +124,13 @@ bool swift::usesFlowSensitiveIsolation(AbstractFunctionDecl const *fn) {
124124
}
125125

126126
auto *dc = fn->getDeclContext();
127+
if (!dc)
128+
return false;
127129

128130
// Must be part of a nominal type.
129131
auto *nominal = dc->getSelfNominalTypeDecl();
130-
assert(nominal && "init/deinit not part of a nominal?");
132+
if (!nominal)
133+
return false;
131134

132135
// If it's part of an actor type, then its deinit and some of its inits use
133136
// flow-isolation.
@@ -1489,6 +1492,7 @@ static FuncDecl *findAnnotatableFunction(DeclContext *dc) {
14891492
}
14901493

14911494
/// Note when the enclosing context could be put on a global actor.
1495+
// FIXME: This should handle closures too.
14921496
static void noteGlobalActorOnContext(DeclContext *dc, Type globalActor) {
14931497
// If we are in a synchronous function on the global actor,
14941498
// suggest annotating with the global actor itself.
@@ -3755,14 +3759,6 @@ ActorIsolation ActorIsolationRequest::evaluate(
37553759
// If this is a local function, inherit the actor isolation from its
37563760
// context if it global or was captured.
37573761
if (auto func = dyn_cast<FuncDecl>(value)) {
3758-
// If this is a defer body, inherit unconditionally; we don't
3759-
// care if the enclosing function captures the isolated parameter.
3760-
if (func->isDeferBody()) {
3761-
auto enclosingIsolation =
3762-
getActorIsolationOfContext(func->getDeclContext());
3763-
return inferredIsolation(enclosingIsolation);
3764-
}
3765-
37663762
if (func->isLocalCapture() && !func->isSendable()) {
37673763
switch (auto enclosingIsolation =
37683764
getActorIsolationOfContext(func->getDeclContext())) {

stdlib/public/core/StringGutsRangeReplaceable.swift

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -483,9 +483,13 @@ extension _StringGuts {
483483
let newUTF8Count =
484484
oldUTF8Count + newUTF8Subrange.count - oldUTF8SubrangeCount
485485

486-
// Get the character stride in the entire string, not just the substring.
487-
// (Characters in a substring may end beyond the bounds of it.)
488-
let newStride = _opaqueCharacterStride(startingAt: utf8StartOffset)
486+
var newStride = 0
487+
488+
if !newUTF8Subrange.isEmpty {
489+
// Get the character stride in the entire string, not just the substring.
490+
// (Characters in a substring may end beyond the bounds of it.)
491+
newStride = _opaqueCharacterStride(startingAt: utf8StartOffset)
492+
}
489493

490494
startIndex = String.Index(
491495
encodedOffset: utf8StartOffset,
@@ -522,9 +526,14 @@ extension _StringGuts {
522526
// needs to look ahead by more than one Unicode scalar.)
523527
let oldStride = startIndex.characterStride ?? 0
524528
if oldRange.lowerBound <= oldBounds.lowerBound &+ oldStride {
525-
// Get the character stride in the entire string, not just the substring.
526-
// (Characters in a substring may end beyond the bounds of it.)
527-
let newStride = _opaqueCharacterStride(startingAt: newBounds.lowerBound)
529+
var newStride = 0
530+
531+
if !newBounds.isEmpty {
532+
// Get the character stride in the entire string, not just the substring.
533+
// (Characters in a substring may end beyond the bounds of it.)
534+
newStride = _opaqueCharacterStride(startingAt: newBounds.lowerBound)
535+
}
536+
528537
var newStart = String.Index(
529538
encodedOffset: newBounds.lowerBound,
530539
characterStride: newStride

test/Concurrency/actor_defer.swift

Lines changed: 86 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66
func doSomething() {}
77

8-
// expected-note @+1 4 {{calls to global function 'requiresMainActor()' from outside of its actor context are implicitly asynchronous}}
8+
// expected-note @+1 6 {{calls to global function 'requiresMainActor()' from outside of its actor context are implicitly asynchronous}}
99
@MainActor func requiresMainActor() {}
1010

1111
@MainActor func testNonDefer_positive() {
@@ -66,7 +66,7 @@ func testGlobalActorAsync_negative() async {
6666

6767
@available(SwiftStdlib 5.1, *)
6868
actor Actor {
69-
// expected-note @+1 3 {{mutation of this property is only permitted within the actor}}
69+
// expected-note @+1 6 {{mutation of this property is only permitted within the actor}}
7070
var actorProperty = 0
7171

7272
func testActor_positive() {
@@ -76,6 +76,13 @@ actor Actor {
7676
doSomething()
7777
}
7878

79+
func testActor_task_positive() {
80+
Task {
81+
defer { actorProperty += 1 }
82+
doSomething()
83+
}
84+
}
85+
7986
#if NEGATIVES
8087
nonisolated func testActor_negative() {
8188
defer {
@@ -84,13 +91,30 @@ actor Actor {
8491
}
8592
doSomething()
8693
}
94+
95+
nonisolated func testActor_task_negative() {
96+
Task {
97+
// expected-error @+1 {{actor-isolated property 'actorProperty' can not be mutated from a non-isolated context}}
98+
defer { actorProperty += 1 }
99+
doSomething()
100+
}
101+
}
102+
87103
@MainActor func testActor_negative_globalActor() {
88104
defer {
89105
// expected-error @+1 {{actor-isolated property 'actorProperty' can not be mutated from the main actor}}
90106
actorProperty += 1
91107
}
92108
doSomething()
93109
}
110+
111+
func testActor_task_negative_globalActor() {
112+
Task { @MainActor in
113+
// expected-error @+1 {{actor-isolated property 'actorProperty' can not be mutated from the main actor}}
114+
defer { actorProperty += 1 }
115+
doSomething()
116+
}
117+
}
94118
#endif
95119

96120
@MainActor func testGlobalActor_positive() {
@@ -99,6 +123,13 @@ actor Actor {
99123
}
100124
doSomething()
101125
}
126+
127+
func testGlobalActor_task_positive() {
128+
Task { @MainActor in
129+
defer { requiresMainActor() }
130+
doSomething()
131+
}
132+
}
102133

103134
#if NEGATIVES
104135
func testGlobalActor_negative() {
@@ -108,6 +139,14 @@ actor Actor {
108139
}
109140
doSomething()
110141
}
142+
143+
func testGlobalActor_task_negative() {
144+
Task {
145+
// expected-error @+1 {{call to main actor-isolated global function 'requiresMainActor()' in a synchronous nonisolated context}}
146+
defer { requiresMainActor() }
147+
doSomething()
148+
}
149+
}
111150
#endif
112151
}
113152

@@ -130,3 +169,48 @@ func testIsolatedActor_negative(actor: Actor) {
130169
doSomething()
131170
}
132171
#endif
172+
173+
@available(SwiftStdlib 5.1, *)
174+
func testGlobalActor_inTask_positive() {
175+
Task { @MainActor in
176+
defer { requiresMainActor() }
177+
doSomething()
178+
}
179+
}
180+
181+
#if NEGATIVES
182+
@available(SwiftStdlib 5.1, *)
183+
func testGlobalActor_inTask_negative() {
184+
Task {
185+
// expected-error @+1 {{call to main actor-isolated global function 'requiresMainActor()' in a synchronous nonisolated context}}
186+
defer { requiresMainActor() }
187+
doSomething()
188+
}
189+
}
190+
#endif
191+
192+
@available(SwiftStdlib 5.1, *)
193+
func takeClosureWithIsolatedParam(body: (isolated Actor) -> Void) {}
194+
195+
@available(SwiftStdlib 5.1, *)
196+
func takeClosureWithNotIsolatedParam(body: (Actor) -> Void) {}
197+
198+
@available(SwiftStdlib 5.1, *)
199+
func testIsolatedActor_closure_positive() {
200+
takeClosureWithIsolatedParam { actor in
201+
actor.actorProperty += 1
202+
defer { actor.actorProperty += 1 }
203+
doSomething()
204+
}
205+
}
206+
207+
#if NEGATIVES
208+
@available(SwiftStdlib 5.1, *)
209+
func testIsolatedActor_closure_negative() {
210+
takeClosureWithNotIsolatedParam { actor in
211+
// expected-error @+1 {{actor-isolated property 'actorProperty' can not be mutated from a non-isolated context}}
212+
defer { actor.actorProperty += 1 }
213+
doSomething()
214+
}
215+
}
216+
#endif

0 commit comments

Comments
 (0)