Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

#[derive(NetworkBehaviour)] doesn't work as documented when out_event is set #2663

Closed
jacklund opened this issue May 22, 2022 · 4 comments
Closed

Comments

@jacklund
Copy link

Summary

When using #[derive(NetworkBehaviour)] as documented here, I get a compiler error.

Example code:

use libp2p::{
    floodsub::{Floodsub, FloodsubEvent},
    mdns::{Mdns, MdnsEvent},
    NetworkBehaviour,
};
use std::error::Error;

#[tokio::main]
async fn main() -> Result<(), Box<dyn Error>> {
    #[derive(NetworkBehaviour)]
    #[behaviour(out_event = Event)]
    struct MyBehaviour {
        floodsub: Floodsub,
        mdns: Mdns,
    }

    enum Event {
        FloodsubEvent(FloodsubEvent),
        MdnsEvent(MdnsEvent),
    }

    impl From<FloodsubEvent> for Event {
        fn from(event: FloodsubEvent) -> Self {
            Self::FloodsubEvent(event)
        }
    }

    impl From<MdnsEvent> for Event {
        fn from(event: MdnsEvent) -> Self {
            Self::MdnsEvent(event)
        }
    }
}

Expected behaviour

The code compiles

Actual behaviour

I get the following:

error[E0277]: the trait bound `(): From<MdnsEvent>` is not satisfied
  --> src/bin.rs:52:14
   |
52 |     #[derive(NetworkBehaviour)]
   |              ^^^^^^^^^^^^^^^^ the trait `From<MdnsEvent>` is not implemented for `()`
   |
   = help: the following implementations were found:
             <(Vec<u8>, std::net::SocketAddr) as From<trust_dns_proto::xfer::serial_message::SerialMessage>>
             <(netlink_packet_core::message::NetlinkMessage<T>, netlink_sys::addr::SocketAddr, M) as From<netlink_proto::protocol::request::Request<T, M>>>
   = help: see issue #48214
   = note: this error originates in the derive macro `NetworkBehaviour` (in Nightly builds, run with -Z macro-backtrace for more info)

error[E0277]: the trait bound `(): From<FloodsubEvent>` is not satisfied
  --> src/bin.rs:52:14
   |
52 |     #[derive(NetworkBehaviour)]
   |              ^^^^^^^^^^^^^^^^ the trait `From<FloodsubEvent>` is not implemented for `()`
   |
   = help: the following implementations were found:
             <(Vec<u8>, std::net::SocketAddr) as From<trust_dns_proto::xfer::serial_message::SerialMessage>>
             <(netlink_packet_core::message::NetlinkMessage<T>, netlink_sys::addr::SocketAddr, M) as From<netlink_proto::protocol::request::Request<T, M>>>
   = help: see issue #48214
   = note: this error originates in the derive macro `NetworkBehaviour` (in Nightly builds, run with -Z macro-backtrace for more info)

For more information about this error, try `rustc --explain E0277`.

Note: This may be because of #2373

Possible Solution

Not sure, but I'm guessing that somehow the default out_event of () is being used, somehow.

Version

  • libp2p version (version number, commit, or branch):
    0.44.0

Would you like to work on fixing this bug?

Sure, but I'm not very familiar with the code, having just started playing with your very awesome library.

@elenaf9
Copy link
Contributor

elenaf9 commented May 23, 2022

Hi @jacklund, I think the reason for your error is that #[behaviour(out_event = Event)] is incorrect syntax.
The attribute macro requires that the name of your custom event is provided as a String literal (see syn::MetaNameValue).

So it would have to be

    #[derive(NetworkBehaviour)]
    #[behaviour(out_event = "Event")] // Note the quotation marks around "Event".
    struct MyBehaviour {

If the syntax is incorrect, the NetworkBehaviour macro just sets the out_event to (), which caused your error. Lmk if this fixes it.


Imo it would be easier to debug this if we just panic within the macro if the syntax is incorrect. I would propose to do that in an Err case here

if let syn::Lit::Str(ref s) = m.lit {
let ident: syn::Type = syn::parse_str(&s.value()).unwrap();
out = quote! {#ident};
}

What do folks think? @jacklund Would you be interested in doing a PR for this?

@jacklund
Copy link
Author

🤦‍♂️

Amazing how I saw the way to do it, but my brain put it without the quotes, I think because I'm used to that mode with Rust.

I'll be happy to take a look at PR-ing that, thank you soooo much @elenaf9 for clearing that up!!

@jacklund
Copy link
Author

#2672

@thomaseizinger
Copy link
Contributor

Closing as stale.

@thomaseizinger thomaseizinger closed this as not planned Won't fix, can't repro, duplicate, stale Mar 29, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants