Don't store thir::Pat in error structs

In several cases this avoids the need to clone the underlying pattern, and then
print the clone later.
This commit is contained in:
Zalathar 2024-07-28 15:12:14 +10:00
parent 3148b35f6a
commit e1fc4a997d
4 changed files with 32 additions and 40 deletions

View File

@ -9,7 +9,6 @@
//! [rustc dev guide]: https://rustc-dev-guide.rust-lang.org/thir.html
use rustc_ast::{InlineAsmOptions, InlineAsmTemplatePiece};
use rustc_errors::{DiagArgValue, IntoDiagArg};
use rustc_hir as hir;
use rustc_hir::def_id::DefId;
use rustc_hir::{BindingMode, ByRef, HirId, MatchSource, RangeEnd};
@ -702,12 +701,6 @@ pub fn is_never_pattern(&self) -> bool {
}
}
impl<'tcx> IntoDiagArg for Pat<'tcx> {
fn into_diag_arg(self) -> DiagArgValue {
format!("{self}").into_diag_arg()
}
}
#[derive(Clone, Debug, HashStable, TypeVisitable)]
pub struct Ascription<'tcx> {
pub annotation: CanonicalUserTypeAnnotation<'tcx>,

View File

@ -856,7 +856,7 @@ pub(crate) struct PatternNotCovered<'s, 'tcx> {
pub(crate) span: Span,
pub(crate) origin: &'s str,
#[subdiagnostic]
pub(crate) uncovered: Uncovered<'tcx>,
pub(crate) uncovered: Uncovered,
#[subdiagnostic]
pub(crate) inform: Option<Inform>,
#[subdiagnostic]

View File

@ -1,6 +1,5 @@
use rustc_errors::{Diag, EmissionGuarantee, SubdiagMessageOp, Subdiagnostic};
use rustc_macros::{LintDiagnostic, Subdiagnostic};
use rustc_middle::thir::Pat;
use rustc_middle::ty::Ty;
use rustc_span::Span;
@ -8,18 +7,18 @@
#[derive(Subdiagnostic)]
#[label(pattern_analysis_uncovered)]
pub struct Uncovered<'tcx> {
pub struct Uncovered {
#[primary_span]
span: Span,
count: usize,
witness_1: Pat<'tcx>,
witness_2: Pat<'tcx>,
witness_3: Pat<'tcx>,
witness_1: String, // a printed pattern
witness_2: String, // a printed pattern
witness_3: String, // a printed pattern
remainder: usize,
}
impl<'tcx> Uncovered<'tcx> {
pub fn new<'p>(
impl Uncovered {
pub fn new<'p, 'tcx>(
span: Span,
cx: &RustcPatCtxt<'p, 'tcx>,
witnesses: Vec<WitnessPat<'p, 'tcx>>,
@ -27,19 +26,19 @@ pub fn new<'p>(
where
'tcx: 'p,
{
let witness_1 = cx.hoist_witness_pat(witnesses.get(0).unwrap());
let witness_1 = cx.hoist_witness_pat(witnesses.get(0).unwrap()).to_string();
Self {
span,
count: witnesses.len(),
// Substitute dummy values if witnesses is smaller than 3. These will never be read.
witness_2: witnesses
.get(1)
.map(|w| cx.hoist_witness_pat(w))
.unwrap_or_else(|| witness_1.clone()),
.map(|w| cx.hoist_witness_pat(w).to_string())
.unwrap_or_default(),
witness_3: witnesses
.get(2)
.map(|w| cx.hoist_witness_pat(w))
.unwrap_or_else(|| witness_1.clone()),
.map(|w| cx.hoist_witness_pat(w).to_string())
.unwrap_or_default(),
witness_1,
remainder: witnesses.len().saturating_sub(3),
}
@ -49,19 +48,19 @@ pub fn new<'p>(
#[derive(LintDiagnostic)]
#[diag(pattern_analysis_overlapping_range_endpoints)]
#[note]
pub struct OverlappingRangeEndpoints<'tcx> {
pub struct OverlappingRangeEndpoints {
#[label]
pub range: Span,
#[subdiagnostic]
pub overlap: Vec<Overlap<'tcx>>,
pub overlap: Vec<Overlap>,
}
pub struct Overlap<'tcx> {
pub struct Overlap {
pub span: Span,
pub range: Pat<'tcx>,
pub range: String, // a printed pattern
}
impl<'tcx> Subdiagnostic for Overlap<'tcx> {
impl Subdiagnostic for Overlap {
fn add_to_diag_with<G: EmissionGuarantee, F: SubdiagMessageOp<G>>(
self,
diag: &mut Diag<'_, G>,
@ -78,38 +77,38 @@ fn add_to_diag_with<G: EmissionGuarantee, F: SubdiagMessageOp<G>>(
#[derive(LintDiagnostic)]
#[diag(pattern_analysis_excluside_range_missing_max)]
pub struct ExclusiveRangeMissingMax<'tcx> {
pub struct ExclusiveRangeMissingMax {
#[label]
#[suggestion(code = "{suggestion}", applicability = "maybe-incorrect")]
/// This is an exclusive range that looks like `lo..max` (i.e. doesn't match `max`).
pub first_range: Span,
/// Suggest `lo..=max` instead.
pub suggestion: String,
pub max: Pat<'tcx>,
pub max: String, // a printed pattern
}
#[derive(LintDiagnostic)]
#[diag(pattern_analysis_excluside_range_missing_gap)]
pub struct ExclusiveRangeMissingGap<'tcx> {
pub struct ExclusiveRangeMissingGap {
#[label]
#[suggestion(code = "{suggestion}", applicability = "maybe-incorrect")]
/// This is an exclusive range that looks like `lo..gap` (i.e. doesn't match `gap`).
pub first_range: Span,
pub gap: Pat<'tcx>,
pub gap: String, // a printed pattern
/// Suggest `lo..=gap` instead.
pub suggestion: String,
#[subdiagnostic]
/// All these ranges skipped over `gap` which we think is probably a mistake.
pub gap_with: Vec<GappedRange<'tcx>>,
pub gap_with: Vec<GappedRange>,
}
pub struct GappedRange<'tcx> {
pub struct GappedRange {
pub span: Span,
pub gap: Pat<'tcx>,
pub first_range: Pat<'tcx>,
pub gap: String, // a printed pattern
pub first_range: String, // a printed pattern
}
impl<'tcx> Subdiagnostic for GappedRange<'tcx> {
impl Subdiagnostic for GappedRange {
fn add_to_diag_with<G: EmissionGuarantee, F: SubdiagMessageOp<G>>(
self,
diag: &mut Diag<'_, G>,
@ -134,7 +133,7 @@ fn add_to_diag_with<G: EmissionGuarantee, F: SubdiagMessageOp<G>>(
pub(crate) struct NonExhaustiveOmittedPattern<'tcx> {
pub scrut_ty: Ty<'tcx>,
#[subdiagnostic]
pub uncovered: Uncovered<'tcx>,
pub uncovered: Uncovered,
}
#[derive(LintDiagnostic)]

View File

@ -966,7 +966,7 @@ fn lint_overlapping_range_endpoints(
let overlaps: Vec<_> = overlaps_with
.iter()
.map(|pat| pat.data().span)
.map(|span| errors::Overlap { range: overlap_as_pat.clone(), span })
.map(|span| errors::Overlap { range: overlap_as_pat.to_string(), span })
.collect();
let pat_span = pat.data().span;
self.tcx.emit_node_span_lint(
@ -1014,7 +1014,7 @@ fn lint_non_contiguous_range_endpoints(
// Point at this range.
first_range: thir_pat.span,
// That's the gap that isn't covered.
max: gap_as_pat.clone(),
max: gap_as_pat.to_string(),
// Suggest `lo..=max` instead.
suggestion: suggested_range.to_string(),
},
@ -1028,7 +1028,7 @@ fn lint_non_contiguous_range_endpoints(
// Point at this range.
first_range: thir_pat.span,
// That's the gap that isn't covered.
gap: gap_as_pat.clone(),
gap: gap_as_pat.to_string(),
// Suggest `lo..=gap` instead.
suggestion: suggested_range.to_string(),
// All these ranges skipped over `gap` which we think is probably a
@ -1037,8 +1037,8 @@ fn lint_non_contiguous_range_endpoints(
.iter()
.map(|pat| errors::GappedRange {
span: pat.data().span,
gap: gap_as_pat.clone(),
first_range: thir_pat.clone(),
gap: gap_as_pat.to_string(),
first_range: thir_pat.to_string(),
})
.collect(),
},