@@ -4,8 +4,7 @@ use rustc_span::ErrorGuaranteed;
4
4
use crate :: constructor:: { Constructor , SplitConstructorSet } ;
5
5
use crate :: errors:: { NonExhaustiveOmittedPattern , NonExhaustiveOmittedPatternLintOnArm , Uncovered } ;
6
6
use crate :: pat:: { DeconstructedPat , PatOrWild } ;
7
- use crate :: rustc:: { MatchCtxt , RevealedTy , RustcMatchCheckCtxt , WitnessPat } ;
8
- use crate :: usefulness:: PlaceCtxt ;
7
+ use crate :: rustc:: { RevealedTy , RustcMatchCheckCtxt , WitnessPat } ;
9
8
use crate :: { MatchArm , TypeCx } ;
10
9
11
10
/// A column of patterns in the matrix, where a column is the intuitive notion of "subpatterns that
@@ -50,9 +49,9 @@ impl<'p, Cx: TypeCx> PatternColumn<'p, Cx> {
50
49
}
51
50
52
51
/// Do constructor splitting on the constructors of the column.
53
- fn analyze_ctors ( & self , pcx : & PlaceCtxt < ' _ , Cx > ) -> Result < SplitConstructorSet < Cx > , Cx :: Error > {
52
+ fn analyze_ctors ( & self , cx : & Cx , ty : & Cx :: Ty ) -> Result < SplitConstructorSet < Cx > , Cx :: Error > {
54
53
let column_ctors = self . patterns . iter ( ) . map ( |p| p. ctor ( ) ) ;
55
- let ctors_for_ty = & pcx . ctors_for_ty ( ) ?;
54
+ let ctors_for_ty = cx . ctors_for_ty ( ty ) ?;
56
55
Ok ( ctors_for_ty. split ( column_ctors) )
57
56
}
58
57
@@ -63,10 +62,11 @@ impl<'p, Cx: TypeCx> PatternColumn<'p, Cx> {
63
62
/// which may change the lengths.
64
63
fn specialize (
65
64
& self ,
66
- pcx : & PlaceCtxt < ' _ , Cx > ,
65
+ cx : & Cx ,
66
+ ty : & Cx :: Ty ,
67
67
ctor : & Constructor < Cx > ,
68
68
) -> Vec < PatternColumn < ' p , Cx > > {
69
- let arity = ctor. arity ( pcx ) ;
69
+ let arity = ctor. arity ( cx , ty ) ;
70
70
if arity == 0 {
71
71
return Vec :: new ( ) ;
72
72
}
@@ -77,7 +77,7 @@ impl<'p, Cx: TypeCx> PatternColumn<'p, Cx> {
77
77
let mut specialized_columns: Vec < _ > =
78
78
( 0 ..arity) . map ( |_| Self { patterns : Vec :: new ( ) } ) . collect ( ) ;
79
79
let relevant_patterns =
80
- self . patterns . iter ( ) . filter ( |pat| ctor. is_covered_by ( pcx , pat. ctor ( ) ) ) ;
80
+ self . patterns . iter ( ) . filter ( |pat| ctor. is_covered_by ( cx , pat. ctor ( ) ) ) ;
81
81
for pat in relevant_patterns {
82
82
let specialized = pat. specialize ( ctor, arity) ;
83
83
for ( subpat, column) in specialized. into_iter ( ) . zip ( & mut specialized_columns) {
@@ -92,15 +92,14 @@ impl<'p, Cx: TypeCx> PatternColumn<'p, Cx> {
92
92
/// in a given column.
93
93
#[ instrument( level = "debug" , skip( cx) , ret) ]
94
94
fn collect_nonexhaustive_missing_variants < ' a , ' p , ' tcx > (
95
- cx : MatchCtxt < ' a , ' p , ' tcx > ,
95
+ cx : & RustcMatchCheckCtxt < ' p , ' tcx > ,
96
96
column : & PatternColumn < ' p , RustcMatchCheckCtxt < ' p , ' tcx > > ,
97
97
) -> Result < Vec < WitnessPat < ' p , ' tcx > > , ErrorGuaranteed > {
98
98
let Some ( & ty) = column. head_ty ( ) else {
99
99
return Ok ( Vec :: new ( ) ) ;
100
100
} ;
101
- let pcx = & PlaceCtxt :: new_dummy ( cx, & ty) ;
102
101
103
- let set = column. analyze_ctors ( pcx ) ?;
102
+ let set = column. analyze_ctors ( cx , & ty ) ?;
104
103
if set. present . is_empty ( ) {
105
104
// We can't consistently handle the case where no constructors are present (since this would
106
105
// require digging deep through any type in case there's a non_exhaustive enum somewhere),
@@ -109,20 +108,20 @@ fn collect_nonexhaustive_missing_variants<'a, 'p, 'tcx>(
109
108
}
110
109
111
110
let mut witnesses = Vec :: new ( ) ;
112
- if cx. tycx . is_foreign_non_exhaustive_enum ( ty) {
111
+ if cx. is_foreign_non_exhaustive_enum ( ty) {
113
112
witnesses. extend (
114
113
set. missing
115
114
. into_iter ( )
116
115
// This will list missing visible variants.
117
116
. filter ( |c| !matches ! ( c, Constructor :: Hidden | Constructor :: NonExhaustive ) )
118
- . map ( |missing_ctor| WitnessPat :: wild_from_ctor ( pcx , missing_ctor) ) ,
117
+ . map ( |missing_ctor| WitnessPat :: wild_from_ctor ( cx , missing_ctor, ty ) ) ,
119
118
)
120
119
}
121
120
122
121
// Recurse into the fields.
123
122
for ctor in set. present {
124
- let specialized_columns = column. specialize ( pcx , & ctor) ;
125
- let wild_pat = WitnessPat :: wild_from_ctor ( pcx , ctor) ;
123
+ let specialized_columns = column. specialize ( cx , & ty , & ctor) ;
124
+ let wild_pat = WitnessPat :: wild_from_ctor ( cx , ctor, ty ) ;
126
125
for ( i, col_i) in specialized_columns. iter ( ) . enumerate ( ) {
127
126
// Compute witnesses for each column.
128
127
let wits_for_col_i = collect_nonexhaustive_missing_variants ( cx, col_i) ?;
@@ -138,18 +137,17 @@ fn collect_nonexhaustive_missing_variants<'a, 'p, 'tcx>(
138
137
Ok ( witnesses)
139
138
}
140
139
141
- pub ( crate ) fn lint_nonexhaustive_missing_variants < ' a , ' p , ' tcx > (
142
- cx : MatchCtxt < ' a , ' p , ' tcx > ,
140
+ pub ( crate ) fn lint_nonexhaustive_missing_variants < ' p , ' tcx > (
141
+ rcx : & RustcMatchCheckCtxt < ' p , ' tcx > ,
143
142
arms : & [ MatchArm < ' p , RustcMatchCheckCtxt < ' p , ' tcx > > ] ,
144
143
pat_column : & PatternColumn < ' p , RustcMatchCheckCtxt < ' p , ' tcx > > ,
145
144
scrut_ty : RevealedTy < ' tcx > ,
146
145
) -> Result < ( ) , ErrorGuaranteed > {
147
- let rcx: & RustcMatchCheckCtxt < ' _ , ' _ > = cx. tycx ;
148
146
if !matches ! (
149
147
rcx. tcx. lint_level_at_node( NON_EXHAUSTIVE_OMITTED_PATTERNS , rcx. match_lint_level) . 0 ,
150
148
rustc_session:: lint:: Level :: Allow
151
149
) {
152
- let witnesses = collect_nonexhaustive_missing_variants ( cx , pat_column) ?;
150
+ let witnesses = collect_nonexhaustive_missing_variants ( rcx , pat_column) ?;
153
151
if !witnesses. is_empty ( ) {
154
152
// Report that a match of a `non_exhaustive` enum marked with `non_exhaustive_omitted_patterns`
155
153
// is not exhaustive enough.
0 commit comments