|
1 |
| -use smallvec::SmallVec; |
2 |
| - |
3 |
| -use rustc_data_structures::captures::Captures; |
4 |
| -use rustc_middle::ty; |
5 | 1 | use rustc_session::lint;
|
6 | 2 | use rustc_session::lint::builtin::NON_EXHAUSTIVE_OMITTED_PATTERNS;
|
7 |
| -use rustc_span::{ErrorGuaranteed, Span}; |
| 3 | +use rustc_span::ErrorGuaranteed; |
8 | 4 |
|
9 |
| -use crate::constructor::{IntRange, MaybeInfiniteInt}; |
10 | 5 | use crate::errors::{
|
11 |
| - NonExhaustiveOmittedPattern, NonExhaustiveOmittedPatternLintOnArm, Overlap, |
12 |
| - OverlappingRangeEndpoints, Uncovered, |
| 6 | + self, NonExhaustiveOmittedPattern, NonExhaustiveOmittedPatternLintOnArm, Uncovered, |
13 | 7 | };
|
14 | 8 | use crate::pat::PatOrWild;
|
15 | 9 | use crate::rustc::{
|
16 |
| - Constructor, DeconstructedPat, MatchArm, MatchCtxt, PlaceCtxt, RevealedTy, RustcMatchCheckCtxt, |
17 |
| - SplitConstructorSet, WitnessPat, |
| 10 | + self, Constructor, DeconstructedPat, MatchArm, MatchCtxt, PlaceCtxt, RevealedTy, |
| 11 | + RustcMatchCheckCtxt, SplitConstructorSet, WitnessPat, |
18 | 12 | };
|
19 | 13 |
|
20 | 14 | /// A column of patterns in the matrix, where a column is the intuitive notion of "subpatterns that
|
@@ -68,10 +62,6 @@ impl<'p, 'tcx> PatternColumn<'p, 'tcx> {
|
68 | 62 | Ok(ctors_for_ty.split(pcx, column_ctors))
|
69 | 63 | }
|
70 | 64 |
|
71 |
| - fn iter(&self) -> impl Iterator<Item = &'p DeconstructedPat<'p, 'tcx>> + Captures<'_> { |
72 |
| - self.patterns.iter().copied() |
73 |
| - } |
74 |
| - |
75 | 65 | /// Does specialization: given a constructor, this takes the patterns from the column that match
|
76 | 66 | /// the constructor, and outputs their fields.
|
77 | 67 | /// This returns one column per field of the constructor. They usually all have the same length
|
@@ -207,78 +197,25 @@ pub(crate) fn lint_nonexhaustive_missing_variants<'a, 'p, 'tcx>(
|
207 | 197 | Ok(())
|
208 | 198 | }
|
209 | 199 |
|
210 |
| -/// Traverse the patterns to warn the user about ranges that overlap on their endpoints. |
211 |
| -#[instrument(level = "debug", skip(cx))] |
212 | 200 | pub(crate) fn lint_overlapping_range_endpoints<'a, 'p, 'tcx>(
|
213 | 201 | cx: MatchCtxt<'a, 'p, 'tcx>,
|
214 |
| - column: &PatternColumn<'p, 'tcx>, |
215 |
| -) -> Result<(), ErrorGuaranteed> { |
216 |
| - let Some(ty) = column.head_ty() else { |
217 |
| - return Ok(()); |
218 |
| - }; |
219 |
| - let pcx = &PlaceCtxt::new_dummy(cx, ty); |
220 |
| - let rcx: &RustcMatchCheckCtxt<'_, '_> = cx.tycx; |
221 |
| - |
222 |
| - let set = column.analyze_ctors(pcx)?; |
223 |
| - |
224 |
| - if matches!(ty.kind(), ty::Char | ty::Int(_) | ty::Uint(_)) { |
225 |
| - let emit_lint = |overlap: &IntRange, this_span: Span, overlapped_spans: &[Span]| { |
226 |
| - let overlap_as_pat = rcx.hoist_pat_range(overlap, ty); |
227 |
| - let overlaps: Vec<_> = overlapped_spans |
228 |
| - .iter() |
229 |
| - .copied() |
230 |
| - .map(|span| Overlap { range: overlap_as_pat.clone(), span }) |
231 |
| - .collect(); |
232 |
| - rcx.tcx.emit_spanned_lint( |
233 |
| - lint::builtin::OVERLAPPING_RANGE_ENDPOINTS, |
234 |
| - rcx.match_lint_level, |
235 |
| - this_span, |
236 |
| - OverlappingRangeEndpoints { overlap: overlaps, range: this_span }, |
237 |
| - ); |
238 |
| - }; |
239 |
| - |
240 |
| - // If two ranges overlapped, the split set will contain their intersection as a singleton. |
241 |
| - let split_int_ranges = set.present.iter().filter_map(|c| c.as_int_range()); |
242 |
| - for overlap_range in split_int_ranges.clone() { |
243 |
| - if overlap_range.is_singleton() { |
244 |
| - let overlap: MaybeInfiniteInt = overlap_range.lo; |
245 |
| - // Ranges that look like `lo..=overlap`. |
246 |
| - let mut prefixes: SmallVec<[_; 1]> = Default::default(); |
247 |
| - // Ranges that look like `overlap..=hi`. |
248 |
| - let mut suffixes: SmallVec<[_; 1]> = Default::default(); |
249 |
| - // Iterate on patterns that contained `overlap`. |
250 |
| - for pat in column.iter() { |
251 |
| - let Constructor::IntRange(this_range) = pat.ctor() else { continue }; |
252 |
| - let this_span = pat.data().unwrap().span; |
253 |
| - if this_range.is_singleton() { |
254 |
| - // Don't lint when one of the ranges is a singleton. |
255 |
| - continue; |
256 |
| - } |
257 |
| - if this_range.lo == overlap { |
258 |
| - // `this_range` looks like `overlap..=this_range.hi`; it overlaps with any |
259 |
| - // ranges that look like `lo..=overlap`. |
260 |
| - if !prefixes.is_empty() { |
261 |
| - emit_lint(overlap_range, this_span, &prefixes); |
262 |
| - } |
263 |
| - suffixes.push(this_span) |
264 |
| - } else if this_range.hi == overlap.plus_one() { |
265 |
| - // `this_range` looks like `this_range.lo..=overlap`; it overlaps with any |
266 |
| - // ranges that look like `overlap..=hi`. |
267 |
| - if !suffixes.is_empty() { |
268 |
| - emit_lint(overlap_range, this_span, &suffixes); |
269 |
| - } |
270 |
| - prefixes.push(this_span) |
271 |
| - } |
272 |
| - } |
273 |
| - } |
274 |
| - } |
275 |
| - } else { |
276 |
| - // Recurse into the fields. |
277 |
| - for ctor in set.present { |
278 |
| - for col in column.specialize(pcx, &ctor) { |
279 |
| - lint_overlapping_range_endpoints(cx, &col)?; |
280 |
| - } |
281 |
| - } |
| 202 | + overlapping_range_endpoints: &[rustc::OverlappingRanges<'p, 'tcx>], |
| 203 | +) { |
| 204 | + let rcx = cx.tycx; |
| 205 | + for overlap in overlapping_range_endpoints { |
| 206 | + let overlap_as_pat = rcx.hoist_pat_range(&overlap.overlaps_on, overlap.pat.ty()); |
| 207 | + let overlaps: Vec<_> = overlap |
| 208 | + .overlaps_with |
| 209 | + .iter() |
| 210 | + .map(|pat| pat.data().unwrap().span) |
| 211 | + .map(|span| errors::Overlap { range: overlap_as_pat.clone(), span }) |
| 212 | + .collect(); |
| 213 | + let pat_span = overlap.pat.data().unwrap().span; |
| 214 | + rcx.tcx.emit_spanned_lint( |
| 215 | + lint::builtin::OVERLAPPING_RANGE_ENDPOINTS, |
| 216 | + rcx.match_lint_level, |
| 217 | + pat_span, |
| 218 | + errors::OverlappingRangeEndpoints { overlap: overlaps, range: pat_span }, |
| 219 | + ); |
282 | 220 | }
|
283 |
| - Ok(()) |
284 | 221 | }
|
0 commit comments