Skip to content

Commit 03fce0e

Browse files
committed
Moving toward a better model of inferred thrown error types
1 parent f461373 commit 03fce0e

File tree

2 files changed

+29
-10
lines changed

2 files changed

+29
-10
lines changed

lib/Sema/CSGen.cpp

+6-6
Original file line numberDiff line numberDiff line change
@@ -916,6 +916,9 @@ TypeVarRefCollector::walkToStmtPre(Stmt *stmt) {
916916
!Locator->directlyAt<ClosureExpr>()) {
917917
SmallPtrSet<TypeVariableType *, 4> typeVars;
918918
CS.getClosureType(CE)->getResult()->getTypeVariables(typeVars);
919+
920+
FIXME if we're doing full typed throws, also look at the thrown
921+
error type here?
919922
TypeVars.insert(typeVars.begin(), typeVars.end());
920923
}
921924
}
@@ -2470,12 +2473,9 @@ namespace {
24702473
// If we are inferring thrown error types, create a type variable
24712474
// to capture the thrown error type. This will be resolved based on the
24722475
// throw sites that occur within the body of the closure.
2473-
// FIXME: Single-expression closures don't yet work.
2474-
if (CS.getASTContext().LangOpts.hasFeature(Feature::FullTypedThrows) &&
2475-
!CS.getAppliedResultBuilderTransform(closure) &&
2476-
!closure->hasSingleExpressionBody()) {
2477-
return Type(
2478-
CS.createTypeVariable(thrownErrorLocator, TVO_CanBindToHole));
2476+
if (CS.getASTContext().LangOpts.hasFeature(
2477+
Feature::FullTypedThrows)) {
2478+
return Type(CS.createTypeVariable(thrownErrorLocator, 0));
24792479
}
24802480

24812481
// Thrown type inferred from context.

lib/Sema/CSSyntacticElement.cpp

+23-4
Original file line numberDiff line numberDiff line change
@@ -287,6 +287,23 @@ static bool isViableElement(ASTNode element,
287287
using ElementInfo = std::tuple<ASTNode, ContextualTypeInfo,
288288
/*isDiscarded=*/bool, ConstraintLocator *>;
289289

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+
290307
static void createConjunction(ConstraintSystem &cs, DeclContext *dc,
291308
ArrayRef<ElementInfo> elements,
292309
ConstraintLocator *locator, bool isIsolated,
@@ -370,14 +387,16 @@ static void createConjunction(ConstraintSystem &cs, DeclContext *dc,
370387
for (auto *externalVar : paramCollector.getTypeVars())
371388
referencedVars.push_back(externalVar);
372389

390+
#if false
373391
// If the body of the closure is being used to infer the thrown error type
374392
// of that closure, introduce a constraint to do so.
375393
if (locator->directlyAt<ClosureExpr>()) {
376394
auto *closure = castToExpr<ClosureExpr>(locator->getAnchor());
377-
if (auto thrownErrorTypeVar = cs.getInferredThrownError(closure))
395+
if (auto thrownErrorTypeVar = assignClosureThrownErrorType(cs, closure))
378396
referencedVars.push_back(thrownErrorTypeVar);
379397
}
380-
398+
#endif
399+
381400
// It's possible that there are no viable elements in the body,
382401
// because e.g. whole body is an `#if` statement or it only has
383402
// declarations that are checked during solution application.
@@ -1137,9 +1156,9 @@ class SyntacticElementConstraintGenerator
11371156
}
11381157

11391158
if (closure) {
1140-
auto closureType = cs.getClosureType(closure);
1159+
assignClosureThrownErrorType(cs, closure);
11411160
}
1142-
1161+
11431162
return;
11441163
}
11451164

0 commit comments

Comments
 (0)