Skip to content

Commit 815699d

Browse files
committed
[Diagnostics] Produce a diagnostic for existential mismatch in same-type constraint
Previously this would result in a fallback diagnostic because type mismatches associated with `ExistentialConstraintType` locations weren't handled at all.
1 parent d151118 commit 815699d

File tree

3 files changed

+34
-0
lines changed

3 files changed

+34
-0
lines changed

lib/Sema/CSSimplify.cpp

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6203,6 +6203,24 @@ bool ConstraintSystem::repairFailures(
62036203
break;
62046204
}
62056205

6206+
case ConstraintLocator::ExistentialConstraintType: {
6207+
if (lhs->hasPlaceholder() || rhs->hasPlaceholder())
6208+
return true;
6209+
6210+
// If there are any restrictions/conversions left to attempt, wait.
6211+
if (hasAnyRestriction())
6212+
break;
6213+
6214+
// Drop the element introduced by DeepEquality matcher.
6215+
path.pop_back();
6216+
6217+
// Presence of DeepEquality conversion delayed repair but since the
6218+
// constraint types didn't match easier, let's retry it.
6219+
return repairFailures(ExistentialType::get(lhs), ExistentialType::get(rhs),
6220+
matchKind, flags, conversionsOrFixes,
6221+
getConstraintLocator(anchor, path));
6222+
}
6223+
62066224
case ConstraintLocator::ClosureBody:
62076225
case ConstraintLocator::ClosureResult: {
62086226
if (repairByInsertingExplicitCall(lhs, rhs))

test/Constraints/generics.swift

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1057,3 +1057,18 @@ func test_mismatches_with_dependent_member_generic_arguments() {
10571057
// expected-error@-1 {{cannot convert value of type 'Optional<Int>' to expected argument type 'Optional<Data.SomeAssociated>'}}
10581058
// expected-note@-2 {{arguments to generic parameter 'Wrapped' ('Int' and 'Data.SomeAssociated') are expected to be equal}}
10591059
}
1060+
1061+
extension Dictionary where Value == Any { // expected-note {{where 'Value' = 'any P'}}
1062+
func compute() {}
1063+
}
1064+
1065+
do {
1066+
struct S {
1067+
var test: [String: any P] = [:]
1068+
}
1069+
1070+
func test_existential_mismatch(s: S) {
1071+
s.test.compute()
1072+
// expected-error@-1 {{referencing instance method 'compute()' on 'Dictionary' requires the types 'any P' and 'Any' be equivalent}}
1073+
}
1074+
}

test/Constraints/parameterized_existentials.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ func g3(x: G<any P<Int>>) -> G<any P<String>> {
3737

3838
func h1(x: (any P)?) -> (any P<Int>)? {
3939
return x // expected-error {{cannot convert return expression of type '(any P)?' to return type '(any P<Int>)?'}}
40+
// expected-note@-1 {{arguments to generic parameter 'Wrapped' ('any P' and 'any P<Int>') are expected to be equal}}
4041
}
4142

4243
func h2(x: (any P<Int>)?) -> (any P)? {

0 commit comments

Comments
 (0)