From 372ac9c1a29820f4393ba59eb49f81959bca2926 Mon Sep 17 00:00:00 2001 From: mejrs <> Date: Mon, 9 Jan 2023 22:37:56 +0100 Subject: [PATCH] Translate `Overlap` eagerly --- .../locales/en-US/mir_build.ftl | 2 -- compiler/rustc_mir_build/src/errors.rs | 19 +++++++++++++++---- .../src/thir/pattern/deconstruct_pat.rs | 9 +++------ .../overlapping_range_endpoints.stderr | 1 + 4 files changed, 19 insertions(+), 12 deletions(-) diff --git a/compiler/rustc_error_messages/locales/en-US/mir_build.ftl b/compiler/rustc_error_messages/locales/en-US/mir_build.ftl index 976614ecd9e..801a5b31e02 100644 --- a/compiler/rustc_error_messages/locales/en-US/mir_build.ftl +++ b/compiler/rustc_error_messages/locales/en-US/mir_build.ftl @@ -323,8 +323,6 @@ mir_build_overlapping_range_endpoints = multiple patterns overlap on their endpo .range = ... with this range .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 .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 diff --git a/compiler/rustc_mir_build/src/errors.rs b/compiler/rustc_mir_build/src/errors.rs index 1b2fbae2cd5..39b67d995fa 100644 --- a/compiler/rustc_mir_build/src/errors.rs +++ b/compiler/rustc_mir_build/src/errors.rs @@ -677,17 +677,28 @@ pub struct OverlappingRangeEndpoints<'tcx> { #[label(range)] pub range: Span, #[subdiagnostic] - pub overlap: Overlap<'tcx>, + pub overlap: Vec>, } -#[derive(Subdiagnostic)] -#[label(mir_build_overlapping_range)] pub struct Overlap<'tcx> { - #[primary_span] pub span: Span, pub range: Pat<'tcx>, } +impl<'tcx> AddToDiagnostic for Overlap<'tcx> { + fn add_to_diagnostic_with(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)] #[diag(mir_build_non_exhaustive_omitted_pattern)] #[help] diff --git a/compiler/rustc_mir_build/src/thir/pattern/deconstruct_pat.rs b/compiler/rustc_mir_build/src/thir/pattern/deconstruct_pat.rs index 323df1b8147..17b3c475f83 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/deconstruct_pat.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/deconstruct_pat.rs @@ -285,19 +285,16 @@ pub(super) fn lint_overlapping_range_endpoints<'a, 'p: 'a, 'tcx: 'a>( return; } - // Get the first overlap. We get only the first rather than all of them - // because displaying multiple overlaps requires a way to eagerly translate - // lintdiagnostics, but that doesn't exist. - let overlap = pats + let overlap: Vec<_> = pats .filter_map(|pat| Some((pat.ctor().as_int_range()?, pat.span()))) .filter(|(range, _)| self.suspicious_intersection(range)) .map(|(range, span)| Overlap { range: self.intersection(&range).unwrap().to_pat(pcx.cx.tcx, pcx.ty), span, }) - .next(); + .collect(); - if let Some(overlap) = overlap { + if !overlap.is_empty() { pcx.cx.tcx.emit_spanned_lint( lint::builtin::OVERLAPPING_RANGE_ENDPOINTS, hir_id, diff --git a/tests/ui/pattern/usefulness/integer-ranges/overlapping_range_endpoints.stderr b/tests/ui/pattern/usefulness/integer-ranges/overlapping_range_endpoints.stderr index a1c802add17..ea0e8f6e49e 100644 --- a/tests/ui/pattern/usefulness/integer-ranges/overlapping_range_endpoints.stderr +++ b/tests/ui/pattern/usefulness/integer-ranges/overlapping_range_endpoints.stderr @@ -59,6 +59,7 @@ error: multiple patterns overlap on their endpoints LL | 0..=10 => {} | ------ this range overlaps on `10_u8`... LL | 20..=30 => {} + | ------- this range overlaps on `20_u8`... LL | 10..=20 => {} | ^^^^^^^ ... with this range |