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

impl ::prost::Message for a struct shadows the user-defined type #1042

Open
shizzard opened this issue Apr 25, 2024 · 3 comments · May be fixed by #1045
Open

impl ::prost::Message for a struct shadows the user-defined type #1042

shizzard opened this issue Apr 25, 2024 · 3 comments · May be fixed by #1045

Comments

@shizzard
Copy link

shizzard commented Apr 25, 2024

Minimal protobuf file to reproduce:

syntax = "proto3";
enum B {
  DEFAULT = 0;
  NON_DEFAULT = 1;
}
message A { B f1 = 1; }

Problem is that generated impl ::prost::Message for A contains a generic type parameter for a number of functions, that shadows the B enum:

            #[allow(unused_variables)]
            fn encode_raw<B>(&self, buf: &mut B)
            where
                B: ::prost::bytes::BufMut,
            {
                if self.f1 != B::default() as i32 {
                    ::prost::encoding::int32::encode(1u32, &self.f1, buf);
                }
            }

The error message from the compiler, that is not clear:

error[E0599]: no function or associated item named `default` found for type parameter `B` in the current scope
 --> tests/../.proto_out/test.rs:3:28
  |
3 | #[derive(Clone, PartialEq, ::prost::Message)]
  |                            ^^^^^^^^^^^^^^^^
  |                            |
  |                            function or associated item not found in `B`
  |                            function or associated item `default` not found for this type parameter
  |
  = help: items from traits can only be used if the type parameter is bounded by the trait
  = note: this error originates in the derive macro `::prost::Message` (in Nightly builds, run with -Z macro-backtrace for more info)
help: the following trait defines an item `default`, perhaps you need to restrict type parameter `B` with it:
  |
3 | #[derive(Clone, PartialEq, ::prost::Message: Default)]
  |                                            +++++++++

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

There are at least two possible solutions:

  1. Rename the generic type parameter to reduce the chance of ident clashes (e.g. <ImplProstBytesBufMut> instead of <B>);
  2. Add a note or a known issue regarding this problem.

Probably, there are some other similar issues that are not noticed yet.

@caspermeijn
Copy link
Collaborator

So because you generate an enum B and there is a generic type B, there is a conflict.

The simplest solution seems to change the generated function signature to: fn encode_raw(&self, buf: &mut impl ::prost::bytes::BufMut). That way there is no generic parameter B. Are you willing to create a PR that changes all <B> + where B to a impl Type?

@shizzard
Copy link
Author

shizzard commented Apr 26, 2024

Yes, the solution makes sense, I'll make a PR with these changes.

@shizzard
Copy link
Author

@caspermeijn note, I also changed the generated functions for enums (Enumeration derive), to make everything consistent and to avoid similar issues with enums.

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

Successfully merging a pull request may close this issue.

2 participants