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