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

better checking of tag duplicates, avoid discarding invalid variant errs #951

Merged
merged 11 commits into from
May 24, 2024

Conversation

mumbleskates
Copy link
Contributor

@mumbleskates mumbleskates commented Nov 25, 2023

Currently it seems that the "invalid oneof variant" Errs are always discarded because they are being passed directly into flat_map from a closure, rather than actually propagating the error.

This PR also streamlines the checks for duplicated tag numbers and adds some rudimentary tests for the affected code in those proc macros.

Comment on lines 96 to 98
.sorted_unstable()
.tuple_windows()
.find(|(a, b)| a == b)
Copy link
Contributor Author

Choose a reason for hiding this comment

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

it would kinda be preferable to write this as .duplicates().next() using Itertools, but that method unfortunately requires use_std.

Copy link
Collaborator

Choose a reason for hiding this comment

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

As I understand prost_derive will run on the host, so it is not subject to no_std rules. The code does also use std::fmt;, so std must be available. So I think it is safe to use_std for Itertools. Do you agree?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

yeah from what i've seen since i published this that is totally possible. i'll update it

Copy link
Collaborator

Choose a reason for hiding this comment

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

It seems you updated the other case, but not this one. Was that intentional?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

it was not.

@mumbleskates mumbleskates marked this pull request as ready for review November 26, 2023 00:10
@mumbleskates mumbleskates force-pushed the deduping branch 2 times, most recently from ef347ff to 01eaa46 Compare May 17, 2024 13:56
@mumbleskates mumbleskates force-pushed the deduping branch 3 times, most recently from 169f10c to b235c8b Compare May 17, 2024 14:08
Copy link
Collaborator

@caspermeijn caspermeijn left a comment

Choose a reason for hiding this comment

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

This fixes the error reporting for duplicate tags, improves the error message and adds tests. I like it.

prost-derive/src/lib.rs Show resolved Hide resolved
Comment on lines 96 to 98
.sorted_unstable()
.tuple_windows()
.find(|(a, b)| a == b)
Copy link
Collaborator

Choose a reason for hiding this comment

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

As I understand prost_derive will run on the host, so it is not subject to no_std rules. The code does also use std::fmt;, so std must be available. So I think it is safe to use_std for Itertools. Do you agree?

prost-derive/src/lib.rs Show resolved Hide resolved
@@ -412,23 +414,21 @@ fn try_oneof(input: TokenStream) -> Result<TokenStream, Error> {
}
}

let mut tags = fields
if fields.iter().any(|(_, field)| field.tags().len() > 1) {
panic!("variant with multiple tags"); // Not clear if this is possible, but good to be safe
Copy link
Collaborator

Choose a reason for hiding this comment

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

This error message is a regression, right? The old message was: "invalid oneof variant {}::{}: oneof variants may only have a single tag"

Copy link
Contributor Author

Choose a reason for hiding this comment

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

i can re-expand this, sure

prost-derive/src/lib.rs Show resolved Hide resolved
prost-derive/Cargo.toml Outdated Show resolved Hide resolved
prost-derive/Cargo.toml Show resolved Hide resolved
prost-derive/src/lib.rs Show resolved Hide resolved
prost-derive/src/lib.rs Show resolved Hide resolved
Comment on lines 96 to 98
.sorted_unstable()
.tuple_windows()
.find(|(a, b)| a == b)
Copy link
Collaborator

Choose a reason for hiding this comment

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

It seems you updated the other case, but not this one. Was that intentional?

prost-derive/src/lib.rs Outdated Show resolved Hide resolved
@mumbleskates
Copy link
Contributor Author

mumbleskates commented May 24, 2024

incidentally, most (all? probably, all) of my contributions to Prost were discovered/developed while forking and almost completely rewriting it. Downstream of here i have changed the nature of the encoding slightly (not dramatically), but i have also achieved huge strides in usability:

  • fully trait-based dispatch for encoding and decoding, with derive attributes simple enough to use on existing user types and support for generics and lifetimes on message types
  • ignored fields
  • useful functionality on the object-safe traits
  • oneofs that may bear their own empty variant rather than needing to nest within Option
  • oneofs in messages must have known matching tags, checked at compile time
  • greatly increased type support, including nesting values in ways that protobuf schemas cannot even express
  • novel linear-time encoding via writing the output back-to-front, which can be dramatically faster without caching extra data inside the structs
  • guaranteed field ordering (protobuf as an encoding has no real use for this)
  • distinguished decoding of canonical data (protobuf can't do this as easily)
  • all of this and it's actually faster

if any of these sound useful to upstream it could be a good project for myself or someone to trace back over my steps in achieving all some of these. some of these can probably be upstreamed in a day or two, others could take longer.

Copy link
Collaborator

@caspermeijn caspermeijn left a comment

Choose a reason for hiding this comment

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

Thanks for your contribution

prost-derive/src/lib.rs Show resolved Hide resolved
prost-derive/src/lib.rs Outdated Show resolved Hide resolved
@caspermeijn
Copy link
Collaborator

if any of these sound useful to upstream it could be a good project for myself or someone to trace back over my steps in achieving all these. some of these can probably be upstreamed in a day or two, others could take longer.

Improvements are welcome. However, review capacity is low, so bringing in a reviewer would be appreciated.

Keep in mind that prost is focused on an unopinionated implementation of protobuf.

@caspermeijn caspermeijn added this pull request to the merge queue May 24, 2024
Merged via the queue into tokio-rs:master with commit eec717b May 24, 2024
14 checks passed
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 this pull request may close these issues.

None yet

2 participants