Skip to content
This repository was archived by the owner on May 28, 2025. It is now read-only.

Commit 7948f91

Browse files
committed
Run the annoying lint separately
1 parent 5a24b2c commit 7948f91

File tree

2 files changed

+43
-54
lines changed

2 files changed

+43
-54
lines changed

compiler/rustc_mir_build/src/thir/pattern/deconstruct_pat.rs

Lines changed: 36 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ use rustc_middle::mir::Field;
1919
use rustc_middle::ty::layout::IntegerExt;
2020
use rustc_middle::ty::{self, Const, Ty, TyCtxt};
2121
use rustc_session::lint;
22-
use rustc_span::{Span, DUMMY_SP};
22+
use rustc_span::DUMMY_SP;
2323
use rustc_target::abi::{Integer, Size, VariantIdx};
2424

2525
use smallvec::{smallvec, SmallVec};
@@ -184,51 +184,42 @@ impl IntRange {
184184
}
185185

186186
/// Split this range, as described at the top of the file.
187-
fn split<'p, 'tcx>(
188-
&self,
189-
pcx: PatCtxt<'_, 'p, 'tcx>,
190-
hir_id: Option<HirId>,
191-
) -> SmallVec<[Constructor<'tcx>; 1]> {
192-
// We collect the span and range of all the intersecting ranges to lint on likely incorrect
193-
// range patterns. (#63987)
194-
let mut overlaps = vec![];
187+
fn split<'p, 'tcx>(&self, pcx: PatCtxt<'_, 'p, 'tcx>) -> SmallVec<[Constructor<'tcx>; 1]> {
195188
let mut split_range = SplitIntRange::new(self.clone());
196-
let row_len = pcx.matrix.column_count().unwrap_or(0);
197-
let intranges = pcx
198-
.matrix
199-
.head_ctors_and_spans(pcx.cx)
200-
.filter_map(|(ctor, span)| Some((ctor.as_int_range()?, span)));
201-
let intranges = intranges.inspect(|(range, span)| {
202-
if let Some(intersection) = self.intersection(&range) {
203-
if row_len == 1 && self.suspicious_intersection(&range) {
204-
// FIXME: for now, only check for overlapping ranges on simple range
205-
// patterns. Otherwise with the current logic the following is detected
206-
// as overlapping:
207-
// ```
208-
// match (0u8, true) {
209-
// (0 ..= 125, false) => {}
210-
// (125 ..= 255, true) => {}
211-
// _ => {}
212-
// }
213-
// ```
214-
overlaps.push((intersection.clone(), *span));
215-
}
216-
}
217-
});
218-
split_range.split(intranges.map(|(range, _)| range).cloned());
219-
220-
self.lint_overlapping_range_endpoints(pcx, hir_id, overlaps);
221-
189+
let intranges = pcx.matrix.head_ctors(pcx.cx).filter_map(|ctor| ctor.as_int_range());
190+
split_range.split(intranges.cloned());
222191
split_range.iter().map(IntRange).collect()
223192
}
224193

225-
fn lint_overlapping_range_endpoints(
226-
&self,
227-
pcx: PatCtxt<'_, '_, '_>,
228-
hir_id: Option<HirId>,
229-
overlaps: Vec<(IntRange, Span)>,
230-
) {
231-
if let (true, Some(hir_id)) = (!overlaps.is_empty(), hir_id) {
194+
/// Lint on likely incorrect range patterns (#63987)
195+
pub(super) fn lint_overlapping_range_endpoints(&self, pcx: PatCtxt<'_, '_, '_>, hir_id: HirId) {
196+
if self.is_singleton() {
197+
return;
198+
}
199+
200+
if pcx.matrix.column_count().unwrap_or(0) != 1 {
201+
// FIXME: for now, only check for overlapping ranges on simple range
202+
// patterns. Otherwise with the current logic the following is detected
203+
// as overlapping:
204+
// ```
205+
// match (0u8, true) {
206+
// (0 ..= 125, false) => {}
207+
// (125 ..= 255, true) => {}
208+
// _ => {}
209+
// }
210+
// ```
211+
return;
212+
}
213+
214+
let overlaps: Vec<_> = pcx
215+
.matrix
216+
.head_ctors_and_spans(pcx.cx)
217+
.filter_map(|(ctor, span)| Some((ctor.as_int_range()?, span)))
218+
.filter(|(range, _)| self.suspicious_intersection(range))
219+
.map(|(range, span)| (self.intersection(&range).unwrap(), span))
220+
.collect();
221+
222+
if !overlaps.is_empty() {
232223
pcx.cx.tcx.struct_span_lint_hir(
233224
lint::builtin::OVERLAPPING_RANGE_ENDPOINTS,
234225
hir_id,
@@ -673,21 +664,14 @@ impl<'tcx> Constructor<'tcx> {
673664
/// This function may discard some irrelevant constructors if this preserves behavior and
674665
/// diagnostics. Eg. for the `_` case, we ignore the constructors already present in the
675666
/// matrix, unless all of them are.
676-
///
677-
/// `hir_id` is `None` when we're evaluating the wildcard pattern. In that case we do not want
678-
/// to lint for overlapping ranges.
679-
pub(super) fn split<'p>(
680-
&self,
681-
pcx: PatCtxt<'_, 'p, 'tcx>,
682-
hir_id: Option<HirId>,
683-
) -> SmallVec<[Self; 1]> {
667+
pub(super) fn split<'p>(&self, pcx: PatCtxt<'_, 'p, 'tcx>) -> SmallVec<[Self; 1]> {
684668
debug!("Constructor::split({:#?}, {:#?})", self, pcx.matrix);
685669

686670
match self {
687671
Wildcard => Constructor::split_wildcard(pcx),
688672
// Fast-track if the range is trivial. In particular, we don't do the overlapping
689673
// ranges check.
690-
IntRange(ctor_range) if !ctor_range.is_singleton() => ctor_range.split(pcx, hir_id),
674+
IntRange(ctor_range) if !ctor_range.is_singleton() => ctor_range.split(pcx),
691675
Slice(slice @ Slice { kind: VarLen(..), .. }) => slice.split(pcx),
692676
// Any other constructor can be used unchanged.
693677
_ => smallvec![self.clone()],
@@ -937,7 +921,7 @@ impl<'tcx> MissingConstructors<'tcx> {
937921
pcx.matrix.head_ctors(pcx.cx).cloned().filter(|c| !c.is_wildcard()).collect();
938922
// Since `all_ctors` never contains wildcards, this won't recurse further.
939923
let all_ctors =
940-
all_constructors(pcx).into_iter().flat_map(|ctor| ctor.split(pcx, None)).collect();
924+
all_constructors(pcx).into_iter().flat_map(|ctor| ctor.split(pcx)).collect();
941925

942926
MissingConstructors { all_ctors, used_ctors }
943927
}

compiler/rustc_mir_build/src/thir/pattern/usefulness.rs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -991,11 +991,16 @@ fn is_useful<'p, 'tcx>(
991991
});
992992
Usefulness::merge(usefulnesses)
993993
} else {
994+
let v_ctor = v.head_ctor(cx);
995+
if let Constructor::IntRange(ctor_range) = &v_ctor {
996+
// Lint on likely incorrect range patterns (#63987)
997+
ctor_range.lint_overlapping_range_endpoints(pcx, hir_id)
998+
}
994999
// We split the head constructor of `v`.
995-
let ctors = v.head_ctor(cx).split(pcx, Some(hir_id));
1000+
let split_ctors = v_ctor.split(pcx);
9961001
// For each constructor, we compute whether there's a value that starts with it that would
9971002
// witness the usefulness of `v`.
998-
let usefulnesses = ctors.into_iter().map(|ctor| {
1003+
let usefulnesses = split_ctors.into_iter().map(|ctor| {
9991004
// We cache the result of `Fields::wildcards` because it is used a lot.
10001005
let ctor_wild_subpatterns = Fields::wildcards(pcx, &ctor);
10011006
let matrix = pcx.matrix.specialize_constructor(pcx, &ctor, &ctor_wild_subpatterns);

0 commit comments

Comments
 (0)