Skip to content

Commit 24d8aa1

Browse files
authored
Merge pull request swiftlang#30185 from hborla/dependent-type-requirement-failure
[ConstraintSystem] Replace dependent member types with holes when the…
2 parents 12f8b51 + fce8738 commit 24d8aa1

File tree

5 files changed

+43
-25
lines changed

5 files changed

+43
-25
lines changed

lib/Sema/CSSimplify.cpp

Lines changed: 0 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -3560,14 +3560,6 @@ bool ConstraintSystem::repairFailures(
35603560
if (lhs->hasHole() || rhs->hasHole())
35613561
return true;
35623562

3563-
// If dependent members are present here it's because the base doesn't
3564-
// conform to the associated type's protocol. We can only get here if we
3565-
// already applied a fix for the conformance failure.
3566-
if (lhs->hasDependentMember() || rhs->hasDependentMember()) {
3567-
increaseScore(SK_Fix);
3568-
return true;
3569-
}
3570-
35713563
// If requirement is something like `T == [Int]` let's let
35723564
// type matcher a chance to match generic parameters before
35733565
// recording a fix, because then we'll know exactly how many
@@ -4195,15 +4187,6 @@ ConstraintSystem::matchTypes(Type type1, Type type2, ConstraintKind kind,
41954187
llvm_unreachable("type variables should have already been handled by now");
41964188

41974189
case TypeKind::DependentMember: {
4198-
// If one of the dependent member types has no type variables, the
4199-
// dependent member can't be simplified because the base doesn't conform
4200-
// to the associated type's protocol. We can only get here if we already
4201-
// applied a fix for the conformance failure.
4202-
if (!desugar1->hasTypeVariable() || !desugar2->hasTypeVariable()) {
4203-
increaseScore(SK_Fix);
4204-
return getTypeMatchSuccess();
4205-
}
4206-
42074190
// Nothing we can solve yet, since we need to wait until
42084191
// type variables will get resolved.
42094192
return formUnsolvedResult();

lib/Sema/ConstraintSystem.cpp

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2454,8 +2454,17 @@ Type ConstraintSystem::simplifyTypeImpl(Type type,
24542454
auto *proto = assocType->getProtocol();
24552455
auto conformance = DC->getParentModule()->lookupConformance(
24562456
lookupBaseType, proto);
2457-
if (!conformance)
2457+
if (!conformance) {
2458+
// If the base type doesn't conform to the associatedtype's protocol,
2459+
// there will be a missing conformance fix applied in diagnostic mode,
2460+
// so the concrete dependent member type is considered a "hole" in
2461+
// order to continue solving.
2462+
if (shouldAttemptFixes() &&
2463+
getPhase() == ConstraintSystemPhase::Solving)
2464+
return getASTContext().TheUnresolvedType;
2465+
24582466
return DependentMemberType::get(lookupBaseType, assocType);
2467+
}
24592468

24602469
auto subs = SubstitutionMap::getProtocolSubstitutions(
24612470
proto, lookupBaseType, conformance);
@@ -2895,22 +2904,24 @@ static bool diagnoseConflictingGenericArguments(ConstraintSystem &cs,
28952904
static bool
28962905
diagnoseAmbiguityWithEphemeralPointers(ConstraintSystem &cs,
28972906
ArrayRef<Solution> solutions) {
2898-
bool allSolutionsHaveFixes = true;
2907+
unsigned numSolutionsWithFixes = 0;
28992908
for (const auto &solution : solutions) {
29002909
if (solution.Fixes.empty()) {
2901-
allSolutionsHaveFixes = false;
29022910
continue;
29032911
}
29042912

29052913
if (!llvm::all_of(solution.Fixes, [](const ConstraintFix *fix) {
29062914
return fix->getKind() == FixKind::TreatEphemeralAsNonEphemeral;
29072915
}))
29082916
return false;
2917+
2918+
numSolutionsWithFixes += 1;
29092919
}
29102920

2911-
// If all solutions have fixes for ephemeral pointers, let's
2921+
// If all or no solutions have fixes for ephemeral pointers, let's
29122922
// let `diagnoseAmbiguityWithFixes` diagnose the problem.
2913-
if (allSolutionsHaveFixes)
2923+
if (numSolutionsWithFixes == 0 ||
2924+
numSolutionsWithFixes == solutions.size())
29142925
return false;
29152926

29162927
// If only some of the solutions have ephemeral pointer fixes
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
// RUN: %target-typecheck-verify-swift
2+
3+
protocol P {
4+
associatedtype V
5+
}
6+
7+
struct Person {
8+
var name: String = ""
9+
}
10+
11+
struct Row : P {
12+
typealias V = String
13+
init(_: V) {}
14+
}
15+
16+
func foo<C: Collection, R: P>(_ collection: C, _: (C.Element.V) -> R) where C.Element: P { }
17+
// expected-note@-1 {{where 'C.Element' = 'Person'}}
18+
19+
func bar(_ arr: [Person]) {
20+
foo(arr) { person in // expected-error {{global function 'foo' requires that 'Person' conform to 'P'}}
21+
Row(person.name)
22+
}
23+
}
24+

test/Generics/deduction.swift

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -243,11 +243,12 @@ genericInheritsA(C_GI())
243243
//===----------------------------------------------------------------------===//
244244
// Deduction for member operators
245245
//===----------------------------------------------------------------------===//
246-
protocol Addable { // expected-note {{where 'Self' = 'U'}}
246+
protocol Addable {
247247
static func +(x: Self, y: Self) -> Self
248248
}
249249
func addAddables<T : Addable, U>(_ x: T, y: T, u: U) -> T {
250-
u + u // expected-error{{referencing operator function '+' on 'Addable' requires that 'U' conform to 'Addable'}}
250+
// FIXME(diagnostics): This should report the "no exact matches" diagnostic.
251+
u + u // expected-error{{referencing operator function '+' on 'RangeReplaceableCollection' requires that 'U' conform to 'RangeReplaceableCollection'}}
251252
return x+y
252253
}
253254

validation-test/compiler_crashers_2_fixed/0119-rdar33613329.swift

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,4 +44,3 @@ var x = X()
4444
x ~> \X.y ≈> { a in a += 1; return 3 }
4545
// expected-error@-1 {{referencing operator function '~>' on 'P' requires that 'M<WritableKeyPath<X, Int>, R>' conform to 'P'}}
4646
// expected-error@-2 {{unable to infer complex closure return type; add explicit type to disambiguate}}
47-
// expected-error@-3 {{cannot convert value of type 'X' to expected argument type 'M<WritableKeyPath<X, Int>, R>.A'}}

0 commit comments

Comments
 (0)