Bound for reference of associated type

557 Views Asked by At

I need an associated type that is bound to be "any kind of collection" (i.e. anything that has a .iter() method). Now, .iter() in rust collections isn't part of a trait usually, but collections do implement &Vec: IntoIterator, which does the same thing since IntoIterator is implemented on the reference of a Vec and creates an iterator borrowing the elements. So basically, now I want to define an associated type whose reference has a bound to IntoIterator.

trait MyTrait {
    // This defines the bound on `U8Collection` but I want to put the bound on `&U8Collection`.
    type U8Collection: IntoIterator<Item = &u8>;
    
    fn make(&self) -> Self::U8Collection;
}

First attempt

#![feature(generic_associated_types)]

trait MyTrait {
    type U8Collection where for <'a> &'a Self::U8Collection : IntoIterator<Item = &'a u8>;
    
    fn make(&self) -> Self::U8Collection;
}

fn f(s: impl MyTrait) {
    let x = s.make();
    IntoIterator::into_iter(&x);
}

playground

Fails with

error[E0277]: `&'a <Self as MyTrait>::U8Collection` is not an iterator
 --> src/lib.rs:6:23
  |
6 |     fn make(&self) -> Self::U8Collection;
  |                       ^^^^^^^^^^^^^^^^^^ `&'a <Self as MyTrait>::U8Collection` is not an iterator
  |
  = help: the trait `for<'a> Iterator` is not implemented for `&'a <Self as MyTrait>::U8Collection`
  = note: required because of the requirements on the impl of `for<'a> IntoIterator` for `&'a <Self as MyTrait>::U8Collection`
note: required by a bound in `MyTrait::U8Collection`
 --> src/lib.rs:4:63
  |
4 |     type U8Collection where for <'a> &'a Self::U8Collection : IntoIterator<Item = &'a u8>;
  |                                                               ^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `MyTrait::U8Collection`

For more information about this error, try `rustc --explain E0277`.
error: could not compile `playground` due to previous error

Second attempt

#![feature(generic_associated_types)]

trait MyTrait where for <'a> &'a Self::U8Collection : IntoIterator<Item = &'a u8> {
    type U8Collection;
    
    fn make(&self) -> Self::U8Collection;
}

fn f(s: impl MyTrait) {
    let x = s.make();
    IntoIterator::into_iter(&x);
}

playground

Fails with:

error[E0277]: `&'a <impl MyTrait as MyTrait>::U8Collection` is not an iterator
 --> src/lib.rs:9:14
  |
9 | fn f(s: impl MyTrait) {
  |              ^^^^^^^ `&'a <impl MyTrait as MyTrait>::U8Collection` is not an iterator
  |
  = help: the trait `for<'a> Iterator` is not implemented for `&'a <impl MyTrait as MyTrait>::U8Collection`
  = note: required because of the requirements on the impl of `for<'a> IntoIterator` for `&'a <impl MyTrait as MyTrait>::U8Collection`
note: required by a bound in `MyTrait`
 --> src/lib.rs:3:55
  |
3 | trait MyTrait where for <'a> &'a Self::U8Collection : IntoIterator<Item = &'a u8> {
  |                                                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `MyTrait`

For more information about this error, try `rustc --explain E0277`.
error: could not compile `playground` due to previous error

Any ideas how I could write such a bound?

0

There are 0 best solutions below