Skip to content

Commit c6d84b3

Browse files
committed
NFC: Refactor inout error msg emission
Global actors need to work with non-lookup non-member values. As such, we can't rely on the argument of the call being a LookupExpr. The error message emission logic only relies on the declaration and the subExpr argument. This refactor will allow us to avoid having another switch statement for the global-actor case that more-or-less does the same thing.
1 parent f3da35a commit c6d84b3

File tree

1 file changed

+33
-28
lines changed

1 file changed

+33
-28
lines changed

lib/Sema/TypeCheckConcurrency.cpp

Lines changed: 33 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -904,45 +904,50 @@ namespace {
904904
return false;
905905

906906
Expr *subArg = arg->getSubExpr();
907+
ValueDecl *valueDecl = nullptr;
907908
if (LookupExpr *baseArg = dyn_cast<LookupExpr>(subArg)) {
908909
while (LookupExpr *nextLayer = dyn_cast<LookupExpr>(baseArg->getBase()))
909910
baseArg = nextLayer;
910911
// subArg: the actual property being passed inout
911912
// baseArg: the property in the actor who's property is being passed
912913
// inout
913914

914-
auto memberDecl = baseArg->getMember().getDecl();
915-
auto isolation = ActorIsolationRestriction::forDeclaration(memberDecl);
916-
switch (isolation) {
917-
case ActorIsolationRestriction::Unrestricted:
918-
case ActorIsolationRestriction::LocalCapture:
919-
case ActorIsolationRestriction::Unsafe:
920-
case ActorIsolationRestriction::GlobalActor: // TODO: handle global
921-
// actors
922-
break;
923-
case ActorIsolationRestriction::ActorSelf: {
924-
if (isPartialApply) {
925-
// The partially applied InoutArg is a property of actor. This can
926-
// really only happen when the property is a struct with a mutating
927-
// async method.
928-
if (auto partialApply = dyn_cast<ApplyExpr>(call->getFn())) {
929-
ValueDecl *fnDecl =
930-
cast<DeclRefExpr>(partialApply->getFn())->getDecl();
931-
ctx.Diags.diagnose(
932-
call->getLoc(), diag::actor_isolated_mutating_func,
933-
fnDecl->getName(), memberDecl->getDescriptiveKind(),
934-
memberDecl->getName());
935-
return true;
936-
}
937-
} else {
915+
valueDecl = baseArg->getMember().getDecl();
916+
} else if (DeclRefExpr *declExpr = dyn_cast<DeclRefExpr>(subArg)) {
917+
valueDecl = declExpr->getDecl();
918+
} else {
919+
llvm_unreachable("Inout argument is neither a lookup nor decl.");
920+
}
921+
assert(valueDecl != nullptr && "valueDecl was never set!");
922+
auto isolation = ActorIsolationRestriction::forDeclaration(valueDecl);
923+
switch (isolation) {
924+
case ActorIsolationRestriction::Unrestricted:
925+
case ActorIsolationRestriction::LocalCapture:
926+
case ActorIsolationRestriction::Unsafe:
927+
case ActorIsolationRestriction::GlobalActor: // TODO: handle global
928+
// actors
929+
break;
930+
case ActorIsolationRestriction::ActorSelf: {
931+
if (isPartialApply) {
932+
// The partially applied InoutArg is a property of actor. This can
933+
// really only happen when the property is a struct with a mutating
934+
// async method.
935+
if (auto partialApply = dyn_cast<ApplyExpr>(call->getFn())) {
936+
ValueDecl *fnDecl =
937+
cast<DeclRefExpr>(partialApply->getFn())->getDecl();
938938
ctx.Diags.diagnose(
939-
subArg->getLoc(), diag::actor_isolated_inout_state,
940-
memberDecl->getDescriptiveKind(), memberDecl->getName(),
941-
call->implicitlyAsync());
939+
call->getLoc(), diag::actor_isolated_mutating_func,
940+
fnDecl->getName(), valueDecl->getDescriptiveKind(),
941+
valueDecl->getName());
942942
return true;
943943
}
944+
} else {
945+
ctx.Diags.diagnose(
946+
subArg->getLoc(), diag::actor_isolated_inout_state,
947+
valueDecl->getDescriptiveKind(), valueDecl->getName(), call->implicitlyAsync());
948+
return true;
944949
}
945-
}
950+
}
946951
}
947952
return false;
948953
}

0 commit comments

Comments
 (0)