about summary refs log tree commit diff
diff options
context:
space:
mode:
authorJonas Schievink <jonasschievink@gmail.com>2020-10-03 00:31:04 +0200
committerGitHub <noreply@github.com>2020-10-03 00:31:04 +0200
commit1118ab99301025f371f03c1345a5212c3068cf56 (patch)
tree37ad4f9a8a33347ac47a652ff3f1d11e882a2d46
parent8876ffc9235dade728e1fbc4be4c85415fdd0bcd (diff)
parent8faf550e5f7211188bc9560ae459c155fb1aafdf (diff)
downloadrust-1118ab99301025f371f03c1345a5212c3068cf56.tar.gz
rust-1118ab99301025f371f03c1345a5212c3068cf56.zip
Rollup merge of #75377 - canova:map_debug_impl, r=dtolnay
Fix Debug implementations of some of the HashMap and BTreeMap iterator types

HashMap's `ValuesMut`, BTreeMaps `ValuesMut`, IntoValues and `IntoKeys` structs were printing both keys and values on their Debug implementations. But they are iterators over either keys or values. Irrelevant values should not be visible. With this PR, they only show relevant fields.
This fixes #75297.

[Here's an example code.](https://play.rust-lang.org/?version=nightly&mode=debug&edition=2018&gist=0c79356ed860e347a0c1a205616f93b7) This prints this on nightly:
```
ValuesMut { inner: IterMut { range: [(1, "hello"), (2, "goodbye")], length: 2 } }
IntoKeys { inner: [(1, "hello"), (2, "goodbye")] }
IntoValues { inner: [(1, "hello"), (2, "goodbye")] }
[(2, "goodbye"), (1, "hello")]
```

After the patch this example prints these instead:
```
["hello", "goodbye"]
["hello", "goodbye"]
[1, 2]
["hello", "goodbye"]
```

I didn't add test cases for them, since I couldn't see any tests for Debug implementations anywhere. But please let me know if I should add it to a specific place.

r? @dtolnay
-rw-r--r--library/alloc/src/collections/btree/map.rs58
-rw-r--r--library/std/src/collections/hash/map.rs12
2 files changed, 55 insertions, 15 deletions
diff --git a/library/alloc/src/collections/btree/map.rs b/library/alloc/src/collections/btree/map.rs
index 3fb03a5412e..2b244a04d22 100644
--- a/library/alloc/src/collections/btree/map.rs
+++ b/library/alloc/src/collections/btree/map.rs
@@ -297,14 +297,23 @@ pub struct IntoIter<K, V> {
     length: usize,
 }
 
-#[stable(feature = "collection_debug", since = "1.17.0")]
-impl<K: fmt::Debug, V: fmt::Debug> fmt::Debug for IntoIter<K, V> {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+impl<K, V> IntoIter<K, V> {
+    /// Returns an iterator of references over the remaining items.
+    #[inline]
+    pub(super) fn iter(&self) -> Iter<'_, K, V> {
         let range = Range {
             front: self.front.as_ref().map(|f| f.reborrow()),
             back: self.back.as_ref().map(|b| b.reborrow()),
         };
-        f.debug_list().entries(range).finish()
+
+        Iter { range: range, length: self.length }
+    }
+}
+
+#[stable(feature = "collection_debug", since = "1.17.0")]
+impl<K: fmt::Debug, V: fmt::Debug> fmt::Debug for IntoIter<K, V> {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        f.debug_list().entries(self.iter()).finish()
     }
 }
 
@@ -351,11 +360,17 @@ impl<K, V: fmt::Debug> fmt::Debug for Values<'_, K, V> {
 ///
 /// [`values_mut`]: BTreeMap::values_mut
 #[stable(feature = "map_values_mut", since = "1.10.0")]
-#[derive(Debug)]
 pub struct ValuesMut<'a, K: 'a, V: 'a> {
     inner: IterMut<'a, K, V>,
 }
 
+#[stable(feature = "map_values_mut", since = "1.10.0")]
+impl<K, V: fmt::Debug> fmt::Debug for ValuesMut<'_, K, V> {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        f.debug_list().entries(self.inner.iter().map(|(_, val)| val)).finish()
+    }
+}
+
 /// An owning iterator over the keys of a `BTreeMap`.
 ///
 /// This `struct` is created by the [`into_keys`] method on [`BTreeMap`].
@@ -363,11 +378,17 @@ pub struct ValuesMut<'a, K: 'a, V: 'a> {
 ///
 /// [`into_keys`]: BTreeMap::into_keys
 #[unstable(feature = "map_into_keys_values", issue = "75294")]
-#[derive(Debug)]
 pub struct IntoKeys<K, V> {
     inner: IntoIter<K, V>,
 }
 
+#[unstable(feature = "map_into_keys_values", issue = "75294")]
+impl<K: fmt::Debug, V> fmt::Debug for IntoKeys<K, V> {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        f.debug_list().entries(self.inner.iter().map(|(key, _)| key)).finish()
+    }
+}
+
 /// An owning iterator over the values of a `BTreeMap`.
 ///
 /// This `struct` is created by the [`into_values`] method on [`BTreeMap`].
@@ -375,11 +396,17 @@ pub struct IntoKeys<K, V> {
 ///
 /// [`into_values`]: BTreeMap::into_values
 #[unstable(feature = "map_into_keys_values", issue = "75294")]
-#[derive(Debug)]
 pub struct IntoValues<K, V> {
     inner: IntoIter<K, V>,
 }
 
+#[unstable(feature = "map_into_keys_values", issue = "75294")]
+impl<K, V: fmt::Debug> fmt::Debug for IntoValues<K, V> {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        f.debug_list().entries(self.inner.iter().map(|(_, val)| val)).finish()
+    }
+}
+
 /// An iterator over a sub-range of entries in a `BTreeMap`.
 ///
 /// This `struct` is created by the [`range`] method on [`BTreeMap`]. See its
@@ -1465,6 +1492,14 @@ impl<K, V> ExactSizeIterator for IterMut<'_, K, V> {
 #[stable(feature = "fused", since = "1.26.0")]
 impl<K, V> FusedIterator for IterMut<'_, K, V> {}
 
+impl<'a, K, V> IterMut<'a, K, V> {
+    /// Returns an iterator of references over the remaining items.
+    #[inline]
+    pub(super) fn iter(&self) -> Iter<'_, K, V> {
+        Iter { range: self.range.iter(), length: self.length }
+    }
+}
+
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<K, V> IntoIterator for BTreeMap<K, V> {
     type Item = (K, V);
@@ -1949,6 +1984,15 @@ impl<'a, K, V> RangeMut<'a, K, V> {
     unsafe fn next_unchecked(&mut self) -> (&'a K, &'a mut V) {
         unsafe { unwrap_unchecked(self.front.as_mut()).next_unchecked() }
     }
+
+    /// Returns an iterator of references over the remaining items.
+    #[inline]
+    pub(super) fn iter(&self) -> Range<'_, K, V> {
+        Range {
+            front: self.front.as_ref().map(|f| f.reborrow()),
+            back: self.back.as_ref().map(|b| b.reborrow()),
+        }
+    }
 }
 
 #[stable(feature = "btree_range", since = "1.17.0")]
diff --git a/library/std/src/collections/hash/map.rs b/library/std/src/collections/hash/map.rs
index 4424a4c1992..f12cefffbf6 100644
--- a/library/std/src/collections/hash/map.rs
+++ b/library/std/src/collections/hash/map.rs
@@ -2042,13 +2042,9 @@ impl<K, V> ExactSizeIterator for ValuesMut<'_, K, V> {
 impl<K, V> FusedIterator for ValuesMut<'_, K, V> {}
 
 #[stable(feature = "std_debug", since = "1.16.0")]
-impl<K, V> fmt::Debug for ValuesMut<'_, K, V>
-where
-    K: fmt::Debug,
-    V: fmt::Debug,
-{
+impl<K, V: fmt::Debug> fmt::Debug for ValuesMut<'_, K, V> {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        f.debug_list().entries(self.inner.iter()).finish()
+        f.debug_list().entries(self.inner.iter().map(|(_, val)| val)).finish()
     }
 }
 
@@ -2076,7 +2072,7 @@ impl<K, V> ExactSizeIterator for IntoKeys<K, V> {
 impl<K, V> FusedIterator for IntoKeys<K, V> {}
 
 #[unstable(feature = "map_into_keys_values", issue = "75294")]
-impl<K: Debug, V: Debug> fmt::Debug for IntoKeys<K, V> {
+impl<K: Debug, V> fmt::Debug for IntoKeys<K, V> {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         f.debug_list().entries(self.inner.iter().map(|(k, _)| k)).finish()
     }
@@ -2106,7 +2102,7 @@ impl<K, V> ExactSizeIterator for IntoValues<K, V> {
 impl<K, V> FusedIterator for IntoValues<K, V> {}
 
 #[unstable(feature = "map_into_keys_values", issue = "75294")]
-impl<K: Debug, V: Debug> fmt::Debug for IntoValues<K, V> {
+impl<K, V: Debug> fmt::Debug for IntoValues<K, V> {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         f.debug_list().entries(self.inner.iter().map(|(_, v)| v)).finish()
     }