@@ -971,65 +971,237 @@ void swift::checkActorIsolation(const Expr *expr, const DeclContext *dc) {
971971 const_cast <Expr *>(expr)->walk (walker);
972972}
973973
974- ActorIsolation ActorIsolationRequest::evaluate (
975- Evaluator &evaluator, ValueDecl *value) const {
974+ // / Determine actor isolation solely from attributes.
975+ // /
976+ // / \returns the actor isolation determined from attributes alone (with no
977+ // / inference rules). Returns \c None if there were no attributes on this
978+ // / declaration.
979+ static Optional<ActorIsolation> getIsolationFromAttributes (Decl *decl) {
976980 // Look up attributes on the declaration that can affect its actor isolation.
977981 // If any of them are present, use that attribute.
978- auto independentAttr = value ->getAttrs ().getAttribute <ActorIndependentAttr>();
979- auto globalActorAttr = value ->getGlobalActorAttr ();
982+ auto independentAttr = decl ->getAttrs ().getAttribute <ActorIndependentAttr>();
983+ auto globalActorAttr = decl ->getGlobalActorAttr ();
980984 unsigned numIsolationAttrs =
981985 (independentAttr ? 1 : 0 ) + (globalActorAttr ? 1 : 0 );
982- if (numIsolationAttrs > 0 ) {
983- // Only one such attribute is valid.
984- if (numIsolationAttrs > 1 ) {
985- value->diagnose (
986- diag::actor_isolation_multiple_attr, value->getDescriptiveKind (),
987- value->getName (), independentAttr->getAttrName (),
988- globalActorAttr->second ->getName ().str ())
989- .highlight (independentAttr->getRangeWithAt ())
990- .highlight (globalActorAttr->first ->getRangeWithAt ());
991- }
986+ if (numIsolationAttrs == 0 )
987+ return None;
992988
993- // If the declaration is explicitly marked @actorIndependent, report it as
994- // independent.
995- if (independentAttr) {
996- return ActorIsolation::forIndependent ();
989+ // Only one such attribute is valid.
990+ if (numIsolationAttrs > 1 ) {
991+ DeclName name;
992+ if (auto value = dyn_cast<ValueDecl>(decl)) {
993+ name = value->getName ();
994+ } else if (auto ext = dyn_cast<ExtensionDecl>(decl)) {
995+ if (auto selfTypeDecl = ext->getSelfNominalTypeDecl ())
996+ name = selfTypeDecl->getName ();
997997 }
998998
999- // If the declaration is marked with a global actor, report it as being
1000- // part of that global actor.
1001- if (globalActorAttr) {
1002- TypeResolutionOptions options (TypeResolverContext::None);
1003- TypeResolution resolver = TypeResolution::forInterface (
1004- value->getInnermostDeclContext (), options, nullptr );
1005- Type globalActorType = resolver.resolveType (
1006- globalActorAttr->first ->getTypeRepr (), nullptr );
1007- if (!globalActorType || globalActorType->hasError ())
1008- return ActorIsolation::forUnspecified ();
999+ decl->diagnose (
1000+ diag::actor_isolation_multiple_attr, decl->getDescriptiveKind (),
1001+ name, independentAttr->getAttrName (),
1002+ globalActorAttr->second ->getName ().str ())
1003+ .highlight (independentAttr->getRangeWithAt ())
1004+ .highlight (globalActorAttr->first ->getRangeWithAt ());
1005+ }
1006+
1007+ // If the declaration is explicitly marked @actorIndependent, report it as
1008+ // independent.
1009+ if (independentAttr) {
1010+ return ActorIsolation::forIndependent ();
1011+ }
1012+
1013+ // If the declaration is marked with a global actor, report it as being
1014+ // part of that global actor.
1015+ if (globalActorAttr) {
1016+ TypeResolutionOptions options (TypeResolverContext::None);
1017+ TypeResolution resolver = TypeResolution::forInterface (
1018+ decl->getInnermostDeclContext (), options, nullptr );
1019+ Type globalActorType = resolver.resolveType (
1020+ globalActorAttr->first ->getTypeRepr (), nullptr );
1021+ if (!globalActorType || globalActorType->hasError ())
1022+ return ActorIsolation::forUnspecified ();
1023+
1024+ return ActorIsolation::forGlobalActor (globalActorType);
1025+ }
1026+
1027+ llvm_unreachable (" Forgot about an attribute?" );
1028+ }
1029+
1030+ // / Infer isolation from witnessed protocol requirements.
1031+ static Optional<ActorIsolation> getIsolationFromWitnessedRequirements (
1032+ ValueDecl *value) {
1033+ auto dc = value->getDeclContext ();
1034+ auto idc = dyn_cast_or_null<IterableDeclContext>(dc->getAsDecl ());
1035+ if (!idc)
1036+ return None;
1037+
1038+ // Walk through each of the conformances in this context, collecting any
1039+ // requirements that have actor isolation.
1040+ auto conformances = evaluateOrDefault (
1041+ dc->getASTContext ().evaluator ,
1042+ LookupAllConformancesInContextRequest{idc}, { });
1043+ using IsolatedRequirement =
1044+ std::tuple<ProtocolConformance *, ActorIsolation, ValueDecl *>;
1045+ SmallVector<IsolatedRequirement, 2 > isolatedRequirements;
1046+ for (auto conformance : conformances) {
1047+ auto protocol = conformance->getProtocol ();
1048+ for (auto found : protocol->lookupDirect (value->getName ())) {
1049+ if (!isa<ProtocolDecl>(found->getDeclContext ()))
1050+ continue ;
1051+
1052+ auto requirement = dyn_cast<ValueDecl>(found);
1053+ if (!requirement || isa<TypeDecl>(requirement))
1054+ continue ;
1055+
1056+ auto requirementIsolation = getActorIsolation (requirement);
1057+ if (requirementIsolation.isUnspecified ())
1058+ continue ;
1059+
1060+ auto witness = conformance->getWitnessDecl (requirement);
1061+ if (witness != value)
1062+ continue ;
10091063
1010- return ActorIsolation::forGlobalActor (globalActorType);
1064+ isolatedRequirements.push_back (
1065+ IsolatedRequirement{conformance, requirementIsolation, requirement});
10111066 }
1067+ }
1068+
1069+ // Filter out duplicate actors.
1070+ SmallPtrSet<CanType, 2 > globalActorTypes;
1071+ bool sawActorIndependent = false ;
1072+ isolatedRequirements.erase (
1073+ std::remove_if (isolatedRequirements.begin (), isolatedRequirements.end (),
1074+ [&](IsolatedRequirement &isolated) {
1075+ auto isolation = std::get<1 >(isolated);
1076+ switch (isolation) {
1077+ case ActorIsolation::ActorInstance:
1078+ llvm_unreachable (" protocol requirements cannot be actor instances" );
1079+
1080+ case ActorIsolation::Independent:
1081+ // We only need one @actorIndependent.
1082+ if (sawActorIndependent)
1083+ return true ;
1084+
1085+ sawActorIndependent = true ;
1086+ return false ;
1087+
1088+ case ActorIsolation::Unspecified:
1089+ return true ;
1090+
1091+ case ActorIsolation::GlobalActor: {
1092+ // Substitute into the global actor type.
1093+ auto conformance = std::get<0 >(isolated);
1094+ auto requirementSubs = SubstitutionMap::getProtocolSubstitutions (
1095+ conformance->getProtocol (), dc->getSelfTypeInContext (),
1096+ ProtocolConformanceRef (conformance));
1097+ Type globalActor = isolation.getGlobalActor ().subst (requirementSubs);
1098+ if (!globalActorTypes.insert (globalActor->getCanonicalType ()).second )
1099+ return true ;
1100+
1101+ // Update the global actor type, now that we've done this substitution.
1102+ std::get<1 >(isolated) = ActorIsolation::forGlobalActor (globalActor);
1103+ return false ;
1104+ }
1105+ }
1106+ }),
1107+ isolatedRequirements.end ());
1108+
1109+ if (isolatedRequirements.size () != 1 )
1110+ return None;
1111+
1112+ return std::get<1 >(isolatedRequirements.front ());
1113+ }
1114+
1115+ ActorIsolation ActorIsolationRequest::evaluate (
1116+ Evaluator &evaluator, ValueDecl *value) const {
1117+ // If this declaration has one of the actor isolation attributes, report
1118+ // that.
1119+ if (auto isolationFromAttr = getIsolationFromAttributes (value)) {
1120+ return *isolationFromAttr;
1121+ }
1122+
1123+ // Determine the default isolation for this declaration, which may still be
1124+ // overridden by other inference rules.
1125+ ActorIsolation defaultIsolation = ActorIsolation::forUnspecified ();
1126+
1127+ // Check for instance members of actor classes, which are part of
1128+ // actor-isolated state.
1129+ auto classDecl = value->getDeclContext ()->getSelfClassDecl ();
1130+ if (classDecl && classDecl->isActor () && value->isInstanceMember ()) {
1131+ defaultIsolation = ActorIsolation::forActorInstance (classDecl);
1132+ }
10121133
1013- llvm_unreachable (" Forgot about an attribute?" );
1134+ // Disable inference of actor attributes outside of normal Swift source files.
1135+ if (auto sourceFile = value->getDeclContext ()->getParentSourceFile ()) {
1136+ switch (sourceFile->Kind ) {
1137+ case SourceFileKind::Interface:
1138+ case SourceFileKind::SIL:
1139+ return defaultIsolation;
1140+
1141+ case SourceFileKind::Library:
1142+ case SourceFileKind::Main:
1143+ // Attempt inference below.
1144+ break ;
1145+ }
1146+ } else {
1147+ return defaultIsolation;
10141148 }
10151149
1150+ // Function used when returning an inferred isolation.
1151+ auto inferredIsolation = [&](ActorIsolation inferred) {
1152+ return inferred;
1153+ };
1154+
10161155 // If the declaration overrides another declaration, it must have the same
10171156 // actor isolation.
10181157 if (auto overriddenValue = value->getOverriddenDecl ()) {
10191158 if (auto isolation = getActorIsolation (overriddenValue))
1020- return isolation;
1159+ return inferredIsolation ( isolation) ;
10211160 }
10221161
1023- // Check for instance members of actor classes, which are part of
1024- // actor-isolated state.
1025- auto classDecl = value->getDeclContext ()->getSelfClassDecl ();
1026- if (classDecl && classDecl->isActor () && value->isInstanceMember ()) {
1027- // Part of the actor's isolated state.
1028- return ActorIsolation::forActorInstance (classDecl);
1162+ // If the declaration witnesses a protocol requirement that is isolated,
1163+ // use that.
1164+ if (auto witnessedIsolation = getIsolationFromWitnessedRequirements (value)) {
1165+ return inferredIsolation (*witnessedIsolation);
1166+ }
1167+
1168+ // If the declaration is a class with a superclass that has specified
1169+ // isolation, use that.
1170+ if (auto classDecl = dyn_cast<ClassDecl>(value)) {
1171+ if (auto superclassDecl = classDecl->getSuperclassDecl ()) {
1172+ auto superclassIsolation = getActorIsolation (superclassDecl);
1173+ if (!superclassIsolation.isUnspecified ())
1174+ return inferredIsolation (superclassIsolation);
1175+ }
1176+ }
1177+
1178+ // If this is an accessor, use the actor isolation of its storage
1179+ // declaration.
1180+ if (auto accessor = dyn_cast<AccessorDecl>(value)) {
1181+ auto storageIsolation = getActorIsolation (accessor->getStorage ());
1182+ if (!storageIsolation.isUnspecified ())
1183+ return inferredIsolation (storageIsolation);
1184+ }
1185+
1186+ // If the declaration is in an extension that has one of the isolation
1187+ // attributes, use that.
1188+ if (auto ext = dyn_cast<ExtensionDecl>(value->getDeclContext ())) {
1189+ if (auto isolationFromAttr = getIsolationFromAttributes (ext)) {
1190+ return inferredIsolation (*isolationFromAttr);
1191+ }
1192+ }
1193+
1194+ // If the declaration is in a nominal type (or extension thereof) that
1195+ // has isolation, use that.
1196+ if (auto selfTypeDecl = value->getDeclContext ()->getSelfNominalTypeDecl ()) {
1197+ auto selfTypeIsolation = getActorIsolation (selfTypeDecl);
1198+ if (!selfTypeIsolation.isUnspecified ()) {
1199+ return inferredIsolation (selfTypeIsolation);
1200+ }
10291201 }
10301202
1031- // Everything else is unspecified .
1032- return ActorIsolation::forUnspecified () ;
1203+ // Default isolation for this member .
1204+ return defaultIsolation ;
10331205}
10341206
10351207ActorIsolation swift::getActorIsolation (ValueDecl *value) {
0 commit comments