Remove `Debug` constraint on `SumTree` (and its related traits/structs) (#18248)

Antonio Scandurra and Nathan created

Release Notes:

- N/A

Co-authored-by: Nathan <nathan@zed.dev>

Change summary

crates/editor/src/selections_collection.rs |  4 
crates/sum_tree/src/cursor.rs              |  6 -
crates/sum_tree/src/sum_tree.rs            | 53 +++++++++++++++++++++--
crates/sum_tree/src/tree_map.rs            | 34 +++++++-------
4 files changed, 69 insertions(+), 28 deletions(-)

Detailed changes

crates/editor/src/selections_collection.rs 🔗

@@ -109,7 +109,7 @@ impl SelectionsCollection {
 
     pub fn all<'a, D>(&self, cx: &AppContext) -> Vec<Selection<D>>
     where
-        D: 'a + TextDimension + Ord + Sub<D, Output = D> + std::fmt::Debug,
+        D: 'a + TextDimension + Ord + Sub<D, Output = D>,
     {
         let disjoint_anchors = &self.disjoint;
         let mut disjoint =
@@ -850,7 +850,7 @@ pub(crate) fn resolve_multiple<'a, D, I>(
     snapshot: &MultiBufferSnapshot,
 ) -> impl 'a + Iterator<Item = Selection<D>>
 where
-    D: TextDimension + Ord + Sub<D, Output = D> + std::fmt::Debug,
+    D: TextDimension + Ord + Sub<D, Output = D>,
     I: 'a + IntoIterator<Item = &'a Selection<Anchor>>,
 {
     let (to_summarize, selections) = selections.into_iter().tee();

crates/sum_tree/src/cursor.rs 🔗

@@ -431,11 +431,9 @@ where
         aggregate: &mut dyn SeekAggregate<'a, T>,
         cx: &<T::Summary as Summary>::Context,
     ) -> bool {
-        debug_assert!(
+        assert!(
             target.cmp(&self.position, cx) >= Ordering::Equal,
-            "cannot seek backward from {:?} to {:?}",
-            self.position,
-            target
+            "cannot seek backward",
         );
 
         if !self.did_seek {

crates/sum_tree/src/sum_tree.rs 🔗

@@ -34,7 +34,7 @@ pub trait KeyedItem: Item {
 ///
 /// Each Summary type can have multiple [`Dimensions`] that it measures,
 /// which can be used to navigate the tree
-pub trait Summary: Clone + fmt::Debug {
+pub trait Summary: Clone {
     type Context;
 
     fn zero(cx: &Self::Context) -> Self;
@@ -49,7 +49,7 @@ pub trait Summary: Clone + fmt::Debug {
 /// # Example:
 /// Zed's rope has a `TextSummary` type that summarizes lines, characters, and bytes.
 /// Each of these are different dimensions we may want to seek to
-pub trait Dimension<'a, S: Summary>: Clone + fmt::Debug {
+pub trait Dimension<'a, S: Summary>: Clone {
     fn zero(cx: &S::Context) -> Self;
 
     fn add_summary(&mut self, summary: &'a S, cx: &S::Context);
@@ -71,7 +71,7 @@ impl<'a, T: Summary> Dimension<'a, T> for T {
     }
 }
 
-pub trait SeekTarget<'a, S: Summary, D: Dimension<'a, S>>: fmt::Debug {
+pub trait SeekTarget<'a, S: Summary, D: Dimension<'a, S>> {
     fn cmp(&self, cursor_location: &D, cx: &S::Context) -> Ordering;
 }
 
@@ -173,9 +173,19 @@ impl Bias {
 /// The maximum number of items per node is `TREE_BASE * 2`.
 ///
 /// Any [`Dimension`] supported by the [`Summary`] type can be used to seek to a specific location in the tree.
-#[derive(Debug, Clone)]
+#[derive(Clone)]
 pub struct SumTree<T: Item>(Arc<Node<T>>);
 
+impl<T> fmt::Debug for SumTree<T>
+where
+    T: fmt::Debug + Item,
+    T::Summary: fmt::Debug,
+{
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        f.debug_tuple("SumTree").field(&self.0).finish()
+    }
+}
+
 impl<T: Item> SumTree<T> {
     pub fn new(cx: &<T::Summary as Summary>::Context) -> Self {
         SumTree(Arc::new(Node::Leaf {
@@ -763,7 +773,7 @@ where
     }
 }
 
-#[derive(Clone, Debug)]
+#[derive(Clone)]
 pub enum Node<T: Item> {
     Internal {
         height: u8,
@@ -778,6 +788,39 @@ pub enum Node<T: Item> {
     },
 }
 
+impl<T> fmt::Debug for Node<T>
+where
+    T: Item + fmt::Debug,
+    T::Summary: fmt::Debug,
+{
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        match self {
+            Node::Internal {
+                height,
+                summary,
+                child_summaries,
+                child_trees,
+            } => f
+                .debug_struct("Internal")
+                .field("height", height)
+                .field("summary", summary)
+                .field("child_summaries", child_summaries)
+                .field("child_trees", child_trees)
+                .finish(),
+            Node::Leaf {
+                summary,
+                items,
+                item_summaries,
+            } => f
+                .debug_struct("Leaf")
+                .field("summary", summary)
+                .field("items", items)
+                .field("item_summaries", item_summaries)
+                .finish(),
+        }
+    }
+}
+
 impl<T: Item> Node<T> {
     fn is_leaf(&self) -> bool {
         matches!(self, Node::Leaf { .. })

crates/sum_tree/src/tree_map.rs 🔗

@@ -5,8 +5,8 @@ use crate::{Bias, Dimension, Edit, Item, KeyedItem, SeekTarget, SumTree, Summary
 #[derive(Clone, PartialEq, Eq)]
 pub struct TreeMap<K, V>(SumTree<MapEntry<K, V>>)
 where
-    K: Clone + Debug + Ord,
-    V: Clone + Debug;
+    K: Clone + Ord,
+    V: Clone;
 
 #[derive(Clone, Debug, PartialEq, Eq)]
 pub struct MapEntry<K, V> {
@@ -35,9 +35,9 @@ impl<'a, K> Default for MapKeyRef<'a, K> {
 #[derive(Clone)]
 pub struct TreeSet<K>(TreeMap<K, ()>)
 where
-    K: Clone + Debug + Ord;
+    K: Clone + Ord;
 
-impl<K: Clone + Debug + Ord, V: Clone + Debug> TreeMap<K, V> {
+impl<K: Clone + Ord, V: Clone> TreeMap<K, V> {
     pub fn from_ordered_entries(entries: impl IntoIterator<Item = (K, V)>) -> Self {
         let tree = SumTree::from_iter(
             entries
@@ -172,7 +172,7 @@ impl<K: Clone + Debug + Ord, V: Clone + Debug> TreeMap<K, V> {
     }
 }
 
-impl<K: Debug, V: Debug> Debug for TreeMap<K, V>
+impl<K, V> Debug for TreeMap<K, V>
 where
     K: Clone + Debug + Ord,
     V: Clone + Debug,
@@ -185,7 +185,7 @@ where
 #[derive(Debug)]
 struct MapSeekTargetAdaptor<'a, T>(&'a T);
 
-impl<'a, K: Debug + Clone + Ord, T: MapSeekTarget<K>> SeekTarget<'a, MapKey<K>, MapKeyRef<'a, K>>
+impl<'a, K: Clone + Ord, T: MapSeekTarget<K>> SeekTarget<'a, MapKey<K>, MapKeyRef<'a, K>>
     for MapSeekTargetAdaptor<'_, T>
 {
     fn cmp(&self, cursor_location: &MapKeyRef<K>, _: &()) -> Ordering {
@@ -197,11 +197,11 @@ impl<'a, K: Debug + Clone + Ord, T: MapSeekTarget<K>> SeekTarget<'a, MapKey<K>,
     }
 }
 
-pub trait MapSeekTarget<K>: Debug {
+pub trait MapSeekTarget<K> {
     fn cmp_cursor(&self, cursor_location: &K) -> Ordering;
 }
 
-impl<K: Debug + Ord> MapSeekTarget<K> for K {
+impl<K: Ord> MapSeekTarget<K> for K {
     fn cmp_cursor(&self, cursor_location: &K) -> Ordering {
         self.cmp(cursor_location)
     }
@@ -209,8 +209,8 @@ impl<K: Debug + Ord> MapSeekTarget<K> for K {
 
 impl<K, V> Default for TreeMap<K, V>
 where
-    K: Clone + Debug + Ord,
-    V: Clone + Debug,
+    K: Clone + Ord,
+    V: Clone,
 {
     fn default() -> Self {
         Self(Default::default())
@@ -219,7 +219,7 @@ where
 
 impl<K, V> Item for MapEntry<K, V>
 where
-    K: Clone + Debug + Ord,
+    K: Clone + Ord,
     V: Clone,
 {
     type Summary = MapKey<K>;
@@ -231,7 +231,7 @@ where
 
 impl<K, V> KeyedItem for MapEntry<K, V>
 where
-    K: Clone + Debug + Ord,
+    K: Clone + Ord,
     V: Clone,
 {
     type Key = MapKey<K>;
@@ -243,7 +243,7 @@ where
 
 impl<K> Summary for MapKey<K>
 where
-    K: Clone + Debug,
+    K: Clone,
 {
     type Context = ();
 
@@ -258,7 +258,7 @@ where
 
 impl<'a, K> Dimension<'a, MapKey<K>> for MapKeyRef<'a, K>
 where
-    K: Clone + Debug + Ord,
+    K: Clone + Ord,
 {
     fn zero(_cx: &()) -> Self {
         Default::default()
@@ -271,7 +271,7 @@ where
 
 impl<'a, K> SeekTarget<'a, MapKey<K>, MapKeyRef<'a, K>> for MapKeyRef<'_, K>
 where
-    K: Clone + Debug + Ord,
+    K: Clone + Ord,
 {
     fn cmp(&self, cursor_location: &MapKeyRef<K>, _: &()) -> Ordering {
         Ord::cmp(&self.0, &cursor_location.0)
@@ -280,7 +280,7 @@ where
 
 impl<K> Default for TreeSet<K>
 where
-    K: Clone + Debug + Ord,
+    K: Clone + Ord,
 {
     fn default() -> Self {
         Self(Default::default())
@@ -289,7 +289,7 @@ where
 
 impl<K> TreeSet<K>
 where
-    K: Clone + Debug + Ord,
+    K: Clone + Ord,
 {
     pub fn from_ordered_entries(entries: impl IntoIterator<Item = K>) -> Self {
         Self(TreeMap::from_ordered_entries(