I'm using Xcode 9.3 (9E145) on macOS High Sierra 10.13.4.
Trying out some sorting routines in a linked-list protocol:
/// Transfers out a suffix such that the remaining elements are strictly stored according to the given predicate.
@discardableResult
public mutating func removeAfterMissort(by areInIncreasingOrder: (Element, Element) throws -> Bool) rethrows -> Self? {
var lastIncluded = startIndex
for i in indices.dropFirst() {
if try !areInIncreasingOrder(self[lastIncluded], self[i]) {
return removeLast(after: lastIncluded)
}
lastIncluded = i
}
return nil
}
And I can specialize for Comparable:
/// Transfers the elements after where the collection first stops increasing to a new instance.
@discardableResult
public mutating func removeNonincreasingSuffix() -> Self? {
return removeAfterMissort(by: <)
}
But it doesn't work silently for another method:
/// Creates an instance by merging the elements of two other instances, with a non-decreasing prefix.
public init(stealFromAndMergeWithNondecreasingPrefix first: inout Self, and second: inout Self) {
self.init(stealFromAndMerge: &first, and: &second, admittingFirstOverSecondBy: <)
}
This gives an error that I need to handle throwing. I got around it by adding "try" to the statement and marking the method with "throws," but I thought that "<" is always non-throwing, and such any method channelling it through rethrows is also non-throwing.
I don't think my primary method throws anywhere else besides the comparison:
/// Creates an instance by merging the elements of two other instances, with admission order controlled by a closure.
public init(stealFromAndMerge first: inout Self, and second: inout Self, admittingFirstOverSecondBy body: (Element, Element) throws -> Bool) rethrows {
// Determine the order of insertion.
var firstIndex = first.startIndex, secondIndex = second.startIndex
var chooseFirst = [Bool]()
chooseFirst.reserveCapacity(first.underestimatedCount + second.underestimatedCount)
while firstIndex != first.endIndex, secondIndex != second.endIndex {
let goWithFirst = try body(first[firstIndex], second[secondIndex])
chooseFirst.append(goWithFirst)
if goWithFirst {
first.formIndex(after: &firstIndex)
} else {
second.formIndex(after: &secondIndex)
}
}
// Do the transfers.
self.init()
chooseFirst.forEach {
var endSelf = endIndex >** endIndex
var otherRange: LeftOpenRange<Index>
if $0 {
otherRange = first.beforeStartIndex >** first.startIndex
trade(&endSelf, with: &first, along: &otherRange)
} else {
otherRange = second.beforeStartIndex >** second.startIndex
trade(&endSelf, with: &second, along: &otherRange)
}
}
append(stealingFrom: &first)
append(stealingFrom: &second)
}
Is there a compiler problem? Or is there a throwing spot I'm missing?