mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
Revert "[TypeChecker] SE-0326: Enable multi-statement closure inference by default"
This commit is contained in:
@@ -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 {
|
||||
|
||||
Reference in New Issue
Block a user