[E0599] Please help me figure out which trait bounds are not satisfied

Hi,

I have been staring at this code and thinking about it for a couple of hours, but I am still not able to figure out which trait bounds are not satisfied. Any insight would be appreciated.

The method call is here: https://github.com/teohhanhui/stocker/blob/918bbd0f3b56b74316bfba18e7d04d3549fdcc33/src/event.rs#L44

The method is defined here: https://github.com/teohhanhui/stocker/blob/918bbd0f3b56b74316bfba18e7d04d3549fdcc33/src/reactive/stream_ext.rs#L44

The compiler error:

error[E0599]: no method named `with_latest_from` found for struct `reactive::stream_ext::WithLatestFrom<S, reactive_rs::stream::Map<U, reactive_rs::stream::NoContext<[closure@src/event.rs:36:75: 36:97]>>, reactive::stream_ext::NoContext<[closure@src/event.rs:41:58: 43:10]>>` in the current scope
   --> src/event.rs:44:10
    |
44  |         .with_latest_from(
    |          ^^^^^^^^^^^^^^^^ method not found in `reactive::stream_ext::WithLatestFrom<S, reactive_rs::stream::Map<U, reactive_rs::stream::NoContext<[closure@src/event.rs:36:75: 36:97]>>, reactive::stream_ext::NoContext<[closure@src/event.rs:41:58: 43:10]>>`
    | 
   ::: src/reactive/stream_ext.rs:227:1
    |
227 | pub struct WithLatestFrom<S, U, F> {
    | ----------------------------------
    | |
    | method `with_latest_from` not found for this
    | doesn't satisfy `_: reactive::stream_ext::StreamExt`
    | doesn't satisfy `_: reactive_rs::stream::Stream<'_>`
    |
    = note: the method `with_latest_from` exists but the following trait bounds were not satisfied:
            `reactive::stream_ext::WithLatestFrom<S, reactive_rs::stream::Map<U, reactive_rs::stream::NoContext<[closure@src/event.rs:36:75: 36:97]>>, reactive::stream_ext::NoContext<[closure@src/event.rs:41:58: 43:10]>>: reactive_rs::stream::Stream<'_>`
            which is required by `reactive::stream_ext::WithLatestFrom<S, reactive_rs::stream::Map<U, reactive_rs::stream::NoContext<[closure@src/event.rs:36:75: 36:97]>>, reactive::stream_ext::NoContext<[closure@src/event.rs:41:58: 43:10]>>: reactive::stream_ext::StreamExt`
            `&reactive::stream_ext::WithLatestFrom<S, reactive_rs::stream::Map<U, reactive_rs::stream::NoContext<[closure@src/event.rs:36:75: 36:97]>>, reactive::stream_ext::NoContext<[closure@src/event.rs:41:58: 43:10]>>: reactive_rs::stream::Stream<'_>`
            which is required by `&reactive::stream_ext::WithLatestFrom<S, reactive_rs::stream::Map<U, reactive_rs::stream::NoContext<[closure@src/event.rs:36:75: 36:97]>>, reactive::stream_ext::NoContext<[closure@src/event.rs:41:58: 43:10]>>: reactive::stream_ext::StreamExt`
            `&mut reactive::stream_ext::WithLatestFrom<S, reactive_rs::stream::Map<U, reactive_rs::stream::NoContext<[closure@src/event.rs:36:75: 36:97]>>, reactive::stream_ext::NoContext<[closure@src/event.rs:41:58: 43:10]>>: reactive_rs::stream::Stream<'_>`
            which is required by `&mut reactive::stream_ext::WithLatestFrom<S, reactive_rs::stream::Map<U, reactive_rs::stream::NoContext<[closure@src/event.rs:36:75: 36:97]>>, reactive::stream_ext::NoContext<[closure@src/event.rs:41:58: 43:10]>>: reactive::stream_ext::StreamExt`

Well it seems like this value does not implement Stream.

input_events
    .with_latest_from(activation_mouse_target_areas, |(ev, activation_areas)| {
        (*ev, *activation_areas)
    })

Try defining a function like this:

fn takes_a_stream<'a, S: Stream<'a>>(s: S) {}

and call it with the value above:

let s = input_events
    .with_latest_from(activation_mouse_target_areas, |(ev, activation_areas)| {
        (*ev, *activation_areas)
    });
takes_a_stream(s);

This should give an error message with more details about why it doesn't implement Stream. I tried locally, but one of the build scripts failed.

Once you figure out why, I recommend making sure that the where bounds on with_latest_from guarantee that the Stream impl for WithLatestFrom applies, as that results in much better error messages.

3 Likes

You need protoc from protobuf.

That's a cool "trick"! I tried it locally (after installing protoc) and it seems like C needs to be Clone.

1 Like

Thanks for all your help. I've rewritten it as such: https://github.com/teohhanhui/stocker/blob/35e20d35e6b964d1ba0c65bd6a6d7347268cb4cd/src/reactive/stream_ext.rs#L225-L262

Hi, I'm back again with a similar problem:

error[E0599]: no method named `insert` found for struct `std::cell::RefMut<'_, im::hash::map::HashMap<K, reactive::stream_ext::Grouped<'a, K, V, C>>>` in the current scope
   --> src/reactive/stream_ext.rs:255:50
    |
255 |                     key_grouped_map.borrow_mut().insert(key, grouped);
    |                                                  ^^^^^^ method not found in `std::cell::RefMut<'_, im::hash::map::HashMap<K, reactive::stream_ext::Grouped<'a, K, V, C>>>`
...
263 | pub struct Grouped<'a, K: Sized, V: 'a + Sized, C: 'a> {
    | ------------------------------------------------------ doesn't satisfy `_: std::clone::Clone`
    |
    = note: the method `insert` exists but the following trait bounds were not satisfied:
            `reactive::stream_ext::Grouped<'a, K, V, C>: std::clone::Clone`

at https://github.com/teohhanhui/stocker/blob/ad4076c988d2d8b2ebcb79fbdf97e092b256b568/src/reactive/stream_ext.rs#L255

Even though Grouped clearly implements Clone: https://github.com/teohhanhui/stocker/blob/ad4076c988d2d8b2ebcb79fbdf97e092b256b568/src/reactive/stream_ext.rs#L262

I took a look at the docs using cargo doc --open to see what the derived Clone impl actually looks like, and found

impl<'a, K: Clone + Sized, V: Clone + 'a + Sized, C: Clone + 'a> Clone for Grouped<'a, K, V, C>

The derived Clone works by simply cloning each field I'm pretty sure, so all its fields need to be Clone for it to work, and so the impl has a Clone bound on all the generic types. You can make it compile by adding Clone bounds to V and C in subscribe_ctx's signature.

1 Like

Uhh, I was wondering if there's a way to see the derived implementation. Thanks for that tip!

It would be great though if rust-analyzer supports viewing such code directly.

And I really hope the compiler can be more helpful in such cases. Do you know of any discussion on this front?

But I'm also wondering why there's Clone bound on V and C. These types would never actually get cloned. I guess it's a limitation of derive (since it can't tell)?

I agree that the error message could be a lot better, I've definitely hit this kind of issue before myself. I was able to find a relatively recent issue on it, looks like it's already better on nightly! (edit: maybe not...I tried it on nightly and the error message is the same, maybe it only works for simple cases)

Seems like it: https://github.com/rust-lang/rust/issues/26925

In addition to cargo doc --open, you can also use cargo expand reactive::stream_ext (needs to be installed separately with cargo install cargo-expand) to look at what a module looks like after macro expansion, though there's quite a bit of noise from all the other things in the module. Running it and then searching for Clone for Grouped finds

    impl<
            'a,
            K: ::core::clone::Clone + Sized,
            V: ::core::clone::Clone + 'a + Sized,
            C: ::core::clone::Clone + 'a,
        > ::core::clone::Clone for Grouped<'a, K, V, C>
    { ... }

There's an issue to do it from rust-analyzer, so maybe this'll become more convenient in the future as well.

1 Like

Saw this from https://github.com/rust-lang/rust/issues/26925, it looks like the derivative crate would come in handy: https://mcarton.github.io/rust-derivative/Clone.html