Migrate deconstruct_pat.rs
This commit is contained in:
parent
519b1abd19
commit
5d2b9a9ed0
@ -317,4 +317,10 @@ mir_build_indirect_structural_match =
|
||||
to use a constant of type `{$non_sm_ty}` in a pattern, `{$non_sm_ty}` must be annotated with `#[derive(PartialEq, Eq)]`
|
||||
|
||||
mir_build_nontrivial_structural_match =
|
||||
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)]`
|
||||
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)]`
|
||||
|
||||
mir_build_overlapping_range_endpoints = multiple patterns overlap on their endpoints
|
||||
.range = ... with this range
|
||||
.note = you likely meant to write mutually exclusive ranges
|
||||
|
||||
mir_build_overlapping_range = this range overlaps on `{$range}`...
|
||||
|
@ -9,6 +9,7 @@
|
||||
//! [rustc dev guide]: https://rustc-dev-guide.rust-lang.org/thir.html
|
||||
|
||||
use rustc_ast::{InlineAsmOptions, InlineAsmTemplatePiece};
|
||||
use rustc_errors::{DiagnosticArgValue, IntoDiagnosticArg};
|
||||
use rustc_hir as hir;
|
||||
use rustc_hir::def_id::DefId;
|
||||
use rustc_hir::RangeEnd;
|
||||
@ -575,6 +576,12 @@ impl<'tcx> Pat<'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> IntoDiagnosticArg for Pat<'tcx> {
|
||||
fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
|
||||
format!("{}", self).into_diagnostic_arg()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, HashStable)]
|
||||
pub struct Ascription<'tcx> {
|
||||
pub annotation: CanonicalUserTypeAnnotation<'tcx>,
|
||||
|
@ -4,6 +4,7 @@ use rustc_errors::{
|
||||
error_code, Applicability, DiagnosticBuilder, ErrorGuaranteed, IntoDiagnostic, MultiSpan,
|
||||
};
|
||||
use rustc_macros::{Diagnostic, LintDiagnostic, Subdiagnostic};
|
||||
use rustc_middle::thir::Pat;
|
||||
use rustc_middle::ty::{self, Ty};
|
||||
use rustc_span::{symbol::Ident, Span};
|
||||
|
||||
@ -665,3 +666,22 @@ pub struct IndirectStructuralMatch<'tcx> {
|
||||
pub struct NontrivialStructuralMatch<'tcx> {
|
||||
pub non_sm_ty: Ty<'tcx>,
|
||||
}
|
||||
|
||||
#[derive(LintDiagnostic)]
|
||||
#[diag(mir_build_overlapping_range_endpoints)]
|
||||
#[note]
|
||||
pub struct OverlappingRangeEndpoints<'tcx> {
|
||||
#[label(range)]
|
||||
pub range: Span,
|
||||
#[subdiagnostic]
|
||||
pub overlap: Overlap<'tcx>,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
#[derive(Subdiagnostic)]
|
||||
#[label(mir_build_overlapping_range)]
|
||||
pub struct Overlap<'tcx> {
|
||||
#[primary_span]
|
||||
pub span: Span,
|
||||
pub range: Pat<'tcx>,
|
||||
}
|
||||
|
@ -67,6 +67,7 @@ use self::SliceKind::*;
|
||||
|
||||
use super::compare_const_vals;
|
||||
use super::usefulness::{MatchCheckCtxt, PatCtxt};
|
||||
use crate::errors::{Overlap, OverlappingRangeEndpoints};
|
||||
|
||||
/// Recursively expand this pattern into its subpatterns. Only useful for or-patterns.
|
||||
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>> {
|
||||
/// `IntRange` is never used to encode an empty range or a "range" that wraps
|
||||
/// around the (offset) space: i.e., `range.lo <= range.hi`.
|
||||
#[derive(Clone, PartialEq, Eq)]
|
||||
pub(super) struct IntRange {
|
||||
pub(crate) struct IntRange {
|
||||
range: RangeInclusive<u128>,
|
||||
/// Keeps the bias used for encoding the range. It depends on the type of the range and
|
||||
/// possibly the pointer size of the current architecture. The algorithm ensures we never
|
||||
@ -284,32 +285,24 @@ impl IntRange {
|
||||
return;
|
||||
}
|
||||
|
||||
let overlaps: Vec<_> = pats
|
||||
// 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
|
||||
.filter_map(|pat| Some((pat.ctor().as_int_range()?, pat.span())))
|
||||
.filter(|(range, _)| self.suspicious_intersection(range))
|
||||
.map(|(range, span)| (self.intersection(&range).unwrap(), span))
|
||||
.collect();
|
||||
.map(|(range, span)| Overlap {
|
||||
range: self.intersection(&range).unwrap().to_pat(pcx.cx.tcx, pcx.ty),
|
||||
span,
|
||||
})
|
||||
.next();
|
||||
|
||||
if !overlaps.is_empty() {
|
||||
pcx.cx.tcx.struct_span_lint_hir(
|
||||
if let Some(overlap) = overlap {
|
||||
pcx.cx.tcx.emit_spanned_lint(
|
||||
lint::builtin::OVERLAPPING_RANGE_ENDPOINTS,
|
||||
hir_id,
|
||||
pcx.span,
|
||||
"multiple patterns overlap on their endpoints",
|
||||
|lint| {
|
||||
for (int_range, span) in overlaps {
|
||||
lint.span_label(
|
||||
span,
|
||||
&format!(
|
||||
"this range overlaps on `{}`...",
|
||||
int_range.to_pat(pcx.cx.tcx, pcx.ty)
|
||||
),
|
||||
);
|
||||
}
|
||||
lint.span_label(pcx.span, "... with this range");
|
||||
lint.note("you likely meant to write mutually exclusive ranges");
|
||||
lint
|
||||
},
|
||||
OverlappingRangeEndpoints { overlap, range: pcx.span },
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -59,7 +59,6 @@ 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
|
||||
|
|
||||
|
Loading…
x
Reference in New Issue
Block a user