Translate Overlap eagerly

This commit is contained in:
mejrs 2023-01-09 22:37:56 +01:00 committed by David Tolnay
parent 3d260fa63c
commit 372ac9c1a2
No known key found for this signature in database
GPG Key ID: F9BA143B95FF6D82
4 changed files with 19 additions and 12 deletions

View File

@ -323,8 +323,6 @@ mir_build_overlapping_range_endpoints = multiple patterns overlap on their endpo
.range = ... with this range .range = ... with this range
.note = you likely meant to write mutually exclusive ranges .note = you likely meant to write mutually exclusive ranges
mir_build_overlapping_range = this range overlaps on `{$range}`...
mir_build_non_exhaustive_omitted_pattern = some variants are not matched explicitly mir_build_non_exhaustive_omitted_pattern = some variants are not matched explicitly
.help = ensure that all variants are matched explicitly by adding the suggested match arms .help = ensure that all variants are matched explicitly by adding the suggested match arms
.note = the matched value is of type `{$scrut_ty}` and the `non_exhaustive_omitted_patterns` attribute was found .note = the matched value is of type `{$scrut_ty}` and the `non_exhaustive_omitted_patterns` attribute was found

View File

@ -677,17 +677,28 @@ pub struct OverlappingRangeEndpoints<'tcx> {
#[label(range)] #[label(range)]
pub range: Span, pub range: Span,
#[subdiagnostic] #[subdiagnostic]
pub overlap: Overlap<'tcx>, pub overlap: Vec<Overlap<'tcx>>,
} }
#[derive(Subdiagnostic)]
#[label(mir_build_overlapping_range)]
pub struct Overlap<'tcx> { pub struct Overlap<'tcx> {
#[primary_span]
pub span: Span, pub span: Span,
pub range: Pat<'tcx>, pub range: Pat<'tcx>,
} }
impl<'tcx> AddToDiagnostic for Overlap<'tcx> {
fn add_to_diagnostic_with<F>(self, diag: &mut Diagnostic, _: F)
where
F: Fn(&mut Diagnostic, SubdiagnosticMessage) -> SubdiagnosticMessage,
{
let Overlap { span, range } = self;
// FIXME(mejrs) unfortunately `#[derive(LintDiagnostic)]`
// does not support `#[subdiagnostic(eager)]`...
let message = format!("this range overlaps on `{range}`...");
diag.span_label(span, message);
}
}
#[derive(LintDiagnostic)] #[derive(LintDiagnostic)]
#[diag(mir_build_non_exhaustive_omitted_pattern)] #[diag(mir_build_non_exhaustive_omitted_pattern)]
#[help] #[help]

View File

@ -285,19 +285,16 @@ pub(super) fn lint_overlapping_range_endpoints<'a, 'p: 'a, 'tcx: 'a>(
return; return;
} }
// Get the first overlap. We get only the first rather than all of them let overlap: Vec<_> = pats
// because displaying multiple overlaps requires a way to eagerly translate
// lintdiagnostics, but that doesn't exist.
let overlap = pats
.filter_map(|pat| Some((pat.ctor().as_int_range()?, pat.span()))) .filter_map(|pat| Some((pat.ctor().as_int_range()?, pat.span())))
.filter(|(range, _)| self.suspicious_intersection(range)) .filter(|(range, _)| self.suspicious_intersection(range))
.map(|(range, span)| Overlap { .map(|(range, span)| Overlap {
range: self.intersection(&range).unwrap().to_pat(pcx.cx.tcx, pcx.ty), range: self.intersection(&range).unwrap().to_pat(pcx.cx.tcx, pcx.ty),
span, span,
}) })
.next(); .collect();
if let Some(overlap) = overlap { if !overlap.is_empty() {
pcx.cx.tcx.emit_spanned_lint( pcx.cx.tcx.emit_spanned_lint(
lint::builtin::OVERLAPPING_RANGE_ENDPOINTS, lint::builtin::OVERLAPPING_RANGE_ENDPOINTS,
hir_id, hir_id,

View File

@ -59,6 +59,7 @@ error: multiple patterns overlap on their endpoints
LL | 0..=10 => {} LL | 0..=10 => {}
| ------ this range overlaps on `10_u8`... | ------ this range overlaps on `10_u8`...
LL | 20..=30 => {} LL | 20..=30 => {}
| ------- this range overlaps on `20_u8`...
LL | 10..=20 => {} LL | 10..=20 => {}
| ^^^^^^^ ... with this range | ^^^^^^^ ... with this range
| |