@@ -205,7 +205,14 @@ extension Unsafe${Mutable}BufferPointer: ${Mutable}Collection, RandomAccessColle
205205 // optimizer is not capable of creating partial specializations yet.
206206 // NOTE: Range checks are not performed here, because it is done later by
207207 // the subscript function.
208- return i + 1
208+ // NOTE: Wrapping math because we allow unsafe buffer pointers not to verify
209+ // index preconditions in release builds. Our (optimistic) assumption is
210+ // that the caller is already ensuring that indices are valid, so we can
211+ // elide the usual checks to help the optimizer generate better code.
212+ // However, we still check for overflow in debug mode.
213+ let result = i. addingReportingOverflow ( 1 )
214+ _debugPrecondition ( !result. overflow)
215+ return result. partialValue
209216 }
210217
211218 @inlinable // unsafe-performance
@@ -215,7 +222,10 @@ extension Unsafe${Mutable}BufferPointer: ${Mutable}Collection, RandomAccessColle
215222 // optimizer is not capable of creating partial specializations yet.
216223 // NOTE: Range checks are not performed here, because it is done later by
217224 // the subscript function.
218- i += 1
225+ // See note on wrapping arithmetic in `index(after:)` above.
226+ let result = i. addingReportingOverflow ( 1 )
227+ _debugPrecondition ( !result. overflow)
228+ i = result. partialValue
219229 }
220230
221231 @inlinable // unsafe-performance
@@ -225,7 +235,10 @@ extension Unsafe${Mutable}BufferPointer: ${Mutable}Collection, RandomAccessColle
225235 // optimizer is not capable of creating partial specializations yet.
226236 // NOTE: Range checks are not performed here, because it is done later by
227237 // the subscript function.
228- return i - 1
238+ // See note on wrapping arithmetic in `index(after:)` above.
239+ let result = i. subtractingReportingOverflow ( 1 )
240+ _debugPrecondition ( !result. overflow)
241+ return result. partialValue
229242 }
230243
231244 @inlinable // unsafe-performance
@@ -235,7 +248,10 @@ extension Unsafe${Mutable}BufferPointer: ${Mutable}Collection, RandomAccessColle
235248 // optimizer is not capable of creating partial specializations yet.
236249 // NOTE: Range checks are not performed here, because it is done later by
237250 // the subscript function.
238- i -= 1
251+ // See note on wrapping arithmetic in `index(after:)` above.
252+ let result = i. subtractingReportingOverflow ( 1 )
253+ _debugPrecondition ( !result. overflow)
254+ i = result. partialValue
239255 }
240256
241257 @inlinable // unsafe-performance
@@ -245,7 +261,10 @@ extension Unsafe${Mutable}BufferPointer: ${Mutable}Collection, RandomAccessColle
245261 // optimizer is not capable of creating partial specializations yet.
246262 // NOTE: Range checks are not performed here, because it is done later by
247263 // the subscript function.
248- return i + n
264+ // See note on wrapping arithmetic in `index(after:)` above.
265+ let result = i. addingReportingOverflow ( n)
266+ _debugPrecondition ( !result. overflow)
267+ return result. partialValue
249268 }
250269
251270 @inlinable // unsafe-performance
@@ -255,11 +274,18 @@ extension Unsafe${Mutable}BufferPointer: ${Mutable}Collection, RandomAccessColle
255274 // optimizer is not capable of creating partial specializations yet.
256275 // NOTE: Range checks are not performed here, because it is done later by
257276 // the subscript function.
258- let l = limit - i
277+ // See note on wrapping arithmetic in `index(after:)` above.
278+ let maxOffset = limit. subtractingReportingOverflow ( i)
279+ _debugPrecondition ( !maxOffset. overflow)
280+ let l = maxOffset. partialValue
281+
259282 if n > 0 ? l >= 0 && l < n : l <= 0 && n < l {
260283 return nil
261284 }
262- return i + n
285+
286+ let result = i. addingReportingOverflow ( n)
287+ _debugPrecondition ( !result. overflow)
288+ return result. partialValue
263289 }
264290
265291 @inlinable // unsafe-performance
@@ -295,7 +321,8 @@ extension Unsafe${Mutable}BufferPointer: ${Mutable}Collection, RandomAccessColle
295321
296322 @inlinable // unsafe-performance
297323 public var indices : Indices {
298- return startIndex..< endIndex
324+ // Not checked because init forbids negative count.
325+ return Indices ( uncheckedBounds: ( startIndex, endIndex) )
299326 }
300327
301328 /// Accesses the element at the specified position.
0 commit comments