Skip to content

Commit 07d63b6

Browse files
committed
[Concurrency] Don't skip pattern bindings with multiple vars when inferring the
isolation of implicit initializers. (cherry picked from commit cc1fd1c)
1 parent a641192 commit 07d63b6

File tree

2 files changed

+59
-46
lines changed

2 files changed

+59
-46
lines changed

lib/Sema/CodeSynthesis.cpp

Lines changed: 48 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -354,62 +354,64 @@ static ConstructorDecl *createImplicitConstructor(NominalTypeDecl *decl,
354354
VarDecl *previousVar = nullptr;
355355

356356
for (auto member : decl->getImplementationContext()->getAllMembers()) {
357+
bool hasError = false;
357358
auto pbd = dyn_cast<PatternBindingDecl>(member);
358359
if (!pbd || pbd->isStatic())
359360
continue;
360361

361-
auto *var = pbd->getSingleVar();
362-
if (!var) {
363-
shouldAddNonisolated = false;
364-
break;
365-
}
366-
367-
auto i = pbd->getPatternEntryIndexForVarDecl(var);
368-
if (pbd->isInitializerSubsumed(i))
369-
continue;
370-
371-
ActorIsolation initIsolation;
372-
if (var->hasInitAccessor()) {
373-
// Init accessors share the actor isolation of the property;
374-
// the accessor body can call anything in that isolation domain,
375-
// and we don't attempt to infer when the isolation isn't
376-
// necessary.
377-
initIsolation = getActorIsolation(var);
378-
} else {
379-
initIsolation = var->getInitializerIsolation();
380-
}
362+
for (auto i : range(pbd->getNumPatternEntries())) {
363+
if (pbd->isInitializerSubsumed(i))
364+
continue;
365+
366+
auto *var = pbd->getAnchoringVarDecl(i);
367+
368+
ActorIsolation initIsolation;
369+
if (var->hasInitAccessor()) {
370+
// Init accessors share the actor isolation of the property;
371+
// the accessor body can call anything in that isolation domain,
372+
// and we don't attempt to infer when the isolation isn't
373+
// necessary.
374+
initIsolation = getActorIsolation(var);
375+
} else {
376+
initIsolation = var->getInitializerIsolation();
377+
}
381378

382-
auto type = var->getTypeInContext();
383-
auto isolation = getActorIsolation(var);
384-
if (isolation.isGlobalActor()) {
385-
if (!isSendableType(decl->getModuleContext(), type) ||
386-
initIsolation.isGlobalActor()) {
387-
// If different isolated stored properties require different
388-
// global actors, it is impossible to initialize this type.
389-
if (existingIsolation != isolation) {
390-
ctx.Diags.diagnose(decl->getLoc(),
391-
diag::conflicting_stored_property_isolation,
392-
ICK == ImplicitConstructorKind::Memberwise,
393-
decl->getDeclaredType(), existingIsolation, isolation)
394-
.warnUntilSwiftVersion(6);
395-
if (previousVar) {
396-
previousVar->diagnose(
379+
auto type = var->getTypeInContext();
380+
auto isolation = getActorIsolation(var);
381+
if (isolation.isGlobalActor()) {
382+
if (!isSendableType(decl->getModuleContext(), type) ||
383+
initIsolation.isGlobalActor()) {
384+
// If different isolated stored properties require different
385+
// global actors, it is impossible to initialize this type.
386+
if (existingIsolation != isolation) {
387+
ctx.Diags.diagnose(decl->getLoc(),
388+
diag::conflicting_stored_property_isolation,
389+
ICK == ImplicitConstructorKind::Memberwise,
390+
decl->getDeclaredType(), existingIsolation, isolation)
391+
.warnUntilSwiftVersion(6);
392+
if (previousVar) {
393+
previousVar->diagnose(
394+
diag::property_requires_actor,
395+
previousVar->getDescriptiveKind(),
396+
previousVar->getName(), existingIsolation);
397+
}
398+
var->diagnose(
397399
diag::property_requires_actor,
398-
previousVar->getDescriptiveKind(),
399-
previousVar->getName(), existingIsolation);
400+
var->getDescriptiveKind(),
401+
var->getName(), isolation);
402+
hasError = true;
403+
break;
400404
}
401-
var->diagnose(
402-
diag::property_requires_actor,
403-
var->getDescriptiveKind(),
404-
var->getName(), isolation);
405-
break;
406-
}
407405

408-
existingIsolation = isolation;
409-
previousVar = var;
410-
shouldAddNonisolated = false;
406+
existingIsolation = isolation;
407+
previousVar = var;
408+
shouldAddNonisolated = false;
409+
}
411410
}
412411
}
412+
413+
if (hasError)
414+
break;
413415
}
414416

415417
if (shouldAddNonisolated) {

test/Concurrency/isolated_default_arguments.swift

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -220,10 +220,21 @@ class C3 {
220220
var y = 0
221221
}
222222

223+
@MainActor class MultipleVars {
224+
var (x, y) = (0, 0)
225+
}
226+
223227
func callDefaultInit() async {
224228
_ = C2()
225229
_ = NonIsolatedInit()
226230
_ = NonIsolatedInit(x: 10)
231+
_ = MultipleVars()
232+
}
233+
234+
// expected-warning@+1 {{default initializer for 'MultipleVarsInvalid' cannot be both nonisolated and main actor-isolated; this is an error in Swift 6}}
235+
class MultipleVarsInvalid {
236+
// expected-note@+1 {{initializer for property 'x' is main actor-isolated}}
237+
@MainActor var (x, y) = (requiresMainActor(), requiresMainActor())
227238
}
228239

229240
@propertyWrapper

0 commit comments

Comments
 (0)