Skip to content

Commit dd946d9

Browse files
committed
[CodeCompletion] Use type from solution to determine actor isolation
1 parent a0308ee commit dd946d9

File tree

2 files changed

+37
-1
lines changed

2 files changed

+37
-1
lines changed

include/swift/IDE/PostfixCompletion.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,11 @@ class PostfixCompletionCallback : public TypeCheckCompletionCallback {
3535
/// Whether the surrounding context is async and thus calling async
3636
/// functions is supported.
3737
bool IsInAsyncContext;
38+
39+
/// Actor isolations that were determined during constraint solving but that
40+
/// haven't been saved to the AST.
41+
llvm::DenseMap<AbstractClosureExpr *, ClosureActorIsolation>
42+
ClosureActorIsolations;
3843
};
3944

4045
CodeCompletionExpr *CompletionExpr;

lib/IDE/PostfixCompletion.cpp

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,29 @@ void PostfixCompletionCallback::fallbackTypeCheck(DeclContext *DC) {
4444
[&](const Solution &S) { sawSolution(S); });
4545
}
4646

47+
static ClosureActorIsolation
48+
getClosureActorIsolation(const Solution &S, AbstractClosureExpr *ACE) {
49+
auto getType = [&S](Expr *E) -> Type {
50+
// Prefer the contextual type of the closure because it might be 'weaker'
51+
// than the type determined for the closure by the constraints system. E.g.
52+
// the contextual type might have a global actor attribute but because no
53+
// methods from that global actor are called in the closure, the closure has
54+
// a non-actor type.
55+
auto target = S.solutionApplicationTargets.find(dyn_cast<ClosureExpr>(E));
56+
if (target != S.solutionApplicationTargets.end()) {
57+
if (auto Ty = target->second.getClosureContextualType()) {
58+
return Ty;
59+
}
60+
}
61+
return getTypeForCompletion(S, E);
62+
};
63+
auto getClosureActorIsolationThunk = [&S](AbstractClosureExpr *ACE) {
64+
return getClosureActorIsolation(S, ACE);
65+
};
66+
return determineClosureActorIsolation(ACE, getType,
67+
getClosureActorIsolationThunk);
68+
}
69+
4770
void PostfixCompletionCallback::sawSolutionImpl(
4871
const constraints::Solution &S) {
4972
auto &CS = S.getConstraintSystem();
@@ -68,7 +91,14 @@ void PostfixCompletionCallback::sawSolutionImpl(
6891
if (auto SelectedOverload = S.getOverloadChoiceIfAvailable(CalleeLocator))
6992
ReferencedDecl = SelectedOverload->choice.getDeclOrNull();
7093

94+
llvm::DenseMap<AbstractClosureExpr *, ClosureActorIsolation>
95+
ClosureActorIsolations;
7196
bool IsAsync = isContextAsync(S, DC);
97+
for (auto SAT : S.solutionApplicationTargets) {
98+
if (auto ACE = getAsExpr<AbstractClosureExpr>(SAT.second.getAsASTNode())) {
99+
ClosureActorIsolations[ACE] = getClosureActorIsolation(S, ACE);
100+
}
101+
}
72102

73103
auto Key = std::make_pair(BaseTy, ReferencedDecl);
74104
auto Ret = BaseToSolutionIdx.insert({Key, Results.size()});
@@ -91,7 +121,7 @@ void PostfixCompletionCallback::sawSolutionImpl(
91121

92122
Results.push_back({BaseTy, ReferencedDecl,
93123
/*ExpectedTypes=*/{}, DisallowVoid, ISDMT,
94-
ImplicitReturn, IsAsync});
124+
ImplicitReturn, IsAsync, ClosureActorIsolations});
95125
if (ExpectedTy) {
96126
Results.back().ExpectedTypes.push_back(ExpectedTy);
97127
}
@@ -131,6 +161,7 @@ void PostfixCompletionCallback::deliverResults(
131161
Lookup.shouldCheckForDuplicates(Results.size() > 1);
132162
for (auto &Result : Results) {
133163
Lookup.setCanCurrDeclContextHandleAsync(Result.IsInAsyncContext);
164+
Lookup.setClosureActorIsolations(Result.ClosureActorIsolations);
134165
Lookup.setIsStaticMetatype(Result.BaseIsStaticMetaType);
135166
Lookup.getPostfixKeywordCompletions(Result.BaseTy, BaseExpr);
136167
Lookup.setExpectedTypes(Result.ExpectedTypes,

0 commit comments

Comments
 (0)