I’m not sure if this is sensible, but if not it might inspire someone to have a better idea:
unsafe trait ExactSizeIterator {}
trait MaybeExactSizeIterator {
// Edit: The `&self` isn't actually used in the blanket impls, but it
// seems necessary for object safety?
fn size_hint_is_exact(&self) -> bool;
}
impl<T> MaybeExactSizeIterator for T where T: ExactSizeIterator {
fn size_hint_is_exact(&self) -> bool { true }
}
impl<T> MaybeExactSizeIterator for T where T: !ExactSizeIterator {
fn size_hint_is_exact(&self) -> bool { false }
}
trait Iterator : MaybeExactSizeIterator {
// ...
}
Pros:
- Addresses this issue.
- Everyone who accepts an
Iterator can get this information without loss of generality.
-
unsafe is in the right place.
Cons:
- It makes no sense to implement
ExactSizeIterator without also implementing Iterator, so the dependence is a bit weird.
- We have to have specialization that can get something like the above past the coherence rules. If you don’t have negative bounds of some sort, you unfortunately can’t express anything about the absence of an unsafe trait.