@@ -26,6 +26,10 @@ use build::{BlockAnd, BlockAndExtension, Builder};
26
26
use build:: matches:: { Ascription , Binding , MatchPair , Candidate } ;
27
27
use hair:: * ;
28
28
use rustc:: mir:: * ;
29
+ use rustc:: ty;
30
+ use rustc:: ty:: layout:: { Integer , IntegerExt , Size } ;
31
+ use syntax:: attr:: { SignedInt , UnsignedInt } ;
32
+ use rustc:: hir:: RangeEnd ;
29
33
30
34
use std:: mem;
31
35
@@ -62,6 +66,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
62
66
match_pair : MatchPair < ' pat , ' tcx > ,
63
67
candidate : & mut Candidate < ' pat , ' tcx > )
64
68
-> Result < ( ) , MatchPair < ' pat , ' tcx > > {
69
+ let tcx = self . hir . tcx ( ) ;
65
70
match * match_pair. pattern . kind {
66
71
PatternKind :: AscribeUserType { ref subpattern, ref user_ty, user_ty_span } => {
67
72
candidate. ascriptions . push ( Ascription {
@@ -104,7 +109,34 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
104
109
Err ( match_pair)
105
110
}
106
111
107
- PatternKind :: Range { .. } => {
112
+ PatternKind :: Range { lo, hi, ty, end } => {
113
+ let range = match ty. sty {
114
+ ty:: Char => {
115
+ Some ( ( '\u{0000}' as u128 , '\u{10FFFF}' as u128 , Size :: from_bits ( 32 ) ) )
116
+ }
117
+ ty:: Int ( ity) => {
118
+ // FIXME(49937): refactor these bit manipulations into interpret.
119
+ let size = Integer :: from_attr ( & tcx, SignedInt ( ity) ) . size ( ) ;
120
+ let min = 1u128 << ( size. bits ( ) - 1 ) ;
121
+ let max = ( 1u128 << ( size. bits ( ) - 1 ) ) - 1 ;
122
+ Some ( ( min, max, size) )
123
+ }
124
+ ty:: Uint ( uty) => {
125
+ // FIXME(49937): refactor these bit manipulations into interpret.
126
+ let size = Integer :: from_attr ( & tcx, UnsignedInt ( uty) ) . size ( ) ;
127
+ let max = !0u128 >> ( 128 - size. bits ( ) ) ;
128
+ Some ( ( 0 , max, size) )
129
+ }
130
+ _ => None ,
131
+ } ;
132
+ if let Some ( ( min, max, sz) ) = range {
133
+ if let ( Some ( lo) , Some ( hi) ) = ( lo. val . try_to_bits ( sz) , hi. val . try_to_bits ( sz) ) {
134
+ if lo <= min && ( hi > max || hi == max && end == RangeEnd :: Included ) {
135
+ // Irrefutable pattern match.
136
+ return Ok ( ( ) ) ;
137
+ }
138
+ }
139
+ }
108
140
Err ( match_pair)
109
141
}
110
142
0 commit comments