-
Notifications
You must be signed in to change notification settings - Fork 10.5k
[stdlib] Make String.makeContiguousUTF8() strictly true #82851
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
37737a1
6211579
77f34f4
3dfdd87
9341973
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -177,15 +177,27 @@ extension StringProtocol { | |
|
||
// Contiguous UTF-8 strings | ||
extension String { | ||
/// Returns whether this string is capable of providing access to | ||
/// validly-encoded UTF-8 contents in contiguous memory in O(1) time. | ||
/// Returns whether this string's storage contains | ||
/// validly-encoded UTF-8 contents in contiguous memory. | ||
/// | ||
/// Contiguous strings always operate in O(1) time for withUTF8 and always | ||
/// give a result for String.UTF8View.withContiguousStorageIfAvailable. | ||
/// Contiguous strings always operate in O(1) time for withUTF8, always give | ||
/// a result for String.UTF8View.withContiguousStorageIfAvailable, and always | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Was this comment actually inaccurate before? Did There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It was not lying: There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. OK. With this returning |
||
/// return a non-nil value from `String._utf8Span` and `String.UTF8View._span`. | ||
/// Contiguous strings also benefit from fast-paths and better optimizations. | ||
/// | ||
@_alwaysEmitIntoClient | ||
public var isContiguousUTF8: Bool { return _guts.isFastUTF8 } | ||
public var isContiguousUTF8: Bool { | ||
if _guts.isFastUTF8 { | ||
#if os(watchOS) && _pointerBitWidth(_32) | ||
// Required for compatibility with some small strings that | ||
// may be encoded in the 32-bit slice of watchOS binaries. | ||
if _guts.isSmall && _guts.count > _SmallString.contiguousCapacity() { | ||
return false | ||
} | ||
#endif | ||
return true | ||
} | ||
return false | ||
} | ||
|
||
/// If this string is not contiguous, make it so. If this mutates the string, | ||
/// it will invalidate any pre-existing indices. | ||
|
@@ -223,13 +235,14 @@ extension String { | |
|
||
// Contiguous UTF-8 strings | ||
extension Substring { | ||
/// Returns whether this string is capable of providing access to | ||
/// validly-encoded UTF-8 contents in contiguous memory in O(1) time. | ||
/// Returns whether this string's storage contains | ||
/// validly-encoded UTF-8 contents in contiguous memory. | ||
/// | ||
/// Contiguous strings always operate in O(1) time for withUTF8 and always | ||
/// give a result for String.UTF8View.withContiguousStorageIfAvailable. | ||
/// Contiguous strings always operate in O(1) time for withUTF8, always give | ||
/// a result for Substring.UTF8View.withContiguousStorageIfAvailable, and | ||
/// always return a non-nil value from `Substring._utf8Span` and | ||
/// `Substring.UTF8View._span`. | ||
/// Contiguous strings also benefit from fast-paths and better optimizations. | ||
/// | ||
@_alwaysEmitIntoClient | ||
public var isContiguousUTF8: Bool { return self.base.isContiguousUTF8 } | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
//===--- SmallStringCompatibility.swift -----------------------------------===// | ||
// | ||
// This source file is part of the Swift.org open source project | ||
// | ||
// Copyright (c) 2025 Apple Inc. and the Swift project authors | ||
// Licensed under Apache License v2.0 with Runtime Library Exception | ||
// | ||
// See https://swift.org/LICENSE.txt for license information | ||
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors | ||
// | ||
//===----------------------------------------------------------------------===// | ||
|
||
// RUN: %target-run-stdlib-swift | ||
|
||
// REQUIRES: executable_test | ||
// REQUIRES: CPU=wasm32 || CPU=arm64_32 | ||
|
||
import StdlibUnittest | ||
|
||
var suite = TestSuite("SmallStringCompatibility") | ||
defer { runAllTests() } | ||
|
||
var strings = [ | ||
("Small", true), | ||
("Less small", true), | ||
("Positively large.", true), | ||
] | ||
|
||
#if os(watchOS) | ||
strings[1].1 = false | ||
#endif | ||
|
||
strings.forEach { (string, contiguous) in | ||
suite.test("Contiguous: \(string)") | ||
.require(.stdlib_6_2).code { | ||
|
||
expectEqual(string.isContiguousUTF8, contiguous) | ||
} | ||
} | ||
|
||
strings.forEach { (string, contiguous) in | ||
suite.test("Contiguous Substring: \(string)") | ||
.require(.stdlib_6_2).code { | ||
let substring = string[...] | ||
expectEqual(substring.isContiguousUTF8, contiguous) | ||
} | ||
} | ||
|
||
strings.forEach { (string, contiguous) in | ||
suite.test("String.makeContiguousUTF8: \(string)") | ||
.require(.stdlib_6_2).code { | ||
var s = string | ||
s.makeContiguousUTF8() | ||
expectTrue(s.isContiguousUTF8) | ||
expectEqual(s, string) | ||
} | ||
} | ||
|
||
strings.forEach { (string, contiguous) in | ||
suite.test("Substring.makeContiguousUTF8: \(string)") | ||
.require(.stdlib_6_2).code { | ||
var s: Substring = string.dropFirst().dropLast() | ||
s.makeContiguousUTF8() | ||
expectTrue(s.isContiguousUTF8) | ||
expectEqual(s, string.dropFirst().dropLast()) | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In non-watchOS or 64-bit environments, will the compiler not complain about this
var
being unmutated?Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I didn't notice it complaining when building on macOS. Apparently it knows to consider statements that are conditionally skipped: https://swift.godbolt.org/z/aT1naWfce