Skip to content

Commit 6b219a9

Browse files
authored
[stdlib] fix another accidental infinite-recursion bug (#38950)
fixes: SR-6501, SR-11516
1 parent 67db14e commit 6b219a9

File tree

2 files changed

+29
-0
lines changed

2 files changed

+29
-0
lines changed

stdlib/public/core/RangeReplaceableCollection.swift

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -757,6 +757,23 @@ extension RangeReplaceableCollection {
757757
self.replaceSubrange(subrange.relative(to: self), with: newElements)
758758
}
759759

760+
// This unavailable default implementation of
761+
// `replaceSubrange<C: Collection>(_: Range<Index>, with: C)` prevents
762+
// incomplete RangeReplaceableCollection implementations from satisfying
763+
// the protocol through the use of the generic convenience implementation
764+
// `replaceSubrange<C: Collection, R: RangeExpression>(_: R, with: C)`,
765+
// If that were the case, at runtime the implementation generic over
766+
// `RangeExpression` would call itself in an infinite recursion
767+
// due to the absence of a better option.
768+
@available(*, unavailable)
769+
@_alwaysEmitIntoClient
770+
public mutating func replaceSubrange<C>(
771+
_ subrange: Range<Index>,
772+
with newElements: C
773+
) where C: Collection, C.Element == Element {
774+
fatalError()
775+
}
776+
760777
/// Removes the elements in the specified subrange from the collection.
761778
///
762779
/// All the elements following the specified position are moved to close the

validation-test/stdlib/CollectionDiagnostics.swift

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,18 @@ func subscriptMutableCollectionIgnored() {
200200
ds[3..<5] = goodSlice
201201
}
202202

203+
// expected-error@+2 {{type 'IncompleteRangeReplaceableCollection' does not conform to protocol 'RangeReplaceableCollection'}}
204+
// expected-error@+1 {{unavailable instance method 'replaceSubrange(_:with:)' was used to satisfy a requirement of protocol 'RangeReplaceableCollection'}}
205+
struct IncompleteRangeReplaceableCollection: RangeReplaceableCollection {
206+
var startIndex: Int
207+
var endIndex: Int
208+
209+
func index(after i: Int) -> Int { i+1 }
210+
subscript(position: Int) -> Int { position }
211+
212+
init() { startIndex = 0; endIndex = 0 }
213+
}
214+
203215
// FIXME: Remove -verify-ignore-unknown.
204216
// <unknown>:0: error: unexpected note produced: possibly intended match
205217
// <unknown>:0: error: unexpected note produced: possibly intended match

0 commit comments

Comments
 (0)