Skip to content

Commit b57fd71

Browse files
committed
[Concurrency] Don't produce notes about invalid calls for partial applies
If invalid actor reference is a partial application, let's not produce a note that talks about invalid "call".
1 parent d303cb1 commit b57fd71

File tree

3 files changed

+30
-13
lines changed

3 files changed

+30
-13
lines changed

lib/Sema/TypeCheckConcurrency.cpp

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1082,7 +1082,7 @@ namespace {
10821082
if (auto lookup = dyn_cast<LookupExpr>(expr)) {
10831083
checkMemberReference(lookup->getBase(), lookup->getMember(),
10841084
lookup->getLoc(),
1085-
/*isEscapingPartialApply*/false,
1085+
/*partialApply*/None,
10861086
lookup);
10871087
return { true, expr };
10881088
}
@@ -1108,7 +1108,7 @@ namespace {
11081108
// implicitly async, regardless of whether they are escaping.
11091109
checkMemberReference(
11101110
partialApply->base, memberRef->first, memberRef->second,
1111-
partialApply->isEscaping);
1111+
partialApply);
11121112

11131113
partialApply->base->walk(*this);
11141114

@@ -1127,7 +1127,7 @@ namespace {
11271127
if (auto memberRef = findMemberReference(fn)) {
11281128
checkMemberReference(
11291129
call->getArg(), memberRef->first, memberRef->second,
1130-
/*isEscapingPartialApply=*/false, call);
1130+
/*partialApply=*/None, call);
11311131

11321132
call->getArg()->walk(*this);
11331133

@@ -1951,7 +1951,7 @@ namespace {
19511951
/// in an invalid or unsafe way such that a diagnostic was emitted.
19521952
bool checkMemberReference(
19531953
Expr *base, ConcreteDeclRef memberRef, SourceLoc memberLoc,
1954-
bool isEscapingPartialApply = false,
1954+
Optional<PartialApplyThunkInfo> partialApply = None,
19551955
Expr *context = nullptr) {
19561956
if (!base || !memberRef)
19571957
return false;
@@ -1999,7 +1999,9 @@ namespace {
19991999
getNearestEnclosingActorContext(getDeclContext()),
20002000
useKind
20012001
);
2002-
noteIsolatedActorMember(member, context);
2002+
2003+
if (!partialApply)
2004+
noteIsolatedActorMember(member, context);
20032005
return true;
20042006
}
20052007

@@ -2009,12 +2011,11 @@ namespace {
20092011
case ActorIsolation::ActorInstance:
20102012
// An escaping partial application of something that is part of
20112013
// the actor's isolated state is never permitted.
2012-
if (isEscapingPartialApply) {
2014+
if (partialApply && partialApply->isEscaping) {
20132015
ctx.Diags.diagnose(
20142016
memberLoc, diag::actor_isolated_partial_apply,
20152017
member->getDescriptiveKind(),
20162018
member->getName());
2017-
noteIsolatedActorMember(member, context);
20182019
return true;
20192020
}
20202021

@@ -2037,7 +2038,9 @@ namespace {
20372038
auto diag = findActorIndependentReason(curDC);
20382039
ctx.Diags.diagnose(memberLoc, diag, member->getDescriptiveKind(),
20392040
member->getName(), useKind);
2040-
noteIsolatedActorMember(member, context);
2041+
2042+
if (!partialApply)
2043+
noteIsolatedActorMember(member, context);
20412044
return true;
20422045
}
20432046

@@ -2059,7 +2062,9 @@ namespace {
20592062
contextIsolation.getGlobalActor(), useKind,
20602063
result == AsyncMarkingResult::SyncContext
20612064
);
2062-
noteIsolatedActorMember(member, context);
2065+
2066+
if (!partialApply)
2067+
noteIsolatedActorMember(member, context);
20632068
return true;
20642069
}
20652070
}

test/Concurrency/actor_call_implicitly_async.swift

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,11 +33,9 @@ actor BankAccount {
3333
curBalance = initialDeposit
3434
}
3535

36-
// NOTE: this func is accessed through both async and sync calls.
37-
// expected-note@+1 {{calls to instance method 'balance()' from outside of its actor context are implicitly asynchronous}}
3836
func balance() -> Int { return curBalance }
3937

40-
// expected-note@+1 2{{calls to instance method 'deposit' from outside of its actor context are implicitly asynchronous}}
38+
// expected-note@+1 {{calls to instance method 'deposit' from outside of its actor context are implicitly asynchronous}}
4139
func deposit(_ amount : Int) -> Int {
4240
guard amount >= 0 else { return 0 }
4341

test/Concurrency/actor_isolation.swift

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ actor MyActor: MySuperActor { // expected-error{{actor types do not support inhe
7070
class func synchronousClass() { }
7171
static func synchronousStatic() { }
7272

73-
func synchronous() -> String { text.first ?? "nothing" } // expected-note 19{{calls to instance method 'synchronous()' from outside of its actor context are implicitly asynchronous}}
73+
func synchronous() -> String { text.first ?? "nothing" } // expected-note 5{{calls to instance method 'synchronous()' from outside of its actor context are implicitly asynchronous}}
7474
func asynchronous() async -> String {
7575
super.superState += 4
7676
return synchronous()
@@ -820,3 +820,17 @@ func test_conforming_actor_to_global_actor_protocol() {
820820
actor MyValue : GloballyIsolatedProto {}
821821
// expected-error@-1 {{actor 'MyValue' cannot conform to global actor isolated protocol 'GloballyIsolatedProto'}}
822822
}
823+
824+
func test_invalid_reference_to_actor_member_without_a_call_note() {
825+
actor A {
826+
func partial() { }
827+
}
828+
829+
actor Test {
830+
func returnPartial(other: A) async -> () async -> () {
831+
let a = other.partial
832+
// expected-error@-1 {{actor-isolated instance method 'partial()' can only be referenced from inside the actor}}
833+
return a
834+
}
835+
}
836+
}

0 commit comments

Comments
 (0)