Skip to content

Commit 60d52f0

Browse files
committed
[Typechecker] Fix fix-it loc when throwing function is called on a protocol typed value
1 parent f38ce6a commit 60d52f0

File tree

1 file changed

+21
-11
lines changed

1 file changed

+21
-11
lines changed

lib/Sema/TypeCheckError.cpp

Lines changed: 21 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -215,9 +215,13 @@ class ErrorHandlingWalker : public ASTWalker {
215215
} else if (auto optionalTryExpr = dyn_cast<OptionalTryExpr>(E)) {
216216
recurse = asImpl().checkOptionalTry(optionalTryExpr);
217217
} else if (auto apply = dyn_cast<ApplyExpr>(E)) {
218-
recurse = asImpl().checkApply(apply);
218+
recurse = asImpl().checkApply(apply, nullptr);
219219
} else if (auto interpolated = dyn_cast<InterpolatedStringLiteralExpr>(E)) {
220220
recurse = asImpl().checkInterpolatedStringLiteral(interpolated);
221+
} else if (auto openExistExpr = dyn_cast<OpenExistentialExpr>(E)) {
222+
if (auto applyExpr = dyn_cast<ApplyExpr>(openExistExpr->getSubExpr())) {
223+
recurse = asImpl().checkApply(applyExpr, openExistExpr);
224+
}
221225
}
222226
// Error handling validation (via checkTopLevelErrorHandling) happens after
223227
// type checking. If an unchecked expression is still around, the code was
@@ -594,7 +598,7 @@ class ApplyClassifier {
594598
ShouldRecurse_t checkOptionalTry(OptionalTryExpr *E) {
595599
return ShouldNotRecurse;
596600
}
597-
ShouldRecurse_t checkApply(ApplyExpr *E) {
601+
ShouldRecurse_t checkApply(ApplyExpr *E, Expr *BaseExpr) {
598602
Result = std::max(Result, Self.classifyApply(E).getResult());
599603
return ShouldRecurse;
600604
}
@@ -1016,7 +1020,7 @@ class Context {
10161020
llvm_unreachable("bad reason kind");
10171021
}
10181022

1019-
void diagnoseUncoveredThrowSite(TypeChecker &TC, ASTNode E,
1023+
void diagnoseUncoveredThrowSite(TypeChecker &TC, ASTNode E, Expr *BaseExpr,
10201024
const PotentialReason &reason) {
10211025
auto message = diag::throwing_call_without_try;
10221026
auto loc = E.getStartLoc();
@@ -1030,9 +1034,15 @@ class Context {
10301034
loc = e->getFn()->getStartLoc();
10311035
message = diag::throwing_operator_without_try;
10321036
}
1033-
insertLoc = loc;
1034-
highlight = e->getSourceRange();
1035-
1037+
1038+
if (auto OEE = dyn_cast_or_null<OpenExistentialExpr>(BaseExpr)) {
1039+
insertLoc = OEE->getExistentialValue()->getStartLoc();
1040+
highlight = e->getSourceRange();
1041+
} else {
1042+
insertLoc = loc;
1043+
highlight = e->getSourceRange();
1044+
}
1045+
10361046
if (InterpolatedString &&
10371047
e->getCalledValue() &&
10381048
e->getCalledValue()->getBaseName() ==
@@ -1444,12 +1454,12 @@ class CheckErrorCoverage : public ErrorHandlingWalker<CheckErrorCoverage> {
14441454
CurContext = savedContext;
14451455
}
14461456

1447-
ShouldRecurse_t checkApply(ApplyExpr *E) {
1457+
ShouldRecurse_t checkApply(ApplyExpr *E, Expr *BaseExpr) {
14481458
// An apply expression is a potential throw site if the function throws.
14491459
// But if the expression didn't type-check, suppress diagnostics.
14501460
auto classification = Classifier.classifyApply(E);
14511461

1452-
checkThrowSite(E, /*requiresTry*/ true, classification);
1462+
checkThrowSite(E, BaseExpr, /*requiresTry*/ true, classification);
14531463

14541464
// HACK: functions can get queued multiple times in
14551465
// definedFunctions, so be sure to be idempotent.
@@ -1510,12 +1520,12 @@ class CheckErrorCoverage : public ErrorHandlingWalker<CheckErrorCoverage> {
15101520
}
15111521

15121522
ShouldRecurse_t checkThrow(ThrowStmt *S) {
1513-
checkThrowSite(S, /*requiresTry*/ false,
1523+
checkThrowSite(S, nullptr, /*requiresTry*/ false,
15141524
Classification::forThrow(PotentialReason::forThrow()));
15151525
return ShouldRecurse;
15161526
}
15171527

1518-
void checkThrowSite(ASTNode E, bool requiresTry,
1528+
void checkThrowSite(ASTNode E, Expr *BaseExpr, bool requiresTry,
15191529
const Classification &classification) {
15201530
MaxThrowingKind = std::max(MaxThrowingKind, classification.getResult());
15211531

@@ -1551,7 +1561,7 @@ class CheckErrorCoverage : public ErrorHandlingWalker<CheckErrorCoverage> {
15511561
CurContext.diagnoseUnhandledThrowSite(TC, E, isTryCovered,
15521562
classification.getThrowsReason());
15531563
} else if (!isTryCovered) {
1554-
CurContext.diagnoseUncoveredThrowSite(TC, E,
1564+
CurContext.diagnoseUncoveredThrowSite(TC, E, BaseExpr,
15551565
classification.getThrowsReason());
15561566
}
15571567
return;

0 commit comments

Comments
 (0)