From 97d9339d7615105a9fee231cf087f01bd3c0259d Mon Sep 17 00:00:00 2001 From: Alejandro Alonso Date: Wed, 4 Dec 2024 11:46:14 -0800 Subject: [PATCH 1/7] Adopt typed throws in some Dictionary APIs as well as Sequence APIs --- stdlib/public/core/Dictionary.swift | 21 +-- stdlib/public/core/DictionaryBridging.swift | 8 +- stdlib/public/core/DictionaryVariant.swift | 8 +- stdlib/public/core/LegacyABI.swift | 156 ++++++++++++++++++ stdlib/public/core/NativeDictionary.swift | 8 +- stdlib/public/core/Sequence.swift | 40 ++--- stdlib/public/core/SequenceAlgorithms.swift | 22 ++- ...tability-stdlib-source-base.swift.expected | 26 +++ .../stability-stdlib-abi-without-asserts.test | 38 +++++ 9 files changed, 266 insertions(+), 61 deletions(-) diff --git a/stdlib/public/core/Dictionary.swift b/stdlib/public/core/Dictionary.swift index 6e867aedec522..17b9060b98a8c 100644 --- a/stdlib/public/core/Dictionary.swift +++ b/stdlib/public/core/Dictionary.swift @@ -926,10 +926,10 @@ extension Dictionary { /// this dictionary. /// /// - Complexity: O(*n*), where *n* is the length of the dictionary. - @inlinable - public func mapValues( - _ transform: (Value) throws -> T - ) rethrows -> Dictionary { + @_alwaysEmitIntoClient + public func mapValues( + _ transform: (Value) throws(E) -> T + ) throws(E) -> Dictionary { return try Dictionary(_native: _variant.mapValues(transform)) } @@ -959,12 +959,13 @@ extension Dictionary { /// /// - Complexity: O(*m* + *n*), where *n* is the length of the original /// dictionary and *m* is the length of the resulting dictionary. - @inlinable - public func compactMapValues( - _ transform: (Value) throws -> T? - ) rethrows -> Dictionary { - let result: _NativeDictionary = - try self.reduce(into: _NativeDictionary()) { (result, element) in + @_alwaysEmitIntoClient + public func compactMapValues( + _ transform: (Value) throws(E) -> T? + ) throws(E) -> Dictionary { + let result: _NativeDictionary = try self.reduce( + into: _NativeDictionary() + ) { (result, element) throws(E) in if let value = try transform(element.value) { result.insertNew(key: element.key, value: value) } diff --git a/stdlib/public/core/DictionaryBridging.swift b/stdlib/public/core/DictionaryBridging.swift index 15d682d128ead..6b804d11c21db 100644 --- a/stdlib/public/core/DictionaryBridging.swift +++ b/stdlib/public/core/DictionaryBridging.swift @@ -559,10 +559,10 @@ extension __CocoaDictionary: _DictionaryBuffer { } extension __CocoaDictionary { - @inlinable - internal func mapValues( - _ transform: (Value) throws -> T - ) rethrows -> _NativeDictionary { + @_alwaysEmitIntoClient + internal func mapValues( + _ transform: (Value) throws(E) -> T + ) throws(E) -> _NativeDictionary { var result = _NativeDictionary(capacity: self.count) for (cocoaKey, cocoaValue) in self { let key = _forceBridgeFromObjectiveC(cocoaKey, Key.self) diff --git a/stdlib/public/core/DictionaryVariant.swift b/stdlib/public/core/DictionaryVariant.swift index 199f404237fb5..92d41839be6ab 100644 --- a/stdlib/public/core/DictionaryVariant.swift +++ b/stdlib/public/core/DictionaryVariant.swift @@ -452,10 +452,10 @@ extension Dictionary._Variant { } extension Dictionary._Variant { - @inlinable - internal func mapValues( - _ transform: (Value) throws -> T - ) rethrows -> _NativeDictionary { + @_alwaysEmitIntoClient + internal func mapValues( + _ transform: (Value) throws(E) -> T + ) throws(E) -> _NativeDictionary { #if _runtime(_ObjC) guard isNative else { return try asCocoa.mapValues(transform) diff --git a/stdlib/public/core/LegacyABI.swift b/stdlib/public/core/LegacyABI.swift index 819257b7ed1b4..b2354db30fc8c 100644 --- a/stdlib/public/core/LegacyABI.swift +++ b/stdlib/public/core/LegacyABI.swift @@ -113,3 +113,159 @@ internal func _unsafeMinus(_ lhs: Int, _ rhs: Int) -> Int { return lhs &- rhs #endif } + +extension Dictionary { + @usableFromInline + @_silgen_name("$sSD9mapValuesySDyxqd__Gqd__q_KXEKlF") + internal func __abi_mapValues( + _ transform: (Value) throws -> T + ) rethrows -> Dictionary { + return try Dictionary(_native: _variant.mapValues(transform)) + } + + @usableFromInline + @_silgen_name("$sSD16compactMapValuesySDyxqd__Gqd__Sgq_KXEKlF") + internal func __abi_compactMapValues( + _ transform: (Value) throws -> T? + ) rethrows -> Dictionary { + let result: _NativeDictionary = + try self.reduce(into: _NativeDictionary()) { (result, element) in + if let value = try transform(element.value) { + result.insertNew(key: element.key, value: value) + } + } + return Dictionary(_native: result) + } +} + +extension Dictionary._Variant { + @usableFromInline + @_silgen_name("$sSD8_VariantV9mapValuesys17_NativeDictionaryVyxqd__Gqd__q_KXEKlF") + internal func __abi_mapValues( + _ transform: (Value) throws -> T + ) rethrows -> _NativeDictionary { +#if _runtime(_ObjC) + guard isNative else { + return try asCocoa.mapValues(transform) + } +#endif + return try asNative.mapValues(transform) + } +} + +extension __CocoaDictionary { + @usableFromInline + @_silgen_name("$ss17__CocoaDictionaryV9mapValuesys07_NativeB0Vyxq0_Gq0_q_KXEKSHRzr1_lF") + internal func __abi_mapValues( + _ transform: (Value) throws -> T + ) rethrows -> _NativeDictionary { + var result = _NativeDictionary(capacity: self.count) + for (cocoaKey, cocoaValue) in self { + let key = _forceBridgeFromObjectiveC(cocoaKey, Key.self) + let value = _forceBridgeFromObjectiveC(cocoaValue, Value.self) + try result.insertNew(key: key, value: transform(value)) + } + return result + } +} + +extension _NativeDictionary { + @usableFromInline + @_silgen_name("$ss17_NativeDictionaryV9mapValuesyAByxqd__Gqd__q_KXEKlF") + internal func __abi_mapValues( + _ transform: (Value) throws -> T + ) rethrows -> _NativeDictionary { + let resultStorage = _DictionaryStorage.copy(original: _storage) + _internalInvariant(resultStorage._seed == _storage._seed) + let result = _NativeDictionary(resultStorage) + // Because the current and new buffer have the same scale and seed, we can + // initialize to the same locations in the new buffer, skipping hash value + // recalculations. + for bucket in hashTable { + let key = self.uncheckedKey(at: bucket) + let value = self.uncheckedValue(at: bucket) + try result._insert(at: bucket, key: key, value: transform(value)) + } + return result + } +} + +extension Sequence { + // ABI-only entrypoint for the rethrows version of map, which has been + // superseded by the typed-throws version. Expressed as "throws", which is + // ABI-compatible with "rethrows". + @_spi(SwiftStdlibLegacyABI) @available(swift, obsoleted: 1) + @usableFromInline + @_silgen_name("$sSTsE3mapySayqd__Gqd__7ElementQzKXEKlF") + func __rethrows_map( + _ transform: (Element) throws -> T + ) throws -> [T] { + try map(transform) + } + + @usableFromInline + @_silgen_name("$sSTsE6filterySay7ElementQzGSbACKXEKF") + internal __consuming func __abi_filter( + _ isIncluded: (Element) throws -> Bool + ) rethrows -> [Element] { + return try __abi__filter(isIncluded) + } + + @usableFromInline + @_silgen_name("$sSTsE7_filterySay7ElementQzGSbACKXEKF") + internal func __abi__filter( + _ isIncluded: (Element) throws -> Bool + ) rethrows -> [Element] { + + var result = ContiguousArray() + + var iterator = self.makeIterator() + + while let element = iterator.next() { + if try isIncluded(element) { + result.append(element) + } + } + + return Array(result) + } + + @usableFromInline + @_semantics("sequence.forEach") + @_silgen_name("$sSTsE7forEachyyy7ElementQzKXEKF") + internal func __abi_forEach( + _ body: (Element) throws -> Void + ) rethrows { + for element in self { + try body(element) + } + } + + @usableFromInline + @_silgen_name("$sSTsE6reduceyqd__qd___qd__qd___7ElementQztKXEtKlF") + internal func __abi_reduce( + _ initialResult: Result, + _ nextPartialResult: + (_ partialResult: Result, Element) throws -> Result + ) rethrows -> Result { + var accumulator = initialResult + for element in self { + accumulator = try nextPartialResult(accumulator, element) + } + return accumulator + } + + @usableFromInline + @_silgen_name("$sSTsE6reduce4into_qd__qd__n_yqd__z_7ElementQztKXEtKlF") + internal func __abi_reduce( + into initialResult: __owned Result, + _ updateAccumulatingResult: + (_ partialResult: inout Result, Element) throws -> () + ) rethrows -> Result { + var accumulator = initialResult + for element in self { + try updateAccumulatingResult(&accumulator, element) + } + return accumulator + } +} diff --git a/stdlib/public/core/NativeDictionary.swift b/stdlib/public/core/NativeDictionary.swift index 039ce5eef3a81..314145649289d 100644 --- a/stdlib/public/core/NativeDictionary.swift +++ b/stdlib/public/core/NativeDictionary.swift @@ -755,10 +755,10 @@ extension _NativeDictionary { // Deletion } extension _NativeDictionary { // High-level operations - @inlinable - internal func mapValues( - _ transform: (Value) throws -> T - ) rethrows -> _NativeDictionary { + @_alwaysEmitIntoClient + internal func mapValues( + _ transform: (Value) throws(E) -> T + ) throws(E) -> _NativeDictionary { let resultStorage = unsafe _DictionaryStorage.copy(original: _storage) unsafe _internalInvariant(resultStorage._seed == _storage._seed) let result = unsafe _NativeDictionary(resultStorage) diff --git a/stdlib/public/core/Sequence.swift b/stdlib/public/core/Sequence.swift index e34bb9d8df267..ade92d4501754 100644 --- a/stdlib/public/core/Sequence.swift +++ b/stdlib/public/core/Sequence.swift @@ -705,18 +705,6 @@ extension Sequence { return Array(result) } - // ABI-only entrypoint for the rethrows version of map, which has been - // superseded by the typed-throws version. Expressed as "throws", which is - // ABI-compatible with "rethrows". - @_spi(SwiftStdlibLegacyABI) @available(swift, obsoleted: 1) - @usableFromInline - @_silgen_name("$sSTsE3mapySayqd__Gqd__7ElementQzKXEKlF") - func __rethrows_map( - _ transform: (Element) throws -> T - ) throws -> [T] { - try map(transform) - } - /// Returns an array containing, in order, the elements of the sequence /// that satisfy the given predicate. /// @@ -734,20 +722,18 @@ extension Sequence { /// - Returns: An array of the elements that `isIncluded` allowed. /// /// - Complexity: O(*n*), where *n* is the length of the sequence. - @inlinable - public __consuming func filter( - _ isIncluded: (Element) throws -> Bool - ) rethrows -> [Element] { - return try _filter(isIncluded) + @_alwaysEmitIntoClient + public __consuming func filter( + _ isIncluded: (Element) throws(E) -> Bool + ) throws(E) -> [Element] { + try _filter(isIncluded) } - @_transparent - public func _filter( - _ isIncluded: (Element) throws -> Bool - ) rethrows -> [Element] { - + @_alwaysEmitIntoClient + public func _filter( + _ isIncluded: (Element) throws(E) -> Bool + ) throws(E) -> [Element] { var result = ContiguousArray() - var iterator = self.makeIterator() while let element = iterator.next() { @@ -809,11 +795,11 @@ extension Sequence { /// /// - Parameter body: A closure that takes an element of the sequence as a /// parameter. + @_alwaysEmitIntoClient @_semantics("sequence.forEach") - @inlinable - public func forEach( - _ body: (Element) throws -> Void - ) rethrows { + public func forEach( + _ body: (Element) throws(E) -> Void + ) throws(E) { for element in self { try body(element) } diff --git a/stdlib/public/core/SequenceAlgorithms.swift b/stdlib/public/core/SequenceAlgorithms.swift index 8ba0171d69086..9ed0a261928f4 100644 --- a/stdlib/public/core/SequenceAlgorithms.swift +++ b/stdlib/public/core/SequenceAlgorithms.swift @@ -664,12 +664,11 @@ extension Sequence { /// the result is `initialResult`. /// /// - Complexity: O(*n*), where *n* is the length of the sequence. - @inlinable - public func reduce( - _ initialResult: Result, - _ nextPartialResult: - (_ partialResult: Result, Element) throws -> Result - ) rethrows -> Result { + @_alwaysEmitIntoClient + public func reduce( + _ initialResult: consuming Result, + _ nextPartialResult: (borrowing Result, Element) throws(E) -> Result + ) throws(E) -> Result { var accumulator = initialResult for element in self { accumulator = try nextPartialResult(accumulator, element) @@ -721,12 +720,11 @@ extension Sequence { /// the result is `initialResult`. /// /// - Complexity: O(*n*), where *n* is the length of the sequence. - @inlinable - public func reduce( - into initialResult: __owned Result, - _ updateAccumulatingResult: - (_ partialResult: inout Result, Element) throws -> () - ) rethrows -> Result { + @_alwaysEmitIntoClient + public func reduce( + into initialResult: consuming Result, + _ updateAccumulatingResult: (inout Result, Element) throws(E) -> () + ) throws(E) -> Result { var accumulator = initialResult for element in self { try updateAccumulatingResult(&accumulator, element) diff --git a/test/api-digester/Outputs/stability-stdlib-source-base.swift.expected b/test/api-digester/Outputs/stability-stdlib-source-base.swift.expected index 131ce99fa0cfb..70871a6850179 100644 --- a/test/api-digester/Outputs/stability-stdlib-source-base.swift.expected +++ b/test/api-digester/Outputs/stability-stdlib-source-base.swift.expected @@ -375,3 +375,29 @@ Accessor UnsafeMutableBufferPointer.indices.Get() has generic signature change f Func type(of:) has generic signature change from to Func type(of:) has parameter 0 changing from Default to Shared + +// Adoption of typed throws for Dictionary.compactMapValues(_:) +Func Dictionary.compactMapValues(_:) has generic signature change from to +Func Dictionary.compactMapValues(_:) is now without @rethrows + +// Adoption of typed throws for Dictionary.mapValues(_:) +Func Dictionary.mapValues(_:) has generic signature change from to +Func Dictionary.mapValues(_:) is now without @rethrows + +// Adoption of typed throws for Sequence.filter(_:) +Func Sequence.filter(_:) has generic signature change from to +Func Sequence.filter(_:) is now without @rethrows + +// Adoption of typed throws for Sequence.forEach(_:) +Func Sequence.forEach(_:) has generic signature change from to +Func Sequence.forEach(_:) is now without @rethrows + +// Adoption of typed throws for Sequence.reduce(_:_:) +Func Sequence.reduce(_:_:) has generic signature change from to +Func Sequence.reduce(_:_:) has parameter 0 changing from Default to Owned +Func Sequence.reduce(_:_:) is now without @rethrows + +// Adoption of typed throws for Sequence.reduce(into:_:) +Func Sequence.reduce(into:_:) has generic signature change from to +Func Sequence.reduce(into:_:) has parameter 1 type change from (inout Result, Self.Element) throws -> () to (inout Result, Self.Element) throws(E) -> () +Func Sequence.reduce(into:_:) is now without @rethrows diff --git a/test/api-digester/stability-stdlib-abi-without-asserts.test b/test/api-digester/stability-stdlib-abi-without-asserts.test index c65f73b776718..189bf3f8675f4 100644 --- a/test/api-digester/stability-stdlib-abi-without-asserts.test +++ b/test/api-digester/stability-stdlib-abi-without-asserts.test @@ -859,4 +859,42 @@ Func !=(_:_:) has been removed Func ==(_:_:) has been removed Func type(of:) has been removed +// Adoption of typed throws for Dictionary._Variant.mapValues(_:) +Func Dictionary._Variant.mapValues(_:) has been renamed to Func __abi_mapValues(_:) +Func Dictionary._Variant.mapValues(_:) has mangled name changing from 'Swift.Dictionary._Variant.mapValues((B) throws -> A1) throws -> Swift._NativeDictionary' to 'Swift.Dictionary._Variant.__abi_mapValues((B) throws -> A1) throws -> Swift._NativeDictionary' + +// Adoption of typed throws for Dictionary.compactMapValues(_:) +Func Dictionary.compactMapValues(_:) has been renamed to Func __abi_compactMapValues(_:) +Func Dictionary.compactMapValues(_:) has mangled name changing from 'Swift.Dictionary.compactMapValues((B) throws -> Swift.Optional) throws -> Swift.Dictionary' to 'Swift.Dictionary.__abi_compactMapValues((B) throws -> Swift.Optional) throws -> Swift.Dictionary' + +// Adoption of typed throws for Dictionary.mapValues(_:) +Func Dictionary.mapValues(_:) has been renamed to Func __abi_mapValues(_:) +Func Dictionary.mapValues(_:) has mangled name changing from 'Swift.Dictionary.mapValues((B) throws -> A1) throws -> Swift.Dictionary' to 'Swift.Dictionary.__abi_mapValues((B) throws -> A1) throws -> Swift.Dictionary' + +// Adoption of typed throws Sequence.filter(_:) +Func Sequence._filter(_:) has been renamed to Func __abi__filter(_:) +Func Sequence._filter(_:) has mangled name changing from '(extension in Swift):Swift.Sequence._filter((A.Element) throws -> Swift.Bool) throws -> Swift.Array' to '(extension in Swift):Swift.Sequence.__abi__filter((A.Element) throws -> Swift.Bool) throws -> Swift.Array' +Func Sequence.filter(_:) has been renamed to Func __abi_filter(_:) +Func Sequence.filter(_:) has mangled name changing from '(extension in Swift):Swift.Sequence.filter((A.Element) throws -> Swift.Bool) throws -> Swift.Array' to '(extension in Swift):Swift.Sequence.__abi_filter((A.Element) throws -> Swift.Bool) throws -> Swift.Array' + +// Adoption of typed throws for Sequence.forEach(_:) +Func Sequence.forEach(_:) has been renamed to Func __abi_forEach(_:) +Func Sequence.forEach(_:) has mangled name changing from '(extension in Swift):Swift.Sequence.forEach((A.Element) throws -> ()) throws -> ()' to '(extension in Swift):Swift.Sequence.__abi_forEach((A.Element) throws -> ()) throws -> ()' + +// Adoption of typed throws for Sequence.reduce(_:_:) +Func Sequence.reduce(_:_:) has been renamed to Func __abi_reduce(_:_:) +Func Sequence.reduce(_:_:) has mangled name changing from '(extension in Swift):Swift.Sequence.reduce(A1, (A1, A.Element) throws -> A1) throws -> A1' to '(extension in Swift):Swift.Sequence.__abi_reduce(A1, (A1, A.Element) throws -> A1) throws -> A1' + +// Adoption of typed throws for Sequence.reduce(into:_:) +Func Sequence.reduce(into:_:) has been renamed to Func __abi_reduce(into:_:) +Func Sequence.reduce(into:_:) has mangled name changing from '(extension in Swift):Swift.Sequence.reduce(into: __owned A1, _: (inout A1, A.Element) throws -> ()) throws -> A1' to '(extension in Swift):Swift.Sequence.__abi_reduce(into: __owned A1, _: (inout A1, A.Element) throws -> ()) throws -> A1' + +// Adoption of typed throws for _NativeDictionary.mapValues(_:) +Func _NativeDictionary.mapValues(_:) has been renamed to Func __abi_mapValues(_:) +Func _NativeDictionary.mapValues(_:) has mangled name changing from 'Swift._NativeDictionary.mapValues((B) throws -> A1) throws -> Swift._NativeDictionary' to 'Swift._NativeDictionary.__abi_mapValues((B) throws -> A1) throws -> Swift._NativeDictionary' + +// Adoption of typed throws for __CocoaDictionary.mapValues(_:) +Func __CocoaDictionary.mapValues(_:) has been renamed to Func __abi_mapValues(_:) +Func __CocoaDictionary.mapValues(_:) has mangled name changing from 'Swift.__CocoaDictionary.mapValues((B) throws -> C) throws -> Swift._NativeDictionary' to 'Swift.__CocoaDictionary.__abi_mapValues((B) throws -> C) throws -> Swift._NativeDictionary' + // *** DO NOT DISABLE OR XFAIL THIS TEST. *** (See comment above.) From a25a383e0ce9eaf5845ea2202460a4dbc4cb148c Mon Sep 17 00:00:00 2001 From: Alejandro Alonso Date: Wed, 4 Dec 2024 12:56:58 -0800 Subject: [PATCH 2/7] Remove generalization of the result for Sequence.reduce --- stdlib/public/core/SequenceAlgorithms.swift | 10 +++++----- .../stability-stdlib-source-base.swift.expected | 5 ++--- 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/stdlib/public/core/SequenceAlgorithms.swift b/stdlib/public/core/SequenceAlgorithms.swift index 9ed0a261928f4..a43d004d9fc0e 100644 --- a/stdlib/public/core/SequenceAlgorithms.swift +++ b/stdlib/public/core/SequenceAlgorithms.swift @@ -665,9 +665,9 @@ extension Sequence { /// /// - Complexity: O(*n*), where *n* is the length of the sequence. @_alwaysEmitIntoClient - public func reduce( - _ initialResult: consuming Result, - _ nextPartialResult: (borrowing Result, Element) throws(E) -> Result + public func reduce( + _ initialResult: Result, + _ nextPartialResult: (Result, Element) throws(E) -> Result ) throws(E) -> Result { var accumulator = initialResult for element in self { @@ -721,8 +721,8 @@ extension Sequence { /// /// - Complexity: O(*n*), where *n* is the length of the sequence. @_alwaysEmitIntoClient - public func reduce( - into initialResult: consuming Result, + public func reduce( + into initialResult: __owned Result, _ updateAccumulatingResult: (inout Result, Element) throws(E) -> () ) throws(E) -> Result { var accumulator = initialResult diff --git a/test/api-digester/Outputs/stability-stdlib-source-base.swift.expected b/test/api-digester/Outputs/stability-stdlib-source-base.swift.expected index 70871a6850179..be67b4e3212db 100644 --- a/test/api-digester/Outputs/stability-stdlib-source-base.swift.expected +++ b/test/api-digester/Outputs/stability-stdlib-source-base.swift.expected @@ -393,11 +393,10 @@ Func Sequence.forEach(_:) has generic signature change from to -Func Sequence.reduce(_:_:) has parameter 0 changing from Default to Owned +Func Sequence.reduce(_:_:) has generic signature change from to Func Sequence.reduce(_:_:) is now without @rethrows // Adoption of typed throws for Sequence.reduce(into:_:) -Func Sequence.reduce(into:_:) has generic signature change from to +Func Sequence.reduce(into:_:) has generic signature change from to Func Sequence.reduce(into:_:) has parameter 1 type change from (inout Result, Self.Element) throws -> () to (inout Result, Self.Element) throws(E) -> () Func Sequence.reduce(into:_:) is now without @rethrows From 8dc064d8bd573f0c214707f79d6366fd43e9bf87 Mon Sep 17 00:00:00 2001 From: Alejandro Alonso Date: Wed, 4 Dec 2024 12:58:01 -0800 Subject: [PATCH 3/7] CocoaDictionary only available in objc runtime --- stdlib/public/core/LegacyABI.swift | 2 ++ 1 file changed, 2 insertions(+) diff --git a/stdlib/public/core/LegacyABI.swift b/stdlib/public/core/LegacyABI.swift index b2354db30fc8c..f2027c8cd4bae 100644 --- a/stdlib/public/core/LegacyABI.swift +++ b/stdlib/public/core/LegacyABI.swift @@ -153,6 +153,7 @@ extension Dictionary._Variant { } } +#if _runtime(_ObjC) extension __CocoaDictionary { @usableFromInline @_silgen_name("$ss17__CocoaDictionaryV9mapValuesys07_NativeB0Vyxq0_Gq0_q_KXEKSHRzr1_lF") @@ -168,6 +169,7 @@ extension __CocoaDictionary { return result } } +#endif extension _NativeDictionary { @usableFromInline From 59e497668bc8296f3f4cc3a593fffb30aec7b45f Mon Sep 17 00:00:00 2001 From: Alejandro Alonso Date: Tue, 13 May 2025 10:10:18 -0700 Subject: [PATCH 4/7] Update LegacyABI.swift --- stdlib/public/core/LegacyABI.swift | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/stdlib/public/core/LegacyABI.swift b/stdlib/public/core/LegacyABI.swift index f2027c8cd4bae..35729c053ba2b 100644 --- a/stdlib/public/core/LegacyABI.swift +++ b/stdlib/public/core/LegacyABI.swift @@ -177,15 +177,15 @@ extension _NativeDictionary { internal func __abi_mapValues( _ transform: (Value) throws -> T ) rethrows -> _NativeDictionary { - let resultStorage = _DictionaryStorage.copy(original: _storage) - _internalInvariant(resultStorage._seed == _storage._seed) - let result = _NativeDictionary(resultStorage) + let resultStorage = unsafe _DictionaryStorage.copy(original: _storage) + unsafe _internalInvariant(resultStorage._seed == _storage._seed) + let result = unsafe _NativeDictionary(resultStorage) // Because the current and new buffer have the same scale and seed, we can // initialize to the same locations in the new buffer, skipping hash value // recalculations. - for bucket in hashTable { - let key = self.uncheckedKey(at: bucket) - let value = self.uncheckedValue(at: bucket) + for unsafe bucket in unsafe hashTable { + let key = unsafe self.uncheckedKey(at: bucket) + let value = unsafe self.uncheckedValue(at: bucket) try result._insert(at: bucket, key: key, value: transform(value)) } return result From 940fe65399c729cb8c789a469ab1225aa4feddcb Mon Sep 17 00:00:00 2001 From: Alejandro Alonso Date: Thu, 22 May 2025 13:49:04 -0700 Subject: [PATCH 5/7] Resolve a few tests relying on the old signatures --- lib/SILOptimizer/LoopTransforms/ForEachLoopUnroll.cpp | 7 ++++--- test/Constraints/diagnostics.swift | 3 ++- test/Constraints/issue-55410.swift | 4 +++- test/Constraints/pack-expansion-expressions.swift | 2 +- test/Constraints/tuple-arguments-unsupported.swift | 4 ++-- test/Constraints/tuple_arguments.swift | 2 +- test/IDE/complete_from_stdlib.swift | 2 +- 7 files changed, 14 insertions(+), 10 deletions(-) diff --git a/lib/SILOptimizer/LoopTransforms/ForEachLoopUnroll.cpp b/lib/SILOptimizer/LoopTransforms/ForEachLoopUnroll.cpp index 0b12222f412b0..5de7f76f9199e 100644 --- a/lib/SILOptimizer/LoopTransforms/ForEachLoopUnroll.cpp +++ b/lib/SILOptimizer/LoopTransforms/ForEachLoopUnroll.cpp @@ -394,7 +394,7 @@ void ArrayInfo::getLastDestroys( /// not clean up any resulting dead instructions. static void removeForEachCall(TryApplyInst *forEachCall, InstructionDeleter &deleter) { - auto *sbi = cast(forEachCall->getArgument(1)); + auto *sbi = cast(forEachCall->getArgument(2)); auto *asi = cast(sbi->getDest()); // The allocStack will be used in the forEach call and also in a store // instruction and a dealloc_stack instruction. Force delete all of them. @@ -440,7 +440,8 @@ static void unrollForEach(ArrayInfo &arrayInfo, TryApplyInst *forEachCall, SILFunction *fun = forEachCall->getFunction(); SILLocation forEachLoc = forEachCall->getLoc(); - SILValue forEachBodyClosure = forEachCall->getArgument(0); + SILValue typedThrowValue = forEachCall->getArgument(0); + SILValue forEachBodyClosure = forEachCall->getArgument(1); SILType arrayElementType = arrayInfo.getElementSILType(); SILFunctionType *bodyClosureType = @@ -582,7 +583,7 @@ static void unrollForEach(ArrayInfo &arrayInfo, TryApplyInst *forEachCall, // elements of address-only type. All elements in the array are guaranteed // to be loadable. TODO: generalize this to address-only types. unrollBuilder.createTryApply(forEachLoc, forEachBodyClosure, - SubstitutionMap(), addr, nextNormalBB, + SubstitutionMap(), {typedThrowValue, addr}, nextNormalBB, errorTarget); if (nextNormalBB == normalBB) { diff --git a/test/Constraints/diagnostics.swift b/test/Constraints/diagnostics.swift index faf9971ef5a6f..5a73f41b56714 100644 --- a/test/Constraints/diagnostics.swift +++ b/test/Constraints/diagnostics.swift @@ -1127,7 +1127,8 @@ func rdar17170728() { } let _ = [i, j, k].reduce(0 as Int?) { // expected-error {{missing argument label 'into:' in call}} - // expected-error@-1 {{cannot convert value of type 'Int?' to expected argument type '(inout (Bool, Bool) -> Bool?, Int?) throws -> ()'}} + // expected-error@-1 {{cannot convert value of type 'Int?' to expected argument type '(inout (Bool, Bool) -> Bool?, Int?) throws(E) -> ()'}} + // expected-error@-2 {{generic parameter 'E' could not be inferred}} $0 && $1 ? $0 + $1 : ($0 ? $0 : ($1 ? $1 : nil)) // expected-error@-1 {{binary operator '+' cannot be applied to two 'Bool' operands}} } diff --git a/test/Constraints/issue-55410.swift b/test/Constraints/issue-55410.swift index cd22ff5d2dbae..1cb9c77929fc2 100644 --- a/test/Constraints/issue-55410.swift +++ b/test/Constraints/issue-55410.swift @@ -5,4 +5,6 @@ protocol P {} typealias T = (P) -> Void let x: T! = [1, 2, 3].reversed().reduce() -// expected-error@-1 {{missing arguments for parameters #1, #2 in call}} +// expected-error@-1 {{no exact matches in call to instance method 'reduce'}} +// expected-note@-2 {{found candidate with type '(Optional, (Optional, Int) throws(_) -> Optional) throws(_) -> Optional' (aka '(Optional<(any P) -> ()>, (Optional<(any P) -> ()>, Int) throws(_) -> Optional<(any P) -> ()>) throws(_) -> Optional<(any P) -> ()>')}} +// expected-note@-3 {{found candidate with type '(__owned Optional, (inout Optional, Int) throws(_) -> ()) throws(_) -> Optional' (aka '(__owned Optional<(any P) -> ()>, (inout Optional<(any P) -> ()>, Int) throws(_) -> ()) throws(_) -> Optional<(any P) -> ()>')}} diff --git a/test/Constraints/pack-expansion-expressions.swift b/test/Constraints/pack-expansion-expressions.swift index f05040f17219d..be106f42e405e 100644 --- a/test/Constraints/pack-expansion-expressions.swift +++ b/test/Constraints/pack-expansion-expressions.swift @@ -72,7 +72,7 @@ func forEachEach(c: repeat each C, function: (U) -> Void) where repeat each C: Collection, repeat (each C).Element == U { // expected-error@-1{{same-element requirements are not yet supported}} _ = (repeat (each c).forEach(function)) - // expected-error@-1 {{cannot convert value of type '(U) -> Void' to expected argument type '((each C).Element) throws -> Void'}} + // expected-error@-1 {{cannot convert value of type '(U) -> Void' to expected argument type '((each C).Element) -> Void'}} } func typeReprPacks(_ t: repeat each T) { diff --git a/test/Constraints/tuple-arguments-unsupported.swift b/test/Constraints/tuple-arguments-unsupported.swift index 6954355f1bca7..b66a28a8b8a03 100644 --- a/test/Constraints/tuple-arguments-unsupported.swift +++ b/test/Constraints/tuple-arguments-unsupported.swift @@ -11,9 +11,9 @@ test3(.success()) // expected-error {{missing argument for parameter #1 in call} func toString(indexes: Int?...) -> String { let _ = indexes.reduce(0) { print($0); return $0.0 + ($0.1 ?? 0)} - // expected-error@-1 {{contextual closure type '(Int, Int?) throws -> Int' expects 2 arguments, but 1 was used in closure body}} + // expected-error@-1 {{contextual closure type '(Int, Int?) -> Int' expects 2 arguments, but 1 was used in closure body}} let _ = indexes.reduce(0) { (true ? $0 : (1, 2)).0 + ($0.1 ?? 0) } - // expected-error@-1 {{contextual closure type '(Int, Int?) throws -> Int' expects 2 arguments, but 1 was used in closure body}} + // expected-error@-1 {{contextual closure type '(Int, Int?) -> Int' expects 2 arguments, but 1 was used in closure body}} _ = ["Hello", "Foo"].sorted { print($0); return $0.0.count > ($0).1.count } // expected-error@-1 {{contextual closure type '(String, String) throws -> Bool' expects 2 arguments, but 1 was used in closure body}} } diff --git a/test/Constraints/tuple_arguments.swift b/test/Constraints/tuple_arguments.swift index a24c78a443458..f14fc4f20b8ae 100644 --- a/test/Constraints/tuple_arguments.swift +++ b/test/Constraints/tuple_arguments.swift @@ -1422,7 +1422,7 @@ func processArrayOfFunctions(f1: [((Bool, Bool)) -> ()], } f2.forEach { (block: ((Bool, Bool)) -> ()) in - // expected-error@-1 {{cannot convert value of type '(((Bool, Bool)) -> ()) -> Void' to expected argument type '(@escaping (Bool, Bool) -> ()) throws -> Void'}} + // expected-error@-1 {{cannot convert value of type '(((Bool, Bool)) -> ()) -> Void' to expected argument type '(@escaping (Bool, Bool) -> ()) -> Void'}} block(p) block((c, c)) block(c, c) // expected-error {{parameter 'block' expects a single parameter of type '(Bool, Bool)'}} diff --git a/test/IDE/complete_from_stdlib.swift b/test/IDE/complete_from_stdlib.swift index e9ffdfa963584..4f0edcb311aa7 100644 --- a/test/IDE/complete_from_stdlib.swift +++ b/test/IDE/complete_from_stdlib.swift @@ -74,7 +74,7 @@ func testArchetypeReplacement2(_ a: [BAR]) { // PRIVATE_NOMINAL_MEMBERS_6-DAG: Decl[InstanceMethod]/Super/IsSystem: min({#by: (Equatable, Equatable) throws -> Bool##(Equatable, Equatable) throws -> Bool#})[' rethrows'][#Equatable?#]{{; name=.+}} // PRIVATE_NOMINAL_MEMBERS_6-DAG: Decl[InstanceMethod]/Super/IsSystem: max({#by: (Equatable, Equatable) throws -> Bool##(Equatable, Equatable) throws -> Bool#})[' rethrows'][#Equatable?#]{{; name=.+}} // FIXME: The following should include 'partialResult' as local parameter name: "(nextPartialResult): (_ partialResult: Result, Equatable)" -// PRIVATE_NOMINAL_MEMBERS_6-DAG: Decl[InstanceMethod]/Super/IsSystem: reduce({#(initialResult): Result#}, {#(nextPartialResult): (Result, Equatable) throws -> Result##(_ partialResult: Result, Equatable) throws -> Result#})[' rethrows'][#Result#]{{; name=.+}} +// PRIVATE_NOMINAL_MEMBERS_6-DAG: Decl[InstanceMethod]/Super/IsSystem: reduce({#(initialResult): Result#}, {#(nextPartialResult): (Result, Equatable) throws(Error) -> Result##(Result, Equatable) throws(Error) -> Result#})[' throws'][#Result#]{{; name=.+}} // PRIVATE_NOMINAL_MEMBERS_6-DAG: Decl[InstanceMethod]/Super/IsSystem: dropFirst({#(k): Int#})[#ArraySlice#]{{; name=.+}} // FIXME: restore Decl[InstanceMethod]/Super: flatMap({#(transform): (Equatable) throws -> Sequence##(Equatable) throws -> Sequence#})[' rethrows'][#[IteratorProtocol.Element]#]{{; name=.+}} From 479019a4bd309775300ea90a2d4cd0584c756a0c Mon Sep 17 00:00:00 2001 From: Alejandro Alonso Date: Tue, 27 May 2025 09:52:28 -0700 Subject: [PATCH 6/7] Update for_each_loop_unroll_test.swift --- .../for_each_loop_unroll_test.swift | 20 +++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/test/SILOptimizer/for_each_loop_unroll_test.swift b/test/SILOptimizer/for_each_loop_unroll_test.swift index 4730227681262..d1520f8371309 100644 --- a/test/SILOptimizer/for_each_loop_unroll_test.swift +++ b/test/SILOptimizer/for_each_loop_unroll_test.swift @@ -12,13 +12,14 @@ func unrollLetArrayLiteralTest() { // CHECK: [[LIT2:%[0-9]+]] = integer_literal $Builtin.Int64, 27 // CHECK: [[INT2:%[0-9]+]] = struct $Int64 ([[LIT2]] : $Builtin.Int64) // CHECK-NOT: forEach + // CHECK: [[NEVER:%[0-9]+]] = alloc_stack $Never // CHECK: [[STACK:%[0-9]+]] = alloc_stack $Int64 // CHECK: store [[INT1]] to [[STACK]] - // CHECK: try_apply %{{.*}}([[STACK]]) : {{.*}}, normal [[NORMAL:bb[0-9]+]], error [[ERROR:bb[0-9]+]] + // CHECK: try_apply %{{.*}}([[NEVER]], [[STACK]]) : {{.*}}, normal [[NORMAL:bb[0-9]+]], error [[ERROR:bb[0-9]+]] // CHECK: [[NORMAL]](%{{.*}} : $()): // CHECK: store [[INT2]] to [[STACK]] : $*Int64 - // CHECK: try_apply {{.*}}([[STACK]]) + // CHECK: try_apply {{.*}}([[NEVER]], [[STACK]]) } // CHECK-LABEL: sil hidden @$s25for_each_loop_unroll_test0D35LetArrayLiteralWithVariableElements1x1yys5Int64V_AFtF @@ -26,13 +27,14 @@ func unrollLetArrayLiteralWithVariableElements(x: Int64, y: Int64) { let a = [x, y] a.forEach { print($0) } // CHECK-NOT: forEach + // CHECK: [[NEVER:%[0-9]+]] = alloc_stack $Never // CHECK: [[STACK:%[0-9]+]] = alloc_stack $Int64 // CHECK: store %0 to [[STACK]] - // CHECK: try_apply %{{.*}}([[STACK]]) : {{.*}}, normal [[NORMAL:bb[0-9]+]], error [[ERROR:bb[0-9]+]] + // CHECK: try_apply %{{.*}}([[NEVER]], [[STACK]]) : {{.*}}, normal [[NORMAL:bb[0-9]+]], error [[ERROR:bb[0-9]+]] // CHECK: [[NORMAL]](%{{.*}} : $()): // CHECK: store %1 to [[STACK]] : $*Int64 - // CHECK: try_apply {{.*}}([[STACK]]) + // CHECK: try_apply {{.*}}([[NEVER]], [[STACK]]) } // CHECK-LABEL: sil hidden @$s25for_each_loop_unroll_test0D37LetArrayLiteralWithNonTrivialElementsyyF @@ -48,13 +50,14 @@ func unrollLetArrayLiteralWithNonTrivialElements() { // CHECK: [[STRING2:%[0-9]+]] = apply [[STRING_INIT2]]([[LIT2]], // CHECK-NOT: forEach + // CHECK: [[NEVER:%[0-9]+]] = alloc_stack $Never // CHECK: [[STACK:%[0-9]+]] = alloc_stack $String // CHECK: store [[STRING1]] to [[STACK]] : $*String - // CHECK: try_apply %{{.*}}([[STACK]]) : {{.*}}, normal [[NORMAL:bb[0-9]+]], error [[ERROR:bb[0-9]+]] + // CHECK: try_apply %{{.*}}([[NEVER]], [[STACK]]) : {{.*}}, normal [[NORMAL:bb[0-9]+]], error [[ERROR:bb[0-9]+]] // CHECK: [[NORMAL]](%{{.*}} : $()): // CHECK: store [[STRING2]] to [[STACK]] : $*String - // CHECK: try_apply {{.*}}([[STACK]]) + // CHECK: try_apply {{.*}}([[NEVER]], [[STACK]]) } // This test mimics the array literal and forEach created by the OSLogOptimization pass. @@ -73,13 +76,14 @@ func unrollLetArrayLiteralWithClosures(i: Int32, j: Int32) { // CHECK: store [[CLOSURE2:%[0-9]+]] to [[INDEX1]] // CHECK-NOT: forEach + // CHECK: [[NEVER:%[0-9]+]] = alloc_stack $Never // CHECK: [[STACK:%[0-9]+]] = alloc_stack // CHECK: store [[CLOSURE1]] to [[STACK]] - // CHECK: try_apply %{{.*}}([[STACK]]) : ${{.*}}, normal [[NORMAL:bb[0-9]+]], error [[ERROR:bb[0-9]+]] + // CHECK: try_apply %{{.*}}([[NEVER]], [[STACK]]) : ${{.*}}, normal [[NORMAL:bb[0-9]+]], error [[ERROR:bb[0-9]+]] // CHECK: [[NORMAL]](%{{.*}} : $()): // CHECK: store [[CLOSURE2]] to [[STACK]] - // CHECK: try_apply {{.*}}([[STACK]]) + // CHECK: try_apply {{.*}}([[NEVER]], [[STACK]]) } // CHECK-LABEL: sil hidden @$s25for_each_loop_unroll_test0E16NoUnrollScenarioyyF From 56065fe6397634bb635522c0c9ca1212f76c107a Mon Sep 17 00:00:00 2001 From: Alejandro Alonso Date: Tue, 27 May 2025 09:55:00 -0700 Subject: [PATCH 7/7] Update stability-stdlib-source-base.swift.expected --- .../stability-stdlib-source-base.swift.expected | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/test/api-digester/Outputs/stability-stdlib-source-base.swift.expected b/test/api-digester/Outputs/stability-stdlib-source-base.swift.expected index be67b4e3212db..7262a0bbb33c1 100644 --- a/test/api-digester/Outputs/stability-stdlib-source-base.swift.expected +++ b/test/api-digester/Outputs/stability-stdlib-source-base.swift.expected @@ -378,25 +378,25 @@ Func type(of:) has parameter 0 changing from Default to Shared // Adoption of typed throws for Dictionary.compactMapValues(_:) Func Dictionary.compactMapValues(_:) has generic signature change from to -Func Dictionary.compactMapValues(_:) is now without @rethrows +Func Dictionary.compactMapValues(_:) is now without rethrows // Adoption of typed throws for Dictionary.mapValues(_:) Func Dictionary.mapValues(_:) has generic signature change from to -Func Dictionary.mapValues(_:) is now without @rethrows +Func Dictionary.mapValues(_:) is now without rethrows // Adoption of typed throws for Sequence.filter(_:) Func Sequence.filter(_:) has generic signature change from to -Func Sequence.filter(_:) is now without @rethrows +Func Sequence.filter(_:) is now without rethrows // Adoption of typed throws for Sequence.forEach(_:) Func Sequence.forEach(_:) has generic signature change from to -Func Sequence.forEach(_:) is now without @rethrows +Func Sequence.forEach(_:) is now without rethrows // Adoption of typed throws for Sequence.reduce(_:_:) Func Sequence.reduce(_:_:) has generic signature change from to -Func Sequence.reduce(_:_:) is now without @rethrows +Func Sequence.reduce(_:_:) is now without rethrows // Adoption of typed throws for Sequence.reduce(into:_:) Func Sequence.reduce(into:_:) has generic signature change from to Func Sequence.reduce(into:_:) has parameter 1 type change from (inout Result, Self.Element) throws -> () to (inout Result, Self.Element) throws(E) -> () -Func Sequence.reduce(into:_:) is now without @rethrows +Func Sequence.reduce(into:_:) is now without rethrows