Skip to content

Commit 97d9339

Browse files
committed
Adopt typed throws in some Dictionary APIs as well as Sequence APIs
1 parent 80cd764 commit 97d9339

9 files changed

+266
-61
lines changed

stdlib/public/core/Dictionary.swift

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -926,10 +926,10 @@ extension Dictionary {
926926
/// this dictionary.
927927
///
928928
/// - Complexity: O(*n*), where *n* is the length of the dictionary.
929-
@inlinable
930-
public func mapValues<T>(
931-
_ transform: (Value) throws -> T
932-
) rethrows -> Dictionary<Key, T> {
929+
@_alwaysEmitIntoClient
930+
public func mapValues<T, E: Error>(
931+
_ transform: (Value) throws(E) -> T
932+
) throws(E) -> Dictionary<Key, T> {
933933
return try Dictionary<Key, T>(_native: _variant.mapValues(transform))
934934
}
935935

@@ -959,12 +959,13 @@ extension Dictionary {
959959
///
960960
/// - Complexity: O(*m* + *n*), where *n* is the length of the original
961961
/// dictionary and *m* is the length of the resulting dictionary.
962-
@inlinable
963-
public func compactMapValues<T>(
964-
_ transform: (Value) throws -> T?
965-
) rethrows -> Dictionary<Key, T> {
966-
let result: _NativeDictionary<Key, T> =
967-
try self.reduce(into: _NativeDictionary<Key, T>()) { (result, element) in
962+
@_alwaysEmitIntoClient
963+
public func compactMapValues<T, E: Error>(
964+
_ transform: (Value) throws(E) -> T?
965+
) throws(E) -> Dictionary<Key, T> {
966+
let result: _NativeDictionary<Key, T> = try self.reduce(
967+
into: _NativeDictionary<Key, T>()
968+
) { (result, element) throws(E) in
968969
if let value = try transform(element.value) {
969970
result.insertNew(key: element.key, value: value)
970971
}

stdlib/public/core/DictionaryBridging.swift

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -559,10 +559,10 @@ extension __CocoaDictionary: _DictionaryBuffer {
559559
}
560560

561561
extension __CocoaDictionary {
562-
@inlinable
563-
internal func mapValues<Key: Hashable, Value, T>(
564-
_ transform: (Value) throws -> T
565-
) rethrows -> _NativeDictionary<Key, T> {
562+
@_alwaysEmitIntoClient
563+
internal func mapValues<Key: Hashable, Value, T, E: Error>(
564+
_ transform: (Value) throws(E) -> T
565+
) throws(E) -> _NativeDictionary<Key, T> {
566566
var result = _NativeDictionary<Key, T>(capacity: self.count)
567567
for (cocoaKey, cocoaValue) in self {
568568
let key = _forceBridgeFromObjectiveC(cocoaKey, Key.self)

stdlib/public/core/DictionaryVariant.swift

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -452,10 +452,10 @@ extension Dictionary._Variant {
452452
}
453453

454454
extension Dictionary._Variant {
455-
@inlinable
456-
internal func mapValues<T>(
457-
_ transform: (Value) throws -> T
458-
) rethrows -> _NativeDictionary<Key, T> {
455+
@_alwaysEmitIntoClient
456+
internal func mapValues<T, E: Error>(
457+
_ transform: (Value) throws(E) -> T
458+
) throws(E) -> _NativeDictionary<Key, T> {
459459
#if _runtime(_ObjC)
460460
guard isNative else {
461461
return try asCocoa.mapValues(transform)

stdlib/public/core/LegacyABI.swift

Lines changed: 156 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,3 +113,159 @@ internal func _unsafeMinus(_ lhs: Int, _ rhs: Int) -> Int {
113113
return lhs &- rhs
114114
#endif
115115
}
116+
117+
extension Dictionary {
118+
@usableFromInline
119+
@_silgen_name("$sSD9mapValuesySDyxqd__Gqd__q_KXEKlF")
120+
internal func __abi_mapValues<T>(
121+
_ transform: (Value) throws -> T
122+
) rethrows -> Dictionary<Key, T> {
123+
return try Dictionary<Key, T>(_native: _variant.mapValues(transform))
124+
}
125+
126+
@usableFromInline
127+
@_silgen_name("$sSD16compactMapValuesySDyxqd__Gqd__Sgq_KXEKlF")
128+
internal func __abi_compactMapValues<T>(
129+
_ transform: (Value) throws -> T?
130+
) rethrows -> Dictionary<Key, T> {
131+
let result: _NativeDictionary<Key, T> =
132+
try self.reduce(into: _NativeDictionary<Key, T>()) { (result, element) in
133+
if let value = try transform(element.value) {
134+
result.insertNew(key: element.key, value: value)
135+
}
136+
}
137+
return Dictionary<Key, T>(_native: result)
138+
}
139+
}
140+
141+
extension Dictionary._Variant {
142+
@usableFromInline
143+
@_silgen_name("$sSD8_VariantV9mapValuesys17_NativeDictionaryVyxqd__Gqd__q_KXEKlF")
144+
internal func __abi_mapValues<T>(
145+
_ transform: (Value) throws -> T
146+
) rethrows -> _NativeDictionary<Key, T> {
147+
#if _runtime(_ObjC)
148+
guard isNative else {
149+
return try asCocoa.mapValues(transform)
150+
}
151+
#endif
152+
return try asNative.mapValues(transform)
153+
}
154+
}
155+
156+
extension __CocoaDictionary {
157+
@usableFromInline
158+
@_silgen_name("$ss17__CocoaDictionaryV9mapValuesys07_NativeB0Vyxq0_Gq0_q_KXEKSHRzr1_lF")
159+
internal func __abi_mapValues<Key: Hashable, Value, T>(
160+
_ transform: (Value) throws -> T
161+
) rethrows -> _NativeDictionary<Key, T> {
162+
var result = _NativeDictionary<Key, T>(capacity: self.count)
163+
for (cocoaKey, cocoaValue) in self {
164+
let key = _forceBridgeFromObjectiveC(cocoaKey, Key.self)
165+
let value = _forceBridgeFromObjectiveC(cocoaValue, Value.self)
166+
try result.insertNew(key: key, value: transform(value))
167+
}
168+
return result
169+
}
170+
}
171+
172+
extension _NativeDictionary {
173+
@usableFromInline
174+
@_silgen_name("$ss17_NativeDictionaryV9mapValuesyAByxqd__Gqd__q_KXEKlF")
175+
internal func __abi_mapValues<T>(
176+
_ transform: (Value) throws -> T
177+
) rethrows -> _NativeDictionary<Key, T> {
178+
let resultStorage = _DictionaryStorage<Key, T>.copy(original: _storage)
179+
_internalInvariant(resultStorage._seed == _storage._seed)
180+
let result = _NativeDictionary<Key, T>(resultStorage)
181+
// Because the current and new buffer have the same scale and seed, we can
182+
// initialize to the same locations in the new buffer, skipping hash value
183+
// recalculations.
184+
for bucket in hashTable {
185+
let key = self.uncheckedKey(at: bucket)
186+
let value = self.uncheckedValue(at: bucket)
187+
try result._insert(at: bucket, key: key, value: transform(value))
188+
}
189+
return result
190+
}
191+
}
192+
193+
extension Sequence {
194+
// ABI-only entrypoint for the rethrows version of map, which has been
195+
// superseded by the typed-throws version. Expressed as "throws", which is
196+
// ABI-compatible with "rethrows".
197+
@_spi(SwiftStdlibLegacyABI) @available(swift, obsoleted: 1)
198+
@usableFromInline
199+
@_silgen_name("$sSTsE3mapySayqd__Gqd__7ElementQzKXEKlF")
200+
func __rethrows_map<T>(
201+
_ transform: (Element) throws -> T
202+
) throws -> [T] {
203+
try map(transform)
204+
}
205+
206+
@usableFromInline
207+
@_silgen_name("$sSTsE6filterySay7ElementQzGSbACKXEKF")
208+
internal __consuming func __abi_filter(
209+
_ isIncluded: (Element) throws -> Bool
210+
) rethrows -> [Element] {
211+
return try __abi__filter(isIncluded)
212+
}
213+
214+
@usableFromInline
215+
@_silgen_name("$sSTsE7_filterySay7ElementQzGSbACKXEKF")
216+
internal func __abi__filter(
217+
_ isIncluded: (Element) throws -> Bool
218+
) rethrows -> [Element] {
219+
220+
var result = ContiguousArray<Element>()
221+
222+
var iterator = self.makeIterator()
223+
224+
while let element = iterator.next() {
225+
if try isIncluded(element) {
226+
result.append(element)
227+
}
228+
}
229+
230+
return Array(result)
231+
}
232+
233+
@usableFromInline
234+
@_semantics("sequence.forEach")
235+
@_silgen_name("$sSTsE7forEachyyy7ElementQzKXEKF")
236+
internal func __abi_forEach(
237+
_ body: (Element) throws -> Void
238+
) rethrows {
239+
for element in self {
240+
try body(element)
241+
}
242+
}
243+
244+
@usableFromInline
245+
@_silgen_name("$sSTsE6reduceyqd__qd___qd__qd___7ElementQztKXEtKlF")
246+
internal func __abi_reduce<Result>(
247+
_ initialResult: Result,
248+
_ nextPartialResult:
249+
(_ partialResult: Result, Element) throws -> Result
250+
) rethrows -> Result {
251+
var accumulator = initialResult
252+
for element in self {
253+
accumulator = try nextPartialResult(accumulator, element)
254+
}
255+
return accumulator
256+
}
257+
258+
@usableFromInline
259+
@_silgen_name("$sSTsE6reduce4into_qd__qd__n_yqd__z_7ElementQztKXEtKlF")
260+
internal func __abi_reduce<Result>(
261+
into initialResult: __owned Result,
262+
_ updateAccumulatingResult:
263+
(_ partialResult: inout Result, Element) throws -> ()
264+
) rethrows -> Result {
265+
var accumulator = initialResult
266+
for element in self {
267+
try updateAccumulatingResult(&accumulator, element)
268+
}
269+
return accumulator
270+
}
271+
}

stdlib/public/core/NativeDictionary.swift

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -755,10 +755,10 @@ extension _NativeDictionary { // Deletion
755755
}
756756

757757
extension _NativeDictionary { // High-level operations
758-
@inlinable
759-
internal func mapValues<T>(
760-
_ transform: (Value) throws -> T
761-
) rethrows -> _NativeDictionary<Key, T> {
758+
@_alwaysEmitIntoClient
759+
internal func mapValues<T, E: Error>(
760+
_ transform: (Value) throws(E) -> T
761+
) throws(E) -> _NativeDictionary<Key, T> {
762762
let resultStorage = unsafe _DictionaryStorage<Key, T>.copy(original: _storage)
763763
unsafe _internalInvariant(resultStorage._seed == _storage._seed)
764764
let result = unsafe _NativeDictionary<Key, T>(resultStorage)

stdlib/public/core/Sequence.swift

Lines changed: 13 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -705,18 +705,6 @@ extension Sequence {
705705
return Array(result)
706706
}
707707

708-
// ABI-only entrypoint for the rethrows version of map, which has been
709-
// superseded by the typed-throws version. Expressed as "throws", which is
710-
// ABI-compatible with "rethrows".
711-
@_spi(SwiftStdlibLegacyABI) @available(swift, obsoleted: 1)
712-
@usableFromInline
713-
@_silgen_name("$sSTsE3mapySayqd__Gqd__7ElementQzKXEKlF")
714-
func __rethrows_map<T>(
715-
_ transform: (Element) throws -> T
716-
) throws -> [T] {
717-
try map(transform)
718-
}
719-
720708
/// Returns an array containing, in order, the elements of the sequence
721709
/// that satisfy the given predicate.
722710
///
@@ -734,20 +722,18 @@ extension Sequence {
734722
/// - Returns: An array of the elements that `isIncluded` allowed.
735723
///
736724
/// - Complexity: O(*n*), where *n* is the length of the sequence.
737-
@inlinable
738-
public __consuming func filter(
739-
_ isIncluded: (Element) throws -> Bool
740-
) rethrows -> [Element] {
741-
return try _filter(isIncluded)
725+
@_alwaysEmitIntoClient
726+
public __consuming func filter<E: Error>(
727+
_ isIncluded: (Element) throws(E) -> Bool
728+
) throws(E) -> [Element] {
729+
try _filter(isIncluded)
742730
}
743731

744-
@_transparent
745-
public func _filter(
746-
_ isIncluded: (Element) throws -> Bool
747-
) rethrows -> [Element] {
748-
732+
@_alwaysEmitIntoClient
733+
public func _filter<E: Error>(
734+
_ isIncluded: (Element) throws(E) -> Bool
735+
) throws(E) -> [Element] {
749736
var result = ContiguousArray<Element>()
750-
751737
var iterator = self.makeIterator()
752738

753739
while let element = iterator.next() {
@@ -809,11 +795,11 @@ extension Sequence {
809795
///
810796
/// - Parameter body: A closure that takes an element of the sequence as a
811797
/// parameter.
798+
@_alwaysEmitIntoClient
812799
@_semantics("sequence.forEach")
813-
@inlinable
814-
public func forEach(
815-
_ body: (Element) throws -> Void
816-
) rethrows {
800+
public func forEach<E: Error>(
801+
_ body: (Element) throws(E) -> Void
802+
) throws(E) {
817803
for element in self {
818804
try body(element)
819805
}

stdlib/public/core/SequenceAlgorithms.swift

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -664,12 +664,11 @@ extension Sequence {
664664
/// the result is `initialResult`.
665665
///
666666
/// - Complexity: O(*n*), where *n* is the length of the sequence.
667-
@inlinable
668-
public func reduce<Result>(
669-
_ initialResult: Result,
670-
_ nextPartialResult:
671-
(_ partialResult: Result, Element) throws -> Result
672-
) rethrows -> Result {
667+
@_alwaysEmitIntoClient
668+
public func reduce<Result: ~Copyable, E: Error>(
669+
_ initialResult: consuming Result,
670+
_ nextPartialResult: (borrowing Result, Element) throws(E) -> Result
671+
) throws(E) -> Result {
673672
var accumulator = initialResult
674673
for element in self {
675674
accumulator = try nextPartialResult(accumulator, element)
@@ -721,12 +720,11 @@ extension Sequence {
721720
/// the result is `initialResult`.
722721
///
723722
/// - Complexity: O(*n*), where *n* is the length of the sequence.
724-
@inlinable
725-
public func reduce<Result>(
726-
into initialResult: __owned Result,
727-
_ updateAccumulatingResult:
728-
(_ partialResult: inout Result, Element) throws -> ()
729-
) rethrows -> Result {
723+
@_alwaysEmitIntoClient
724+
public func reduce<Result: ~Copyable, E: Error>(
725+
into initialResult: consuming Result,
726+
_ updateAccumulatingResult: (inout Result, Element) throws(E) -> ()
727+
) throws(E) -> Result {
730728
var accumulator = initialResult
731729
for element in self {
732730
try updateAccumulatingResult(&accumulator, element)

test/api-digester/Outputs/stability-stdlib-source-base.swift.expected

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -375,3 +375,29 @@ Accessor UnsafeMutableBufferPointer.indices.Get() has generic signature change f
375375

376376
Func type(of:) has generic signature change from <T, Metatype> to <T, Metatype where T : ~Copyable, T : ~Escapable>
377377
Func type(of:) has parameter 0 changing from Default to Shared
378+
379+
// Adoption of typed throws for Dictionary.compactMapValues(_:)
380+
Func Dictionary.compactMapValues(_:) has generic signature change from <Key, Value, T where Key : Swift.Hashable> to <Key, Value, T, E where Key : Swift.Hashable, E : Swift.Error>
381+
Func Dictionary.compactMapValues(_:) is now without @rethrows
382+
383+
// Adoption of typed throws for Dictionary.mapValues(_:)
384+
Func Dictionary.mapValues(_:) has generic signature change from <Key, Value, T where Key : Swift.Hashable> to <Key, Value, T, E where Key : Swift.Hashable, E : Swift.Error>
385+
Func Dictionary.mapValues(_:) is now without @rethrows
386+
387+
// Adoption of typed throws for Sequence.filter(_:)
388+
Func Sequence.filter(_:) has generic signature change from <Self where Self : Swift.Sequence> to <Self, E where Self : Swift.Sequence, E : Swift.Error>
389+
Func Sequence.filter(_:) is now without @rethrows
390+
391+
// Adoption of typed throws for Sequence.forEach(_:)
392+
Func Sequence.forEach(_:) has generic signature change from <Self where Self : Swift.Sequence> to <Self, E where Self : Swift.Sequence, E : Swift.Error>
393+
Func Sequence.forEach(_:) is now without @rethrows
394+
395+
// Adoption of typed throws for Sequence.reduce(_:_:)
396+
Func Sequence.reduce(_:_:) has generic signature change from <Self, Result where Self : Swift.Sequence> to <Self, Result, E where Self : Swift.Sequence, E : Swift.Error, Result : ~Copyable>
397+
Func Sequence.reduce(_:_:) has parameter 0 changing from Default to Owned
398+
Func Sequence.reduce(_:_:) is now without @rethrows
399+
400+
// Adoption of typed throws for Sequence.reduce(into:_:)
401+
Func Sequence.reduce(into:_:) has generic signature change from <Self, Result where Self : Swift.Sequence> to <Self, Result, E where Self : Swift.Sequence, E : Swift.Error, Result : ~Copyable>
402+
Func Sequence.reduce(into:_:) has parameter 1 type change from (inout Result, Self.Element) throws -> () to (inout Result, Self.Element) throws(E) -> ()
403+
Func Sequence.reduce(into:_:) is now without @rethrows

0 commit comments

Comments
 (0)