1616//
1717// ===----------------------------------------------------------------------===//
1818
19+ #include " MiscDiagnostics.h"
1920#include " TypeChecker.h"
2021#include " swift/Sema/ConstraintSystem.h"
2122
@@ -162,8 +163,8 @@ static bool isViableElement(ASTNode element) {
162163 return true ;
163164}
164165
165- using ElementInfo =
166- std::tuple<ASTNode, ContextualTypeInfo , ConstraintLocator *>;
166+ using ElementInfo = std::tuple<ASTNode, ContextualTypeInfo,
167+ /* isDiscarded= */ bool , ConstraintLocator *>;
167168
168169static void createConjunction (ConstraintSystem &cs,
169170 ArrayRef<ElementInfo> elements,
@@ -190,7 +191,8 @@ static void createConjunction(ConstraintSystem &cs,
190191 for (const auto &entry : elements) {
191192 ASTNode element = std::get<0 >(entry);
192193 ContextualTypeInfo context = std::get<1 >(entry);
193- ConstraintLocator *elementLoc = std::get<2 >(entry);
194+ bool isDiscarded = std::get<2 >(entry);
195+ ConstraintLocator *elementLoc = std::get<3 >(entry);
194196
195197 if (!isViableElement (element))
196198 continue ;
@@ -201,8 +203,8 @@ static void createConjunction(ConstraintSystem &cs,
201203 if (isIsolated)
202204 element.walk (paramCollector);
203205
204- constraints.push_back (
205- Constraint::createClosureBodyElement ( cs, element, context, elementLoc));
206+ constraints.push_back (Constraint::createClosureBodyElement (
207+ cs, element, context, elementLoc, isDiscarded ));
206208 }
207209
208210 // It's possible that there are no viable elements in the body,
@@ -220,8 +222,9 @@ static void createConjunction(ConstraintSystem &cs,
220222}
221223
222224ElementInfo makeElement (ASTNode node, ConstraintLocator *locator,
223- ContextualTypeInfo context = ContextualTypeInfo()) {
224- return std::make_tuple (node, context, locator);
225+ ContextualTypeInfo context = ContextualTypeInfo(),
226+ bool isDiscarded = false) {
227+ return std::make_tuple (node, context, isDiscarded, locator);
225228}
226229
227230static ProtocolDecl *getSequenceProtocol (ASTContext &ctx, SourceLoc loc,
@@ -751,6 +754,8 @@ class ClosureConstraintGenerator
751754
752755 void visitBraceStmt (BraceStmt *braceStmt) {
753756 if (isSupportedMultiStatementClosure ()) {
757+ auto &ctx = cs.getASTContext ();
758+
754759 if (isChildOf (StmtKind::Case)) {
755760 auto *caseStmt = cast<CaseStmt>(
756761 locator->castLastElementTo <LocatorPathElt::ClosureBodyElement>()
@@ -765,10 +770,15 @@ class ClosureConstraintGenerator
765770
766771 SmallVector<ElementInfo, 4 > elements;
767772 for (auto element : braceStmt->getElements ()) {
773+ bool isDiscarded =
774+ element.is <Expr *>() &&
775+ (!ctx.LangOpts .Playground && !ctx.LangOpts .DebuggerSupport );
776+
768777 elements.push_back (makeElement (
769778 element,
770779 cs.getConstraintLocator (
771- locator, LocatorPathElt::ClosureBodyElement (element))));
780+ locator, LocatorPathElt::ClosureBodyElement (element)),
781+ /* contextualInfo=*/ {}, isDiscarded));
772782 }
773783
774784 createConjunction (cs, elements, locator);
@@ -845,7 +855,7 @@ class ClosureConstraintGenerator
845855
846856 bool isSupportedMultiStatementClosure () const {
847857 return !closure->hasSingleExpressionBody () &&
848- shouldTypeCheckInEnclosingExpression (closure);
858+ cs. participatesInInference (closure);
849859 }
850860
851861#define UNSUPPORTED_STMT (STMT ) void visit##STMT##Stmt(STMT##Stmt *) { \
@@ -876,7 +886,7 @@ class ClosureConstraintGenerator
876886bool ConstraintSystem::generateConstraints (ClosureExpr *closure) {
877887 auto &ctx = closure->getASTContext ();
878888
879- if (shouldTypeCheckInEnclosingExpression (closure)) {
889+ if (participatesInInference (closure)) {
880890 ClosureConstraintGenerator generator (*this , closure,
881891 getConstraintLocator (closure));
882892 generator.visit (closure->getBody ());
@@ -925,28 +935,22 @@ bool isConditionOfStmt(ConstraintLocatorBuilder locator) {
925935
926936ConstraintSystem::SolutionKind
927937ConstraintSystem::simplifyClosureBodyElementConstraint (
928- ASTNode element, ContextualTypeInfo context, TypeMatchOptions flags ,
929- ConstraintLocatorBuilder locator) {
938+ ASTNode element, ContextualTypeInfo context, bool isDiscarded ,
939+ TypeMatchOptions flags, ConstraintLocatorBuilder locator) {
930940 auto *closure = castToExpr<ClosureExpr>(locator.getAnchor ());
931941
932942 ClosureConstraintGenerator generator (*this , closure,
933943 getConstraintLocator (locator));
934944
935945 if (auto *expr = element.dyn_cast <Expr *>()) {
936- if (context.purpose != CTP_Unused) {
937- SolutionApplicationTarget target (expr, closure, context.purpose ,
938- context.getType (),
939- /* isDiscarded=*/ false );
940-
941- if (generateConstraints (target, FreeTypeVariableBinding::Disallow))
942- return SolutionKind::Error;
943-
944- setSolutionApplicationTarget (expr, target);
945- return SolutionKind::Solved;
946- }
946+ SolutionApplicationTarget target (expr, closure, context.purpose ,
947+ context.getType (), isDiscarded);
947948
948- if (! generateConstraints (expr, closure, /* isInputExpression= */ false ))
949+ if (generateConstraints (target, FreeTypeVariableBinding::Disallow ))
949950 return SolutionKind::Error;
951+
952+ setSolutionApplicationTarget (expr, target);
953+ return SolutionKind::Solved;
950954 } else if (auto *stmt = element.dyn_cast <Stmt *>()) {
951955 generator.visit (stmt);
952956 } else if (auto *cond = element.dyn_cast <StmtCondition *>()) {
@@ -1160,12 +1164,17 @@ class ClosureConstraintApplication
11601164
11611165 auto forEachTarget =
11621166 rewriteTarget (*cs.getSolutionApplicationTarget (forEachStmt));
1167+
11631168 if (!forEachTarget)
11641169 hadError = true ;
11651170
11661171 auto body = visit (forEachStmt->getBody ()).get <Stmt *>();
11671172 forEachStmt->setBody (cast<BraceStmt>(body));
11681173
1174+ // Check to see if the sequence expr is throwing (in async context),
1175+ // if so require the stmt to have a `try`.
1176+ hadError |= diagnoseUnhandledThrowsInAsyncContext (closure, forEachStmt);
1177+
11691178 return forEachStmt;
11701179 }
11711180
@@ -1241,13 +1250,32 @@ class ClosureConstraintApplication
12411250 }
12421251
12431252 ASTNode visitBraceStmt (BraceStmt *braceStmt) {
1253+ auto &cs = solution.getConstraintSystem ();
1254+
1255+ // Diagnose defer statement being last one in block.
1256+ if (!braceStmt->empty ()) {
1257+ if (auto stmt = braceStmt->getLastElement ().dyn_cast <Stmt *>()) {
1258+ if (auto deferStmt = dyn_cast<DeferStmt>(stmt)) {
1259+ auto &diags = closure->getASTContext ().Diags ;
1260+ diags
1261+ .diagnose (deferStmt->getStartLoc (), diag::defer_stmt_at_block_end)
1262+ .fixItReplace (deferStmt->getStartLoc (), " do" );
1263+ }
1264+ }
1265+ }
1266+
12441267 for (auto &node : braceStmt->getElements ()) {
12451268 if (auto expr = node.dyn_cast <Expr *>()) {
12461269 // Rewrite the expression.
1247- if (auto rewrittenExpr = rewriteExpr (expr))
1248- node = rewrittenExpr;
1249- else
1270+ auto target = *cs.getSolutionApplicationTarget (expr);
1271+ if (auto rewrittenTarget = rewriteTarget (target)) {
1272+ node = rewrittenTarget->getAsExpr ();
1273+
1274+ if (target.isDiscardedExpr ())
1275+ TypeChecker::checkIgnoredExpr (castToExpr (node));
1276+ } else {
12501277 hadError = true ;
1278+ }
12511279 } else if (auto stmt = node.dyn_cast <Stmt *>()) {
12521280 node = visit (stmt);
12531281 } else {
0 commit comments