diff --git a/stdlib/public/core/RangeReplaceableCollection.swift b/stdlib/public/core/RangeReplaceableCollection.swift index 4281657947ae9..dd9f258698827 100644 --- a/stdlib/public/core/RangeReplaceableCollection.swift +++ b/stdlib/public/core/RangeReplaceableCollection.swift @@ -757,6 +757,23 @@ extension RangeReplaceableCollection { self.replaceSubrange(subrange.relative(to: self), with: newElements) } + // This unavailable default implementation of + // `replaceSubrange(_: Range, with: C)` prevents + // incomplete RangeReplaceableCollection implementations from satisfying + // the protocol through the use of the generic convenience implementation + // `replaceSubrange(_: R, with: C)`, + // If that were the case, at runtime the implementation generic over + // `RangeExpression` would call itself in an infinite recursion + // due to the absence of a better option. + @available(*, unavailable) + @_alwaysEmitIntoClient + public mutating func replaceSubrange( + _ subrange: Range, + with newElements: C + ) where C: Collection, C.Element == Element { + fatalError() + } + /// Removes the elements in the specified subrange from the collection. /// /// All the elements following the specified position are moved to close the diff --git a/validation-test/stdlib/CollectionDiagnostics.swift b/validation-test/stdlib/CollectionDiagnostics.swift index 4ff258648cc5f..f0c60275c02a5 100644 --- a/validation-test/stdlib/CollectionDiagnostics.swift +++ b/validation-test/stdlib/CollectionDiagnostics.swift @@ -200,6 +200,18 @@ func subscriptMutableCollectionIgnored() { ds[3..<5] = goodSlice } +// expected-error@+2 {{type 'IncompleteRangeReplaceableCollection' does not conform to protocol 'RangeReplaceableCollection'}} +// expected-error@+1 {{unavailable instance method 'replaceSubrange(_:with:)' was used to satisfy a requirement of protocol 'RangeReplaceableCollection'}} +struct IncompleteRangeReplaceableCollection: RangeReplaceableCollection { + var startIndex: Int + var endIndex: Int + + func index(after i: Int) -> Int { i+1 } + subscript(position: Int) -> Int { position } + + init() { startIndex = 0; endIndex = 0 } + } + // FIXME: Remove -verify-ignore-unknown. // :0: error: unexpected note produced: possibly intended match // :0: error: unexpected note produced: possibly intended match