From 2025de3ef0898ffa99545bd50aef868516c7f226 Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Sat, 17 Sep 2022 00:57:41 +1000 Subject: [PATCH] swarm-derive/: Allow for templated behaviours (#2907) This patch fixes an issue where we couldn't use type parameters on a behaviour with a custom out event that had different type parameters. --- CHANGELOG.md | 2 ++ Cargo.toml | 2 +- swarm-derive/CHANGELOG.md | 7 +++++ swarm-derive/Cargo.toml | 3 +- swarm-derive/src/lib.rs | 10 ++++-- swarm-derive/tests/test.rs | 62 ++++++++++++++++++++++++++++++++++++++ 6 files changed, 82 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0332b09b316..2aa74dae1df 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -47,6 +47,8 @@ - Update to [`libp2p-tcp` `v0.37.0`](transports/tcp/CHANGELOG.md#0370). +- Update to [`libp2p-swarm-derive` `v0.30.1`](swarm-derive/CHANGELOG.md#0301). + - Update to [`libp2p-metrics` `v0.10.0`](misc/metrics/CHANGELOG.md#0100). - Update to [`libp2p-kad` `v0.41.0`](protocols/kad/CHANGELOG.md#0410). diff --git a/Cargo.toml b/Cargo.toml index 0b67edda7f3..3f82880528b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -96,7 +96,7 @@ libp2p-relay = { version = "0.12.0", path = "protocols/relay", optional = true } libp2p-rendezvous = { version = "0.9.0", path = "protocols/rendezvous", optional = true } libp2p-request-response = { version = "0.21.0", path = "protocols/request-response", optional = true } libp2p-swarm = { version = "0.39.0", path = "swarm" } -libp2p-swarm-derive = { version = "0.30.0", path = "swarm-derive" } +libp2p-swarm-derive = { version = "0.30.1", path = "swarm-derive" } libp2p-uds = { version = "0.35.0", path = "transports/uds", optional = true } libp2p-wasm-ext = { version = "0.36.0", path = "transports/wasm-ext", default-features = false, optional = true } libp2p-yamux = { version = "0.40.0", path = "muxers/yamux", optional = true } diff --git a/swarm-derive/CHANGELOG.md b/swarm-derive/CHANGELOG.md index 79ddf8c8f2e..464bec7fe95 100644 --- a/swarm-derive/CHANGELOG.md +++ b/swarm-derive/CHANGELOG.md @@ -1,3 +1,10 @@ +# 0.30.1 [unreleased] + +- Fix an issue where the derive would generate bad code if the type parameters between the behaviour and a custom + out event differed. See [PR 2907]. + +[PR 2907]: https://github.com/libp2p/rust-libp2p/pull/2907 + # 0.30.0 - Remove support for removed `NetworkBehaviourEventProcess`. See [PR 2840]. diff --git a/swarm-derive/Cargo.toml b/swarm-derive/Cargo.toml index 89ee54447fc..1d2c54a9da1 100644 --- a/swarm-derive/Cargo.toml +++ b/swarm-derive/Cargo.toml @@ -3,7 +3,7 @@ name = "libp2p-swarm-derive" edition = "2021" rust-version = "1.56.1" description = "Procedural macros of libp2p-core" -version = "0.30.0" +version = "0.30.1" authors = ["Parity Technologies "] license = "MIT" repository = "https://github.com/libp2p/rust-libp2p" @@ -22,3 +22,4 @@ syn = { version = "1.0.8", default-features = false, features = ["clone-impls", libp2p = { path = "../", default-features = false, features = ["ping", "identify", "kad"] } either = "1.6.0" futures = "0.3.1" +void = "1" diff --git a/swarm-derive/src/lib.rs b/swarm-derive/src/lib.rs index 3e3bf5b8067..6899ba7d79d 100644 --- a/swarm-derive/src/lib.rs +++ b/swarm-derive/src/lib.rs @@ -100,7 +100,7 @@ fn build_struct(ast: &DeriveInput, data_struct: &DataStruct) -> TokenStream { .iter() .map(|field| { let ty = &field.ty; - quote! {#name #ty_generics: From< <#ty as #trait_to_impl>::OutEvent >} + quote! {#name: From< <#ty as #trait_to_impl>::OutEvent >} }) .collect::>(); (name, definition, from_clauses) @@ -537,6 +537,12 @@ fn build_struct(ast: &DeriveInput, data_struct: &DataStruct) -> TokenStream { }) }); + let out_event_reference = if out_event_definition.is_some() { + quote! { #out_event_name #ty_generics } + } else { + quote! { #out_event_name } + }; + // Now the magic happens. let final_quote = quote! { #out_event_definition @@ -545,7 +551,7 @@ fn build_struct(ast: &DeriveInput, data_struct: &DataStruct) -> TokenStream { #where_clause { type ConnectionHandler = #connection_handler_ty; - type OutEvent = #out_event_name #ty_generics; + type OutEvent = #out_event_reference; fn new_handler(&mut self) -> Self::ConnectionHandler { use #into_connection_handler; diff --git a/swarm-derive/tests/test.rs b/swarm-derive/tests/test.rs index dcddb3a6a3f..e0f77eefd30 100644 --- a/swarm-derive/tests/test.rs +++ b/swarm-derive/tests/test.rs @@ -350,3 +350,65 @@ fn generated_out_event_derive_debug() { require_debug::(); } + +#[test] +fn custom_out_event_no_type_parameters() { + use libp2p::core::connection::ConnectionId; + use libp2p::swarm::handler::DummyConnectionHandler; + use libp2p::swarm::{ + ConnectionHandler, IntoConnectionHandler, NetworkBehaviourAction, PollParameters, + }; + use libp2p::PeerId; + use std::task::Context; + use std::task::Poll; + + pub struct TemplatedBehaviour { + _data: T, + } + + impl NetworkBehaviour for TemplatedBehaviour { + type ConnectionHandler = DummyConnectionHandler; + type OutEvent = void::Void; + + fn new_handler(&mut self) -> Self::ConnectionHandler { + DummyConnectionHandler::default() + } + + fn inject_event( + &mut self, + _peer: PeerId, + _connection: ConnectionId, + message: <::Handler as ConnectionHandler>::OutEvent, + ) { + void::unreachable(message); + } + + fn poll( + &mut self, + _ctx: &mut Context, + _: &mut impl PollParameters, + ) -> Poll> { + Poll::Pending + } + } + + #[derive(NetworkBehaviour)] + #[behaviour(out_event = "OutEvent")] + struct Behaviour { + custom: TemplatedBehaviour, + } + + #[derive(Debug)] + enum OutEvent { + None, + } + + impl From for OutEvent { + fn from(_e: void::Void) -> Self { + Self::None + } + } + + require_net_behaviour::>(); + require_net_behaviour::>(); +}