[CS] Diagnose UnresolvedPatternExprs as part of constraint solving

Instead of diagnosing in CSApply, let's create a
fix and diagnose in the solver instead.
Additionally, make sure we assign ErrorTypes to
any VarDecls bound by the invalid pattern, which
fixes a crash.

rdar://110638279
This commit is contained in:
Hamish Knight
2023-06-13 12:14:25 +01:00
parent 762cd4d10e
commit c6dd3ad839
10 changed files with 118 additions and 29 deletions

View File

@@ -8303,6 +8303,32 @@ bool InvalidEmptyKeyPathFailure::diagnoseAsError() {
return true;
}
bool InvalidPatternInExprFailure::diagnoseAsError() {
// Check to see if we have something like 'case <fn>(let foo)', where <fn>
// has a fix associated with it. In such a case, it's more likely than not
// that the user is trying to write an EnumElementPattern, but has made some
// kind of mistake in the function expr that causes it to be treated as an
// ExprPattern. Emitting an additional error for the out of place 'let foo' is
// just noise in that case, so let's avoid diagnosing.
llvm::SmallPtrSet<Expr *, 4> fixAnchors;
for (auto *fix : getSolution().Fixes) {
if (auto *anchor = getAsExpr(fix->getAnchor()))
fixAnchors.insert(anchor);
}
{
auto *E = castToExpr(getLocator()->getAnchor());
while (auto *parent = findParentExpr(E)) {
if (auto *CE = dyn_cast<CallExpr>(parent)) {
if (fixAnchors.contains(CE->getFn()))
return false;
}
E = parent;
}
}
emitDiagnostic(diag::pattern_in_expr, P->getDescriptiveKind());
return true;
}
bool MissingContextualTypeForNil::diagnoseAsError() {
auto *expr = castToExpr<NilLiteralExpr>(getAnchor());