Skip to content

Commit 2c5b193

Browse files
committed
[Sema] Type check multi-statement closures inside result builders
1 parent 4169f93 commit 2c5b193

File tree

6 files changed

+36
-10
lines changed

6 files changed

+36
-10
lines changed

include/swift/Sema/ConstraintSystem.h

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -73,8 +73,9 @@ class SolutionApplicationTarget;
7373
// so they could be made friends of ConstraintSystem.
7474
namespace TypeChecker {
7575

76-
Optional<BraceStmt *> applyResultBuilderBodyTransform(FuncDecl *func,
77-
Type builderType);
76+
Optional<BraceStmt *> applyResultBuilderBodyTransform(
77+
FuncDecl *func, Type builderType,
78+
bool ClosuresInResultBuilderDontParticipateInInference);
7879

7980
Optional<constraints::SolutionApplicationTarget>
8081
typeCheckExpression(constraints::SolutionApplicationTarget &target,
@@ -1801,6 +1802,12 @@ enum class ConstraintSystemFlags {
18011802

18021803
/// Disable macro expansions.
18031804
DisableMacroExpansions = 0x100,
1805+
1806+
/// Non solver-based code completion expects that closures inside result
1807+
/// builders don't participate in inference.
1808+
/// Once all code completion kinds are migrated to solver-based we should be
1809+
/// able to remove this flag.
1810+
ClosuresInResultBuildersDontParticipateInInference = 0x200,
18041811
};
18051812

18061813
/// Options that affect the constraint system as a whole.
@@ -3609,8 +3616,9 @@ class ConstraintSystem {
36093616

36103617
// FIXME: Perhaps these belong on ConstraintSystem itself.
36113618
friend Optional<BraceStmt *>
3612-
swift::TypeChecker::applyResultBuilderBodyTransform(FuncDecl *func,
3613-
Type builderType);
3619+
swift::TypeChecker::applyResultBuilderBodyTransform(
3620+
FuncDecl *func, Type builderType,
3621+
bool ClosuresInResultBuilderDontParticipateInInference);
36143622

36153623
friend Optional<SolutionApplicationTarget>
36163624
swift::TypeChecker::typeCheckExpression(

lib/Sema/BuilderTransform.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2224,7 +2224,8 @@ BraceStmt *swift::applyResultBuilderTransform(
22242224
}
22252225

22262226
Optional<BraceStmt *> TypeChecker::applyResultBuilderBodyTransform(
2227-
FuncDecl *func, Type builderType) {
2227+
FuncDecl *func, Type builderType,
2228+
bool ClosuresInResultBuilderDontParticipateInInference) {
22282229
// Pre-check the body: pre-check any expressions in it and look
22292230
// for return statements.
22302231
//
@@ -2280,6 +2281,10 @@ Optional<BraceStmt *> TypeChecker::applyResultBuilderBodyTransform(
22802281
}
22812282

22822283
ConstraintSystemOptions options = ConstraintSystemFlags::AllowFixes;
2284+
if (ClosuresInResultBuilderDontParticipateInInference) {
2285+
options |= ConstraintSystemFlags::
2286+
ClosuresInResultBuildersDontParticipateInInference;
2287+
}
22832288
auto resultInterfaceTy = func->getResultInterfaceType();
22842289
auto resultContextType = func->mapTypeIntoContext(resultInterfaceTy);
22852290

lib/Sema/CSFix.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -622,6 +622,10 @@ bool AllowTupleTypeMismatch::coalesceAndDiagnose(
622622
purpose = cs.getContextualTypePurpose(locator->getAnchor());
623623
}
624624

625+
if (!getFromType()->is<TupleType>() || !getToType()->is<TupleType>()) {
626+
return false;
627+
}
628+
625629
TupleContextualFailure failure(solution, purpose, getFromType(), getToType(),
626630
indices, locator);
627631
return failure.diagnose(asNote);

lib/Sema/ConstraintSystem.cpp

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7143,7 +7143,13 @@ bool ConstraintSystem::participatesInInference(ClosureExpr *closure) const {
71437143

71447144
// If body is nested in a parent that has a function builder applied,
71457145
// let's prevent inference until result builders.
7146-
return !isInResultBuilderContext(closure);
7146+
if (Options.contains(
7147+
ConstraintSystemFlags::
7148+
ClosuresInResultBuildersDontParticipateInInference)) {
7149+
return !isInResultBuilderContext(closure);
7150+
} else {
7151+
return true;
7152+
}
71477153
}
71487154

71497155
TypeVarBindingProducer::TypeVarBindingProducer(BindingSet &bindings)

lib/Sema/TypeCheckStmt.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2336,8 +2336,10 @@ bool TypeCheckASTNodeAtLocRequest::evaluate(
23362336
// Function builder function doesn't support partial type checking.
23372337
if (auto *func = dyn_cast<FuncDecl>(DC)) {
23382338
if (Type builderType = getResultBuilderType(func)) {
2339-
auto optBody =
2340-
TypeChecker::applyResultBuilderBodyTransform(func, builderType);
2339+
auto optBody = TypeChecker::applyResultBuilderBodyTransform(
2340+
func, builderType,
2341+
/*ClosuresInResultBuilderDontParticipateInInference=*/
2342+
ctx.CompletionCallback == nullptr);
23412343
if (optBody && *optBody) {
23422344
// Wire up the function body now.
23432345
func->setBody(*optBody, AbstractFunctionDecl::BodyKind::TypeChecked);

lib/Sema/TypeChecker.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -457,8 +457,9 @@ void typeCheckASTNode(ASTNode &node, DeclContext *DC,
457457
/// e.g., because of a \c return statement. Otherwise, returns either the
458458
/// fully type-checked body of the function (on success) or a \c nullptr
459459
/// value if an error occurred while type checking the transformed body.
460-
Optional<BraceStmt *> applyResultBuilderBodyTransform(FuncDecl *func,
461-
Type builderType);
460+
Optional<BraceStmt *> applyResultBuilderBodyTransform(
461+
FuncDecl *func, Type builderType,
462+
bool ClosuresInResultBuilderDontParticipateInInference = true);
462463

463464
/// Find the return statements within the body of the given function.
464465
std::vector<ReturnStmt *> findReturnStatements(AnyFunctionRef fn);

0 commit comments

Comments
 (0)