Skip to content

Commit e264e8d

Browse files
authored
Merge pull request #70382 from xedin/improve-sendability-checking-of-keypth-to-func
[CSBindings] keypath-to-function conversion should respect sendabilit…
2 parents d0de3a9 + bb20c7a commit e264e8d

File tree

2 files changed

+14
-5
lines changed

2 files changed

+14
-5
lines changed

lib/Sema/CSBindings.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -668,6 +668,14 @@ void BindingSet::finalize(
668668

669669
// Functions don't have capability so we can simply add them.
670670
if (auto *fnType = bindingTy->getAs<FunctionType>()) {
671+
auto extInfo = fnType->getExtInfo();
672+
673+
bool isKeyPathSendable = capability && capability->second;
674+
if (!isKeyPathSendable && extInfo.isSendable()) {
675+
fnType = FunctionType::get(fnType->getParams(), fnType->getResult(),
676+
extInfo.withConcurrent(false));
677+
}
678+
671679
updatedBindings.insert(binding.withType(fnType));
672680
}
673681
}

test/Concurrency/sendable_keypaths.swift

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -96,13 +96,13 @@ do {
9696
testSendableFn(v: v, \.[42]) // Ok
9797

9898
testSendableKP(v: v, \.[NonSendable()]) // expected-warning {{type 'KeyPath<V, Int>' does not conform to the 'Sendable' protocol}}
99-
// Note that there is no warning here because the key path is wrapped in a closure and not captured by it: `{ $0[keyPath: \.[NonSendable()]] }`
100-
testSendableFn(v: v, \.[NonSendable()]) // Ok
99+
testSendableFn(v: v, \.[NonSendable()]) // expected-warning {{converting non-sendable function value to '@Sendable (V) -> Int' may introduce data races}}
101100

102101
testNonSendableKP(v: v, \.[NonSendable()]) // Ok
103102
testNonSendableFn(v: v, \.[NonSendable()]) // Ok
104103

105-
let _: @Sendable (V) -> Int = \.[NonSendable()] // Ok
104+
let _: @Sendable (V) -> Int = \.[NonSendable()]
105+
// expected-warning@-1 {{converting non-sendable function value to '@Sendable (V) -> Int' may introduce data races}}
106106

107107
let _: KeyPath<V, Int> & Sendable = \.[42, CondSendable(NonSendable(data: [1, 2, 3]))]
108108
// expected-warning@-1 {{type 'ReferenceWritableKeyPath<V, Int>' does not conform to the 'Sendable' protocol}}
@@ -114,15 +114,16 @@ do {
114114

115115
testSendableKP(v: v, \.[42, CondSendable(NonSendable(data: [1, 2, 3]))])
116116
// expected-warning@-1 {{type 'ReferenceWritableKeyPath<V, Int>' does not conform to the 'Sendable' protocol}}
117-
testSendableFn(v: v, \.[42, CondSendable(NonSendable(data: [1, 2, 3]))]) // Ok
117+
testSendableFn(v: v, \.[42, CondSendable(NonSendable(data: [1, 2, 3]))])
118+
// expected-warning@-1 {{converting non-sendable function value to '@Sendable (V) -> Int' may introduce data races}}
118119
testSendableKP(v: v, \.[42, CondSendable(42)]) // Ok
119120

120121
let nonSendable = NonSendable()
121122
testSendableKP(v: v, \.[42, CondSendable(nonSendable)])
122123
// expected-warning@-1 {{type 'ReferenceWritableKeyPath<V, Int>' does not conform to the 'Sendable' protocol}}
123124

124-
// TODO: This should be diagnosed by the isolation checker because implicitly synthesized closures captures a non-Sendable value.
125125
testSendableFn(v: v, \.[42, CondSendable(nonSendable)])
126+
// expected-warning@-1 {{converting non-sendable function value to '@Sendable (V) -> Int' may introduce data races}}
126127
}
127128

128129
// @dynamicMemberLookup with Sendable requirement

0 commit comments

Comments
 (0)