diff options
| author | Matthias Krüger <matthias.krueger@famsik.de> | 2024-01-25 08:39:45 +0100 | 
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-01-25 08:39:45 +0100 | 
| commit | a1ecced532ecffb288ca176cce56a8aa96f155ab (patch) | |
| tree | a71c5efff647eae177ddc1499b6c653cb5b22c7f /compiler/rustc_pattern_analysis/src/pat.rs | |
| parent | b677c776865be82071d14d52aa5930ecd266f26d (diff) | |
| parent | 354b45f52854d4534aaf4bf860d539a9657a596f (diff) | |
| download | rust-a1ecced532ecffb288ca176cce56a8aa96f155ab.tar.gz rust-a1ecced532ecffb288ca176cce56a8aa96f155ab.zip | |
Rollup merge of #120318 - Nadrieril:share-debug-impl, r=compiler-errors
pattern_analysis: Reuse most of the `DeconstructedPat` `Debug` impl The `DeconstructedPat: Debug` is best-effort because we'd need `tcx` to get things like field names etc. Since rust-analyzer has a similar constraint, this PR moves most the impl to be shared between the two. While I was at it I also fixed a nit in the `IntRange: Debug` impl. r? `@compiler-errors`
Diffstat (limited to 'compiler/rustc_pattern_analysis/src/pat.rs')
| -rw-r--r-- | compiler/rustc_pattern_analysis/src/pat.rs | 70 | 
1 files changed, 69 insertions, 1 deletions
| diff --git a/compiler/rustc_pattern_analysis/src/pat.rs b/compiler/rustc_pattern_analysis/src/pat.rs index 1c98ec5bc12..1cc31074556 100644 --- a/compiler/rustc_pattern_analysis/src/pat.rs +++ b/compiler/rustc_pattern_analysis/src/pat.rs @@ -142,7 +142,75 @@ impl<'p, Cx: TypeCx> DeconstructedPat<'p, Cx> { /// This is best effort and not good enough for a `Display` impl. impl<'p, Cx: TypeCx> fmt::Debug for DeconstructedPat<'p, Cx> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - Cx::debug_pat(f, self) + 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(", "); + + 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 pat.iter_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 => { + let subpattern = pat.iter_fields().next().unwrap(); + write!(f, "&{:?}", subpattern) + } + Slice(slice) => { + let mut subpatterns = pat.iter_fields(); + write!(f, "[")?; + match slice.kind { + SliceKind::FixedLen(_) => { + for p in subpatterns { + write!(f, "{}{:?}", start_or_comma(), p)?; + } + } + SliceKind::VarLen(prefix_len, _) => { + for p in subpatterns.by_ref().take(prefix_len) { + write!(f, "{}{:?}", start_or_comma(), p)?; + } + write!(f, "{}", start_or_comma())?; + write!(f, "..")?; + for p in subpatterns { + 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 pat.iter_fields() { + write!(f, "{}{:?}", start_or_continue(" | "), pat)?; + } + Ok(()) + } + Wildcard | Missing { .. } | NonExhaustive | Hidden => write!(f, "_ : {:?}", pat.ty()), + } } } | 
