rust-clippy
rust-clippy copied to clipboard
unsafe_derive_deserialize should ignore types that use #[serde(from)] or #[serde(try_from)]
Summary
When deriving Deserialize
for a type with #[serde(from)]
or #[serde(try_from)]
, serde only generates wrapper code that invokes the safe interface of standard conversion traits. As such, there is no risk of it invalidating unsafe invariants, provided that the impls are correct.
Lint Name
unsafe_derive_deserialize
Reproducer
I tried this code:
#![deny(clippy::unsafe_derive_deserialize)]
use serde::{Serialize, Deserialize};
#[derive(Serialize, Deserialize)]
#[serde(try_from = "bool")]
pub struct False;
#[derive(Debug)]
pub struct TrueError;
impl std::fmt::Display for TrueError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "bruh")
}
}
impl TryFrom<bool> for False {
type Error = TrueError;
fn try_from(b: bool) -> Result<Self, TrueError> {
if b {
Err(TrueError)
} else {
Ok(False)
}
}
}
impl False {
pub const unsafe fn new_unchecked(b: bool) -> Self {
False
}
}
I saw this happen:
error: you are deriving `serde::Deserialize` on a type that has methods using `unsafe`
--> src/lib.rs:5:21
|
5 | #[derive(Serialize, Deserialize)]
| ^^^^^^^^^^^
|
note: the lint level is defined here
--> src/lib.rs:1:9
|
1 | #![deny(clippy::unsafe_derive_deserialize)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
= help: consider implementing `serde::Deserialize` manually. See https://serde.rs/impl-deserialize.html
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#unsafe_derive_deserialize
= note: this error originates in the derive macro `Deserialize` (in Nightly builds, run with -Z macro-backtrace for more info)
I expected to see this happen:
Code compiles.
Version
rustc 1.62.1 (e092d0b6b 2022-07-16)
binary: rustc
commit-hash: e092d0b6b43f2de967af0887873151bb1c0b18d3
commit-date: 2022-07-16
host: x86_64-unknown-linux-gnu
release: 1.62.1
LLVM version: 14.0.5
Additional Labels
No response