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