Skip to content

Commit 17b8287

Browse files
committed
[CSFix] Bound Generic Class Types require explicit coercion due to loss of generic parameters
1 parent bdd6bfd commit 17b8287

File tree

2 files changed

+48
-0
lines changed

2 files changed

+48
-0
lines changed

lib/Sema/CSFix.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2506,6 +2506,14 @@ bool AddExplicitExistentialCoercion::isRequired(
25062506
RequiresCoercion = true;
25072507
return Action::Stop;
25082508
}
2509+
2510+
if (auto *const nominal = erasedMemberTy->getAs<NominalOrBoundGenericNominalType>()) {
2511+
// Bound Generic Nominals
2512+
if (!hasConstrainedAssociatedTypes(member, *existentialType)) {
2513+
RequiresCoercion = true;
2514+
return Action::Stop;
2515+
}
2516+
}
25092517

25102518
return Action::SkipChildren;
25112519
}
@@ -2554,6 +2562,7 @@ bool AddExplicitExistentialCoercion::isRequired(
25542562
case RequirementKind::Layout: {
25552563
if (isAnchoredOn(req.getFirstType(), member->getAssocType()))
25562564
return true;
2565+
25572566
break;
25582567
}
25592568

test/Constraints/opened_existentials.swift

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -305,3 +305,42 @@ func testExplicitCoercionRequirement(v: any B, otherV: any B & D) {
305305
getP((getC(v) as any P)) // Ok - parens avoid opening suppression
306306
getP((v.getC() as any P)) // Ok - parens avoid opening suppression
307307
}
308+
309+
// Generic Class Types
310+
class C1 {}
311+
class C2<T>: C1 {}
312+
313+
// Protocols With Associated Types
314+
protocol Q {
315+
associatedtype A
316+
associatedtype B: C2<A>
317+
318+
func returnAssocTypeB() -> B
319+
}
320+
321+
func testAssocReturn(p: any Q) {
322+
let _ = p.returnAssocTypeB() // expected-error {{inferred result type 'C2<(any U<String>).A>' requires explicit coercion due to loss of generic requirements}} {{14-14=as as C2<(any Q).A>}}
323+
}
324+
325+
// Protocols With Primary Associated Types
326+
protocol U<A> {
327+
associatedtype A
328+
associatedtype B: C2<A>
329+
330+
func returnAssocTypeB() -> B
331+
func returnPrimaryAssocTypeA() -> A
332+
func returnAssocTypeCollection() -> any Collection<A>
333+
}
334+
335+
func testPrimaryAssocReturn(p: any U<String>) {
336+
let _ = p.returnAssocTypeB()
337+
}
338+
339+
func testPrimaryAssocReturn(p: any U<Int>) {
340+
let _ = p.returnPrimaryAssocTypeA() // what would the output even be here?
341+
}
342+
343+
func testPrimaryAssocCollection(p: any U<Float>) -> any Collection {
344+
let x = p.returnAssocTypeCollection()
345+
return x
346+
}

0 commit comments

Comments
 (0)