@@ -228,28 +228,38 @@ extension String {
228228 return _slowFromCodeUnits ( input, encoding: encoding, repair: repair)
229229 }
230230
231- // Needed for double-optional due to returning optional string in
232- // _fromASCIIValidating in withContiguousStorageIfAvailable
233- let resultOpt : String ?
231+ // Helper to simplify early returns
232+ func resultOrSlow( _ resultOpt: String ? ) -> ( String , repairsMade: Bool ) ? {
233+ guard let result = resultOpt else {
234+ return _slowFromCodeUnits ( input, encoding: encoding, repair: repair)
235+ }
236+ return ( result, repairsMade: false )
237+ }
234238
239+ // Fast path for untyped raw storage and known stdlib types
240+ if let contigBytes = input as? _HasContiguousBytes ,
241+ contigBytes. _providesContiguousBytesNoCopy {
242+ return resultOrSlow ( contigBytes. withUnsafeBytes { rawBufPtr in
243+ let buffer = UnsafeBufferPointer (
244+ start: rawBufPtr. baseAddress? . assumingMemoryBound ( to: UInt8 . self) ,
245+ count: rawBufPtr. count)
246+ return String . _fromASCIIValidating ( buffer)
247+ } )
248+ }
249+
250+ // Fast path for user-defined Collections
235251 if let strOpt = input. withContiguousStorageIfAvailable ( {
236252 ( buffer: UnsafeBufferPointer < Input . Element > ) -> String ? in
237253 return String . _fromASCIIValidating (
238254 UnsafeRawBufferPointer ( buffer) . bindMemory ( to: UInt8 . self) )
239255 } ) {
240- resultOpt = strOpt
241- } else {
242- resultOpt = Array ( input) . withUnsafeBufferPointer {
243- let buffer = UnsafeRawBufferPointer ( $0) . bindMemory ( to: UInt8 . self)
244- return String . _fromASCIIValidating ( buffer)
245- }
246- }
247-
248- guard let result = resultOpt else {
249- return _slowFromCodeUnits ( input, encoding: encoding, repair: repair)
256+ return resultOrSlow ( strOpt)
250257 }
251258
252- return ( result, repairsMade: false )
259+ return resultOrSlow ( Array ( input) . withUnsafeBufferPointer {
260+ let buffer = UnsafeRawBufferPointer ( $0) . bindMemory ( to: UInt8 . self)
261+ return String . _fromASCIIValidating ( buffer)
262+ } )
253263 }
254264
255265 public // @testable
0 commit comments