Snap for 8564071 from 6e1d8718fc5e3dbc97a6b030204ef46f4e0289dd to mainline-sdkext-release

Change-Id: I7e9080e9d496a99cdc44c20c9f16c06b84cb6696
diff --git a/.cargo_vcs_info.json b/.cargo_vcs_info.json
index 71f38ef..7239a8b 100644
--- a/.cargo_vcs_info.json
+++ b/.cargo_vcs_info.json
@@ -1,5 +1,6 @@
 {
   "git": {
-    "sha1": "3d6c4149b177e9cadfb948ebc6d1e55b33861792"
-  }
-}
+    "sha1": "02bd79a0bada78dd88d050f6478806f001f41fb0"
+  },
+  "path_in_vcs": "serde_derive"
+}
\ No newline at end of file
diff --git a/Android.bp b/Android.bp
index 89739c0..d7a8421 100644
--- a/Android.bp
+++ b/Android.bp
@@ -1,4 +1,5 @@
-// This file is generated by cargo2android.py --run --device --dependencies.
+// This file is generated by cargo2android.py --config cargo2android.json.
+// Do not modify this file as changes will be overridden on upgrade.
 
 package {
     default_applicable_licenses: ["external_rust_crates_serde_derive_license"],
@@ -39,11 +40,14 @@
 rust_proc_macro {
     name: "libserde_derive",
     crate_name: "serde_derive",
+    cargo_env_compat: true,
+    cargo_pkg_version: "1.0.136",
     srcs: ["src/lib.rs"],
     edition: "2015",
     features: ["default"],
-    flags: [
-        "--cfg underscore_consts",
+    cfgs: [
+        "ptr_addr_of",
+        "underscore_consts",
     ],
     rustlibs: [
         "libproc_macro2",
@@ -51,9 +55,3 @@
         "libsyn",
     ],
 }
-
-// dependent_library ["feature_list"]
-//   proc-macro2-1.0.24 "default,proc-macro"
-//   quote-1.0.8 "default,proc-macro"
-//   syn-1.0.60 "clone-impls,default,derive,parsing,printing,proc-macro,quote"
-//   unicode-xid-0.2.1 "default"
diff --git a/Cargo.toml b/Cargo.toml
index 389d48c..6fac8e3 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -3,16 +3,16 @@
 # When uploading crates to the registry Cargo will automatically
 # "normalize" Cargo.toml files for maximal compatibility
 # with all versions of Cargo and also rewrite `path` dependencies
-# to registry (e.g., crates.io) dependencies
+# to registry (e.g., crates.io) dependencies.
 #
-# If you believe there's an error in this file please file an
-# issue against the rust-lang/cargo repository. If you're
-# editing this file be aware that the upstream Cargo.toml
-# will likely look very different (and much more reasonable)
+# If you are reading this file be aware that the original Cargo.toml
+# will likely look very different (and much more reasonable).
+# See Cargo.toml.orig for the original contents.
 
 [package]
+rust-version = "1.31"
 name = "serde_derive"
-version = "1.0.123"
+version = "1.0.136"
 authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>", "David Tolnay <dtolnay@gmail.com>"]
 include = ["build.rs", "src/**/*.rs", "crates-io.md", "README.md", "LICENSE-APACHE", "LICENSE-MIT"]
 description = "Macros 1.1 implementation of #[derive(Serialize, Deserialize)]"
diff --git a/Cargo.toml.orig b/Cargo.toml.orig
index 24e2f6b..47fda7f 100644
--- a/Cargo.toml.orig
+++ b/Cargo.toml.orig
@@ -1,7 +1,8 @@
 [package]
 name = "serde_derive"
-version = "1.0.123" # remember to update html_root_url
+version = "1.0.136" # remember to update html_root_url
 authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>", "David Tolnay <dtolnay@gmail.com>"]
+rust-version = "1.31"
 license = "MIT OR Apache-2.0"
 description = "Macros 1.1 implementation of #[derive(Serialize, Deserialize)]"
 homepage = "https://serde.rs"
diff --git a/METADATA b/METADATA
index aea0a1a..5954db1 100644
--- a/METADATA
+++ b/METADATA
@@ -7,13 +7,13 @@
   }
   url {
     type: ARCHIVE
-    value: "https://static.crates.io/crates/serde_derive/serde_derive-1.0.123.crate"
+    value: "https://static.crates.io/crates/serde_derive/serde_derive-1.0.136.crate"
   }
-  version: "1.0.123"
+  version: "1.0.136"
   license_type: NOTICE
   last_upgrade_date {
-    year: 2021
-    month: 2
-    day: 9
+    year: 2022
+    month: 3
+    day: 1
   }
 }
diff --git a/README.md b/README.md
index 14b0098..79409a3 100644
--- a/README.md
+++ b/README.md
@@ -77,17 +77,20 @@
 
 Serde is one of the most widely used Rust libraries so any place that Rustaceans
 congregate will be able to help you out. For chat, consider trying the
-[#general] or [#beginners] channels of the unofficial community Discord, the
-[#rust-usage] channel of the official Rust Project Discord, or the
-[#general][zulip] stream in Zulip. For asynchronous, consider the [\[rust\] tag
-on StackOverflow][stackoverflow], the [/r/rust] subreddit which has a pinned
-weekly easy questions post, or the Rust [Discourse forum][discourse]. It's
-acceptable to file a support issue in this repo but they tend not to get as many
-eyes as any of the above and may get closed without a response after some time.
+[#rust-questions] or [#rust-beginners] channels of the unofficial community
+Discord (invite: <https://discord.gg/rust-lang-community>), the [#rust-usage] or
+[#beginners] channels of the official Rust Project Discord (invite:
+<https://discord.gg/rust-lang>), or the [#general][zulip] stream in Zulip. For
+asynchronous, consider the [\[rust\] tag on StackOverflow][stackoverflow], the
+[/r/rust] subreddit which has a pinned weekly easy questions post, or the Rust
+[Discourse forum][discourse]. It's acceptable to file a support issue in this
+repo but they tend not to get as many eyes as any of the above and may get
+closed without a response after some time.
 
-[#general]: https://discord.com/channels/273534239310479360/274215136414400513
-[#beginners]: https://discord.com/channels/273534239310479360/273541522815713281
+[#rust-questions]: https://discord.com/channels/273534239310479360/274215136414400513
+[#rust-beginners]: https://discord.com/channels/273534239310479360/273541522815713281
 [#rust-usage]: https://discord.com/channels/442252698964721669/443150878111694848
+[#beginners]: https://discord.com/channels/442252698964721669/448238009733742612
 [zulip]: https://rust-lang.zulipchat.com/#narrow/stream/122651-general
 [stackoverflow]: https://stackoverflow.com/questions/tagged/rust
 [/r/rust]: https://www.reddit.com/r/rust
diff --git a/TEST_MAPPING b/TEST_MAPPING
index f4547bb..b424c9c 100644
--- a/TEST_MAPPING
+++ b/TEST_MAPPING
@@ -1,14 +1,117 @@
 // Generated by update_crate_tests.py for tests that depend on this crate.
 {
+  "imports": [
+    {
+      "path": "external/rust/crates/base64"
+    },
+    {
+      "path": "external/rust/crates/bitflags"
+    },
+    {
+      "path": "external/rust/crates/bytes"
+    },
+    {
+      "path": "external/rust/crates/either"
+    },
+    {
+      "path": "external/rust/crates/rand_chacha"
+    },
+    {
+      "path": "external/rust/crates/serde"
+    },
+    {
+      "path": "external/rust/crates/serde-xml-rs"
+    },
+    {
+      "path": "external/rust/crates/serde_cbor"
+    },
+    {
+      "path": "external/rust/crates/slab"
+    },
+    {
+      "path": "external/rust/crates/tinytemplate"
+    },
+    {
+      "path": "external/rust/crates/tinyvec"
+    },
+    {
+      "path": "external/rust/crates/unicode-bidi"
+    },
+    {
+      "path": "external/rust/crates/unicode-xid"
+    },
+    {
+      "path": "external/rust/crates/url"
+    }
+  ],
   "presubmit": [
     {
-      "name": "url_device_test_src_lib"
+      "name": "ZipFuseTest"
     },
     {
-      "name": "unicode-bidi_device_test_src_lib"
+      "name": "apkdmverity.test"
     },
     {
-      "name": "serde_test_device_test_src_lib"
+      "name": "authfs_device_test_src_lib"
+    },
+    {
+      "name": "diced_test"
+    },
+    {
+      "name": "diced_vendor_test"
+    },
+    {
+      "name": "keystore2_test"
+    },
+    {
+      "name": "keystore2_test_utils_test"
+    },
+    {
+      "name": "legacykeystore_test"
+    },
+    {
+      "name": "libcert_request_validator_tests"
+    },
+    {
+      "name": "microdroid_manager_test"
+    },
+    {
+      "name": "virtualizationservice_device_test"
+    }
+  ],
+  "presubmit-rust": [
+    {
+      "name": "ZipFuseTest"
+    },
+    {
+      "name": "apkdmverity.test"
+    },
+    {
+      "name": "authfs_device_test_src_lib"
+    },
+    {
+      "name": "diced_test"
+    },
+    {
+      "name": "diced_vendor_test"
+    },
+    {
+      "name": "keystore2_test"
+    },
+    {
+      "name": "keystore2_test_utils_test"
+    },
+    {
+      "name": "legacykeystore_test"
+    },
+    {
+      "name": "libcert_request_validator_tests"
+    },
+    {
+      "name": "microdroid_manager_test"
+    },
+    {
+      "name": "virtualizationservice_device_test"
     }
   ]
 }
diff --git a/build.rs b/build.rs
index 6e1b7b6..d0c827a 100644
--- a/build.rs
+++ b/build.rs
@@ -16,6 +16,12 @@
     if minor >= 37 {
         println!("cargo:rustc-cfg=underscore_consts");
     }
+
+    // The ptr::addr_of! macro stabilized in Rust 1.51:
+    // https://blog.rust-lang.org/2021/03/25/Rust-1.51.0.html#stabilized-apis
+    if minor >= 51 {
+        println!("cargo:rustc-cfg=ptr_addr_of");
+    }
 }
 
 fn rustc_minor_version() -> Option<u32> {
diff --git a/cargo2android.json b/cargo2android.json
new file mode 100644
index 0000000..bf78496
--- /dev/null
+++ b/cargo2android.json
@@ -0,0 +1,4 @@
+{
+  "device": true,
+  "run": true
+}
\ No newline at end of file
diff --git a/crates-io.md b/crates-io.md
index 0775761..b57bc5f 100644
--- a/crates-io.md
+++ b/crates-io.md
@@ -45,17 +45,20 @@
 
 Serde is one of the most widely used Rust libraries so any place that Rustaceans
 congregate will be able to help you out. For chat, consider trying the
-[#general] or [#beginners] channels of the unofficial community Discord, the
-[#rust-usage] channel of the official Rust Project Discord, or the
-[#general][zulip] stream in Zulip. For asynchronous, consider the [\[rust\] tag
-on StackOverflow][stackoverflow], the [/r/rust] subreddit which has a pinned
-weekly easy questions post, or the Rust [Discourse forum][discourse]. It's
-acceptable to file a support issue in this repo but they tend not to get as many
-eyes as any of the above and may get closed without a response after some time.
+[#rust-questions] or [#rust-beginners] channels of the unofficial community
+Discord (invite: <https://discord.gg/rust-lang-community>, the [#rust-usage] or
+[#beginners] channels of the official Rust Project Discord (invite:
+<https://discord.gg/rust-lang>), or the [#general][zulip] stream in Zulip. For
+asynchronous, consider the [\[rust\] tag on StackOverflow][stackoverflow], the
+[/r/rust] subreddit which has a pinned weekly easy questions post, or the Rust
+[Discourse forum][discourse]. It's acceptable to file a support issue in this
+repo but they tend not to get as many eyes as any of the above and may get
+closed without a response after some time.
 
-[#general]: https://discord.com/channels/273534239310479360/274215136414400513
-[#beginners]: https://discord.com/channels/273534239310479360/273541522815713281
+[#rust-questions]: https://discord.com/channels/273534239310479360/274215136414400513
+[#rust-beginners]: https://discord.com/channels/273534239310479360/273541522815713281
 [#rust-usage]: https://discord.com/channels/442252698964721669/443150878111694848
+[#beginners]: https://discord.com/channels/442252698964721669/448238009733742612
 [zulip]: https://rust-lang.zulipchat.com/#narrow/stream/122651-general
 [stackoverflow]: https://stackoverflow.com/questions/tagged/rust
 [/r/rust]: https://www.reddit.com/r/rust
diff --git a/src/bound.rs b/src/bound.rs
index 0949dfc..abca467 100644
--- a/src/bound.rs
+++ b/src/bound.rs
@@ -49,8 +49,8 @@
     let predicates = cont
         .data
         .all_fields()
-        .flat_map(|field| from_field(&field.attrs))
-        .flat_map(|predicates| predicates.to_vec());
+        .filter_map(|field| from_field(&field.attrs))
+        .flat_map(<[syn::WherePredicate]>::to_vec);
 
     let mut generics = generics.clone();
     generics.make_where_clause().predicates.extend(predicates);
@@ -71,8 +71,8 @@
 
     let predicates = variants
         .iter()
-        .flat_map(|variant| from_variant(&variant.attrs))
-        .flat_map(|predicates| predicates.to_vec());
+        .filter_map(|variant| from_variant(&variant.attrs))
+        .flat_map(<[syn::WherePredicate]>::to_vec);
 
     let mut generics = generics.clone();
     generics.make_where_clause().predicates.extend(predicates);
diff --git a/src/de.rs b/src/de.rs
index 3daa9d1..ff7bc42 100644
--- a/src/de.rs
+++ b/src/de.rs
@@ -36,7 +36,7 @@
 
     let impl_block = if let Some(remote) = cont.attrs.remote() {
         let vis = &input.vis;
-        let used = pretend::pretend_used(&cont);
+        let used = pretend::pretend_used(&cont, params.is_packed);
         quote! {
             impl #de_impl_generics #ident #ty_generics #where_clause {
                 #vis fn deserialize<__D>(__deserializer: __D) -> #serde::__private::Result<#remote #ty_generics, __D::Error>
@@ -125,6 +125,9 @@
     /// At least one field has a serde(getter) attribute, implying that the
     /// remote type has a private field.
     has_getter: bool,
+
+    /// Type has a repr(packed) attribute.
+    is_packed: bool,
 }
 
 impl Parameters {
@@ -137,6 +140,7 @@
         let borrowed = borrowed_lifetimes(cont);
         let generics = build_generics(cont, &borrowed);
         let has_getter = cont.data.has_getter();
+        let is_packed = cont.attrs.is_packed();
 
         Parameters {
             local,
@@ -144,6 +148,7 @@
             generics,
             borrowed,
             has_getter,
+            is_packed,
         }
     }
 
@@ -475,7 +480,7 @@
     };
 
     let visit_seq = Stmts(deserialize_seq(
-        &type_path, params, fields, false, cattrs, &expecting,
+        &type_path, params, fields, false, cattrs, expecting,
     ));
 
     let visitor_expr = quote! {
@@ -561,7 +566,7 @@
         None
     };
 
-    let visit_seq = Stmts(deserialize_seq_in_place(params, fields, cattrs, &expecting));
+    let visit_seq = Stmts(deserialize_seq_in_place(params, fields, cattrs, expecting));
 
     let visitor_expr = quote! {
         __Visitor {
@@ -922,7 +927,7 @@
     let expecting = cattrs.expecting().unwrap_or(&expecting);
 
     let visit_seq = Stmts(deserialize_seq(
-        &type_path, params, fields, true, cattrs, &expecting,
+        &type_path, params, fields, true, cattrs, expecting,
     ));
 
     let (field_visitor, fields_stmt, visit_map) = if cattrs.has_flatten() {
@@ -1063,7 +1068,7 @@
     };
     let expecting = cattrs.expecting().unwrap_or(&expecting);
 
-    let visit_seq = Stmts(deserialize_seq_in_place(params, fields, cattrs, &expecting));
+    let visit_seq = Stmts(deserialize_seq_in_place(params, fields, cattrs, expecting));
 
     let (field_visitor, fields_stmt, visit_map) =
         deserialize_struct_as_struct_in_place_visitor(params, fields, cattrs);
@@ -1453,7 +1458,7 @@
             while let _serde::__private::Some(__k) = #next_key {
                 match __k {
                     _serde::__private::de::TagContentOtherField::Other => {
-                        try!(_serde::de::MapAccess::next_value::<_serde::de::IgnoredAny>(&mut __map));
+                        let _ = try!(_serde::de::MapAccess::next_value::<_serde::de::IgnoredAny>(&mut __map));
                         continue;
                     },
                     _serde::__private::de::TagContentOtherField::Tag => {
@@ -1728,6 +1733,8 @@
     }
 }
 
+// Generates significant part of the visit_seq and visit_map bodies of visitors
+// for the variants of internally tagged enum.
 fn deserialize_internally_tagged_variant(
     params: &Parameters,
     variant: &Variant,
@@ -1779,11 +1786,9 @@
     deserializer: TokenStream,
 ) -> Fragment {
     if let Some(path) = variant.attrs.deserialize_with() {
-        let (wrapper, wrapper_ty, unwrap_fn) = wrap_deserialize_variant_with(params, variant, path);
+        let unwrap_fn = unwrap_to_variant_closure(params, variant, false);
         return quote_block! {
-            #wrapper
-            _serde::__private::Result::map(
-                <#wrapper_ty as _serde::Deserialize>::deserialize(#deserializer), #unwrap_fn)
+            _serde::__private::Result::map(#path(#deserializer), #unwrap_fn)
         };
     }
 
@@ -2087,7 +2092,7 @@
 ) -> Fragment {
     let mut flat_fields = Vec::new();
     for (_, ident, aliases) in fields {
-        flat_fields.extend(aliases.iter().map(|alias| (alias, ident)))
+        flat_fields.extend(aliases.iter().map(|alias| (alias, ident)));
     }
 
     let field_strs: &Vec<_> = &flat_fields.iter().map(|(name, _)| name).collect();
@@ -2285,7 +2290,7 @@
     };
 
     let visit_borrowed = if fallthrough_borrowed.is_some() || collect_other_fields {
-        let fallthrough_borrowed_arm = fallthrough_borrowed.as_ref().unwrap_or(&fallthrough_arm);
+        let fallthrough_borrowed_arm = fallthrough_borrowed.as_ref().unwrap_or(fallthrough_arm);
         Some(quote! {
             fn visit_borrowed_str<__E>(self, __value: &'de str) -> _serde::__private::Result<Self::Value, __E>
             where
@@ -2883,44 +2888,61 @@
     variant: &Variant,
     deserialize_with: &syn::ExprPath,
 ) -> (TokenStream, TokenStream, TokenStream) {
-    let this = &params.this;
-    let variant_ident = &variant.ident;
-
     let field_tys = variant.fields.iter().map(|field| field.ty);
     let (wrapper, wrapper_ty) =
         wrap_deserialize_with(params, &quote!((#(#field_tys),*)), deserialize_with);
 
+    let unwrap_fn = unwrap_to_variant_closure(params, variant, true);
+
+    (wrapper, wrapper_ty, unwrap_fn)
+}
+
+// Generates closure that converts single input parameter to the final value.
+fn unwrap_to_variant_closure(
+    params: &Parameters,
+    variant: &Variant,
+    with_wrapper: bool,
+) -> TokenStream {
+    let this = &params.this;
+    let variant_ident = &variant.ident;
+
+    let (arg, wrapper) = if with_wrapper {
+        (quote! { __wrap }, quote! { __wrap.value })
+    } else {
+        let field_tys = variant.fields.iter().map(|field| field.ty);
+        (quote! { __wrap: (#(#field_tys),*) }, quote! { __wrap })
+    };
+
     let field_access = (0..variant.fields.len()).map(|n| {
         Member::Unnamed(Index {
             index: n as u32,
             span: Span::call_site(),
         })
     });
-    let unwrap_fn = match variant.style {
+
+    match variant.style {
         Style::Struct if variant.fields.len() == 1 => {
             let member = &variant.fields[0].member;
             quote! {
-                |__wrap| #this::#variant_ident { #member: __wrap.value }
+                |#arg| #this::#variant_ident { #member: #wrapper }
             }
         }
         Style::Struct => {
             let members = variant.fields.iter().map(|field| &field.member);
             quote! {
-                |__wrap| #this::#variant_ident { #(#members: __wrap.value.#field_access),* }
+                |#arg| #this::#variant_ident { #(#members: #wrapper.#field_access),* }
             }
         }
         Style::Tuple => quote! {
-            |__wrap| #this::#variant_ident(#(__wrap.value.#field_access),*)
+            |#arg| #this::#variant_ident(#(#wrapper.#field_access),*)
         },
         Style::Newtype => quote! {
-            |__wrap| #this::#variant_ident(__wrap.value)
+            |#arg| #this::#variant_ident(#wrapper)
         },
         Style::Unit => quote! {
-            |__wrap| #this::#variant_ident
+            |#arg| #this::#variant_ident
         },
-    };
-
-    (wrapper, wrapper_ty, unwrap_fn)
+    }
 }
 
 fn expr_is_missing(field: &Field, cattrs: &attr::Container) -> Fragment {
diff --git a/src/dummy.rs b/src/dummy.rs
index 9a4e5f0..29de260 100644
--- a/src/dummy.rs
+++ b/src/dummy.rs
@@ -23,7 +23,7 @@
             use #path as _serde;
         },
         None => quote! {
-            #[allow(rust_2018_idioms, clippy::useless_attribute)]
+            #[allow(unused_extern_crates, clippy::useless_attribute)]
             extern crate serde as _serde;
         },
     };
diff --git a/src/internals/ast.rs b/src/internals/ast.rs
index 1afdaee..2a6950b 100644
--- a/src/internals/ast.rs
+++ b/src/internals/ast.rs
@@ -23,7 +23,7 @@
 
 /// The fields of a struct or enum.
 ///
-/// Analagous to `syn::Data`.
+/// Analogous to `syn::Data`.
 pub enum Data<'a> {
     Enum(Vec<Variant<'a>>),
     Struct(Style, Vec<Field<'a>>),
diff --git a/src/internals/attr.rs b/src/internals/attr.rs
index dcc4bf8..13f5525 100644
--- a/src/internals/attr.rs
+++ b/src/internals/attr.rs
@@ -556,7 +556,7 @@
                 // Parse `#[serde(crate = "foo")]`
                 Meta(NameValue(m)) if m.path == CRATE => {
                     if let Ok(path) = parse_lit_into_path(cx, CRATE, &m.lit) {
-                        serde_path.set(&m.path, path)
+                        serde_path.set(&m.path, path);
                     }
                 }
 
@@ -1609,7 +1609,7 @@
 fn parse_lit_into_path(cx: &Ctxt, attr_name: Symbol, lit: &syn::Lit) -> Result<syn::Path, ()> {
     let string = get_lit_str(cx, attr_name, lit)?;
     parse_lit_str(string).map_err(|_| {
-        cx.error_spanned_by(lit, format!("failed to parse path: {:?}", string.value()))
+        cx.error_spanned_by(lit, format!("failed to parse path: {:?}", string.value()));
     })
 }
 
@@ -1620,7 +1620,7 @@
 ) -> Result<syn::ExprPath, ()> {
     let string = get_lit_str(cx, attr_name, lit)?;
     parse_lit_str(string).map_err(|_| {
-        cx.error_spanned_by(lit, format!("failed to parse path: {:?}", string.value()))
+        cx.error_spanned_by(lit, format!("failed to parse path: {:?}", string.value()));
     })
 }
 
@@ -1649,7 +1649,7 @@
         cx.error_spanned_by(
             lit,
             format!("failed to parse type: {} = {:?}", attr_name, string.value()),
-        )
+        );
     })
 }
 
diff --git a/src/internals/check.rs b/src/internals/check.rs
index 30ede1c..0e2484a 100644
--- a/src/internals/check.rs
+++ b/src/internals/check.rs
@@ -260,7 +260,7 @@
         cx.error_spanned_by(
             cont.original,
             format!("variant field name `{}` conflicts with internal tag", tag),
-        )
+        );
     };
 
     for variant in variants {
@@ -396,7 +396,7 @@
 }
 
 fn allow_transparent(field: &Field, derive: Derive) -> bool {
-    if let Type::Path(ty) = ungroup(&field.ty) {
+    if let Type::Path(ty) = ungroup(field.ty) {
         if let Some(seg) = ty.path.segments.last() {
             if seg.ident == "PhantomData" {
                 return false;
diff --git a/src/lib.rs b/src/lib.rs
index f4a93ae..8079bb6 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -13,13 +13,18 @@
 //!
 //! [https://serde.rs/derive.html]: https://serde.rs/derive.html
 
-#![doc(html_root_url = "https://docs.rs/serde_derive/1.0.123")]
+#![doc(html_root_url = "https://docs.rs/serde_derive/1.0.136")]
 #![allow(unknown_lints, bare_trait_objects)]
-#![deny(clippy::all, clippy::pedantic)]
 // Ignored clippy lints
 #![allow(
+    // clippy false positive: https://github.com/rust-lang/rust-clippy/issues/7054
+    clippy::branches_sharing_code,
     clippy::cognitive_complexity,
+    // clippy bug: https://github.com/rust-lang/rust-clippy/issues/7575
+    clippy::collapsible_match,
     clippy::enum_variant_names,
+    // clippy bug: https://github.com/rust-lang/rust-clippy/issues/6797
+    clippy::manual_map,
     clippy::match_like_matches_macro,
     clippy::needless_pass_by_value,
     clippy::too_many_arguments,
@@ -35,11 +40,14 @@
     clippy::checked_conversions,
     clippy::doc_markdown,
     clippy::enum_glob_use,
-    clippy::filter_map,
     clippy::indexing_slicing,
     clippy::items_after_statements,
+    clippy::let_underscore_drop,
+    clippy::manual_assert,
     clippy::map_err_ignore,
     clippy::match_same_arms,
+    // clippy bug: https://github.com/rust-lang/rust-clippy/issues/6984
+    clippy::match_wildcard_for_single_variants,
     clippy::module_name_repetitions,
     clippy::must_use_candidate,
     clippy::option_if_let_else,
diff --git a/src/pretend.rs b/src/pretend.rs
index 955ce3d..3af6a66 100644
--- a/src/pretend.rs
+++ b/src/pretend.rs
@@ -1,7 +1,7 @@
-use proc_macro2::{Span, TokenStream};
-use syn::Ident;
+use proc_macro2::TokenStream;
+use quote::format_ident;
 
-use internals::ast::{Container, Data, Field, Style};
+use internals::ast::{Container, Data, Field, Style, Variant};
 
 // Suppress dead_code warnings that would otherwise appear when using a remote
 // derive. Other than this pretend code, a struct annotated with remote derive
@@ -20,8 +20,8 @@
 //     8 | enum EnumDef { V }
 //       |                ^
 //
-pub fn pretend_used(cont: &Container) -> TokenStream {
-    let pretend_fields = pretend_fields_used(cont);
+pub fn pretend_used(cont: &Container, is_packed: bool) -> TokenStream {
+    let pretend_fields = pretend_fields_used(cont, is_packed);
     let pretend_variants = pretend_variants_used(cont);
 
     quote! {
@@ -32,49 +32,117 @@
 
 // For structs with named fields, expands to:
 //
+//     match None::<&T> {
+//         Some(T { a: __v0, b: __v1 }) => {}
+//         _ => {}
+//     }
+//
+// For packed structs on sufficiently new rustc, expands to:
+//
+//     match None::<&T> {
+//         Some(__v @ T { a: _, b: _ }) => {
+//             let _ = addr_of!(__v.a);
+//             let _ = addr_of!(__v.b);
+//         }
+//         _ => {}
+//     }
+//
+// For packed structs on older rustc, we assume Sized and !Drop, and expand to:
+//
 //     match None::<T> {
-//         Some(T { a: ref __v0, b: ref __v1 }) => {}
+//         Some(T { a: __v0, b: __v1 }) => {}
 //         _ => {}
 //     }
 //
 // For enums, expands to the following but only including struct variants:
 //
-//     match None::<T> {
-//         Some(T::A { a: ref __v0 }) => {}
-//         Some(T::B { b: ref __v0 }) => {}
+//     match None::<&T> {
+//         Some(T::A { a: __v0 }) => {}
+//         Some(T::B { b: __v0 }) => {}
 //         _ => {}
 //     }
 //
-// The `ref` is important in case the user has written a Drop impl on their
-// type. Rust does not allow destructuring a struct or enum that has a Drop
-// impl.
-fn pretend_fields_used(cont: &Container) -> TokenStream {
+fn pretend_fields_used(cont: &Container, is_packed: bool) -> TokenStream {
+    match &cont.data {
+        Data::Enum(variants) => pretend_fields_used_enum(cont, variants),
+        Data::Struct(Style::Struct, fields) => {
+            if is_packed {
+                pretend_fields_used_struct_packed(cont, fields)
+            } else {
+                pretend_fields_used_struct(cont, fields)
+            }
+        }
+        Data::Struct(_, _) => quote!(),
+    }
+}
+
+fn pretend_fields_used_struct(cont: &Container, fields: &[Field]) -> TokenStream {
     let type_ident = &cont.ident;
     let (_, ty_generics, _) = cont.generics.split_for_impl();
 
-    let patterns = match &cont.data {
-        Data::Enum(variants) => variants
-            .iter()
-            .filter_map(|variant| match variant.style {
-                Style::Struct => {
-                    let variant_ident = &variant.ident;
-                    let pat = struct_pattern(&variant.fields);
-                    Some(quote!(#type_ident::#variant_ident #pat))
-                }
-                _ => None,
-            })
-            .collect::<Vec<_>>(),
-        Data::Struct(Style::Struct, fields) => {
-            let pat = struct_pattern(fields);
-            vec![quote!(#type_ident #pat)]
-        }
-        Data::Struct(_, _) => {
-            return quote!();
-        }
-    };
+    let members = fields.iter().map(|field| &field.member);
+    let placeholders = (0usize..).map(|i| format_ident!("__v{}", i));
 
     quote! {
-        match _serde::__private::None::<#type_ident #ty_generics> {
+        match _serde::__private::None::<&#type_ident #ty_generics> {
+            _serde::__private::Some(#type_ident { #(#members: #placeholders),* }) => {}
+            _ => {}
+        }
+    }
+}
+
+fn pretend_fields_used_struct_packed(cont: &Container, fields: &[Field]) -> TokenStream {
+    let type_ident = &cont.ident;
+    let (_, ty_generics, _) = cont.generics.split_for_impl();
+
+    let members = fields.iter().map(|field| &field.member).collect::<Vec<_>>();
+
+    #[cfg(ptr_addr_of)]
+    {
+        quote! {
+            match _serde::__private::None::<&#type_ident #ty_generics> {
+                _serde::__private::Some(__v @ #type_ident { #(#members: _),* }) => {
+                    #(
+                        let _ = _serde::__private::ptr::addr_of!(__v.#members);
+                    )*
+                }
+                _ => {}
+            }
+        }
+    }
+
+    #[cfg(not(ptr_addr_of))]
+    {
+        let placeholders = (0usize..).map(|i| format_ident!("__v{}", i));
+
+        quote! {
+            match _serde::__private::None::<#type_ident #ty_generics> {
+                _serde::__private::Some(#type_ident { #(#members: #placeholders),* }) => {}
+                _ => {}
+            }
+        }
+    }
+}
+
+fn pretend_fields_used_enum(cont: &Container, variants: &[Variant]) -> TokenStream {
+    let type_ident = &cont.ident;
+    let (_, ty_generics, _) = cont.generics.split_for_impl();
+
+    let patterns = variants
+        .iter()
+        .filter_map(|variant| match variant.style {
+            Style::Struct => {
+                let variant_ident = &variant.ident;
+                let members = variant.fields.iter().map(|field| &field.member);
+                let placeholders = (0usize..).map(|i| format_ident!("__v{}", i));
+                Some(quote!(#type_ident::#variant_ident { #(#members: #placeholders),* }))
+            }
+            _ => None,
+        })
+        .collect::<Vec<_>>();
+
+    quote! {
+        match _serde::__private::None::<&#type_ident #ty_generics> {
             #(
                 _serde::__private::Some(#patterns) => {}
             )*
@@ -107,7 +175,7 @@
     let cases = variants.iter().map(|variant| {
         let variant_ident = &variant.ident;
         let placeholders = &(0..variant.fields.len())
-            .map(|i| Ident::new(&format!("__v{}", i), Span::call_site()))
+            .map(|i| format_ident!("__v{}", i))
             .collect::<Vec<_>>();
 
         let pat = match variant.style {
@@ -131,10 +199,3 @@
 
     quote!(#(#cases)*)
 }
-
-fn struct_pattern(fields: &[Field]) -> TokenStream {
-    let members = fields.iter().map(|field| &field.member);
-    let placeholders =
-        (0..fields.len()).map(|i| Ident::new(&format!("__v{}", i), Span::call_site()));
-    quote!({ #(#members: ref #placeholders),* })
-}
diff --git a/src/ser.rs b/src/ser.rs
index c663c3b..529a20d 100644
--- a/src/ser.rs
+++ b/src/ser.rs
@@ -30,7 +30,7 @@
 
     let impl_block = if let Some(remote) = cont.attrs.remote() {
         let vis = &input.vis;
-        let used = pretend::pretend_used(&cont);
+        let used = pretend::pretend_used(&cont, params.is_packed);
         quote! {
             impl #impl_generics #ident #ty_generics #where_clause {
                 #vis fn serialize<__S>(__self: &#remote #ty_generics, __serializer: __S) -> #serde::__private::Result<__S::Ok, __S::Error>
@@ -1099,7 +1099,7 @@
             let mut field_expr = if is_enum {
                 quote!(#member)
             } else {
-                get_member(params, field, &member)
+                get_member(params, field, member)
             };
 
             let key_expr = field.attrs.name().serialize_name();