@@ -4,7 +4,7 @@ use rustc_data_structures::captures::Captures;
4
4
use rustc_middle:: ty;
5
5
use rustc_session:: lint;
6
6
use rustc_session:: lint:: builtin:: NON_EXHAUSTIVE_OMITTED_PATTERNS ;
7
- use rustc_span:: Span ;
7
+ use rustc_span:: { ErrorGuaranteed , Span } ;
8
8
9
9
use crate :: constructor:: { IntRange , MaybeInfiniteInt } ;
10
10
use crate :: errors:: {
@@ -59,9 +59,13 @@ impl<'p, 'tcx> PatternColumn<'p, 'tcx> {
59
59
}
60
60
61
61
/// Do constructor splitting on the constructors of the column.
62
- fn analyze_ctors ( & self , pcx : & PlaceCtxt < ' _ , ' p , ' tcx > ) -> SplitConstructorSet < ' p , ' tcx > {
62
+ fn analyze_ctors (
63
+ & self ,
64
+ pcx : & PlaceCtxt < ' _ , ' p , ' tcx > ,
65
+ ) -> Result < SplitConstructorSet < ' p , ' tcx > , ErrorGuaranteed > {
63
66
let column_ctors = self . patterns . iter ( ) . map ( |p| p. ctor ( ) ) ;
64
- pcx. ctors_for_ty ( ) . split ( pcx, column_ctors)
67
+ let ctors_for_ty = & pcx. ctors_for_ty ( ) ?;
68
+ Ok ( ctors_for_ty. split ( pcx, column_ctors) )
65
69
}
66
70
67
71
fn iter ( & self ) -> impl Iterator < Item = & ' p DeconstructedPat < ' p , ' tcx > > + Captures < ' _ > {
@@ -106,18 +110,18 @@ impl<'p, 'tcx> PatternColumn<'p, 'tcx> {
106
110
fn collect_nonexhaustive_missing_variants < ' a , ' p , ' tcx > (
107
111
cx : MatchCtxt < ' a , ' p , ' tcx > ,
108
112
column : & PatternColumn < ' p , ' tcx > ,
109
- ) -> Vec < WitnessPat < ' p , ' tcx > > {
113
+ ) -> Result < Vec < WitnessPat < ' p , ' tcx > > , ErrorGuaranteed > {
110
114
let Some ( ty) = column. head_ty ( ) else {
111
- return Vec :: new ( ) ;
115
+ return Ok ( Vec :: new ( ) ) ;
112
116
} ;
113
117
let pcx = & PlaceCtxt :: new_dummy ( cx, ty) ;
114
118
115
- let set = column. analyze_ctors ( pcx) ;
119
+ let set = column. analyze_ctors ( pcx) ? ;
116
120
if set. present . is_empty ( ) {
117
121
// We can't consistently handle the case where no constructors are present (since this would
118
122
// require digging deep through any type in case there's a non_exhaustive enum somewhere),
119
123
// so for consistency we refuse to handle the top-level case, where we could handle it.
120
- return vec ! [ ] ;
124
+ return Ok ( Vec :: new ( ) ) ;
121
125
}
122
126
123
127
let mut witnesses = Vec :: new ( ) ;
@@ -137,7 +141,7 @@ fn collect_nonexhaustive_missing_variants<'a, 'p, 'tcx>(
137
141
let wild_pat = WitnessPat :: wild_from_ctor ( pcx, ctor) ;
138
142
for ( i, col_i) in specialized_columns. iter ( ) . enumerate ( ) {
139
143
// Compute witnesses for each column.
140
- let wits_for_col_i = collect_nonexhaustive_missing_variants ( cx, col_i) ;
144
+ let wits_for_col_i = collect_nonexhaustive_missing_variants ( cx, col_i) ? ;
141
145
// For each witness, we build a new pattern in the shape of `ctor(_, _, wit, _, _)`,
142
146
// adding enough wildcards to match `arity`.
143
147
for wit in wits_for_col_i {
@@ -147,21 +151,21 @@ fn collect_nonexhaustive_missing_variants<'a, 'p, 'tcx>(
147
151
}
148
152
}
149
153
}
150
- witnesses
154
+ Ok ( witnesses)
151
155
}
152
156
153
157
pub ( crate ) fn lint_nonexhaustive_missing_variants < ' a , ' p , ' tcx > (
154
158
cx : MatchCtxt < ' a , ' p , ' tcx > ,
155
159
arms : & [ MatchArm < ' p , ' tcx > ] ,
156
160
pat_column : & PatternColumn < ' p , ' tcx > ,
157
161
scrut_ty : RevealedTy < ' tcx > ,
158
- ) {
162
+ ) -> Result < ( ) , ErrorGuaranteed > {
159
163
let rcx: & RustcMatchCheckCtxt < ' _ , ' _ > = cx. tycx ;
160
164
if !matches ! (
161
165
rcx. tcx. lint_level_at_node( NON_EXHAUSTIVE_OMITTED_PATTERNS , rcx. match_lint_level) . 0 ,
162
166
rustc_session:: lint:: Level :: Allow
163
167
) {
164
- let witnesses = collect_nonexhaustive_missing_variants ( cx, pat_column) ;
168
+ let witnesses = collect_nonexhaustive_missing_variants ( cx, pat_column) ? ;
165
169
if !witnesses. is_empty ( ) {
166
170
// Report that a match of a `non_exhaustive` enum marked with `non_exhaustive_omitted_patterns`
167
171
// is not exhaustive enough.
@@ -200,21 +204,22 @@ pub(crate) fn lint_nonexhaustive_missing_variants<'a, 'p, 'tcx>(
200
204
}
201
205
}
202
206
}
207
+ Ok ( ( ) )
203
208
}
204
209
205
210
/// Traverse the patterns to warn the user about ranges that overlap on their endpoints.
206
211
#[ instrument( level = "debug" , skip( cx) ) ]
207
212
pub ( crate ) fn lint_overlapping_range_endpoints < ' a , ' p , ' tcx > (
208
213
cx : MatchCtxt < ' a , ' p , ' tcx > ,
209
214
column : & PatternColumn < ' p , ' tcx > ,
210
- ) {
215
+ ) -> Result < ( ) , ErrorGuaranteed > {
211
216
let Some ( ty) = column. head_ty ( ) else {
212
- return ;
217
+ return Ok ( ( ) ) ;
213
218
} ;
214
219
let pcx = & PlaceCtxt :: new_dummy ( cx, ty) ;
215
220
let rcx: & RustcMatchCheckCtxt < ' _ , ' _ > = cx. tycx ;
216
221
217
- let set = column. analyze_ctors ( pcx) ;
222
+ let set = column. analyze_ctors ( pcx) ? ;
218
223
219
224
if matches ! ( ty. kind( ) , ty:: Char | ty:: Int ( _) | ty:: Uint ( _) ) {
220
225
let emit_lint = |overlap : & IntRange , this_span : Span , overlapped_spans : & [ Span ] | {
@@ -271,8 +276,9 @@ pub(crate) fn lint_overlapping_range_endpoints<'a, 'p, 'tcx>(
271
276
// Recurse into the fields.
272
277
for ctor in set. present {
273
278
for col in column. specialize ( pcx, & ctor) {
274
- lint_overlapping_range_endpoints ( cx, & col) ;
279
+ lint_overlapping_range_endpoints ( cx, & col) ? ;
275
280
}
276
281
}
277
282
}
283
+ Ok ( ( ) )
278
284
}
0 commit comments