Improve the WitnessPat: Debug
impl
This commit is contained in:
parent
3dfd0fd858
commit
e4487ad391
4 changed files with 89 additions and 76 deletions
|
@ -819,6 +819,81 @@ impl<Cx: PatCx> Constructor<Cx> {
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) fn fmt_fields(
|
||||||
|
&self,
|
||||||
|
f: &mut fmt::Formatter<'_>,
|
||||||
|
ty: &Cx::Ty,
|
||||||
|
mut fields: impl Iterator<Item = impl fmt::Debug>,
|
||||||
|
) -> fmt::Result {
|
||||||
|
let mut first = true;
|
||||||
|
let mut start_or_continue = |s| {
|
||||||
|
if first {
|
||||||
|
first = false;
|
||||||
|
""
|
||||||
|
} else {
|
||||||
|
s
|
||||||
|
}
|
||||||
|
};
|
||||||
|
let mut start_or_comma = || start_or_continue(", ");
|
||||||
|
|
||||||
|
match self {
|
||||||
|
Struct | Variant(_) | UnionField => {
|
||||||
|
Cx::write_variant_name(f, self, ty)?;
|
||||||
|
// Without `cx`, we can't know which field corresponds to which, so we can't
|
||||||
|
// get the names of the fields. Instead we just display everything as a tuple
|
||||||
|
// struct, which should be good enough.
|
||||||
|
write!(f, "(")?;
|
||||||
|
for p in fields {
|
||||||
|
write!(f, "{}{:?}", start_or_comma(), p)?;
|
||||||
|
}
|
||||||
|
write!(f, ")")?;
|
||||||
|
}
|
||||||
|
// Note: given the expansion of `&str` patterns done in `expand_pattern`, we should
|
||||||
|
// be careful to detect strings here. However a string literal pattern will never
|
||||||
|
// be reported as a non-exhaustiveness witness, so we can ignore this issue.
|
||||||
|
Ref => {
|
||||||
|
write!(f, "&{:?}", &fields.next().unwrap())?;
|
||||||
|
}
|
||||||
|
Slice(slice) => {
|
||||||
|
write!(f, "[")?;
|
||||||
|
match slice.kind {
|
||||||
|
SliceKind::FixedLen(_) => {
|
||||||
|
for p in fields {
|
||||||
|
write!(f, "{}{:?}", start_or_comma(), p)?;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
SliceKind::VarLen(prefix_len, _) => {
|
||||||
|
for p in fields.by_ref().take(prefix_len) {
|
||||||
|
write!(f, "{}{:?}", start_or_comma(), p)?;
|
||||||
|
}
|
||||||
|
write!(f, "{}..", start_or_comma())?;
|
||||||
|
for p in fields {
|
||||||
|
write!(f, "{}{:?}", start_or_comma(), p)?;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
write!(f, "]")?;
|
||||||
|
}
|
||||||
|
Bool(b) => write!(f, "{b}")?,
|
||||||
|
// Best-effort, will render signed ranges incorrectly
|
||||||
|
IntRange(range) => write!(f, "{range:?}")?,
|
||||||
|
F32Range(lo, hi, end) => write!(f, "{lo}{end}{hi}")?,
|
||||||
|
F64Range(lo, hi, end) => write!(f, "{lo}{end}{hi}")?,
|
||||||
|
Str(value) => write!(f, "{value:?}")?,
|
||||||
|
Opaque(..) => write!(f, "<constant pattern>")?,
|
||||||
|
Or => {
|
||||||
|
for pat in fields {
|
||||||
|
write!(f, "{}{:?}", start_or_continue(" | "), pat)?;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Never => write!(f, "!")?,
|
||||||
|
Wildcard | Missing | NonExhaustive | Hidden | PrivateUninhabited => {
|
||||||
|
write!(f, "_ : {:?}", ty)?
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy)]
|
#[derive(Debug, Clone, Copy)]
|
||||||
|
|
|
@ -120,7 +120,8 @@ pub trait PatCx: Sized + fmt::Debug {
|
||||||
/// `DeconstructedPat`. Only invoqued when `pat.ctor()` is `Struct | Variant(_) | UnionField`.
|
/// `DeconstructedPat`. Only invoqued when `pat.ctor()` is `Struct | Variant(_) | UnionField`.
|
||||||
fn write_variant_name(
|
fn write_variant_name(
|
||||||
f: &mut fmt::Formatter<'_>,
|
f: &mut fmt::Formatter<'_>,
|
||||||
pat: &crate::pat::DeconstructedPat<Self>,
|
ctor: &crate::constructor::Constructor<Self>,
|
||||||
|
ty: &Self::Ty,
|
||||||
) -> fmt::Result;
|
) -> fmt::Result;
|
||||||
|
|
||||||
/// Raise a bug.
|
/// Raise a bug.
|
||||||
|
|
|
@ -138,81 +138,11 @@ impl<Cx: PatCx> DeconstructedPat<Cx> {
|
||||||
/// This is best effort and not good enough for a `Display` impl.
|
/// This is best effort and not good enough for a `Display` impl.
|
||||||
impl<Cx: PatCx> fmt::Debug for DeconstructedPat<Cx> {
|
impl<Cx: PatCx> fmt::Debug for DeconstructedPat<Cx> {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
let pat = self;
|
|
||||||
let mut first = true;
|
|
||||||
let mut start_or_continue = |s| {
|
|
||||||
if first {
|
|
||||||
first = false;
|
|
||||||
""
|
|
||||||
} else {
|
|
||||||
s
|
|
||||||
}
|
|
||||||
};
|
|
||||||
let mut start_or_comma = || start_or_continue(", ");
|
|
||||||
|
|
||||||
let mut fields: Vec<_> = (0..self.arity).map(|_| PatOrWild::Wild).collect();
|
let mut fields: Vec<_> = (0..self.arity).map(|_| PatOrWild::Wild).collect();
|
||||||
for ipat in self.iter_fields() {
|
for ipat in self.iter_fields() {
|
||||||
fields[ipat.idx] = PatOrWild::Pat(&ipat.pat);
|
fields[ipat.idx] = PatOrWild::Pat(&ipat.pat);
|
||||||
}
|
}
|
||||||
|
self.ctor().fmt_fields(f, self.ty(), fields.into_iter())
|
||||||
match pat.ctor() {
|
|
||||||
Struct | Variant(_) | UnionField => {
|
|
||||||
Cx::write_variant_name(f, pat)?;
|
|
||||||
// Without `cx`, we can't know which field corresponds to which, so we can't
|
|
||||||
// get the names of the fields. Instead we just display everything as a tuple
|
|
||||||
// struct, which should be good enough.
|
|
||||||
write!(f, "(")?;
|
|
||||||
for p in fields {
|
|
||||||
write!(f, "{}", start_or_comma())?;
|
|
||||||
write!(f, "{p:?}")?;
|
|
||||||
}
|
|
||||||
write!(f, ")")
|
|
||||||
}
|
|
||||||
// Note: given the expansion of `&str` patterns done in `expand_pattern`, we should
|
|
||||||
// be careful to detect strings here. However a string literal pattern will never
|
|
||||||
// be reported as a non-exhaustiveness witness, so we can ignore this issue.
|
|
||||||
Ref => {
|
|
||||||
write!(f, "&{:?}", &fields[0])
|
|
||||||
}
|
|
||||||
Slice(slice) => {
|
|
||||||
write!(f, "[")?;
|
|
||||||
match slice.kind {
|
|
||||||
SliceKind::FixedLen(_) => {
|
|
||||||
for p in fields {
|
|
||||||
write!(f, "{}{:?}", start_or_comma(), p)?;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
SliceKind::VarLen(prefix_len, _) => {
|
|
||||||
for p in &fields[..prefix_len] {
|
|
||||||
write!(f, "{}{:?}", start_or_comma(), p)?;
|
|
||||||
}
|
|
||||||
write!(f, "{}", start_or_comma())?;
|
|
||||||
write!(f, "..")?;
|
|
||||||
for p in &fields[prefix_len..] {
|
|
||||||
write!(f, "{}{:?}", start_or_comma(), p)?;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
write!(f, "]")
|
|
||||||
}
|
|
||||||
Bool(b) => write!(f, "{b}"),
|
|
||||||
// Best-effort, will render signed ranges incorrectly
|
|
||||||
IntRange(range) => write!(f, "{range:?}"),
|
|
||||||
F32Range(lo, hi, end) => write!(f, "{lo}{end}{hi}"),
|
|
||||||
F64Range(lo, hi, end) => write!(f, "{lo}{end}{hi}"),
|
|
||||||
Str(value) => write!(f, "{value:?}"),
|
|
||||||
Opaque(..) => write!(f, "<constant pattern>"),
|
|
||||||
Or => {
|
|
||||||
for pat in fields {
|
|
||||||
write!(f, "{}{:?}", start_or_continue(" | "), pat)?;
|
|
||||||
}
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
Never => write!(f, "!"),
|
|
||||||
Wildcard | Missing | NonExhaustive | Hidden | PrivateUninhabited => {
|
|
||||||
write!(f, "_ : {:?}", pat.ty())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -295,7 +225,6 @@ impl<'p, Cx: PatCx> fmt::Debug for PatOrWild<'p, Cx> {
|
||||||
|
|
||||||
/// Same idea as `DeconstructedPat`, except this is a fictitious pattern built up for diagnostics
|
/// Same idea as `DeconstructedPat`, except this is a fictitious pattern built up for diagnostics
|
||||||
/// purposes. As such they don't use interning and can be cloned.
|
/// purposes. As such they don't use interning and can be cloned.
|
||||||
#[derive(Debug)]
|
|
||||||
pub struct WitnessPat<Cx: PatCx> {
|
pub struct WitnessPat<Cx: PatCx> {
|
||||||
ctor: Constructor<Cx>,
|
ctor: Constructor<Cx>,
|
||||||
pub(crate) fields: Vec<WitnessPat<Cx>>,
|
pub(crate) fields: Vec<WitnessPat<Cx>>,
|
||||||
|
@ -353,3 +282,10 @@ impl<Cx: PatCx> WitnessPat<Cx> {
|
||||||
self.fields.iter()
|
self.fields.iter()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// This is best effort and not good enough for a `Display` impl.
|
||||||
|
impl<Cx: PatCx> fmt::Debug for WitnessPat<Cx> {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
|
self.ctor().fmt_fields(f, self.ty(), self.fields.iter())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -874,13 +874,14 @@ impl<'p, 'tcx: 'p> PatCx for RustcPatCtxt<'p, 'tcx> {
|
||||||
|
|
||||||
fn write_variant_name(
|
fn write_variant_name(
|
||||||
f: &mut fmt::Formatter<'_>,
|
f: &mut fmt::Formatter<'_>,
|
||||||
pat: &crate::pat::DeconstructedPat<Self>,
|
ctor: &crate::constructor::Constructor<Self>,
|
||||||
|
ty: &Self::Ty,
|
||||||
) -> fmt::Result {
|
) -> fmt::Result {
|
||||||
if let ty::Adt(adt, _) = pat.ty().kind() {
|
if let ty::Adt(adt, _) = ty.kind() {
|
||||||
if adt.is_box() {
|
if adt.is_box() {
|
||||||
write!(f, "Box")?
|
write!(f, "Box")?
|
||||||
} else {
|
} else {
|
||||||
let variant = adt.variant(Self::variant_index_for_adt(pat.ctor(), *adt));
|
let variant = adt.variant(Self::variant_index_for_adt(ctor, *adt));
|
||||||
write!(f, "{}", variant.name)?;
|
write!(f, "{}", variant.name)?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue