Skip to content

Commit acca597

Browse files
authored
Merge pull request swiftlang#59984 from ahoppen/pr/typecheck-multistamtent-closures-in-result-builders
[Sema] Type check multi-statement closures inside result builders
2 parents e530fa2 + 2c5b193 commit acca597

File tree

8 files changed

+42
-12
lines changed

8 files changed

+42
-12
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/AST/ASTDumper.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3766,8 +3766,10 @@ namespace {
37663766
printFlag("error_expr");
37673767
} else if (auto *DMT = originator.dyn_cast<DependentMemberType *>()) {
37683768
printRec("dependent_member_type", DMT);
3769-
} else {
3769+
} else if (originator.is<PlaceholderTypeRepr *>()) {
37703770
printFlag("placeholder_type_repr");
3771+
} else {
3772+
assert(false && "unknown originator");
37713773
}
37723774
PrintWithColorRAII(OS, ParenthesisColor) << ')';
37733775
}

lib/AST/ASTPrinter.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5702,8 +5702,10 @@ class TypePrinter : public TypeVisitor<TypePrinter> {
57025702
Printer << "error_expr";
57035703
} else if (auto *DMT = originator.dyn_cast<DependentMemberType *>()) {
57045704
visit(DMT);
5705-
} else {
5705+
} else if (originator.is<PlaceholderTypeRepr *>()) {
57065706
Printer << "placeholder_type_repr";
5707+
} else {
5708+
assert(false && "unknown originator");
57075709
}
57085710
Printer << ">>";
57095711
} else {

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
@@ -7123,7 +7123,13 @@ bool ConstraintSystem::participatesInInference(ClosureExpr *closure) const {
71237123

71247124
// If body is nested in a parent that has a function builder applied,
71257125
// let's prevent inference until result builders.
7126-
return !isInResultBuilderContext(closure);
7126+
if (Options.contains(
7127+
ConstraintSystemFlags::
7128+
ClosuresInResultBuildersDontParticipateInInference)) {
7129+
return !isInResultBuilderContext(closure);
7130+
} else {
7131+
return true;
7132+
}
71277133
}
71287134

71297135
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)