@@ -106,27 +106,34 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
106
106
}
107
107
108
108
PatternKind :: Range ( PatternRange { lo, hi, ty, end } ) => {
109
- let range = match ty. sty {
109
+ let ( range, bias ) = match ty. sty {
110
110
ty:: Char => {
111
- Some ( ( '\u{0000}' as u128 , '\u{10FFFF}' as u128 , Size :: from_bits ( 32 ) ) )
111
+ ( Some ( ( '\u{0000}' as u128 , '\u{10FFFF}' as u128 , Size :: from_bits ( 32 ) ) ) , 0 )
112
112
}
113
113
ty:: Int ( ity) => {
114
114
// FIXME(49937): refactor these bit manipulations into interpret.
115
115
let size = Integer :: from_attr ( & tcx, SignedInt ( ity) ) . size ( ) ;
116
- let min = 1u128 << ( size. bits ( ) - 1 ) ;
117
- let max = ( 1u128 << ( size. bits ( ) - 1 ) ) - 1 ;
118
- Some ( ( min , max, size) )
116
+ let max = ! 0u128 >> ( 128 - size. bits ( ) ) ;
117
+ let bias = 1u128 << ( size. bits ( ) - 1 ) ;
118
+ ( Some ( ( 0 , max, size) ) , bias )
119
119
}
120
120
ty:: Uint ( uty) => {
121
121
// FIXME(49937): refactor these bit manipulations into interpret.
122
122
let size = Integer :: from_attr ( & tcx, UnsignedInt ( uty) ) . size ( ) ;
123
123
let max = !0u128 >> ( 128 - size. bits ( ) ) ;
124
- Some ( ( 0 , max, size) )
124
+ ( Some ( ( 0 , max, size) ) , 0 )
125
125
}
126
- _ => None ,
126
+ _ => ( None , 0 ) ,
127
127
} ;
128
128
if let Some ( ( min, max, sz) ) = range {
129
129
if let ( Some ( lo) , Some ( hi) ) = ( lo. val . try_to_bits ( sz) , hi. val . try_to_bits ( sz) ) {
130
+ // We want to compare ranges numerically, but the order of the bitwise
131
+ // representation of signed integers does not match their numeric order.
132
+ // Thus, to correct the ordering, we need to shift the range of signed
133
+ // integers to correct the comparison. This is achieved by XORing with a
134
+ // bias (see pattern/_match.rs for another pertinent example of this
135
+ // pattern).
136
+ let ( lo, hi) = ( lo ^ bias, hi ^ bias) ;
130
137
if lo <= min && ( hi > max || hi == max && end == RangeEnd :: Included ) {
131
138
// Irrefutable pattern match.
132
139
return Ok ( ( ) ) ;
0 commit comments