Skip to content

Commit a11dc3c

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.
1 parent cc1fd1c commit a11dc3c

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
@@ -350,21 +350,31 @@ static ConstructorDecl *createImplicitConstructor(NominalTypeDecl *decl,
350350
// initializers apply Sendable checking to arguments at the call-site,
351351
// and actor initializers do not run on the actor, so initial values
352352
// cannot be actor-instance-isolated.
353-
bool shouldAddNonisolated = true;
354353
ActorIsolation existingIsolation = getActorIsolation(decl);
355354
VarDecl *previousVar = nullptr;
355+
bool hasError = false;
356356

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

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

367-
auto *var = pbd->getAnchoringVarDecl(i);
375+
auto i = pbd->getPatternEntryIndexForVarDecl(var);
376+
if (pbd->isInitializerSubsumed(i))
377+
continue;
368378

369379
ActorIsolation initIsolation;
370380
if (var->hasInitAccessor()) {
@@ -401,21 +411,21 @@ static ConstructorDecl *createImplicitConstructor(NominalTypeDecl *decl,
401411
var->getDescriptiveKind(),
402412
var->getName(), isolation);
403413
hasError = true;
404-
break;
414+
return false;
405415
}
406416

407417
existingIsolation = isolation;
408418
previousVar = var;
409-
shouldAddNonisolated = false;
419+
addNonisolated = false;
410420
}
411421
}
412422
}
413423

414-
if (hasError)
415-
break;
416-
}
424+
return addNonisolated;
425+
};
417426

418-
if (shouldAddNonisolated) {
427+
if (shouldAddNonisolated(stored) &&
428+
shouldAddNonisolated(initAccessor)) {
419429
addNonIsolatedToSynthesized(decl, ctor);
420430
}
421431
}

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)