@@ -19,7 +19,7 @@ use rustc_middle::mir::Field;
19
19
use rustc_middle:: ty:: layout:: IntegerExt ;
20
20
use rustc_middle:: ty:: { self , Const , Ty , TyCtxt } ;
21
21
use rustc_session:: lint;
22
- use rustc_span:: { Span , DUMMY_SP } ;
22
+ use rustc_span:: DUMMY_SP ;
23
23
use rustc_target:: abi:: { Integer , Size , VariantIdx } ;
24
24
25
25
use smallvec:: { smallvec, SmallVec } ;
@@ -184,51 +184,42 @@ impl IntRange {
184
184
}
185
185
186
186
/// 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 ] > {
195
188
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 ( ) ) ;
222
191
split_range. iter ( ) . map ( IntRange ) . collect ( )
223
192
}
224
193
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 ( ) {
232
223
pcx. cx . tcx . struct_span_lint_hir (
233
224
lint:: builtin:: OVERLAPPING_RANGE_ENDPOINTS ,
234
225
hir_id,
@@ -673,21 +664,14 @@ impl<'tcx> Constructor<'tcx> {
673
664
/// This function may discard some irrelevant constructors if this preserves behavior and
674
665
/// diagnostics. Eg. for the `_` case, we ignore the constructors already present in the
675
666
/// 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 ] > {
684
668
debug ! ( "Constructor::split({:#?}, {:#?})" , self , pcx. matrix) ;
685
669
686
670
match self {
687
671
Wildcard => Constructor :: split_wildcard ( pcx) ,
688
672
// Fast-track if the range is trivial. In particular, we don't do the overlapping
689
673
// 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) ,
691
675
Slice ( slice @ Slice { kind : VarLen ( ..) , .. } ) => slice. split ( pcx) ,
692
676
// Any other constructor can be used unchanged.
693
677
_ => smallvec ! [ self . clone( ) ] ,
@@ -937,7 +921,7 @@ impl<'tcx> MissingConstructors<'tcx> {
937
921
pcx. matrix . head_ctors ( pcx. cx ) . cloned ( ) . filter ( |c| !c. is_wildcard ( ) ) . collect ( ) ;
938
922
// Since `all_ctors` never contains wildcards, this won't recurse further.
939
923
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 ( ) ;
941
925
942
926
MissingConstructors { all_ctors, used_ctors }
943
927
}
0 commit comments