Skip to content

Commit 51c2bd0

Browse files
committed
stdlib: remove a wrong internal check for COW array mutation
Don't complain if the empty array buffer singleton is set to mutable. This can happen if reserveCapacity is called with a 0-capacity for an empty array. In this case the resulting array is still the empty array singleton. For the compiler, it's safe to treat the empty array singleton as "mutable", because there is never anything written to an array with zero capacity: all mutating array operations do any form of capacity/size > 0 check in addition to the uniqueness check. Unfortunately the empty array singleton sometimes needs such special handling with is not obvious (not to say hacky). This wrong check only fired in very specific optimization scenarios, where the inliner and the COW optimizations must play together in a certain way. I could not find an isolated test case for this problem. rdar://problem/71107908
1 parent 56928ba commit 51c2bd0

File tree

1 file changed

+8
-9
lines changed

1 file changed

+8
-9
lines changed

stdlib/public/core/ContiguousArrayBuffer.swift

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -470,18 +470,17 @@ internal struct _ContiguousArrayBuffer<Element>: _ArrayBufferProtocol {
470470
nonmutating set {
471471
if #available(macOS 9999, iOS 9999, watchOS 9999, tvOS 9999, *) {
472472
if (_COWChecksEnabled()) {
473-
if newValue {
474-
if capacity > 0 {
475-
let wasImmutable = _swift_setImmutableCOWBuffer(_storage, true)
473+
// Make sure to not modify the empty array singleton (which has a
474+
// capacity of 0).
475+
if capacity > 0 {
476+
let wasImmutable = _swift_setImmutableCOWBuffer(_storage, newValue)
477+
if newValue {
476478
_internalInvariant(!wasImmutable,
477479
"re-setting immutable array buffer to immutable")
480+
} else {
481+
_internalInvariant(wasImmutable,
482+
"re-setting mutable array buffer to mutable")
478483
}
479-
} else {
480-
_internalInvariant(capacity > 0,
481-
"setting empty array buffer to mutable")
482-
let wasImmutable = _swift_setImmutableCOWBuffer(_storage, false)
483-
_internalInvariant(wasImmutable,
484-
"re-setting mutable array buffer to mutable")
485484
}
486485
}
487486
}

0 commit comments

Comments
 (0)