1
1
use smallvec:: SmallVec ;
2
2
3
3
use rustc_data_structures:: captures:: Captures ;
4
- use rustc_middle:: ty:: { self , Ty } ;
4
+ use rustc_middle:: ty;
5
5
use rustc_session:: lint;
6
6
use rustc_session:: lint:: builtin:: NON_EXHAUSTIVE_OMITTED_PATTERNS ;
7
7
use rustc_span:: Span ;
@@ -11,11 +11,11 @@ use crate::errors::{
11
11
NonExhaustiveOmittedPattern , NonExhaustiveOmittedPatternLintOnArm , Overlap ,
12
12
OverlappingRangeEndpoints , Uncovered ,
13
13
} ;
14
+ use crate :: pat:: PatOrWild ;
14
15
use crate :: rustc:: {
15
- Constructor , DeconstructedPat , MatchArm , MatchCtxt , PlaceCtxt , RustcMatchCheckCtxt ,
16
+ Constructor , DeconstructedPat , MatchArm , MatchCtxt , PlaceCtxt , RevealedTy , RustcMatchCheckCtxt ,
16
17
SplitConstructorSet , WitnessPat ,
17
18
} ;
18
- use crate :: TypeCx ;
19
19
20
20
/// A column of patterns in the matrix, where a column is the intuitive notion of "subpatterns that
21
21
/// inspect the same subvalue/place".
@@ -34,28 +34,24 @@ pub(crate) struct PatternColumn<'p, 'tcx> {
34
34
35
35
impl < ' p , ' tcx > PatternColumn < ' p , ' tcx > {
36
36
pub ( crate ) fn new ( arms : & [ MatchArm < ' p , ' tcx > ] ) -> Self {
37
- let mut patterns = Vec :: with_capacity ( arms. len ( ) ) ;
37
+ let mut column = PatternColumn { patterns : Vec :: with_capacity ( arms. len ( ) ) } ;
38
38
for arm in arms {
39
- if arm. pat . is_or_pat ( ) {
40
- patterns. extend ( arm. pat . flatten_or_pat ( ) )
41
- } else {
42
- patterns. push ( arm. pat )
43
- }
39
+ column. expand_and_push ( PatOrWild :: Pat ( arm. pat ) ) ;
44
40
}
45
- Self { patterns }
46
- }
47
-
48
- fn is_empty ( & self ) -> bool {
49
- self . patterns . is_empty ( )
41
+ column
50
42
}
51
- fn head_ty ( & self , cx : MatchCtxt < ' _ , ' p , ' tcx > ) -> Option < Ty < ' tcx > > {
52
- if self . patterns . len ( ) == 0 {
53
- return None ;
43
+ fn expand_and_push ( & mut self , pat : PatOrWild < ' p , RustcMatchCheckCtxt < ' p , ' tcx > > ) {
44
+ if pat. is_or_pat ( ) {
45
+ self . patterns . extend (
46
+ pat. flatten_or_pat ( ) . into_iter ( ) . filter_map ( |pat_or_wild| pat_or_wild. as_pat ( ) ) ,
47
+ )
48
+ } else if let Some ( pat) = pat. as_pat ( ) {
49
+ self . patterns . push ( pat)
54
50
}
51
+ }
55
52
56
- let ty = self . patterns [ 0 ] . ty ( ) ;
57
- // FIXME(Nadrieril): `Cx` should only give us revealed types.
58
- Some ( cx. tycx . reveal_opaque_ty ( ty) )
53
+ fn head_ty ( & self ) -> Option < RevealedTy < ' tcx > > {
54
+ self . patterns . first ( ) . map ( |pat| pat. ty ( ) )
59
55
}
60
56
61
57
/// Do constructor splitting on the constructors of the column.
@@ -91,21 +87,11 @@ impl<'p, 'tcx> PatternColumn<'p, 'tcx> {
91
87
let relevant_patterns =
92
88
self . patterns . iter ( ) . filter ( |pat| ctor. is_covered_by ( pcx, pat. ctor ( ) ) ) ;
93
89
for pat in relevant_patterns {
94
- let specialized = pat. specialize ( pcx, ctor) ;
95
- for ( subpat, column) in specialized. iter ( ) . zip ( & mut specialized_columns) {
96
- if subpat. is_or_pat ( ) {
97
- column. patterns . extend ( subpat. flatten_or_pat ( ) )
98
- } else {
99
- column. patterns . push ( subpat)
100
- }
90
+ let specialized = pat. specialize ( ctor, pcx. ctor_arity ( ctor) ) ;
91
+ for ( subpat, column) in specialized. into_iter ( ) . zip ( & mut specialized_columns) {
92
+ column. expand_and_push ( subpat) ;
101
93
}
102
94
}
103
-
104
- assert ! (
105
- !specialized_columns[ 0 ] . is_empty( ) ,
106
- "ctor {ctor:?} was listed as present but isn't;
107
- there is an inconsistency between `Constructor::is_covered_by` and `ConstructorSet::split`"
108
- ) ;
109
95
specialized_columns
110
96
}
111
97
}
@@ -117,7 +103,7 @@ fn collect_nonexhaustive_missing_variants<'a, 'p, 'tcx>(
117
103
cx : MatchCtxt < ' a , ' p , ' tcx > ,
118
104
column : & PatternColumn < ' p , ' tcx > ,
119
105
) -> Vec < WitnessPat < ' p , ' tcx > > {
120
- let Some ( ty) = column. head_ty ( cx ) else {
106
+ let Some ( ty) = column. head_ty ( ) else {
121
107
return Vec :: new ( ) ;
122
108
} ;
123
109
let pcx = & PlaceCtxt :: new_dummy ( cx, ty) ;
@@ -164,7 +150,7 @@ pub(crate) fn lint_nonexhaustive_missing_variants<'a, 'p, 'tcx>(
164
150
cx : MatchCtxt < ' a , ' p , ' tcx > ,
165
151
arms : & [ MatchArm < ' p , ' tcx > ] ,
166
152
pat_column : & PatternColumn < ' p , ' tcx > ,
167
- scrut_ty : Ty < ' tcx > ,
153
+ scrut_ty : RevealedTy < ' tcx > ,
168
154
) {
169
155
let rcx: & RustcMatchCheckCtxt < ' _ , ' _ > = cx. tycx ;
170
156
if !matches ! (
@@ -182,7 +168,7 @@ pub(crate) fn lint_nonexhaustive_missing_variants<'a, 'p, 'tcx>(
182
168
rcx. match_lint_level ,
183
169
rcx. scrut_span ,
184
170
NonExhaustiveOmittedPattern {
185
- scrut_ty,
171
+ scrut_ty : scrut_ty . inner ( ) ,
186
172
uncovered : Uncovered :: new ( rcx. scrut_span , rcx, witnesses) ,
187
173
} ,
188
174
) ;
@@ -218,7 +204,7 @@ pub(crate) fn lint_overlapping_range_endpoints<'a, 'p, 'tcx>(
218
204
cx : MatchCtxt < ' a , ' p , ' tcx > ,
219
205
column : & PatternColumn < ' p , ' tcx > ,
220
206
) {
221
- let Some ( ty) = column. head_ty ( cx ) else {
207
+ let Some ( ty) = column. head_ty ( ) else {
222
208
return ;
223
209
} ;
224
210
let pcx = & PlaceCtxt :: new_dummy ( cx, ty) ;
0 commit comments