@@ -368,6 +368,114 @@ bool ConstraintSystem::containsIDEInspectionTarget(
368
368
Context.SourceMgr);
369
369
}
370
370
371
+ void ConstraintSystem::recordPotentialThrowSite(
372
+ PotentialThrowSite::Kind kind, Type type,
373
+ ConstraintLocatorBuilder locator) {
374
+ ASTContext &ctx = getASTContext();
375
+
376
+ // Only record potential throw sites when typed throws is enabled.
377
+ if (!ctx.LangOpts.hasFeature(Feature::TypedThrows))
378
+ return;
379
+
380
+ // Catch node location is determined by the source location.
381
+ auto sourceLoc = locator.getAnchor().getStartLoc();
382
+ if (!sourceLoc)
383
+ return;
384
+
385
+ auto catchNode = ASTScope::lookupCatchNode(DC->getParentModule(), sourceLoc);
386
+ if (!catchNode)
387
+ return;
388
+
389
+ // If there is an explicit caught type for this node, we don't need to
390
+ // record a potential throw site.
391
+ if (Type explicitCaughtType = catchNode.getExplicitCaughtType(ctx))
392
+ return;
393
+
394
+ // do..catch statements without an explicit `throws` clause do infer
395
+ // thrown types.
396
+ if (auto doCatch = catchNode.dyn_cast<DoCatchStmt *>()) {
397
+ potentialThrowSites.push_back(
398
+ {catchNode,
399
+ PotentialThrowSite{kind, type, getConstraintLocator(locator)}});
400
+ return;
401
+ }
402
+
403
+ // Closures without an explicit `throws` clause, and which syntactically
404
+ // appear that they can throw, do infer thrown types.
405
+ auto closure = catchNode.get<ClosureExpr *>();
406
+
407
+ // Check whether the closure syntactically throws. If not, there is no
408
+ // need to record a throw site.
409
+ if (!closureEffects(closure).isThrowing())
410
+ return;
411
+
412
+ potentialThrowSites.push_back(
413
+ {catchNode,
414
+ PotentialThrowSite{kind, type, getConstraintLocator(locator)}});
415
+ }
416
+
417
+ Type ConstraintSystem::getCaughtErrorType(CatchNode catchNode) {
418
+ ASTContext &ctx = getASTContext();
419
+
420
+ // If there is an explicit caught type for this node, use it.
421
+ if (Type explicitCaughtType = catchNode.getExplicitCaughtType(ctx)) {
422
+ if (explicitCaughtType->hasTypeParameter())
423
+ explicitCaughtType = DC->mapTypeIntoContext(explicitCaughtType);
424
+
425
+ return explicitCaughtType;
426
+ }
427
+
428
+ // Retrieve the thrown error type of a closure.
429
+ // FIXME: This will need to change when we do inference of thrown error
430
+ // types in closures.
431
+ if (auto closure = catchNode.dyn_cast<ClosureExpr *>()) {
432
+ return getClosureType(closure)->getEffectiveThrownErrorTypeOrNever();
433
+ }
434
+
435
+ // Handle inference of caught error types.
436
+
437
+ // Collect all of the potential throw sites for this catch node.
438
+ SmallVector<PotentialThrowSite, 2> throwSites;
439
+ for (const auto &potentialThrowSite : potentialThrowSites) {
440
+ if (potentialThrowSite.first == catchNode) {
441
+ throwSites.push_back(potentialThrowSite.second);
442
+ }
443
+ }
444
+
445
+ Type caughtErrorType = ctx.getNeverType();
446
+ for (const auto &throwSite : throwSites) {
447
+ Type type = simplifyType(throwSite.type);
448
+
449
+ Type thrownErrorType;
450
+ switch (throwSite.kind) {
451
+ case PotentialThrowSite::Application: {
452
+ auto fnType = type->castTo<AnyFunctionType>();
453
+ thrownErrorType = fnType->getEffectiveThrownErrorTypeOrNever();
454
+ break;
455
+ }
456
+
457
+ case PotentialThrowSite::ExplicitThrow:
458
+ case PotentialThrowSite::NonExhaustiveDoCatch:
459
+ thrownErrorType = type;
460
+ break;
461
+ }
462
+
463
+ // Perform the errorUnion() of the caught error type so far with the
464
+ // thrown error type of this potential throw site.
465
+ caughtErrorType = TypeChecker::errorUnion(
466
+ caughtErrorType, thrownErrorType,
467
+ [&](Type type) {
468
+ return simplifyType(type);
469
+ });
470
+
471
+ // If we ended up at 'any Error', we're done.
472
+ if (caughtErrorType->isErrorExistentialType())
473
+ break;
474
+ }
475
+
476
+ return caughtErrorType;
477
+ }
478
+
371
479
ConstraintLocator *ConstraintSystem::getConstraintLocator(
372
480
ASTNode anchor, ArrayRef<ConstraintLocator::PathElement> path) {
373
481
auto summaryFlags = ConstraintLocator::getSummaryFlagsForPath(path);
0 commit comments