Encapsulate the printing of WitnessPat
This hides the fact that we print `WitnessPat` by converting it to `thir::Pat` and then printing that.
This commit is contained in:
parent
e1fc4a997d
commit
db05b0fd34
3 changed files with 18 additions and 16 deletions
|
@ -1077,7 +1077,7 @@ fn report_non_exhaustive_match<'p, 'tcx>(
|
||||||
let suggested_arm = if suggest_the_witnesses {
|
let suggested_arm = if suggest_the_witnesses {
|
||||||
let pattern = witnesses
|
let pattern = witnesses
|
||||||
.iter()
|
.iter()
|
||||||
.map(|witness| cx.hoist_witness_pat(witness).to_string())
|
.map(|witness| cx.print_witness_pat(witness))
|
||||||
.collect::<Vec<String>>()
|
.collect::<Vec<String>>()
|
||||||
.join(" | ");
|
.join(" | ");
|
||||||
if witnesses.iter().all(|p| p.is_never_pattern()) && cx.tcx.features().never_patterns {
|
if witnesses.iter().all(|p| p.is_never_pattern()) && cx.tcx.features().never_patterns {
|
||||||
|
@ -1195,13 +1195,13 @@ fn joined_uncovered_patterns<'p, 'tcx>(
|
||||||
witnesses: &[WitnessPat<'p, 'tcx>],
|
witnesses: &[WitnessPat<'p, 'tcx>],
|
||||||
) -> String {
|
) -> String {
|
||||||
const LIMIT: usize = 3;
|
const LIMIT: usize = 3;
|
||||||
let pat_to_str = |pat: &WitnessPat<'p, 'tcx>| cx.hoist_witness_pat(pat).to_string();
|
let pat_to_str = |pat: &WitnessPat<'p, 'tcx>| cx.print_witness_pat(pat);
|
||||||
match witnesses {
|
match witnesses {
|
||||||
[] => bug!(),
|
[] => bug!(),
|
||||||
[witness] => format!("`{}`", cx.hoist_witness_pat(witness)),
|
[witness] => format!("`{}`", cx.print_witness_pat(witness)),
|
||||||
[head @ .., tail] if head.len() < LIMIT => {
|
[head @ .., tail] if head.len() < LIMIT => {
|
||||||
let head: Vec<_> = head.iter().map(pat_to_str).collect();
|
let head: Vec<_> = head.iter().map(pat_to_str).collect();
|
||||||
format!("`{}` and `{}`", head.join("`, `"), cx.hoist_witness_pat(tail))
|
format!("`{}` and `{}`", head.join("`, `"), cx.print_witness_pat(tail))
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
let (head, tail) = witnesses.split_at(LIMIT);
|
let (head, tail) = witnesses.split_at(LIMIT);
|
||||||
|
|
|
@ -26,19 +26,13 @@ impl Uncovered {
|
||||||
where
|
where
|
||||||
'tcx: 'p,
|
'tcx: 'p,
|
||||||
{
|
{
|
||||||
let witness_1 = cx.hoist_witness_pat(witnesses.get(0).unwrap()).to_string();
|
let witness_1 = cx.print_witness_pat(witnesses.get(0).unwrap());
|
||||||
Self {
|
Self {
|
||||||
span,
|
span,
|
||||||
count: witnesses.len(),
|
count: witnesses.len(),
|
||||||
// Substitute dummy values if witnesses is smaller than 3. These will never be read.
|
// Substitute dummy values if witnesses is smaller than 3. These will never be read.
|
||||||
witness_2: witnesses
|
witness_2: witnesses.get(1).map(|w| cx.print_witness_pat(w)).unwrap_or_default(),
|
||||||
.get(1)
|
witness_3: witnesses.get(2).map(|w| cx.print_witness_pat(w)).unwrap_or_default(),
|
||||||
.map(|w| cx.hoist_witness_pat(w).to_string())
|
|
||||||
.unwrap_or_default(),
|
|
||||||
witness_3: witnesses
|
|
||||||
.get(2)
|
|
||||||
.map(|w| cx.hoist_witness_pat(w).to_string())
|
|
||||||
.unwrap_or_default(),
|
|
||||||
witness_1,
|
witness_1,
|
||||||
remainder: witnesses.len().saturating_sub(3),
|
remainder: witnesses.len().saturating_sub(3),
|
||||||
}
|
}
|
||||||
|
|
|
@ -744,7 +744,7 @@ impl<'p, 'tcx: 'p> RustcPatCtxt<'p, 'tcx> {
|
||||||
/// Note: it is possible to get `isize/usize::MAX+1` here, as explained in the doc for
|
/// Note: it is possible to get `isize/usize::MAX+1` here, as explained in the doc for
|
||||||
/// [`IntRange::split`]. This cannot be represented as a `Const`, so we represent it with
|
/// [`IntRange::split`]. This cannot be represented as a `Const`, so we represent it with
|
||||||
/// `PosInfinity`.
|
/// `PosInfinity`.
|
||||||
pub(crate) fn hoist_pat_range_bdy(
|
fn hoist_pat_range_bdy(
|
||||||
&self,
|
&self,
|
||||||
miint: MaybeInfiniteInt,
|
miint: MaybeInfiniteInt,
|
||||||
ty: RevealedTy<'tcx>,
|
ty: RevealedTy<'tcx>,
|
||||||
|
@ -775,7 +775,7 @@ impl<'p, 'tcx: 'p> RustcPatCtxt<'p, 'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Convert back to a `thir::Pat` for diagnostic purposes.
|
/// Convert back to a `thir::Pat` for diagnostic purposes.
|
||||||
pub(crate) fn hoist_pat_range(&self, range: &IntRange, ty: RevealedTy<'tcx>) -> Pat<'tcx> {
|
fn hoist_pat_range(&self, range: &IntRange, ty: RevealedTy<'tcx>) -> Pat<'tcx> {
|
||||||
use MaybeInfiniteInt::*;
|
use MaybeInfiniteInt::*;
|
||||||
let cx = self;
|
let cx = self;
|
||||||
let kind = if matches!((range.lo, range.hi), (NegInfinity, PosInfinity)) {
|
let kind = if matches!((range.lo, range.hi), (NegInfinity, PosInfinity)) {
|
||||||
|
@ -811,9 +811,17 @@ impl<'p, 'tcx: 'p> RustcPatCtxt<'p, 'tcx> {
|
||||||
|
|
||||||
Pat { ty: ty.inner(), span: DUMMY_SP, kind }
|
Pat { ty: ty.inner(), span: DUMMY_SP, kind }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Prints a [`WitnessPat`] to an owned string, for diagnostic purposes.
|
||||||
|
pub fn print_witness_pat(&self, pat: &WitnessPat<'p, 'tcx>) -> String {
|
||||||
|
// This works by converting the witness pattern back to a `thir::Pat`
|
||||||
|
// and then printing that, but callers don't need to know that.
|
||||||
|
self.hoist_witness_pat(pat).to_string()
|
||||||
|
}
|
||||||
|
|
||||||
/// Convert back to a `thir::Pat` for diagnostic purposes. This panics for patterns that don't
|
/// Convert back to a `thir::Pat` for diagnostic purposes. This panics for patterns that don't
|
||||||
/// appear in diagnostics, like float ranges.
|
/// appear in diagnostics, like float ranges.
|
||||||
pub fn hoist_witness_pat(&self, pat: &WitnessPat<'p, 'tcx>) -> Pat<'tcx> {
|
fn hoist_witness_pat(&self, pat: &WitnessPat<'p, 'tcx>) -> Pat<'tcx> {
|
||||||
let cx = self;
|
let cx = self;
|
||||||
let is_wildcard = |pat: &Pat<'_>| matches!(pat.kind, PatKind::Wild);
|
let is_wildcard = |pat: &Pat<'_>| matches!(pat.kind, PatKind::Wild);
|
||||||
let mut subpatterns = pat.iter_fields().map(|p| Box::new(cx.hoist_witness_pat(p)));
|
let mut subpatterns = pat.iter_fields().map(|p| Box::new(cx.hoist_witness_pat(p)));
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue