-
-
Notifications
You must be signed in to change notification settings - Fork 791
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
#[derive(Serialize)
and #[derive(Deserialize)]
on deprecated types emit deprecation warnings
#2195
Comments
Not exactly a perfect workaround however you can disable the lint if the warnings are an issue by moving the deprecated items to another module (playground link). |
I am having trouble trying to use a deprecated struct in a (non-deprecated) enum. For example, this (playground) emits warnings no matter how hard I try to suppress them. If I don't derive serde traits on the enum, the problem goes away. mod current_structs {
use serde::{Deserialize, Serialize};
#[derive(Serialize, Deserialize)]
pub struct IsCurrent;
}
mod deprecated_structs {
#![allow(deprecated)]
use serde::{Deserialize, Serialize};
#[deprecated]
#[derive(Serialize, Deserialize)]
pub struct IsDeprecated;
}
use serde::{Deserialize, Serialize};
use current_structs::*;
#[allow(deprecated)]
use deprecated_structs::*;
#[allow(deprecated)]
#[derive(Serialize, Deserialize)]
enum Container {
#[allow(deprecated)]
A(#[allow(deprecated)] IsDeprecated),
B(IsCurrent),
} |
Allow deprecated in the `Serialize`/`Deserialize` derive implementations. This allows you to deprecate structs, enums, struct fields, or enum variants and not get compiler warnings/errors about use of deprecated thing. Resolves serde-rs#2195
Allow deprecated in the `Serialize`/`Deserialize` derive implementations. This allows you to deprecate structs, enums, struct fields, or enum variants and not get compiler warnings/errors about use of deprecated thing. Resolves serde-rs#2195
@eric-seppanen Simply put: you're missing a bang / exclamation point / If you go to the playground in the original issue and select "Tools" > "Expand Macros", you will find, among other code (and scoping magic aside), this: #[allow(unused_extern_crates, clippy :: useless_attribute)]
extern crate serde as _serde;
#[automatically_derived]
impl _serde::Serialize for WithSerialize {
fn serialize<__S>(&self, __serializer: __S)
-> _serde::__private::Result<__S::Ok, __S::Error> where
__S: _serde::Serializer {
_serde::Serializer::serialize_unit_struct(__serializer,
"WithSerialize")
}
} Here you can clearly see that the derive macro creates an That's why you need an inner attribute (#![...]), which applies to the containing scope. The problem with that is, now you're basically ignoring all deprecations in the whole module. That's where we try to limit the "damage" as much as possible, by putting the deprecated serde items into their own module. So the problem is not that you deprecated soem structs (which you put inside a module with an allow), but that you are again trying, through serde to use / instantiate that item. So all your serde items need to be inside that module, if they contain a deprecated item. Your module should probably be this: use serde::{Deserialize, Serialize};
#[derive(Serialize, Deserialize)]
pub struct IsCurrent;
mod deprecated_structs {
#![allow(deprecated)]
use super::*;
#[deprecated]
#[derive(Serialize, Deserialize)]
pub struct IsDeprecated;
#[derive(Serialize, Deserialize)]
pub enum Container {
A(IsDeprecated),
B(IsCurrent),
}
}
pub use deprecated_structs::*; But I think this still leaves a lot of potential to accidentally allow other deprecations, or ignore new ones that should not be allowed. There really should be some way to tell serde, to allow certain specific deprecated items. |
@Elias-Graf I don't think "you're missing a Yes, if I move the affected code into a module with the lint allowed, it will be suppressed (this is what I did it the real code that inspired my comment). But should we encourage that? Or should we try to allow more precisely targeted Rewriting my example to move the enum into one of the other modules isn't a general fix. In my example the modules were representing code that comes from other crates, so moving the enum isn't practical. If I'm trying to use a foreign deprecated item inside the enum, there seems to be no way to do that other than adding I don't think forgiving lints at module scope is a practice that should be encouraged. The technique I'd like to encourage is applying the attribute at the most focused level possible. This is possible almost everywhere else, but not here, as far as I can tell. The reason I think this is an interesting discussion at the serde level is because serde's derive proc-macro can see the attribute attached to the enum variant. If it wanted to, that macro could copy the |
@eric-seppanen I'm currently with the opinion of the author of this pr: #2879 (comment), which would fix the issue at hand. And sorry if I did not address your post correctly. I do notice it was too broadly written. I hoped it would also be of use to other people finding this in the future. |
Given this code (playground link):
I expect not to get deprecation warnings. Instead, I get the following:
Notice that the derives for
Default
don't trigger any warnings (this seems to have been fixed some time ago).Not aware of any workaround (other than undeprecating), and this leads to a bunch of warnings for things that are deprecated but that we still want to be able to support serialization for.
The text was updated successfully, but these errors were encountered: