11use smallvec:: SmallVec ;
22
33use rustc_data_structures:: captures:: Captures ;
4- use rustc_middle:: ty:: { self , Ty } ;
4+ use rustc_middle:: ty;
55use rustc_session:: lint;
66use rustc_session:: lint:: builtin:: NON_EXHAUSTIVE_OMITTED_PATTERNS ;
77use rustc_span:: Span ;
@@ -11,11 +11,11 @@ use crate::errors::{
1111 NonExhaustiveOmittedPattern , NonExhaustiveOmittedPatternLintOnArm , Overlap ,
1212 OverlappingRangeEndpoints , Uncovered ,
1313} ;
14+ use crate :: pat:: PatOrWild ;
1415use crate :: rustc:: {
15- Constructor , DeconstructedPat , MatchArm , MatchCtxt , PlaceCtxt , RustcMatchCheckCtxt ,
16+ Constructor , DeconstructedPat , MatchArm , MatchCtxt , PlaceCtxt , RevealedTy , RustcMatchCheckCtxt ,
1617 SplitConstructorSet , WitnessPat ,
1718} ;
18- use crate :: TypeCx ;
1919
2020/// A column of patterns in the matrix, where a column is the intuitive notion of "subpatterns that
2121/// inspect the same subvalue/place".
@@ -34,28 +34,24 @@ pub(crate) struct PatternColumn<'p, 'tcx> {
3434
3535impl < ' p , ' tcx > PatternColumn < ' p , ' tcx > {
3636 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 ( ) ) } ;
3838 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 ) ) ;
4440 }
45- Self { patterns }
46- }
47-
48- fn is_empty ( & self ) -> bool {
49- self . patterns . is_empty ( )
41+ column
5042 }
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)
5450 }
51+ }
5552
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 ( ) )
5955 }
6056
6157 /// Do constructor splitting on the constructors of the column.
@@ -91,21 +87,11 @@ impl<'p, 'tcx> PatternColumn<'p, 'tcx> {
9187 let relevant_patterns =
9288 self . patterns . iter ( ) . filter ( |pat| ctor. is_covered_by ( pcx, pat. ctor ( ) ) ) ;
9389 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) ;
10193 }
10294 }
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- ) ;
10995 specialized_columns
11096 }
11197}
@@ -117,7 +103,7 @@ fn collect_nonexhaustive_missing_variants<'a, 'p, 'tcx>(
117103 cx : MatchCtxt < ' a , ' p , ' tcx > ,
118104 column : & PatternColumn < ' p , ' tcx > ,
119105) -> Vec < WitnessPat < ' p , ' tcx > > {
120- let Some ( ty) = column. head_ty ( cx ) else {
106+ let Some ( ty) = column. head_ty ( ) else {
121107 return Vec :: new ( ) ;
122108 } ;
123109 let pcx = & PlaceCtxt :: new_dummy ( cx, ty) ;
@@ -164,7 +150,7 @@ pub(crate) fn lint_nonexhaustive_missing_variants<'a, 'p, 'tcx>(
164150 cx : MatchCtxt < ' a , ' p , ' tcx > ,
165151 arms : & [ MatchArm < ' p , ' tcx > ] ,
166152 pat_column : & PatternColumn < ' p , ' tcx > ,
167- scrut_ty : Ty < ' tcx > ,
153+ scrut_ty : RevealedTy < ' tcx > ,
168154) {
169155 let rcx: & RustcMatchCheckCtxt < ' _ , ' _ > = cx. tycx ;
170156 if !matches ! (
@@ -182,7 +168,7 @@ pub(crate) fn lint_nonexhaustive_missing_variants<'a, 'p, 'tcx>(
182168 rcx. match_lint_level ,
183169 rcx. scrut_span ,
184170 NonExhaustiveOmittedPattern {
185- scrut_ty,
171+ scrut_ty : scrut_ty . inner ( ) ,
186172 uncovered : Uncovered :: new ( rcx. scrut_span , rcx, witnesses) ,
187173 } ,
188174 ) ;
@@ -218,7 +204,7 @@ pub(crate) fn lint_overlapping_range_endpoints<'a, 'p, 'tcx>(
218204 cx : MatchCtxt < ' a , ' p , ' tcx > ,
219205 column : & PatternColumn < ' p , ' tcx > ,
220206) {
221- let Some ( ty) = column. head_ty ( cx ) else {
207+ let Some ( ty) = column. head_ty ( ) else {
222208 return ;
223209 } ;
224210 let pcx = & PlaceCtxt :: new_dummy ( cx, ty) ;
0 commit comments