File tree Expand file tree Collapse file tree 2 files changed +53
-3
lines changed Expand file tree Collapse file tree 2 files changed +53
-3
lines changed Original file line number Diff line number Diff line change @@ -2172,10 +2172,43 @@ static Type getOptionalSuperclass(Type type) {
21722172 type = underlying;
21732173 }
21742174
2175- if (!type->mayHaveSuperclass ())
2176- return Type ();
2175+ Type superclass;
2176+ if (auto *existential = type->getAs <ExistentialType>()) {
2177+ auto constraintTy = existential->getConstraintType ();
2178+ if (auto *compositionTy = constraintTy->getAs <ProtocolCompositionType>()) {
2179+ SmallVector<Type, 2 > members;
2180+ bool found = false ;
2181+ // Preserve all of the protocol requirements of the type i.e.
2182+ // if the type was `any B & P` where `B : A` the supertype is
2183+ // going to be `any A & P`.
2184+ //
2185+ // This is especially important for Sendable key paths because
2186+ // to reserve sendability of the original type.
2187+ for (auto member : compositionTy->getMembers ()) {
2188+ if (member->getClassOrBoundGenericClass ()) {
2189+ member = member->getSuperclass ();
2190+ if (!member)
2191+ return Type ();
2192+ found = true ;
2193+ }
2194+ members.push_back (member);
2195+ }
2196+
2197+ if (!found)
2198+ return Type ();
2199+
2200+ superclass = ExistentialType::get (
2201+ ProtocolCompositionType::get (type->getASTContext (), members,
2202+ compositionTy->hasExplicitAnyObject ()));
2203+ } else {
2204+ // Avoid producing superclass for situations like `any P` where `P` is
2205+ // `protocol P : C`.
2206+ return Type ();
2207+ }
2208+ } else {
2209+ superclass = type->getSuperclass ();
2210+ }
21772211
2178- auto superclass = type->getSuperclass ();
21792212 if (!superclass)
21802213 return Type ();
21812214
Original file line number Diff line number Diff line change @@ -200,3 +200,20 @@ func testReferencesToDifferentGlobalActorIsolatedMembers() {
200200 // expected-warning@-1 {{cannot form key path to main actor-isolated property 'name'; this is an error in Swift 6}}
201201 }
202202}
203+
204+ do {
205+ struct S {
206+ var a : Int
207+ var b : String ?
208+ }
209+
210+ func test< T: Sendable > ( _: T ) { }
211+
212+ let kp = [ \S . a, \S . b]
213+
214+ test ( kp) // Ok
215+ test ( [ \S . a, \S . b] ) // Ok
216+
217+ let _: [ PartialKeyPath < S > ] = [ \. a, \. b] // Ok
218+ let _: [ any PartialKeyPath < S > & Sendable ] = [ \. a, \. b] // Ok
219+ }
You can’t perform that action at this time.
0 commit comments