Skip to content

Commit ac1738f

Browse files
authored
Merge pull request #18066 from huonw/sr8022-workaround
[stdlib] Work-around incorrect name resolution with conditional BidirectionalCollections.
2 parents dc958d6 + 72a87a7 commit ac1738f

File tree

2 files changed

+47
-3
lines changed

2 files changed

+47
-3
lines changed

stdlib/public/core/BidirectionalCollection.swift

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -255,7 +255,9 @@ extension BidirectionalCollection where SubSequence == Self {
255255
_precondition(n >= 0, "Number of elements to remove should be non-negative")
256256
_precondition(count >= n,
257257
"Can't remove more items from a collection than it contains")
258-
self = self[startIndex..<index(endIndex, offsetBy: -n)]
258+
// FIXME: using non-_'d `index` incorrectly calls the Collection one for
259+
// conditional conformances to BidirectionalCollections.
260+
self = self[startIndex..<_index(endIndex, offsetBy: -n)]
259261
}
260262
}
261263

@@ -281,7 +283,9 @@ extension BidirectionalCollection {
281283
public func dropLast(_ n: Int) -> SubSequence {
282284
_precondition(
283285
n >= 0, "Can't drop a negative number of elements from a collection")
284-
let end = index(
286+
// FIXME: using non-_'d `index` incorrectly calls the Collection one for
287+
// conditional conformances to BidirectionalCollections.
288+
let end = _index(
285289
endIndex,
286290
offsetBy: -n,
287291
limitedBy: startIndex) ?? startIndex
@@ -311,7 +315,9 @@ extension BidirectionalCollection {
311315
_precondition(
312316
maxLength >= 0,
313317
"Can't take a suffix of negative length from a collection")
314-
let start = index(
318+
// FIXME: using non-_'d `index` incorrectly calls the Collection one for
319+
// conditional conformances to BidirectionalCollections.
320+
let start = _index(
315321
endIndex,
316322
offsetBy: -maxLength,
317323
limitedBy: startIndex) ?? startIndex
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
// RUN: %target-run-simple-swift
2+
// REQUIRES: executable_test
3+
4+
5+
struct X: BidirectionalCollection {
6+
var startIndex: Int { return 0 }
7+
var endIndex: Int { return 10 }
8+
subscript(position: Int) -> String { return "element" }
9+
subscript(range: Range<Int>) -> X { return X() }
10+
func index(after i: Int) -> Int { return i + 1 }
11+
func index(before i: Int) -> Int { return i - 1 }
12+
}
13+
struct A<C: Collection>: Collection {
14+
let c: C
15+
var startIndex: C.Index { return c.startIndex }
16+
var endIndex: C.Index { return c.endIndex }
17+
subscript(position: C.Index) -> C.Element { return c[position] }
18+
subscript(range: Range<C.Index>) -> A<C.SubSequence> {
19+
return A<C.SubSequence>(c: c[range])
20+
}
21+
func index(after i: C.Index) -> C.Index { return c.index(after: i) }
22+
}
23+
24+
extension A: BidirectionalCollection where C: BidirectionalCollection {
25+
func index(before i: C.Index) -> C.Index { return c.index(before: i) }
26+
}
27+
28+
// SR-8022
29+
func sr8022() {
30+
var c = A(c: X())
31+
_ = c.popLast()
32+
_ = c.removeLast()
33+
c.removeLast(2)
34+
_ = c.dropLast(2)
35+
_ = c.suffix(2)
36+
}
37+
38+
sr8022()

0 commit comments

Comments
 (0)