@@ -355,6 +355,17 @@ extension Array {
355355 }
356356 }
357357
358+ #if INTERNAL_CHECKS_ENABLED && COW_CHECKS_ENABLED
359+ @inlinable
360+ @_semantics ( " array.make_mutable " )
361+ @_effects ( notEscaping self.** )
362+ internal mutating func _makeMutableAndUniqueUnchecked( ) {
363+ if _slowPath ( !_buffer. beginCOWMutationUnchecked ( ) ) {
364+ _buffer = _buffer. _consumeAndCreateNew ( )
365+ }
366+ }
367+ #endif
368+
358369 /// Marks the end of an Array mutation.
359370 ///
360371 /// After a call to `_endMutation` the buffer must not be mutated until a call
@@ -1737,10 +1748,15 @@ extension Array {
17371748 @lifetime ( & self )
17381749 @_alwaysEmitIntoClient
17391750 mutating get {
1751+ // _makeMutableAndUnique*() inserts begin_cow_mutation.
1752+ // LifetimeDependence analysis inserts call to end_cow_mutation_addr since we cannot schedule it in the stdlib for mutableSpan property.
1753+ #if INTERNAL_CHECKS_ENABLED && COW_CHECKS_ENABLED
1754+ // We have runtime verification to check if begin_cow_mutation/end_cow_mutation are properly nested in asserts build of stdlib,
1755+ // disable checking whenever it is turned on since the compiler generated `end_cow_mutation_addr` is conservative and cannot be verified.
1756+ _makeMutableAndUniqueUnchecked ( )
1757+ #else
17401758 _makeMutableAndUnique ( )
1741- // NOTE: We don't have the ability to schedule a call to
1742- // ContiguousArrayBuffer.endCOWMutation().
1743- // rdar://146785284 (lifetime analysis for end of mutation)
1759+ #endif
17441760 let pointer = unsafe _buffer . firstElementAddress
17451761 let count = _buffer. mutableCount
17461762 let span = unsafe MutableSpan( _unsafeStart: pointer, count: count)
0 commit comments