Skip to content

Commit a796c45

Browse files
committed
[CSSimplify] Diagnose contextual mismatch between fully resolved dependent member types
If a constraint has fully resolved but incorrect (not simplifiable) dependent member types, let's diagnose that as a contextual mismatch instead of failing (which sometimes leads to a fallback diagnostic). Resolves: rdar://101412179
1 parent 49405aa commit a796c45

File tree

2 files changed

+30
-0
lines changed

2 files changed

+30
-0
lines changed

lib/Sema/CSSimplify.cpp

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6343,6 +6343,23 @@ ConstraintSystem::matchTypes(Type type1, Type type2, ConstraintKind kind,
63436343
if (desugar1->isEqual(desugar2))
63446344
return getTypeMatchSuccess();
63456345

6346+
if (shouldAttemptFixes()) {
6347+
if (!desugar1->hasTypeVariable() && !desugar2->hasTypeVariable()) {
6348+
auto *loc = getConstraintLocator(locator);
6349+
6350+
auto *fix =
6351+
loc->isLastElement<LocatorPathElt::TypeParameterRequirement>()
6352+
? fixRequirementFailure(*this, type1, type2, loc->getAnchor(),
6353+
loc->getPath())
6354+
: ContextualMismatch::create(*this, type1, type2, loc);
6355+
6356+
if (!fix || recordFix(fix))
6357+
return getTypeMatchFailure(locator);
6358+
6359+
return getTypeMatchSuccess();
6360+
}
6361+
}
6362+
63466363
// If one of the dependent member types has no type variables,
63476364
// this comparison is effectively illformed, because dependent
63486365
// member couldn't be simplified down to the actual type, and

test/Constraints/generics.swift

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -983,3 +983,16 @@ func testOverloadGenericVarFn() {
983983
S<((String) -> Void)?>().foo?("")
984984
S<((String) -> Void)?>().foo!("")
985985
}
986+
987+
do {
988+
func foo<T, U>(_: T, _: U) where T: Sequence, U: Sequence, T.Element == U.Element {}
989+
// expected-note@-1 {{required by local function 'foo' where 'T' = 'Set<Int>.Type'}}
990+
// expected-note@-2 {{required by local function 'foo' where 'U' = 'Array<String>.Type'}}
991+
// expected-note@-3 {{where 'T.Element' = 'Set<Int>.Type.Element', 'U.Element' = 'Array<String>.Type.Element'}}
992+
993+
foo(Set<Int>, Array<String>)
994+
// expected-error@-1 {{type 'Set<Int>.Type' cannot conform to 'Sequence'}}
995+
// expected-error@-2 {{type 'Array<String>.Type' cannot conform to 'Sequence'}}
996+
// expected-error@-3 {{local function 'foo' requires the types 'Set<Int>.Type.Element' and 'Array<String>.Type.Element' be equivalent}}
997+
// expected-note@-4 2 {{only concrete types such as structs, enums and classes can conform to protocols}}
998+
}

0 commit comments

Comments
 (0)