Skip to content

Commit d6d8d08

Browse files
committed
[CS] Better diagnose conformance failures for EnumElementPatterns
Previously we could end up with a ContextualMismatch fix and a MissingConformance fix for different elements of the `matchTypes` disjunction, leading to an ambiguity. Instead, avoid recording the ContextualMismatch if we're matching an existential, and tweak the MissingConformance failure to have a custom diagnostic for EnumElementPattern matching.
1 parent cd1b6ed commit d6d8d08

File tree

5 files changed

+30
-1
lines changed

5 files changed

+30
-1
lines changed

include/swift/AST/DiagnosticsSema.def

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -208,6 +208,9 @@ ERROR(cannot_match_unresolved_expr_pattern_with_value,none,
208208
ERROR(cannot_match_value_with_pattern,none,
209209
"pattern of type %1 cannot match %0",
210210
(Type, Type))
211+
ERROR(pattern_does_not_conform_to_match,none,
212+
"pattern of type %0 does not conform to expected match type %1",
213+
(Type, Type))
211214

212215
ERROR(cannot_reference_compare_types,none,
213216
"cannot check reference equality of functions; operands here have types "

lib/Sema/CSDiagnostics.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6505,6 +6505,13 @@ bool MissingContextualConformanceFailure::diagnoseAsError() {
65056505
break;
65066506
}
65076507

6508+
case ConstraintLocator::EnumPatternImplicitCastMatch: {
6509+
emitDiagnostic(diag::pattern_does_not_conform_to_match, getFromType(),
6510+
getToType())
6511+
.highlight(getSourceRange());
6512+
return true;
6513+
}
6514+
65086515
default:
65096516
break;
65106517
}

lib/Sema/CSSimplify.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6667,6 +6667,11 @@ bool ConstraintSystem::repairFailures(
66676667
if (lhs->isPlaceholder() || rhs->isPlaceholder())
66686668
return true;
66696669

6670+
// If we're converting to an existential, we'll diagnose failures in
6671+
// the conformance constraint.
6672+
if (hasConversionOrRestriction(ConversionRestrictionKind::Existential))
6673+
return false;
6674+
66706675
conversionsOrFixes.push_back(ContextualMismatch::create(
66716676
*this, lhs, rhs, getConstraintLocator(locator)));
66726677
break;

test/Constraints/patterns.swift

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -791,3 +791,17 @@ do {
791791
}
792792
}
793793
}
794+
795+
func testMatchingNonErrorConformingTypeInClosure(_ x: any Error) {
796+
enum E {
797+
case e
798+
}
799+
_ = {
800+
switch x {
801+
case E.e: // expected-error {{pattern of type 'E' does not conform to expected match type 'Error'}}
802+
break
803+
default:
804+
break
805+
}
806+
}
807+
}

test/stmt/errors.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -156,7 +156,7 @@ func twelve() {
156156
twelve_helper { (a, b) in // expected-error {{invalid conversion from throwing function of type '(Int, Int) throws -> ()' to non-throwing function type '(Int, Int) -> ()'}}
157157
do {
158158
try thrower()
159-
} catch Twelve.Payload(a...b) {
159+
} catch Twelve.Payload(a...b) { // expected-error {{pattern of type 'Twelve' does not conform to expected match type 'Error'}}
160160
}
161161
}
162162
}

0 commit comments

Comments
 (0)