Range<UInt64>.count can abort


(Jens Alfke) #1

I’m writing some code that deals with ranges of “sequence numbers”, which are consecutively-assigned positive 64-bit integers, thus Range<UInt64> in Swift. I’m having trouble handling half-open ranges with no maximum, which are very commonly used for representing all items created since a certain time.

The trouble is, if I represent these with Ranges whose endIndex is UInt64.max, those ranges tend to bomb:

let r: Range<UInt64> = 5..<UInt64.max
r.count // FATAL ERROR

The problem is that Range.count’s type is Element.Distance, and UInt64.Distance is a typealias of … Int. Huh? It’s pretty clear that the distance between two UInt64s can’t be represented by a signed Int64. Why isn’t Distance UInt64?

(I’m guessing it’s because Distance needs to be signed, to represent backwards distances? But that’s not needed for Ranges, of course.)

It’s sort of worrisome that Swift will let me create a valid Range value that nonetheless bombs when accessed! I think I’m going to stop using Range for working with sequence numbers :confused:

—Jens