@@ -26,6 +26,10 @@ use build::{BlockAnd, BlockAndExtension, Builder};
2626use build:: matches:: { Ascription , Binding , MatchPair , Candidate } ;
2727use hair:: * ;
2828use 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 ;
2933
3034use std:: mem;
3135
@@ -62,6 +66,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
6266 match_pair : MatchPair < ' pat , ' tcx > ,
6367 candidate : & mut Candidate < ' pat , ' tcx > )
6468 -> Result < ( ) , MatchPair < ' pat , ' tcx > > {
69+ let tcx = self . hir . tcx ( ) ;
6570 match * match_pair. pattern . kind {
6671 PatternKind :: AscribeUserType { ref subpattern, ref user_ty, user_ty_span } => {
6772 candidate. ascriptions . push ( Ascription {
@@ -104,7 +109,34 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
104109 Err ( match_pair)
105110 }
106111
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+ }
108140 Err ( match_pair)
109141 }
110142
0 commit comments