From 7301c6af8a03adbd83d89400a7386dcd4fe52f5b Mon Sep 17 00:00:00 2001 From: Dylan MacKenzie Date: Thu, 23 Dec 2021 18:21:28 -0800 Subject: [PATCH] Omit empty lists from `ConstrainedSubsts` This is harder than it should be due to the way we write `Display` impls. `ConstrainedSubsts` is wrapped in `Canonical`, a container over a generic `T`, so the `Display` impl for `Canonical` cannot know that the contained type has a `display` method that bundles the interner. As a result, the interner is gone by the time we get to the `Display` impl for `ConstrainedSubsts`. I think a better solution is to implement a custom `DebugWith` trait (see Jonathan Turner's `lark` for prior art). --- chalk-ir/src/debug.rs | 39 +++++++++++++++++++++++++++++++++------ 1 file changed, 33 insertions(+), 6 deletions(-) diff --git a/chalk-ir/src/debug.rs b/chalk-ir/src/debug.rs index e4c5ab56a51..34774e48e13 100644 --- a/chalk-ir/src/debug.rs +++ b/chalk-ir/src/debug.rs @@ -1,9 +1,23 @@ //! Debug impls for types. -use std::fmt::{Debug, Display, Error, Formatter}; +use std::fmt::{self, Debug, Display, Error, Formatter}; use super::*; +/// Wrapper to allow forwarding to `Display::fmt`, `Debug::fmt`, etc. +pub struct Fmt(pub F) +where + F: Fn(&mut fmt::Formatter<'_>) -> fmt::Result; + +impl fmt::Display for Fmt +where + F: Fn(&mut fmt::Formatter<'_>) -> fmt::Result, +{ + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + (self.0)(f) + } +} + impl Debug for TraitId { fn fmt(&self, fmt: &mut Formatter<'_>) -> Result<(), Error> { I::debug_trait_id(*self, fmt).unwrap_or_else(|| write!(fmt, "TraitId({:?})", self.0)) @@ -959,14 +973,27 @@ impl Debug for Constraint { } impl Display for ConstrainedSubst { + #[rustfmt::skip] fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error> { let ConstrainedSubst { subst, constraints } = self; - write!( - f, - "substitution {}, lifetime constraints {:?}", - subst, constraints, - ) + let mut first = true; + + let subst = format!("{}", Fmt(|f| Display::fmt(subst, f))); + if subst != "[]" { + write!(f, "substitution {}", subst)?; + first = false; + } + + let constraints = format!("{}", Fmt(|f| Debug::fmt(constraints, f))); + if constraints != "[]" { + if !first { write!(f, ", ")?; } + write!(f, "lifetime constraints {}", constraints)?; + first = false; + } + + let _ = first; + Ok(()) } }