@@ -1761,7 +1761,7 @@ static bool hasTrivialTrailingClosure(const FuncDecl *FD,
17611761}
17621762
17631763// / Returns \c true if \p DC can handles async call.
1764- static bool canDeclContextHandlesAsync (const DeclContext *DC) {
1764+ static bool canDeclContextHandleAsync (const DeclContext *DC) {
17651765 if (auto *func = dyn_cast<AbstractFunctionDecl>(DC))
17661766 return func->isAsyncContext ();
17671767
@@ -1840,6 +1840,7 @@ class CompletionLookup final : public swift::VisibleDeclConsumer {
18401840 // / Expected types of the code completion expression.
18411841 ExpectedTypeContext expectedTypeContext;
18421842
1843+ bool CanCurrDeclContextHandleAsync = false ;
18431844 bool HaveDot = false ;
18441845 bool IsUnwrappedOptional = false ;
18451846 SourceLoc DotLoc;
@@ -1855,6 +1856,7 @@ class CompletionLookup final : public swift::VisibleDeclConsumer {
18551856 bool IsSwiftKeyPathExpr = false ;
18561857 bool IsAfterSwiftKeyPathRoot = false ;
18571858 bool IsDynamicLookup = false ;
1859+ bool IsCrossActorReference = false ;
18581860 bool PreferFunctionReferencesToCalls = false ;
18591861 bool HaveLeadingSpace = false ;
18601862
@@ -1987,6 +1989,7 @@ class CompletionLookup final : public swift::VisibleDeclConsumer {
19871989 CurrentMethod = CurrDeclContext->getInnermostMethodContext ();
19881990 if (auto *FD = dyn_cast_or_null<FuncDecl>(CurrentMethod))
19891991 InsideStaticMethod = FD->isStatic ();
1992+ CanCurrDeclContextHandleAsync = canDeclContextHandleAsync (CurrDeclContext);
19901993 }
19911994 }
19921995
@@ -2530,11 +2533,12 @@ class CompletionLookup final : public swift::VisibleDeclConsumer {
25302533 addValueBaseName (Builder, Name);
25312534 setClangDeclKeywords (VD, Pairs, Builder);
25322535
2536+ Optional<CodeCompletionResult::NotRecommendedReason> NotRecommended;
25332537 // "not recommended" in its own getter.
25342538 if (Kind == LookupKind::ValueInDeclContext) {
25352539 if (auto accessor = dyn_cast<AccessorDecl>(CurrDeclContext)) {
25362540 if (accessor->getStorage () == VD && accessor->isGetter ())
2537- Builder. setNotRecommended ( CodeCompletionResult::NoReason) ;
2541+ NotRecommended = CodeCompletionResult::NoReason;
25382542 }
25392543 }
25402544
@@ -2543,6 +2547,37 @@ class CompletionLookup final : public swift::VisibleDeclConsumer {
25432547
25442548 // Add a type annotation.
25452549 Type VarType = getTypeOfMember (VD, dynamicLookupInfo);
2550+
2551+ bool implicitlyAsync = false ;
2552+ auto isolation = getActorIsolation (const_cast <VarDecl *>(VD));
2553+ switch (isolation.getKind ()) {
2554+ case ActorIsolation::ActorInstance: {
2555+ if (IsCrossActorReference) {
2556+ implicitlyAsync = true ;
2557+ if (!isSendableType (CurrDeclContext, VarType)) {
2558+ NotRecommended = CodeCompletionResult::CrossActorReference;
2559+ }
2560+ // TODO: 'NotRecommended' if this is a r-value reference.
2561+ }
2562+ break ;
2563+ }
2564+ case ActorIsolation::GlobalActor:
2565+ case ActorIsolation::GlobalActorUnsafe:
2566+ // TODO: Implement.
2567+ break ;
2568+ case ActorIsolation::Unspecified:
2569+ case ActorIsolation::Independent:
2570+ case ActorIsolation::IndependentUnsafe:
2571+ break ;
2572+ }
2573+
2574+ if (!NotRecommended && implicitlyAsync && !CanCurrDeclContextHandleAsync) {
2575+ NotRecommended = CodeCompletionResult::InvalidContext;
2576+ }
2577+
2578+ if (NotRecommended)
2579+ Builder.setNotRecommended (*NotRecommended);
2580+
25462581 if (auto *PD = dyn_cast<ParamDecl>(VD)) {
25472582 if (Name != Ctx.Id_self && PD->isInOut ()) {
25482583 // It is useful to show inout for function parameters.
@@ -2566,6 +2601,9 @@ class CompletionLookup final : public swift::VisibleDeclConsumer {
25662601 else
25672602 addTypeAnnotation (Builder, VarType, genericSig);
25682603
2604+ if (implicitlyAsync)
2605+ Builder.addAnnotatedAsync ();
2606+
25692607 if (isUnresolvedMemberIdealType (VarType))
25702608 Builder.setSemanticContext (SemanticContextKind::ExpressionSpecific);
25712609 }
@@ -2686,11 +2724,12 @@ class CompletionLookup final : public swift::VisibleDeclConsumer {
26862724
26872725 static void addEffectsSpecifiers (CodeCompletionResultBuilder &Builder,
26882726 const AnyFunctionType *AFT,
2689- const AbstractFunctionDecl *AFD) {
2727+ const AbstractFunctionDecl *AFD,
2728+ bool forceAsync = false ) {
26902729 assert (AFT != nullptr );
26912730
26922731 // 'async'.
2693- if ((AFD && AFD->hasAsync ()) || AFT->isAsync ())
2732+ if (forceAsync || (AFD && AFD->hasAsync ()) || AFT->isAsync ())
26942733 Builder.addAnnotatedAsync ();
26952734
26962735 // 'throws' or 'rethrows'.
@@ -2861,8 +2900,7 @@ class CompletionLookup final : public swift::VisibleDeclConsumer {
28612900 else
28622901 addTypeAnnotation (Builder, AFT->getResult (), genericSig);
28632902
2864- if (AFT->isAsync () &&
2865- !canDeclContextHandlesAsync (CurrDeclContext)) {
2903+ if (AFT->isAsync () && !CanCurrDeclContextHandleAsync) {
28662904 Builder.setNotRecommended (
28672905 CodeCompletionResult::NotRecommendedReason::InvalidContext);
28682906 }
@@ -2973,6 +3011,47 @@ class CompletionLookup final : public swift::VisibleDeclConsumer {
29733011 if (AFT && !IsImplicitlyCurriedInstanceMethod)
29743012 trivialTrailingClosure = hasTrivialTrailingClosure (FD, AFT);
29753013
3014+ Optional<CodeCompletionResult::NotRecommendedReason> NotRecommended;
3015+ bool implictlyAsync = false ;
3016+ auto isolation = getActorIsolation (const_cast <FuncDecl *>(FD));
3017+ switch (isolation.getKind ()) {
3018+ case ActorIsolation::ActorInstance: {
3019+ if (IsCrossActorReference) {
3020+ implictlyAsync = true ;
3021+
3022+ // Check if the result and the param types are all concurrent values.
3023+ if (AFT) {
3024+ if (!isSendableType (CurrDeclContext, AFT->getResult ())) {
3025+ NotRecommended = CodeCompletionResult::CrossActorReference;
3026+ } else {
3027+ for (auto ¶m : AFT->getParams ()) {
3028+ Type paramType = param.getPlainType ();
3029+ if (!isSendableType (CurrDeclContext, paramType)) {
3030+ NotRecommended = CodeCompletionResult::CrossActorReference;
3031+ break ;
3032+ }
3033+ }
3034+ }
3035+ }
3036+ }
3037+ break ;
3038+ }
3039+ case ActorIsolation::GlobalActor:
3040+ case ActorIsolation::GlobalActorUnsafe:
3041+ // TODO: implement.
3042+ break ;
3043+ case ActorIsolation::Unspecified:
3044+ case ActorIsolation::Independent:
3045+ case ActorIsolation::IndependentUnsafe:
3046+ break ;
3047+ }
3048+
3049+ if (!NotRecommended && !IsImplicitlyCurriedInstanceMethod &&
3050+ ((AFT && AFT->isAsync ()) || implictlyAsync) &&
3051+ !CanCurrDeclContextHandleAsync) {
3052+ NotRecommended = CodeCompletionResult::InvalidContext;
3053+ }
3054+
29763055 // Add the method, possibly including any default arguments.
29773056 auto addMethodImpl = [&](bool includeDefaultArgs = true ,
29783057 bool trivialTrailingClosure = false ) {
@@ -2983,6 +3062,10 @@ class CompletionLookup final : public swift::VisibleDeclConsumer {
29833062 expectedTypeContext);
29843063 setClangDeclKeywords (FD, Pairs, Builder);
29853064 Builder.setAssociatedDecl (FD);
3065+
3066+ if (NotRecommended)
3067+ Builder.setNotRecommended (*NotRecommended);
3068+
29863069 addLeadingDot (Builder);
29873070 addValueBaseName (Builder, Name);
29883071 if (IsDynamicLookup)
@@ -3004,14 +3087,14 @@ class CompletionLookup final : public swift::VisibleDeclConsumer {
30043087 Builder.addRightParen ();
30053088 } else if (trivialTrailingClosure) {
30063089 Builder.addBraceStmtWithCursor (" { code }" );
3007- addEffectsSpecifiers (Builder, AFT, FD);
3090+ addEffectsSpecifiers (Builder, AFT, FD, implictlyAsync );
30083091 } else {
30093092 Builder.addLeftParen ();
30103093 addCallArgumentPatterns (Builder, AFT, FD->getParameters (),
30113094 FD->getGenericSignatureOfContext (),
30123095 includeDefaultArgs);
30133096 Builder.addRightParen ();
3014- addEffectsSpecifiers (Builder, AFT, FD);
3097+ addEffectsSpecifiers (Builder, AFT, FD, implictlyAsync );
30153098 }
30163099
30173100 // Build type annotation.
@@ -3076,13 +3159,6 @@ class CompletionLookup final : public swift::VisibleDeclConsumer {
30763159 ResultType->isVoid ()) {
30773160 Builder.setExpectedTypeRelation (CodeCompletionResult::Invalid);
30783161 }
3079-
3080- if (!IsImplicitlyCurriedInstanceMethod &&
3081- AFT->isAsync () &&
3082- !canDeclContextHandlesAsync (CurrDeclContext)) {
3083- Builder.setNotRecommended (
3084- CodeCompletionResult::NotRecommendedReason::InvalidContext);
3085- }
30863162 };
30873163
30883164 if (!AFT || IsImplicitlyCurriedInstanceMethod) {
@@ -3170,8 +3246,7 @@ class CompletionLookup final : public swift::VisibleDeclConsumer {
31703246 addTypeAnnotation (Builder, *Result, CD->getGenericSignatureOfContext ());
31713247 }
31723248
3173- if (ConstructorType->isAsync () &&
3174- !canDeclContextHandlesAsync (CurrDeclContext)) {
3249+ if (ConstructorType->isAsync () && !CanCurrDeclContextHandleAsync) {
31753250 Builder.setNotRecommended (
31763251 CodeCompletionResult::NotRecommendedReason::InvalidContext);
31773252 }
@@ -3223,13 +3298,53 @@ class CompletionLookup final : public swift::VisibleDeclConsumer {
32233298 if (!subscriptType)
32243299 return ;
32253300
3301+ Optional<CodeCompletionResult::NotRecommendedReason> NotRecommended;
3302+ bool implictlyAsync = false ;
3303+ auto isolation = getActorIsolation (const_cast <SubscriptDecl *>(SD));
3304+ switch (isolation.getKind ()) {
3305+ case ActorIsolation::ActorInstance: {
3306+ if (IsCrossActorReference) {
3307+ implictlyAsync = true ;
3308+
3309+ // Check if the result and the param types are all concurrent values.
3310+ if (!isSendableType (CurrDeclContext, subscriptType->getResult ())) {
3311+ NotRecommended = CodeCompletionResult::CrossActorReference;
3312+ } else {
3313+ for (auto ¶m : subscriptType->getParams ()) {
3314+ Type paramType = param.getPlainType ();
3315+ if (!isSendableType (CurrDeclContext, paramType))
3316+ NotRecommended = CodeCompletionResult::CrossActorReference;
3317+ }
3318+ }
3319+
3320+ // TODO: 'NotRecommended' if this is a r-value reference.
3321+ }
3322+ break ;
3323+ }
3324+ case ActorIsolation::GlobalActor:
3325+ case ActorIsolation::GlobalActorUnsafe:
3326+ // TODO: implement.
3327+ break ;
3328+ case ActorIsolation::Unspecified:
3329+ case ActorIsolation::Independent:
3330+ case ActorIsolation::IndependentUnsafe:
3331+ break ;
3332+ }
3333+
3334+ if (!NotRecommended && implictlyAsync && !CanCurrDeclContextHandleAsync) {
3335+ NotRecommended = CodeCompletionResult::InvalidContext;
3336+ }
3337+
32263338 CommandWordsPairs Pairs;
32273339 CodeCompletionResultBuilder Builder (
32283340 Sink, CodeCompletionResult::ResultKind::Declaration,
32293341 getSemanticContext (SD, Reason, dynamicLookupInfo), expectedTypeContext);
32303342 Builder.setAssociatedDecl (SD);
32313343 setClangDeclKeywords (SD, Pairs, Builder);
32323344
3345+ if (NotRecommended)
3346+ Builder.setNotRecommended (*NotRecommended);
3347+
32333348 // '\TyName#^TOKEN^#' requires leading dot.
32343349 if (!HaveDot && IsAfterSwiftKeyPathRoot)
32353350 Builder.addLeadingDot ();
@@ -3251,6 +3366,10 @@ class CompletionLookup final : public swift::VisibleDeclConsumer {
32513366 // Optional<T> type.
32523367 resultTy = OptionalType::get (resultTy);
32533368 }
3369+
3370+ if (implictlyAsync)
3371+ Builder.addAnnotatedAsync ();
3372+
32543373 addTypeAnnotation (Builder, resultTy, SD->getGenericSignatureOfContext ());
32553374 }
32563375
@@ -3916,6 +4035,11 @@ class CompletionLookup final : public swift::VisibleDeclConsumer {
39164035 if (ExprType->isAnyExistentialType ())
39174036 ExprType = OpenedArchetypeType::getAny (ExprType);
39184037
4038+ if (!IsSelfRefExpr && !IsSuperRefExpr && ExprType->getAnyNominal () &&
4039+ ExprType->getAnyNominal ()->isActor ()) {
4040+ IsCrossActorReference = true ;
4041+ }
4042+
39194043 if (WasOptional)
39204044 ExprType = OptionalType::get (ExprType);
39214045
0 commit comments