16
16
//
17
17
// ===----------------------------------------------------------------------===//
18
18
19
- #include " MiscDiagnostics.h"
20
19
#include " TypeChecker.h"
21
20
#include " swift/Sema/ConstraintSystem.h"
22
21
@@ -163,8 +162,8 @@ static bool isViableElement(ASTNode element) {
163
162
return true ;
164
163
}
165
164
166
- using ElementInfo = std::tuple<ASTNode, ContextualTypeInfo,
167
- /* isDiscarded= */ bool , ConstraintLocator *>;
165
+ using ElementInfo =
166
+ std::tuple<ASTNode, ContextualTypeInfo , ConstraintLocator *>;
168
167
169
168
static void createConjunction (ConstraintSystem &cs,
170
169
ArrayRef<ElementInfo> elements,
@@ -191,8 +190,7 @@ static void createConjunction(ConstraintSystem &cs,
191
190
for (const auto &entry : elements) {
192
191
ASTNode element = std::get<0 >(entry);
193
192
ContextualTypeInfo context = std::get<1 >(entry);
194
- bool isDiscarded = std::get<2 >(entry);
195
- ConstraintLocator *elementLoc = std::get<3 >(entry);
193
+ ConstraintLocator *elementLoc = std::get<2 >(entry);
196
194
197
195
if (!isViableElement (element))
198
196
continue ;
@@ -203,8 +201,8 @@ static void createConjunction(ConstraintSystem &cs,
203
201
if (isIsolated)
204
202
element.walk (paramCollector);
205
203
206
- constraints.push_back (Constraint::createClosureBodyElement (
207
- cs, element, context, elementLoc, isDiscarded ));
204
+ constraints.push_back (
205
+ Constraint::createClosureBodyElement ( cs, element, context, elementLoc));
208
206
}
209
207
210
208
// It's possible that there are no viable elements in the body,
@@ -222,9 +220,8 @@ static void createConjunction(ConstraintSystem &cs,
222
220
}
223
221
224
222
ElementInfo makeElement (ASTNode node, ConstraintLocator *locator,
225
- ContextualTypeInfo context = ContextualTypeInfo(),
226
- bool isDiscarded = false) {
227
- return std::make_tuple (node, context, isDiscarded, locator);
223
+ ContextualTypeInfo context = ContextualTypeInfo()) {
224
+ return std::make_tuple (node, context, locator);
228
225
}
229
226
230
227
static ProtocolDecl *getSequenceProtocol (ASTContext &ctx, SourceLoc loc,
@@ -754,8 +751,6 @@ class ClosureConstraintGenerator
754
751
755
752
void visitBraceStmt (BraceStmt *braceStmt) {
756
753
if (isSupportedMultiStatementClosure ()) {
757
- auto &ctx = cs.getASTContext ();
758
-
759
754
if (isChildOf (StmtKind::Case)) {
760
755
auto *caseStmt = cast<CaseStmt>(
761
756
locator->castLastElementTo <LocatorPathElt::ClosureBodyElement>()
@@ -770,15 +765,10 @@ class ClosureConstraintGenerator
770
765
771
766
SmallVector<ElementInfo, 4 > elements;
772
767
for (auto element : braceStmt->getElements ()) {
773
- bool isDiscarded =
774
- element.is <Expr *>() &&
775
- (!ctx.LangOpts .Playground && !ctx.LangOpts .DebuggerSupport );
776
-
777
768
elements.push_back (makeElement (
778
769
element,
779
770
cs.getConstraintLocator (
780
- locator, LocatorPathElt::ClosureBodyElement (element)),
781
- /* contextualInfo=*/ {}, isDiscarded));
771
+ locator, LocatorPathElt::ClosureBodyElement (element))));
782
772
}
783
773
784
774
createConjunction (cs, elements, locator);
@@ -855,7 +845,7 @@ class ClosureConstraintGenerator
855
845
856
846
bool isSupportedMultiStatementClosure () const {
857
847
return !closure->hasSingleExpressionBody () &&
858
- cs. participatesInInference (closure);
848
+ shouldTypeCheckInEnclosingExpression (closure);
859
849
}
860
850
861
851
#define UNSUPPORTED_STMT (STMT ) void visit##STMT##Stmt(STMT##Stmt *) { \
@@ -886,7 +876,7 @@ class ClosureConstraintGenerator
886
876
bool ConstraintSystem::generateConstraints (ClosureExpr *closure) {
887
877
auto &ctx = closure->getASTContext ();
888
878
889
- if (participatesInInference (closure)) {
879
+ if (shouldTypeCheckInEnclosingExpression (closure)) {
890
880
ClosureConstraintGenerator generator (*this , closure,
891
881
getConstraintLocator (closure));
892
882
generator.visit (closure->getBody ());
@@ -935,22 +925,28 @@ bool isConditionOfStmt(ConstraintLocatorBuilder locator) {
935
925
936
926
ConstraintSystem::SolutionKind
937
927
ConstraintSystem::simplifyClosureBodyElementConstraint (
938
- ASTNode element, ContextualTypeInfo context, bool isDiscarded ,
939
- TypeMatchOptions flags, ConstraintLocatorBuilder locator) {
928
+ ASTNode element, ContextualTypeInfo context, TypeMatchOptions flags ,
929
+ ConstraintLocatorBuilder locator) {
940
930
auto *closure = castToExpr<ClosureExpr>(locator.getAnchor ());
941
931
942
932
ClosureConstraintGenerator generator (*this , closure,
943
933
getConstraintLocator (locator));
944
934
945
935
if (auto *expr = element.dyn_cast <Expr *>()) {
946
- SolutionApplicationTarget target (expr, closure, context.purpose ,
947
- context.getType (), isDiscarded);
936
+ if (context.purpose != CTP_Unused) {
937
+ SolutionApplicationTarget target (expr, closure, context.purpose ,
938
+ context.getType (),
939
+ /* isDiscarded=*/ false );
948
940
949
- if (generateConstraints (target, FreeTypeVariableBinding::Disallow))
950
- return SolutionKind::Error;
941
+ if (generateConstraints (target, FreeTypeVariableBinding::Disallow))
942
+ return SolutionKind::Error;
943
+
944
+ setSolutionApplicationTarget (expr, target);
945
+ return SolutionKind::Solved;
946
+ }
951
947
952
- setSolutionApplicationTarget ( expr, target);
953
- return SolutionKind::Solved ;
948
+ if (! generateConstraints ( expr, closure, /* isInputExpression= */ false ))
949
+ return SolutionKind::Error ;
954
950
} else if (auto *stmt = element.dyn_cast <Stmt *>()) {
955
951
generator.visit (stmt);
956
952
} else if (auto *cond = element.dyn_cast <StmtCondition *>()) {
@@ -1164,17 +1160,12 @@ class ClosureConstraintApplication
1164
1160
1165
1161
auto forEachTarget =
1166
1162
rewriteTarget (*cs.getSolutionApplicationTarget (forEachStmt));
1167
-
1168
1163
if (!forEachTarget)
1169
1164
hadError = true ;
1170
1165
1171
1166
auto body = visit (forEachStmt->getBody ()).get <Stmt *>();
1172
1167
forEachStmt->setBody (cast<BraceStmt>(body));
1173
1168
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
-
1178
1169
return forEachStmt;
1179
1170
}
1180
1171
@@ -1250,32 +1241,13 @@ class ClosureConstraintApplication
1250
1241
}
1251
1242
1252
1243
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
-
1267
1244
for (auto &node : braceStmt->getElements ()) {
1268
1245
if (auto expr = node.dyn_cast <Expr *>()) {
1269
1246
// Rewrite the expression.
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 {
1247
+ if (auto rewrittenExpr = rewriteExpr (expr))
1248
+ node = rewrittenExpr;
1249
+ else
1277
1250
hadError = true ;
1278
- }
1279
1251
} else if (auto stmt = node.dyn_cast <Stmt *>()) {
1280
1252
node = visit (stmt);
1281
1253
} else {
0 commit comments