@@ -1447,7 +1447,7 @@ static bool memberAccessHasSpecialPermissionInSwift5(DeclContext const *refCxt,
14471447 member->getDescriptiveKind (),
14481448 member->getName (),
14491449 useKindInt,
1450- baseActor.kind ,
1450+ baseActor.kind + 1 ,
14511451 baseActor.globalActor ,
14521452 getActorIsolation (const_cast <ValueDecl *>(member)))
14531453 .warnUntilSwiftVersion (6 );
@@ -1881,16 +1881,23 @@ namespace {
18811881 recordMutableVarParent (load, load->getSubExpr ());
18821882
18831883 if (auto lookup = dyn_cast<LookupExpr>(expr)) {
1884- checkMemberReference (lookup->getBase (), lookup->getMember (),
1884+ checkReference (lookup->getBase (), lookup->getMember (),
18851885 lookup->getLoc (),
18861886 /* partialApply*/ None,
18871887 lookup);
18881888 return { true , expr };
18891889 }
18901890
18911891 if (auto declRef = dyn_cast<DeclRefExpr>(expr)) {
1892- checkNonMemberReference (
1893- declRef->getDeclRef (), declRef->getLoc (), declRef);
1892+ auto valueRef = declRef->getDeclRef ();
1893+ auto value = valueRef.getDecl ();
1894+ auto loc = declRef->getLoc ();
1895+
1896+ // FIXME: Should this be subsumed in reference checking?
1897+ if (value->isLocalCapture ())
1898+ checkLocalCapture (valueRef, loc, declRef);
1899+ else
1900+ checkReference (nullptr , valueRef, loc, None, declRef);
18941901 return { true , expr };
18951902 }
18961903
@@ -1907,7 +1914,7 @@ namespace {
19071914 if (auto memberRef = findMemberReference (partialApply->fn )) {
19081915 // NOTE: partially-applied thunks are never annotated as
19091916 // implicitly async, regardless of whether they are escaping.
1910- checkMemberReference (
1917+ checkReference (
19111918 partialApply->base , memberRef->first , memberRef->second ,
19121919 partialApply);
19131920
@@ -1926,7 +1933,7 @@ namespace {
19261933 if (auto call = dyn_cast<SelfApplyExpr>(expr)) {
19271934 Expr *fn = call->getFn ()->getValueProvidingExpr ();
19281935 if (auto memberRef = findMemberReference (fn)) {
1929- checkMemberReference (
1936+ checkReference (
19301937 call->getBase (), memberRef->first , memberRef->second ,
19311938 /* partialApply=*/ None, call);
19321939
@@ -2215,7 +2222,15 @@ namespace {
22152222 if (!var || var->isLet ())
22162223 return false ;
22172224
2218- if (!var->getDeclContext ()->isModuleScopeContext () && !var->isStatic ())
2225+ if (!var->getDeclContext ()->isModuleScopeContext () &&
2226+ !(var->getDeclContext ()->isTypeContext () && !var->isInstanceMember ()))
2227+ return false ;
2228+
2229+ if (!var->hasStorage ())
2230+ return false ;
2231+
2232+ // If it's actor-isolated, it's already been dealt with.
2233+ if (getActorIsolation (value).isActorIsolated ())
22192234 return false ;
22202235
22212236 ctx.Diags .diagnose (
@@ -2604,97 +2619,6 @@ namespace {
26042619 return false ;
26052620 }
26062621
2607- // / Check a reference to an entity within a global actor.
2608- bool checkGlobalActorReference (
2609- ConcreteDeclRef valueRef, SourceLoc loc, Type globalActor,
2610- bool isCrossActor,
2611- Expr *context) {
2612- ValueDecl *value = valueRef.getDecl ();
2613- auto declContext = const_cast <DeclContext *>(getDeclContext ());
2614-
2615- // Check whether we are within the same isolation context, in which
2616- // case there is nothing further to check,
2617- auto contextIsolation = getInnermostIsolatedContext (declContext);
2618- if (contextIsolation.isGlobalActor () &&
2619- contextIsolation.getGlobalActor ()->isEqual (globalActor)) {
2620- return false ;
2621- }
2622-
2623- // A cross-actor access requires types to be concurrent-safe.
2624- if (isCrossActor) {
2625- return diagnoseNonSendableTypesInReference (
2626- valueRef, getDeclContext (), loc,
2627- SendableCheckReason::CrossActor);
2628- }
2629-
2630- // Call is implicitly asynchronous.
2631- auto result = tryMarkImplicitlyAsync (
2632- loc, valueRef, context,
2633- ImplicitActorHopTarget::forGlobalActor (globalActor),
2634- /* FIXME if we get global distributed actors*/ false );
2635- if (result == AsyncMarkingResult::FoundAsync)
2636- return false ;
2637-
2638- // Diagnose failures.
2639- switch (contextIsolation) {
2640- case ActorIsolation::ActorInstance: {
2641- auto useKind = static_cast <unsigned >(
2642- kindOfUsage (value, context).getValueOr (VarRefUseEnv::Read));
2643-
2644- ctx.Diags .diagnose (loc, diag::global_actor_from_instance_actor_context,
2645- value->getDescriptiveKind (), value->getName (),
2646- globalActor, contextIsolation.getActor ()->getName (),
2647- useKind, result == AsyncMarkingResult::SyncContext);
2648- noteIsolatedActorMember (value, context);
2649- return true ;
2650- }
2651-
2652- case ActorIsolation::GlobalActor:
2653- case ActorIsolation::GlobalActorUnsafe: {
2654- auto useKind = static_cast <unsigned >(
2655- kindOfUsage (value, context).getValueOr (VarRefUseEnv::Read));
2656-
2657- // Otherwise, this is a problematic global actor decl reference.
2658- ctx.Diags .diagnose (
2659- loc, diag::global_actor_from_other_global_actor_context,
2660- value->getDescriptiveKind (), value->getName (), globalActor,
2661- contextIsolation.getGlobalActor (), useKind,
2662- result == AsyncMarkingResult::SyncContext);
2663- noteIsolatedActorMember (value, context);
2664- return true ;
2665- }
2666-
2667- case ActorIsolation::Independent: {
2668- auto useKind = static_cast <unsigned >(
2669- kindOfUsage (value, context).getValueOr (VarRefUseEnv::Read));
2670-
2671- ctx.Diags .diagnose (loc, diag::global_actor_from_nonactor_context,
2672- value->getDescriptiveKind (), value->getName (),
2673- globalActor,
2674- /* actorIndependent=*/ true , useKind,
2675- result == AsyncMarkingResult::SyncContext);
2676- noteIsolatedActorMember (value, context);
2677- return true ;
2678- }
2679-
2680- case ActorIsolation::Unspecified: {
2681- // Diagnose the reference.
2682- auto useKind = static_cast <unsigned >(
2683- kindOfUsage (value, context).getValueOr (VarRefUseEnv::Read));
2684- ctx.Diags .diagnose (
2685- loc, diag::global_actor_from_nonactor_context,
2686- value->getDescriptiveKind (), value->getName (), globalActor,
2687- /* actorIndependent=*/ false , useKind,
2688- result == AsyncMarkingResult::SyncContext);
2689- noteGlobalActorOnContext (declContext, globalActor);
2690- noteIsolatedActorMember (value, context);
2691-
2692- return true ;
2693- } // end Unspecified case
2694- } // end switch
2695- llvm_unreachable (" unhandled actor isolation kind!" );
2696- }
2697-
26982622 // / Find the innermost context in which this declaration was explicitly
26992623 // / captured.
27002624 const DeclContext *findCapturedDeclContext (ValueDecl *value) {
@@ -2874,65 +2798,38 @@ namespace {
28742798 return diagnosed;
28752799 }
28762800
2877- // / Check a reference to a local or global.
2878- bool checkNonMemberReference (
2879- ConcreteDeclRef valueRef, SourceLoc loc, DeclRefExpr *declRefExpr) {
2880- if (!valueRef)
2881- return false ;
2882-
2883- auto value = valueRef.getDecl ();
2884-
2885- if (value->isLocalCapture ())
2886- return checkLocalCapture (valueRef, loc, declRefExpr);
2887-
2888- switch (auto isolation =
2889- ActorIsolationRestriction::forDeclaration (
2890- valueRef, getDeclContext ())) {
2891- case ActorIsolationRestriction::Unrestricted:
2892- return false ;
2893-
2894- case ActorIsolationRestriction::CrossActorSelf:
2895- case ActorIsolationRestriction::ActorSelf:
2896- llvm_unreachable (" non-member reference into an actor" );
2897-
2898- case ActorIsolationRestriction::GlobalActorUnsafe:
2899- // Only complain if we're in code that's adopted concurrency features.
2900- if (!shouldDiagnoseExistingDataRaces (getDeclContext ()))
2901- return false ;
2902-
2903- LLVM_FALLTHROUGH;
2904-
2905- case ActorIsolationRestriction::GlobalActor:
2906- return checkGlobalActorReference (
2907- valueRef, loc, isolation.getGlobalActor (), isolation.isCrossActor ,
2908- declRefExpr);
2909-
2910- case ActorIsolationRestriction::Unsafe:
2911- return diagnoseReferenceToUnsafeGlobal (value, loc);
2912- }
2913- llvm_unreachable (" unhandled actor isolation kind!" );
2914- }
2915-
2916- // / Check a reference with the given base expression to the given member.
2917- // / Returns true iff the member reference refers to actor-isolated state
2918- // / in an invalid or unsafe way such that a diagnostic was emitted.
2919- bool checkMemberReference (
2920- Expr *base, ConcreteDeclRef memberRef, SourceLoc memberLoc,
2801+ // / Check a reference to the given declaration.
2802+ // /
2803+ // / \param base For a reference to a member, the base expression. May be
2804+ // / nullptr for non-member referenced.
2805+ // /
2806+ // / \returns true if the reference is invalid, in which case a diagnostic
2807+ // / has already been emitted.
2808+ bool checkReference (
2809+ Expr *base, ConcreteDeclRef declRef, SourceLoc loc,
29212810 Optional<PartialApplyThunkInfo> partialApply = None,
29222811 Expr *context = nullptr ) {
2923- if (!base || !memberRef )
2812+ if (!declRef )
29242813 return false ;
29252814
2926- auto member = memberRef.getDecl ();
2927- auto isolatedActor = getIsolatedActor (base);
2815+ auto decl = declRef.getDecl ();
2816+ Optional<ReferencedActor> isolatedActor;
2817+ if (base)
2818+ isolatedActor.emplace (getIsolatedActor (base));
29282819 auto result = ActorReferenceResult::forReference (
2929- memberRef, memberLoc , getDeclContext (),
2930- kindOfUsage (member , context), isolatedActor);
2820+ declRef, loc , getDeclContext (),
2821+ kindOfUsage (decl , context), isolatedActor);
29312822 switch (result) {
29322823 case ActorReferenceResult::SameConcurrencyDomain:
2824+ if (diagnoseReferenceToUnsafeGlobal (decl, loc))
2825+ return true ;
2826+
29332827 return false ;
29342828
29352829 case ActorReferenceResult::ExitsActorToNonisolated:
2830+ if (diagnoseReferenceToUnsafeGlobal (decl, loc))
2831+ return true ;
2832+
29362833 // FIXME: SE-0338 would trigger Sendable checks here.
29372834 return false ;
29382835
@@ -2949,24 +2846,24 @@ namespace {
29492846
29502847 // A call to a global-actor-isolated function is diagnosed elsewhere.
29512848 if (!partialApply && result.isolation .isGlobalActor () &&
2952- isa<AbstractFunctionDecl>(member ))
2849+ isa<AbstractFunctionDecl>(decl ))
29532850 return false ;
29542851
29552852 // An escaping partial application of something that is part of
29562853 // the actor's isolated state is never permitted.
2957- if (partialApply && partialApply->isEscaping && !isAsyncDecl (memberRef )) {
2854+ if (partialApply && partialApply->isEscaping && !isAsyncDecl (declRef )) {
29582855 ctx.Diags .diagnose (
2959- memberLoc , diag::actor_isolated_partial_apply,
2960- member ->getDescriptiveKind (),
2961- member ->getName ());
2856+ loc , diag::actor_isolated_partial_apply,
2857+ decl ->getDescriptiveKind (),
2858+ decl ->getName ());
29622859 return true ;
29632860 }
29642861
29652862 // If we do not need any async/throws/distributed checks, just perform
29662863 // Sendable checking and we're done.
29672864 if (!result.options ) {
29682865 return diagnoseNonSendableTypesInReference (
2969- memberRef , getDeclContext (), memberLoc ,
2866+ declRef , getDeclContext (), loc ,
29702867 SendableCheckReason::CrossActor);
29712868 }
29722869
@@ -2980,7 +2877,7 @@ namespace {
29802877 result.isolation .getGlobalActor ())
29812878 : ImplicitActorHopTarget::forInstanceSelf ();
29822879 auto implicitAsyncResult = tryMarkImplicitlyAsync (
2983- memberLoc, memberRef , context, target, isDistributed);
2880+ loc, declRef , context, target, isDistributed);
29842881 switch (implicitAsyncResult) {
29852882 case AsyncMarkingResult::FoundAsync:
29862883 // Success! We're done.
@@ -2995,18 +2892,44 @@ namespace {
29952892 case AsyncMarkingResult::NotFound:
29962893 // Complain about access outside of the isolation domain.
29972894 auto useKind = static_cast <unsigned >(
2998- kindOfUsage (member, context).getValueOr (VarRefUseEnv::Read));
2895+ kindOfUsage (decl, context).getValueOr (VarRefUseEnv::Read));
2896+
2897+ ReferencedActor::Kind refKind;
2898+ Type refGlobalActor;
2899+ if (isolatedActor) {
2900+ refKind = isolatedActor->kind ;
2901+ refGlobalActor = isolatedActor->globalActor ;
2902+ } else {
2903+ auto contextIsolation = getInnermostIsolatedContext (getDeclContext ());
2904+ switch (contextIsolation) {
2905+ case ActorIsolation::ActorInstance:
2906+ refKind = ReferencedActor::Isolated;
2907+ break ;
2908+
2909+ case ActorIsolation::GlobalActor:
2910+ case ActorIsolation::GlobalActorUnsafe:
2911+ refGlobalActor = contextIsolation.getGlobalActor ();
2912+ refKind = isMainActor (refGlobalActor)
2913+ ? ReferencedActor::MainActor
2914+ : ReferencedActor::GlobalActor;
2915+ break ;
2916+
2917+ case ActorIsolation::Unspecified:
2918+ case ActorIsolation::Independent:
2919+ refKind = ReferencedActor::NonIsolatedContext;
2920+ break ;
2921+ }
2922+ }
29992923
30002924 ctx.Diags .diagnose (
3001- memberLoc , diag::actor_isolated_non_self_reference,
3002- member ->getDescriptiveKind (),
3003- member ->getName (),
2925+ loc , diag::actor_isolated_non_self_reference,
2926+ decl ->getDescriptiveKind (),
2927+ decl ->getName (),
30042928 useKind,
3005- isolatedActor.kind ,
3006- isolatedActor.globalActor ,
2929+ refKind + 1 , refGlobalActor,
30072930 result.isolation );
30082931
3009- noteIsolatedActorMember (member , context);
2932+ noteIsolatedActorMember (decl , context);
30102933
30112934 if (result.isolation .isGlobalActor ()) {
30122935 noteGlobalActorOnContext (
0 commit comments