Skip to content

Commit 5d2b9a9

Browse files
mejrsdtolnay
mejrs
authored andcommitted
Migrate deconstruct_pat.rs
1 parent 519b1ab commit 5d2b9a9

File tree

5 files changed

+48
-23
lines changed

5 files changed

+48
-23
lines changed

compiler/rustc_error_messages/locales/en-US/mir_build.ftl

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -317,4 +317,10 @@ mir_build_indirect_structural_match =
317317
to use a constant of type `{$non_sm_ty}` in a pattern, `{$non_sm_ty}` must be annotated with `#[derive(PartialEq, Eq)]`
318318
319319
mir_build_nontrivial_structural_match =
320-
to use a constant of type `{$non_sm_ty}` in a pattern, the constant's initializer must be trivial or `{$non_sm_ty}` must be annotated with `#[derive(PartialEq, Eq)]`
320+
to use a constant of type `{$non_sm_ty}` in a pattern, the constant's initializer must be trivial or `{$non_sm_ty}` must be annotated with `#[derive(PartialEq, Eq)]`
321+
322+
mir_build_overlapping_range_endpoints = multiple patterns overlap on their endpoints
323+
.range = ... with this range
324+
.note = you likely meant to write mutually exclusive ranges
325+
326+
mir_build_overlapping_range = this range overlaps on `{$range}`...

compiler/rustc_middle/src/thir.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
//! [rustc dev guide]: https://rustc-dev-guide.rust-lang.org/thir.html
1010
1111
use rustc_ast::{InlineAsmOptions, InlineAsmTemplatePiece};
12+
use rustc_errors::{DiagnosticArgValue, IntoDiagnosticArg};
1213
use rustc_hir as hir;
1314
use rustc_hir::def_id::DefId;
1415
use rustc_hir::RangeEnd;
@@ -575,6 +576,12 @@ impl<'tcx> Pat<'tcx> {
575576
}
576577
}
577578

579+
impl<'tcx> IntoDiagnosticArg for Pat<'tcx> {
580+
fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
581+
format!("{}", self).into_diagnostic_arg()
582+
}
583+
}
584+
578585
#[derive(Clone, Debug, HashStable)]
579586
pub struct Ascription<'tcx> {
580587
pub annotation: CanonicalUserTypeAnnotation<'tcx>,

compiler/rustc_mir_build/src/errors.rs

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ use rustc_errors::{
44
error_code, Applicability, DiagnosticBuilder, ErrorGuaranteed, IntoDiagnostic, MultiSpan,
55
};
66
use rustc_macros::{Diagnostic, LintDiagnostic, Subdiagnostic};
7+
use rustc_middle::thir::Pat;
78
use rustc_middle::ty::{self, Ty};
89
use rustc_span::{symbol::Ident, Span};
910

@@ -665,3 +666,22 @@ pub struct IndirectStructuralMatch<'tcx> {
665666
pub struct NontrivialStructuralMatch<'tcx> {
666667
pub non_sm_ty: Ty<'tcx>,
667668
}
669+
670+
#[derive(LintDiagnostic)]
671+
#[diag(mir_build_overlapping_range_endpoints)]
672+
#[note]
673+
pub struct OverlappingRangeEndpoints<'tcx> {
674+
#[label(range)]
675+
pub range: Span,
676+
#[subdiagnostic]
677+
pub overlap: Overlap<'tcx>,
678+
}
679+
680+
#[derive(Debug)]
681+
#[derive(Subdiagnostic)]
682+
#[label(mir_build_overlapping_range)]
683+
pub struct Overlap<'tcx> {
684+
#[primary_span]
685+
pub span: Span,
686+
pub range: Pat<'tcx>,
687+
}

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

Lines changed: 14 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ use self::SliceKind::*;
6767

6868
use super::compare_const_vals;
6969
use super::usefulness::{MatchCheckCtxt, PatCtxt};
70+
use crate::errors::{Overlap, OverlappingRangeEndpoints};
7071

7172
/// Recursively expand this pattern into its subpatterns. Only useful for or-patterns.
7273
fn expand_or_pat<'p, 'tcx>(pat: &'p Pat<'tcx>) -> Vec<&'p Pat<'tcx>> {
@@ -96,7 +97,7 @@ fn expand_or_pat<'p, 'tcx>(pat: &'p Pat<'tcx>) -> Vec<&'p Pat<'tcx>> {
9697
/// `IntRange` is never used to encode an empty range or a "range" that wraps
9798
/// around the (offset) space: i.e., `range.lo <= range.hi`.
9899
#[derive(Clone, PartialEq, Eq)]
99-
pub(super) struct IntRange {
100+
pub(crate) struct IntRange {
100101
range: RangeInclusive<u128>,
101102
/// Keeps the bias used for encoding the range. It depends on the type of the range and
102103
/// possibly the pointer size of the current architecture. The algorithm ensures we never
@@ -284,32 +285,24 @@ impl IntRange {
284285
return;
285286
}
286287

287-
let overlaps: Vec<_> = pats
288+
// Get the first overlap. We get only the first rather than all of them
289+
// because displaying multiple overlaps requires a way to eagerly translate
290+
// lintdiagnostics, but that doesn't exist.
291+
let overlap = pats
288292
.filter_map(|pat| Some((pat.ctor().as_int_range()?, pat.span())))
289293
.filter(|(range, _)| self.suspicious_intersection(range))
290-
.map(|(range, span)| (self.intersection(&range).unwrap(), span))
291-
.collect();
294+
.map(|(range, span)| Overlap {
295+
range: self.intersection(&range).unwrap().to_pat(pcx.cx.tcx, pcx.ty),
296+
span,
297+
})
298+
.next();
292299

293-
if !overlaps.is_empty() {
294-
pcx.cx.tcx.struct_span_lint_hir(
300+
if let Some(overlap) = overlap {
301+
pcx.cx.tcx.emit_spanned_lint(
295302
lint::builtin::OVERLAPPING_RANGE_ENDPOINTS,
296303
hir_id,
297304
pcx.span,
298-
"multiple patterns overlap on their endpoints",
299-
|lint| {
300-
for (int_range, span) in overlaps {
301-
lint.span_label(
302-
span,
303-
&format!(
304-
"this range overlaps on `{}`...",
305-
int_range.to_pat(pcx.cx.tcx, pcx.ty)
306-
),
307-
);
308-
}
309-
lint.span_label(pcx.span, "... with this range");
310-
lint.note("you likely meant to write mutually exclusive ranges");
311-
lint
312-
},
305+
OverlappingRangeEndpoints { overlap, range: pcx.span },
313306
);
314307
}
315308
}

tests/ui/pattern/usefulness/integer-ranges/overlapping_range_endpoints.stderr

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,6 @@ error: multiple patterns overlap on their endpoints
5959
LL | 0..=10 => {}
6060
| ------ this range overlaps on `10_u8`...
6161
LL | 20..=30 => {}
62-
| ------- this range overlaps on `20_u8`...
6362
LL | 10..=20 => {}
6463
| ^^^^^^^ ... with this range
6564
|

0 commit comments

Comments
 (0)