Skip to content

Commit cc1fd1c

Browse files
committed
[Concurrency] Don't skip pattern bindings with multiple vars when inferring the
isolation of implicit initializers.
1 parent 20829fa commit cc1fd1c

File tree

2 files changed

+59
-46
lines changed

2 files changed

+59
-46
lines changed

lib/Sema/CodeSynthesis.cpp

+48-46
Original file line numberDiff line numberDiff line change
@@ -355,62 +355,64 @@ static ConstructorDecl *createImplicitConstructor(NominalTypeDecl *decl,
355355
VarDecl *previousVar = nullptr;
356356

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

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

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

409-
existingIsolation = isolation;
410-
previousVar = var;
411-
shouldAddNonisolated = false;
407+
existingIsolation = isolation;
408+
previousVar = var;
409+
shouldAddNonisolated = false;
410+
}
412411
}
413412
}
413+
414+
if (hasError)
415+
break;
414416
}
415417

416418
if (shouldAddNonisolated) {

test/Concurrency/isolated_default_arguments.swift

+11
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)