@@ -2516,47 +2516,15 @@ class CompletionLookup final : public swift::VisibleDeclConsumer {
2516
2516
return Type ();
2517
2517
}
2518
2518
2519
- void addVarDeclRef (const VarDecl *VD, DeclVisibilityKind Reason,
2520
- DynamicLookupInfo dynamicLookupInfo) {
2521
- if (!VD->hasName ())
2522
- return ;
2523
-
2524
- const Identifier Name = VD->getName ();
2525
- assert (!Name.empty () && " name should not be empty" );
2526
-
2527
- CommandWordsPairs Pairs;
2528
- CodeCompletionResultBuilder Builder (
2529
- Sink, CodeCompletionResult::ResultKind::Declaration,
2530
- getSemanticContext (VD, Reason, dynamicLookupInfo), expectedTypeContext);
2531
- Builder.setAssociatedDecl (VD);
2532
- addLeadingDot (Builder);
2533
- addValueBaseName (Builder, Name);
2534
- setClangDeclKeywords (VD, Pairs, Builder);
2519
+ void analyzeActorIsolation (
2520
+ const ValueDecl *VD, Type T, bool &implicitlyAsync,
2521
+ Optional<CodeCompletionResult::NotRecommendedReason> &NotRecommended) {
2522
+ auto isolation = getActorIsolation (const_cast <ValueDecl *>(VD));
2535
2523
2536
- Optional<CodeCompletionResult::NotRecommendedReason> NotRecommended;
2537
- // "not recommended" in its own getter.
2538
- if (Kind == LookupKind::ValueInDeclContext) {
2539
- if (auto accessor = dyn_cast<AccessorDecl>(CurrDeclContext)) {
2540
- if (accessor->getStorage () == VD && accessor->isGetter ())
2541
- NotRecommended = CodeCompletionResult::NoReason;
2542
- }
2543
- }
2544
-
2545
- if (!VD->hasInterfaceType ())
2546
- return ;
2547
-
2548
- // Add a type annotation.
2549
- Type VarType = getTypeOfMember (VD, dynamicLookupInfo);
2550
-
2551
- bool implicitlyAsync = false ;
2552
- auto isolation = getActorIsolation (const_cast <VarDecl *>(VD));
2553
2524
switch (isolation.getKind ()) {
2554
2525
case ActorIsolation::ActorInstance: {
2555
2526
if (IsCrossActorReference) {
2556
2527
implicitlyAsync = true ;
2557
- if (!isSendableType (CurrDeclContext, VarType)) {
2558
- NotRecommended = CodeCompletionResult::CrossActorReference;
2559
- }
2560
2528
// TODO: 'NotRecommended' if this is a r-value reference.
2561
2529
}
2562
2530
break ;
@@ -2568,16 +2536,75 @@ class CompletionLookup final : public swift::VisibleDeclConsumer {
2568
2536
case ActorIsolation::Unspecified:
2569
2537
case ActorIsolation::Independent:
2570
2538
case ActorIsolation::IndependentUnsafe:
2571
- break ;
2539
+ return ;
2572
2540
}
2573
2541
2542
+ // If the reference is 'async', all types must be 'Sendable'.
2543
+ if (implicitlyAsync && T) {
2544
+ if (isa<VarDecl>(VD)) {
2545
+ if (!isSendableType (CurrDeclContext, T)) {
2546
+ NotRecommended = CodeCompletionResult::CrossActorReference;
2547
+ }
2548
+ } else {
2549
+ assert (isa<FuncDecl>(VD) || isa<SubscriptDecl>(VD));
2550
+ // Check if the result and the param types are all 'Sendable'.
2551
+ auto *AFT = T->castTo <AnyFunctionType>();
2552
+ if (!isSendableType (CurrDeclContext, AFT->getResult ())) {
2553
+ NotRecommended = CodeCompletionResult::CrossActorReference;
2554
+ } else {
2555
+ for (auto ¶m : AFT->getParams ()) {
2556
+ Type paramType = param.getPlainType ();
2557
+ if (!isSendableType (CurrDeclContext, paramType)) {
2558
+ NotRecommended = CodeCompletionResult::CrossActorReference;
2559
+ break ;
2560
+ }
2561
+ }
2562
+ }
2563
+ }
2564
+ }
2565
+ }
2566
+
2567
+ void addVarDeclRef (const VarDecl *VD, DeclVisibilityKind Reason,
2568
+ DynamicLookupInfo dynamicLookupInfo) {
2569
+ if (!VD->hasName ())
2570
+ return ;
2571
+
2572
+ const Identifier Name = VD->getName ();
2573
+ assert (!Name.empty () && " name should not be empty" );
2574
+
2575
+ Type VarType;
2576
+ if (VD->hasInterfaceType ())
2577
+ VarType = getTypeOfMember (VD, dynamicLookupInfo);
2578
+
2579
+ Optional<CodeCompletionResult::NotRecommendedReason> NotRecommended;
2580
+ // "not recommended" in its own getter.
2581
+ if (Kind == LookupKind::ValueInDeclContext) {
2582
+ if (auto accessor = dyn_cast<AccessorDecl>(CurrDeclContext)) {
2583
+ if (accessor->getStorage () == VD && accessor->isGetter ())
2584
+ NotRecommended = CodeCompletionResult::NoReason;
2585
+ }
2586
+ }
2587
+ bool implicitlyAsync = false ;
2588
+ analyzeActorIsolation (VD, VarType, implicitlyAsync, NotRecommended);
2574
2589
if (!NotRecommended && implicitlyAsync && !CanCurrDeclContextHandleAsync) {
2575
2590
NotRecommended = CodeCompletionResult::InvalidContext;
2576
2591
}
2577
2592
2593
+ CommandWordsPairs Pairs;
2594
+ CodeCompletionResultBuilder Builder (
2595
+ Sink, CodeCompletionResult::ResultKind::Declaration,
2596
+ getSemanticContext (VD, Reason, dynamicLookupInfo), expectedTypeContext);
2597
+ Builder.setAssociatedDecl (VD);
2598
+ addLeadingDot (Builder);
2599
+ addValueBaseName (Builder, Name);
2600
+ setClangDeclKeywords (VD, Pairs, Builder);
2601
+
2578
2602
if (NotRecommended)
2579
2603
Builder.setNotRecommended (*NotRecommended);
2580
2604
2605
+ if (!VarType)
2606
+ return ;
2607
+
2581
2608
if (auto *PD = dyn_cast<ParamDecl>(VD)) {
2582
2609
if (Name != Ctx.Id_self && PD->isInOut ()) {
2583
2610
// It is useful to show inout for function parameters.
@@ -3013,38 +3040,7 @@ class CompletionLookup final : public swift::VisibleDeclConsumer {
3013
3040
3014
3041
Optional<CodeCompletionResult::NotRecommendedReason> NotRecommended;
3015
3042
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
- }
3043
+ analyzeActorIsolation (FD, AFT, implictlyAsync, NotRecommended);
3048
3044
3049
3045
if (!NotRecommended && !IsImplicitlyCurriedInstanceMethod &&
3050
3046
((AFT && AFT->isAsync ()) || implictlyAsync) &&
@@ -3300,36 +3296,7 @@ class CompletionLookup final : public swift::VisibleDeclConsumer {
3300
3296
3301
3297
Optional<CodeCompletionResult::NotRecommendedReason> NotRecommended;
3302
3298
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
- }
3299
+ analyzeActorIsolation (SD, subscriptType, implictlyAsync, NotRecommended);
3333
3300
3334
3301
if (!NotRecommended && implictlyAsync && !CanCurrDeclContextHandleAsync) {
3335
3302
NotRecommended = CodeCompletionResult::InvalidContext;
0 commit comments