Skip to content

[ConstraintSystem] Allow solving same-type requirements for associated types... #29520

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jan 29, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 15 additions & 10 deletions lib/Sema/CSSimplify.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3331,10 +3331,13 @@ bool ConstraintSystem::repairFailures(
if (lhs->hasHole() || rhs->hasHole())
return true;

// If dependent members are present here it's because
// base doesn't conform to associated type's protocol.
if (lhs->hasDependentMember() || rhs->hasDependentMember())
break;
// If dependent members are present here it's because the base doesn't
// conform to the associated type's protocol. We can only get here if we
// already applied a fix for the conformance failure.
if (lhs->hasDependentMember() || rhs->hasDependentMember()) {
increaseScore(SK_Fix);
return true;
}

// If requirement is something like `T == [Int]` let's let
// type matcher a chance to match generic parameters before
Expand Down Expand Up @@ -3949,12 +3952,14 @@ ConstraintSystem::matchTypes(Type type1, Type type2, ConstraintKind kind,
llvm_unreachable("type variables should have already been handled by now");

case TypeKind::DependentMember: {
// If one of the dependent member types has no type variables,
// this comparison is effectively illformed, because dependent
// member couldn't be simplified down to the actual type, and
// we wouldn't be able to solve this constraint, so let's just fail.
if (!desugar1->hasTypeVariable() || !desugar2->hasTypeVariable())
return getTypeMatchFailure(locator);
// If one of the dependent member types has no type variables, the
// dependent member can't be simplified because the base doesn't conform
// to the associated type's protocol. We can only get here if we already
// applied a fix for the conformance failure.
if (!desugar1->hasTypeVariable() || !desugar2->hasTypeVariable()) {
increaseScore(SK_Fix);
return getTypeMatchSuccess();
}

// Nothing we can solve yet, since we need to wait until
// type variables will get resolved.
Expand Down
22 changes: 22 additions & 0 deletions test/Constraints/same_types.swift
Original file line number Diff line number Diff line change
Expand Up @@ -333,3 +333,25 @@ class R<T>: P7 where T: P7, T.A == T.Type { // expected-note {{'T' declared as p

R.fn(args: R.self) // expected-error {{generic parameter 'T' could not be inferred}}
// expected-note@-1 {{explicitly specify the generic arguments to fix this issue}}

// rdar://problem/58607155
protocol AssocType1 { associatedtype A }
protocol AssocType2 { associatedtype A }

func rdar58607155() {
func f<T1: AssocType1, T2: AssocType2>(t1: T1, t2: T2) where T1.A == T2.A {}
// expected-note@-1 2 {{where 'T2' = 'MissingConformance'}}
// expected-note@-2 2 {{where 'T1' = 'MissingConformance'}}

class Conformance: AssocType1, AssocType2 { typealias A = Int }
class MissingConformance {}

// One generic argument has a conformance failure
f(t1: MissingConformance(), t2: Conformance()) // expected-error {{local function 'f(t1:t2:)' requires that 'MissingConformance' conform to 'AssocType1'}}
f(t1: Conformance(), t2: MissingConformance()) // expected-error {{local function 'f(t1:t2:)' requires that 'MissingConformance' conform to 'AssocType2'}}

// Both generic arguments have a conformance failure
f(t1: MissingConformance(), t2: MissingConformance())
// expected-error@-1 {{local function 'f(t1:t2:)' requires that 'MissingConformance' conform to 'AssocType1'}}
// expected-error@-2 {{local function 'f(t1:t2:)' requires that 'MissingConformance' conform to 'AssocType2'}}
}