Merge "Upgrade serde_derive to 1.0.150"
diff --git a/.cargo_vcs_info.json b/.cargo_vcs_info.json
index 7239a8b..ca41412 100644
--- a/.cargo_vcs_info.json
+++ b/.cargo_vcs_info.json
@@ -1,6 +1,6 @@
 {
   "git": {
-    "sha1": "02bd79a0bada78dd88d050f6478806f001f41fb0"
+    "sha1": "d493649f5299106b66dfb7a99d61b38d9599f972"
   },
   "path_in_vcs": "serde_derive"
 }
\ No newline at end of file
diff --git a/Android.bp b/Android.bp
index ab35b60..f54155d 100644
--- a/Android.bp
+++ b/Android.bp
@@ -41,14 +41,10 @@
     name: "libserde_derive",
     crate_name: "serde_derive",
     cargo_env_compat: true,
-    cargo_pkg_version: "1.0.136",
+    cargo_pkg_version: "1.0.150",
     srcs: ["src/lib.rs"],
     edition: "2015",
     features: ["default"],
-    cfgs: [
-        "ptr_addr_of",
-        "underscore_consts",
-    ],
     rustlibs: [
         "libproc_macro2",
         "libquote",
@@ -61,7 +57,7 @@
     name: "serde_derive_test_src_lib",
     crate_name: "serde_derive",
     cargo_env_compat: true,
-    cargo_pkg_version: "1.0.136",
+    cargo_pkg_version: "1.0.150",
     srcs: ["src/lib.rs"],
     test_suites: ["general-tests"],
     auto_gen_config: true,
@@ -70,10 +66,6 @@
     },
     edition: "2015",
     features: ["default"],
-    cfgs: [
-        "ptr_addr_of",
-        "underscore_consts",
-    ],
     rustlibs: [
         "libproc_macro2",
         "libquote",
diff --git a/Cargo.toml b/Cargo.toml
index 6fac8e3..e268bf7 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -12,22 +12,40 @@
 [package]
 rust-version = "1.31"
 name = "serde_derive"
-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"]
+version = "1.0.150"
+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)]"
 homepage = "https://serde.rs"
 documentation = "https://serde.rs/derive.html"
 readme = "crates-io.md"
-keywords = ["serde", "serialization", "no_std"]
+keywords = [
+    "serde",
+    "serialization",
+    "no_std",
+    "derive",
+]
+categories = ["no-std"]
 license = "MIT OR Apache-2.0"
 repository = "https://github.com/serde-rs/serde"
+
 [package.metadata.docs.rs]
 targets = ["x86_64-unknown-linux-gnu"]
 
 [lib]
 name = "serde_derive"
 proc-macro = true
+
 [dependencies.proc-macro2]
 version = "1.0"
 
@@ -35,7 +53,8 @@
 version = "1.0"
 
 [dependencies.syn]
-version = "1.0.60"
+version = "1.0.104"
+
 [dev-dependencies.serde]
 version = "1.0"
 
diff --git a/Cargo.toml.orig b/Cargo.toml.orig
index 47fda7f..b047f34 100644
--- a/Cargo.toml.orig
+++ b/Cargo.toml.orig
@@ -1,16 +1,17 @@
 [package]
 name = "serde_derive"
-version = "1.0.136" # remember to update html_root_url
+version = "1.0.150" # 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"
+categories = ["no-std"]
 description = "Macros 1.1 implementation of #[derive(Serialize, Deserialize)]"
-homepage = "https://serde.rs"
-repository = "https://github.com/serde-rs/serde"
 documentation = "https://serde.rs/derive.html"
-keywords = ["serde", "serialization", "no_std"]
-readme = "crates-io.md"
+homepage = "https://serde.rs"
 include = ["build.rs", "src/**/*.rs", "crates-io.md", "README.md", "LICENSE-APACHE", "LICENSE-MIT"]
+keywords = ["serde", "serialization", "no_std", "derive"]
+license = "MIT OR Apache-2.0"
+readme = "crates-io.md"
+repository = "https://github.com/serde-rs/serde"
+rust-version = "1.31"
 
 [features]
 default = []
@@ -23,7 +24,7 @@
 [dependencies]
 proc-macro2 = "1.0"
 quote = "1.0"
-syn = "1.0.60"
+syn = "1.0.104"
 
 [dev-dependencies]
 serde = { version = "1.0", path = "../serde" }
diff --git a/METADATA b/METADATA
index 5954db1..68bc83c 100644
--- a/METADATA
+++ b/METADATA
@@ -1,3 +1,7 @@
+# This project was upgraded with external_updater.
+# Usage: tools/external_updater/updater.sh update rust/crates/serde_derive
+# For more info, check https://cs.android.com/android/platform/superproject/+/master:tools/external_updater/README.md
+
 name: "serde_derive"
 description: "Macros 1.1 implementation of #[derive(Serialize, Deserialize)]"
 third_party {
@@ -7,13 +11,13 @@
   }
   url {
     type: ARCHIVE
-    value: "https://static.crates.io/crates/serde_derive/serde_derive-1.0.136.crate"
+    value: "https://static.crates.io/crates/serde_derive/serde_derive-1.0.150.crate"
   }
-  version: "1.0.136"
+  version: "1.0.150"
   license_type: NOTICE
   last_upgrade_date {
     year: 2022
-    month: 3
-    day: 1
+    month: 12
+    day: 12
   }
 }
diff --git a/build.rs b/build.rs
index d0c827a..2aece04 100644
--- a/build.rs
+++ b/build.rs
@@ -13,14 +13,14 @@
 
     // Underscore const names stabilized in Rust 1.37:
     // https://blog.rust-lang.org/2019/08/15/Rust-1.37.0.html#using-unnamed-const-items-for-macros
-    if minor >= 37 {
-        println!("cargo:rustc-cfg=underscore_consts");
+    if minor < 37 {
+        println!("cargo:rustc-cfg=no_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");
+    if minor < 51 {
+        println!("cargo:rustc-cfg=no_ptr_addr_of");
     }
 }
 
diff --git a/src/bound.rs b/src/bound.rs
index abca467..74c9506 100644
--- a/src/bound.rs
+++ b/src/bound.rs
@@ -184,9 +184,7 @@
 
                 syn::Type::Infer(_) | syn::Type::Never(_) | syn::Type::Verbatim(_) => {}
 
-                #[cfg(test)]
-                syn::Type::__TestExhaustive(_) => unimplemented!(),
-                #[cfg(not(test))]
+                #[cfg_attr(all(test, exhaustive), deny(non_exhaustive_omitted_patterns))]
                 _ => {}
             }
         }
diff --git a/src/de.rs b/src/de.rs
index ff7bc42..a703ada 100644
--- a/src/de.rs
+++ b/src/de.rs
@@ -10,6 +10,7 @@
 use internals::ast::{Container, Data, Field, Style, Variant};
 use internals::{attr, replace_receiver, ungroup, Ctxt, Derive};
 use pretend;
+use this;
 
 use std::collections::BTreeSet;
 use std::ptr;
@@ -111,9 +112,13 @@
     local: syn::Ident,
 
     /// Path to the type the impl is for. Either a single `Ident` for local
-    /// types or `some::remote::Ident` for remote types. Does not include
-    /// generic parameters.
-    this: syn::Path,
+    /// types (does not include generic parameters) or `some::remote::Path` for
+    /// remote types.
+    this_type: syn::Path,
+
+    /// Same as `this_type` but using `::<T>` for generic parameters for use in
+    /// expression position.
+    this_value: syn::Path,
 
     /// Generics including any explicit and inferred bounds for the impl.
     generics: syn::Generics,
@@ -133,10 +138,8 @@
 impl Parameters {
     fn new(cont: &Container) -> Self {
         let local = cont.ident.clone();
-        let this = match cont.attrs.remote() {
-            Some(remote) => remote.clone(),
-            None => cont.ident.clone().into(),
-        };
+        let this_type = this::this_type(cont);
+        let this_value = this::this_value(cont);
         let borrowed = borrowed_lifetimes(cont);
         let generics = build_generics(cont, &borrowed);
         let has_getter = cont.data.has_getter();
@@ -144,7 +147,8 @@
 
         Parameters {
             local,
-            this,
+            this_type,
+            this_value,
             generics,
             borrowed,
             has_getter,
@@ -155,7 +159,7 @@
     /// Type name to use in error messages and `&'static str` arguments to
     /// various Deserializer methods.
     fn type_name(&self) -> String {
-        self.this.segments.last().unwrap().ident.to_string()
+        self.this_type.segments.last().unwrap().ident.to_string()
     }
 }
 
@@ -358,7 +362,7 @@
         Data::Enum(_) => unreachable!(),
     };
 
-    let this = &params.this;
+    let this_value = &params.this_value;
     let transparent_field = fields.iter().find(|f| f.attrs.transparent()).unwrap();
 
     let path = match transparent_field.attrs.deserialize_with() {
@@ -386,7 +390,7 @@
     quote_block! {
         _serde::__private::Result::map(
             #path(__deserializer),
-            |__transparent| #this { #(#assign),* })
+            |__transparent| #this_value { #(#assign),* })
     }
 }
 
@@ -407,7 +411,8 @@
 }
 
 fn deserialize_unit_struct(params: &Parameters, cattrs: &attr::Container) -> Fragment {
-    let this = &params.this;
+    let this_type = &params.this_type;
+    let this_value = &params.this_value;
     let type_name = cattrs.name().deserialize_name();
 
     let expecting = format!("unit struct {}", params.type_name());
@@ -417,7 +422,7 @@
         struct __Visitor;
 
         impl<'de> _serde::de::Visitor<'de> for __Visitor {
-            type Value = #this;
+            type Value = #this_type;
 
             fn expecting(&self, __formatter: &mut _serde::__private::Formatter) -> _serde::__private::fmt::Result {
                 _serde::__private::Formatter::write_str(__formatter, #expecting)
@@ -428,7 +433,7 @@
             where
                 __E: _serde::de::Error,
             {
-                _serde::__private::Ok(#this)
+                _serde::__private::Ok(#this_value)
             }
         }
 
@@ -443,7 +448,8 @@
     cattrs: &attr::Container,
     deserializer: Option<TokenStream>,
 ) -> Fragment {
-    let this = &params.this;
+    let this_type = &params.this_type;
+    let this_value = &params.this_value;
     let (de_impl_generics, de_ty_generics, ty_generics, where_clause) =
         split_with_de_lifetime(params);
     let delife = params.borrowed.de_lifetime();
@@ -457,7 +463,7 @@
         let local = &params.local;
         quote!(#local)
     } else {
-        quote!(#this)
+        quote!(#this_value)
     };
 
     let is_enum = variant_ident.is_some();
@@ -485,7 +491,7 @@
 
     let visitor_expr = quote! {
         __Visitor {
-            marker: _serde::__private::PhantomData::<#this #ty_generics>,
+            marker: _serde::__private::PhantomData::<#this_type #ty_generics>,
             lifetime: _serde::__private::PhantomData,
         }
     };
@@ -510,12 +516,12 @@
 
     quote_block! {
         struct __Visitor #de_impl_generics #where_clause {
-            marker: _serde::__private::PhantomData<#this #ty_generics>,
+            marker: _serde::__private::PhantomData<#this_type #ty_generics>,
             lifetime: _serde::__private::PhantomData<&#delife ()>,
         }
 
         impl #de_impl_generics _serde::de::Visitor<#delife> for __Visitor #de_ty_generics #where_clause {
-            type Value = #this #ty_generics;
+            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)
@@ -544,7 +550,7 @@
     cattrs: &attr::Container,
     deserializer: Option<TokenStream>,
 ) -> Fragment {
-    let this = &params.this;
+    let this_type = &params.this_type;
     let (de_impl_generics, de_ty_generics, ty_generics, where_clause) =
         split_with_de_lifetime(params);
     let delife = params.borrowed.de_lifetime();
@@ -600,7 +606,7 @@
 
     quote_block! {
         struct __Visitor #in_place_impl_generics #where_clause {
-            place: &#place_life mut #this #ty_generics,
+            place: &#place_life mut #this_type #ty_generics,
             lifetime: _serde::__private::PhantomData<&#delife ()>,
         }
 
@@ -705,9 +711,10 @@
     };
 
     if params.has_getter {
-        let this = &params.this;
+        let this_type = &params.this_type;
+        let (_, ty_generics, _) = params.generics.split_for_impl();
         result = quote! {
-            _serde::__private::Into::<#this>::into(#result)
+            _serde::__private::Into::<#this_type #ty_generics>::into(#result)
         };
     }
 
@@ -801,14 +808,14 @@
         }
     });
 
-    let this = &params.this;
+    let this_type = &params.this_type;
     let (_, ty_generics, _) = params.generics.split_for_impl();
     let let_default = match cattrs.default() {
         attr::Default::Default => Some(quote!(
-            let __default: #this #ty_generics  = _serde::__private::Default::default();
+            let __default: #this_type #ty_generics = _serde::__private::Default::default();
         )),
         attr::Default::Path(path) => Some(quote!(
-            let __default: #this #ty_generics  = #path();
+            let __default: #this_type #ty_generics = #path();
         )),
         attr::Default::None => {
             // We don't need the default value, to prevent an unused variable warning
@@ -849,9 +856,10 @@
 
     let mut result = quote!(#type_path(__field0));
     if params.has_getter {
-        let this = &params.this;
+        let this_type = &params.this_type;
+        let (_, ty_generics, _) = params.generics.split_for_impl();
         result = quote! {
-            _serde::__private::Into::<#this>::into(#result)
+            _serde::__private::Into::<#this_type #ty_generics>::into(#result)
         };
     }
 
@@ -901,7 +909,8 @@
 ) -> Fragment {
     let is_enum = variant_ident.is_some();
 
-    let this = &params.this;
+    let this_type = &params.this_type;
+    let this_value = &params.this_value;
     let (de_impl_generics, de_ty_generics, ty_generics, where_clause) =
         split_with_de_lifetime(params);
     let delife = params.borrowed.de_lifetime();
@@ -913,7 +922,7 @@
         let local = &params.local;
         quote!(#local)
     } else {
-        quote!(#this)
+        quote!(#this_value)
     };
 
     let type_path = match variant_ident {
@@ -941,7 +950,7 @@
 
     let visitor_expr = quote! {
         __Visitor {
-            marker: _serde::__private::PhantomData::<#this #ty_generics>,
+            marker: _serde::__private::PhantomData::<#this_type #ty_generics>,
             lifetime: _serde::__private::PhantomData,
         }
     };
@@ -993,7 +1002,7 @@
     let visitor_seed = if is_enum && cattrs.has_flatten() {
         Some(quote! {
             impl #de_impl_generics _serde::de::DeserializeSeed<#delife> for __Visitor #de_ty_generics #where_clause {
-                type Value = #this #ty_generics;
+                type Value = #this_type #ty_generics;
 
                 fn deserialize<__D>(self, __deserializer: __D) -> _serde::__private::Result<Self::Value, __D::Error>
                 where
@@ -1011,12 +1020,12 @@
         #field_visitor
 
         struct __Visitor #de_impl_generics #where_clause {
-            marker: _serde::__private::PhantomData<#this #ty_generics>,
+            marker: _serde::__private::PhantomData<#this_type #ty_generics>,
             lifetime: _serde::__private::PhantomData<&#delife ()>,
         }
 
         impl #de_impl_generics _serde::de::Visitor<#delife> for __Visitor #de_ty_generics #where_clause {
-            type Value = #this #ty_generics;
+            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)
@@ -1057,7 +1066,7 @@
         return None;
     }
 
-    let this = &params.this;
+    let this_type = &params.this_type;
     let (de_impl_generics, de_ty_generics, ty_generics, where_clause) =
         split_with_de_lifetime(params);
     let delife = params.borrowed.de_lifetime();
@@ -1123,7 +1132,7 @@
         #field_visitor
 
         struct __Visitor #in_place_impl_generics #where_clause {
-            place: &#place_life mut #this #ty_generics,
+            place: &#place_life mut #this_type #ty_generics,
             lifetime: _serde::__private::PhantomData<&#delife ()>,
         }
 
@@ -1212,7 +1221,7 @@
     variants: &[Variant],
     cattrs: &attr::Container,
 ) -> Fragment {
-    let this = &params.this;
+    let this_type = &params.this_type;
     let (de_impl_generics, de_ty_generics, ty_generics, where_clause) =
         split_with_de_lifetime(params);
     let delife = params.borrowed.de_lifetime();
@@ -1266,12 +1275,12 @@
         #variant_visitor
 
         struct __Visitor #de_impl_generics #where_clause {
-            marker: _serde::__private::PhantomData<#this #ty_generics>,
+            marker: _serde::__private::PhantomData<#this_type #ty_generics>,
             lifetime: _serde::__private::PhantomData<&#delife ()>,
         }
 
         impl #de_impl_generics _serde::de::Visitor<#delife> for __Visitor #de_ty_generics #where_clause {
-            type Value = #this #ty_generics;
+            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)
@@ -1292,7 +1301,7 @@
             #type_name,
             VARIANTS,
             __Visitor {
-                marker: _serde::__private::PhantomData::<#this #ty_generics>,
+                marker: _serde::__private::PhantomData::<#this_type #ty_generics>,
                 lifetime: _serde::__private::PhantomData,
             },
         )
@@ -1354,7 +1363,8 @@
     tag: &str,
     content: &str,
 ) -> Fragment {
-    let this = &params.this;
+    let this_type = &params.this_type;
+    let this_value = &params.this_value;
     let (de_impl_generics, de_ty_generics, ty_generics, where_clause) =
         split_with_de_lifetime(params);
     let delife = params.borrowed.de_lifetime();
@@ -1415,13 +1425,13 @@
 
             let arm = match variant.style {
                 Style::Unit => quote! {
-                    _serde::__private::Ok(#this::#variant_ident)
+                    _serde::__private::Ok(#this_value::#variant_ident)
                 },
                 Style::Newtype if variant.attrs.deserialize_with().is_none() => {
                     let span = variant.original.span();
                     let func = quote_spanned!(span=> _serde::__private::de::missing_field);
                     quote! {
-                        #func(#content).map(#this::#variant_ident)
+                        #func(#content).map(#this_value::#variant_ident)
                     }
                 }
                 _ => {
@@ -1513,12 +1523,12 @@
 
         struct __Seed #de_impl_generics #where_clause {
             field: __Field,
-            marker: _serde::__private::PhantomData<#this #ty_generics>,
+            marker: _serde::__private::PhantomData<#this_type #ty_generics>,
             lifetime: _serde::__private::PhantomData<&#delife ()>,
         }
 
         impl #de_impl_generics _serde::de::DeserializeSeed<#delife> for __Seed #de_ty_generics #where_clause {
-            type Value = #this #ty_generics;
+            type Value = #this_type #ty_generics;
 
             fn deserialize<__D>(self, __deserializer: __D) -> _serde::__private::Result<Self::Value, __D::Error>
             where
@@ -1531,12 +1541,12 @@
         }
 
         struct __Visitor #de_impl_generics #where_clause {
-            marker: _serde::__private::PhantomData<#this #ty_generics>,
+            marker: _serde::__private::PhantomData<#this_type #ty_generics>,
             lifetime: _serde::__private::PhantomData<&#delife ()>,
         }
 
         impl #de_impl_generics _serde::de::Visitor<#delife> for __Visitor #de_ty_generics #where_clause {
-            type Value = #this #ty_generics;
+            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)
@@ -1638,7 +1648,7 @@
             #type_name,
             FIELDS,
             __Visitor {
-                marker: _serde::__private::PhantomData::<#this #ty_generics>,
+                marker: _serde::__private::PhantomData::<#this_type #ty_generics>,
                 lifetime: _serde::__private::PhantomData,
             },
         )
@@ -1707,10 +1717,10 @@
 
     match variant.style {
         Style::Unit => {
-            let this = &params.this;
+            let this_value = &params.this_value;
             quote_block! {
                 try!(_serde::de::VariantAccess::unit_variant(__variant));
-                _serde::__private::Ok(#this::#variant_ident)
+                _serde::__private::Ok(#this_value::#variant_ident)
             }
         }
         Style::Newtype => deserialize_externally_tagged_newtype_variant(
@@ -1749,7 +1759,7 @@
 
     match effective_style(variant) {
         Style::Unit => {
-            let this = &params.this;
+            let this_value = &params.this_value;
             let type_name = params.type_name();
             let variant_name = variant.ident.to_string();
             let default = variant.fields.get(0).map(|field| {
@@ -1758,7 +1768,7 @@
             });
             quote_block! {
                 try!(_serde::Deserializer::deserialize_any(#deserializer, _serde::__private::de::InternallyTaggedUnitVisitor::new(#type_name, #variant_name)));
-                _serde::__private::Ok(#this::#variant_ident #default)
+                _serde::__private::Ok(#this_value::#variant_ident #default)
             }
         }
         Style::Newtype => deserialize_untagged_newtype_variant(
@@ -1796,7 +1806,7 @@
 
     match effective_style(variant) {
         Style::Unit => {
-            let this = &params.this;
+            let this_value = &params.this_value;
             let type_name = params.type_name();
             let variant_name = variant.ident.to_string();
             let default = variant.fields.get(0).map(|field| {
@@ -1808,7 +1818,7 @@
                     #deserializer,
                     _serde::__private::de::UntaggedUnitVisitor::new(#type_name, #variant_name)
                 ) {
-                    _serde::__private::Ok(()) => _serde::__private::Ok(#this::#variant_ident #default),
+                    _serde::__private::Ok(()) => _serde::__private::Ok(#this_value::#variant_ident #default),
                     _serde::__private::Err(__err) => _serde::__private::Err(__err),
                 }
             }
@@ -1843,14 +1853,13 @@
     field: &Field,
     cattrs: &attr::Container,
 ) -> Fragment {
-    let this = &params.this;
+    let this_value = &params.this_value;
 
     if field.attrs.skip_deserializing() {
-        let this = &params.this;
         let default = Expr(expr_is_missing(field, cattrs));
         return quote_block! {
             try!(_serde::de::VariantAccess::unit_variant(__variant));
-            _serde::__private::Ok(#this::#variant_ident(#default))
+            _serde::__private::Ok(#this_value::#variant_ident(#default))
         };
     }
 
@@ -1861,7 +1870,7 @@
             let func =
                 quote_spanned!(span=> _serde::de::VariantAccess::newtype_variant::<#field_ty>);
             quote_expr! {
-                _serde::__private::Result::map(#func(__variant), #this::#variant_ident)
+                _serde::__private::Result::map(#func(__variant), #this_value::#variant_ident)
             }
         }
         Some(path) => {
@@ -1870,7 +1879,7 @@
                 #wrapper
                 _serde::__private::Result::map(
                     _serde::de::VariantAccess::newtype_variant::<#wrapper_ty>(__variant),
-                    |__wrapper| #this::#variant_ident(__wrapper.value))
+                    |__wrapper| #this_value::#variant_ident(__wrapper.value))
             }
         }
     }
@@ -1882,20 +1891,20 @@
     field: &Field,
     deserializer: &TokenStream,
 ) -> Fragment {
-    let this = &params.this;
+    let this_value = &params.this_value;
     let field_ty = field.ty;
     match field.attrs.deserialize_with() {
         None => {
             let span = field.original.span();
             let func = quote_spanned!(span=> <#field_ty as _serde::Deserialize>::deserialize);
             quote_expr! {
-                _serde::__private::Result::map(#func(#deserializer), #this::#variant_ident)
+                _serde::__private::Result::map(#func(#deserializer), #this_value::#variant_ident)
             }
         }
         Some(path) => {
             quote_block! {
                 let __value: _serde::__private::Result<#field_ty, _> = #path(#deserializer);
-                _serde::__private::Result::map(__value, #this::#variant_ident)
+                _serde::__private::Result::map(__value, #this_value::#variant_ident)
             }
         }
     }
@@ -1907,7 +1916,7 @@
     is_variant: bool,
     other_idx: Option<usize>,
 ) -> Fragment {
-    let this = quote!(__Field);
+    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() {
@@ -1927,7 +1936,7 @@
     };
 
     let visitor_impl = Stmts(deserialize_identifier(
-        &this,
+        &this_value,
         fields,
         is_variant,
         fallthrough,
@@ -1982,8 +1991,8 @@
         attr::Identifier::No => unreachable!(),
     };
 
-    let this = &params.this;
-    let this = quote!(#this);
+    let this_type = params.this_type.to_token_stream();
+    let this_value = params.this_value.to_token_stream();
 
     let (ordinary, fallthrough, fallthrough_borrowed) = if let Some(last) = variants.last() {
         let last_ident = &last.ident;
@@ -1992,7 +2001,7 @@
             // last variant (checked in `check_identifier`), so all preceding
             // are ordinary variants.
             let ordinary = &variants[..variants.len() - 1];
-            let fallthrough = quote!(_serde::__private::Ok(#this::#last_ident));
+            let fallthrough = quote!(_serde::__private::Ok(#this_value::#last_ident));
             (ordinary, Some(fallthrough), None)
         } else if let Style::Newtype = last.style {
             let ordinary = &variants[..variants.len() - 1];
@@ -2002,7 +2011,7 @@
                         _serde::Deserialize::deserialize(
                             _serde::__private::de::IdentifierDeserializer::from(#value)
                         ),
-                        #this::#last_ident)
+                        #this_value::#last_ident)
                 }
             };
             (
@@ -2050,7 +2059,7 @@
         split_with_de_lifetime(params);
     let delife = params.borrowed.de_lifetime();
     let visitor_impl = Stmts(deserialize_identifier(
-        &this,
+        &this_value,
         &names_idents,
         is_variant,
         fallthrough,
@@ -2063,18 +2072,18 @@
         #names_const
 
         struct __FieldVisitor #de_impl_generics #where_clause {
-            marker: _serde::__private::PhantomData<#this #ty_generics>,
+            marker: _serde::__private::PhantomData<#this_type #ty_generics>,
             lifetime: _serde::__private::PhantomData<&#delife ()>,
         }
 
         impl #de_impl_generics _serde::de::Visitor<#delife> for __FieldVisitor #de_ty_generics #where_clause {
-            type Value = #this #ty_generics;
+            type Value = #this_type #ty_generics;
 
             #visitor_impl
         }
 
         let __visitor = __FieldVisitor {
-            marker: _serde::__private::PhantomData::<#this #ty_generics>,
+            marker: _serde::__private::PhantomData::<#this_type #ty_generics>,
             lifetime: _serde::__private::PhantomData,
         };
         _serde::Deserializer::deserialize_identifier(__deserializer, __visitor)
@@ -2082,7 +2091,7 @@
 }
 
 fn deserialize_identifier(
-    this: &TokenStream,
+    this_value: &TokenStream,
     fields: &[(String, Ident, Vec<String>)],
     is_variant: bool,
     fallthrough: Option<TokenStream>,
@@ -2103,11 +2112,11 @@
 
     let constructors: &Vec<_> = &flat_fields
         .iter()
-        .map(|(_, ident)| quote!(#this::#ident))
+        .map(|(_, ident)| quote!(#this_value::#ident))
         .collect();
     let main_constructors: &Vec<_> = &fields
         .iter()
-        .map(|(_, ident, _)| quote!(#this::#ident))
+        .map(|(_, ident, _)| quote!(#this_value::#ident))
         .collect();
 
     let expecting = expecting.unwrap_or(if is_variant {
@@ -2621,9 +2630,10 @@
 
     let mut result = quote!(#struct_path { #(#result),* });
     if params.has_getter {
-        let this = &params.this;
+        let this_type = &params.this_type;
+        let (_, ty_generics, _) = params.generics.split_for_impl();
         result = quote! {
-            _serde::__private::Into::<#this>::into(#result)
+            _serde::__private::Into::<#this_type #ty_generics>::into(#result)
         };
     }
 
@@ -2803,15 +2813,15 @@
             }
         });
 
-    let this = &params.this;
+    let this_type = &params.this_type;
     let (_, _, ty_generics, _) = split_with_de_lifetime(params);
 
     let let_default = match cattrs.default() {
         attr::Default::Default => Some(quote!(
-            let __default: #this #ty_generics = _serde::__private::Default::default();
+            let __default: #this_type #ty_generics = _serde::__private::Default::default();
         )),
         attr::Default::Path(path) => Some(quote!(
-            let __default: #this #ty_generics = #path();
+            let __default: #this_type #ty_generics = #path();
         )),
         attr::Default::None => {
             // We don't need the default value, to prevent an unused variable warning
@@ -2844,7 +2854,7 @@
     value_ty: &TokenStream,
     deserialize_with: &syn::ExprPath,
 ) -> (TokenStream, TokenStream) {
-    let this = &params.this;
+    let this_type = &params.this_type;
     let (de_impl_generics, de_ty_generics, ty_generics, where_clause) =
         split_with_de_lifetime(params);
     let delife = params.borrowed.de_lifetime();
@@ -2852,7 +2862,7 @@
     let wrapper = quote! {
         struct __DeserializeWith #de_impl_generics #where_clause {
             value: #value_ty,
-            phantom: _serde::__private::PhantomData<#this #ty_generics>,
+            phantom: _serde::__private::PhantomData<#this_type #ty_generics>,
             lifetime: _serde::__private::PhantomData<&#delife ()>,
         }
 
@@ -2903,7 +2913,7 @@
     variant: &Variant,
     with_wrapper: bool,
 ) -> TokenStream {
-    let this = &params.this;
+    let this_value = &params.this_value;
     let variant_ident = &variant.ident;
 
     let (arg, wrapper) = if with_wrapper {
@@ -2924,23 +2934,23 @@
         Style::Struct if variant.fields.len() == 1 => {
             let member = &variant.fields[0].member;
             quote! {
-                |#arg| #this::#variant_ident { #member: #wrapper }
+                |#arg| #this_value::#variant_ident { #member: #wrapper }
             }
         }
         Style::Struct => {
             let members = variant.fields.iter().map(|field| &field.member);
             quote! {
-                |#arg| #this::#variant_ident { #(#members: #wrapper.#field_access),* }
+                |#arg| #this_value::#variant_ident { #(#members: #wrapper.#field_access),* }
             }
         }
         Style::Tuple => quote! {
-            |#arg| #this::#variant_ident(#(#wrapper.#field_access),*)
+            |#arg| #this_value::#variant_ident(#(#wrapper.#field_access),*)
         },
         Style::Newtype => quote! {
-            |#arg| #this::#variant_ident(#wrapper)
+            |#arg| #this_value::#variant_ident(#wrapper)
         },
         Style::Unit => quote! {
-            |#arg| #this::#variant_ident
+            |#arg| #this_value::#variant_ident
         },
     }
 }
diff --git a/src/dummy.rs b/src/dummy.rs
index 29de260..a02bd37 100644
--- a/src/dummy.rs
+++ b/src/dummy.rs
@@ -12,10 +12,10 @@
 ) -> TokenStream {
     let try_replacement = try::replacement();
 
-    let dummy_const = if cfg!(underscore_consts) {
-        format_ident!("_")
-    } else {
+    let dummy_const = if cfg!(no_underscore_consts) {
         format_ident!("_IMPL_{}_FOR_{}", trait_, unraw(ty))
+    } else {
+        format_ident!("_")
     };
 
     let use_serde = match serde_path {
diff --git a/src/internals/attr.rs b/src/internals/attr.rs
index 13f5525..dc53248 100644
--- a/src/internals/attr.rs
+++ b/src/internals/attr.rs
@@ -1912,9 +1912,7 @@
         | syn::Type::Infer(_)
         | syn::Type::Verbatim(_) => {}
 
-        #[cfg(test)]
-        syn::Type::__TestExhaustive(_) => unimplemented!(),
-        #[cfg(not(test))]
+        #[cfg_attr(all(test, exhaustive), deny(non_exhaustive_omitted_patterns))]
         _ => {}
     }
 }
diff --git a/src/internals/check.rs b/src/internals/check.rs
index 0e2484a..eb1297a 100644
--- a/src/internals/check.rs
+++ b/src/internals/check.rs
@@ -6,6 +6,7 @@
 /// Cross-cutting checks that require looking at more than a single attrs
 /// object. Simpler checks should happen when parsing and building the attrs.
 pub fn check(cx: &Ctxt, cont: &mut Container, derive: Derive) {
+    check_remote_generic(cx, cont);
     check_getter(cx, cont);
     check_flatten(cx, cont);
     check_identifier(cx, cont);
@@ -16,6 +17,28 @@
     check_from_and_try_from(cx, cont);
 }
 
+/// Remote derive definition type must have either all of the generics of the
+/// remote type:
+///
+///     #[serde(remote = "Generic")]
+///     struct Generic<T> {…}
+///
+/// or none of them, i.e. defining impls for one concrete instantiation of the
+/// remote type only:
+///
+///     #[serde(remote = "Generic<T>")]
+///     struct ConcreteDef {…}
+///
+fn check_remote_generic(cx: &Ctxt, cont: &Container) {
+    if let Some(remote) = cont.attrs.remote() {
+        let local_has_generic = !cont.generics.params.is_empty();
+        let remote_has_generic = !remote.segments.last().unwrap().arguments.is_none();
+        if local_has_generic && remote_has_generic {
+            cx.error_spanned_by(remote, "remove generic parameters from this path");
+        }
+    }
+}
+
 /// Getters are only allowed inside structs (not enums) with the `remote`
 /// attribute.
 fn check_getter(cx: &Ctxt, cont: &Container) {
diff --git a/src/internals/receiver.rs b/src/internals/receiver.rs
index 2b722d8..b08c670 100644
--- a/src/internals/receiver.rs
+++ b/src/internals/receiver.rs
@@ -147,9 +147,7 @@
 
             Type::Infer(_) | Type::Never(_) | Type::Verbatim(_) => {}
 
-            #[cfg(test)]
-            Type::__TestExhaustive(_) => unimplemented!(),
-            #[cfg(not(test))]
+            #[cfg_attr(all(test, exhaustive), deny(non_exhaustive_omitted_patterns))]
             _ => {}
         }
     }
diff --git a/src/lib.rs b/src/lib.rs
index 8079bb6..13b2103 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -13,7 +13,7 @@
 //!
 //! [https://serde.rs/derive.html]: https://serde.rs/derive.html
 
-#![doc(html_root_url = "https://docs.rs/serde_derive/1.0.136")]
+#![doc(html_root_url = "https://docs.rs/serde_derive/1.0.150")]
 #![allow(unknown_lints, bare_trait_objects)]
 // Ignored clippy lints
 #![allow(
@@ -22,6 +22,7 @@
     clippy::cognitive_complexity,
     // clippy bug: https://github.com/rust-lang/rust-clippy/issues/7575
     clippy::collapsible_match,
+    clippy::derive_partial_eq_without_eq,
     clippy::enum_variant_names,
     // clippy bug: https://github.com/rust-lang/rust-clippy/issues/6797
     clippy::manual_map,
@@ -42,7 +43,6 @@
     clippy::enum_glob_use,
     clippy::indexing_slicing,
     clippy::items_after_statements,
-    clippy::let_underscore_drop,
     clippy::manual_assert,
     clippy::map_err_ignore,
     clippy::match_same_arms,
@@ -60,6 +60,7 @@
     clippy::use_self,
     clippy::wildcard_imports
 )]
+#![cfg_attr(all(test, exhaustive), feature(non_exhaustive_omitted_patterns_lint))]
 
 #[macro_use]
 extern crate quote;
@@ -83,6 +84,7 @@
 mod dummy;
 mod pretend;
 mod ser;
+mod this;
 mod try;
 
 #[proc_macro_derive(Serialize, attributes(serde))]
diff --git a/src/pretend.rs b/src/pretend.rs
index 3af6a66..d7b953d 100644
--- a/src/pretend.rs
+++ b/src/pretend.rs
@@ -97,7 +97,7 @@
 
     let members = fields.iter().map(|field| &field.member).collect::<Vec<_>>();
 
-    #[cfg(ptr_addr_of)]
+    #[cfg(not(no_ptr_addr_of))]
     {
         quote! {
             match _serde::__private::None::<&#type_ident #ty_generics> {
@@ -111,7 +111,7 @@
         }
     }
 
-    #[cfg(not(ptr_addr_of))]
+    #[cfg(no_ptr_addr_of)]
     {
         let placeholders = (0usize..).map(|i| format_ident!("__v{}", i));
 
diff --git a/src/ser.rs b/src/ser.rs
index 529a20d..43695dd 100644
--- a/src/ser.rs
+++ b/src/ser.rs
@@ -8,6 +8,7 @@
 use internals::ast::{Container, Data, Field, Style, Variant};
 use internals::{attr, replace_receiver, Ctxt, Derive};
 use pretend;
+use this;
 
 pub fn expand_derive_serialize(
     input: &mut syn::DeriveInput,
@@ -82,9 +83,13 @@
     self_var: Ident,
 
     /// Path to the type the impl is for. Either a single `Ident` for local
-    /// types or `some::remote::Ident` for remote types. Does not include
-    /// generic parameters.
-    this: syn::Path,
+    /// types (does not include generic parameters) or `some::remote::Path` for
+    /// remote types.
+    this_type: syn::Path,
+
+    /// Same as `this_type` but using `::<T>` for generic parameters for use in
+    /// expression position.
+    this_value: syn::Path,
 
     /// Generics including any explicit and inferred bounds for the impl.
     generics: syn::Generics,
@@ -105,18 +110,15 @@
             Ident::new("self", Span::call_site())
         };
 
-        let this = match cont.attrs.remote() {
-            Some(remote) => remote.clone(),
-            None => cont.ident.clone().into(),
-        };
-
+        let this_type = this::this_type(cont);
+        let this_value = this::this_value(cont);
         let is_packed = cont.attrs.is_packed();
-
         let generics = build_generics(cont);
 
         Parameters {
             self_var,
-            this,
+            this_type,
+            this_value,
             generics,
             is_remote,
             is_packed,
@@ -126,7 +128,7 @@
     /// Type name to use in error messages and `&'static str` arguments to
     /// various Serializer methods.
     fn type_name(&self) -> String {
-        self.this.segments.last().unwrap().ident.to_string()
+        self.this_type.segments.last().unwrap().ident.to_string()
     }
 }
 
@@ -427,7 +429,7 @@
     variant_index: u32,
     cattrs: &attr::Container,
 ) -> TokenStream {
-    let this = &params.this;
+    let this_value = &params.this_value;
     let variant_ident = &variant.ident;
 
     if variant.attrs.skip_serializing() {
@@ -445,32 +447,32 @@
             Style::Struct => quote!({ .. }),
         };
         quote! {
-            #this::#variant_ident #fields_pat => #skipped_err,
+            #this_value::#variant_ident #fields_pat => #skipped_err,
         }
     } else {
         // variant wasn't skipped
         let case = match variant.style {
             Style::Unit => {
                 quote! {
-                    #this::#variant_ident
+                    #this_value::#variant_ident
                 }
             }
             Style::Newtype => {
                 quote! {
-                    #this::#variant_ident(ref __field0)
+                    #this_value::#variant_ident(ref __field0)
                 }
             }
             Style::Tuple => {
                 let field_names = (0..variant.fields.len())
                     .map(|i| Ident::new(&format!("__field{}", i), Span::call_site()));
                 quote! {
-                    #this::#variant_ident(#(ref #field_names),*)
+                    #this_value::#variant_ident(#(ref #field_names),*)
                 }
             }
             Style::Struct => {
                 let members = variant.fields.iter().map(|f| &f.member);
                 quote! {
-                    #this::#variant_ident { #(ref #members),* }
+                    #this_value::#variant_ident { #(ref #members),* }
                 }
             }
         };
@@ -640,7 +642,7 @@
     tag: &str,
     content: &str,
 ) -> Fragment {
-    let this = &params.this;
+    let this_type = &params.this_type;
     let type_name = cattrs.name().serialize_name();
     let variant_name = variant.attrs.name().serialize_name();
 
@@ -719,7 +721,7 @@
     quote_block! {
         struct __AdjacentlyTagged #wrapper_generics #where_clause {
             data: (#(&'__a #fields_ty,)*),
-            phantom: _serde::__private::PhantomData<#this #ty_generics>,
+            phantom: _serde::__private::PhantomData<#this_type #ty_generics>,
         }
 
         impl #wrapper_impl_generics _serde::Serialize for __AdjacentlyTagged #wrapper_ty_generics #where_clause {
@@ -741,7 +743,7 @@
         try!(_serde::ser::SerializeStruct::serialize_field(
             &mut __struct, #content, &__AdjacentlyTagged {
                 data: (#(#fields_ident,)*),
-                phantom: _serde::__private::PhantomData::<#this #ty_generics>,
+                phantom: _serde::__private::PhantomData::<#this_type #ty_generics>,
             }));
         _serde::ser::SerializeStruct::end(__struct)
     }
@@ -866,8 +868,8 @@
     Untagged,
 }
 
-fn serialize_struct_variant<'a>(
-    context: StructVariant<'a>,
+fn serialize_struct_variant(
+    context: StructVariant,
     params: &Parameters,
     fields: &[Field],
     name: &str,
@@ -950,8 +952,8 @@
     }
 }
 
-fn serialize_struct_variant_with_flatten<'a>(
-    context: StructVariant<'a>,
+fn serialize_struct_variant_with_flatten(
+    context: StructVariant,
     params: &Parameters,
     fields: &[Field],
     name: &str,
@@ -971,7 +973,7 @@
             variant_index,
             variant_name,
         } => {
-            let this = &params.this;
+            let this_type = &params.this_type;
             let fields_ty = fields.iter().map(|f| &f.ty);
             let members = &fields.iter().map(|f| &f.member).collect::<Vec<_>>();
 
@@ -982,7 +984,7 @@
             quote_block! {
                 struct __EnumFlatten #wrapper_generics #where_clause {
                     data: (#(&'__a #fields_ty,)*),
-                    phantom: _serde::__private::PhantomData<#this #ty_generics>,
+                    phantom: _serde::__private::PhantomData<#this_type #ty_generics>,
                 }
 
                 impl #wrapper_impl_generics _serde::Serialize for __EnumFlatten #wrapper_ty_generics #where_clause {
@@ -1006,7 +1008,7 @@
                     #variant_name,
                     &__EnumFlatten {
                         data: (#(#members,)*),
-                        phantom: _serde::__private::PhantomData::<#this #ty_generics>,
+                        phantom: _serde::__private::PhantomData::<#this_type #ty_generics>,
                     })
             }
         }
@@ -1192,7 +1194,7 @@
     field_tys: &[&syn::Type],
     field_exprs: &[TokenStream],
 ) -> TokenStream {
-    let this = &params.this;
+    let this_type = &params.this_type;
     let (_, ty_generics, where_clause) = params.generics.split_for_impl();
 
     let wrapper_generics = if field_exprs.is_empty() {
@@ -1212,7 +1214,7 @@
     quote!({
         struct __SerializeWith #wrapper_impl_generics #where_clause {
             values: (#(&'__a #field_tys, )*),
-            phantom: _serde::__private::PhantomData<#this #ty_generics>,
+            phantom: _serde::__private::PhantomData<#this_type #ty_generics>,
         }
 
         impl #wrapper_impl_generics _serde::Serialize for __SerializeWith #wrapper_ty_generics #where_clause {
@@ -1226,7 +1228,7 @@
 
         &__SerializeWith {
             values: (#(#field_exprs, )*),
-            phantom: _serde::__private::PhantomData::<#this #ty_generics>,
+            phantom: _serde::__private::PhantomData::<#this_type #ty_generics>,
         }
     })
 }
diff --git a/src/this.rs b/src/this.rs
new file mode 100644
index 0000000..32731d0
--- /dev/null
+++ b/src/this.rs
@@ -0,0 +1,32 @@
+use internals::ast::Container;
+use syn::{Path, PathArguments, Token};
+
+pub fn this_type(cont: &Container) -> Path {
+    if let Some(remote) = cont.attrs.remote() {
+        let mut this = remote.clone();
+        for segment in &mut this.segments {
+            if let PathArguments::AngleBracketed(arguments) = &mut segment.arguments {
+                arguments.colon2_token = None;
+            }
+        }
+        this
+    } else {
+        Path::from(cont.ident.clone())
+    }
+}
+
+pub fn this_value(cont: &Container) -> Path {
+    if let Some(remote) = cont.attrs.remote() {
+        let mut this = remote.clone();
+        for segment in &mut this.segments {
+            if let PathArguments::AngleBracketed(arguments) = &mut segment.arguments {
+                if arguments.colon2_token.is_none() {
+                    arguments.colon2_token = Some(Token![::](arguments.lt_token.span));
+                }
+            }
+        }
+        this
+    } else {
+        Path::from(cont.ident.clone())
+    }
+}