@@ -19,7 +19,7 @@ use rustc_middle::mir::Field;
1919use rustc_middle:: ty:: layout:: IntegerExt ;
2020use rustc_middle:: ty:: { self , Const , Ty , TyCtxt } ;
2121use rustc_session:: lint;
22- use rustc_span:: { Span , DUMMY_SP } ;
22+ use rustc_span:: DUMMY_SP ;
2323use rustc_target:: abi:: { Integer , Size , VariantIdx } ;
2424
2525use smallvec:: { smallvec, SmallVec } ;
@@ -184,51 +184,42 @@ impl IntRange {
184184 }
185185
186186 /// Split this range, as described at the top of the file.
187- fn split < ' p , ' tcx > (
188- & self ,
189- pcx : PatCtxt < ' _ , ' p , ' tcx > ,
190- hir_id : Option < HirId > ,
191- ) -> SmallVec < [ Constructor < ' tcx > ; 1 ] > {
192- // We collect the span and range of all the intersecting ranges to lint on likely incorrect
193- // range patterns. (#63987)
194- let mut overlaps = vec ! [ ] ;
187+ fn split < ' p , ' tcx > ( & self , pcx : PatCtxt < ' _ , ' p , ' tcx > ) -> SmallVec < [ Constructor < ' tcx > ; 1 ] > {
195188 let mut split_range = SplitIntRange :: new ( self . clone ( ) ) ;
196- let row_len = pcx. matrix . column_count ( ) . unwrap_or ( 0 ) ;
197- let intranges = pcx
198- . matrix
199- . head_ctors_and_spans ( pcx. cx )
200- . filter_map ( |( ctor, span) | Some ( ( ctor. as_int_range ( ) ?, span) ) ) ;
201- let intranges = intranges. inspect ( |( range, span) | {
202- if let Some ( intersection) = self . intersection ( & range) {
203- if row_len == 1 && self . suspicious_intersection ( & range) {
204- // FIXME: for now, only check for overlapping ranges on simple range
205- // patterns. Otherwise with the current logic the following is detected
206- // as overlapping:
207- // ```
208- // match (0u8, true) {
209- // (0 ..= 125, false) => {}
210- // (125 ..= 255, true) => {}
211- // _ => {}
212- // }
213- // ```
214- overlaps. push ( ( intersection. clone ( ) , * span) ) ;
215- }
216- }
217- } ) ;
218- split_range. split ( intranges. map ( |( range, _) | range) . cloned ( ) ) ;
219-
220- self . lint_overlapping_range_endpoints ( pcx, hir_id, overlaps) ;
221-
189+ let intranges = pcx. matrix . head_ctors ( pcx. cx ) . filter_map ( |ctor| ctor. as_int_range ( ) ) ;
190+ split_range. split ( intranges. cloned ( ) ) ;
222191 split_range. iter ( ) . map ( IntRange ) . collect ( )
223192 }
224193
225- fn lint_overlapping_range_endpoints (
226- & self ,
227- pcx : PatCtxt < ' _ , ' _ , ' _ > ,
228- hir_id : Option < HirId > ,
229- overlaps : Vec < ( IntRange , Span ) > ,
230- ) {
231- if let ( true , Some ( hir_id) ) = ( !overlaps. is_empty ( ) , hir_id) {
194+ /// Lint on likely incorrect range patterns (#63987)
195+ pub ( super ) fn lint_overlapping_range_endpoints ( & self , pcx : PatCtxt < ' _ , ' _ , ' _ > , hir_id : HirId ) {
196+ if self . is_singleton ( ) {
197+ return ;
198+ }
199+
200+ if pcx. matrix . column_count ( ) . unwrap_or ( 0 ) != 1 {
201+ // FIXME: for now, only check for overlapping ranges on simple range
202+ // patterns. Otherwise with the current logic the following is detected
203+ // as overlapping:
204+ // ```
205+ // match (0u8, true) {
206+ // (0 ..= 125, false) => {}
207+ // (125 ..= 255, true) => {}
208+ // _ => {}
209+ // }
210+ // ```
211+ return ;
212+ }
213+
214+ let overlaps: Vec < _ > = pcx
215+ . matrix
216+ . head_ctors_and_spans ( pcx. cx )
217+ . filter_map ( |( ctor, span) | Some ( ( ctor. as_int_range ( ) ?, span) ) )
218+ . filter ( |( range, _) | self . suspicious_intersection ( range) )
219+ . map ( |( range, span) | ( self . intersection ( & range) . unwrap ( ) , span) )
220+ . collect ( ) ;
221+
222+ if !overlaps. is_empty ( ) {
232223 pcx. cx . tcx . struct_span_lint_hir (
233224 lint:: builtin:: OVERLAPPING_RANGE_ENDPOINTS ,
234225 hir_id,
@@ -673,21 +664,14 @@ impl<'tcx> Constructor<'tcx> {
673664 /// This function may discard some irrelevant constructors if this preserves behavior and
674665 /// diagnostics. Eg. for the `_` case, we ignore the constructors already present in the
675666 /// matrix, unless all of them are.
676- ///
677- /// `hir_id` is `None` when we're evaluating the wildcard pattern. In that case we do not want
678- /// to lint for overlapping ranges.
679- pub ( super ) fn split < ' p > (
680- & self ,
681- pcx : PatCtxt < ' _ , ' p , ' tcx > ,
682- hir_id : Option < HirId > ,
683- ) -> SmallVec < [ Self ; 1 ] > {
667+ pub ( super ) fn split < ' p > ( & self , pcx : PatCtxt < ' _ , ' p , ' tcx > ) -> SmallVec < [ Self ; 1 ] > {
684668 debug ! ( "Constructor::split({:#?}, {:#?})" , self , pcx. matrix) ;
685669
686670 match self {
687671 Wildcard => Constructor :: split_wildcard ( pcx) ,
688672 // Fast-track if the range is trivial. In particular, we don't do the overlapping
689673 // ranges check.
690- IntRange ( ctor_range) if !ctor_range. is_singleton ( ) => ctor_range. split ( pcx, hir_id ) ,
674+ IntRange ( ctor_range) if !ctor_range. is_singleton ( ) => ctor_range. split ( pcx) ,
691675 Slice ( slice @ Slice { kind : VarLen ( ..) , .. } ) => slice. split ( pcx) ,
692676 // Any other constructor can be used unchanged.
693677 _ => smallvec ! [ self . clone( ) ] ,
@@ -937,7 +921,7 @@ impl<'tcx> MissingConstructors<'tcx> {
937921 pcx. matrix . head_ctors ( pcx. cx ) . cloned ( ) . filter ( |c| !c. is_wildcard ( ) ) . collect ( ) ;
938922 // Since `all_ctors` never contains wildcards, this won't recurse further.
939923 let all_ctors =
940- all_constructors ( pcx) . into_iter ( ) . flat_map ( |ctor| ctor. split ( pcx, None ) ) . collect ( ) ;
924+ all_constructors ( pcx) . into_iter ( ) . flat_map ( |ctor| ctor. split ( pcx) ) . collect ( ) ;
941925
942926 MissingConstructors { all_ctors, used_ctors }
943927 }
0 commit comments