Skip to content

Commit 76fe9ea

Browse files
committed
[SDK] Fix IndexSet.startIndex for empty sets that used to have values
We can't rely on `_range(at:)` producing valid results for sets that have no ranges. Fixes SR-4947.
1 parent f9893a9 commit 76fe9ea

File tree

2 files changed

+24
-4
lines changed

2 files changed

+24
-4
lines changed

stdlib/public/SDK/Foundation/IndexSet.swift

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -237,9 +237,14 @@ public struct IndexSet : ReferenceConvertible, Equatable, BidirectionalCollectio
237237
}
238238

239239
public var startIndex: Index {
240-
// If this winds up being NSNotFound, that's ok because then endIndex is also NSNotFound, and empty collections have startIndex == endIndex
241-
let extent = _range(at: 0)
242-
return Index(value: extent.lowerBound, extent: extent, rangeIndex: 0, rangeCount: _rangeCount)
240+
let rangeCount = _rangeCount
241+
if rangeCount > 0 {
242+
// If this winds up being NSNotFound, that's ok because then endIndex is also NSNotFound, and empty collections have startIndex == endIndex
243+
let extent = _range(at: 0)
244+
return Index(value: extent.lowerBound, extent: extent, rangeIndex: 0, rangeCount: _rangeCount)
245+
} else {
246+
return Index(value: 0, extent: 0..<0, rangeIndex: -1, rangeCount: rangeCount)
247+
}
243248
}
244249

245250
public var endIndex: Index {

test/stdlib/TestIndexSet.swift

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -326,7 +326,7 @@ class TestIndexSet : TestIndexSetSuper {
326326
}
327327

328328
func testEmptyIteration() {
329-
let empty = IndexSet()
329+
var empty = IndexSet()
330330
let start = empty.startIndex
331331
let end = empty.endIndex
332332

@@ -345,6 +345,21 @@ class TestIndexSet : TestIndexSetSuper {
345345
}
346346

347347
expectEqual(count, 0)
348+
349+
empty.insert(5)
350+
empty.remove(5)
351+
352+
count = 0
353+
for _ in empty {
354+
count += 1
355+
}
356+
expectEqual(count, 0)
357+
358+
count = 0
359+
for _ in empty.rangeView {
360+
count += 1
361+
}
362+
expectEqual(count, 0)
348363
}
349364

350365
func testSubsequences() {

0 commit comments

Comments
 (0)