Skip to content

Commit fccc202

Browse files
committed
Adopt typed throws in some Dictionary APIs as well as Sequence APIs
1 parent 1965f96 commit fccc202

9 files changed

+267
-61
lines changed

stdlib/public/core/Dictionary.swift

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -916,10 +916,10 @@ extension Dictionary {
916916
/// this dictionary.
917917
///
918918
/// - Complexity: O(*n*), where *n* is the length of the dictionary.
919-
@inlinable
920-
public func mapValues<T>(
921-
_ transform: (Value) throws -> T
922-
) rethrows -> Dictionary<Key, T> {
919+
@_alwaysEmitIntoClient
920+
public func mapValues<T, E: Error>(
921+
_ transform: (Value) throws(E) -> T
922+
) throws(E) -> Dictionary<Key, T> {
923923
return try Dictionary<Key, T>(_native: _variant.mapValues(transform))
924924
}
925925

@@ -949,12 +949,13 @@ extension Dictionary {
949949
///
950950
/// - Complexity: O(*m* + *n*), where *n* is the length of the original
951951
/// dictionary and *m* is the length of the resulting dictionary.
952-
@inlinable
953-
public func compactMapValues<T>(
954-
_ transform: (Value) throws -> T?
955-
) rethrows -> Dictionary<Key, T> {
956-
let result: _NativeDictionary<Key, T> =
957-
try self.reduce(into: _NativeDictionary<Key, T>()) { (result, element) in
952+
@_alwaysEmitIntoClient
953+
public func compactMapValues<T, E: Error>(
954+
_ transform: (Value) throws(E) -> T?
955+
) throws(E) -> Dictionary<Key, T> {
956+
let result: _NativeDictionary<Key, T> = try self.reduce(
957+
into: _NativeDictionary<Key, T>()
958+
) { (result, element) throws(E) in
958959
if let value = try transform(element.value) {
959960
result.insertNew(key: element.key, value: value)
960961
}

stdlib/public/core/DictionaryBridging.swift

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -557,10 +557,10 @@ extension __CocoaDictionary: _DictionaryBuffer {
557557
}
558558

559559
extension __CocoaDictionary {
560-
@inlinable
561-
internal func mapValues<Key: Hashable, Value, T>(
562-
_ transform: (Value) throws -> T
563-
) rethrows -> _NativeDictionary<Key, T> {
560+
@_alwaysEmitIntoClient
561+
internal func mapValues<Key: Hashable, Value, T, E: Error>(
562+
_ transform: (Value) throws(E) -> T
563+
) throws(E) -> _NativeDictionary<Key, T> {
564564
var result = _NativeDictionary<Key, T>(capacity: self.count)
565565
for (cocoaKey, cocoaValue) in self {
566566
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
@@ -451,10 +451,10 @@ extension Dictionary._Variant {
451451
}
452452

453453
extension Dictionary._Variant {
454-
@inlinable
455-
internal func mapValues<T>(
456-
_ transform: (Value) throws -> T
457-
) rethrows -> _NativeDictionary<Key, T> {
454+
@_alwaysEmitIntoClient
455+
internal func mapValues<T, E: Error>(
456+
_ transform: (Value) throws(E) -> T
457+
) throws(E) -> _NativeDictionary<Key, T> {
458458
#if _runtime(_ObjC)
459459
guard isNative else {
460460
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
@@ -746,10 +746,10 @@ extension _NativeDictionary { // Deletion
746746
}
747747

748748
extension _NativeDictionary { // High-level operations
749-
@inlinable
750-
internal func mapValues<T>(
751-
_ transform: (Value) throws -> T
752-
) rethrows -> _NativeDictionary<Key, T> {
749+
@_alwaysEmitIntoClient
750+
internal func mapValues<T, E: Error>(
751+
_ transform: (Value) throws(E) -> T
752+
) throws(E) -> _NativeDictionary<Key, T> {
753753
let resultStorage = _DictionaryStorage<Key, T>.copy(original: _storage)
754754
_internalInvariant(resultStorage._seed == _storage._seed)
755755
let result = _NativeDictionary<Key, T>(resultStorage)

stdlib/public/core/Sequence.swift

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

706-
// ABI-only entrypoint for the rethrows version of map, which has been
707-
// superseded by the typed-throws version. Expressed as "throws", which is
708-
// ABI-compatible with "rethrows".
709-
@_spi(SwiftStdlibLegacyABI) @available(swift, obsoleted: 1)
710-
@usableFromInline
711-
@_silgen_name("$sSTsE3mapySayqd__Gqd__7ElementQzKXEKlF")
712-
func __rethrows_map<T>(
713-
_ transform: (Element) throws -> T
714-
) throws -> [T] {
715-
try map(transform)
716-
}
717-
718706
/// Returns an array containing, in order, the elements of the sequence
719707
/// that satisfy the given predicate.
720708
///
@@ -732,20 +720,18 @@ extension Sequence {
732720
/// - Returns: An array of the elements that `isIncluded` allowed.
733721
///
734722
/// - Complexity: O(*n*), where *n* is the length of the sequence.
735-
@inlinable
736-
public __consuming func filter(
737-
_ isIncluded: (Element) throws -> Bool
738-
) rethrows -> [Element] {
739-
return try _filter(isIncluded)
723+
@_alwaysEmitIntoClient
724+
public __consuming func filter<E: Error>(
725+
_ isIncluded: (Element) throws(E) -> Bool
726+
) throws(E) -> [Element] {
727+
try _filter(isIncluded)
740728
}
741729

742-
@_transparent
743-
public func _filter(
744-
_ isIncluded: (Element) throws -> Bool
745-
) rethrows -> [Element] {
746-
730+
@_alwaysEmitIntoClient
731+
public func _filter<E: Error>(
732+
_ isIncluded: (Element) throws(E) -> Bool
733+
) throws(E) -> [Element] {
747734
var result = ContiguousArray<Element>()
748-
749735
var iterator = self.makeIterator()
750736

751737
while let element = iterator.next() {
@@ -807,11 +793,11 @@ extension Sequence {
807793
///
808794
/// - Parameter body: A closure that takes an element of the sequence as a
809795
/// parameter.
796+
@_alwaysEmitIntoClient
810797
@_semantics("sequence.forEach")
811-
@inlinable
812-
public func forEach(
813-
_ body: (Element) throws -> Void
814-
) rethrows {
798+
public func forEach<E: Error>(
799+
_ body: (Element) throws(E) -> Void
800+
) throws(E) {
815801
for element in self {
816802
try body(element)
817803
}

stdlib/public/core/SequenceAlgorithms.swift

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -662,12 +662,11 @@ extension Sequence {
662662
/// the result is `initialResult`.
663663
///
664664
/// - Complexity: O(*n*), where *n* is the length of the sequence.
665-
@inlinable
666-
public func reduce<Result>(
667-
_ initialResult: Result,
668-
_ nextPartialResult:
669-
(_ partialResult: Result, Element) throws -> Result
670-
) rethrows -> Result {
665+
@_alwaysEmitIntoClient
666+
public func reduce<Result: ~Copyable, E: Error>(
667+
_ initialResult: consuming Result,
668+
_ nextPartialResult: (borrowing Result, Element) throws(E) -> Result
669+
) throws(E) -> Result {
671670
var accumulator = initialResult
672671
for element in self {
673672
accumulator = try nextPartialResult(accumulator, element)
@@ -719,12 +718,11 @@ extension Sequence {
719718
/// the result is `initialResult`.
720719
///
721720
/// - Complexity: O(*n*), where *n* is the length of the sequence.
722-
@inlinable
723-
public func reduce<Result>(
724-
into initialResult: __owned Result,
725-
_ updateAccumulatingResult:
726-
(_ partialResult: inout Result, Element) throws -> ()
727-
) rethrows -> Result {
721+
@_alwaysEmitIntoClient
722+
public func reduce<Result: ~Copyable, E: Error>(
723+
into initialResult: consuming Result,
724+
_ updateAccumulatingResult: (inout Result, Element) throws(E) -> ()
725+
) throws(E) -> Result {
728726
var accumulator = initialResult
729727
for element in self {
730728
try updateAccumulatingResult(&accumulator, element)

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

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -378,3 +378,30 @@ Struct UnsafePointer is now with @unsafe
378378
Struct UnsafeRawBufferPointer is now with @unsafe
379379
Struct UnsafeRawPointer is now with @unsafe
380380
Var Optional.unsafelyUnwrapped is now with @unsafe
381+
382+
// Adoption of typed throws for Dictionary.compactMapValues(_:)
383+
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>
384+
Func Dictionary.compactMapValues(_:) is now without @rethrows
385+
386+
// Adoption of typed throws for Dictionary.mapValues(_:)
387+
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>
388+
Func Dictionary.mapValues(_:) is now without @rethrows
389+
390+
// Adoption of typed throws for Sequence.filter(_:)
391+
Func Sequence.filter(_:) has generic signature change from <Self where Self : Swift.Sequence> to <Self, E where Self : Swift.Sequence, E : Swift.Error>
392+
Func Sequence.filter(_:) is now without @rethrows
393+
394+
// Adoption of typed throws for Sequence.forEach(_:)
395+
Func Sequence.forEach(_:) has generic signature change from <Self where Self : Swift.Sequence> to <Self, E where Self : Swift.Sequence, E : Swift.Error>
396+
Func Sequence.forEach(_:) is now without @rethrows
397+
398+
// Adoption of typed throws for Sequence.reduce(_:_:)
399+
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>
400+
Func Sequence.reduce(_:_:) has parameter 0 changing from Default to Owned
401+
Func Sequence.reduce(_:_:) is now without @rethrows
402+
403+
// Adoption of typed throws for Sequence.reduce(into:_:)
404+
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>
405+
Func Sequence.reduce(into:_:) has parameter 1 type change from (inout Result, Self.Element) throws -> () to (inout Result, Self.Element) throws(E) -> ()
406+
Func Sequence.reduce(into:_:) is now without @rethrows
407+

0 commit comments

Comments
 (0)