E0277: Trait bound not satisfied


#1

Need some help with the following error message.

error[E0277]: the trait bound `std::vec::Vec<D>: std::iter::FromIterator<<D as std::ops::Neg>::Output>` is not satisfied
   --> src/jq.rs:301:44
    |
301 |     Ok(thunk(doc)?.into_iter().map(|x| -x).collect())
    |                                            ^^^^^^^ a collection of type `std::vec::Vec<D>` cannot be built from an iterator
over elements of type `<D as std::ops::Neg>::Output`
    |
    = help: the trait `std::iter::FromIterator<<D as std::ops::Neg>::Output>` is not implemented for `std::vec::Vec<D>`
    = help: consider adding a `where std::vec::Vec<D>: std::iter::FromIterator<<D as std::ops::Neg>::Output>` bound

Scenario happens in this function:

fn do_neg<D>(thunk: &mut Thunk, doc: D) -> Result<Vec<D>> where D: Document {
    Ok(thunk(doc)?.into_iter().map(|x| -x).collect())
}

where Document trait is constrained as:

pub trait Document : Neg + Not + Mul + Div + Rem + Add + Sub {
}

and Thunk implements FnMut:

impl<D> FnMut<(D,)> for Thunk where D: Document {

The return value for FnMut’s call_mut is Result<Vec>

We are unwrapping the return value and applying Neg op on each D in Vec.
and finally collecting them back as Vec. That is when type signatures are
not matching.

Am I doing any mistake here ? Is it possible to resolve this issue ?


#2

That’s because Document::Neg is allowed to return anything else. I could implement Document on Foo, but make -Document be i32 if it wanted to. So result of -x is not D, but whatever else that D's Neg implementation decides it to be.

You can put bound Neg<Output=Document> to limit it to sensible implementations of Neg.


#3

Thanks, that solved the issue. More precisely I did the following.

pub trait Document :
    Clone + Sized + From<bool> + From<Json> +
    Neg<Output=Self> + Not<Output=Self> +
    Mul<Output=Self> + Div<Output=Self> + Rem<Output=Self> +
    Add<Output=Self> + Sub<Output=Self> +
    Shr<Output=Self> + Shl<Output=Self> +
    BitAnd<Output=Self> + BitXor<Output=Self> + BitOr<Output=Self> +
    PartialEq + PartialOrd +
    And<Output=Self> + Or<Output=Self> +
    Recurse + Slice + Comprehension {