tokio-rs / prost

PROST! a Protocol Buffers implementation for the Rust Language
Apache License 2.0
3.78k stars 489 forks source link

#[deprecated] decorator is missing on enum access functions #985

Open Orycterope opened 6 months ago

Orycterope commented 6 months ago

If you declare a message with a deprecated enum field, like so:

message Shirt {
    Color deprecated_color = 1 [deprecated = true];
}

enum Color {
    BLUE = 0;
    RED = 1;
    GREEN = 2;
}

You don't get a deprecation warning if you try to use the deprecated_color access functions:

    // This produces a deprecation warning:
    shirt.deprecated_color = Color::Blue as _;

    // But this does not:
    shirt.set_deprecated_color(Color::Blue);

I've made a reproducer for this bug here: https://github.com/Orycterope/prost_deprecation_reproducer

It looks like this is because the generated structure correctly marks the field as deprecated but not the access functions generated by #[prost(enumeration = "Color", tag = "1")].

To see the actual function generated by the macro I had to use cargo expand:

cargo expand -p prost_reproducer_app --color always items | less -r
...
    #[allow(dead_code)]
    impl Shirt {
        ///Returns the enum value of `deprecated_color`, or the default if the field is set to an invalid enum value.
        pub fn deprecated_color(&self) -> Color {
            ::core::convert::TryFrom::try_from(self.deprecated_color)
                .unwrap_or(Color::default())
        }
        ///Sets `deprecated_color` to the provided enum value.
        pub fn set_deprecated_color(&mut self, value: Color) {
            self.deprecated_color = value as i32;
        }
    }

We can see that the functions have no #[deprecated] decorator attached to them. However, they do access deprecated_color internally, which should raise a warning. I don't know why rustc silences it (just because it's a macro ? Couldn't find anything about this behavior), but it does.