Skip to content

Commit d49445b

Browse files
authored
Merge pull request #70502 from xedin/subtype-between-sendable-and-non-sendable
[TypeChecker] `TypeChecker::isSubtypeOf` should recognize Sendable s…
2 parents 0b0959a + 359ea14 commit d49445b

File tree

3 files changed

+44
-1
lines changed

3 files changed

+44
-1
lines changed

lib/Sema/TypeCheckConstraints.cpp

+15-1
Original file line numberDiff line numberDiff line change
@@ -1068,8 +1068,22 @@ bool TypeChecker::typesSatisfyConstraint(Type type1, Type type2,
10681068
}
10691069

10701070
if (auto solution = cs.solveSingle()) {
1071+
const auto &score = solution->getFixedScore();
10711072
if (unwrappedIUO)
1072-
*unwrappedIUO = solution->getFixedScore().Data[SK_ForceUnchecked] > 0;
1073+
*unwrappedIUO = score.Data[SK_ForceUnchecked] > 0;
1074+
1075+
// Make sure that Sendable vs. no-Sendable mismatches are
1076+
// failures here to establish subtyping relationship
1077+
// (unlike in the solver where they are warnings until Swift 6).
1078+
if (kind == ConstraintKind::Subtype) {
1079+
if (score.Data[SK_MissingSynthesizableConformance] > 0)
1080+
return false;
1081+
1082+
if (llvm::any_of(solution->Fixes, [](const auto *fix) {
1083+
return fix->getKind() == FixKind::AddSendableAttribute;
1084+
}))
1085+
return false;
1086+
}
10731087

10741088
return true;
10751089
}

test/Concurrency/sendable_keypaths.swift

+13
Original file line numberDiff line numberDiff line change
@@ -217,3 +217,16 @@ do {
217217
let _: [PartialKeyPath<S>] = [\.a, \.b] // Ok
218218
let _: [any PartialKeyPath<S> & Sendable] = [\.a, \.b] // Ok
219219
}
220+
221+
do {
222+
func kp() -> KeyPath<String, Int> & Sendable {
223+
fatalError()
224+
}
225+
226+
func test() -> KeyPath<String, Int> {
227+
true ? kp() : kp() // Ok
228+
}
229+
230+
func forward<T>(_ v: T) -> T { v }
231+
let _: KeyPath<String, Int> = forward(kp()) // Ok
232+
}

test/Concurrency/sendable_methods.swift

+16
Original file line numberDiff line numberDiff line change
@@ -228,3 +228,19 @@ do {
228228
}
229229
}
230230
}
231+
232+
do {
233+
struct Test {
234+
static func fn() {}
235+
static func otherFn() {}
236+
}
237+
238+
func fnRet(cond: Bool) -> () -> Void {
239+
cond ? Test.fn : Test.otherFn // Ok
240+
}
241+
242+
func forward<T>(_: T) -> T {
243+
}
244+
245+
let _: () -> Void = forward(Test.fn) // Ok
246+
}

0 commit comments

Comments
 (0)