rust-lang / rust-lang/rust-clippy
unsafe_derive_deserialize should ignore types that use #[serde(from)] or #[serde(try_from)]
Nobody has claimed this yet.
- Dominant language
- Rust
- Stars
- 13.5k
- Forks
- 2.2k
- Avg merge
- 2d 10h
- Merged PRs (30d)
- 32
Description
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
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by locating the implementation and tests for the unsafe_derive_deserialize lint, then inspect how serde(from) and serde(try_from) attributes are handled. Add regression coverage for both conversion attributes and verify that valid derives no longer produce the lint diagnostic.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- devtools
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 48/100