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

fix(swarm-derive): add bounds to OutEvent on generic fields #3393

Merged
merged 5 commits into from
Feb 1, 2023

Conversation

jxs
Copy link
Member

@jxs jxs commented Jan 26, 2023

Description

This PR isolates the bugfix for the NetworkBehaviour derive implementation for structures with generic fields. When out_event was not provided, the generated enum was missing the NetworkBehaviour impl constraint for the generic variants whilst using the generics for <Generic>::OutEvent.

Meanwhile I also found that the generated poll function loops the sub behaviours and either return's when Poll::Ready or break's when Poll::Pending. This is a relict from when we still had NetworkBehaviourEventProcess which had added a branch within this loop that did not return but consume the event and continue. This trait was removed a while ago meaning this loop is no longer needed.

Notes

code generated by the ping example:

fn poll(
        &mut self,
        cx: &mut std::task::Context,
        poll_params: &mut impl ::libp2p::swarm::derive_prelude::PollParameters,
    ) -> std::task::Poll<
        ::libp2p::swarm::derive_prelude::NetworkBehaviourAction<
            Self::OutEvent,
            Self::ConnectionHandler,
        >,
    > {
        use ::libp2p::swarm::derive_prelude::futures::*;
        loop {
            match ::libp2p::swarm::derive_prelude::NetworkBehaviour::poll(
                &mut self.keep_alive,
                cx,
                poll_params,
            ) {
                std::task::Poll::Ready(
                    ::libp2p::swarm::derive_prelude::NetworkBehaviourAction::GenerateEvent(
                        event,
                    ),
                ) => {
                    return std::task::Poll::Ready(
                        ::libp2p::swarm::derive_prelude::NetworkBehaviourAction::GenerateEvent(
                            BehaviourEvent::KeepAlive(event),
                        ),
                    );
                }
                std::task::Poll::Ready(
                    ::libp2p::swarm::derive_prelude::NetworkBehaviourAction::Dial {
                        opts,
                        handler: provided_handler,
                    },
                ) => {
                    return std::task::Poll::Ready(::libp2p::swarm::derive_prelude::NetworkBehaviourAction::Dial {
                        opts,
                        handler: ::libp2p::swarm::derive_prelude::IntoConnectionHandler::select(
                            provided_handler,
                            self.ping.new_handler(),
                        ),
                    });
                }
                std::task::Poll::Ready(
                    ::libp2p::swarm::derive_prelude::NetworkBehaviourAction::NotifyHandler {
                        peer_id,
                        handler,
                        event,
                    },
                ) => {
                    return std::task::Poll::Ready(::libp2p::swarm::derive_prelude::NetworkBehaviourAction::NotifyHandler {
                        peer_id,
                        handler,
                        event: ::libp2p::swarm::derive_prelude::Either::Left(event),
                    });
                }
                std::task::Poll::Ready(
                    ::libp2p::swarm::derive_prelude::NetworkBehaviourAction::ReportObservedAddr {
                        address,
                        score,
                    },
                ) => {
                    return std::task::Poll::Ready(::libp2p::swarm::derive_prelude::NetworkBehaviourAction::ReportObservedAddr {
                        address,
                        score,
                    });
                }
                std::task::Poll::Ready(
                    ::libp2p::swarm::derive_prelude::NetworkBehaviourAction::CloseConnection {
                        peer_id,
                        connection,
                    },
                ) => {
                    return std::task::Poll::Ready(::libp2p::swarm::derive_prelude::NetworkBehaviourAction::CloseConnection {
                        peer_id,
                        connection,
                    });
                }
                std::task::Poll::Pending => break,
            }
        }
        loop {
            match ::libp2p::swarm::derive_prelude::NetworkBehaviour::poll(
                &mut self.ping,
                cx,
                poll_params,
            ) {
                std::task::Poll::Ready(
                    ::libp2p::swarm::derive_prelude::NetworkBehaviourAction::GenerateEvent(
                        event,
                    ),
                ) => {
                    return std::task::Poll::Ready(
                        ::libp2p::swarm::derive_prelude::NetworkBehaviourAction::GenerateEvent(
                            BehaviourEvent::Ping(event),
                        ),
                    );
                }
                std::task::Poll::Ready(
                    ::libp2p::swarm::derive_prelude::NetworkBehaviourAction::Dial {
                        opts,
                        handler: provided_handler,
                    },
                ) => {
                    return std::task::Poll::Ready(::libp2p::swarm::derive_prelude::NetworkBehaviourAction::Dial {
                        opts,
                        handler: ::libp2p::swarm::derive_prelude::IntoConnectionHandler::select(
                            self.keep_alive.new_handler(),
                            provided_handler,
                        ),
                    });
                }
                std::task::Poll::Ready(
                    ::libp2p::swarm::derive_prelude::NetworkBehaviourAction::NotifyHandler {
                        peer_id,
                        handler,
                        event,
                    },
                ) => {
                    return std::task::Poll::Ready(::libp2p::swarm::derive_prelude::NetworkBehaviourAction::NotifyHandler {
                        peer_id,
                        handler,
                        event: ::libp2p::swarm::derive_prelude::Either::Right(event),
                    });
                }
                std::task::Poll::Ready(
                    ::libp2p::swarm::derive_prelude::NetworkBehaviourAction::ReportObservedAddr {
                        address,
                        score,
                    },
                ) => {
                    return std::task::Poll::Ready(::libp2p::swarm::derive_prelude::NetworkBehaviourAction::ReportObservedAddr {
                        address,
                        score,
                    });
                }
                std::task::Poll::Ready(
                    ::libp2p::swarm::derive_prelude::NetworkBehaviourAction::CloseConnection {
                        peer_id,
                        connection,
                    },
                ) => {
                    return std::task::Poll::Ready(::libp2p::swarm::derive_prelude::NetworkBehaviourAction::CloseConnection {
                        peer_id,
                        connection,
                    });
                }
                std::task::Poll::Pending => break,
            }
        }
        std::task::Poll::Pending
    }

Links to any relevant issues

Open Questions

Change checklist

  • I have performed a self-review of my own code
  • I have made corresponding changes to the documentation
  • I have added tests that prove my fix is effective or that my feature works
  • A changelog entry has been made in the appropriate crates

@jxs jxs force-pushed the fix-macro-generics branch from 9361a9f to bc86fbf Compare January 26, 2023 22:27
@thomaseizinger
Copy link
Contributor

thomaseizinger commented Jan 26, 2023

I think the loops are a historical left-over from when we had NetworkBehaviourEventProcess which would have consumed an event and then would have to poll the inner behaviour again. Well spotted!

jxs added 2 commits January 27, 2023 12:34
for generic types when out_event was not provided. Previously The enum generated
didn't have the NetworkBehaviour impl constraints whilst using the generics for <Generic>::OutEvent.
@jxs jxs force-pushed the fix-macro-generics branch from fbc639f to 2e1638d Compare January 27, 2023 12:34
@jxs jxs mentioned this pull request Jan 27, 2023
4 tasks
@thomaseizinger thomaseizinger changed the title fix(swarm_derive): Fix derive macro for structures with generic fields fix(swarm-derive): Fix derive macro for structures with generic fields Feb 1, 2023
.map(|where_clause| quote! {#where_clause, #(#additional_debug),*});

let match_variants = fields.map(|(variant, _ty)| variant);
let msg = format!("`NetworkBehaviour::OutEvent` produced by {name}.");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

swarm-derive/CHANGELOG.md Outdated Show resolved Hide resolved
@thomaseizinger thomaseizinger changed the title fix(swarm-derive): Fix derive macro for structures with generic fields fix(swarm-derive): add required bounds to OutEvent on generic fields Feb 1, 2023
@thomaseizinger thomaseizinger changed the title fix(swarm-derive): add required bounds to OutEvent on generic fields fix(swarm-derive): add bounds to OutEvent on generic fields Feb 1, 2023
@mergify mergify bot merged commit b98b03e into libp2p:master Feb 1, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants