Reputation: 51
I have a trait for which I want to require that implementing types are iterable by borrow. I have managed to do this using a for<'x>
higher-ranked trait bound (HRTB) on &'x Self
.
However, I also want to require that the IntoIter
associated type implements ExactSizeIterator
, but every way I try to describe this in the type system causes compilation issues which seem to stem from the use of the HRTB (which I am not fully confident I'm using correctly).
Here is the (simplified) code:
struct Thing<'thing>(&'thing ());
trait Trait<'thing>
where
for<'x> &'x Self: IntoIterator<Item = &'x Thing<'thing>>,
// Compiles fine until uncommenting this line:
//for<'x> <&'x Self as IntoIterator>::IntoIter: ExactSizeIterator
{ }
struct Bucket<'things> {
things: Vec<Thing<'things>>,
}
struct BucketRef<'a, 'things: 'a> {
bucket: &'a Bucket<'things>,
}
impl<'x, 'a, 'things: 'a> IntoIterator for &'x BucketRef<'a, 'things> {
type Item = &'x Thing<'things>;
type IntoIter = std::slice::Iter<'x, Thing<'things>>;
fn into_iter(self) -> Self::IntoIter {
self.bucket.things.iter()
}
}
impl<'a, 'things: 'a> Trait<'things> for BucketRef<'a, 'things> { }
fn foo<'a, 'things>(anchor: &BucketRef<'a, 'things>) {
println!("{}", ExactSizeIterator::len(&anchor.into_iter()));
}
As written this compiles fine, but when I try to further restrict the bounds on Trait
via the commented line, I get the following compiler error:
error[E0277]: the trait bound `for<'x> <&'x anchor::BucketRef<'a, 'things> as std::iter::IntoIterator>::IntoIter: std::iter::ExactSizeIterator` is not satisfied
It seems to my not-a-compiler-writer mind that given rustc
appears able to determine inside the function foo
that all instances of &BucketRef
are ExactSizeIterator
s, that it should be able to do similarly for the trait bound, but this is not borne out in reality.
Can anyone explain to me why this doesn't work and if there is a better way to express either the bound itself or the intent behind the bound?
active toolchain
----------------
stable-x86_64-unknown-linux-gnu (default)
rustc 1.43.0 (4fb7144ed 2020-04-20)
Upvotes: 5
Views: 659
Reputation: 21
this maybe related to this compiler bug and will be fixed soon: https://github.com/rust-lang/rust/issues/56556
https://github.com/rust-lang/rust/pull/85499
workarounds: https://github.com/Lucretiel/joinery/blob/master/src/join.rs#L174-L188
Upvotes: 2