I have a code base using Vapor 4 that has functioned fine. I upgraded to Xcode 13.3 from 13.1, and now the same, unchanged code will not compile.
The errors are
Type 'MarkedCircularBuffer<Element>' does not conform to protocol 'MutableCollection'
and
Unavailable subscript 'subscript(_:)' was used to satisfy a requirement of protocol 'MutableCollection'
MarkedCircularBuffer is a struct in SwiftNIO, used by Vapor. It looks like this:
public struct MarkedCircularBuffer<Element>: CustomStringConvertible {
@usableFromInline internal var _buffer: CircularBuffer<Element>
@usableFromInline internal var _markedIndexOffset: Int? /* nil: nothing marked */
/// Create a new instance.
///
/// - paramaters:
/// - initialCapacity: The initial capacity of the internal storage.
@inlinable
public init(initialCapacity: Int) {
self._buffer = CircularBuffer(initialCapacity: initialCapacity)
}
// MARK: Forwarding
/// Appends an entry to the buffer, expanding it if needed.
@inlinable
public mutating func append(_ value: Element) {
self._buffer.append(value)
}
/// Removes the first element from the buffer.
@inlinable
public mutating func removeFirst() -> Element {
assert(self._buffer.count > 0)
return self.popFirst()!
}
@inlinable
public mutating func popFirst() -> Element? {
if let markedIndexOffset = self._markedIndexOffset {
if markedIndexOffset > 0 {
self._markedIndexOffset = markedIndexOffset - 1
} else {
self._markedIndexOffset = nil
}
}
return self._buffer.popFirst()
}
/// The first element in the buffer.
@inlinable
public var first: Element? {
return self._buffer.first
}
/// If the buffer is empty.
@inlinable
public var isEmpty: Bool {
return self._buffer.isEmpty
}
/// The number of elements in the buffer.
@inlinable
public var count: Int {
return self._buffer.count
}
@inlinable
public var description: String {
return self._buffer.description
}
// MARK: Marking
/// Marks the buffer at the current index, making the last index in the buffer marked.
@inlinable
public mutating func mark() {
let count = self._buffer.count
if count > 0 {
self._markedIndexOffset = count - 1
} else {
assert(self._markedIndexOffset == nil, "marked index is \(self._markedIndexOffset.debugDescription)")
}
}
/// Returns true if the buffer is currently marked at the given index.
@inlinable
public func isMarked(index: Index) -> Bool {
assert(index >= self.startIndex, "index must not be negative")
precondition(index < self.endIndex, "index \(index) out of range (0..<\(self._buffer.count))")
if let markedIndexOffset = self._markedIndexOffset {
return self.index(self.startIndex, offsetBy: markedIndexOffset) == index
} else {
return false
}
}
/// Returns the index of the marked element.
@inlinable
public var markedElementIndex: Index? {
if let markedIndexOffset = self._markedIndexOffset {
assert(markedIndexOffset >= 0)
return self.index(self.startIndex, offsetBy: markedIndexOffset)
} else {
return nil
}
}
/// Returns the marked element.
@inlinable
public var markedElement: Element? {
return self.markedElementIndex.map { self._buffer[$0] }
}
/// Returns true if the buffer has been marked at all.
@inlinable
public var hasMark: Bool {
return self._markedIndexOffset != nil
}
}
extension MarkedCircularBuffer: Collection, MutableCollection {
public typealias RangeType<Bound> = Range<Bound> where Bound: Strideable, Bound.Stride: SignedInteger
public typealias Index = CircularBuffer<Element>.Index
public typealias SubSequence = CircularBuffer<Element>
@inlinable
public func index(after i: Index) -> Index {
return self._buffer.index(after: i)
}
@inlinable
public var startIndex: Index { return self._buffer.startIndex }
@inlinable
public var endIndex: Index { return self._buffer.endIndex }
/// Retrieves the element at the given index from the buffer, without removing it.
@inlinable
public subscript(index: Index) -> Element {
get {
return self._buffer[index]
}
set {
self._buffer[index] = newValue
}
}
@inlinable
public subscript(bounds: Range<Index>) -> SubSequence {
get {
return self._buffer[bounds]
}
}
}
extension MarkedCircularBuffer: RandomAccessCollection {
@inlinable
public func index(_ i: Index, offsetBy distance: Int) -> Index {
return self._buffer.index(i, offsetBy: distance)
}
@inlinable
public func distance(from start: Index, to end: Index) -> Int {
return self._buffer.distance(from: start, to: end)
}
@inlinable
public func index(before i: Index) -> Index {
return self._buffer.index(before: i)
}
}
and the error is thrown at the first extension.... does this mean anything to anyone?