Skip to content

Commit 46518b3

Browse files
authored
Merge pull request #16322 from milseman/4_2_identity_crisis
[4.2][string] Only bridge tagged NSStrings to small string form.
2 parents e55d297 + 7340f11 commit 46518b3

File tree

3 files changed

+76
-18
lines changed

3 files changed

+76
-18
lines changed

stdlib/public/core/StringBridge.swift

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -203,22 +203,6 @@ func _makeCocoaStringGuts(_ cocoaString: _CocoaString) -> _StringGuts {
203203

204204
let length = _StringGuts.getCocoaLength(
205205
_unsafeBitPattern: Builtin.reinterpretCast(immutableCopy))
206-
207-
// TODO(SSO): And also for UTF-16 strings and non-contiguous strings
208-
if let ptr = start, !isUTF16 && length <= _SmallUTF8String.capacity {
209-
if let small = _SmallUTF8String(
210-
UnsafeBufferPointer(
211-
start: ptr.assumingMemoryBound(to: UInt8.self), count: length)
212-
) {
213-
return _StringGuts(small)
214-
} else {
215-
#if arch(i386) || arch(arm)
216-
#else
217-
_sanityCheckFailure("Couldn't fit 15-char ASCII small string?")
218-
#endif
219-
}
220-
}
221-
222206
return _StringGuts(
223207
_largeNonTaggedCocoaObject: immutableCopy,
224208
count: length,

stdlib/public/core/StringStorage.swift

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -62,8 +62,10 @@ where CodeUnit : UnsignedInteger & FixedWidthInteger {
6262

6363
#if arch(i386) || arch(arm)
6464
#else
65-
_sanityCheck((CodeUnit.self != UInt8.self || capacity > 15),
66-
"Should prefer a small representation")
65+
// TODO(SR-7594): Restore below invariant
66+
// _sanityCheck(
67+
// CodeUnit.self != UInt8.self || capacity > _SmallUTF8String.capacity,
68+
// "Should prefer a small representation")
6769
#endif // 64-bit
6870

6971
let storage = Builtin.allocWithTailElems_1(

test/stdlib/StringBridge.swift

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
// RUN: %target-run-simple-swift
2+
// REQUIRES: executable_test
3+
4+
// REQUIRES: objc_interop
5+
6+
import Foundation
7+
import StdlibUnittest
8+
9+
var StringBridgeTests = TestSuite("StringBridgeTests")
10+
11+
extension String {
12+
init(fromCocoa s: String) {
13+
self = (s as NSString) as String
14+
}
15+
16+
17+
}
18+
19+
func expectSmall(_ str: String,
20+
stackTrace: SourceLocStack = SourceLocStack(),
21+
showFrame: Bool = true,
22+
file: String = #file, line: UInt = #line
23+
) {
24+
expectTrue(str._guts._isSmall,
25+
stackTrace: stackTrace, showFrame: showFrame, file: file, line: line)
26+
}
27+
func expectCocoa(_ str: String,
28+
stackTrace: SourceLocStack = SourceLocStack(),
29+
showFrame: Bool = true,
30+
file: String = #file, line: UInt = #line
31+
) {
32+
expectTrue(str._guts._isCocoa,
33+
stackTrace: stackTrace, showFrame: showFrame, file: file, line: line)
34+
}
35+
36+
StringBridgeTests.test("Tagged NSString") {
37+
#if arch(i386) || arch(arm)
38+
#else
39+
// Bridge tagged strings as small
40+
expectSmall((("0123456" as NSString) as String))
41+
expectSmall((("012345678" as NSString) as String))
42+
expectSmall((("aaaaaaaaaaa" as NSString) as String))
43+
expectSmall((("bbbbbbbbb" as NSString) as String))
44+
45+
// Bridge non-tagged as non-small even if they fit, for fear of losing
46+
// associated information
47+
let bigAs = ("aaaaaaaaaaaa" as NSString) as String
48+
let bigBs = ("bbbbbbbbbb" as NSString) as String
49+
let bigQs = ("????????" as NSString) as String
50+
expectCocoa(bigAs)
51+
expectCocoa(bigBs)
52+
expectCocoa(bigQs)
53+
54+
#if false // TODO(SR-7594): re-enable
55+
let littleAsNSString = ("aa" as NSString)
56+
var littleAs = littleAsNSString as String
57+
58+
// But become small when appended to
59+
expectSmall(bigAs + "c")
60+
expectSmall(bigBs + "c")
61+
expectSmall("a\(bigAs)")
62+
expectSmall("a\(bigBs)")
63+
expectSmall(littleAs + bigQs)
64+
expectSmall(bigQs + littleAs)
65+
expectSmall("\(littleAs)bigQs\(littleAs)")
66+
#endif // false
67+
68+
#endif // not 32bit
69+
}
70+
71+
runAllTests()
72+

0 commit comments

Comments
 (0)