@@ -971,65 +971,237 @@ void swift::checkActorIsolation(const Expr *expr, const DeclContext *dc) {
971
971
const_cast <Expr *>(expr)->walk (walker);
972
972
}
973
973
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) {
976
980
// Look up attributes on the declaration that can affect its actor isolation.
977
981
// 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 ();
980
984
unsigned numIsolationAttrs =
981
985
(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;
992
988
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 ();
997
997
}
998
998
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 ;
1009
1063
1010
- return ActorIsolation::forGlobalActor (globalActorType);
1064
+ isolatedRequirements.push_back (
1065
+ IsolatedRequirement{conformance, requirementIsolation, requirement});
1011
1066
}
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
+ }
1012
1133
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;
1014
1148
}
1015
1149
1150
+ // Function used when returning an inferred isolation.
1151
+ auto inferredIsolation = [&](ActorIsolation inferred) {
1152
+ return inferred;
1153
+ };
1154
+
1016
1155
// If the declaration overrides another declaration, it must have the same
1017
1156
// actor isolation.
1018
1157
if (auto overriddenValue = value->getOverriddenDecl ()) {
1019
1158
if (auto isolation = getActorIsolation (overriddenValue))
1020
- return isolation;
1159
+ return inferredIsolation ( isolation) ;
1021
1160
}
1022
1161
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
+ }
1029
1201
}
1030
1202
1031
- // Everything else is unspecified .
1032
- return ActorIsolation::forUnspecified () ;
1203
+ // Default isolation for this member .
1204
+ return defaultIsolation ;
1033
1205
}
1034
1206
1035
1207
ActorIsolation swift::getActorIsolation (ValueDecl *value) {
0 commit comments