@@ -37,14 +37,12 @@ use std::ops::RangeInclusive;
3737/// 
3838/// `IntRange` is never used to encode an empty range or a "range" that wraps 
3939/// around the (offset) space: i.e., `range.lo <= range.hi`. 
40- #[ derive( Clone ,  Debug ) ]  
41- pub ( super )  struct  IntRange < ' tcx >  { 
40+ #[ derive( Clone ,  Debug ,   PartialEq ,   Eq ) ]  
41+ pub ( super )  struct  IntRange  { 
4242    range :  RangeInclusive < u128 > , 
43-     ty :  Ty < ' tcx > , 
44-     span :  Span , 
4543} 
4644
47- impl < ' tcx >  IntRange < ' tcx >  { 
45+ impl  IntRange  { 
4846    #[ inline]  
4947    fn  is_integral ( ty :  Ty < ' _ > )  -> bool  { 
5048        matches ! ( ty. kind( ) ,  ty:: Char  | ty:: Int ( _)  | ty:: Uint ( _)  | ty:: Bool ) 
@@ -58,14 +56,8 @@ impl<'tcx> IntRange<'tcx> {
5856        ( * self . range . start ( ) ,  * self . range . end ( ) ) 
5957    } 
6058
61-     /// Don't treat `usize`/`isize` exhaustively unless the `precise_pointer_size_matching` feature 
62-      /// is enabled. 
63-      fn  treat_exhaustively ( & self ,  tcx :  TyCtxt < ' tcx > )  -> bool  { 
64-         !self . ty . is_ptr_sized_integral ( )  || tcx. features ( ) . precise_pointer_size_matching 
65-     } 
66- 
6759    #[ inline]  
68-     fn  integral_size_and_signed_bias ( tcx :  TyCtxt < ' tcx > ,  ty :  Ty < ' _ > )  -> Option < ( Size ,  u128 ) >  { 
60+     fn  integral_size_and_signed_bias ( tcx :  TyCtxt < ' _ > ,  ty :  Ty < ' _ > )  -> Option < ( Size ,  u128 ) >  { 
6961        match  * ty. kind ( )  { 
7062            ty:: Bool  => Some ( ( Size :: from_bytes ( 1 ) ,  0 ) ) , 
7163            ty:: Char  => Some ( ( Size :: from_bytes ( 4 ) ,  0 ) ) , 
@@ -79,12 +71,11 @@ impl<'tcx> IntRange<'tcx> {
7971    } 
8072
8173    #[ inline]  
82-     fn  from_const ( 
74+     fn  from_const < ' tcx > ( 
8375        tcx :  TyCtxt < ' tcx > , 
8476        param_env :  ty:: ParamEnv < ' tcx > , 
8577        value :  & Const < ' tcx > , 
86-         span :  Span , 
87-     )  -> Option < IntRange < ' tcx > >  { 
78+     )  -> Option < IntRange >  { 
8879        if  let  Some ( ( target_size,  bias) )  = Self :: integral_size_and_signed_bias ( tcx,  value. ty )  { 
8980            let  ty = value. ty ; 
9081            let  val = ( || { 
@@ -101,21 +92,20 @@ impl<'tcx> IntRange<'tcx> {
10192                value. try_eval_bits ( tcx,  param_env,  ty) 
10293            } ) ( ) ?; 
10394            let  val = val ^ bias; 
104-             Some ( IntRange  {  range :  val..=val,  ty ,  span  } ) 
95+             Some ( IntRange  {  range :  val..=val } ) 
10596        }  else  { 
10697            None 
10798        } 
10899    } 
109100
110101    #[ inline]  
111-     fn  from_range ( 
102+     fn  from_range < ' tcx > ( 
112103        tcx :  TyCtxt < ' tcx > , 
113104        lo :  u128 , 
114105        hi :  u128 , 
115106        ty :  Ty < ' tcx > , 
116107        end :  & RangeEnd , 
117-         span :  Span , 
118-     )  -> Option < IntRange < ' tcx > >  { 
108+     )  -> Option < IntRange >  { 
119109        if  Self :: is_integral ( ty)  { 
120110            // Perform a shift if the underlying types are signed, 
121111            // which makes the interval arithmetic simpler. 
@@ -126,14 +116,14 @@ impl<'tcx> IntRange<'tcx> {
126116                // This should have been caught earlier by E0030. 
127117                bug ! ( "malformed range pattern: {}..={}" ,  lo,  ( hi - offset) ) ; 
128118            } 
129-             Some ( IntRange  {  range :  lo..=( hi - offset) ,  ty ,  span  } ) 
119+             Some ( IntRange  {  range :  lo..=( hi - offset)  } ) 
130120        }  else  { 
131121            None 
132122        } 
133123    } 
134124
135125    // The return value of `signed_bias` should be XORed with an endpoint to encode/decode it. 
136-     fn  signed_bias ( tcx :  TyCtxt < ' tcx > ,  ty :  Ty < ' tcx > )  -> u128  { 
126+     fn  signed_bias ( tcx :  TyCtxt < ' _ > ,  ty :  Ty < ' _ > )  -> u128  { 
137127        match  * ty. kind ( )  { 
138128            ty:: Int ( ity)  => { 
139129                let  bits = Integer :: from_attr ( & tcx,  SignedInt ( ity) ) . size ( ) . bits ( )  as  u128 ; 
@@ -147,20 +137,13 @@ impl<'tcx> IntRange<'tcx> {
147137        other. range . start ( )  <= self . range . start ( )  && self . range . end ( )  <= other. range . end ( ) 
148138    } 
149139
150-     fn  intersection ( & self ,  tcx :  TyCtxt < ' tcx > ,  other :  & Self )  -> Option < Self >  { 
151-         let  ty = self . ty ; 
140+     fn  intersection ( & self ,  other :  & Self )  -> Option < Self >  { 
152141        let  ( lo,  hi)  = self . boundaries ( ) ; 
153142        let  ( other_lo,  other_hi)  = other. boundaries ( ) ; 
154-         if  self . treat_exhaustively ( tcx)  { 
155-             if  lo <= other_hi && other_lo <= hi { 
156-                 let  span = other. span ; 
157-                 Some ( IntRange  {  range :  max ( lo,  other_lo) ..=min ( hi,  other_hi) ,  ty,  span } ) 
158-             }  else  { 
159-                 None 
160-             } 
143+         if  lo <= other_hi && other_lo <= hi { 
144+             Some ( IntRange  {  range :  max ( lo,  other_lo) ..=min ( hi,  other_hi)  } ) 
161145        }  else  { 
162-             // If the range should not be treated exhaustively, fallback to checking for inclusion. 
163-             if  self . is_subrange ( other)  {  Some ( self . clone ( ) )  }  else  {  None  } 
146+             None 
164147        } 
165148    } 
166149
@@ -181,24 +164,23 @@ impl<'tcx> IntRange<'tcx> {
181164        lo == other_hi || hi == other_lo
182165    } 
183166
184-     fn  to_pat ( & self ,  tcx :  TyCtxt < ' tcx > )  -> Pat < ' tcx >  { 
167+     fn  to_pat < ' tcx > ( & self ,  tcx :  TyCtxt < ' tcx > ,   ty :   Ty < ' tcx > )  -> Pat < ' tcx >  { 
185168        let  ( lo,  hi)  = self . boundaries ( ) ; 
186169
187-         let  bias = IntRange :: signed_bias ( tcx,  self . ty ) ; 
170+         let  bias = IntRange :: signed_bias ( tcx,  ty) ; 
188171        let  ( lo,  hi)  = ( lo ^ bias,  hi ^ bias) ; 
189172
190-         let  ty  = ty:: ParamEnv :: empty ( ) . and ( self . ty ) ; 
191-         let  lo_const = ty:: Const :: from_bits ( tcx,  lo,  ty ) ; 
192-         let  hi_const = ty:: Const :: from_bits ( tcx,  hi,  ty ) ; 
173+         let  env  = ty:: ParamEnv :: empty ( ) . and ( ty) ; 
174+         let  lo_const = ty:: Const :: from_bits ( tcx,  lo,  env ) ; 
175+         let  hi_const = ty:: Const :: from_bits ( tcx,  hi,  env ) ; 
193176
194177        let  kind = if  lo == hi { 
195178            PatKind :: Constant  {  value :  lo_const } 
196179        }  else  { 
197180            PatKind :: Range ( PatRange  {  lo :  lo_const,  hi :  hi_const,  end :  RangeEnd :: Included  } ) 
198181        } ; 
199182
200-         // This is a brand new pattern, so we don't reuse `self.span`. 
201-         Pat  {  ty :  self . ty ,  span :  DUMMY_SP ,  kind :  Box :: new ( kind)  } 
183+         Pat  {  ty,  span :  DUMMY_SP ,  kind :  Box :: new ( kind)  } 
202184    } 
203185
204186    /// For exhaustive integer matching, some constructors are grouped within other constructors 
@@ -233,13 +215,11 @@ impl<'tcx> IntRange<'tcx> {
233215     /// boundaries for each interval range, sort them, then create constructors for each new interval 
234216     /// between every pair of boundary points. (This essentially sums up to performing the intuitive 
235217     /// merging operation depicted above.) 
236-      fn  split < ' p > ( 
218+      fn  split < ' p ,   ' tcx > ( 
237219        & self , 
238220        pcx :  PatCtxt < ' _ ,  ' p ,  ' tcx > , 
239221        hir_id :  Option < HirId > , 
240222    )  -> SmallVec < [ Constructor < ' tcx > ;  1 ] >  { 
241-         let  ty = pcx. ty ; 
242- 
243223        /// Represents a border between 2 integers. Because the intervals spanning borders 
244224         /// must be able to cover every integer, we need to be able to represent 
245225         /// 2^128 + 1 such borders. 
@@ -250,7 +230,7 @@ impl<'tcx> IntRange<'tcx> {
250230        } 
251231
252232        // A function for extracting the borders of an integer interval. 
253-         fn  range_borders ( r :  IntRange < ' _ > )  -> impl  Iterator < Item  = Border >  { 
233+         fn  range_borders ( r :  IntRange )  -> impl  Iterator < Item  = Border >  { 
254234            let  ( lo,  hi)  = r. range . into_inner ( ) ; 
255235            let  from = Border :: JustBefore ( lo) ; 
256236            let  to = match  hi. checked_add ( 1 )  { 
@@ -268,21 +248,23 @@ impl<'tcx> IntRange<'tcx> {
268248        // class lies between 2 borders. 
269249        let  row_borders = pcx
270250            . matrix 
271-             . head_ctors ( pcx. cx ) 
272-             . filter_map ( |ctor|  ctor. as_int_range ( ) ) 
273-             . filter_map ( |range| { 
274-                 let  intersection = self . intersection ( pcx . cx . tcx ,   & range) ; 
251+             . head_ctors_and_spans ( pcx. cx ) 
252+             . filter_map ( |( ctor,  span ) |  Some ( ( ctor. as_int_range ( ) ? ,  span ) ) ) 
253+             . filter_map ( |( range,  span ) | { 
254+                 let  intersection = self . intersection ( & range) ; 
275255                let  should_lint = self . suspicious_intersection ( & range) ; 
276256                if  let  ( Some ( range) ,  1 ,  true )  = ( & intersection,  row_len,  should_lint)  { 
277257                    // FIXME: for now, only check for overlapping ranges on simple range 
278258                    // patterns. Otherwise with the current logic the following is detected 
279259                    // as overlapping: 
280-                     //   match (10u8, true) { 
281-                     //    (0 ..= 125, false) => {} 
282-                     //    (126 ..= 255, false) => {} 
283-                     //    (0 ..= 255, true) => {} 
284-                     //  } 
285-                     overlaps. push ( range. clone ( ) ) ; 
260+                     // ``` 
261+                     // match (0u8, true) { 
262+                     //   (0 ..= 125, false) => {} 
263+                     //   (125 ..= 255, true) => {} 
264+                     //   _ => {} 
265+                     // } 
266+                     // ``` 
267+                     overlaps. push ( ( range. clone ( ) ,  span) ) ; 
286268                } 
287269                intersection
288270            } ) 
@@ -291,7 +273,7 @@ impl<'tcx> IntRange<'tcx> {
291273        let  mut  borders:  Vec < _ >  = row_borders. chain ( self_borders) . collect ( ) ; 
292274        borders. sort_unstable ( ) ; 
293275
294-         self . lint_overlapping_patterns ( pcx. cx . tcx ,  hir_id,  ty ,  overlaps) ; 
276+         self . lint_overlapping_patterns ( pcx,  hir_id,  overlaps) ; 
295277
296278        // We're going to iterate through every adjacent pair of borders, making sure that 
297279        // each represents an interval of nonnegative length, and convert each such 
@@ -309,33 +291,32 @@ impl<'tcx> IntRange<'tcx> {
309291                [ Border :: JustBefore ( n) ,  Border :: AfterMax ]  => Some ( n..=u128:: MAX ) , 
310292                [ Border :: AfterMax ,  _]  => None , 
311293            } ) 
312-             . map ( |range| IntRange  {  range,  ty ,   span :  pcx . span  } ) 
294+             . map ( |range| IntRange  {  range } ) 
313295            . map ( IntRange ) 
314296            . collect ( ) 
315297    } 
316298
317299    fn  lint_overlapping_patterns ( 
318300        & self , 
319-         tcx :   TyCtxt < ' tcx > , 
301+         pcx :   PatCtxt < ' _ ,   ' _ ,   ' _ > , 
320302        hir_id :  Option < HirId > , 
321-         ty :  Ty < ' tcx > , 
322-         overlaps :  Vec < IntRange < ' tcx > > , 
303+         overlaps :  Vec < ( IntRange ,  Span ) > , 
323304    )  { 
324305        if  let  ( true ,  Some ( hir_id) )  = ( !overlaps. is_empty ( ) ,  hir_id)  { 
325-             tcx. struct_span_lint_hir ( 
306+             pcx . cx . tcx . struct_span_lint_hir ( 
326307                lint:: builtin:: OVERLAPPING_PATTERNS , 
327308                hir_id, 
328-                 self . span , 
309+                 pcx . span , 
329310                |lint| { 
330311                    let  mut  err = lint. build ( "multiple patterns covering the same range" ) ; 
331-                     err. span_label ( self . span ,  "overlapping patterns" ) ; 
332-                     for  int_range in  overlaps { 
312+                     err. span_label ( pcx . span ,  "overlapping patterns" ) ; 
313+                     for  ( int_range,  span )  in  overlaps { 
333314                        // Use the real type for user display of the ranges: 
334315                        err. span_label ( 
335-                             int_range . span , 
316+                             span, 
336317                            & format ! ( 
337318                                "this range overlaps on `{}`" , 
338-                                 IntRange   {  range :   int_range. range ,  ty ,  span :   DUMMY_SP   } . to_pat( tcx) , 
319+                                 int_range. to_pat( pcx . cx . tcx,  pcx . ty ) , 
339320                            ) , 
340321                        ) ; 
341322                    } 
@@ -346,8 +327,8 @@ impl<'tcx> IntRange<'tcx> {
346327    } 
347328
348329    /// See `Constructor::is_covered_by` 
349-      fn  is_covered_by < ' p > ( & self ,   pcx :   PatCtxt < ' _ ,   ' p ,   ' tcx > ,  other :  & Self )  -> bool  { 
350-         if  self . intersection ( pcx . cx . tcx ,   other) . is_some ( )  { 
330+      fn  is_covered_by ( & self ,  other :  & Self )  -> bool  { 
331+         if  self . intersection ( other) . is_some ( )  { 
351332            // Constructor splitting should ensure that all intersections we encounter are actually 
352333            // inclusions. 
353334            assert ! ( self . is_subrange( other) ) ; 
@@ -358,13 +339,6 @@ impl<'tcx> IntRange<'tcx> {
358339    } 
359340} 
360341
361- /// Ignore spans when comparing, they don't carry semantic information as they are only for lints. 
362- impl < ' tcx >  std:: cmp:: PartialEq  for  IntRange < ' tcx >  { 
363-     fn  eq ( & self ,  other :  & Self )  -> bool  { 
364-         self . range  == other. range  && self . ty  == other. ty 
365-     } 
366- } 
367- 
368342#[ derive( Copy ,  Clone ,  Debug ,  PartialEq ,  Eq ) ]  
369343enum  SliceKind  { 
370344    /// Patterns of length `n` (`[x, y]`). 
@@ -558,7 +532,7 @@ pub(super) enum Constructor<'tcx> {
558532    /// Enum variants. 
559533     Variant ( DefId ) , 
560534    /// Ranges of integer literal values (`2`, `2..=5` or `2..5`). 
561-      IntRange ( IntRange < ' tcx > ) , 
535+      IntRange ( IntRange ) , 
562536    /// Ranges of floating-point literal values (`2.0..=5.2`). 
563537     FloatRange ( & ' tcx  ty:: Const < ' tcx > ,  & ' tcx  ty:: Const < ' tcx > ,  RangeEnd ) , 
564538    /// String literals. Strings are not quite the same as `&[u8]` so we treat them separately. 
@@ -581,7 +555,7 @@ impl<'tcx> Constructor<'tcx> {
581555        matches ! ( self ,  Wildcard ) 
582556    } 
583557
584-     fn  as_int_range ( & self )  -> Option < & IntRange < ' tcx > >  { 
558+     fn  as_int_range ( & self )  -> Option < & IntRange >  { 
585559        match  self  { 
586560            IntRange ( range)  => Some ( range) , 
587561            _ => None , 
@@ -616,8 +590,7 @@ impl<'tcx> Constructor<'tcx> {
616590                Variant ( adt_def. variants [ variant_index] . def_id ) 
617591            } 
618592            PatKind :: Constant  {  value }  => { 
619-                 if  let  Some ( int_range)  = IntRange :: from_const ( cx. tcx ,  cx. param_env ,  value,  pat. span ) 
620-                 { 
593+                 if  let  Some ( int_range)  = IntRange :: from_const ( cx. tcx ,  cx. param_env ,  value)  { 
621594                    IntRange ( int_range) 
622595                }  else  { 
623596                    match  pat. ty . kind ( )  { 
@@ -641,7 +614,6 @@ impl<'tcx> Constructor<'tcx> {
641614                    hi. eval_bits ( cx. tcx ,  cx. param_env ,  hi. ty ) , 
642615                    ty, 
643616                    & end, 
644-                     pat. span , 
645617                )  { 
646618                    IntRange ( int_range) 
647619                }  else  { 
@@ -694,11 +666,7 @@ impl<'tcx> Constructor<'tcx> {
694666            Wildcard  => Constructor :: split_wildcard ( pcx) , 
695667            // Fast-track if the range is trivial. In particular, we don't do the overlapping 
696668            // ranges check. 
697-             IntRange ( ctor_range) 
698-                 if  ctor_range. treat_exhaustively ( pcx. cx . tcx )  && !ctor_range. is_singleton ( )  =>
699-             { 
700-                 ctor_range. split ( pcx,  hir_id) 
701-             } 
669+             IntRange ( ctor_range)  if  !ctor_range. is_singleton ( )  => ctor_range. split ( pcx,  hir_id) , 
702670            Slice ( slice @ Slice  {  kind :  VarLen ( ..) ,  .. } )  => slice. split ( pcx) , 
703671            // Any other constructor can be used unchanged. 
704672            _ => smallvec ! [ self . clone( ) ] , 
@@ -740,9 +708,7 @@ impl<'tcx> Constructor<'tcx> {
740708            ( Single ,  Single )  => true , 
741709            ( Variant ( self_id) ,  Variant ( other_id) )  => self_id == other_id, 
742710
743-             ( IntRange ( self_range) ,  IntRange ( other_range) )  => { 
744-                 self_range. is_covered_by ( pcx,  other_range) 
745-             } 
711+             ( IntRange ( self_range) ,  IntRange ( other_range) )  => self_range. is_covered_by ( other_range) , 
746712            ( 
747713                FloatRange ( self_from,  self_to,  self_end) , 
748714                FloatRange ( other_from,  other_to,  other_end) , 
@@ -803,15 +769,15 @@ impl<'tcx> Constructor<'tcx> {
803769            IntRange ( range)  => used_ctors
804770                . iter ( ) 
805771                . filter_map ( |c| c. as_int_range ( ) ) 
806-                 . any ( |other| range. is_covered_by ( pcx ,   other) ) , 
772+                 . any ( |other| range. is_covered_by ( other) ) , 
807773            Slice ( slice)  => used_ctors
808774                . iter ( ) 
809775                . filter_map ( |c| c. as_slice ( ) ) 
810776                . any ( |other| slice. is_covered_by ( other) ) , 
811777            // This constructor is never covered by anything else 
812778            NonExhaustive  => false , 
813779            Str ( ..)  | FloatRange ( ..)  | Opaque  | Wildcard  => { 
814-                 bug ! ( "found unexpected ctor in all_ctors: {:?}" ,  self ) 
780+                 span_bug ! ( pcx . span ,   "found unexpected ctor in all_ctors: {:?}" ,  self ) 
815781            } 
816782        } 
817783    } 
@@ -832,8 +798,7 @@ fn all_constructors<'p, 'tcx>(pcx: PatCtxt<'_, 'p, 'tcx>) -> Vec<Constructor<'tc
832798    let  make_range = |start,  end| { 
833799        IntRange ( 
834800            // `unwrap()` is ok because we know the type is an integer. 
835-             IntRange :: from_range ( cx. tcx ,  start,  end,  pcx. ty ,  & RangeEnd :: Included ,  pcx. span ) 
836-                 . unwrap ( ) , 
801+             IntRange :: from_range ( cx. tcx ,  start,  end,  pcx. ty ,  & RangeEnd :: Included ) . unwrap ( ) , 
837802        ) 
838803    } ; 
839804    match  pcx. ty . kind ( )  { 
@@ -1238,7 +1203,7 @@ impl<'p, 'tcx> Fields<'p, 'tcx> {
12381203            } , 
12391204            & Str ( value)  => PatKind :: Constant  {  value } , 
12401205            & FloatRange ( lo,  hi,  end)  => PatKind :: Range ( PatRange  {  lo,  hi,  end } ) , 
1241-             IntRange ( range)  => return  range. to_pat ( pcx. cx . tcx ) , 
1206+             IntRange ( range)  => return  range. to_pat ( pcx. cx . tcx ,  pcx . ty ) , 
12421207            NonExhaustive  => PatKind :: Wild , 
12431208            Opaque  => bug ! ( "we should not try to apply an opaque constructor" ) , 
12441209            Wildcard  => bug ! ( 
0 commit comments