@@ -269,12 +269,7 @@ class ResultBuilderTransform
269
269
for (auto element : braceStmt->getElements ()) {
270
270
if (auto unsupported =
271
271
transformBraceElement (element, newBody, buildBlockArguments)) {
272
- // When in code completion mode, simply ignore unsported constructs to
273
- // get results for anything that's unrelated to the unsupported
274
- // constructs.
275
- if (!ctx.CompletionCallback ) {
276
- return failTransform (*unsupported);
277
- }
272
+ return failTransform (*unsupported);
278
273
}
279
274
}
280
275
@@ -780,16 +775,17 @@ class ResultBuilderTransform
780
775
#undef UNSUPPORTED_STMT
781
776
782
777
private:
783
- static bool isBuildableIfChainRecursive (IfStmt *ifStmt, unsigned &numPayloads,
784
- bool &isOptional) {
778
+ static void checkBuildableIfChainRecursive (IfStmt *ifStmt,
779
+ unsigned &numPayloads,
780
+ bool &isOptional) {
785
781
// The 'then' clause contributes a payload.
786
782
++numPayloads;
787
783
788
784
// If there's an 'else' clause, it contributes payloads:
789
785
if (auto elseStmt = ifStmt->getElseStmt ()) {
790
786
// If it's 'else if', it contributes payloads recursively.
791
787
if (auto elseIfStmt = dyn_cast<IfStmt>(elseStmt)) {
792
- return isBuildableIfChainRecursive (elseIfStmt, numPayloads, isOptional);
788
+ checkBuildableIfChainRecursive (elseIfStmt, numPayloads, isOptional);
793
789
// Otherwise it's just the one.
794
790
} else {
795
791
++numPayloads;
@@ -799,8 +795,6 @@ class ResultBuilderTransform
799
795
} else {
800
796
isOptional = true ;
801
797
}
802
-
803
- return true ;
804
798
}
805
799
806
800
static bool hasUnconditionalElse (IfStmt *ifStmt) {
@@ -815,8 +809,7 @@ class ResultBuilderTransform
815
809
816
810
bool isBuildableIfChain (IfStmt *ifStmt, unsigned &numPayloads,
817
811
bool &isOptional) {
818
- if (!isBuildableIfChainRecursive (ifStmt, numPayloads, isOptional))
819
- return false ;
812
+ checkBuildableIfChainRecursive (ifStmt, numPayloads, isOptional);
820
813
821
814
// If there's a missing 'else', we need 'buildOptional' to exist.
822
815
if (isOptional && !builder.supportsOptional ())
@@ -991,11 +984,11 @@ TypeChecker::applyResultBuilderBodyTransform(FuncDecl *func, Type builderType) {
991
984
// of this decl; it's not part of the interface type.
992
985
builderType = func->mapTypeIntoContext (builderType);
993
986
994
- if ( auto result = cs. matchResultBuilder (
995
- func, builderType, resultContextType, resultConstraintKind,
996
- /* contextualType= */ Type () ,
997
- cs.getConstraintLocator (func->getBody ()))) {
998
- if (result->isFailure ())
987
+ {
988
+ auto result = cs. matchResultBuilder (
989
+ func, builderType, resultContextType, resultConstraintKind ,
990
+ /* contextualType= */ Type (), cs.getConstraintLocator (func->getBody ()));
991
+ if (!result || result->isFailure ())
999
992
return nullptr ;
1000
993
}
1001
994
@@ -1132,8 +1125,9 @@ ConstraintSystem::matchResultBuilder(AnyFunctionRef fn, Type builderType,
1132
1125
if (fn.bodyHasExplicitReturnStmt ()) {
1133
1126
// Diagnostic mode means that solver couldn't reach any viable
1134
1127
// solution, so let's diagnose presence of a `return` statement
1135
- // in the closure body.
1136
- if (shouldAttemptFixes ()) {
1128
+ // in the closure body. Avoid doing this for completion since we need to
1129
+ // continue solving the body.
1130
+ if (shouldAttemptFixes () && !isForCodeCompletion ()) {
1137
1131
if (recordFix (IgnoreResultBuilderWithReturnStmts::create (
1138
1132
*this , builderType,
1139
1133
getConstraintLocator (fn.getAbstractClosureExpr ()))))
@@ -1157,18 +1151,17 @@ ConstraintSystem::matchResultBuilder(AnyFunctionRef fn, Type builderType,
1157
1151
auto *body = transform.apply (fn.getBody ());
1158
1152
1159
1153
if (auto unsupported = transform.getUnsupportedElement ()) {
1160
- assert (!body || getASTContext ().CompletionCallback );
1161
-
1162
- // If we aren't supposed to attempt fixes, fail.
1163
- if (!shouldAttemptFixes ()) {
1164
- return getTypeMatchFailure (locator);
1165
- }
1154
+ assert (!body);
1166
1155
1167
1156
// If we're solving for code completion and the body contains the code
1168
- // completion location, skipping it won't get us to a useful solution so
1169
- // just bail.
1157
+ // completion location, fall back to solving as a regular function body.
1170
1158
if (isForCodeCompletion () &&
1171
1159
containsIDEInspectionTarget (fn.getBody ())) {
1160
+ return std::nullopt;
1161
+ }
1162
+
1163
+ // If we aren't supposed to attempt fixes, fail.
1164
+ if (!shouldAttemptFixes ()) {
1172
1165
return getTypeMatchFailure (locator);
1173
1166
}
1174
1167
0 commit comments