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