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