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

Code before:
        .filter(|&(_, variant)| !variant.attrs.skip_deserializing())
        .map(|(i, variant)| {
            let variant_name = field_i(i);

            let block = Match(deserialize_externally_tagged_variant(
                params, variant, cattrs,
            ));

            quote! {
                _serde::#private::Ok((__Field::#variant_name, __variant)) => #block
            }
        });

    quote_block! {
        #variant_visitor

        #[doc(hidden)]
        struct __Visitor #de_impl_generics #where_clause {
            marker: _serde::#private::PhantomData<#this_type #ty_generics>,
            lifetime: _serde::#private::PhantomData<&#delife ()>,
        }

        #[automatically_derived]
        impl #de_impl_generics _serde::de::Visitor<#delife> for __Visitor #de_ty_generics #where_clause {
            type Value = #this_type #ty_generics;

            fn expecting(&self, __formatter: &mut _serde::#private::Formatter) -> _serde::#private::fmt::Result {
                _serde::#private::Formatter::write_str(__formatter, #expecting)
            }

            fn visit_enum<__A>(self, __data: __A) -> _serde::#private::Result<Self::Value, __A::Error>
            where
                __A: _serde::de::EnumAccess<#delife>,
            {
                match _serde::de::EnumAccess::variant::<__Field>(__data) {
                    #(#variant_arms)*
                    _serde::#private::Err(__err) => _serde::#private::Err(__err),
                }
            }
        }

        #variants_stmt

        _serde::Deserializer::deserialize_enum(
            __deserializer,
            #type_name,
            VARIANTS,
            __Visitor {
                marker: _serde::#private::PhantomData::<#this_type #ty_generics>,
                lifetime: _serde::#private::PhantomData,
            },

Review comment (suggestion):
This codepath for the zero variant case is here in order for the generated code to compile with rust older than 1.82. After this PR it would not compile:

```console
error[E0004]: non-exhaustive patterns: `Ok(_)` not covered
 --> src/main.rs:1:10
  |
1 | #[derive(serde::Deserialize)] pub enum Void {}
  |          ^^^^^^^^^^^^^^^^^^ pattern `Ok(_)` not covered
  |
note: `Result<(__Field, <__A as EnumAccess<'_>>::Variant), <__A as EnumAccess<'_>>::Error>` defined here
 --> /rustc/eeb90cda1969383f56a2637cbd3037bdf598841c/library/core/src/result.rs:527:1
 ::: /rustc/eeb90cda1969383f56a2637cbd3037bdf598841c/library/core/src/result.rs:531:5
  |
  = note: not covered
  = note: the matched value is of type `Result<(__Field, <__A as EnumAccess<'_>>::Variant), <__A as EnumAccess<'_>>::Error>`
  = note: this error originates in the derive macro `serde::Deserialize` (in Nightly builds, run with -Z macro-backtrace for more info)
```

Serde_derive presently aims to support rust 1.61. We can probably raise that but I am not sure if 1.82 is too recent.

Code after:
        .filter(|&(_, variant)| !variant.attrs.skip_deserializing())
        .map(|(i, variant)| {
            let variant_name = field_i(i);

            let block = Match(deserialize_externally_tagged_variant(
                params, variant, cattrs,
            ));

            quote! {
                _serde::#private::Ok((__Field::#variant_name, __variant)) => #block
            }
        });

    let all_skipped = variants
        .iter()
        .all(|variant| variant.attrs.skip_deserializing());
    let match_variant = if all_skipped {
        // This is an empty enum like `enum Impossible {}` or an enum in which
        // all variants have `#[serde(skip_deserializing)]`.
        quote! {
            // FIXME: Once feature(exhaustive_patterns) is stable:
            // let _serde::#private::Err(__err) = _serde::de::EnumAccess::variant::<__Field>(__data);
            // _serde::#private::Err(__err)
            _serde::#private::Result::map(
                _serde::de::EnumAccess::variant::<__Field>(__data),
                |(__impossible, _)| match __impossible {})
        }
    } else {
        quote! {
            match _serde::de::EnumAccess::variant(__data) {
                #(#variant_arms)*
                _serde::#private::Err(__err) => _serde::#private::Err(__err),
            }
        }
    };

    quote_block! {
        #variant_visitor

        #[doc(hidden)]
        struct __Visitor #de_impl_generics #where_clause {
            marker: _serde::#private::PhantomData<#this_type #ty_generics>,
            lifetime: _serde::#private::PhantomData<&#delife ()>,
        }

        #[automatically_derived]
        impl #de_impl_generics _serde::de::Visitor<#delife> for __Visitor #de_ty_generics #where_clause {
            type Value = #this_type #ty_generics;

            fn expecting(&self, __formatter: &mut _serde::#private::Formatter) -> _serde::#private::fmt::Result {
                _serde::#private::Formatter::write_str(__formatter, #expecting)