Revert "[TypeChecker] SE-0326: Enable multi-statement closure inference by default"

This commit is contained in:
Pavel Yaskevich
2021-11-29 17:26:08 -08:00
committed by GitHub
parent e7120a61ad
commit bc54bc6bb7
49 changed files with 247 additions and 480 deletions

View File

@@ -16,7 +16,6 @@
//
//===----------------------------------------------------------------------===//
#include "MiscDiagnostics.h"
#include "TypeChecker.h"
#include "swift/Sema/ConstraintSystem.h"
@@ -163,8 +162,8 @@ static bool isViableElement(ASTNode element) {
return true;
}
using ElementInfo = std::tuple<ASTNode, ContextualTypeInfo,
/*isDiscarded=*/bool, ConstraintLocator *>;
using ElementInfo =
std::tuple<ASTNode, ContextualTypeInfo, ConstraintLocator *>;
static void createConjunction(ConstraintSystem &cs,
ArrayRef<ElementInfo> elements,
@@ -191,8 +190,7 @@ static void createConjunction(ConstraintSystem &cs,
for (const auto &entry : elements) {
ASTNode element = std::get<0>(entry);
ContextualTypeInfo context = std::get<1>(entry);
bool isDiscarded = std::get<2>(entry);
ConstraintLocator *elementLoc = std::get<3>(entry);
ConstraintLocator *elementLoc = std::get<2>(entry);
if (!isViableElement(element))
continue;
@@ -203,8 +201,8 @@ static void createConjunction(ConstraintSystem &cs,
if (isIsolated)
element.walk(paramCollector);
constraints.push_back(Constraint::createClosureBodyElement(
cs, element, context, elementLoc, isDiscarded));
constraints.push_back(
Constraint::createClosureBodyElement(cs, element, context, elementLoc));
}
// It's possible that there are no viable elements in the body,
@@ -222,9 +220,8 @@ static void createConjunction(ConstraintSystem &cs,
}
ElementInfo makeElement(ASTNode node, ConstraintLocator *locator,
ContextualTypeInfo context = ContextualTypeInfo(),
bool isDiscarded = false) {
return std::make_tuple(node, context, isDiscarded, locator);
ContextualTypeInfo context = ContextualTypeInfo()) {
return std::make_tuple(node, context, locator);
}
static ProtocolDecl *getSequenceProtocol(ASTContext &ctx, SourceLoc loc,
@@ -754,8 +751,6 @@ private:
void visitBraceStmt(BraceStmt *braceStmt) {
if (isSupportedMultiStatementClosure()) {
auto &ctx = cs.getASTContext();
if (isChildOf(StmtKind::Case)) {
auto *caseStmt = cast<CaseStmt>(
locator->castLastElementTo<LocatorPathElt::ClosureBodyElement>()
@@ -770,15 +765,10 @@ private:
SmallVector<ElementInfo, 4> elements;
for (auto element : braceStmt->getElements()) {
bool isDiscarded =
element.is<Expr *>() &&
(!ctx.LangOpts.Playground && !ctx.LangOpts.DebuggerSupport);
elements.push_back(makeElement(
element,
cs.getConstraintLocator(
locator, LocatorPathElt::ClosureBodyElement(element)),
/*contextualInfo=*/{}, isDiscarded));
locator, LocatorPathElt::ClosureBodyElement(element))));
}
createConjunction(cs, elements, locator);
@@ -855,7 +845,7 @@ private:
bool isSupportedMultiStatementClosure() const {
return !closure->hasSingleExpressionBody() &&
cs.participatesInInference(closure);
shouldTypeCheckInEnclosingExpression(closure);
}
#define UNSUPPORTED_STMT(STMT) void visit##STMT##Stmt(STMT##Stmt *) { \
@@ -886,7 +876,7 @@ private:
bool ConstraintSystem::generateConstraints(ClosureExpr *closure) {
auto &ctx = closure->getASTContext();
if (participatesInInference(closure)) {
if (shouldTypeCheckInEnclosingExpression(closure)) {
ClosureConstraintGenerator generator(*this, closure,
getConstraintLocator(closure));
generator.visit(closure->getBody());
@@ -935,22 +925,28 @@ bool isConditionOfStmt(ConstraintLocatorBuilder locator) {
ConstraintSystem::SolutionKind
ConstraintSystem::simplifyClosureBodyElementConstraint(
ASTNode element, ContextualTypeInfo context, bool isDiscarded,
TypeMatchOptions flags, ConstraintLocatorBuilder locator) {
ASTNode element, ContextualTypeInfo context, TypeMatchOptions flags,
ConstraintLocatorBuilder locator) {
auto *closure = castToExpr<ClosureExpr>(locator.getAnchor());
ClosureConstraintGenerator generator(*this, closure,
getConstraintLocator(locator));
if (auto *expr = element.dyn_cast<Expr *>()) {
SolutionApplicationTarget target(expr, closure, context.purpose,
context.getType(), isDiscarded);
if (context.purpose != CTP_Unused) {
SolutionApplicationTarget target(expr, closure, context.purpose,
context.getType(),
/*isDiscarded=*/false);
if (generateConstraints(target, FreeTypeVariableBinding::Disallow))
if (generateConstraints(target, FreeTypeVariableBinding::Disallow))
return SolutionKind::Error;
setSolutionApplicationTarget(expr, target);
return SolutionKind::Solved;
}
if (!generateConstraints(expr, closure, /*isInputExpression=*/false))
return SolutionKind::Error;
setSolutionApplicationTarget(expr, target);
return SolutionKind::Solved;
} else if (auto *stmt = element.dyn_cast<Stmt *>()) {
generator.visit(stmt);
} else if (auto *cond = element.dyn_cast<StmtCondition *>()) {
@@ -1164,17 +1160,12 @@ private:
auto forEachTarget =
rewriteTarget(*cs.getSolutionApplicationTarget(forEachStmt));
if (!forEachTarget)
hadError = true;
auto body = visit(forEachStmt->getBody()).get<Stmt *>();
forEachStmt->setBody(cast<BraceStmt>(body));
// Check to see if the sequence expr is throwing (in async context),
// if so require the stmt to have a `try`.
hadError |= diagnoseUnhandledThrowsInAsyncContext(closure, forEachStmt);
return forEachStmt;
}
@@ -1250,32 +1241,13 @@ private:
}
ASTNode visitBraceStmt(BraceStmt *braceStmt) {
auto &cs = solution.getConstraintSystem();
// Diagnose defer statement being last one in block.
if (!braceStmt->empty()) {
if (auto stmt = braceStmt->getLastElement().dyn_cast<Stmt *>()) {
if (auto deferStmt = dyn_cast<DeferStmt>(stmt)) {
auto &diags = closure->getASTContext().Diags;
diags
.diagnose(deferStmt->getStartLoc(), diag::defer_stmt_at_block_end)
.fixItReplace(deferStmt->getStartLoc(), "do");
}
}
}
for (auto &node : braceStmt->getElements()) {
if (auto expr = node.dyn_cast<Expr *>()) {
// Rewrite the expression.
auto target = *cs.getSolutionApplicationTarget(expr);
if (auto rewrittenTarget = rewriteTarget(target)) {
node = rewrittenTarget->getAsExpr();
if (target.isDiscardedExpr())
TypeChecker::checkIgnoredExpr(castToExpr(node));
} else {
if (auto rewrittenExpr = rewriteExpr(expr))
node = rewrittenExpr;
else
hadError = true;
}
} else if (auto stmt = node.dyn_cast<Stmt *>()) {
node = visit(stmt);
} else {