Incorrect compiler's suggestion on a #[derive(Deserialize)] on struct with an Option's field and custom deserialize_with · Issue #106720 · rust-lang/rust (original) (raw)

Given the following code (playground):

use serde::Deserialize;

pub fn custom_deserialize<'de, D>(deserializer: D) -> Result<bool, D::Error> where D: serde::Deserializer<'de>, { Ok(true) }

#[derive(Deserialize)] struct Foo { #[serde(deserialize_with = "custom_deserialize")] bar: Option, }

The current output is:

error[E0308]: mismatched types
  --> src/lib.rs:10:10
   |
10 | #[derive(Deserialize)]
   |          ^^^^^^^^^^^ expected enum `std::option::Option`, found `bool`
   |
   = note: expected enum `std::option::Option<bool>`
              found type `bool`
   = note: this error originates in the macro `try` (in Nightly builds, run with -Z macro-backtrace for more info)
help: try wrapping the expression in `Option`
   |
10 | #[derive(Some(Deserialize))]
   |          +++++           +

Ideally the output should look like (not sure of my proposition, but at least, the second part needs to change):

error[E0308]: mismatched types
  --> src/lib.rs:10:10
   |
10 | #[derive(Deserialize)]
   |          ^^^^^^^^^^^ expected enum `std::option::Option`, found `bool`
   |
   = note: expected enum `std::option::Option<bool>`
              found type `bool`
   = note: this error originates in the macro `try` (in Nightly builds, run with -Z macro-backtrace for more info)
help: try wrapping the expression in `Some`
   |
 3 | pub fn custom_deserialize<'de, D>(deserializer: D) -> Result<Option<bool>, D::Error>
   |                                                              +++++++    +

The compiler correctly identifies the code as incorrect, since the function used in deserialize_with returns a bool instead of an Option<bool>. However, the suggestion of the compiler seems off.

Discussion about this diagnostic problem has been started on URLO (see this thread).