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) {
2172
2172
type = underlying;
2173
2173
}
2174
2174
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
+ }
2177
2211
2178
- auto superclass = type->getSuperclass ();
2179
2212
if (!superclass)
2180
2213
return Type ();
2181
2214
Original file line number Diff line number Diff line change @@ -200,3 +200,20 @@ func testReferencesToDifferentGlobalActorIsolatedMembers() {
200
200
// expected-warning@-1 {{cannot form key path to main actor-isolated property 'name'; this is an error in Swift 6}}
201
201
}
202
202
}
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