@@ -423,6 +423,24 @@ extension String {
423
423
return
424
424
}
425
425
426
+ // Fast path for user-defined Collections and typed contiguous collections.
427
+ //
428
+ // Note: this comes first, as the optimizer nearly always has insight into
429
+ // wCSIA, but cannot prove that a type does not have conformance to
430
+ // _HasContiguousBytes.
431
+ if let str = codeUnits. withContiguousStorageIfAvailable ( {
432
+ ( buffer: UnsafeBufferPointer < C . Element > ) -> String in
433
+ Builtin . onFastPath ( ) // encourage SIL Optimizer to inline this closure :-(
434
+ let rawBufPtr = UnsafeRawBufferPointer ( buffer)
435
+ return String . _fromUTF8Repairing (
436
+ UnsafeBufferPointer (
437
+ start: rawBufPtr. baseAddress? . assumingMemoryBound ( to: UInt8 . self) ,
438
+ count: rawBufPtr. count) ) . 0
439
+ } ) {
440
+ self = str
441
+ return
442
+ }
443
+
426
444
// Fast path for untyped raw storage and known stdlib types
427
445
if let contigBytes = codeUnits as? _HasContiguousBytes ,
428
446
contigBytes. _providesContiguousBytesNoCopy
@@ -436,16 +454,6 @@ extension String {
436
454
return
437
455
}
438
456
439
- // Fast path for user-defined Collections
440
- if let str = codeUnits. withContiguousStorageIfAvailable ( {
441
- ( buffer: UnsafeBufferPointer < C . Element > ) -> String in
442
- return String . _fromUTF8Repairing (
443
- UnsafeRawBufferPointer ( buffer) . bindMemory ( to: UInt8 . self) ) . 0
444
- } ) {
445
- self = str
446
- return
447
- }
448
-
449
457
self = String . _fromNonContiguousUnsafeBitcastUTF8Repairing ( codeUnits) . 0
450
458
}
451
459
0 commit comments