@@ -1761,7 +1761,7 @@ static bool hasTrivialTrailingClosure(const FuncDecl *FD,
1761
1761
}
1762
1762
1763
1763
// / Returns \c true if \p DC can handles async call.
1764
- static bool canDeclContextHandlesAsync (const DeclContext *DC) {
1764
+ static bool canDeclContextHandleAsync (const DeclContext *DC) {
1765
1765
if (auto *func = dyn_cast<AbstractFunctionDecl>(DC))
1766
1766
return func->isAsyncContext ();
1767
1767
@@ -1840,6 +1840,7 @@ class CompletionLookup final : public swift::VisibleDeclConsumer {
1840
1840
// / Expected types of the code completion expression.
1841
1841
ExpectedTypeContext expectedTypeContext;
1842
1842
1843
+ bool CanCurrDeclContextHandleAsync = false ;
1843
1844
bool HaveDot = false ;
1844
1845
bool IsUnwrappedOptional = false ;
1845
1846
SourceLoc DotLoc;
@@ -1855,6 +1856,7 @@ class CompletionLookup final : public swift::VisibleDeclConsumer {
1855
1856
bool IsSwiftKeyPathExpr = false ;
1856
1857
bool IsAfterSwiftKeyPathRoot = false ;
1857
1858
bool IsDynamicLookup = false ;
1859
+ bool IsCrossActorReference = false ;
1858
1860
bool PreferFunctionReferencesToCalls = false ;
1859
1861
bool HaveLeadingSpace = false ;
1860
1862
@@ -1987,6 +1989,7 @@ class CompletionLookup final : public swift::VisibleDeclConsumer {
1987
1989
CurrentMethod = CurrDeclContext->getInnermostMethodContext ();
1988
1990
if (auto *FD = dyn_cast_or_null<FuncDecl>(CurrentMethod))
1989
1991
InsideStaticMethod = FD->isStatic ();
1992
+ CanCurrDeclContextHandleAsync = canDeclContextHandleAsync (CurrDeclContext);
1990
1993
}
1991
1994
}
1992
1995
@@ -2530,11 +2533,12 @@ class CompletionLookup final : public swift::VisibleDeclConsumer {
2530
2533
addValueBaseName (Builder, Name);
2531
2534
setClangDeclKeywords (VD, Pairs, Builder);
2532
2535
2536
+ Optional<CodeCompletionResult::NotRecommendedReason> NotRecommended;
2533
2537
// "not recommended" in its own getter.
2534
2538
if (Kind == LookupKind::ValueInDeclContext) {
2535
2539
if (auto accessor = dyn_cast<AccessorDecl>(CurrDeclContext)) {
2536
2540
if (accessor->getStorage () == VD && accessor->isGetter ())
2537
- Builder. setNotRecommended ( CodeCompletionResult::NoReason) ;
2541
+ NotRecommended = CodeCompletionResult::NoReason;
2538
2542
}
2539
2543
}
2540
2544
@@ -2543,6 +2547,37 @@ class CompletionLookup final : public swift::VisibleDeclConsumer {
2543
2547
2544
2548
// Add a type annotation.
2545
2549
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
+
2546
2581
if (auto *PD = dyn_cast<ParamDecl>(VD)) {
2547
2582
if (Name != Ctx.Id_self && PD->isInOut ()) {
2548
2583
// It is useful to show inout for function parameters.
@@ -2566,6 +2601,9 @@ class CompletionLookup final : public swift::VisibleDeclConsumer {
2566
2601
else
2567
2602
addTypeAnnotation (Builder, VarType, genericSig);
2568
2603
2604
+ if (implicitlyAsync)
2605
+ Builder.addAnnotatedAsync ();
2606
+
2569
2607
if (isUnresolvedMemberIdealType (VarType))
2570
2608
Builder.setSemanticContext (SemanticContextKind::ExpressionSpecific);
2571
2609
}
@@ -2686,11 +2724,12 @@ class CompletionLookup final : public swift::VisibleDeclConsumer {
2686
2724
2687
2725
static void addEffectsSpecifiers (CodeCompletionResultBuilder &Builder,
2688
2726
const AnyFunctionType *AFT,
2689
- const AbstractFunctionDecl *AFD) {
2727
+ const AbstractFunctionDecl *AFD,
2728
+ bool forceAsync = false ) {
2690
2729
assert (AFT != nullptr );
2691
2730
2692
2731
// 'async'.
2693
- if ((AFD && AFD->hasAsync ()) || AFT->isAsync ())
2732
+ if (forceAsync || (AFD && AFD->hasAsync ()) || AFT->isAsync ())
2694
2733
Builder.addAnnotatedAsync ();
2695
2734
2696
2735
// 'throws' or 'rethrows'.
@@ -2861,8 +2900,7 @@ class CompletionLookup final : public swift::VisibleDeclConsumer {
2861
2900
else
2862
2901
addTypeAnnotation (Builder, AFT->getResult (), genericSig);
2863
2902
2864
- if (AFT->isAsync () &&
2865
- !canDeclContextHandlesAsync (CurrDeclContext)) {
2903
+ if (AFT->isAsync () && !CanCurrDeclContextHandleAsync) {
2866
2904
Builder.setNotRecommended (
2867
2905
CodeCompletionResult::NotRecommendedReason::InvalidContext);
2868
2906
}
@@ -2973,6 +3011,47 @@ class CompletionLookup final : public swift::VisibleDeclConsumer {
2973
3011
if (AFT && !IsImplicitlyCurriedInstanceMethod)
2974
3012
trivialTrailingClosure = hasTrivialTrailingClosure (FD, AFT);
2975
3013
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
+
2976
3055
// Add the method, possibly including any default arguments.
2977
3056
auto addMethodImpl = [&](bool includeDefaultArgs = true ,
2978
3057
bool trivialTrailingClosure = false ) {
@@ -2983,6 +3062,10 @@ class CompletionLookup final : public swift::VisibleDeclConsumer {
2983
3062
expectedTypeContext);
2984
3063
setClangDeclKeywords (FD, Pairs, Builder);
2985
3064
Builder.setAssociatedDecl (FD);
3065
+
3066
+ if (NotRecommended)
3067
+ Builder.setNotRecommended (*NotRecommended);
3068
+
2986
3069
addLeadingDot (Builder);
2987
3070
addValueBaseName (Builder, Name);
2988
3071
if (IsDynamicLookup)
@@ -3004,14 +3087,14 @@ class CompletionLookup final : public swift::VisibleDeclConsumer {
3004
3087
Builder.addRightParen ();
3005
3088
} else if (trivialTrailingClosure) {
3006
3089
Builder.addBraceStmtWithCursor (" { code }" );
3007
- addEffectsSpecifiers (Builder, AFT, FD);
3090
+ addEffectsSpecifiers (Builder, AFT, FD, implictlyAsync );
3008
3091
} else {
3009
3092
Builder.addLeftParen ();
3010
3093
addCallArgumentPatterns (Builder, AFT, FD->getParameters (),
3011
3094
FD->getGenericSignatureOfContext (),
3012
3095
includeDefaultArgs);
3013
3096
Builder.addRightParen ();
3014
- addEffectsSpecifiers (Builder, AFT, FD);
3097
+ addEffectsSpecifiers (Builder, AFT, FD, implictlyAsync );
3015
3098
}
3016
3099
3017
3100
// Build type annotation.
@@ -3076,13 +3159,6 @@ class CompletionLookup final : public swift::VisibleDeclConsumer {
3076
3159
ResultType->isVoid ()) {
3077
3160
Builder.setExpectedTypeRelation (CodeCompletionResult::Invalid);
3078
3161
}
3079
-
3080
- if (!IsImplicitlyCurriedInstanceMethod &&
3081
- AFT->isAsync () &&
3082
- !canDeclContextHandlesAsync (CurrDeclContext)) {
3083
- Builder.setNotRecommended (
3084
- CodeCompletionResult::NotRecommendedReason::InvalidContext);
3085
- }
3086
3162
};
3087
3163
3088
3164
if (!AFT || IsImplicitlyCurriedInstanceMethod) {
@@ -3170,8 +3246,7 @@ class CompletionLookup final : public swift::VisibleDeclConsumer {
3170
3246
addTypeAnnotation (Builder, *Result, CD->getGenericSignatureOfContext ());
3171
3247
}
3172
3248
3173
- if (ConstructorType->isAsync () &&
3174
- !canDeclContextHandlesAsync (CurrDeclContext)) {
3249
+ if (ConstructorType->isAsync () && !CanCurrDeclContextHandleAsync) {
3175
3250
Builder.setNotRecommended (
3176
3251
CodeCompletionResult::NotRecommendedReason::InvalidContext);
3177
3252
}
@@ -3223,13 +3298,53 @@ class CompletionLookup final : public swift::VisibleDeclConsumer {
3223
3298
if (!subscriptType)
3224
3299
return ;
3225
3300
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
+
3226
3338
CommandWordsPairs Pairs;
3227
3339
CodeCompletionResultBuilder Builder (
3228
3340
Sink, CodeCompletionResult::ResultKind::Declaration,
3229
3341
getSemanticContext (SD, Reason, dynamicLookupInfo), expectedTypeContext);
3230
3342
Builder.setAssociatedDecl (SD);
3231
3343
setClangDeclKeywords (SD, Pairs, Builder);
3232
3344
3345
+ if (NotRecommended)
3346
+ Builder.setNotRecommended (*NotRecommended);
3347
+
3233
3348
// '\TyName#^TOKEN^#' requires leading dot.
3234
3349
if (!HaveDot && IsAfterSwiftKeyPathRoot)
3235
3350
Builder.addLeadingDot ();
@@ -3251,6 +3366,10 @@ class CompletionLookup final : public swift::VisibleDeclConsumer {
3251
3366
// Optional<T> type.
3252
3367
resultTy = OptionalType::get (resultTy);
3253
3368
}
3369
+
3370
+ if (implictlyAsync)
3371
+ Builder.addAnnotatedAsync ();
3372
+
3254
3373
addTypeAnnotation (Builder, resultTy, SD->getGenericSignatureOfContext ());
3255
3374
}
3256
3375
@@ -3916,6 +4035,11 @@ class CompletionLookup final : public swift::VisibleDeclConsumer {
3916
4035
if (ExprType->isAnyExistentialType ())
3917
4036
ExprType = OpenedArchetypeType::getAny (ExprType);
3918
4037
4038
+ if (!IsSelfRefExpr && !IsSuperRefExpr && ExprType->getAnyNominal () &&
4039
+ ExprType->getAnyNominal ()->isActor ()) {
4040
+ IsCrossActorReference = true ;
4041
+ }
4042
+
3919
4043
if (WasOptional)
3920
4044
ExprType = OptionalType::get (ExprType);
3921
4045
0 commit comments