about summary refs log tree commit diff
diff options
context:
space:
mode:
authorDylan DPC <99973273+Dylan-DPC@users.noreply.github.com>2023-02-13 11:12:50 +0530
committerGitHub <noreply@github.com>2023-02-13 11:12:50 +0530
commitf7caaa573ee179404454d6d8486e9f3e1d1b5482 (patch)
treefaf10b1f06fe827fb8bffa7f43a5b547be7cb05e
parent2ec6aebb417a067b6ec4c1dd2b4e62ce0be0698e (diff)
parent79d2430e9961c9b38aa8366f028fbcbcf98e74a5 (diff)
downloadrust-f7caaa573ee179404454d6d8486e9f3e1d1b5482.tar.gz
rust-f7caaa573ee179404454d6d8486e9f3e1d1b5482.zip
Rollup merge of #107962 - scottmcm:why-not-exact, r=Mark-Simulacrum
Add a doc note about why `Chain` is not `ExactSizeIterator`

Inspired by <https://rust-lang.zulipchat.com/#narrow/stream/122651-general/topic/Why.20isn't.20Chain.3CA.2C.20B.3E.20an.20ExactSizeIterator.3F/near/327395874>.
-rw-r--r--library/core/src/iter/traits/exact_size.rs10
-rw-r--r--library/core/src/iter/traits/marker.rs11
2 files changed, 21 insertions, 0 deletions
diff --git a/library/core/src/iter/traits/exact_size.rs b/library/core/src/iter/traits/exact_size.rs
index 1757e37ec0e..908830d8a95 100644
--- a/library/core/src/iter/traits/exact_size.rs
+++ b/library/core/src/iter/traits/exact_size.rs
@@ -21,6 +21,16 @@
 ///
 /// [`len`]: ExactSizeIterator::len
 ///
+/// # When *shouldn't* an adapter be `ExactSizeIterator`?
+///
+/// If an adapter makes an iterator *longer*, then it's usually incorrect for
+/// that adapter to implement `ExactSizeIterator`.  The inner exact-sized
+/// iterator might already be `usize::MAX`-long, and thus the length of the
+/// longer adapted iterator would no longer be exactly representable in `usize`.
+///
+/// This is why [`Chain<A, B>`](crate::iter::Chain) isn't `ExactSizeIterator`,
+/// even when `A` and `B` are both `ExactSizeIterator`.
+///
 /// # Examples
 ///
 /// Basic usage:
diff --git a/library/core/src/iter/traits/marker.rs b/library/core/src/iter/traits/marker.rs
index da753745740..af02848233d 100644
--- a/library/core/src/iter/traits/marker.rs
+++ b/library/core/src/iter/traits/marker.rs
@@ -31,6 +31,17 @@ impl<I: FusedIterator + ?Sized> FusedIterator for &mut I {}
 /// The iterator must produce exactly the number of elements it reported
 /// or diverge before reaching the end.
 ///
+/// # When *shouldn't* an adapter be `TrustedLen`?
+///
+/// If an adapter makes an iterator *shorter* by a given amount, then it's
+/// usually incorrect for that adapter to implement `TrustedLen`.  The inner
+/// iterator might return more than `usize::MAX` items, but there's no way to
+/// know what `k` elements less than that will be, since the `size_hint` from
+/// the inner iterator has already saturated and lost that information.
+///
+/// This is why [`Skip<I>`](crate::iter::Skip) isn't `TrustedLen`, even when
+/// `I` implements `TrustedLen`.
+///
 /// # Safety
 ///
 /// This trait must only be implemented when the contract is upheld. Consumers