@@ -170,6 +170,38 @@ extension MutableSpan where Element: BitwiseCopyable {
170170 }
171171}
172172
173+ @available ( SwiftCompatibilitySpan 5 . 0 , * )
174+ @_originallyDefinedIn ( module: " Swift;CompatibilitySpan " , SwiftCompatibilitySpan 6 . 2 )
175+ extension MutableSpan where Element: BitwiseCopyable {
176+ @_alwaysEmitIntoClient
177+ public subscript( _ position: Index ) -> Element {
178+ get {
179+ _checkIndex ( position)
180+ return unsafe self[ unchecked: position]
181+ }
182+ @lifetime ( self : copy self )
183+ set {
184+ _checkIndex ( position)
185+ self [ unchecked: position] = newValue
186+ }
187+ }
188+
189+ @unsafe
190+ @_alwaysEmitIntoClient
191+ public subscript( unchecked position: Index ) -> Element {
192+ get {
193+ let elementOffset = position &* MemoryLayout< Element> . stride
194+ let address = unsafe _start( ) . advanced ( by: elementOffset)
195+ return unsafe address. loadUnaligned ( as: Element . self)
196+ }
197+ @lifetime ( self : copy self )
198+ set {
199+ let elementOffset = position &* MemoryLayout< Element> . stride
200+ _start ( ) . storeBytes ( of: newValue, toByteOffset: elementOffset, as: Element . self)
201+ }
202+ }
203+ }
204+
173205@available ( SwiftCompatibilitySpan 5 . 0 , * )
174206@_originallyDefinedIn ( module: " Swift;CompatibilitySpan " , SwiftCompatibilitySpan 6 . 2 )
175207extension Span where Element: ~ Copyable {
@@ -236,6 +268,7 @@ extension MutableSpan where Element: ~Copyable {
236268extension MutableSpan where Element: ~ Copyable {
237269
238270 @_alwaysEmitIntoClient
271+ @_semantics ( " fixed_storage.get_count " )
239272 public var count : Int { _assumeNonNegative ( _count) }
240273
241274 @_alwaysEmitIntoClient
@@ -279,7 +312,13 @@ extension MutableSpan where Element: BitwiseCopyable {
279312@available ( SwiftCompatibilitySpan 5 . 0 , * )
280313@_originallyDefinedIn ( module: " Swift;CompatibilitySpan " , SwiftCompatibilitySpan 6 . 2 )
281314extension MutableSpan where Element: ~ Copyable {
282-
315+ // SILOptimizer looks for fixed_storage.check_index semantics for bounds check optimizations.
316+ @_semantics ( " fixed_storage.check_index " )
317+ @inline ( __always)
318+ @_alwaysEmitIntoClient
319+ internal func _checkIndex( _ position: Index ) {
320+ _precondition ( indices. contains ( position) , " index out of bounds " )
321+ }
283322 /// Accesses the element at the specified position in the `MutableSpan`.
284323 ///
285324 /// - Parameter position: The offset of the element to access. `position`
@@ -289,12 +328,12 @@ extension MutableSpan where Element: ~Copyable {
289328 @_alwaysEmitIntoClient
290329 public subscript( _ position: Index ) -> Element {
291330 unsafeAddress {
292- _precondition ( indices . contains ( position) , " index out of bounds " )
331+ _checkIndex ( position)
293332 return unsafe UnsafePointer ( _unsafeAddressOfElement ( unchecked: position) )
294333 }
295334 @lifetime ( self : copy self )
296335 unsafeMutableAddress {
297- _precondition ( indices . contains ( position) , " index out of bounds " )
336+ _checkIndex ( position)
298337 return unsafe _unsafeAddressOfElement( unchecked: position)
299338 }
300339 }
0 commit comments