Skip to content

Commit 26e237c

Browse files
committed
[CodeCompletion] Disallow void when code completion expr is a solution application target whose result is not unused
This happens if the code completion expression initializes a variable in a multi-statement closure that doesn’t have LeaveClosureBodiesUnchecked set.
1 parent 2e8ae40 commit 26e237c

File tree

1 file changed

+14
-5
lines changed

1 file changed

+14
-5
lines changed

lib/IDE/PostfixCompletion.cpp

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ void PostfixCompletionCallback::sawSolutionImpl(
6060
auto *Locator = CS.getConstraintLocator(SemanticExpr);
6161
Type ExpectedTy = getTypeForCompletion(S, CompletionExpr);
6262
Expr *ParentExpr = CS.getParentExpr(CompletionExpr);
63-
if (!ParentExpr)
63+
if (!ParentExpr && !ExpectedTy)
6464
ExpectedTy = CS.getContextualType(CompletionExpr, /*forConstraint=*/false);
6565

6666
auto *CalleeLocator = S.getCalleeLocator(Locator);
@@ -75,10 +75,19 @@ void PostfixCompletionCallback::sawSolutionImpl(
7575
if (Ret.second) {
7676
bool ISDMT = S.isStaticallyDerivedMetatype(ParsedExpr);
7777
bool ImplicitReturn = isImplicitSingleExpressionReturn(CS, CompletionExpr);
78-
bool DisallowVoid = ExpectedTy
79-
? !ExpectedTy->isVoid()
80-
: !ParentExpr && CS.getContextualTypePurpose(
81-
CompletionExpr) != CTP_Unused;
78+
bool DisallowVoid = false;
79+
DisallowVoid |= ExpectedTy && !ExpectedTy->isVoid();
80+
DisallowVoid |= !ParentExpr &&
81+
CS.getContextualTypePurpose(CompletionExpr) != CTP_Unused;
82+
for (auto SAT : S.solutionApplicationTargets) {
83+
if (DisallowVoid) {
84+
// DisallowVoid is already set. No need to iterate further.
85+
break;
86+
}
87+
if (SAT.second.getAsExpr() == CompletionExpr) {
88+
DisallowVoid |= SAT.second.getExprContextualTypePurpose() != CTP_Unused;
89+
}
90+
}
8291

8392
Results.push_back({BaseTy, ReferencedDecl,
8493
/*ExpectedTypes=*/{}, DisallowVoid, ISDMT,

0 commit comments

Comments
 (0)