rust-clippy icon indicating copy to clipboard operation
rust-clippy copied to clipboard

unsafe_derive_deserialize should ignore types that use #[serde(from)] or #[serde(try_from)]

Open chitoyuu opened this issue 2 years ago • 0 comments

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

chitoyuu avatar Aug 08 '22 09:08 chitoyuu