@@ -46,7 +46,6 @@ use std::cell::Cell;
4646use std:: cmp:: { self , max, min, Ordering } ;
4747use std:: fmt;
4848use std:: iter:: once;
49- use std:: ops:: RangeInclusive ;
5049
5150use smallvec:: { smallvec, SmallVec } ;
5251
@@ -104,9 +103,10 @@ enum Presence {
104103///
105104/// `IntRange` is never used to encode an empty range or a "range" that wraps
106105/// around the (offset) space: i.e., `range.lo <= range.hi`.
107- #[ derive( Clone , PartialEq , Eq ) ]
106+ #[ derive( Clone , Copy , PartialEq , Eq ) ]
108107pub ( crate ) struct IntRange {
109- range : RangeInclusive < u128 > ,
108+ lo : u128 ,
109+ hi : u128 ,
110110}
111111
112112impl IntRange {
@@ -116,20 +116,16 @@ impl IntRange {
116116 }
117117
118118 fn is_singleton ( & self ) -> bool {
119- self . range . start ( ) == self . range . end ( )
120- }
121-
122- fn boundaries ( & self ) -> ( u128 , u128 ) {
123- ( * self . range . start ( ) , * self . range . end ( ) )
119+ self . lo == self . hi
124120 }
125121
126122 #[ inline]
127123 fn from_bits < ' tcx > ( tcx : TyCtxt < ' tcx > , ty : Ty < ' tcx > , bits : u128 ) -> IntRange {
128124 let bias = IntRange :: signed_bias ( tcx, ty) ;
129- // Perform a shift if the underlying types are signed,
130- // which makes the interval arithmetic simpler .
125+ // Perform a shift if the underlying types are signed, which makes the interval arithmetic
126+ // type-independent .
131127 let val = bits ^ bias;
132- IntRange { range : val..= val }
128+ IntRange { lo : val, hi : val }
133129 }
134130
135131 #[ inline]
@@ -140,16 +136,17 @@ impl IntRange {
140136 ty : Ty < ' tcx > ,
141137 end : RangeEnd ,
142138 ) -> IntRange {
143- // Perform a shift if the underlying types are signed,
144- // which makes the interval arithmetic simpler .
139+ // Perform a shift if the underlying types are signed, which makes the interval arithmetic
140+ // type-independent .
145141 let bias = IntRange :: signed_bias ( tcx, ty) ;
146142 let ( lo, hi) = ( lo ^ bias, hi ^ bias) ;
147143 let offset = ( end == RangeEnd :: Excluded ) as u128 ;
148- if lo > hi || ( lo == hi && end == RangeEnd :: Excluded ) {
144+ let hi = hi - offset;
145+ if lo > hi {
149146 // This should have been caught earlier by E0030.
150- bug ! ( "malformed range pattern: {}..={}" , lo , ( hi - offset ) ) ;
147+ bug ! ( "malformed range pattern: {lo }..={hi}" ) ;
151148 }
152- IntRange { range : lo..= ( hi - offset ) }
149+ IntRange { lo , hi }
153150 }
154151
155152 // The return value of `signed_bias` should be XORed with an endpoint to encode/decode it.
@@ -164,14 +161,12 @@ impl IntRange {
164161 }
165162
166163 fn is_subrange ( & self , other : & Self ) -> bool {
167- other. range . start ( ) <= self . range . start ( ) && self . range . end ( ) <= other. range . end ( )
164+ other. lo <= self . lo && self . hi <= other. hi
168165 }
169166
170167 fn intersection ( & self , other : & Self ) -> Option < Self > {
171- let ( lo, hi) = self . boundaries ( ) ;
172- let ( other_lo, other_hi) = other. boundaries ( ) ;
173- if lo <= other_hi && other_lo <= hi {
174- Some ( IntRange { range : max ( lo, other_lo) ..=min ( hi, other_hi) } )
168+ if self . lo <= other. hi && other. lo <= self . hi {
169+ Some ( IntRange { lo : max ( self . lo , other. lo ) , hi : min ( self . hi , other. hi ) } )
175170 } else {
176171 None
177172 }
@@ -189,9 +184,9 @@ impl IntRange {
189184 // `true` in the following cases:
190185 // 1 ------- // 1 -------
191186 // 2 -------- // 2 -------
192- let ( lo , hi ) = self . boundaries ( ) ;
193- let ( other_lo , other_hi ) = other . boundaries ( ) ;
194- ( lo == other_hi || hi == other_lo ) && ! self . is_singleton ( ) && !other. is_singleton ( )
187+ ( self . lo == other . hi || self . hi == other . lo )
188+ && ! self . is_singleton ( )
189+ && !other. is_singleton ( )
195190 }
196191
197192 /// Partition a range of integers into disjoint subranges. This does constructor splitting for
@@ -235,9 +230,8 @@ impl IntRange {
235230
236231 fn unpack_intrange ( range : IntRange ) -> [ IntBoundary ; 2 ] {
237232 use IntBoundary :: * ;
238- let ( lo, hi) = range. boundaries ( ) ;
239- let lo = JustBefore ( lo) ;
240- let hi = match hi. checked_add ( 1 ) {
233+ let lo = JustBefore ( range. lo ) ;
234+ let hi = match range. hi . checked_add ( 1 ) {
241235 Some ( m) => JustBefore ( m) ,
242236 None => AfterMax ,
243237 } ;
@@ -283,21 +277,19 @@ impl IntRange {
283277 use IntBoundary :: * ;
284278 use Presence :: * ;
285279 let presence = if paren_count > 0 { Seen } else { Unseen } ;
286- let range = match ( prev_bdy, bdy) {
287- ( JustBefore ( n) , JustBefore ( m) ) if n < m => n..= ( m - 1 ) ,
288- ( JustBefore ( n) , AfterMax ) => n..= u128:: MAX ,
280+ let ( lo , hi ) = match ( prev_bdy, bdy) {
281+ ( JustBefore ( n) , JustBefore ( m) ) if n < m => ( n , m - 1 ) ,
282+ ( JustBefore ( n) , AfterMax ) => ( n , u128:: MAX ) ,
289283 _ => unreachable ! ( ) , // Ruled out by the sorting and filtering we did
290284 } ;
291- ( presence, IntRange { range } )
285+ ( presence, IntRange { lo , hi } )
292286 } )
293287 }
294288
295289 /// Only used for displaying the range.
296290 fn to_pat < ' tcx > ( & self , tcx : TyCtxt < ' tcx > , ty : Ty < ' tcx > ) -> Pat < ' tcx > {
297- let ( lo, hi) = self . boundaries ( ) ;
298-
299291 let bias = IntRange :: signed_bias ( tcx, ty) ;
300- let ( lo_bits, hi_bits) = ( lo ^ bias, hi ^ bias) ;
292+ let ( lo_bits, hi_bits) = ( self . lo ^ bias, self . hi ^ bias) ;
301293
302294 let env = ty:: ParamEnv :: empty ( ) . and ( ty) ;
303295 let lo_const = mir:: Const :: from_bits ( tcx, lo_bits, env) ;
@@ -367,7 +359,7 @@ impl IntRange {
367359/// first.
368360impl fmt:: Debug for IntRange {
369361 fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
370- let ( lo, hi) = self . boundaries ( ) ;
362+ let ( lo, hi) = ( self . lo , self . hi ) ;
371363 write ! ( f, "{lo}" ) ?;
372364 write ! ( f, "{}" , RangeEnd :: Included ) ?;
373365 write ! ( f, "{hi}" )
0 commit comments