@@ -904,45 +904,50 @@ namespace {
904
904
return false ;
905
905
906
906
Expr *subArg = arg->getSubExpr ();
907
+ ValueDecl *valueDecl = nullptr ;
907
908
if (LookupExpr *baseArg = dyn_cast<LookupExpr>(subArg)) {
908
909
while (LookupExpr *nextLayer = dyn_cast<LookupExpr>(baseArg->getBase ()))
909
910
baseArg = nextLayer;
910
911
// subArg: the actual property being passed inout
911
912
// baseArg: the property in the actor who's property is being passed
912
913
// inout
913
914
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 ();
938
938
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 ());
942
942
return true ;
943
943
}
944
+ } else {
945
+ ctx.Diags .diagnose (
946
+ subArg->getLoc (), diag::actor_isolated_inout_state,
947
+ valueDecl->getDescriptiveKind (), valueDecl->getName (), call->implicitlyAsync ());
948
+ return true ;
944
949
}
945
- }
950
+ }
946
951
}
947
952
return false ;
948
953
}
0 commit comments