@@ -305,33 +305,42 @@ extension FlattenCollection: Collection {
305305 }
306306
307307 // The following path combines the distances of three regions.
308- let range = minus ? end ..< start : start ..< end
309- var outer = range. lowerBound. _outer
310-
311308 var distance : Int = 0
312- let step : Int = minus ? - 1 : 1
309+ let step : Int
310+ let lowerBound : Index
311+ let upperBound : Index
313312
314- // This unwrap always succeeds.
315- if let inner = range. lowerBound. _inner {
316- let collection = _base [ outer]
317- _base. formIndex ( after: & outer)
313+ if minus {
314+ lowerBound = end
315+ upperBound = start
316+ step = - 1
317+ } else {
318+ lowerBound = start
319+ upperBound = end
320+ step = 01
321+ }
322+
323+ // This always unwraps because start._outer != end._outer.
324+ if let inner = lowerBound. _inner {
325+ let collection = _base [ lowerBound. _outer]
318326 distance += minus
319327 ? collection. distance ( from: collection. endIndex, to: inner)
320328 : collection. distance ( from: inner, to: collection. endIndex)
321329 }
322330
323- // Using count is fine because the distance is nonzero here.
324- // In other words, the most negative nontrapping value is -Int.max.
325- _internalInvariant ( distance != 0 , " distance should not be zero " )
326- while outer < range. upperBound. _outer {
327- // 0...Int.max can always be negated.
328- let collection = _base [ outer]
331+ // We can use each collection's count in the middle region since the
332+ // fast path ensures that the other regions cover a nonzero distance,
333+ // which means that an extra Int.min distance should trap regardless.
334+ var outer = _base. index ( after: lowerBound. _outer)
335+ while outer < upperBound. _outer {
336+ // 0 ... Int.max can always be negated.
337+ distance += _base [ outer] . count &* step
329338 _base. formIndex ( after: & outer)
330- distance += collection. count &* step
331339 }
332340
333- if let inner = range. upperBound. _inner {
334- let collection = _base [ outer]
341+ /// This unwraps if start != endIndex and end != endIndex.
342+ if let inner = upperBound. _inner {
343+ let collection = _base [ upperBound. _outer]
335344 distance += minus
336345 ? collection. distance ( from: inner, to: collection. startIndex)
337346 : collection. distance ( from: collection. startIndex, to: inner)
0 commit comments