|
19 | 19 | #include "TypeCheckType.h" |
20 | 20 | #include "swift/Strings.h" |
21 | 21 | #include "swift/AST/ASTWalker.h" |
| 22 | +#include "swift/AST/GenericEnvironment.h" |
22 | 23 | #include "swift/AST/Initializer.h" |
23 | 24 | #include "swift/AST/ParameterList.h" |
24 | 25 | #include "swift/AST/ProtocolConformance.h" |
@@ -300,7 +301,7 @@ Type swift::getExplicitGlobalActor(ClosureExpr *closure) { |
300 | 301 |
|
301 | 302 | /// Determine the isolation rules for a given declaration. |
302 | 303 | ActorIsolationRestriction ActorIsolationRestriction::forDeclaration( |
303 | | - ConcreteDeclRef declRef, bool fromExpression) { |
| 304 | + ConcreteDeclRef declRef, const DeclContext *fromDC, bool fromExpression) { |
304 | 305 | auto decl = declRef.getDecl(); |
305 | 306 |
|
306 | 307 | switch (decl->getKind()) { |
@@ -355,7 +356,12 @@ ActorIsolationRestriction ActorIsolationRestriction::forDeclaration( |
355 | 356 | // actors. |
356 | 357 | bool isAccessibleAcrossActors = false; |
357 | 358 | if (auto var = dyn_cast<VarDecl>(decl)) { |
358 | | - if (var->isLet()) |
| 359 | + // A 'let' declaration is accessible across actors if it is either |
| 360 | + // nonisolated or it is accessed from within the same module. |
| 361 | + if (var->isLet() && |
| 362 | + (isolation == ActorIsolation::Independent || |
| 363 | + var->getDeclContext()->getParentModule() == |
| 364 | + fromDC->getParentModule())) |
359 | 365 | isAccessibleAcrossActors = true; |
360 | 366 | } |
361 | 367 |
|
@@ -1492,7 +1498,8 @@ namespace { |
1492 | 1498 | bool result = false; |
1493 | 1499 | auto checkDiagnostic = [this, call, isPartialApply, |
1494 | 1500 | &result](ValueDecl *decl, SourceLoc argLoc) { |
1495 | | - auto isolation = ActorIsolationRestriction::forDeclaration(decl); |
| 1501 | + auto isolation = ActorIsolationRestriction::forDeclaration( |
| 1502 | + decl, getDeclContext()); |
1496 | 1503 | switch (isolation) { |
1497 | 1504 | case ActorIsolationRestriction::Unrestricted: |
1498 | 1505 | case ActorIsolationRestriction::Unsafe: |
@@ -1611,11 +1618,6 @@ namespace { |
1611 | 1618 |
|
1612 | 1619 | // is it an access to a property? |
1613 | 1620 | if (isPropOrSubscript(decl)) { |
1614 | | - // we assume let-bound properties are taken care of elsewhere, |
1615 | | - // since they are never implicitly async. |
1616 | | - assert(!isa<VarDecl>(decl) || cast<VarDecl>(decl)->isLet() == false |
1617 | | - && "unexpected let-bound property; never implicitly async!"); |
1618 | | - |
1619 | 1621 | if (auto declRef = dyn_cast_or_null<DeclRefExpr>(context)) { |
1620 | 1622 | if (usageEnv(declRef) == VarRefUseEnv::Read) { |
1621 | 1623 |
|
@@ -2092,7 +2094,8 @@ namespace { |
2092 | 2094 | // The decl referred to by the path component cannot be within an actor. |
2093 | 2095 | if (component.hasDeclRef()) { |
2094 | 2096 | auto concDecl = component.getDeclRef(); |
2095 | | - auto isolation = ActorIsolationRestriction::forDeclaration(concDecl); |
| 2097 | + auto isolation = ActorIsolationRestriction::forDeclaration( |
| 2098 | + concDecl, getDeclContext()); |
2096 | 2099 |
|
2097 | 2100 | switch (isolation.getKind()) { |
2098 | 2101 | case ActorIsolationRestriction::Unsafe: |
@@ -2210,7 +2213,8 @@ namespace { |
2210 | 2213 | return checkLocalCapture(valueRef, loc, declRefExpr); |
2211 | 2214 |
|
2212 | 2215 | switch (auto isolation = |
2213 | | - ActorIsolationRestriction::forDeclaration(valueRef)) { |
| 2216 | + ActorIsolationRestriction::forDeclaration( |
| 2217 | + valueRef, getDeclContext())) { |
2214 | 2218 | case ActorIsolationRestriction::Unrestricted: |
2215 | 2219 | return false; |
2216 | 2220 |
|
@@ -2249,7 +2253,8 @@ namespace { |
2249 | 2253 |
|
2250 | 2254 | auto member = memberRef.getDecl(); |
2251 | 2255 | switch (auto isolation = |
2252 | | - ActorIsolationRestriction::forDeclaration(memberRef)) { |
| 2256 | + ActorIsolationRestriction::forDeclaration( |
| 2257 | + memberRef, getDeclContext())) { |
2253 | 2258 | case ActorIsolationRestriction::Unrestricted: |
2254 | 2259 | return false; |
2255 | 2260 |
|
@@ -3028,6 +3033,19 @@ ActorIsolation ActorIsolationRequest::evaluate( |
3028 | 3033 | // If this declaration has one of the actor isolation attributes, report |
3029 | 3034 | // that. |
3030 | 3035 | if (auto isolationFromAttr = getIsolationFromAttributes(value)) { |
| 3036 | + // Nonisolated declarations must involve Sendable types. |
| 3037 | + if (*isolationFromAttr == ActorIsolation::Independent) { |
| 3038 | + SubstitutionMap subs; |
| 3039 | + if (auto genericEnv = value->getInnermostDeclContext() |
| 3040 | + ->getGenericEnvironmentOfContext()) { |
| 3041 | + subs = genericEnv->getForwardingSubstitutionMap(); |
| 3042 | + } |
| 3043 | + diagnoseNonConcurrentTypesInReference( |
| 3044 | + ConcreteDeclRef(value, subs), |
| 3045 | + value->getDeclContext()->getParentModule(), value->getLoc(), |
| 3046 | + ConcurrentReferenceKind::Nonisolated); |
| 3047 | + } |
| 3048 | + |
3031 | 3049 | return *isolationFromAttr; |
3032 | 3050 | } |
3033 | 3051 |
|
|
0 commit comments