diff options
| author | Dylan DPC <99973273+Dylan-DPC@users.noreply.github.com> | 2023-02-13 11:12:50 +0530 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2023-02-13 11:12:50 +0530 |
| commit | f7caaa573ee179404454d6d8486e9f3e1d1b5482 (patch) | |
| tree | faf10b1f06fe827fb8bffa7f43a5b547be7cb05e | |
| parent | 2ec6aebb417a067b6ec4c1dd2b4e62ce0be0698e (diff) | |
| parent | 79d2430e9961c9b38aa8366f028fbcbcf98e74a5 (diff) | |
| download | rust-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.rs | 10 | ||||
| -rw-r--r-- | library/core/src/iter/traits/marker.rs | 11 |
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 |
