Why do I get "unsatisfied trait bounds" for a Vec<&&str> when using join?

Viewed 4450

I'm confused about this:

use itertools::Itertools; // 0.10.0

fn main() {
    let combos = ["a", "b", "c"].iter().combinations(2).collect::<Vec<_>>();
    println!("{:#?}", combos[0].join(""));
}
error[E0599]: the method `join` exists for struct `Vec<&&str>`, but its trait bounds were not satisfied
   --> src/main.rs:5:33
    |
5   |       println!("{:#?}", combos[0].join(""));
    |                                   ^^^^ method cannot be called on `Vec<&&str>` due to unsatisfied trait bounds
    |
    = note: the following trait bounds were not satisfied:
            `Vec<&&str>: Iterator`
            which is required by `Vec<&&str>: Itertools`
            `<[&&str] as Join<_>>::Output = _`
            `[&&str]: Iterator`
            which is required by `[&&str]: Itertools`
  1. Why is combos[0] a Vec<&&str>, rather than a Vec<&str>?
  2. What are the unsatisfied trait bounds here?
  3. How do I resolve the error?

I'm sure these answers are derivable from the book, but I was hoping not to have to read the whole book to write this trivial program. Perhaps one can not merely dabble in Rust ...

1 Answers

TL;DR the fix:

["a", "b", "c"].iter().copied().combinations(2).collect::<Vec<_>>()

Parts of your question have existing answers:

Concentrating on the remaining piece, we look at the error message:

= note: the following trait bounds were not satisfied:
        `Vec<&&str>: Iterator`
        which is required by `Vec<&&str>: Itertools`
        `<[&&str] as Join<_>>::Output = _`
        `[&&str]: Iterator`
        which is required by `[&&str]: Itertools`

You've created a Vec<&&str>. You are presumably trying to call slice::join:

pub fn join<Separator>(
    &self,
    sep: Separator
) -> <[T] as Join<Separator>>::Output
where
    [T]: Join<Separator>, 

The trait bounds for that method are not met:

fn satisfies<T: std::borrow::Borrow<str>>() {}
satisfies::<&&str>();
error[E0277]: the trait bound `&&str: Borrow<str>` is not satisfied
 --> src/main.rs:9:5
  |
8 |     fn satisfies<T: std::borrow::Borrow<str>>() {}
  |                     ------------------------ required by this bound in `satisfies`
9 |     satisfies::<&&str>();
  |     ^^^^^^^^^^^^^^^^^^ the trait `Borrow<str>` is not implemented for `&&str`

The compiler has instead selected Itertools::join:

pub fn join(&mut self, sep: &str) -> String
where
    Self::Item: Display, 

This also fails to resolve, as neither Vec<&&str> nor [&&str] implement Iterator, which would be required for Itertools to be implemented for those types.

I don't know why the compiler chooses to only report one of the failures. Perhaps it considers one more likely to be what you intended, or one is closer to being implemented, or maybe it's a bug or oversight in the trait resolution algorithm.

Related