@@ -349,6 +349,17 @@ extension _StringGuts {
349349 internal func ensureMatchingEncoding( _ i: Index ) -> Index {
350350 if _fastPath ( hasMatchingEncoding ( i) ) { return i }
351351 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.)
352363 _preconditionFailure ( " Invalid string index " )
353364 }
354365
@@ -380,21 +391,11 @@ extension _StringGuts {
380391 internal func _slowEnsureMatchingEncoding( _ i: Index ) -> Index ? {
381392 guard isUTF8 else {
382393 // 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
386397 // existing binaries running with new stdlibs. If so, we can replace this
387398 // 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`.
398399 return nil
399400 }
400401 // Attempt to use an UTF-16 index on a UTF-8 string.
@@ -416,6 +417,7 @@ extension _StringGuts {
416417 if i. transcodedOffset != 0 {
417418 r = r. encoded ( offsetBy: i. transcodedOffset)
418419 } else {
420+ // Preserve alignment bits if possible.
419421 r = r. _copyingAlignment ( from: i)
420422 }
421423 return r. _knownUTF8
0 commit comments