Skip to content

Commit 60bf038

Browse files
authored
Merge pull request #75629 from xedin/rdar-132700409-6.0
[6.0][CSApply] Allow marker existential to superclass conversions
2 parents e570e35 + eeffdef commit 60bf038

File tree

2 files changed

+44
-0
lines changed

2 files changed

+44
-0
lines changed

lib/Sema/CSApply.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7763,6 +7763,20 @@ Expr *ExprRewriter::coerceToType(Expr *expr, Type toType,
77637763
llvm_unreachable("BuiltinTupleType should not show up here");
77647764
}
77657765

7766+
// Allow existential-to-supertype conversion if all protocol
7767+
// bounds are marker protocols. Normally this requires a
7768+
// conversion restriction but there are situations related
7769+
// to `@preconcurrency` where the `& Sendable` would be stripped
7770+
// transparently to the solver.
7771+
if (auto *existential = fromType->getAs<ExistentialType>()) {
7772+
if (auto *PCT = existential->getConstraintType()
7773+
->getAs<ProtocolCompositionType>()) {
7774+
if (PCT->withoutMarkerProtocols()->isEqual(toType)) {
7775+
return coerceSuperclass(expr, toType);
7776+
}
7777+
}
7778+
}
7779+
77667780
// Unresolved types come up in diagnostics for lvalue and inout types.
77677781
if (fromType->hasUnresolvedType() || toType->hasUnresolvedType())
77687782
return cs.cacheType(new (ctx) UnresolvedTypeConversionExpr(expr, toType));

test/Concurrency/predates_concurrency.swift

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -302,3 +302,33 @@ do {
302302
}
303303
}
304304
}
305+
306+
// rdar://132700409 - coercion PartialKeyPath & Sendable -> PartialKeyPath crashes in CSApply
307+
do {
308+
struct Test {
309+
enum KeyPath {
310+
static var member: PartialKeyPath<Test> {
311+
fatalError()
312+
}
313+
}
314+
}
315+
316+
struct KeyPathComparator<Compared> {
317+
@preconcurrency public let keyPath: any PartialKeyPath<Compared> & Sendable
318+
319+
func testDirect() {
320+
switch keyPath { // Ok
321+
case Test.KeyPath.member: break // Ok
322+
default: break
323+
}
324+
}
325+
326+
func testErasure() {
327+
let kp: PartialKeyPath<Compared> = keyPath
328+
switch kp { // Ok
329+
case Test.KeyPath.member: break // Ok
330+
default: break
331+
}
332+
}
333+
}
334+
}

0 commit comments

Comments
 (0)