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

Recursive oneof message cannot compile #1143

Open
kvc0 opened this issue Aug 31, 2024 · 3 comments
Open

Recursive oneof message cannot compile #1143

kvc0 opened this issue Aug 31, 2024 · 3 comments

Comments

@kvc0
Copy link

kvc0 commented Aug 31, 2024

Expected: A message with a oneof can refer to a map of itself.

Observed: An opaque error message

error[E0596]: cannot borrow `value` as mutable, as it is not declared as mutable
  --> src/value_wrapper.rs:11:28
   |
11 | #[derive(Clone, PartialEq, prost::Oneof)]
   |                            ^^^^^^^^^^^^ cannot borrow as mutable
   |
   = note: this error originates in the derive macro `prost::Oneof` (in Nightly builds, run with -Z macro-backtrace for more info)

Source

use std::collections::HashMap;

#[derive(Clone, PartialEq, prost::Message)]
pub struct DiskValue {
    #[prost(oneof = "ValueKind", tags = "1")]
    pub kind: Option<ValueKind>,
}

#[derive(Clone, PartialEq, prost::Oneof)]
pub enum ValueKind {
    #[prost(map = "string, message", tag = "1")]
    Map(HashMap<String, DiskValue>),
}

I carefully referenced https://github.com/tokio-rs/prost/blob/master/tests/src/message_encoding.rs . This is likely PBKAC but I seem to be missing something here. I have no field named "value" and I'm not sure how to inspect this procedural macro. I use VS Code and Rust Analyzer doesn't have an option to expand the macro to show what's happening.

I'm not using a .proto. This is my source code for dependency prost = { version = "0.13" }

@caspermeijn
Copy link
Collaborator

I don't have experience with using derive prost::OneOf. If you model this in a .proto, does that work? Is the generated code any different from the example?

@Subserial
Copy link

Flyby comment, from the proto3 docs:

You can add fields of any type, except map fields and repeated fields. If you need to add a repeated field to a oneof, you can use a message containing the repeated field.

...and from the proto2 docs:

You can add fields of any type except map fields, but you cannot use the required, optional, or repeated keywords. If you need to add a repeated field to a oneof, you can use a message containing the repeated field.

It might just be a coincidence that it doesn't compile, but it does abide to the specs.

@caspermeijn
Copy link
Collaborator

I don't have experience with using derive prost::OneOf. If you model this in a .proto, does that work? Is the generated code any different from the example?

@kvc0 Can you provide a failing example using a .proto file?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants