Actually slice things in _StringGutsSlice

This commit is contained in:
David Smith
2022-05-17 13:06:45 -07:00
parent 47721d25e6
commit 9dd8d3ad1a
2 changed files with 38 additions and 5 deletions

View File

@@ -946,10 +946,11 @@ extension _StringGutsSlice {
}
internal func _withNFCCodeUnits(_ f: (UInt8) throws -> Void) rethrows {
let substring = String(_guts)[range]
// Fast path: If we're already NFC (or ASCII), then we don't need to do
// anything at all.
if _fastPath(_guts.isNFC) {
try String(_guts).utf8.forEach(f)
try substring.utf8.forEach(f)
return
}
@@ -962,7 +963,7 @@ extension _StringGutsSlice {
// Because we have access to the fastUTF8, we can go through that instead
// of accessing the UTF8 view on String.
if isNFCQC {
try _guts.withFastUTF8 {
try withFastUTF8 {
for byte in $0 {
try f(byte)
}
@@ -971,7 +972,7 @@ extension _StringGutsSlice {
return
}
} else {
for scalar in String(_guts).unicodeScalars {
for scalar in substring.unicodeScalars {
if !_isScalarNFCQC(scalar, &prevCCC) {
isNFCQC = false
break
@@ -979,7 +980,7 @@ extension _StringGutsSlice {
}
if isNFCQC {
for byte in String(_guts).utf8 {
for byte in substring.utf8 {
try f(byte)
}
@@ -987,7 +988,7 @@ extension _StringGutsSlice {
}
}
for scalar in String(_guts)._internalNFC {
for scalar in substring._internalNFC {
try scalar.withUTF8CodeUnits {
for byte in $0 {
try f(byte)

View File

@@ -158,6 +158,28 @@ func checkStringComparison(
expectEqual(expected.isGT(), lhs > rhs, stackTrace: stackTrace)
checkComparable(expected, lhs, rhs, stackTrace: stackTrace.withCurrentLoc())
// Substring / Substring
// Matching slices of != Strings may still be ==, but not vice versa
if expected.isEQ() {
for i in 0 ..< Swift.min(lhs.count, rhs.count) {
let lhsSub = lhs.dropFirst(i)
let rhsSub = rhs.dropFirst(i)
expectEqual(expected.isEQ(), lhsSub == rhsSub, stackTrace: stackTrace)
expectEqual(expected.isNE(), lhsSub != rhsSub, stackTrace: stackTrace)
checkHashable(
expectedEqual: expected.isEQ(),
lhs, rhs, stackTrace: stackTrace.withCurrentLoc())
expectEqual(expected.isLT(), lhsSub < rhsSub, stackTrace: stackTrace)
expectEqual(expected.isLE(), lhsSub <= rhsSub, stackTrace: stackTrace)
expectEqual(expected.isGE(), lhsSub >= rhsSub, stackTrace: stackTrace)
expectEqual(expected.isGT(), lhsSub > rhsSub, stackTrace: stackTrace)
checkComparable(
expected, lhsSub, rhsSub, stackTrace: stackTrace.withCurrentLoc())
}
}
#if _runtime(_ObjC)
// NSString / NSString
let lhsNSString = lhs as NSString
@@ -471,5 +493,15 @@ StringTests.test("Regression/corelibs-foundation") {
expectEqual(substring(of: s5, with: NSFakeRange(1,6)), "\ncats<EFBFBD>")
}
StringTests.test("Regression/radar-87371813") {
let s1 = "what♕/".dropFirst(5)
let s2 = "/"[...]
let s3 = "/⚅".dropLast()
expectEqual(s1, s2)
expectEqual(s1, s3)
expectEqual(s1, s3)
expectEqual(s1.hashValue, s2.hashValue)
expectEqual(s2.hashValue, s3.hashValue)
}
runAllTests()