@@ -349,6 +349,17 @@ extension _StringGuts {
349
349
internal func ensureMatchingEncoding( _ i: Index ) -> Index {
350
350
if _fastPath ( hasMatchingEncoding ( i) ) { return i }
351
351
if let i = _slowEnsureMatchingEncoding ( i) { return i }
352
+ // Note that this trap is not guaranteed to trigger when the process
353
+ // includes client binaries compiled with a previous Swift release.
354
+ // (`i._canBeUTF16` can sometimes return true in that case even if the index
355
+ // actually came from an UTF-8 string.) However, the trap will still often
356
+ // trigger in this case, as long as the index was initialized by code that
357
+ // was compiled with 5.7+.
358
+ //
359
+ // This trap will rarely if ever trigger on OSes that have stdlibs <= 5.6,
360
+ // because those versions never set the `isKnownUTF16` flag in
361
+ // `_StringObject`. (The flag may still be set within inlinable code,
362
+ // though.)
352
363
_preconditionFailure ( " Invalid string index " )
353
364
}
354
365
@@ -380,21 +391,11 @@ extension _StringGuts {
380
391
internal func _slowEnsureMatchingEncoding( _ i: Index ) -> Index ? {
381
392
guard isUTF8 else {
382
393
// Attempt to use an UTF-8 index on a UTF-16 string. Strings don't usually
383
- // get converted to UTF-16 storage, so it seems okay to trap in this case
384
- // -- the index most likely comes from an unrelated string. (Trapping here
385
- // may still turn out to affect binary compatibility with broken code in
394
+ // get converted to UTF-16 storage, so it seems okay to reject this case
395
+ // -- the index most likely comes from an unrelated string. (This may
396
+ // still turn out to affect binary compatibility with broken code in
386
397
// existing binaries running with new stdlibs. If so, we can replace this
387
398
// with the same transcoding hack as in the UTF-16->8 case below.)
388
- //
389
- // Note that this trap is not guaranteed to trigger when the process
390
- // includes client binaries compiled with a previous Swift release.
391
- // (`i._canBeUTF16` can sometimes return true in that case even if the
392
- // index actually came from an UTF-8 string.) However, the trap will still
393
- // often trigger in this case, as long as the index was initialized by
394
- // code that was compiled with 5.7+.
395
- //
396
- // This trap can never trigger on OSes that have stdlibs <= 5.6, because
397
- // those versions never set the `isKnownUTF16` flag in `_StringObject`.
398
399
return nil
399
400
}
400
401
// Attempt to use an UTF-16 index on a UTF-8 string.
@@ -416,6 +417,7 @@ extension _StringGuts {
416
417
if i. transcodedOffset != 0 {
417
418
r = r. encoded ( offsetBy: i. transcodedOffset)
418
419
} else {
420
+ // Preserve alignment bits if possible.
419
421
r = r. _copyingAlignment ( from: i)
420
422
}
421
423
return r. _knownUTF8
0 commit comments