Skip to content

Commit 38a9faa

Browse files
committed
[Concurrency] Don't call getAllMembers() while inferring actor isolation for
implicit initializers. This messes with conformance synthesis for `RawRepresentable` and friends because it invokes conformance synthesis too early. (cherry picked from commit a11dc3c)
1 parent 07d63b6 commit 38a9faa

File tree

2 files changed

+33
-16
lines changed

2 files changed

+33
-16
lines changed

lib/Sema/CodeSynthesis.cpp

Lines changed: 25 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -349,21 +349,31 @@ static ConstructorDecl *createImplicitConstructor(NominalTypeDecl *decl,
349349
// initializers apply Sendable checking to arguments at the call-site,
350350
// and actor initializers do not run on the actor, so initial values
351351
// cannot be actor-instance-isolated.
352-
bool shouldAddNonisolated = true;
353352
ActorIsolation existingIsolation = getActorIsolation(decl);
354353
VarDecl *previousVar = nullptr;
354+
bool hasError = false;
355355

356-
for (auto member : decl->getImplementationContext()->getAllMembers()) {
357-
bool hasError = false;
358-
auto pbd = dyn_cast<PatternBindingDecl>(member);
359-
if (!pbd || pbd->isStatic())
360-
continue;
356+
// FIXME: Calling `getAllMembers` here causes issues for conformance
357+
// synthesis to RawRepresentable and friends. Instead, iterate over
358+
// both the stored properties and the init accessor properties, as
359+
// those can participate in implicit initializers.
361360

362-
for (auto i : range(pbd->getNumPatternEntries())) {
363-
if (pbd->isInitializerSubsumed(i))
361+
auto stored = decl->getStoredProperties();
362+
auto initAccessor = decl->getInitAccessorProperties();
363+
364+
auto shouldAddNonisolated = [&](ArrayRef<VarDecl *> properties) {
365+
if (hasError)
366+
return false;
367+
368+
bool addNonisolated = true;
369+
for (auto *var : properties) {
370+
auto *pbd = var->getParentPatternBinding();
371+
if (!pbd)
364372
continue;
365373

366-
auto *var = pbd->getAnchoringVarDecl(i);
374+
auto i = pbd->getPatternEntryIndexForVarDecl(var);
375+
if (pbd->isInitializerSubsumed(i))
376+
continue;
367377

368378
ActorIsolation initIsolation;
369379
if (var->hasInitAccessor()) {
@@ -400,21 +410,21 @@ static ConstructorDecl *createImplicitConstructor(NominalTypeDecl *decl,
400410
var->getDescriptiveKind(),
401411
var->getName(), isolation);
402412
hasError = true;
403-
break;
413+
return false;
404414
}
405415

406416
existingIsolation = isolation;
407417
previousVar = var;
408-
shouldAddNonisolated = false;
418+
addNonisolated = false;
409419
}
410420
}
411421
}
412422

413-
if (hasError)
414-
break;
415-
}
423+
return addNonisolated;
424+
};
416425

417-
if (shouldAddNonisolated) {
426+
if (shouldAddNonisolated(stored) &&
427+
shouldAddNonisolated(initAccessor)) {
418428
addNonIsolatedToSynthesized(decl, ctor);
419429
}
420430
}

test/Concurrency/isolated_default_arguments.swift

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,7 @@ struct S2 {
149149
}
150150

151151
struct S3 {
152-
// expected-error@+1 {{default argument cannot be both main actor-isolated and global actor 'SomeGlobalActor'-isolated}}
152+
// expected-error@+1 3 {{default argument cannot be both main actor-isolated and global actor 'SomeGlobalActor'-isolated}}
153153
var (x, y, z) = (requiresMainActor(), requiresSomeGlobalActor(), 10)
154154
}
155155

@@ -275,3 +275,10 @@ struct InitAccessors {
275275
}
276276
}
277277
}
278+
279+
// Make sure isolation inference for implicit initializers
280+
// doesn't impact conformance synthesis.
281+
282+
struct CError: Error, RawRepresentable {
283+
var rawValue: CInt
284+
}

0 commit comments

Comments
 (0)