0

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?

Heinzi
  • 5,793
  • 4
  • 40
  • 69
  • 1
    Does this answer your question? [How to write a trait bound for a reference to an associated type on the trait itself?](https://stackoverflow.com/questions/50090578/how-to-write-a-trait-bound-for-a-reference-to-an-associated-type-on-the-trait-it) – cdhowie Apr 25 '22 at 02:51
  • @cdhowie A lot has changed on the GAT front and it's unclear for how much longer this question will remain a duplicate of that question. For instance, [where clauses on associated types](https://rust-lang.github.io/rfcs/1598-generic_associated_types.html#where-clauses-on-associated-types) seems to be the right answer to this question, but aren't mentioned in the original question. Given that some of the newer GAT stuff obviates the answer to the original question, but isn't yet stable, I think this question shouldn't be closed as a duplicate. – BallpointBen Apr 25 '22 at 04:42
  • 1
    @BallpointBen It's still a duplicate, it just means the original answer needs to be updated or a new answer be written. – cdhowie Apr 25 '22 at 17:55
  • I dont understan why would you want to bound a `&` reference to `IntoIterator` when the trait consumes the object. I think this is an X/Y problem. Could you expand on what do you want to do, instead of how are you trying to solve it? does [this](https://play.rust-lang.org/?version=nightly&mode=debug&edition=2021&gist=f93585fc86ebca34e1a0d1ec96befe48) helps? – Netwave Apr 26 '22 at 11:36

0 Answers0