diff --git a/stdlib/public/core/UnicodeScalarProperties.swift b/stdlib/public/core/UnicodeScalarProperties.swift index c08e41cacea91..d0c39c2efee3b 100644 --- a/stdlib/public/core/UnicodeScalarProperties.swift +++ b/stdlib/public/core/UnicodeScalarProperties.swift @@ -692,15 +692,14 @@ extension Unicode.Scalar.Properties { /// all current case mappings. In the event more space is needed, it will be /// allocated on the heap. internal func _applyMapping(_ u_strTo: _U_StrToX) -> String { - // TODO(String performance): Stack buffer first and then detect real count - let count = 64 - var array = Array(repeating: 0, count: count) - let len: Int = array.withUnsafeMutableBufferPointer { bufPtr in + // Allocate 16 code units on the stack. + var fixedArray = _FixedArray16(allZeros: ()) + let count: Int = fixedArray.withUnsafeMutableBufferPointer { buf in return _scalar.withUTF16CodeUnits { utf16 in var err = __swift_stdlib_U_ZERO_ERROR let correctSize = u_strTo( - bufPtr.baseAddress._unsafelyUnwrappedUnchecked, - Int32(bufPtr.count), + buf.baseAddress._unsafelyUnwrappedUnchecked, + Int32(buf.count), utf16.baseAddress._unsafelyUnwrappedUnchecked, Int32(utf16.count), "", @@ -708,13 +707,36 @@ extension Unicode.Scalar.Properties { guard err.isSuccess else { fatalError("Unexpected error case-converting Unicode scalar.") } - // TODO: _internalInvariant(count == correctSize, "inconsistent ICU behavior") return Int(correctSize) } } - // TODO: replace `len` with `count` - return array[..(unsafeUninitializedCapacity: count) { + buf, initializedCount in + _scalar.withUTF16CodeUnits { utf16 in + var err = __swift_stdlib_U_ZERO_ERROR + let correctSize = u_strTo( + buf.baseAddress._unsafelyUnwrappedUnchecked, + Int32(buf.count), + utf16.baseAddress._unsafelyUnwrappedUnchecked, + Int32(utf16.count), + "", + &err) + guard err.isSuccess else { + fatalError("Unexpected error case-converting Unicode scalar.") + } + _internalInvariant(count == correctSize, "inconsistent ICU behavior") + initializedCount = count + } + } + return array.withUnsafeBufferPointer { + String._uncheckedFromUTF16($0) } }