Skip to content

Commit af847c2

Browse files
authored
Merge pull request #29415 from hborla/ambiguity-special-cases
[CSDiag] Start chipping away at FailureDiagnosis::diagnoseAmbiguity
2 parents 78d7243 + 689a57b commit af847c2

File tree

5 files changed

+5
-104
lines changed

5 files changed

+5
-104
lines changed

lib/Sema/CSDiag.cpp

-99
Original file line numberDiff line numberDiff line change
@@ -1447,29 +1447,6 @@ bool FailureDiagnosis::visitApplyExpr(ApplyExpr *callExpr) {
14471447
auto lhsType = CS.getType(lhsExpr)->getRValueType();
14481448
auto rhsType = CS.getType(rhsExpr)->getRValueType();
14491449

1450-
// TODO(diagnostics): There are still cases not yet handled by new
1451-
// diagnostics framework e.g.
1452-
//
1453-
// var tuple = (1, 2, 3)
1454-
// switch tuple {
1455-
// case (let (_, _, _)) + 1: break
1456-
// }
1457-
if (callExpr->isImplicit() && overloadName == "~=") {
1458-
auto flags = ParameterTypeFlags();
1459-
if (calleeInfo.candidates.size() == 1)
1460-
if (auto fnType = calleeInfo.candidates[0].getFunctionType())
1461-
flags = fnType->getParams()[0].getParameterFlags();
1462-
1463-
auto *locator = CS.getConstraintLocator(
1464-
callExpr,
1465-
{ConstraintLocator::ApplyArgument,
1466-
LocatorPathElt::ApplyArgToParam(0, 0, flags)},
1467-
/*summaryFlags=*/0);
1468-
1469-
ArgumentMismatchFailure failure(CS, lhsType, rhsType, locator);
1470-
return failure.diagnosePatternMatchingMismatch();
1471-
}
1472-
14731450
if (isContextualConversionFailure(argTuple))
14741451
return false;
14751452

@@ -1517,41 +1494,6 @@ bool FailureDiagnosis::visitApplyExpr(ApplyExpr *callExpr) {
15171494
AnyFunctionType::decomposeInput(CS.getType(argExpr), params);
15181495
auto argString = AnyFunctionType::getParamListAsString(params);
15191496

1520-
// If we couldn't get the name of the callee, then it must be something of a
1521-
// more complex "value of function type".
1522-
if (overloadName.empty()) {
1523-
// If we couldn't infer the result type of the closure expr, then we have
1524-
// some sort of ambiguity, let the ambiguity diagnostic stuff handle this.
1525-
if (auto ffty = fnType->getAs<AnyFunctionType>())
1526-
if (ffty->getResult()->hasTypeVariable()) {
1527-
diagnoseAmbiguity(fnExpr);
1528-
return true;
1529-
}
1530-
1531-
// The most common unnamed value of closure type is a ClosureExpr, so
1532-
// special case it.
1533-
if (isa<ClosureExpr>(fnExpr->getValueProvidingExpr())) {
1534-
if (fnType->hasTypeVariable())
1535-
diagnose(argExpr->getStartLoc(), diag::cannot_invoke_closure, argString)
1536-
.highlight(fnExpr->getSourceRange());
1537-
else
1538-
diagnose(argExpr->getStartLoc(), diag::cannot_invoke_closure_type,
1539-
fnType, argString)
1540-
.highlight(fnExpr->getSourceRange());
1541-
1542-
} else if (fnType->hasTypeVariable()) {
1543-
diagnose(argExpr->getStartLoc(), diag::cannot_call_function_value,
1544-
argString)
1545-
.highlight(fnExpr->getSourceRange());
1546-
} else {
1547-
diagnose(argExpr->getStartLoc(), diag::cannot_call_value_of_function_type,
1548-
fnType, argString)
1549-
.highlight(fnExpr->getSourceRange());
1550-
}
1551-
1552-
return true;
1553-
}
1554-
15551497
if (auto MTT = fnType->getAs<MetatypeType>()) {
15561498
if (MTT->getInstanceType()->isExistentialType()) {
15571499
diagnose(fnExpr->getLoc(), diag::construct_protocol_value, fnType);
@@ -1756,22 +1698,6 @@ void FailureDiagnosis::diagnoseAmbiguity(Expr *E) {
17561698
if (auto *assignment = dyn_cast<AssignExpr>(E)) {
17571699
if (isa<DiscardAssignmentExpr>(assignment->getDest())) {
17581700
auto *srcExpr = assignment->getSrc();
1759-
1760-
bool diagnosedInvalidUseOfDiscardExpr = false;
1761-
srcExpr->forEachChildExpr([&](Expr *expr) -> Expr * {
1762-
if (auto *DAE = dyn_cast<DiscardAssignmentExpr>(expr)) {
1763-
diagnose(DAE->getLoc(), diag::discard_expr_outside_of_assignment)
1764-
.highlight(srcExpr->getSourceRange());
1765-
diagnosedInvalidUseOfDiscardExpr = true;
1766-
return nullptr;
1767-
}
1768-
1769-
return expr;
1770-
});
1771-
1772-
if (diagnosedInvalidUseOfDiscardExpr)
1773-
return;
1774-
17751701
diagnoseAmbiguity(srcExpr);
17761702
return;
17771703
}
@@ -1785,15 +1711,6 @@ void FailureDiagnosis::diagnoseAmbiguity(Expr *E) {
17851711
return;
17861712
}
17871713

1788-
// A DiscardAssignmentExpr (spelled "_") needs contextual type information to
1789-
// infer its type. If we see one at top level, diagnose that it must be part
1790-
// of an assignment so we don't get a generic "expression is ambiguous" error.
1791-
if (isa<DiscardAssignmentExpr>(E)) {
1792-
diagnose(E->getLoc(), diag::discard_expr_outside_of_assignment)
1793-
.highlight(E->getSourceRange());
1794-
return;
1795-
}
1796-
17971714
// Diagnose ".foo" expressions that lack context specifically.
17981715
if (auto UME =
17991716
dyn_cast<UnresolvedMemberExpr>(E->getSemanticsProvidingExpr())) {
@@ -1805,22 +1722,6 @@ void FailureDiagnosis::diagnoseAmbiguity(Expr *E) {
18051722
}
18061723
}
18071724

1808-
// Diagnose empty collection literals that lack context specifically.
1809-
if (auto CE = dyn_cast<CollectionExpr>(E->getSemanticsProvidingExpr())) {
1810-
if (CE->getNumElements() == 0) {
1811-
diagnose(E->getLoc(), diag::unresolved_collection_literal)
1812-
.highlight(E->getSourceRange());
1813-
return;
1814-
}
1815-
}
1816-
1817-
// Diagnose 'nil' without a contextual type.
1818-
if (isa<NilLiteralExpr>(E->getSemanticsProvidingExpr())) {
1819-
diagnose(E->getLoc(), diag::unresolved_nil_literal)
1820-
.highlight(E->getSourceRange());
1821-
return;
1822-
}
1823-
18241725
// Attempt to re-type-check the entire expression, allowing ambiguity, but
18251726
// ignoring a contextual type.
18261727
if (expr == E) {

lib/Sema/CSGen.cpp

+2-1
Original file line numberDiff line numberDiff line change
@@ -2827,7 +2827,8 @@ namespace {
28272827

28282828
Type visitDiscardAssignmentExpr(DiscardAssignmentExpr *expr) {
28292829
auto locator = CS.getConstraintLocator(expr);
2830-
auto typeVar = CS.createTypeVariable(locator, TVO_CanBindToNoEscape);
2830+
auto typeVar = CS.createTypeVariable(locator, TVO_CanBindToNoEscape |
2831+
TVO_CanBindToHole);
28312832
return LValueType::get(typeVar);
28322833
}
28332834

test/Constraints/diagnostics.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -1271,7 +1271,7 @@ func badTypes() {
12711271
// rdar://34357545
12721272
func unresolvedTypeExistential() -> Bool {
12731273
return (Int.self==_{})
1274-
// expected-error@-1 {{expression type 'Bool' is ambiguous without more context}}
1274+
// expected-error@-1 {{'_' can only appear in a pattern or on the left side of an assignment}}
12751275
}
12761276

12771277
func rdar43525641(_ a: Int, _ b: Int = 0, c: Int = 0, _ d: Int) {}

test/Parse/matching_patterns.swift

+1-2
Original file line numberDiff line numberDiff line change
@@ -288,8 +288,7 @@ case (_, var e, 3) +++ (1, 2, 3):
288288
// expected-error@-2{{'var' binding pattern cannot appear in an expression}}
289289
()
290290
case (let (_, _, _)) + 1:
291-
// expected-error@-1 2 {{'var' binding pattern cannot appear in an expression}}
292-
// expected-error@-2 {{expression pattern of type 'Int' cannot match values of type '(Int, Int, Int)'}}
291+
// expected-error@-1 {{expression pattern of type 'Int' cannot match values of type '(Int, Int, Int)'}}
293292
()
294293
}
295294

test/expr/expressions.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -708,7 +708,7 @@ func test() {
708708
func unusedExpressionResults() {
709709
// Unused l-value
710710
_ // expected-error{{'_' can only appear in a pattern or on the left side of an assignment}}
711-
711+
// expected-error@-1 {{expression resolves to an unused variable}}
712712

713713
// <rdar://problem/20749592> Conditional Optional binding hides compiler error
714714
let optionalc:C? = nil

0 commit comments

Comments
 (0)