Repository: serde-rs/serde
File: serde_derive/src/de.rs (Rust)

Code before:
    } else {
        let ignore_variant = quote!(__ignore,);
        let fallthrough = quote!(_serde::__private::Ok(#this_value::__ignore));
        (Some(ignore_variant), Some(fallthrough))
    };

    let visitor_impl = Stmts(deserialize_identifier(
        &this_value,
        fields,
        is_variant,
        fallthrough,
        None,
        !is_variant && cattrs.has_flatten(),
        None,
    ));

    let lifetime = if !is_variant && cattrs.has_flatten() {
        Some(quote!(<'de>))
    } else {
        None
    };

    quote_block! {
        #[allow(non_camel_case_types)]
        #[doc(hidden)]
        enum #this_value #lifetime {
            #(#field_idents,)*
            #ignore_variant
        }

        #[doc(hidden)]
        struct __FieldVisitor;

        impl<'de> _serde::de::Visitor<'de> for __FieldVisitor {
            type Value = #this_value #lifetime;

            #visitor_impl
        }

        impl<'de> _serde::Deserialize<'de> for #this_value #lifetime {
            #[inline]
            fn deserialize<__D>(__deserializer: __D) -> _serde::__private::Result<Self, __D::Error>
            where
                __D: _serde::Deserializer<'de>,
            {
                _serde::Deserializer::deserialize_identifier(__deserializer, __FieldVisitor)
            }
        }
    }
}


Review comment (bug):
I think the use of `#this_value` is semantically incorrect here and in all the places below in this function. `this_value` refers to the expression-ized (using turbofish) name of a potentially remote type. For example in the case of `serde(remote = "Foo<Bar>")`, we'd have this_type=`Foo<Bar>` and this_value=`Foo::<Bar>`. The turbofish makes it appropriate for use in expression position such as `let _ = #this_value::deserialize(d)`, as opposed to type position such as `let _: #this_value = ...`.

That is not consistent with how you've applied it in this function.

Code after:
        }
        Some(path) => {
            quote_block! {
                let __value: _serde::__private::Result<#field_ty, _> = #path(#deserializer);
                _serde::__private::Result::map(__value, #this_value::#variant_ident)
            }
        }
    }
}

fn deserialize_generated_identifier(
    fields: &[(String, Ident, Vec<String>)],
    cattrs: &attr::Container,
    is_variant: bool,
    other_idx: Option<usize>,
) -> Fragment {
    let this_value = quote!(__Field);
    let field_idents: &Vec<_> = &fields.iter().map(|(_, ident, _)| ident).collect();

    let (ignore_variant, fallthrough) = if !is_variant && cattrs.has_flatten() {
        let ignore_variant = quote!(__other(_serde::__private::de::Content<'de>),);
        let fallthrough = quote!(_serde::__private::Ok(__Field::__other(__value)));
        (Some(ignore_variant), Some(fallthrough))
    } else if let Some(other_idx) = other_idx {
        let ignore_variant = fields[other_idx].1.clone();
        let fallthrough = quote!(_serde::__private::Ok(__Field::#ignore_variant));
        (None, Some(fallthrough))
    } else if is_variant || cattrs.deny_unknown_fields() {
        (None, None)
    } else {
        let ignore_variant = quote!(__ignore,);
        let fallthrough = quote!(_serde::__private::Ok(__Field::__ignore));
        (Some(ignore_variant), Some(fallthrough))
    };

    let visitor_impl = Stmts(deserialize_identifier(
        &this_value,
        fields,
        is_variant,
        fallthrough,
        None,
        !is_variant && cattrs.has_flatten(),
        None,
    ));

    let lifetime = if !is_variant && cattrs.has_flatten() {
        Some(quote!(<'de>))
    } else {
        None
    };