Skip to content

Commit 1875817

Browse files
committed
[Concurrency] Make #isolation macro expansions explicit.
Macro expansions are never considered implicit. They have valid source locations in their macro expansion buffer, they do not cause implicit 'self' capture diagnostics, etc. This fixes an issue where existing code that iterates over an async sequence in an escaping closure would diagnose a use of implicit 'self' via the '#isolation' argument to 'next()'.
1 parent aa99cbc commit 1875817

File tree

3 files changed

+34
-12
lines changed

3 files changed

+34
-12
lines changed

lib/Sema/TypeCheckConcurrency.cpp

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3512,6 +3512,12 @@ namespace {
35123512
auto isolation = getActorIsolationOfContext(
35133513
const_cast<DeclContext *>(getDeclContext()),
35143514
getClosureActorIsolation);
3515+
auto *dc = const_cast<DeclContext *>(getDeclContext());
3516+
3517+
// Note that macro expansions are never implicit. They have
3518+
// valid source locations in their macro expansion buffer, they
3519+
// do not cause implicit 'self' capture diagnostics, etc.
3520+
35153521
Expr *actorExpr = nullptr;
35163522
Type optionalAnyActorType = isolationExpr->getType();
35173523
switch (isolation) {
@@ -3533,7 +3539,7 @@ namespace {
35333539
}
35343540
actorExpr = new (ctx) DeclRefExpr(
35353541
const_cast<VarDecl *>(var), DeclNameLoc(loc),
3536-
/*Implicit=*/true);
3542+
/*implicit=*/false);
35373543

35383544
// For a distributed actor, we need to retrieve the local
35393545
// actor.
@@ -3547,10 +3553,11 @@ namespace {
35473553
// Form a <global actor type>.shared reference.
35483554
Type globalActorType = getDeclContext()->mapTypeIntoContext(
35493555
isolation.getGlobalActor());
3550-
auto typeExpr = TypeExpr::createImplicit(globalActorType, ctx);
3556+
auto typeExpr = TypeExpr::createForDecl(
3557+
DeclNameLoc(loc), globalActorType->getAnyNominal(), dc);
35513558
actorExpr = new (ctx) UnresolvedDotExpr(
3552-
typeExpr, loc, DeclNameRef(ctx.Id_shared), DeclNameLoc(),
3553-
/*implicit=*/true);
3559+
typeExpr, loc, DeclNameRef(ctx.Id_shared), DeclNameLoc(loc),
3560+
/*implicit=*/false);
35543561
break;
35553562
}
35563563

@@ -3560,14 +3567,14 @@ namespace {
35603567
case ActorIsolation::Unspecified:
35613568
case ActorIsolation::Nonisolated:
35623569
case ActorIsolation::NonisolatedUnsafe:
3563-
actorExpr = new (ctx) NilLiteralExpr(loc, /*implicit=*/true);
3570+
actorExpr = new (ctx) NilLiteralExpr(loc, /*implicit=*/false);
35643571
break;
35653572
}
35663573

35673574

35683575
// Convert the actor argument to the appropriate type.
35693576
(void)TypeChecker::typeCheckExpression(
3570-
actorExpr, const_cast<DeclContext *>(getDeclContext()),
3577+
actorExpr, dc,
35713578
constraints::ContextualTypeInfo(
35723579
optionalAnyActorType, CTP_CallArgument));
35733580

test/Concurrency/isolation_macro.swift

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ extension A {
3333
// CHECK: rewritten=current_context_isolation_expr
3434
// CHECK-NEXT: inject_into_optional
3535
// CHECK-NEXT: erasure_expr
36-
// CHECK: declref_expr implicit type="A"{{.*}}self@
36+
// CHECK: declref_expr type="A"{{.*}}self@
3737
_ = #isolation
3838
}
3939
}
@@ -45,7 +45,7 @@ func actorIsolationToParam(_ isolatedParam: isolated A) {
4545
// CHECK: rewritten=current_context_isolation_expr
4646
// CHECK-NEXT: inject_into_optional
4747
// CHECK-NEXT: erasure_expr
48-
// CHECK: declref_expr implicit type="A"{{.*}}isolatedParam@
48+
// CHECK: declref_expr type="A"{{.*}}isolatedParam@
4949
_ = #isolation
5050
}
5151

@@ -57,8 +57,8 @@ func mainActorIsolated() {
5757
// CHECK: rewritten=current_context_isolation_expr
5858
// CHECK-NEXT: inject_into_optional
5959
// CHECK-NEXT: erasure_expr
60-
// CHECK: member_ref_expr implicit type="MainActor" decl="_Concurrency.(file).MainActor.shared"
61-
// CHECK-NEXT: type_expr implicit type="MainActor.Type"
60+
// CHECK: member_ref_expr type="MainActor" location=@__swiftmacro_{{.*}} decl="_Concurrency.(file).MainActor.shared"
61+
// CHECK-NEXT: type_expr type="MainActor.Type"
6262
_ = #isolation
6363
}
6464

@@ -72,9 +72,24 @@ func closureIsolatedToOuterParam(_ isolatedParam: isolated A) {
7272
// CHECK: rewritten=current_context_isolation_expr
7373
// CHECK-NEXT: inject_into_optional
7474
// CHECK-NEXT: erasure_expr
75-
// CHECK: declref_expr implicit type="A"{{.*}}isolatedParam@
75+
// CHECK: declref_expr type="A"{{.*}}isolatedParam@
7676
acceptClosure {
7777
_ = #isolation
7878
print(isolatedParam)
7979
}
8080
}
81+
82+
func acceptEscapingClosure(_ fn: @escaping () -> Void) { }
83+
84+
@available(SwiftStdlib 5.1, *)
85+
extension A {
86+
func f() {
87+
// Make sure this doesn't diagnose a use of implicit 'self'
88+
acceptEscapingClosure {
89+
_ = #isolation
90+
self.g()
91+
}
92+
}
93+
94+
func g() {}
95+
}

test/Distributed/isolation_macro.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ extension DistributedActor {
1616
// CHECK: rewritten=current_context_isolation_expr
1717
// CHECK-NEXT: inject_into_optional
1818
// CHECK: member_ref_expr{{.*}}asLocalActor
19-
// CHECK: declref_expr implicit type="Self"
19+
// CHECK: declref_expr type="Self"
2020
_ = #isolation
2121
}
2222
}

0 commit comments

Comments
 (0)