@@ -157,6 +157,14 @@ public struct Range<Bound: Comparable> {
157157 /// instance does not contain its upper bound.
158158 public let upperBound : Bound
159159
160+ // This works around _debugPrecondition() impacting the performance of
161+ // optimized code. (rdar://72246338)
162+ @_alwaysEmitIntoClient @inline ( __always)
163+ internal init ( _uncheckedBounds bounds: ( lower: Bound , upper: Bound ) ) {
164+ self . lowerBound = bounds. lower
165+ self . upperBound = bounds. upper
166+ }
167+
160168 /// Creates an instance with the given bounds.
161169 ///
162170 /// Because this initializer does not perform any checks, it should be used
@@ -167,8 +175,9 @@ public struct Range<Bound: Comparable> {
167175 /// - Parameter bounds: A tuple of the lower and upper bounds of the range.
168176 @inlinable
169177 public init ( uncheckedBounds bounds: ( lower: Bound , upper: Bound ) ) {
170- self . lowerBound = bounds. lower
171- self . upperBound = bounds. upper
178+ _debugPrecondition ( bounds. lower <= bounds. upper,
179+ " Range requires lowerBound <= upperBound " )
180+ self . init ( _uncheckedBounds: ( lower: bounds. lower, upper: bounds. upper) )
172181 }
173182
174183 /// Returns a Boolean value indicating whether the given element is contained
@@ -308,7 +317,7 @@ extension Range where Bound: Strideable, Bound.Stride: SignedInteger {
308317 /// require an upper bound of `Int.max + 1`, which is not representable as
309318 public init ( _ other: ClosedRange < Bound > ) {
310319 let upperBound = other. upperBound. advanced ( by: 1 )
311- self . init ( uncheckedBounds : ( lower: other. lowerBound, upper: upperBound) )
320+ self . init ( _uncheckedBounds : ( lower: other. lowerBound, upper: upperBound) )
312321 }
313322}
314323
@@ -325,7 +334,7 @@ extension Range: RangeExpression {
325334 @inlinable // trivial-implementation
326335 public func relative< C: Collection > ( to collection: C ) -> Range < Bound >
327336 where C. Index == Bound {
328- return Range ( uncheckedBounds : ( lower : lowerBound , upper : upperBound ) )
337+ self
329338 }
330339}
331340
@@ -359,7 +368,7 @@ extension Range {
359368 limits. upperBound < self . upperBound ? limits. upperBound
360369 : limits. lowerBound > self . upperBound ? limits. lowerBound
361370 : self . upperBound
362- return Range ( uncheckedBounds : ( lower: lower, upper: upper) )
371+ return Range ( _uncheckedBounds : ( lower: lower, upper: upper) )
363372 }
364373}
365374
@@ -435,7 +444,7 @@ extension Range: Decodable where Bound: Decodable {
435444 codingPath: decoder. codingPath,
436445 debugDescription: " Cannot initialize \( Range . self) with a lowerBound ( \( lowerBound) ) greater than upperBound ( \( upperBound) ) " ) )
437446 }
438- self . init ( uncheckedBounds : ( lower: lowerBound, upper: upperBound) )
447+ self . init ( _uncheckedBounds : ( lower: lowerBound, upper: upperBound) )
439448 }
440449}
441450
@@ -729,7 +738,7 @@ extension Comparable {
729738 public static func ..< ( minimum: Self , maximum: Self ) -> Range < Self > {
730739 _precondition ( minimum <= maximum,
731740 " Range requires lowerBound <= upperBound " )
732- return Range( uncheckedBounds : ( lower: minimum, upper: maximum) )
741+ return Range( _uncheckedBounds : ( lower: minimum, upper: maximum) )
733742 }
734743
735744 /// Returns a partial range up to, but not including, its upper bound.
0 commit comments