@@ -287,23 +287,6 @@ static bool isViableElement(ASTNode element,
287
287
using ElementInfo = std::tuple<ASTNode, ContextualTypeInfo,
288
288
/*isDiscarded=*/bool, ConstraintLocator *>;
289
289
290
- static TypeVariableType *assignClosureThrownErrorType(
291
- ConstraintSystem &cs, ClosureExpr *closure) {
292
- // FIXME: Remove this once the inference is working in general.
293
- if (!cs.getASTContext().LangOpts.hasFeature(Feature::FullTypedThrows))
294
- return nullptr;
295
-
296
- auto closureType = cs.getClosureType(closure);
297
- auto thrownType = closureType->getEffectiveThrownErrorTypeOrNever();
298
- auto computedThrownType = cs.inferCaughtErrorType(closure);
299
- cs.addConstraint(
300
- ConstraintKind::Conversion, computedThrownType, thrownType,
301
- cs.getConstraintLocator(closure,
302
- ConstraintLocator::ClosureThrownError));
303
-
304
- return computedThrownType->getAs<TypeVariableType>();
305
- }
306
-
307
290
static void createConjunction(ConstraintSystem &cs, DeclContext *dc,
308
291
ArrayRef<ElementInfo> elements,
309
292
ConstraintLocator *locator, bool isIsolated,
@@ -341,6 +324,17 @@ static void createConjunction(ConstraintSystem &cs, DeclContext *dc,
341
324
isIsolated = true;
342
325
}
343
326
327
+ if (auto syntacticElement =
328
+ locator->getLastElementAs<LocatorPathElt::SyntacticElement>()) {
329
+ // If we are at a do..catch, and we're inferring a throw error type for
330
+ // the do..catch, we're now in a position to finalize the thrown type.
331
+ if (auto doCatch = dyn_cast_or_null<DoCatchStmt>(
332
+ syntacticElement->getElement().dyn_cast<Stmt *>())) {
333
+ if (cs.getCaughtErrorType(doCatch)->is<TypeVariableType>())
334
+ isIsolated = true;
335
+ }
336
+ }
337
+
344
338
if (locator->isForSingleValueStmtConjunction()) {
345
339
auto *SVE = castToExpr<SingleValueStmtExpr>(locator->getAnchor());
346
340
referencedVars.push_back(cs.getType(SVE)->castTo<TypeVariableType>());
@@ -384,19 +378,17 @@ static void createConjunction(ConstraintSystem &cs, DeclContext *dc,
384
378
cs, element, context, elementLoc, isDiscarded));
385
379
}
386
380
387
- for (auto *externalVar : paramCollector.getTypeVars())
388
- referencedVars.push_back(externalVar);
389
-
390
- #if false
391
381
// If the body of the closure is being used to infer the thrown error type
392
382
// of that closure, introduce a constraint to do so.
393
383
if (locator->directlyAt<ClosureExpr>()) {
394
384
auto *closure = castToExpr<ClosureExpr>(locator->getAnchor());
395
- if (auto thrownErrorTypeVar = assignClosureThrownErrorType(cs, closure))
396
- referencedVars.push_back(thrownErrorTypeVar );
385
+ if (auto thrownError = cs.getCaughtErrorType( closure))
386
+ paramCollector.inferTypeVars(thrownError );
397
387
}
398
- #endif
399
-
388
+
389
+ for (auto *externalVar : paramCollector.getTypeVars())
390
+ referencedVars.push_back(externalVar);
391
+
400
392
// It's possible that there are no viable elements in the body,
401
393
// because e.g. whole body is an `#if` statement or it only has
402
394
// declarations that are checked during solution application.
@@ -1055,20 +1047,26 @@ class SyntacticElementConstraintGenerator
1055
1047
void visitDoCatchStmt(DoCatchStmt *doStmt) {
1056
1048
SmallVector<ElementInfo, 4> elements;
1057
1049
1050
+ auto myLocator = locator;
1051
+ if (cs.getASTContext().LangOpts.hasFeature(Feature::FullTypedThrows)) {
1052
+ myLocator = cs.getConstraintLocator(
1053
+ locator, LocatorPathElt::SyntacticElement(doStmt));
1054
+ }
1055
+
1058
1056
// First, let's record a body of `do` statement. Note we need to add a
1059
1057
// SyntaticElement locator path element here to avoid treating the inner
1060
1058
// brace conjunction as being isolated if 'doLoc' is for an isolated
1061
1059
// conjunction (as is the case with 'do' expressions).
1062
1060
auto *doBodyLoc = cs.getConstraintLocator(
1063
- locator , LocatorPathElt::SyntacticElement(doStmt->getBody()));
1061
+ myLocator , LocatorPathElt::SyntacticElement(doStmt->getBody()));
1064
1062
elements.push_back(makeElement(doStmt->getBody(), doBodyLoc));
1065
1063
1066
1064
// After that has been type-checked, let's switch to
1067
1065
// individual `catch` statements.
1068
1066
for (auto *catchStmt : doStmt->getCatches())
1069
1067
elements.push_back(makeElement(catchStmt, locator));
1070
1068
1071
- createConjunction(elements, locator );
1069
+ createConjunction(elements, myLocator );
1072
1070
}
1073
1071
1074
1072
void visitCaseStmt(CaseStmt *caseStmt) {
@@ -1156,7 +1154,7 @@ class SyntacticElementConstraintGenerator
1156
1154
}
1157
1155
1158
1156
if (closure) {
1159
- assignClosureThrownErrorType(cs, closure);
1157
+ cs.finalizeCaughtErrorType( closure);
1160
1158
}
1161
1159
1162
1160
return;
0 commit comments