Skip to content

Commit

Permalink
Improve diagnosis of implicit match expressions
Browse files Browse the repository at this point in the history
When diagnosing failure to typecheck a binary '~=' expression that was
synthesized when typechecking an expression pattern, offer a message
that describes the failure more helpfully.

<rdar://problem/21995744> QoI: Binary operator '~=' cannot be applied to operands of type 'String' and 'String?'

Swift SVN r31286
  • Loading branch information
cwillmor committed Aug 18, 2015
1 parent b74557e commit 8c57b7c
Show file tree
Hide file tree
Showing 4 changed files with 20 additions and 1 deletion.
4 changes: 4 additions & 0 deletions include/swift/AST/DiagnosticsSema.def
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,10 @@ ERROR(comparison_with_nil_illegal,sema,none,
"value of type %0 can never be nil, comparison isn't allowed",
(Type))

ERROR(cannot_match_expr_pattern_with_value,sema,none,
"expression pattern of type %0 cannot match values of type %1",
(Type, Type))

ERROR(cannot_apply_binop_to_args,sema,none,
"binary operator '%0' cannot be applied to operands of type "
"%1 and %2",
Expand Down
9 changes: 9 additions & 0 deletions lib/Sema/CSDiag.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3300,6 +3300,15 @@ bool FailureDiagnosis::visitBinaryExpr(BinaryExpr *binop) {
auto lhsType = lhsExpr->getType()->getRValueType();
auto rhsType = rhsExpr->getType()->getRValueType();

if (binop->isImplicit() && overloadName == "~=") {
// This binop was synthesized when typechecking an expression pattern.
diagnose(lhsExpr->getLoc(),
diag::cannot_match_expr_pattern_with_value, lhsType, rhsType)
.highlight(lhsExpr->getSourceRange())
.highlight(rhsExpr->getSourceRange());
return true;
}

// If this is a comparison against nil, then we should produce a specific
// diagnostic.
if (isa<NilLiteralExpr>(rhsExpr->getValueProvidingExpr()) &&
Expand Down
6 changes: 6 additions & 0 deletions test/Constraints/patterns.swift
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,12 @@ case nil?: break
default: break
}

// <rdar://problem/21995744> QoI: Binary operator '~=' cannot be applied to operands of type 'String' and 'String?'
switch ("foo" as String?) {
case "what": break // expected-error{{expression pattern of type 'String' cannot match values of type 'String?'}}
default: break
}


// Test some value patterns.
let x : Int? = nil
Expand Down
2 changes: 1 addition & 1 deletion test/Misc/misc_diagnostics.swift
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,6 @@ func test17875634() {

// <rdar://problem/20770032> Pattern matching ranges against tuples crashes the compiler
func test20770032() {
if case let 1...10 = (1, 1) { // expected-warning{{'let' pattern has no effect; sub-pattern didn't bind any variables}} {{11-15=}} expected-error{{binary operator '~=' cannot be applied to operands of type 'Range<Int>' and '(Int, Int)'}}
if case let 1...10 = (1, 1) { // expected-warning{{'let' pattern has no effect; sub-pattern didn't bind any variables}} {{11-15=}} expected-error{{expression pattern of type 'Range<Int>' cannot match values of type '(Int, Int)'}}
}
}

0 comments on commit 8c57b7c

Please sign in to comment.