Bug 1447998 - Update cargo lockfile and re-vendor rust dependencies. r?jrmuizel draft
authorKartikaya Gupta <kgupta@mozilla.com>
Wed, 28 Mar 2018 09:13:15 -0400
changeset 773790 2c5ca1d6f4fc74431d0505232e8fcc1ca038aab8
parent 773789 cb665f53ba56fced7a4053de9447ee55d5522d9d
child 773791 522532ce78587673035ca997ec176c47eeb7c9d2
push id104304
push userkgupta@mozilla.com
push dateWed, 28 Mar 2018 13:14:35 +0000
reviewersjrmuizel
bugs1447998
milestone61.0a1
Bug 1447998 - Update cargo lockfile and re-vendor rust dependencies. r?jrmuizel MozReview-Commit-ID: FiipKgejZsy
Cargo.lock
third_party/rust/serde/.cargo-checksum.json
third_party/rust/serde/Cargo.toml
third_party/rust/serde/src/de/from_primitive.rs
third_party/rust/serde/src/de/impls.rs
third_party/rust/serde/src/de/mod.rs
third_party/rust/serde/src/lib.rs
third_party/rust/serde/src/private/de.rs
third_party/rust/serde/src/private/ser.rs
third_party/rust/serde/src/ser/impls.rs
third_party/rust/serde/src/ser/mod.rs
third_party/rust/serde_derive/.cargo-checksum.json
third_party/rust/serde_derive/Cargo.toml
third_party/rust/serde_derive/src/bound.rs
third_party/rust/serde_derive/src/de.rs
third_party/rust/serde_derive/src/fragment.rs
third_party/rust/serde_derive/src/lib.rs
third_party/rust/serde_derive/src/ser.rs
third_party/rust/serde_derive_internals/.cargo-checksum.json
third_party/rust/serde_derive_internals/Cargo.toml
third_party/rust/serde_derive_internals/src/ast.rs
third_party/rust/serde_derive_internals/src/attr.rs
third_party/rust/serde_derive_internals/src/case.rs
third_party/rust/serde_derive_internals/src/check.rs
third_party/rust/serde_derive_internals/src/ctxt.rs
third_party/rust/serde_derive_internals/src/lib.rs
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -17,17 +17,17 @@ version = "0.10.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "app_units"
 version = "0.6.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "num-traits 0.1.43 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "arrayvec"
 version = "0.4.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "nodrop 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -57,18 +57,18 @@ dependencies = [
  "cubeb 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "error-chain 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "futures 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)",
  "iovec 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "libc 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
  "memmap 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "scoped-tls 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_derive 1.0.27 (git+https://github.com/gankro/serde?branch=deserialize_from_enums4)",
+ "serde 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_derive 1.0.35 (git+https://github.com/servo/serde?branch=deserialize_from_enums5)",
  "tokio-core 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
  "tokio-io 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "tokio-uds 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "audioipc-client"
 version = "0.4.0"
@@ -116,17 +116,17 @@ version = "0.1.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "bincode"
 version = "1.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "bindgen"
 version = "0.33.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "cexpr 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -503,18 +503,18 @@ dependencies = [
 name = "dwrote"
 version = "0.4.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "gdi32-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "libc 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_derive 1.0.27 (git+https://github.com/gankro/serde?branch=deserialize_from_enums4)",
+ "serde 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_derive 1.0.35 (git+https://github.com/servo/serde?branch=deserialize_from_enums5)",
  "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "either"
 version = "1.1.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
@@ -558,17 +558,17 @@ version = "0.11.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "euclid"
 version = "0.17.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "num-traits 0.1.43 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "fallible"
 version = "0.0.1"
 dependencies = [
  "hashglobe 0.1.0",
  "smallvec 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1439,17 +1439,17 @@ name = "regex-syntax"
 version = "0.4.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "ron"
 version = "0.1.7"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "serde 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "rsdparsa"
 version = "0.1.0"
 
 [[package]]
 name = "rsdparsa_capi"
@@ -1539,39 +1539,40 @@ dependencies = [
 
 [[package]]
 name = "semver-parser"
 version = "0.7.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "serde"
-version = "1.0.27"
+version = "1.0.35"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "serde_derive 1.0.27 (git+https://github.com/gankro/serde?branch=deserialize_from_enums4)",
+ "serde_derive 1.0.35 (git+https://github.com/servo/serde?branch=deserialize_from_enums5)",
 ]
 
 [[package]]
 name = "serde_derive"
-version = "1.0.27"
-source = "git+https://github.com/gankro/serde?branch=deserialize_from_enums4#93e24f268ab99c0df10e2183587284e02ca30e9e"
+version = "1.0.35"
+source = "git+https://github.com/servo/serde?branch=deserialize_from_enums5#de4534b21f263752ed3b641c3c07e012574985bf"
 dependencies = [
- "quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_derive_internals 0.19.0 (git+https://github.com/gankro/serde?branch=deserialize_from_enums4)",
- "syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)",
+ "proc-macro2 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "quote 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_derive_internals 0.22.1 (git+https://github.com/servo/serde?branch=deserialize_from_enums5)",
+ "syn 0.12.12 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "serde_derive_internals"
-version = "0.19.0"
-source = "git+https://github.com/gankro/serde?branch=deserialize_from_enums4#93e24f268ab99c0df10e2183587284e02ca30e9e"
+version = "0.22.1"
+source = "git+https://github.com/servo/serde?branch=deserialize_from_enums5#de4534b21f263752ed3b641c3c07e012574985bf"
 dependencies = [
- "syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)",
- "synom 0.11.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "proc-macro2 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "syn 0.12.12 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "servo_arc"
 version = "0.1.1"
 dependencies = [
  "nodrop 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)",
  "stable_deref_trait 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1843,17 +1844,17 @@ dependencies = [
  "tokio-io 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "toml"
 version = "0.4.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "serde 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "traitobject"
 version = "0.1.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
@@ -2026,17 +2027,17 @@ dependencies = [
  "fxhash 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "gleam 0.4.20 (registry+https://github.com/rust-lang/crates.io-index)",
  "lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "num-traits 0.1.43 (registry+https://github.com/rust-lang/crates.io-index)",
  "plane-split 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "rayon 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "ron 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)",
  "smallvec 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "thread_profiler 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "time 0.1.38 (registry+https://github.com/rust-lang/crates.io-index)",
  "webrender_api 0.57.0",
 ]
 
 [[package]]
 name = "webrender_api"
@@ -2045,18 +2046,18 @@ dependencies = [
  "app_units 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "bincode 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "bitflags 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "core-foundation 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "core-graphics 0.13.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "dwrote 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "euclid 0.17.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_derive 1.0.27 (git+https://github.com/gankro/serde?branch=deserialize_from_enums4)",
+ "serde 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_derive 1.0.35 (git+https://github.com/servo/serde?branch=deserialize_from_enums5)",
  "time 0.1.38 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "webrender_bindings"
 version = "0.1.0"
 dependencies = [
  "app_units 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -2318,19 +2319,19 @@ dependencies = [
 "checksum rust-ini 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)" = "22dab655e8122ccb15db25a56852ce62506f1486cdefd37e86371bf34ea8f601"
 "checksum rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)" = "dcf128d1287d2ea9d80910b5f1120d0b8eede3fbf1abe91c40d39ea7d51e6fda"
 "checksum safemem 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e27a8b19b835f7aea908818e871f5cc3a5a186550c30773be987e155e8163d8f"
 "checksum same-file 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "d931a44fdaa43b8637009e7632a02adc4f2b2e0733c08caa4cf00e8da4a117a7"
 "checksum scoped-tls 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f417c22df063e9450888a7561788e9bd46d3bb3c1466435b4eccb903807f147d"
 "checksum scopeguard 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c79eb2c3ac4bc2507cda80e7f3ac5b88bd8eae4c0914d5663e6a8933994be918"
 "checksum semver 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7a3186ec9e65071a2095434b1f5bb24838d4e8e130f584c790f6033c79943537"
 "checksum semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3"
-"checksum serde 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)" = "db99f3919e20faa51bb2996057f5031d8685019b5a06139b1ce761da671b8526"
-"checksum serde_derive 1.0.27 (git+https://github.com/gankro/serde?branch=deserialize_from_enums4)" = "<none>"
-"checksum serde_derive_internals 0.19.0 (git+https://github.com/gankro/serde?branch=deserialize_from_enums4)" = "<none>"
+"checksum serde 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)" = "800fdb0a894572994f3970035a8a5f65d8ec2cd40e6cdf7d8cd9001d7b30648e"
+"checksum serde_derive 1.0.35 (git+https://github.com/servo/serde?branch=deserialize_from_enums5)" = "<none>"
+"checksum serde_derive_internals 0.22.1 (git+https://github.com/servo/serde?branch=deserialize_from_enums5)" = "<none>"
 "checksum simd 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3dd0805c7363ab51a829a1511ad24b6ed0349feaa756c4bc2f977f9f496e6673"
 "checksum siphasher 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2ffc669b726f2bc9a3bcff66e5e23b56ba6bf70e22a34c3d7b6d0b3450b65b84"
 "checksum slab 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "17b4fcaed89ab08ef143da37bc52adbcc04d4a69014f4c1208d6b51f0c47bc23"
 "checksum smallbitvec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "79b776f00dfe01df905fa3b2eaa1659522e99e3fc4a7b1334171622205c4bdcf"
 "checksum smallvec 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "44db0ecb22921ef790d17ae13a3f6d15784183ff5f2a01aa32098c7498d2b4b9"
 "checksum stable_deref_trait 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "15132e0e364248108c5e2c02e3ab539be8d6f5d52a01ca9bbf27ed657316f02b"
 "checksum strsim 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b4d15c810519a91cf877e7e36e63fe068815c678181439f2f29e2562147c3694"
 "checksum syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)" = "d3b891b9015c88c576343b9b3e41c2c11a51c219ef067b264bd9c8aa9b441dad"
--- a/third_party/rust/serde/.cargo-checksum.json
+++ b/third_party/rust/serde/.cargo-checksum.json
@@ -1,1 +1,1 @@
-{"files":{"Cargo.toml":"b5e865ec105f4f546fecdf164172e670b2b82a2533700f556cc1c1c246a4ce14","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"6485b8ed310d3f0340bf1ad1f47645069ce4069dcc6bb46c7d5c6faf41de1fdb","README.md":"7dc6376a88195594cd6b43cb891aad10f57144ff737178b55d046aa04739b43a","src/de/from_primitive.rs":"28ec3ab1c430cf27d632b642ccfccb6d055eeb9fb576e7e446ba24c66f507fb4","src/de/ignored_any.rs":"864eaefef0aaae36daf0c2bdee08165dabbf60710f3217142d5e280c0a35c1fe","src/de/impls.rs":"e0d8b5255afb175daf720dd5b1072d2d1888fce6790de57fe51d8d2b51fc1603","src/de/mod.rs":"2984925d7844816cacc290067db049766912d1393732d9df280e6ba020582afc","src/de/utf8.rs":"956b124b7ce98353cb781b56e43a6fed2e67f1389d35b7a468d5be75b1485853","src/de/value.rs":"463e107e9ce9a56cc22901aeb60edbf0d10b144ca03dcdb78988d68f6c96022b","src/export.rs":"dd08253f225862aa5009b27900e04187480c96562c35205b71b36b2ac64c4cce","src/lib.rs":"d8411e8311ec29d8d7184556e014a11f03fe84af26f64daeaf34ad449310084d","src/macros.rs":"e1d542b1dac2c1d1f9d5ada7cc5b6639767fc67851421cc3adfb942a7cf750b6","src/private/de.rs":"55403af32b5b4112ab2203c1598bb033308f8c59ed5c4b5f4730dc2f26d3808d","src/private/macros.rs":"6861a4f332ea24d0ed5db1c28fe3105d2716523902f045c0bbbd439ebf9e44de","src/private/mod.rs":"bcd7c54838e139475c23a323678e20eccbe88c0be93f7977f7675cead4d3b6ed","src/private/ser.rs":"fed0c80a55a214c9bf411fe591f8f99562b01fcd27dfe968f6cc9d694a9c60b2","src/ser/impls.rs":"7eb99e5a74a3fcbb611a6ad762d1915a0ae1f5bb7a95f54115936db3bdde32ca","src/ser/impossible.rs":"009dce92e20bd25335db7d747c595111f5eb8d21dda0f6c75bccf0d0608c5751","src/ser/mod.rs":"b0b970c9e4987db7fbd7bc3bb9f32448e2de864c6596829922cf8fe131dae23d"},"package":"db99f3919e20faa51bb2996057f5031d8685019b5a06139b1ce761da671b8526"}
\ No newline at end of file
+{"files":{"Cargo.toml":"921c55ce109f76220ebcd8f8ba6d7e97816e804818ba33772266eb98413fd024","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"6485b8ed310d3f0340bf1ad1f47645069ce4069dcc6bb46c7d5c6faf41de1fdb","README.md":"7dc6376a88195594cd6b43cb891aad10f57144ff737178b55d046aa04739b43a","src/de/from_primitive.rs":"2ddd1b60696f125652ea69da94575d9a3b76ba667924860df112abc35f56b90b","src/de/ignored_any.rs":"864eaefef0aaae36daf0c2bdee08165dabbf60710f3217142d5e280c0a35c1fe","src/de/impls.rs":"6ea6a19598bb5393de2063deed32c82ebe904b56328ec033f57b55c0e6eea4d7","src/de/mod.rs":"e020b1f027d9e552ff024b44379e87969decf96e4c6cef0e2e7827e2dc4f56c3","src/de/utf8.rs":"956b124b7ce98353cb781b56e43a6fed2e67f1389d35b7a468d5be75b1485853","src/de/value.rs":"463e107e9ce9a56cc22901aeb60edbf0d10b144ca03dcdb78988d68f6c96022b","src/export.rs":"dd08253f225862aa5009b27900e04187480c96562c35205b71b36b2ac64c4cce","src/lib.rs":"22746e82049e9b3f9c60399f552e10fddb4c33a037d00b097f3fc8083d193138","src/macros.rs":"e1d542b1dac2c1d1f9d5ada7cc5b6639767fc67851421cc3adfb942a7cf750b6","src/private/de.rs":"8f2461ead2df284d7b1b84a293b921f0138c368f88af9efd5b82ae345fbcfd59","src/private/macros.rs":"6861a4f332ea24d0ed5db1c28fe3105d2716523902f045c0bbbd439ebf9e44de","src/private/mod.rs":"bcd7c54838e139475c23a323678e20eccbe88c0be93f7977f7675cead4d3b6ed","src/private/ser.rs":"e27af87342c199a494d0001c1684ee6573a3eb330723a86fca3c3b6add38df7a","src/ser/impls.rs":"aaeeb2dd86a86808a292db73764617cce81382a346d117c725f5b48dd7e69212","src/ser/impossible.rs":"009dce92e20bd25335db7d747c595111f5eb8d21dda0f6c75bccf0d0608c5751","src/ser/mod.rs":"97c36fa5b8da27f1f95be9af54c441c8e59437e9533cdd90e376691737fc3d0f"},"package":"800fdb0a894572994f3970035a8a5f65d8ec2cd40e6cdf7d8cd9001d7b30648e"}
\ No newline at end of file
--- a/third_party/rust/serde/Cargo.toml
+++ b/third_party/rust/serde/Cargo.toml
@@ -7,17 +7,17 @@
 #
 # 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)
 
 [package]
 name = "serde"
-version = "1.0.27"
+version = "1.0.35"
 authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>", "David Tolnay <dtolnay@gmail.com>"]
 include = ["Cargo.toml", "src/**/*.rs", "README.md", "LICENSE-APACHE", "LICENSE-MIT"]
 description = "A generic serialization/deserialization framework"
 homepage = "https://serde.rs"
 documentation = "https://docs.serde.rs/serde/"
 readme = "README.md"
 keywords = ["serde", "serialization", "no_std"]
 categories = ["encoding"]
--- a/third_party/rust/serde/src/de/from_primitive.rs
+++ b/third_party/rust/serde/src/de/from_primitive.rs
@@ -5,37 +5,37 @@
 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
 use lib::*;
 
 macro_rules! int_to_int {
     ($dst:ident, $n:ident) => (
-        if $dst::MIN as i64 <= $n as i64 && $n as i64 <= $dst::MAX as i64 {
+        if $dst::min_value() as i64 <= $n as i64 && $n as i64 <= $dst::max_value() as i64 {
             Some($n as $dst)
         } else {
             None
         }
     )
 }
 
 macro_rules! int_to_uint {
     ($dst:ident, $n:ident) => (
-        if 0 <= $n && $n as u64 <= $dst::MAX as u64 {
+        if 0 <= $n && $n as u64 <= $dst::max_value() as u64 {
             Some($n as $dst)
         } else {
             None
         }
     )
 }
 
 macro_rules! uint_to {
     ($dst:ident, $n:ident) => (
-        if $n as u64 <= $dst::MAX as u64 {
+        if $n as u64 <= $dst::max_value() as u64 {
             Some($n as $dst)
         } else {
             None
         }
     )
 }
 
 pub trait FromPrimitive: Sized {
--- a/third_party/rust/serde/src/de/impls.rs
+++ b/third_party/rust/serde/src/de/impls.rs
@@ -1913,32 +1913,63 @@ where
             },
         )
     }
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 
 #[cfg(feature = "unstable")]
+#[allow(deprecated)]
 impl<'de, T> Deserialize<'de> for NonZero<T>
 where
     T: Deserialize<'de> + Zeroable,
 {
     fn deserialize<D>(deserializer: D) -> Result<NonZero<T>, D::Error>
     where
         D: Deserializer<'de>,
     {
         let value = try!(Deserialize::deserialize(deserializer));
         match NonZero::new(value) {
             Some(nonzero) => Ok(nonzero),
             None => Err(Error::custom("expected a non-zero value")),
         }
     }
 }
 
+macro_rules! nonzero_integers {
+    ( $( $T: ty, )+ ) => {
+        $(
+            #[cfg(feature = "unstable")]
+            impl<'de> Deserialize<'de> for $T {
+                fn deserialize<D>(deserializer: D) -> Result<$T, D::Error>
+                where
+                    D: Deserializer<'de>,
+                {
+                    let value = try!(Deserialize::deserialize(deserializer));
+                    match <$T>::new(value) {
+                        Some(nonzero) => Ok(nonzero),
+                        None => Err(Error::custom("expected a non-zero value")),
+                    }
+                }
+            }
+        )+
+    };
+}
+
+nonzero_integers! {
+    // Not including signed NonZeroI* since they might be removed
+    NonZeroU8,
+    NonZeroU16,
+    NonZeroU32,
+    NonZeroU64,
+    // FIXME: https://github.com/serde-rs/serde/issues/1136 NonZeroU128,
+    NonZeroUsize,
+}
+
 ////////////////////////////////////////////////////////////////////////////////
 
 impl<'de, T, E> Deserialize<'de> for Result<T, E>
 where
     T: Deserialize<'de>,
     E: Deserialize<'de>,
 {
     fn deserialize<D>(deserializer: D) -> Result<Result<T, E>, D::Error>
--- a/third_party/rust/serde/src/de/mod.rs
+++ b/third_party/rust/serde/src/de/mod.rs
@@ -93,17 +93,18 @@
 //!    - Box\<CStr\>
 //!    - OsString
 //!  - **Miscellaneous standard library types**:
 //!    - Duration
 //!    - SystemTime
 //!    - Path
 //!    - PathBuf
 //!    - Range\<T\>
-//!    - NonZero\<T\> (unstable)
+//!    - NonZero\<T\> (unstable, deprecated)
+//!    - num::NonZero* (unstable)
 //!  - **Net types**:
 //!    - IpAddr
 //!    - Ipv4Addr
 //!    - Ipv6Addr
 //!    - SocketAddr
 //!    - SocketAddrV4
 //!    - SocketAddrV6
 //!
@@ -508,17 +509,17 @@ pub trait Deserialize<'de>: Sized {
     /// Deserializes a value into `self` from the given Deserializer.
     ///
     /// The purpose of this method is to allow the deserializer to reuse
     /// resources and avoid copies. As such, if this method returns an error,
     /// `self` will be in an indeterminate state where some parts of the struct
     /// have been overwritten. Although whatever state that is will be
     /// memory-safe.
     ///
-    /// This is generally useful when repeateadly deserializing values that
+    /// This is generally useful when repeatedly deserializing values that
     /// are processed one at a time, where the value of `self` doesn't matter
     /// when the next deserialization occurs.
     ///
     /// If you manually implement this, your recursive deserializations should
     /// use `deserialize_in_place`.
     ///
     /// This method is stable and an official public API, but hidden from the
     /// documentation because it is almost never what newbies are looking for.
--- a/third_party/rust/serde/src/lib.rs
+++ b/third_party/rust/serde/src/lib.rs
@@ -74,49 +74,52 @@
 //! [Envy]: https://github.com/softprops/envy
 //! [Redis]: https://github.com/OneSignal/serde-redis
 //! [Cargo]: http://doc.crates.io/manifest.html
 //! [redis-rs]: https://crates.io/crates/redis
 
 ////////////////////////////////////////////////////////////////////////////////
 
 // Serde types in rustdoc of other crates get linked to here.
-#![doc(html_root_url = "https://docs.rs/serde/1.0.27")]
+#![doc(html_root_url = "https://docs.rs/serde/1.0.35")]
 // Support using Serde without the standard library!
 #![cfg_attr(not(feature = "std"), no_std)]
 // Unstable functionality only if the user asks for it. For tracking and
 // discussion of these features please refer to this issue:
 //
 //    https://github.com/serde-rs/serde/issues/812
 #![cfg_attr(feature = "unstable", feature(nonzero, specialization))]
 #![cfg_attr(feature = "alloc", feature(alloc))]
 #![cfg_attr(feature = "cargo-clippy", deny(clippy, clippy_pedantic))]
 // Whitelisted clippy lints
 #![cfg_attr(feature = "cargo-clippy",
             allow(cast_lossless, const_static_lifetime, doc_markdown, linkedlist,
-                  needless_pass_by_value, type_complexity, unreadable_literal,
-                  zero_prefixed_literal))]
+                  needless_pass_by_value, redundant_field_names, type_complexity,
+                  unreadable_literal, zero_prefixed_literal))]
 // Whitelisted clippy_pedantic lints
 #![cfg_attr(feature = "cargo-clippy", allow(
 // integer and float ser/de requires these sorts of casts
     cast_possible_truncation,
     cast_possible_wrap,
     cast_precision_loss,
     cast_sign_loss,
 // simplifies some macros
     invalid_upcast_comparisons,
 // things are often more readable this way
+    decimal_literal_representation,
     option_unwrap_used,
     result_unwrap_used,
     shadow_reuse,
     single_match_else,
     stutter,
     use_self,
 // not practical
+    many_single_char_names,
     missing_docs_in_private_items,
+    similar_names,
 // alternative is not stable
     empty_enum,
     use_debug,
 ))]
 // Blacklisted Rust lints.
 #![deny(missing_docs, unused_imports)]
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -203,17 +206,21 @@ mod lib {
     #[cfg(feature = "std")]
     pub use std::path::{Path, PathBuf};
     #[cfg(feature = "std")]
     pub use std::time::{Duration, SystemTime, UNIX_EPOCH};
     #[cfg(feature = "std")]
     pub use std::sync::{Mutex, RwLock};
 
     #[cfg(feature = "unstable")]
+    #[allow(deprecated)]
     pub use core::nonzero::{NonZero, Zeroable};
+
+    #[cfg(feature = "unstable")]
+    pub use core::num::{NonZeroU8, NonZeroU16, NonZeroU32, NonZeroU64, NonZeroUsize};
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 
 #[macro_use]
 mod macros;
 
 pub mod ser;
--- a/third_party/rust/serde/src/private/de.rs
+++ b/third_party/rust/serde/src/private/de.rs
@@ -6,23 +6,23 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
 use lib::*;
 
 use de::{Deserialize, DeserializeSeed, Deserializer, Error, IntoDeserializer, Visitor};
 
 #[cfg(any(feature = "std", feature = "alloc"))]
-use de::Unexpected;
+use de::{Unexpected, MapAccess};
 
 #[cfg(any(feature = "std", feature = "alloc"))]
 pub use self::content::{Content, ContentDeserializer, ContentRefDeserializer,
                         InternallyTaggedUnitVisitor, TagContentOtherField,
                         TagContentOtherFieldVisitor, TagOrContentField, TagOrContentFieldVisitor,
-                        TaggedContentVisitor, UntaggedUnitVisitor};
+                        TaggedContentVisitor, UntaggedUnitVisitor, EnumDeserializer};
 
 /// If the missing field is of type `Option<T>` then treat is as `None`,
 /// otherwise it is an error.
 pub fn missing_field<'de, V, E>(field: &'static str) -> Result<V, E>
 where
     V: Deserialize<'de>,
     E: Error,
 {
@@ -183,17 +183,17 @@ where
         fn visit_byte_buf<E>(self, v: Vec<u8>) -> Result<Self::Value, E>
         where
             E: Error,
         {
             Ok(Cow::Owned(v))
         }
     }
 
-    deserializer.deserialize_str(CowBytesVisitor)
+    deserializer.deserialize_bytes(CowBytesVisitor)
 }
 
 pub mod size_hint {
     use lib::*;
 
     pub fn from_bounds<I>(iter: &I) -> Option<usize>
     where
         I: Iterator,
@@ -264,16 +264,24 @@ mod content {
 
         Unit,
         Newtype(Box<Content<'de>>),
         Seq(Vec<Content<'de>>),
         Map(Vec<(Content<'de>, Content<'de>)>),
     }
 
     impl<'de> Content<'de> {
+        pub fn as_str(&self) -> Option<&str> {
+            match *self {
+                Content::Str(x) => Some(x),
+                Content::String(ref x) => Some(x),
+                _ => None,
+            }
+        }
+
         fn unexpected(&self) -> Unexpected {
             match *self {
                 Content::Bool(b) => Unexpected::Bool(b),
                 Content::U8(n) => Unexpected::Unsigned(n as u64),
                 Content::U16(n) => Unexpected::Unsigned(n as u64),
                 Content::U32(n) => Unexpected::Unsigned(n as u64),
                 Content::U64(n) => Unexpected::Unsigned(n),
                 Content::I8(n) => Unexpected::Signed(n as i64),
@@ -1113,21 +1121,17 @@ mod content {
                 other => {
                     return Err(de::Error::invalid_type(
                         other.unexpected(),
                         &"string or map",
                     ));
                 }
             };
 
-            visitor.visit_enum(EnumDeserializer {
-                variant: variant,
-                value: value,
-                err: PhantomData,
-            })
+            visitor.visit_enum(EnumDeserializer::new(variant, value))
         }
 
         fn deserialize_unit_struct<V>(
             self,
             _name: &'static str,
             visitor: V,
         ) -> Result<V::Value, Self::Error>
         where
@@ -1165,25 +1169,37 @@ mod content {
         pub fn new(content: Content<'de>) -> Self {
             ContentDeserializer {
                 content: content,
                 err: PhantomData,
             }
         }
     }
 
-    struct EnumDeserializer<'de, E>
+    pub struct EnumDeserializer<'de, E>
     where
         E: de::Error,
     {
         variant: Content<'de>,
         value: Option<Content<'de>>,
         err: PhantomData<E>,
     }
 
+    impl<'de, E> EnumDeserializer<'de, E>
+        where E: de::Error
+    {
+        pub fn new(variant: Content<'de>, value: Option<Content<'de>>) -> EnumDeserializer<'de, E> {
+            EnumDeserializer {
+                variant: variant,
+                value: value,
+                err: PhantomData,
+            }
+        }
+    }
+
     impl<'de, E> de::EnumAccess<'de> for EnumDeserializer<'de, E>
     where
         E: de::Error,
     {
         type Error = E;
         type Variant = VariantDeserializer<'de, Self::Error>;
 
         fn variant_seed<V>(self, seed: V) -> Result<(V::Value, Self::Variant), E>
@@ -1194,17 +1210,17 @@ mod content {
                 value: self.value,
                 err: PhantomData,
             };
             seed.deserialize(ContentDeserializer::new(self.variant))
                 .map(|v| (v, visitor))
         }
     }
 
-    struct VariantDeserializer<'de, E>
+    pub struct VariantDeserializer<'de, E>
     where
         E: de::Error,
     {
         value: Option<Content<'de>>,
         err: PhantomData<E>,
     }
 
     impl<'de, E> de::VariantAccess<'de> for VariantDeserializer<'de, E>
@@ -2057,8 +2073,167 @@ where
     type Value = ();
     fn deserialize<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
     where
         D: Deserializer<'de>,
     {
         T::deserialize_in_place(deserializer, self.0)
     }
 }
+
+#[cfg(any(feature = "std", feature = "alloc"))]
+pub struct FlatMapDeserializer<'a, 'de: 'a, E>(
+    pub &'a mut Vec<Option<(Content<'de>, Content<'de>)>>,
+    pub PhantomData<E>
+);
+
+#[cfg(any(feature = "std", feature = "alloc"))]
+impl<'a, 'de, E> Deserializer<'de> for FlatMapDeserializer<'a, 'de, E>
+    where E: Error
+{
+    type Error = E;
+
+    fn deserialize_any<V>(self, _: V) -> Result<V::Value, Self::Error>
+    where
+        V: Visitor<'de>,
+    {
+        Err(Error::custom("can only flatten structs and maps"))
+    }
+
+    fn deserialize_enum<V>(
+        self,
+        name: &'static str,
+        variants: &'static [&'static str],
+        visitor: V
+    ) -> Result<V::Value, Self::Error>
+    where
+        V: Visitor<'de>,
+    {
+        for item in self.0.iter_mut() {
+            // items in the vector are nulled out when used.  So we can only use
+            // an item if it's still filled in and if the field is one we care
+            // about.
+            let use_item = match *item {
+                None => false,
+                Some((ref c, _)) => c.as_str().map_or(false, |x| variants.contains(&x))
+            };
+
+            if use_item {
+                let (key, value) = item.take().unwrap();
+                return visitor.visit_enum(EnumDeserializer::new(
+                    key,
+                    Some(value)
+                ));
+            }
+        }
+
+        Err(Error::custom(format_args!(
+            "no variant of enum {} not found in flattened data",
+            name
+        )))
+    }
+
+    fn deserialize_map<V>(self, visitor: V) -> Result<V::Value, Self::Error>
+    where
+        V: Visitor<'de>,
+    {
+        visitor.visit_map(FlatMapAccess::new(self.0.iter_mut(), None))
+    }
+
+    fn deserialize_struct<V>(
+        self,
+        _: &'static str,
+        fields: &'static [&'static str],
+        visitor: V
+    ) -> Result<V::Value, Self::Error>
+    where
+        V: Visitor<'de>,
+    {
+        visitor.visit_map(FlatMapAccess::new(self.0.iter_mut(), Some(fields)))
+    }
+
+    fn deserialize_newtype_struct<V>(
+        self,
+        _name: &str,
+        visitor: V,
+    ) -> Result<V::Value, Self::Error>
+    where
+        V: Visitor<'de>,
+    {
+        visitor.visit_newtype_struct(self)
+    }
+
+    forward_to_deserialize_any! {
+        bool i8 i16 i32 i64 u8 u16 u32 u64 f32 f64 char str string bytes
+        byte_buf option unit unit_struct seq tuple tuple_struct identifier
+        ignored_any
+    }
+}
+
+#[cfg(any(feature = "std", feature = "alloc"))]
+pub struct FlatMapAccess<'a, 'de: 'a, E> {
+    iter: slice::IterMut<'a, Option<(Content<'de>, Content<'de>)>>,
+    pending_content: Option<Content<'de>>,
+    fields: Option<&'static [&'static str]>,
+    _marker: PhantomData<E>,
+}
+
+#[cfg(any(feature = "std", feature = "alloc"))]
+impl<'a, 'de, E> FlatMapAccess<'a, 'de, E> {
+    fn new(
+        iter: slice::IterMut<'a, Option<(Content<'de>, Content<'de>)>>,
+        fields: Option<&'static [&'static str]>
+    ) -> FlatMapAccess<'a, 'de, E> {
+        FlatMapAccess {
+            iter: iter,
+            pending_content: None,
+            fields: fields,
+            _marker: PhantomData,
+        }
+    }
+}
+
+#[cfg(any(feature = "std", feature = "alloc"))]
+impl<'a, 'de, E> MapAccess<'de> for FlatMapAccess<'a, 'de, E>
+    where E: Error
+{
+    type Error = E;
+
+    fn next_key_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>, Self::Error>
+    where
+        T: DeserializeSeed<'de>,
+    {
+        while let Some(item) = self.iter.next() {
+            // items in the vector are nulled out when used.  So we can only use
+            // an item if it's still filled in and if the field is one we care
+            // about.  In case we do not know which fields we want, we take them all.
+            let use_item = match *item {
+                None => false,
+                Some((ref c, _)) => {
+                    c.as_str().map_or(self.fields.is_none(), |key| {
+                        match self.fields {
+                            None => true,
+                            Some(fields) if fields.contains(&key) => true,
+                            _ => false
+                        }
+                    })
+                }
+            };
+
+            if use_item {
+                let (key, content) = item.take().unwrap();
+                self.pending_content = Some(content);
+                return seed.deserialize(ContentDeserializer::new(key)).map(Some);
+            }
+        }
+        Ok(None)
+    }
+
+    fn next_value_seed<T>(&mut self, seed: T) -> Result<T::Value, Self::Error>
+    where
+        T: DeserializeSeed<'de>,
+    {
+        match self.pending_content.take() {
+            Some(value) => seed.deserialize(ContentDeserializer::new(value)),
+            None => Err(Error::custom("value is missing")),
+        }
+    }
+}
--- a/third_party/rust/serde/src/private/ser.rs
+++ b/third_party/rust/serde/src/private/ser.rs
@@ -6,17 +6,22 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
 use lib::*;
 
 use ser::{self, Impossible, Serialize, SerializeMap, SerializeStruct, Serializer};
 
 #[cfg(any(feature = "std", feature = "alloc"))]
-use self::content::{SerializeStructVariantAsMapValue, SerializeTupleVariantAsMapValue};
+use self::content::{
+    SerializeStructVariantAsMapValue,
+    SerializeTupleVariantAsMapValue,
+    ContentSerializer,
+    Content,
+};
 
 /// Used to check that serde(getter) attributes return the expected type.
 /// Not public API.
 pub fn constrain<T: ?Sized>(t: &T) -> &T {
     t
 }
 
 /// Not public API.
@@ -53,38 +58,40 @@ enum Unsupported {
     Boolean,
     Integer,
     Float,
     Char,
     String,
     ByteArray,
     Optional,
     Unit,
+    #[cfg(any(feature = "std", feature = "alloc"))]
+    UnitStruct,
     Sequence,
     Tuple,
     TupleStruct,
-    #[cfg(not(any(feature = "std", feature = "alloc")))]
     Enum,
 }
 
 impl Display for Unsupported {
     fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
         match *self {
             Unsupported::Boolean => formatter.write_str("a boolean"),
             Unsupported::Integer => formatter.write_str("an integer"),
             Unsupported::Float => formatter.write_str("a float"),
             Unsupported::Char => formatter.write_str("a char"),
             Unsupported::String => formatter.write_str("a string"),
             Unsupported::ByteArray => formatter.write_str("a byte array"),
             Unsupported::Optional => formatter.write_str("an optional"),
             Unsupported::Unit => formatter.write_str("unit"),
+            #[cfg(any(feature = "std", feature = "alloc"))]
+            Unsupported::UnitStruct => formatter.write_str("unit struct"),
             Unsupported::Sequence => formatter.write_str("a sequence"),
             Unsupported::Tuple => formatter.write_str("a tuple"),
             Unsupported::TupleStruct => formatter.write_str("a tuple struct"),
-            #[cfg(not(any(feature = "std", feature = "alloc")))]
             Unsupported::Enum => formatter.write_str("an enum"),
         }
     }
 }
 
 impl<S> TaggedSerializer<S>
 where
     S: Serializer,
@@ -454,17 +461,17 @@ mod content {
                 self.map
                     .serialize_value(&Content::Struct(self.name, self.fields))
             );
             self.map.end()
         }
     }
 
     #[derive(Debug)]
-    enum Content {
+    pub enum Content {
         Bool(bool),
 
         U8(u8),
         U16(u16),
         U32(u32),
         U64(u64),
 
         I8(i8),
@@ -579,22 +586,22 @@ mod content {
                         try!(sv.serialize_field(k, v));
                     }
                     sv.end()
                 }
             }
         }
     }
 
-    struct ContentSerializer<E> {
+    pub struct ContentSerializer<E> {
         error: PhantomData<E>,
     }
 
     impl<E> ContentSerializer<E> {
-        fn new() -> Self {
+        pub fn new() -> Self {
             ContentSerializer { error: PhantomData }
         }
     }
 
     impl<E> Serializer for ContentSerializer<E>
     where
         E: ser::Error,
     {
@@ -799,17 +806,17 @@ mod content {
                 variant_index: variant_index,
                 variant: variant,
                 fields: Vec::with_capacity(len),
                 error: PhantomData,
             })
         }
     }
 
-    struct SerializeSeq<E> {
+    pub struct SerializeSeq<E> {
         elements: Vec<Content>,
         error: PhantomData<E>,
     }
 
     impl<E> ser::SerializeSeq for SerializeSeq<E>
     where
         E: ser::Error,
     {
@@ -825,17 +832,17 @@ mod content {
             Ok(())
         }
 
         fn end(self) -> Result<Content, E> {
             Ok(Content::Seq(self.elements))
         }
     }
 
-    struct SerializeTuple<E> {
+    pub struct SerializeTuple<E> {
         elements: Vec<Content>,
         error: PhantomData<E>,
     }
 
     impl<E> ser::SerializeTuple for SerializeTuple<E>
     where
         E: ser::Error,
     {
@@ -851,17 +858,17 @@ mod content {
             Ok(())
         }
 
         fn end(self) -> Result<Content, E> {
             Ok(Content::Tuple(self.elements))
         }
     }
 
-    struct SerializeTupleStruct<E> {
+    pub struct SerializeTupleStruct<E> {
         name: &'static str,
         fields: Vec<Content>,
         error: PhantomData<E>,
     }
 
     impl<E> ser::SerializeTupleStruct for SerializeTupleStruct<E>
     where
         E: ser::Error,
@@ -878,17 +885,17 @@ mod content {
             Ok(())
         }
 
         fn end(self) -> Result<Content, E> {
             Ok(Content::TupleStruct(self.name, self.fields))
         }
     }
 
-    struct SerializeTupleVariant<E> {
+    pub struct SerializeTupleVariant<E> {
         name: &'static str,
         variant_index: u32,
         variant: &'static str,
         fields: Vec<Content>,
         error: PhantomData<E>,
     }
 
     impl<E> ser::SerializeTupleVariant for SerializeTupleVariant<E>
@@ -912,17 +919,17 @@ mod content {
                 self.name,
                 self.variant_index,
                 self.variant,
                 self.fields,
             ))
         }
     }
 
-    struct SerializeMap<E> {
+    pub struct SerializeMap<E> {
         entries: Vec<(Content, Content)>,
         key: Option<Content>,
         error: PhantomData<E>,
     }
 
     impl<E> ser::SerializeMap for SerializeMap<E>
     where
         E: ser::Error,
@@ -962,17 +969,17 @@ mod content {
         {
             let key = try!(key.serialize(ContentSerializer::<E>::new()));
             let value = try!(value.serialize(ContentSerializer::<E>::new()));
             self.entries.push((key, value));
             Ok(())
         }
     }
 
-    struct SerializeStruct<E> {
+    pub struct SerializeStruct<E> {
         name: &'static str,
         fields: Vec<(&'static str, Content)>,
         error: PhantomData<E>,
     }
 
     impl<E> ser::SerializeStruct for SerializeStruct<E>
     where
         E: ser::Error,
@@ -989,17 +996,17 @@ mod content {
             Ok(())
         }
 
         fn end(self) -> Result<Content, E> {
             Ok(Content::Struct(self.name, self.fields))
         }
     }
 
-    struct SerializeStructVariant<E> {
+    pub struct SerializeStructVariant<E> {
         name: &'static str,
         variant_index: u32,
         variant: &'static str,
         fields: Vec<(&'static str, Content)>,
         error: PhantomData<E>,
     }
 
     impl<E> ser::SerializeStructVariant for SerializeStructVariant<E>
@@ -1023,8 +1030,288 @@ mod content {
                 self.name,
                 self.variant_index,
                 self.variant,
                 self.fields,
             ))
         }
     }
 }
+
+#[cfg(any(feature = "std", feature = "alloc"))]
+pub struct FlatMapSerializer<'a, M: 'a>(pub &'a mut M);
+
+#[cfg(any(feature = "std", feature = "alloc"))]
+impl<'a, M> FlatMapSerializer<'a, M>
+where
+    M: SerializeMap + 'a
+{
+    fn bad_type(self, what: Unsupported) -> M::Error {
+        ser::Error::custom(format_args!("can only flatten structs and maps (got {})", what))
+    }
+}
+
+#[cfg(any(feature = "std", feature = "alloc"))]
+impl<'a, M> Serializer for FlatMapSerializer<'a, M>
+    where M: SerializeMap + 'a
+{
+    type Ok = ();
+    type Error = M::Error;
+
+    type SerializeSeq = Impossible<Self::Ok, M::Error>;
+    type SerializeTuple = Impossible<Self::Ok, M::Error>;
+    type SerializeTupleStruct = Impossible<Self::Ok, M::Error>;
+    type SerializeMap = FlatMapSerializeMap<'a, M>;
+    type SerializeStruct = FlatMapSerializeStruct<'a, M>;
+    type SerializeTupleVariant = Impossible<Self::Ok, M::Error>;
+    type SerializeStructVariant = FlatMapSerializeStructVariantAsMapValue<'a, M>;
+
+    fn serialize_bool(self, _: bool) -> Result<Self::Ok, Self::Error> {
+        Err(self.bad_type(Unsupported::Boolean))
+    }
+
+    fn serialize_i8(self, _: i8) -> Result<Self::Ok, Self::Error> {
+        Err(self.bad_type(Unsupported::Integer))
+    }
+
+    fn serialize_i16(self, _: i16) -> Result<Self::Ok, Self::Error> {
+        Err(self.bad_type(Unsupported::Integer))
+    }
+
+    fn serialize_i32(self, _: i32) -> Result<Self::Ok, Self::Error> {
+        Err(self.bad_type(Unsupported::Integer))
+    }
+
+    fn serialize_i64(self, _: i64) -> Result<Self::Ok, Self::Error> {
+        Err(self.bad_type(Unsupported::Integer))
+    }
+
+    fn serialize_u8(self, _: u8) -> Result<Self::Ok, Self::Error> {
+        Err(self.bad_type(Unsupported::Integer))
+    }
+
+    fn serialize_u16(self, _: u16) -> Result<Self::Ok, Self::Error> {
+        Err(self.bad_type(Unsupported::Integer))
+    }
+
+    fn serialize_u32(self, _: u32) -> Result<Self::Ok, Self::Error> {
+        Err(self.bad_type(Unsupported::Integer))
+    }
+
+    fn serialize_u64(self, _: u64) -> Result<Self::Ok, Self::Error> {
+        Err(self.bad_type(Unsupported::Integer))
+    }
+
+    fn serialize_f32(self, _: f32) -> Result<Self::Ok, Self::Error> {
+        Err(self.bad_type(Unsupported::Float))
+    }
+
+    fn serialize_f64(self, _: f64) -> Result<Self::Ok, Self::Error> {
+        Err(self.bad_type(Unsupported::Float))
+    }
+
+    fn serialize_char(self, _: char) -> Result<Self::Ok, Self::Error> {
+        Err(self.bad_type(Unsupported::Char))
+    }
+
+    fn serialize_str(self, _: &str) -> Result<Self::Ok, Self::Error> {
+        Err(self.bad_type(Unsupported::String))
+    }
+
+    fn serialize_bytes(self, _: &[u8]) -> Result<Self::Ok, Self::Error> {
+        Err(self.bad_type(Unsupported::ByteArray))
+    }
+
+    fn serialize_none(self) -> Result<Self::Ok, Self::Error> {
+        Err(self.bad_type(Unsupported::Optional))
+    }
+
+    fn serialize_some<T: ?Sized>(self, _: &T) -> Result<Self::Ok, Self::Error>
+    where
+        T: Serialize,
+    {
+        Err(self.bad_type(Unsupported::Optional))
+    }
+
+    fn serialize_unit(self) -> Result<Self::Ok, Self::Error> {
+        Err(self.bad_type(Unsupported::Unit))
+    }
+
+    fn serialize_unit_struct(self, _: &'static str) -> Result<Self::Ok, Self::Error> {
+        Err(self.bad_type(Unsupported::UnitStruct))
+    }
+
+    fn serialize_unit_variant(
+        self,
+        _: &'static str,
+        _: u32,
+        _: &'static str,
+    ) -> Result<Self::Ok, Self::Error> {
+        Err(self.bad_type(Unsupported::Enum))
+    }
+
+    fn serialize_newtype_struct<T: ?Sized>(
+        self,
+        _: &'static str,
+        value: &T,
+    ) -> Result<Self::Ok, Self::Error>
+    where
+        T: Serialize,
+    {
+        value.serialize(self)
+    }
+
+    fn serialize_newtype_variant<T: ?Sized>(
+        self,
+        _: &'static str,
+        _: u32,
+        variant: &'static str,
+        value: &T,
+    ) -> Result<Self::Ok, Self::Error>
+    where
+        T: Serialize,
+    {
+        try!(self.0.serialize_key(variant));
+        self.0.serialize_value(value)
+    }
+
+    fn serialize_seq(self, _: Option<usize>) -> Result<Self::SerializeSeq, Self::Error> {
+        Err(self.bad_type(Unsupported::Sequence))
+    }
+
+    fn serialize_tuple(self, _: usize) -> Result<Self::SerializeTuple, Self::Error> {
+        Err(self.bad_type(Unsupported::Tuple))
+    }
+
+    fn serialize_tuple_struct(
+        self,
+        _: &'static str,
+        _: usize,
+    ) -> Result<Self::SerializeTupleStruct, Self::Error> {
+        Err(self.bad_type(Unsupported::TupleStruct))
+    }
+
+    fn serialize_tuple_variant(
+        self,
+        _: &'static str,
+        _: u32,
+        _: &'static str,
+        _: usize,
+    ) -> Result<Self::SerializeTupleVariant, Self::Error> {
+        Err(self.bad_type(Unsupported::Enum))
+    }
+
+    fn serialize_map(self, _: Option<usize>) -> Result<Self::SerializeMap, Self::Error> {
+        Ok(FlatMapSerializeMap(self.0))
+    }
+
+    fn serialize_struct(
+        self,
+        _: &'static str,
+        _: usize,
+    ) -> Result<Self::SerializeStruct, Self::Error> {
+        Ok(FlatMapSerializeStruct(self.0))
+    }
+
+    fn serialize_struct_variant(
+        self,
+        _: &'static str,
+        _: u32,
+        inner_variant: &'static str,
+        _: usize,
+    ) -> Result<Self::SerializeStructVariant, Self::Error> {
+        try!(self.0.serialize_key(inner_variant));
+        Ok(FlatMapSerializeStructVariantAsMapValue::new(self.0, inner_variant))
+    }
+}
+
+#[cfg(any(feature = "std", feature = "alloc"))]
+pub struct FlatMapSerializeMap<'a, M: 'a>(&'a mut M);
+
+#[cfg(any(feature = "std", feature = "alloc"))]
+impl<'a, M> ser::SerializeMap for FlatMapSerializeMap<'a, M>
+    where M: SerializeMap + 'a
+{
+    type Ok = ();
+    type Error = M::Error;
+
+    fn serialize_key<T: ?Sized>(&mut self, key: &T) -> Result<(), Self::Error>
+    where
+        T: Serialize,
+    {
+        self.0.serialize_key(key)
+    }
+
+    fn serialize_value<T: ?Sized>(&mut self, value: &T) -> Result<(), Self::Error>
+    where
+        T: Serialize,
+    {
+        self.0.serialize_value(value)
+    }
+
+    fn end(self) -> Result<(), Self::Error> {
+        Ok(())
+    }
+}
+
+#[cfg(any(feature = "std", feature = "alloc"))]
+pub struct FlatMapSerializeStruct<'a, M: 'a>(&'a mut M);
+
+#[cfg(any(feature = "std", feature = "alloc"))]
+impl<'a, M> ser::SerializeStruct for FlatMapSerializeStruct<'a, M>
+    where M: SerializeMap + 'a
+{
+    type Ok = ();
+    type Error = M::Error;
+
+    fn serialize_field<T: ?Sized>(&mut self, key: &'static str, value: &T) -> Result<(), Self::Error>
+    where
+        T: Serialize,
+    {
+        self.0.serialize_entry(key, value)
+    }
+
+    fn end(self) -> Result<(), Self::Error> {
+        Ok(())
+    }
+}
+
+#[cfg(any(feature = "std", feature = "alloc"))]
+pub struct FlatMapSerializeStructVariantAsMapValue<'a, M: 'a> {
+    map: &'a mut M,
+    name: &'static str,
+    fields: Vec<(&'static str, Content)>,
+}
+
+#[cfg(any(feature = "std", feature = "alloc"))]
+impl<'a, M> FlatMapSerializeStructVariantAsMapValue<'a, M>
+    where M: SerializeMap + 'a
+{
+    fn new(map: &'a mut M, name: &'static str) -> FlatMapSerializeStructVariantAsMapValue<'a, M> {
+        FlatMapSerializeStructVariantAsMapValue {
+            map: map,
+            name: name,
+            fields: Vec::new(),
+        }
+    }
+}
+
+#[cfg(any(feature = "std", feature = "alloc"))]
+impl<'a, M> ser::SerializeStructVariant for FlatMapSerializeStructVariantAsMapValue<'a, M>
+    where M: SerializeMap + 'a
+{
+    type Ok = ();
+    type Error = M::Error;
+
+    fn serialize_field<T: ?Sized>(&mut self, key: &'static str, value: &T) -> Result<(), Self::Error>
+    where
+        T: Serialize,
+    {
+        let value = try!(value.serialize(ContentSerializer::<M::Error>::new()));
+        self.fields.push((key, value));
+        Ok(())
+    }
+
+    fn end(self) -> Result<(), Self::Error> {
+        try!(self.map.serialize_value(&Content::Struct(self.name, self.fields)));
+        Ok(())
+    }
+}
--- a/third_party/rust/serde/src/ser/impls.rs
+++ b/third_party/rust/serde/src/ser/impls.rs
@@ -346,28 +346,55 @@ deref_impl!(<T: ?Sized> Serialize for Rc
 deref_impl!(<T: ?Sized> Serialize for Arc<T> where T: Serialize);
 
 #[cfg(any(feature = "std", feature = "alloc"))]
 deref_impl!(<'a, T: ?Sized> Serialize for Cow<'a, T> where T: Serialize + ToOwned);
 
 ////////////////////////////////////////////////////////////////////////////////
 
 #[cfg(feature = "unstable")]
+#[allow(deprecated)]
 impl<T> Serialize for NonZero<T>
 where
     T: Serialize + Zeroable + Clone,
 {
     fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
     where
         S: Serializer,
     {
         self.clone().get().serialize(serializer)
     }
 }
 
+macro_rules! nonzero_integers {
+    ( $( $T: ident, )+ ) => {
+        $(
+            #[cfg(feature = "unstable")]
+            impl Serialize for $T {
+                fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
+                where
+                    S: Serializer,
+                {
+                    self.get().serialize(serializer)
+                }
+            }
+        )+
+    }
+}
+
+nonzero_integers! {
+    // Not including signed NonZeroI* since they might be removed
+    NonZeroU8,
+    NonZeroU16,
+    NonZeroU32,
+    NonZeroU64,
+    // FIXME: https://github.com/serde-rs/serde/issues/1136 NonZeroU128,
+    NonZeroUsize,
+}
+
 impl<T> Serialize for Cell<T>
 where
     T: Serialize + Copy,
 {
     fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
     where
         S: Serializer,
     {
--- a/third_party/rust/serde/src/ser/mod.rs
+++ b/third_party/rust/serde/src/ser/mod.rs
@@ -88,17 +88,18 @@
 //!    - OsStr
 //!    - OsString
 //!  - **Miscellaneous standard library types**:
 //!    - Duration
 //!    - SystemTime
 //!    - Path
 //!    - PathBuf
 //!    - Range\<T\>
-//!    - NonZero\<T\> (unstable)
+//!    - NonZero\<T\> (unstable, deprecated)
+//!    - num::NonZero* (unstable)
 //!  - **Net types**:
 //!    - IpAddr
 //!    - Ipv4Addr
 //!    - Ipv6Addr
 //!    - SocketAddr
 //!    - SocketAddrV4
 //!    - SocketAddrV6
 //!
--- a/third_party/rust/serde_derive/.cargo-checksum.json
+++ b/third_party/rust/serde_derive/.cargo-checksum.json
@@ -1,1 +1,1 @@
-{"files":{"Cargo.toml":"f4d63b1c5051b3e0e32fe70dabff07245e8d7e89381b1ed99789072083453201","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"6485b8ed310d3f0340bf1ad1f47645069ce4069dcc6bb46c7d5c6faf41de1fdb","README.md":"7dc6376a88195594cd6b43cb891aad10f57144ff737178b55d046aa04739b43a","src/bound.rs":"a10e5a103ce3866f8701e80c429106aa6b67b8250026ed2c0d36977748d4cc97","src/de.rs":"991ec19db1b486c2e91bce3f097f8f247ab6122eb8900a2c9267fa9c9e493417","src/fragment.rs":"5a63181171d4d05cea9f28d8ed27a550bc8ac176ee90a911a0598fbe340eec1a","src/lib.rs":"40817849b19a73459fbe5955cf22fb73f634e54df53bb309a0b6e4750b310ea6","src/ser.rs":"0ca344ccbe227f99bb875fe583b97757beb8233dc39acb1836782937c9036bd6"},"package":null}
\ No newline at end of file
+{"files":{"Cargo.toml":"cca09c175616b8390468aae4db4cb82688934de6f9e8bb70d7765e775d1304c9","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"6485b8ed310d3f0340bf1ad1f47645069ce4069dcc6bb46c7d5c6faf41de1fdb","README.md":"7dc6376a88195594cd6b43cb891aad10f57144ff737178b55d046aa04739b43a","src/bound.rs":"44373ac15601ad92d7862fa33b59219bce111a5d3d8a1de6386e3490a8e4fbf5","src/de.rs":"fbe74de7a3bbcfe2128f016782d24b0ba925f7976563766f728744889d107020","src/fragment.rs":"4e34eca12e6ac4bd89f55e85786cfb677e98182f21ce1f51c0573bca5a8bcd27","src/lib.rs":"389815c14539bc1b394a53fd838a2d97d10def55acf034b67e87435c9d8287fa","src/ser.rs":"190bd80a820cf05155506c34bf5f512c26bae10f67b5877929b0b859d70a8431"},"package":null}
\ No newline at end of file
--- a/third_party/rust/serde_derive/Cargo.toml
+++ b/third_party/rust/serde_derive/Cargo.toml
@@ -1,11 +1,11 @@
 [package]
 name = "serde_derive"
-version = "1.0.27" # remember to update html_root_url
+version = "1.0.35" # remember to update html_root_url
 authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>", "David Tolnay <dtolnay@gmail.com>"]
 license = "MIT/Apache-2.0"
 description = "Macros 1.1 implementation of #[derive(Serialize, Deserialize)]"
 homepage = "https://serde.rs"
 repository = "https://github.com/serde-rs/serde"
 documentation = "https://serde.rs/codegen.html"
 keywords = ["serde", "serialization", "no_std"]
 readme = "README.md"
@@ -18,14 +18,15 @@ travis-ci = { repository = "serde-rs/ser
 default = []
 deserialize_in_place = []
 
 [lib]
 name = "serde_derive"
 proc-macro = true
 
 [dependencies]
-quote = "0.3.8"
-serde_derive_internals = { version = "=0.19.0", default-features = false, path = "../serde_derive_internals" }
-syn = { version = "0.11", features = ["visit"] }
+proc-macro2 = "0.2"
+quote = "0.4"
+serde_derive_internals = { version = "=0.22.1", default-features = false, path = "../serde_derive_internals" }
+syn = { version = "0.12", features = ["visit"] }
 
 [dev-dependencies]
 serde = { version = "1.0", path = "../serde" }
--- a/third_party/rust/serde_derive/src/bound.rs
+++ b/third_party/rust/serde_derive/src/bound.rs
@@ -4,70 +4,90 @@
 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
 use std::collections::HashSet;
 
 use syn::{self, visit};
+use syn::punctuated::Punctuated;
 
-use internals::ast::{Body, Container};
+use internals::ast::{Data, Container};
 use internals::attr;
 
-macro_rules! path {
-    ($($path:tt)+) => {
-        syn::parse_path(quote!($($path)+).as_str()).unwrap()
-    };
-}
+use proc_macro2::{Span, Term};
 
 // Remove the default from every type parameter because in the generated impls
 // they look like associated types: "error: associated type bindings are not
 // allowed here".
 pub fn without_defaults(generics: &syn::Generics) -> syn::Generics {
     syn::Generics {
-        ty_params: generics
-            .ty_params
+        params: generics
+            .params
             .iter()
-            .map(|ty_param| syn::TyParam {
-                default: None,
-                ..ty_param.clone()
+            .map(|param| match *param {
+                syn::GenericParam::Type(ref param) => {
+                    syn::GenericParam::Type(syn::TypeParam {
+                        eq_token: None,
+                        default: None,
+                        ..param.clone()
+                    })
+                }
+                _ => param.clone(),
             })
             .collect(),
         ..generics.clone()
     }
 }
 
 pub fn with_where_predicates(
     generics: &syn::Generics,
     predicates: &[syn::WherePredicate],
 ) -> syn::Generics {
     let mut generics = generics.clone();
-    generics
-        .where_clause
+    if generics.where_clause.is_none() {
+        generics.where_clause = Some(syn::WhereClause {
+            where_token: Default::default(),
+            predicates: Punctuated::new(),
+        });
+    }
+    generics.where_clause
+        .as_mut()
+        .unwrap()
         .predicates
-        .extend_from_slice(predicates);
+        .extend(predicates.into_iter().cloned());
     generics
 }
 
 pub fn with_where_predicates_from_fields<F>(
     cont: &Container,
     generics: &syn::Generics,
     from_field: F,
 ) -> syn::Generics
 where
     F: Fn(&attr::Field) -> Option<&[syn::WherePredicate]>,
 {
-    let predicates = cont.body
+    let predicates = cont.data
         .all_fields()
         .flat_map(|field| from_field(&field.attrs))
         .flat_map(|predicates| predicates.to_vec());
 
     let mut generics = generics.clone();
-    generics.where_clause.predicates.extend(predicates);
+    if generics.where_clause.is_none() {
+        generics.where_clause = Some(syn::WhereClause {
+            where_token: Default::default(),
+            predicates: Punctuated::new(),
+        });
+    }
+    generics.where_clause
+        .as_mut()
+        .unwrap()
+        .predicates
+        .extend(predicates);
     generics
 }
 
 // Puts the given bound on any generic type parameters that are used in fields
 // for which filter returns true.
 //
 // For example, the following struct needs the bound `A: Serialize, B: Serialize`.
 //
@@ -90,169 +110,213 @@ where
         // Set of all generic type parameters on the current struct (A, B, C in
         // the example). Initialized up front.
         all_ty_params: HashSet<syn::Ident>,
         // Set of generic type parameters used in fields for which filter
         // returns true (A and B in the example). Filled in as the visitor sees
         // them.
         relevant_ty_params: HashSet<syn::Ident>,
     }
-    impl visit::Visitor for FindTyParams {
+    impl<'ast> visit::Visit<'ast> for FindTyParams {
         fn visit_path(&mut self, path: &syn::Path) {
             if let Some(seg) = path.segments.last() {
-                if seg.ident == "PhantomData" {
+                if seg.into_value().ident == "PhantomData" {
                     // Hardcoded exception, because PhantomData<T> implements
                     // Serialize and Deserialize whether or not T implements it.
                     return;
                 }
             }
-            if !path.global && path.segments.len() == 1 {
-                let id = path.segments[0].ident.clone();
+            if path.leading_colon.is_none() && path.segments.len() == 1 {
+                let id = path.segments[0].ident;
                 if self.all_ty_params.contains(&id) {
                     self.relevant_ty_params.insert(id);
                 }
             }
-            visit::walk_path(self, path);
+            visit::visit_path(self, path);
         }
 
         // Type parameter should not be considered used by a macro path.
         //
         //     struct TypeMacro<T> {
         //         mac: T!(),
         //         marker: PhantomData<T>,
         //     }
-        fn visit_mac(&mut self, _mac: &syn::Mac) {}
+        fn visit_macro(&mut self, _mac: &syn::Macro) {}
     }
 
     let all_ty_params: HashSet<_> = generics
-        .ty_params
+        .params
         .iter()
-        .map(|ty_param| ty_param.ident.clone())
+        .filter_map(|param| match *param {
+            syn::GenericParam::Type(ref param) => Some(param.ident),
+            _ => None,
+        })
         .collect();
 
     let mut visitor = FindTyParams {
         all_ty_params: all_ty_params,
         relevant_ty_params: HashSet::new(),
     };
-    match cont.body {
-        Body::Enum(_, ref variants) => for variant in variants.iter() {
+    match cont.data {
+        Data::Enum(_, ref variants) => for variant in variants.iter() {
             let relevant_fields = variant
                 .fields
                 .iter()
                 .filter(|field| filter(&field.attrs, Some(&variant.attrs)));
             for field in relevant_fields {
-                visit::walk_ty(&mut visitor, field.ty);
+                visit::visit_type(&mut visitor, field.ty);
             }
         },
-        Body::Struct(_, ref fields) => {
+        Data::Struct(_, ref fields) => {
             for field in fields.iter().filter(|field| filter(&field.attrs, None)) {
-                visit::walk_ty(&mut visitor, field.ty);
+                visit::visit_type(&mut visitor, field.ty);
             }
         }
     }
 
     let new_predicates = generics
-        .ty_params
+        .params
         .iter()
-        .map(|ty_param| ty_param.ident.clone())
+        .filter_map(|param| match *param {
+            syn::GenericParam::Type(ref param) => Some(param.ident),
+            _ => None,
+        })
         .filter(|id| visitor.relevant_ty_params.contains(id))
         .map(|id| {
-            syn::WherePredicate::BoundPredicate(syn::WhereBoundPredicate {
-                bound_lifetimes: Vec::new(),
+            syn::WherePredicate::Type(syn::PredicateType {
+                lifetimes: None,
                 // the type parameter that is being bounded e.g. T
-                bounded_ty: syn::Ty::Path(None, id.into()),
+                bounded_ty: syn::Type::Path(syn::TypePath {
+                    qself: None,
+                    path: id.into(),
+                }),
+                colon_token: Default::default(),
                 // the bound e.g. Serialize
                 bounds: vec![
-                    syn::TyParamBound::Trait(
-                        syn::PolyTraitRef {
-                            bound_lifetimes: Vec::new(),
-                            trait_ref: bound.clone(),
-                        },
-                        syn::TraitBoundModifier::None,
-                    ),
-                ],
+                    syn::TypeParamBound::Trait(syn::TraitBound {
+                        modifier: syn::TraitBoundModifier::None,
+                        lifetimes: None,
+                        path: bound.clone(),
+                    }),
+                ].into_iter().collect(),
             })
         });
 
     let mut generics = generics.clone();
-    generics.where_clause.predicates.extend(new_predicates);
+    if generics.where_clause.is_none() {
+        generics.where_clause = Some(syn::WhereClause {
+            where_token: Default::default(),
+            predicates: Punctuated::new(),
+        });
+    }
+    generics.where_clause
+        .as_mut()
+        .unwrap()
+        .predicates
+        .extend(new_predicates);
     generics
 }
 
 pub fn with_self_bound(
     cont: &Container,
     generics: &syn::Generics,
     bound: &syn::Path,
 ) -> syn::Generics {
     let mut generics = generics.clone();
-    generics
-        .where_clause
+    if generics.where_clause.is_none() {
+        generics.where_clause = Some(syn::WhereClause {
+            where_token: Default::default(),
+            predicates: Punctuated::new(),
+        });
+    }
+    generics.where_clause
+        .as_mut()
+        .unwrap()
         .predicates
-        .push(syn::WherePredicate::BoundPredicate(
-            syn::WhereBoundPredicate {
-                bound_lifetimes: Vec::new(),
-                // the type that is being bounded e.g. MyStruct<'a, T>
-                bounded_ty: type_of_item(cont),
-                // the bound e.g. Default
-                bounds: vec![
-                    syn::TyParamBound::Trait(
-                        syn::PolyTraitRef {
-                            bound_lifetimes: Vec::new(),
-                            trait_ref: bound.clone(),
-                        },
-                        syn::TraitBoundModifier::None,
-                    ),
-                ],
-            },
-        ));
+        .push(syn::WherePredicate::Type(syn::PredicateType {
+            lifetimes: None,
+            // the type that is being bounded e.g. MyStruct<'a, T>
+            bounded_ty: type_of_item(cont),
+            colon_token: Default::default(),
+            // the bound e.g. Default
+            bounds: vec![
+                syn::TypeParamBound::Trait(syn::TraitBound {
+                    modifier: syn::TraitBoundModifier::None,
+                    lifetimes: None,
+                    path: bound.clone(),
+                }),
+            ].into_iter().collect(),
+        }));
     generics
 }
 
 pub fn with_lifetime_bound(generics: &syn::Generics, lifetime: &str) -> syn::Generics {
-    let mut generics = generics.clone();
-
-    for lifetime_def in &mut generics.lifetimes {
-        lifetime_def.bounds.push(syn::Lifetime::new(lifetime));
-    }
+    let bound = syn::Lifetime::new(Term::intern(lifetime), Span::def_site());
+    let def = syn::LifetimeDef {
+        attrs: Vec::new(),
+        lifetime: bound,
+        colon_token: None,
+        bounds: Punctuated::new(),
+    };
 
-    for ty_param in &mut generics.ty_params {
-        ty_param
-            .bounds
-            .push(syn::TyParamBound::Region(syn::Lifetime::new(lifetime)));
-    }
+    let params = Some(syn::GenericParam::Lifetime(def))
+        .into_iter()
+        .chain(generics.params
+            .iter()
+            .cloned()
+            .map(|mut param| {
+                match param {
+                    syn::GenericParam::Lifetime(ref mut param) => {
+                        param.bounds.push(bound);
+                    }
+                    syn::GenericParam::Type(ref mut param) => {
+                        param.bounds.push(syn::TypeParamBound::Lifetime(bound));
+                    }
+                    syn::GenericParam::Const(_) => {}
+                }
+                param
+            }))
+        .collect();
 
-    generics.lifetimes.push(syn::LifetimeDef {
-        attrs: Vec::new(),
-        lifetime: syn::Lifetime::new(lifetime),
-        bounds: Vec::new(),
-    });
-
-    generics
+    syn::Generics {
+        params: params,
+        ..generics.clone()
+    }
 }
 
-fn type_of_item(cont: &Container) -> syn::Ty {
-    syn::Ty::Path(
-        None,
-        syn::Path {
-            global: false,
+fn type_of_item(cont: &Container) -> syn::Type {
+    syn::Type::Path(syn::TypePath {
+        qself: None,
+        path: syn::Path {
+            leading_colon: None,
             segments: vec![
                 syn::PathSegment {
-                    ident: cont.ident.clone(),
-                    parameters: syn::PathParameters::AngleBracketed(
-                        syn::AngleBracketedParameterData {
-                            lifetimes: cont.generics
-                                .lifetimes
+                    ident: cont.ident,
+                    arguments: syn::PathArguments::AngleBracketed(
+                        syn::AngleBracketedGenericArguments {
+                            colon2_token: None,
+                            lt_token: Default::default(),
+                            args: cont.generics
+                                .params
                                 .iter()
-                                .map(|def| def.lifetime.clone())
+                                .map(|param| match *param {
+                                    syn::GenericParam::Type(ref param) => {
+                                        syn::GenericArgument::Type(syn::Type::Path(syn::TypePath {
+                                            qself: None,
+                                            path: param.ident.into(),
+                                        }))
+                                    }
+                                    syn::GenericParam::Lifetime(ref param) => {
+                                        syn::GenericArgument::Lifetime(param.lifetime)
+                                    }
+                                    syn::GenericParam::Const(_) => {
+                                        panic!("Serde does not support const generics yet");
+                                    }
+                                })
                                 .collect(),
-                            types: cont.generics
-                                .ty_params
-                                .iter()
-                                .map(|param| syn::Ty::Path(None, param.ident.clone().into()))
-                                .collect(),
-                            bindings: Vec::new(),
+                            gt_token: Default::default(),
                         },
                     ),
                 },
-            ],
+            ].into_iter().collect(),
         },
-    )
+    })
 }
--- a/third_party/rust/serde_derive/src/de.rs
+++ b/third_party/rust/serde_derive/src/de.rs
@@ -1,47 +1,51 @@
 // Copyright 2017 Serde Developers
 //
 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use syn::{self, Ident};
-use quote::{self, ToTokens, Tokens};
+use syn::{self, Ident, Index, Member};
+use syn::punctuated::Punctuated;
+use syn::spanned::Spanned;
+use quote::{ToTokens, Tokens};
+use proc_macro2::{Literal, Span, Term};
 
 use bound;
 use fragment::{Expr, Fragment, Match, Stmts};
-use internals::ast::{Body, Container, Field, Style, Variant};
+use internals::ast::{Data, Container, Field, Style, Variant};
 use internals::{self, attr};
 
 #[cfg(feature = "deserialize_in_place")]
 use internals::ast::Repr;
 
 
 use std::collections::BTreeSet;
 
 pub fn expand_derive_deserialize(input: &syn::DeriveInput) -> Result<Tokens, String> {
     let ctxt = internals::Ctxt::new();
     let cont = Container::from_ast(&ctxt, input);
     try!(ctxt.check());
 
     let ident = &cont.ident;
     let params = Parameters::new(&cont);
     let (de_impl_generics, _, ty_generics, where_clause) = split_with_de_lifetime(&params);
-    let dummy_const = Ident::new(format!("_IMPL_DESERIALIZE_FOR_{}", ident));
+    let dummy_const = Ident::new(&format!("_IMPL_DESERIALIZE_FOR_{}", ident), Span::def_site());
     let body = Stmts(deserialize_body(&cont, &params));
     let delife = params.borrowed.de_lifetime();
 
     let impl_block = if let Some(remote) = cont.attrs.remote() {
         let vis = &input.vis;
+        let fun = quote_spanned!(Span::call_site()=> deserialize);
         quote! {
             impl #de_impl_generics #ident #ty_generics #where_clause {
-                #vis fn deserialize<__D>(__deserializer: __D) -> _serde::export::Result<#remote #ty_generics, __D::Error>
+                #vis fn #fun<__D>(__deserializer: __D) -> _serde::export::Result<#remote #ty_generics, __D::Error>
                     where __D: _serde::Deserializer<#delife>
                 {
                     #body
                 }
             }
         }
     } else {
         let fn_deserialize_in_place = deserialize_in_place_body(&cont, &params);
@@ -89,72 +93,72 @@ struct Parameters {
 
     /// At least one field has a serde(getter) attribute, implying that the
     /// remote type has a private field.
     has_getter: bool,
 }
 
 impl Parameters {
     fn new(cont: &Container) -> Self {
-        let local = cont.ident.clone();
+        let local = cont.ident;
         let this = match cont.attrs.remote() {
             Some(remote) => remote.clone(),
-            None => cont.ident.clone().into(),
+            None => cont.ident.into(),
         };
         let borrowed = borrowed_lifetimes(cont);
         let generics = build_generics(cont, &borrowed);
-        let has_getter = cont.body.has_getter();
+        let has_getter = cont.data.has_getter();
 
         Parameters {
             local: local,
             this: this,
             generics: generics,
             borrowed: borrowed,
             has_getter: has_getter,
         }
     }
 
     /// Type name to use in error messages and `&'static str` arguments to
     /// various Deserializer methods.
     fn type_name(&self) -> &str {
-        self.this.segments.last().unwrap().ident.as_ref()
+        self.this.segments.last().unwrap().value().ident.as_ref()
     }
 }
 
 // All the generics in the input, plus a bound `T: Deserialize` for each generic
 // field type that will be deserialized by us, plus a bound `T: Default` for
 // each generic field type that will be set to a default value.
 fn build_generics(cont: &Container, borrowed: &BorrowedLifetimes) -> syn::Generics {
     let generics = bound::without_defaults(cont.generics);
 
     let generics = bound::with_where_predicates_from_fields(cont, &generics, attr::Field::de_bound);
 
     match cont.attrs.de_bound() {
         Some(predicates) => bound::with_where_predicates(&generics, predicates),
         None => {
             let generics = match *cont.attrs.default() {
                 attr::Default::Default => {
-                    bound::with_self_bound(cont, &generics, &path!(_serde::export::Default))
+                    bound::with_self_bound(cont, &generics, &parse_quote!(_serde::export::Default))
                 }
                 attr::Default::None | attr::Default::Path(_) => generics,
             };
 
             let delife = borrowed.de_lifetime();
             let generics = bound::with_bound(
                 cont,
                 &generics,
                 needs_deserialize_bound,
-                &path!(_serde::Deserialize<#delife>),
+                &parse_quote!(_serde::Deserialize<#delife>),
             );
 
             bound::with_bound(
                 cont,
                 &generics,
                 requires_default,
-                &path!(_serde::export::Default),
+                &parse_quote!(_serde::export::Default),
             )
         }
     }
 }
 
 // Fields with a `skip_deserializing` or `deserialize_with` attribute are not
 // deserialized by us so we do not generate a bound. Fields with a `bound`
 // attribute specify their own bound so we do not generate one. All other fields
@@ -162,38 +166,43 @@ fn build_generics(cont: &Container, borr
 fn needs_deserialize_bound(field: &attr::Field, variant: Option<&attr::Variant>) -> bool {
     !field.skip_deserializing() && field.deserialize_with().is_none() && field.de_bound().is_none()
         && variant.map_or(true, |variant| variant.deserialize_with().is_none())
 }
 
 // Fields with a `default` attribute (not `default=...`), and fields with a
 // `skip_deserializing` attribute that do not also have `default=...`.
 fn requires_default(field: &attr::Field, _variant: Option<&attr::Variant>) -> bool {
-    field.default() == &attr::Default::Default
+    if let attr::Default::Default = *field.default() {
+        true
+    } else {
+        false
+    }
 }
 
 #[derive(Clone)]
 enum BorrowedLifetimes {
     Borrowed(BTreeSet<syn::Lifetime>),
     Static,
 }
 
 impl BorrowedLifetimes {
     fn de_lifetime(&self) -> syn::Lifetime {
         match *self {
-            BorrowedLifetimes::Borrowed(_) => syn::Lifetime::new("'de"),
-            BorrowedLifetimes::Static => syn::Lifetime::new("'static"),
+            BorrowedLifetimes::Borrowed(_) => syn::Lifetime::new(Term::intern("'de"), Span::def_site()),
+            BorrowedLifetimes::Static => syn::Lifetime::new(Term::intern("'static"), Span::def_site()),
         }
     }
 
     fn de_lifetime_def(&self) -> Option<syn::LifetimeDef> {
         match *self {
             BorrowedLifetimes::Borrowed(ref bounds) => Some(syn::LifetimeDef {
                 attrs: Vec::new(),
-                lifetime: syn::Lifetime::new("'de"),
+                lifetime: syn::Lifetime::new(Term::intern("'de"), Span::def_site()),
+                colon_token: None,
                 bounds: bounds.iter().cloned().collect(),
             }),
             BorrowedLifetimes::Static => None,
         }
     }
 }
 
 // The union of lifetimes borrowed by each field of the container.
@@ -202,87 +211,91 @@ impl BorrowedLifetimes {
 // lifetimes `'a` and `'b` are borrowed but `'c` is not, the impl is:
 //
 //     impl<'de: 'a + 'b, 'a, 'b, 'c> Deserialize<'de> for S<'a, 'b, 'c>
 //
 // If any borrowed lifetime is `'static`, then `'de: 'static` would be redundant
 // and we use plain `'static` instead of `'de`.
 fn borrowed_lifetimes(cont: &Container) -> BorrowedLifetimes {
     let mut lifetimes = BTreeSet::new();
-    for field in cont.body.all_fields() {
+    for field in cont.data.all_fields() {
         if !field.attrs.skip_deserializing() {
             lifetimes.extend(field.attrs.borrowed_lifetimes().iter().cloned());
         }
     }
-    if lifetimes.iter().any(|b| b.ident == "'static") {
+    if lifetimes.iter().any(|b| b.to_string() == "'static") {
         BorrowedLifetimes::Static
     } else {
         BorrowedLifetimes::Borrowed(lifetimes)
     }
 }
 
 fn deserialize_body(cont: &Container, params: &Parameters) -> Fragment {
-    if let Some(from_type) = cont.attrs.from_type() {
-        deserialize_from(from_type)
+    if let Some(type_from) = cont.attrs.type_from() {
+        deserialize_from(type_from)
     } else if let attr::Identifier::No = cont.attrs.identifier() {
-        match cont.body {
-            Body::Enum(_, ref variants) => deserialize_enum(params, variants, &cont.attrs),
-            Body::Struct(Style::Struct, ref fields) => {
+        match cont.data {
+            Data::Enum(_, ref variants) => deserialize_enum(params, variants, &cont.attrs),
+            Data::Struct(Style::Struct, ref fields) => {
                 if fields.iter().any(|field| field.ident.is_none()) {
                     panic!("struct has unnamed fields");
                 }
-                deserialize_struct(None, params, fields, &cont.attrs, None, Untagged::No)
+                deserialize_struct(None, params, fields, &cont.attrs, None, &Untagged::No)
             }
-            Body::Struct(Style::Tuple, ref fields) | Body::Struct(Style::Newtype, ref fields) => {
+            Data::Struct(Style::Tuple, ref fields) | Data::Struct(Style::Newtype, ref fields) => {
                 if fields.iter().any(|field| field.ident.is_some()) {
                     panic!("tuple struct has named fields");
                 }
                 deserialize_tuple(None, params, fields, &cont.attrs, None)
             }
-            Body::Struct(Style::Unit, _) => deserialize_unit_struct(params, &cont.attrs),
+            Data::Struct(Style::Unit, _) => deserialize_unit_struct(params, &cont.attrs),
         }
     } else {
-        match cont.body {
-            Body::Enum(_, ref variants) => {
+        match cont.data {
+            Data::Enum(_, ref variants) => {
                 deserialize_custom_identifier(params, variants, &cont.attrs)
             }
-            Body::Struct(_, _) => unreachable!("checked in serde_derive_internals"),
+            Data::Struct(_, _) => unreachable!("checked in serde_derive_internals"),
         }
     }
 }
 
 #[cfg(feature = "deserialize_in_place")]
 fn deserialize_in_place_body(cont: &Container, params: &Parameters) -> Option<Stmts> {
     // Only remote derives have getters, and we do not generate
     // deserialize_in_place for remote derives.
     assert!(!params.has_getter);
 
-    if cont.attrs.from_type().is_some() || cont.attrs.identifier().is_some()
-        || cont.body
+    if cont.attrs.type_from().is_some() || cont.attrs.identifier().is_some()
+        || cont.data
             .all_fields()
             .all(|f| f.attrs.deserialize_with().is_some())
     {
         return None;
     }
 
-    let code = match cont.body {
-        Body::Struct(Style::Struct, ref fields) => {
-            deserialize_struct_in_place(None, params, fields, &cont.attrs, None, Untagged::No)
+    let code = match cont.data {
+        Data::Struct(Style::Struct, ref fields) => {
+            if let Some(code) = deserialize_struct_in_place(None, params, fields, &cont.attrs, None) {
+                code
+            } else {
+                return None;
+            }
         }
-        Body::Struct(Style::Tuple, ref fields) | Body::Struct(Style::Newtype, ref fields) => {
+        Data::Struct(Style::Tuple, ref fields) | Data::Struct(Style::Newtype, ref fields) => {
             deserialize_tuple_in_place(None, params, fields, &cont.attrs, None)
         }
-        Body::Enum(ref repr, ref variants) => {
+        Data::Enum(ref repr, ref variants) => {
             if let Some(x) = deserialize_enum_in_place(params, repr, variants, &cont.attrs) {
                 x
             } else {
                 return None;
             }
         }
-        Body::Struct(Style::Unit, _) => {
+        Data::Struct(Style::Unit, _) => {
             return None;
         }
     };
 
     let delife = params.borrowed.de_lifetime();
     let stmts = Stmts(code);
 
     let fn_deserialize_in_place = quote_block! {
@@ -296,20 +309,20 @@ fn deserialize_in_place_body(cont: &Cont
     Some(Stmts(fn_deserialize_in_place))
 }
 
 #[cfg(not(feature = "deserialize_in_place"))]
 fn deserialize_in_place_body(_cont: &Container, _params: &Parameters) -> Option<Stmts> {
     None
 }
 
-fn deserialize_from(from_type: &syn::Ty) -> Fragment {
+fn deserialize_from(type_from: &syn::Type) -> Fragment {
     quote_block! {
         _serde::export::Result::map(
-            <#from_type as _serde::Deserialize>::deserialize(__deserializer),
+            <#type_from as _serde::Deserialize>::deserialize(__deserializer),
             _serde::export::From::from)
     }
 }
 
 fn deserialize_unit_struct(params: &Parameters, cattrs: &attr::Container) -> Fragment {
     let this = &params.this;
     let type_name = cattrs.name().deserialize_name();
 
@@ -344,16 +357,18 @@ fn deserialize_tuple(
     cattrs: &attr::Container,
     deserializer: Option<Tokens>,
 ) -> Fragment {
     let this = &params.this;
     let (de_impl_generics, de_ty_generics, ty_generics, where_clause) =
         split_with_de_lifetime(params);
     let delife = params.borrowed.de_lifetime();
 
+    assert!(!cattrs.has_flatten());
+
     // If there are getters (implying private fields), construct the local type
     // and use an `Into` conversion to get the remote type. If there are no
     // getters then construct the target type directly.
     let construct = if params.has_getter {
         let local = &params.local;
         quote!(#local)
     } else {
         quote!(#this)
@@ -439,16 +454,18 @@ fn deserialize_tuple_in_place(
     cattrs: &attr::Container,
     deserializer: Option<Tokens>,
 ) -> Fragment {
     let this = &params.this;
     let (de_impl_generics, de_ty_generics, ty_generics, where_clause) =
         split_with_de_lifetime(params);
     let delife = params.borrowed.de_lifetime();
 
+    assert!(!cattrs.has_flatten());
+
     let is_enum = variant_ident.is_some();
     let expecting = match variant_ident {
         Some(variant_ident) => format!("tuple variant {}::{}", params.type_name(), variant_ident),
         None => format!("tuple struct {}", params.type_name()),
     };
 
     let nfields = fields.len();
 
@@ -530,34 +547,38 @@ fn deserialize_seq(
     type_path: &Tokens,
     params: &Parameters,
     fields: &[Field],
     is_struct: bool,
     cattrs: &attr::Container,
 ) -> Fragment {
     let vars = (0..fields.len()).map(field_i as fn(_) -> _);
 
+    // XXX: do we need an error for flattening here?
+
     let deserialized_count = fields
         .iter()
         .filter(|field| !field.attrs.skip_deserializing())
         .count();
     let expecting = format!("tuple of {} elements", deserialized_count);
 
     let mut index_in_seq = 0usize;
     let let_values = vars.clone().zip(fields).map(|(var, field)| {
         if field.attrs.skip_deserializing() {
-            let default = Expr(expr_is_missing(&field, cattrs));
+            let default = Expr(expr_is_missing(field, cattrs));
             quote! {
                 let #var = #default;
             }
         } else {
             let visit = match field.attrs.deserialize_with() {
                 None => {
                     let field_ty = &field.ty;
-                    quote!(try!(_serde::de::SeqAccess::next_element::<#field_ty>(&mut __seq)))
+                    let span = Span::def_site().located_at(field.original.span());
+                    let func = quote_spanned!(span=> _serde::de::SeqAccess::next_element::<#field_ty>);
+                    quote!(try!(#func(&mut __seq)))
                 }
                 Some(path) => {
                     let (wrapper, wrapper_ty) = wrap_deserialize_field_with(params, field.ty, path);
                     quote!({
                         #wrapper
                         _serde::export::Option::map(
                             try!(_serde::de::SeqAccess::next_element::<#wrapper_ty>(&mut __seq)),
                             |__wrap| __wrap.value)
@@ -574,21 +595,21 @@ fn deserialize_seq(
             };
             index_in_seq += 1;
             assign
         }
     });
 
     let mut result = if is_struct {
         let names = fields.iter().map(|f| &f.ident);
-        quote! {
+        quote_spanned! {Span::call_site()=>
             #type_path { #( #names: #vars ),* }
         }
     } else {
-        quote! {
+        quote_spanned! {Span::call_site()=>
             #type_path ( #(#vars),* )
         }
     };
 
     if params.has_getter {
         let this = &params.this;
         result = quote! {
             _serde::export::Into::<#this>::into(#result)
@@ -627,60 +648,66 @@ fn deserialize_seq_in_place(
     // so we need to bump all the indices up by 1.
     let index_names = if increment_fields {
         (0..fields.len())
     } else {
         (1..fields.len() + 1)
     };
     let vars = index_names.map(field_i as fn(_) -> _);
 
+    // XXX: do we need an error for flattening here?
+
     let deserialized_count = fields
         .iter()
         .filter(|field| !field.attrs.skip_deserializing())
         .count();
     let expecting = format!("tuple of {} elements", deserialized_count);
 
     let mut index_in_seq = 0usize;
     let write_values = vars.clone()
         .zip(fields)
         .enumerate()
         .map(|(field_index, (_, field))| {
             // If there's no field name, assume we're a tuple-struct and use a numeric index
             let field_name = field
                 .ident
-                .clone()
-                .unwrap_or_else(|| Ident::new(field_index.to_string()));
-
+                .map(Member::Named)
+                .unwrap_or_else(|| Member::Unnamed(Index {
+                    index: field_index as u32,
+                    span: Span::call_site(),
+                }));
+
+            let dot = quote_spanned!(Span::call_site()=> .);
             if field.attrs.skip_deserializing() {
-                let default = Expr(expr_is_missing(&field, cattrs));
+                let default = Expr(expr_is_missing(field, cattrs));
                 quote! {
-                    self.place.#field_name = #default;
+                    self.place #dot #field_name = #default;
                 }
             } else {
                 let return_invalid_length = quote! {
                     return _serde::export::Err(_serde::de::Error::invalid_length(#index_in_seq, &#expecting));
                 };
                 let write = match field.attrs.deserialize_with() {
                     None => {
                         quote! {
                             if let _serde::export::None = try!(_serde::de::SeqAccess::next_element_seed(&mut __seq,
-                                _serde::private::de::InPlaceSeed(&mut self.place.#field_name)))
+                                _serde::private::de::InPlaceSeed(&mut self.place #dot #field_name)))
                             {
                                 #return_invalid_length
                             }
                         }
                     }
                     Some(path) => {
                         let (wrapper, wrapper_ty) =
                             wrap_deserialize_field_with(params, field.ty, path);
                         quote!({
                             #wrapper
                             match try!(_serde::de::SeqAccess::next_element::<#wrapper_ty>(&mut __seq)) {
                                 _serde::export::Some(__wrap) => {
-                                    self.place.#field_name = __wrap.value;
+                                    self.place #dot #field_name = __wrap.value;
                                 }
                                 _serde::export::None => {
                                     #return_invalid_length
                                 }
                             }
                         })
                     }
                 };
@@ -726,17 +753,17 @@ fn deserialize_newtype_struct(type_path:
             let (wrapper, wrapper_ty) = wrap_deserialize_field_with(params, field.ty, path);
             quote!({
                 #wrapper
                 try!(<#wrapper_ty as _serde::Deserialize>::deserialize(__e)).value
             })
         }
     };
 
-    let mut result = quote!(#type_path(#value));
+    let mut result = quote_spanned!(Span::call_site()=> #type_path(#value));
     if params.has_getter {
         let this = &params.this;
         result = quote! {
             _serde::export::Into::<#this>::into(#result)
         };
     }
 
     quote! {
@@ -751,38 +778,39 @@ fn deserialize_newtype_struct(type_path:
 
 #[cfg(feature = "deserialize_in_place")]
 fn deserialize_newtype_struct_in_place(params: &Parameters, field: &Field) -> Tokens {
     // We do not generate deserialize_in_place if every field has a deserialize_with.
     assert!(field.attrs.deserialize_with().is_none());
 
     let delife = params.borrowed.de_lifetime();
 
+    let elem = quote_spanned!(Span::call_site()=> .0);
     quote! {
         #[inline]
         fn visit_newtype_struct<__E>(self, __e: __E) -> _serde::export::Result<Self::Value, __E::Error>
             where __E: _serde::Deserializer<#delife>
         {
-            _serde::Deserialize::deserialize_in_place(__e, &mut self.place.0)
+            _serde::Deserialize::deserialize_in_place(__e, &mut self.place #elem)
         }
     }
 }
 
 enum Untagged {
     Yes,
     No,
 }
 
 fn deserialize_struct(
     variant_ident: Option<&syn::Ident>,
     params: &Parameters,
     fields: &[Field],
     cattrs: &attr::Container,
     deserializer: Option<Tokens>,
-    untagged: Untagged,
+    untagged: &Untagged,
 ) -> Fragment {
     let is_enum = variant_ident.is_some();
 
     let this = &params.this;
     let (de_impl_generics, de_ty_generics, ty_generics, where_clause) =
         split_with_de_lifetime(params);
     let delife = params.borrowed.de_lifetime();
 
@@ -802,61 +830,69 @@ fn deserialize_struct(
     };
     let expecting = match variant_ident {
         Some(variant_ident) => format!("struct variant {}::{}", params.type_name(), variant_ident),
         None => format!("struct {}", params.type_name()),
     };
 
     let visit_seq = Stmts(deserialize_seq(&type_path, params, fields, true, cattrs));
 
-    let (field_visitor, fields_stmt, visit_map) =
-        deserialize_struct_visitor(type_path, params, fields, cattrs);
+    let (field_visitor, fields_stmt, visit_map) = if cattrs.has_flatten() {
+        deserialize_struct_as_map_visitor(&type_path, params, fields, cattrs)
+    } else {
+        deserialize_struct_as_struct_visitor(&type_path, params, fields, cattrs)
+    };
     let field_visitor = Stmts(field_visitor);
-    let fields_stmt = Stmts(fields_stmt);
+    let fields_stmt = fields_stmt.map(Stmts);
     let visit_map = Stmts(visit_map);
 
     let visitor_expr = quote! {
         __Visitor {
             marker: _serde::export::PhantomData::<#this #ty_generics>,
             lifetime: _serde::export::PhantomData,
         }
     };
     let dispatch = if let Some(deserializer) = deserializer {
         quote! {
             _serde::Deserializer::deserialize_any(#deserializer, #visitor_expr)
         }
     } else if is_enum {
         quote! {
             _serde::de::VariantAccess::struct_variant(__variant, FIELDS, #visitor_expr)
         }
+    } else if cattrs.has_flatten() {
+        quote! {
+            _serde::Deserializer::deserialize_map(__deserializer, #visitor_expr)
+        }
     } else {
         let type_name = cattrs.name().deserialize_name();
         quote! {
             _serde::Deserializer::deserialize_struct(__deserializer, #type_name, FIELDS, #visitor_expr)
         }
     };
 
     let all_skipped = fields.iter().all(|field| field.attrs.skip_deserializing());
     let visitor_var = if all_skipped {
         quote!(_)
     } else {
         quote!(mut __seq)
     };
 
-    // untagged struct variants do not get a visit_seq method
-    let visit_seq = match untagged {
-        Untagged::Yes => None,
-        Untagged::No => Some(quote! {
+    // untagged struct variants do not get a visit_seq method.  The same applies to structs that
+    // only have a map representation.
+    let visit_seq = match *untagged {
+        Untagged::No if !cattrs.has_flatten() => Some(quote! {
             #[inline]
             fn visit_seq<__A>(self, #visitor_var: __A) -> _serde::export::Result<Self::Value, __A::Error>
                 where __A: _serde::de::SeqAccess<#delife>
             {
                 #visit_seq
             }
         }),
+        _ => None,
     };
 
     quote_block! {
         #field_visitor
 
         struct __Visitor #de_impl_generics #where_clause {
             marker: _serde::export::PhantomData<#this #ty_generics>,
             lifetime: _serde::export::PhantomData<&#delife ()>,
@@ -887,34 +923,40 @@ fn deserialize_struct(
 
 #[cfg(feature = "deserialize_in_place")]
 fn deserialize_struct_in_place(
     variant_ident: Option<&syn::Ident>,
     params: &Parameters,
     fields: &[Field],
     cattrs: &attr::Container,
     deserializer: Option<Tokens>,
-    untagged: Untagged,
-) -> Fragment {
+) -> Option<Fragment> {
     let is_enum = variant_ident.is_some();
 
+    // for now we do not support in_place deserialization for structs that
+    // are represented as map.
+    if cattrs.has_flatten() {
+        return None;
+    }
+
     let this = &params.this;
     let (de_impl_generics, de_ty_generics, ty_generics, where_clause) =
         split_with_de_lifetime(params);
     let delife = params.borrowed.de_lifetime();
 
     let expecting = match variant_ident {
         Some(variant_ident) => format!("struct variant {}::{}", params.type_name(), variant_ident),
         None => format!("struct {}", params.type_name()),
     };
 
     let visit_seq = Stmts(deserialize_seq_in_place(params, fields, false, cattrs));
 
-    let (field_visitor, fields_stmt, visit_map) =
-        deserialize_struct_in_place_visitor(params, fields, cattrs);
+    let (field_visitor, fields_stmt, visit_map) = deserialize_struct_as_struct_in_place_visitor(
+        params, fields, cattrs);
+
     let field_visitor = Stmts(field_visitor);
     let fields_stmt = Stmts(fields_stmt);
     let visit_map = Stmts(visit_map);
 
     let visitor_expr = quote! {
         __Visitor {
             place: __place,
             lifetime: _serde::export::PhantomData,
@@ -937,34 +979,30 @@ fn deserialize_struct_in_place(
 
     let all_skipped = fields.iter().all(|field| field.attrs.skip_deserializing());
     let visitor_var = if all_skipped {
         quote!(_)
     } else {
         quote!(mut __seq)
     };
 
-    // untagged struct variants do not get a visit_seq method
-    let visit_seq = match untagged {
-        Untagged::Yes => None,
-        Untagged::No => Some(quote! {
-            #[inline]
-            fn visit_seq<__A>(self, #visitor_var: __A) -> _serde::export::Result<Self::Value, __A::Error>
-                where __A: _serde::de::SeqAccess<#delife>
-            {
-                #visit_seq
-            }
-        }),
+    let visit_seq = quote! {
+        #[inline]
+        fn visit_seq<__A>(self, #visitor_var: __A) -> _serde::export::Result<Self::Value, __A::Error>
+            where __A: _serde::de::SeqAccess<#delife>
+        {
+            #visit_seq
+        }
     };
 
     let in_place_impl_generics = de_impl_generics.in_place();
     let in_place_ty_generics = de_ty_generics.in_place();
     let place_life = place_lifetime();
 
-    quote_block! {
+    Some(quote_block! {
         #field_visitor
 
         struct __Visitor #in_place_impl_generics #where_clause {
             place: &#place_life mut #this #ty_generics,
             lifetime: _serde::export::PhantomData<&#delife ()>,
         }
 
         impl #in_place_impl_generics _serde::de::Visitor<#delife> for __Visitor #in_place_ty_generics #where_clause {
@@ -982,17 +1020,17 @@ fn deserialize_struct_in_place(
             {
                 #visit_map
             }
         }
 
         #fields_stmt
 
         #dispatch
-    }
+    })
 }
 
 fn deserialize_enum(
     params: &Parameters,
     variants: &[Variant],
     cattrs: &attr::Container,
 ) -> Fragment {
     match *cattrs.tag() {
@@ -1045,17 +1083,17 @@ fn deserialize_externally_tagged_enum(
     let variants_stmt = {
         let variant_names = variant_names_idents.iter().map(|&(ref name, _)| name);
         quote! {
             const VARIANTS: &'static [&'static str] = &[ #(#variant_names),* ];
         }
     };
 
     let variant_visitor = Stmts(deserialize_generated_identifier(
-        variant_names_idents,
+        &variant_names_idents,
         cattrs,
         true,
     ));
 
     // Match arms to extract a variant from a string
     let variant_arms = variants
         .iter()
         .enumerate()
@@ -1131,17 +1169,17 @@ fn deserialize_externally_tagged_enum(
 #[cfg(feature = "deserialize_in_place")]
 fn deserialize_externally_tagged_enum_in_place(
     params: &Parameters,
     repr: &Repr,
     variants: &[Variant],
     cattrs: &attr::Container,
 ) -> Option<Fragment> {
     let int_repr = repr.get_stable_rust_enum_layout().map(|int_repr| {
-        let int_repr = Ident::new(int_repr);
+        let int_repr = Ident::from(int_repr);
         quote!(#[repr(#int_repr)])
     });
 
     let unit_variant = variants.iter().position(|variant| is_unit(variant));
     let non_unit_variant = variants.iter().enumerate().find(|&(_, variant)| !is_unit(variant));
 
     // We need an int_repr, unit variant, and a non-unit variant to proceed
     if int_repr.is_none() || unit_variant.is_none() || non_unit_variant.is_none() {
@@ -1169,17 +1207,17 @@ fn deserialize_externally_tagged_enum_in
 
     let variants_stmt = {
         let variant_names = variant_names_idents.iter().map(|&(ref name, _)| name);
         quote! {
             const VARIANTS: &'static [&'static str] = &[ #(#variant_names),* ];
         }
     };
 
-    let variant_visitor = Stmts(deserialize_generated_identifier(variant_names_idents, cattrs, true),);
+    let variant_visitor = Stmts(deserialize_generated_identifier(&variant_names_idents, cattrs, true),);
 
     let non_unit_field = field_i(non_unit_index);
     let tag_access = match non_unit_variant.style {
         Style::Struct => {
             quote!(repr.#non_unit_field.tag)
         }
         Style::Tuple | Style::Newtype => {
             quote!(repr.#non_unit_field.0)
@@ -1391,17 +1429,17 @@ fn deserialize_internally_tagged_enum(
     let variants_stmt = {
         let variant_names = variant_names_idents.iter().map(|&(ref name, _)| name);
         quote! {
             const VARIANTS: &'static [&'static str] = &[ #(#variant_names),* ];
         }
     };
 
     let variant_visitor = Stmts(deserialize_generated_identifier(
-        variant_names_idents,
+        &variant_names_idents,
         cattrs,
         true,
     ));
 
     // Match arms to extract a variant from a string
     let variant_arms = variants
         .iter()
         .enumerate()
@@ -1460,22 +1498,22 @@ fn deserialize_adjacently_tagged_enum(
     let variants_stmt = {
         let variant_names = variant_names_idents.iter().map(|&(ref name, _)| name);
         quote! {
             const VARIANTS: &'static [&'static str] = &[ #(#variant_names),* ];
         }
     };
 
     let variant_visitor = Stmts(deserialize_generated_identifier(
-        variant_names_idents,
+        &variant_names_idents,
         cattrs,
         true,
     ));
 
-    let ref variant_arms: Vec<_> = variants
+    let variant_arms: &Vec<_> = &variants
         .iter()
         .enumerate()
         .filter(|&(_, variant)| !variant.attrs.skip_deserializing())
         .map(|(i, variant)| {
             let variant_index = field_i(i);
 
             let block = Match(deserialize_untagged_variant(
                 params,
@@ -1766,17 +1804,17 @@ fn deserialize_untagged_enum(
 
 fn deserialize_externally_tagged_variant(
     params: &Parameters,
     variant: &Variant,
     cattrs: &attr::Container,
 ) -> Fragment {
     if let Some(path) = variant.attrs.deserialize_with() {
         let (wrapper, wrapper_ty, unwrap_fn) =
-            wrap_deserialize_variant_with(params, &variant, path);
+            wrap_deserialize_variant_with(params, variant, path);
         return quote_block! {
             #wrapper
             _serde::export::Result::map(
                 _serde::de::VariantAccess::newtype_variant::<#wrapper_ty>(__variant), #unwrap_fn)
         };
     }
 
     let variant_ident = &variant.ident;
@@ -1796,17 +1834,17 @@ fn deserialize_externally_tagged_variant
             deserialize_tuple(Some(variant_ident), params, &variant.fields, cattrs, None)
         }
         Style::Struct => deserialize_struct(
             Some(variant_ident),
             params,
             &variant.fields,
             cattrs,
             None,
-            Untagged::No,
+            &Untagged::No,
         ),
     }
 }
 
 #[cfg(feature = "deserialize_in_place")]
 fn deserialize_externally_tagged_variant_in_place(
     params: &Parameters,
     variant: &Variant,
@@ -1867,39 +1905,39 @@ fn deserialize_internally_tagged_variant
                 try!(_serde::Deserializer::deserialize_any(#deserializer, _serde::private::de::InternallyTaggedUnitVisitor::new(#type_name, #variant_name)));
                 _serde::export::Ok(#this::#variant_ident)
             }
         }
         Style::Newtype => deserialize_untagged_newtype_variant(
             variant_ident,
             params,
             &variant.fields[0],
-            deserializer,
+            &deserializer,
         ),
         Style::Struct => deserialize_struct(
             Some(variant_ident),
             params,
             &variant.fields,
             cattrs,
             Some(deserializer),
-            Untagged::No,
+            &Untagged::No,
         ),
         Style::Tuple => unreachable!("checked in serde_derive_internals"),
     }
 }
 
 fn deserialize_untagged_variant(
     params: &Parameters,
     variant: &Variant,
     cattrs: &attr::Container,
     deserializer: Tokens,
 ) -> Fragment {
     if let Some(path) = variant.attrs.deserialize_with() {
         let (wrapper, wrapper_ty, unwrap_fn) =
-            wrap_deserialize_variant_with(params, &variant, path);
+            wrap_deserialize_variant_with(params, variant, path);
         return quote_block! {
             #wrapper
             _serde::export::Result::map(
                 <#wrapper_ty as _serde::Deserialize>::deserialize(#deserializer), #unwrap_fn)
         };
     }
 
     let variant_ident = &variant.ident;
@@ -1917,32 +1955,32 @@ fn deserialize_untagged_variant(
                     ),
                     |()| #this::#variant_ident)
             }
         }
         Style::Newtype => deserialize_untagged_newtype_variant(
             variant_ident,
             params,
             &variant.fields[0],
-            deserializer,
+            &deserializer,
         ),
         Style::Tuple => deserialize_tuple(
             Some(variant_ident),
             params,
             &variant.fields,
             cattrs,
             Some(deserializer),
         ),
         Style::Struct => deserialize_struct(
             Some(variant_ident),
             params,
             &variant.fields,
             cattrs,
             Some(deserializer),
-            Untagged::Yes,
+            &Untagged::Yes,
         ),
     }
 }
 
 fn deserialize_externally_tagged_newtype_variant(
     variant_ident: &syn::Ident,
     params: &Parameters,
     field: &Field,
@@ -1996,17 +2034,17 @@ fn deserialize_externally_tagged_newtype
         }
     }
 }
 
 fn deserialize_untagged_newtype_variant(
     variant_ident: &syn::Ident,
     params: &Parameters,
     field: &Field,
-    deserializer: Tokens,
+    deserializer: &Tokens,
 ) -> Fragment {
     let this = &params.this;
     match field.attrs.deserialize_with() {
         None => {
             let field_ty = &field.ty;
             quote_expr! {
                 _serde::export::Result::map(
                     <#field_ty as _serde::Deserialize>::deserialize(#deserializer),
@@ -2021,54 +2059,65 @@ fn deserialize_untagged_newtype_variant(
                     <#wrapper_ty as _serde::Deserialize>::deserialize(#deserializer),
                     |__wrapper| #this::#variant_ident(__wrapper.value))
             }
         }
     }
 }
 
 fn deserialize_generated_identifier(
-    fields: Vec<(String, Ident)>,
+    fields: &[(String, Ident)],
     cattrs: &attr::Container,
-    is_variant: bool,
+    is_variant: bool
 ) -> Fragment {
     let this = quote!(__Field);
     let field_idents: &Vec<_> = &fields.iter().map(|&(_, ref ident)| ident).collect();
 
-    let (ignore_variant, fallthrough) = if is_variant || cattrs.deny_unknown_fields() {
+    let (ignore_variant, fallthrough) = if cattrs.has_flatten() {
+        let ignore_variant = quote!(__other(_serde::private::de::Content<'de>),);
+        let fallthrough = quote!(_serde::export::Ok(__Field::__other(__value)));
+        (Some(ignore_variant), Some(fallthrough))
+    } else if is_variant || cattrs.deny_unknown_fields() {
         (None, None)
     } else {
         let ignore_variant = quote!(__ignore,);
         let fallthrough = quote!(_serde::export::Ok(__Field::__ignore));
         (Some(ignore_variant), Some(fallthrough))
     };
 
     let visitor_impl = Stmts(deserialize_identifier(
-        this,
-        &fields,
+        &this,
+        fields,
         is_variant,
         fallthrough,
+        cattrs.has_flatten(),
     ));
 
+    let lifetime = if cattrs.has_flatten() {
+        Some(quote!(<'de>))
+    } else {
+        None
+    };
+
     quote_block! {
         #[allow(non_camel_case_types)]
-        enum __Field {
+        enum __Field #lifetime {
             #(#field_idents,)*
             #ignore_variant
         }
 
         struct __FieldVisitor;
 
         impl<'de> _serde::de::Visitor<'de> for __FieldVisitor {
-            type Value = __Field;
+            type Value = __Field #lifetime;
 
             #visitor_impl
         }
 
-        impl<'de> _serde::Deserialize<'de> for __Field {
+        impl<'de> _serde::Deserialize<'de> for __Field #lifetime {
             #[inline]
             fn deserialize<__D>(__deserializer: __D) -> _serde::export::Result<Self, __D::Error>
                 where __D: _serde::Deserializer<'de>
             {
                 _serde::Deserializer::deserialize_identifier(__deserializer, __FieldVisitor)
             }
         }
     }
@@ -2110,17 +2159,17 @@ fn deserialize_custom_identifier(
         (variants, None)
     };
 
     let names_idents: Vec<_> = ordinary
         .iter()
         .map(|variant| {
             (
                 variant.attrs.name().deserialize_name(),
-                variant.ident.clone(),
+                variant.ident,
             )
         })
         .collect();
 
     let names = names_idents.iter().map(|&(ref name, _)| name);
 
     let names_const = if fallthrough.is_some() {
         None
@@ -2135,20 +2184,21 @@ fn deserialize_custom_identifier(
         };
         Some(fields)
     };
 
     let (de_impl_generics, de_ty_generics, ty_generics, where_clause) =
         split_with_de_lifetime(params);
     let delife = params.borrowed.de_lifetime();
     let visitor_impl = Stmts(deserialize_identifier(
-        this.clone(),
+        &this,
         &names_idents,
         is_variant,
         fallthrough,
+        false,
     ));
 
     quote_block! {
         #names_const
 
         struct __FieldVisitor #de_impl_generics #where_clause {
             marker: _serde::export::PhantomData<#this #ty_generics>,
             lifetime: _serde::export::PhantomData<&#delife ()>,
@@ -2164,61 +2214,165 @@ fn deserialize_custom_identifier(
             marker: _serde::export::PhantomData::<#this #ty_generics>,
             lifetime: _serde::export::PhantomData,
         };
         _serde::Deserializer::deserialize_identifier(__deserializer, __visitor)
     }
 }
 
 fn deserialize_identifier(
-    this: Tokens,
+    this: &Tokens,
     fields: &[(String, Ident)],
     is_variant: bool,
     fallthrough: Option<Tokens>,
+    collect_other_fields: bool
 ) -> Fragment {
     let field_strs = fields.iter().map(|&(ref name, _)| name);
-    let field_bytes = fields.iter().map(|&(ref name, _)| quote::ByteStr(name));
+    let field_borrowed_strs = fields.iter().map(|&(ref name, _)| name);
+    let field_bytes = fields.iter().map(|&(ref name, _)| Literal::byte_string(name.as_bytes()));
+    let field_borrowed_bytes = fields.iter().map(|&(ref name, _)| Literal::byte_string(name.as_bytes()));
 
     let constructors: &Vec<_> = &fields
         .iter()
         .map(|&(_, ref ident)| quote!(#this::#ident))
         .collect();
 
     let expecting = if is_variant {
         "variant identifier"
     } else {
         "field identifier"
     };
 
     let index_expecting = if is_variant { "variant" } else { "field" };
 
     let variant_indices = 0u64..;
     let fallthrough_msg = format!("{} index 0 <= i < {}", index_expecting, fields.len());
-    let visit_index = quote! {
-        fn visit_u64<__E>(self, __value: u64) -> _serde::export::Result<Self::Value, __E>
-            where __E: _serde::de::Error
-        {
-            match __value {
-                #(
-                    #variant_indices => _serde::export::Ok(#constructors),
-                )*
-                _ => _serde::export::Err(_serde::de::Error::invalid_value(
-                            _serde::de::Unexpected::Unsigned(__value),
-                            &#fallthrough_msg))
+    let visit_other = if collect_other_fields {
+        Some(quote! {
+            fn visit_bool<__E>(self, __value: bool) -> Result<Self::Value, __E>
+                where __E: _serde::de::Error
+            {
+                Ok(__Field::__other(_serde::private::de::Content::Bool(__value)))
+            }
+
+            fn visit_i8<__E>(self, __value: i8) -> Result<Self::Value, __E>
+                where __E: _serde::de::Error
+            {
+                Ok(__Field::__other(_serde::private::de::Content::I8(__value)))
+            }
+
+            fn visit_i16<__E>(self, __value: i16) -> Result<Self::Value, __E>
+                where __E: _serde::de::Error
+            {
+                Ok(__Field::__other(_serde::private::de::Content::I16(__value)))
+            }
+
+            fn visit_i32<__E>(self, __value: i32) -> Result<Self::Value, __E>
+                where __E: _serde::de::Error
+            {
+                Ok(__Field::__other(_serde::private::de::Content::I32(__value)))
+            }
+
+            fn visit_i64<__E>(self, __value: i64) -> Result<Self::Value, __E>
+                where __E: _serde::de::Error
+            {
+                Ok(__Field::__other(_serde::private::de::Content::I64(__value)))
+            }
+
+            fn visit_u8<__E>(self, __value: u8) -> Result<Self::Value, __E>
+                where __E: _serde::de::Error
+            {
+                Ok(__Field::__other(_serde::private::de::Content::U8(__value)))
+            }
+
+            fn visit_u16<__E>(self, __value: u16) -> Result<Self::Value, __E>
+                where __E: _serde::de::Error
+            {
+                Ok(__Field::__other(_serde::private::de::Content::U16(__value)))
+            }
+
+            fn visit_u32<__E>(self, __value: u32) -> Result<Self::Value, __E>
+                where __E: _serde::de::Error
+            {
+                Ok(__Field::__other(_serde::private::de::Content::U32(__value)))
             }
-        }
+
+            fn visit_u64<__E>(self, __value: u64) -> Result<Self::Value, __E>
+                where __E: _serde::de::Error
+            {
+                Ok(__Field::__other(_serde::private::de::Content::U64(__value)))
+            }
+
+            fn visit_f32<__E>(self, __value: f32) -> Result<Self::Value, __E>
+                where __E: _serde::de::Error
+            {
+                Ok(__Field::__other(_serde::private::de::Content::F32(__value)))
+            }
+
+            fn visit_f64<__E>(self, __value: f64) -> Result<Self::Value, __E>
+                where __E: _serde::de::Error
+            {
+                Ok(__Field::__other(_serde::private::de::Content::F64(__value)))
+            }
+
+            fn visit_char<__E>(self, __value: char) -> Result<Self::Value, __E>
+                where __E: _serde::de::Error
+            {
+                Ok(__Field::__other(_serde::private::de::Content::Char(__value)))
+            }
+
+            fn visit_unit<__E>(self) -> Result<Self::Value, __E>
+                where __E: _serde::de::Error
+            {
+                Ok(__Field::__other(_serde::private::de::Content::Unit))
+            }
+        })
+    } else {
+        Some(quote! {
+            fn visit_u64<__E>(self, __value: u64) -> _serde::export::Result<Self::Value, __E>
+                where __E: _serde::de::Error
+            {
+                match __value {
+                    #(
+                        #variant_indices => _serde::export::Ok(#constructors),
+                    )*
+                    _ => _serde::export::Err(_serde::de::Error::invalid_value(
+                                _serde::de::Unexpected::Unsigned(__value),
+                                &#fallthrough_msg))
+                }
+            }
+        })
     };
 
-    let bytes_to_str = if fallthrough.is_some() {
+    let bytes_to_str = if fallthrough.is_some() || collect_other_fields {
         None
     } else {
-        let conversion = quote! {
+        Some(quote! {
             let __value = &_serde::export::from_utf8_lossy(__value);
-        };
-        Some(conversion)
+        })
+    };
+
+    let (value_as_str_content, value_as_borrowed_str_content,
+         value_as_bytes_content, value_as_borrowed_bytes_content) = if !collect_other_fields {
+        (None, None, None, None)
+    } else {
+        (
+            Some(quote! {
+                let __value = _serde::private::de::Content::String(__value.to_string());
+            }),
+            Some(quote! {
+                let __value = _serde::private::de::Content::Str(__value);
+            }),
+            Some(quote! {
+                let __value = _serde::private::de::Content::ByteBuf(__value.to_vec());
+            }),
+            Some(quote! {
+                let __value = _serde::private::de::Content::Bytes(__value);
+            })
+        )
     };
 
     let fallthrough_arm = if let Some(fallthrough) = fallthrough {
         fallthrough
     } else if is_variant {
         quote! {
             _serde::export::Err(_serde::de::Error::unknown_variant(__value, VARIANTS))
         }
@@ -2228,108 +2382,177 @@ fn deserialize_identifier(
         }
     };
 
     quote_block! {
         fn expecting(&self, formatter: &mut _serde::export::Formatter) -> _serde::export::fmt::Result {
             _serde::export::Formatter::write_str(formatter, #expecting)
         }
 
-        #visit_index
+        #visit_other
 
         fn visit_str<__E>(self, __value: &str) -> _serde::export::Result<Self::Value, __E>
             where __E: _serde::de::Error
         {
             match __value {
                 #(
                     #field_strs => _serde::export::Ok(#constructors),
                 )*
-                _ => #fallthrough_arm
+                _ => {
+                    #value_as_str_content
+                    #fallthrough_arm
+                }
+            }
+        }
+
+        fn visit_borrowed_str<__E>(self, __value: &'de str) -> _serde::export::Result<Self::Value, __E>
+            where __E: _serde::de::Error
+        {
+            match __value {
+                #(
+                    #field_borrowed_strs => _serde::export::Ok(#constructors),
+                )*
+                _ => {
+                    #value_as_borrowed_str_content
+                    #fallthrough_arm
+                }
+            }
+        }
+
+        fn visit_borrowed_bytes<__E>(self, __value: &'de [u8]) -> _serde::export::Result<Self::Value, __E>
+            where __E: _serde::de::Error
+        {
+            match __value {
+                #(
+                    #field_borrowed_bytes => _serde::export::Ok(#constructors),
+                )*
+                _ => {
+                    #bytes_to_str
+                    #value_as_borrowed_bytes_content
+                    #fallthrough_arm
+                }
             }
         }
 
         fn visit_bytes<__E>(self, __value: &[u8]) -> _serde::export::Result<Self::Value, __E>
             where __E: _serde::de::Error
         {
             match __value {
                 #(
                     #field_bytes => _serde::export::Ok(#constructors),
                 )*
                 _ => {
                     #bytes_to_str
+                    #value_as_bytes_content
                     #fallthrough_arm
                 }
             }
         }
     }
 }
 
-fn deserialize_struct_visitor(
-    struct_path: Tokens,
+fn deserialize_struct_as_struct_visitor(
+    struct_path: &Tokens,
     params: &Parameters,
     fields: &[Field],
     cattrs: &attr::Container,
-) -> (Fragment, Fragment, Fragment) {
+) -> (Fragment, Option<Fragment>, Fragment) {
+    assert!(!cattrs.has_flatten());
+
     let field_names_idents: Vec<_> = fields
         .iter()
         .enumerate()
         .filter(|&(_, field)| !field.attrs.skip_deserializing())
         .map(|(i, field)| (field.attrs.name().deserialize_name(), field_i(i)))
         .collect();
 
     let fields_stmt = {
         let field_names = field_names_idents.iter().map(|&(ref name, _)| name);
         quote_block! {
             const FIELDS: &'static [&'static str] = &[ #(#field_names),* ];
         }
     };
 
-    let field_visitor = deserialize_generated_identifier(field_names_idents, cattrs, false);
+    let field_visitor = deserialize_generated_identifier(&field_names_idents, cattrs, false);
 
     let visit_map = deserialize_map(struct_path, params, fields, cattrs);
 
-    (field_visitor, fields_stmt, visit_map)
+    (field_visitor, Some(fields_stmt), visit_map)
+}
+
+fn deserialize_struct_as_map_visitor(
+    struct_path: &Tokens,
+    params: &Parameters,
+    fields: &[Field],
+    cattrs: &attr::Container,
+) -> (Fragment, Option<Fragment>, Fragment) {
+    let field_names_idents: Vec<_> = fields
+        .iter()
+        .enumerate()
+        .filter(|&(_, field)| !field.attrs.skip_deserializing() && !field.attrs.flatten())
+        .map(|(i, field)| (field.attrs.name().deserialize_name(), field_i(i)))
+        .collect();
+
+    let field_visitor = deserialize_generated_identifier(&field_names_idents, cattrs, false);
+
+    let visit_map = deserialize_map(struct_path, params, fields, cattrs);
+
+    (field_visitor, None, visit_map)
 }
 
 fn deserialize_map(
-    struct_path: Tokens,
+    struct_path: &Tokens,
     params: &Parameters,
     fields: &[Field],
     cattrs: &attr::Container,
 ) -> Fragment {
     // Create the field names for the fields.
     let fields_names: Vec<_> = fields
         .iter()
         .enumerate()
         .map(|(i, field)| (field, field_i(i)))
         .collect();
 
     // Declare each field that will be deserialized.
     let let_values = fields_names
         .iter()
-        .filter(|&&(field, _)| !field.attrs.skip_deserializing())
+        .filter(|&&(field, _)| !field.attrs.skip_deserializing() && !field.attrs.flatten())
         .map(|&(field, ref name)| {
             let field_ty = &field.ty;
             quote! {
                 let mut #name: _serde::export::Option<#field_ty> = _serde::export::None;
             }
         });
 
+    // Collect contents for flatten fields into a buffer
+    let let_collect = if cattrs.has_flatten() {
+        Some(quote! {
+            let mut __collect = Vec::<Option<(
+                _serde::private::de::Content,
+                _serde::private::de::Content
+            )>>::new();
+        })
+    } else {
+        None
+    };
+
     // Match arms to extract a value for a field.
     let value_arms = fields_names
         .iter()
-        .filter(|&&(field, _)| !field.attrs.skip_deserializing())
+        .filter(|&&(field, _)| !field.attrs.skip_deserializing() && !field.attrs.flatten())
         .map(|&(field, ref name)| {
             let deser_name = field.attrs.name().deserialize_name();
 
             let visit = match field.attrs.deserialize_with() {
                 None => {
                     let field_ty = &field.ty;
+                    let span = Span::def_site().located_at(field.original.span());
+                    let func = quote_spanned!(span=> _serde::de::MapAccess::next_value::<#field_ty>);
                     quote! {
-                        try!(_serde::de::MapAccess::next_value::<#field_ty>(&mut __map))
+                        try!(#func(&mut __map))
                     }
                 }
                 Some(path) => {
                     let (wrapper, wrapper_ty) = wrap_deserialize_field_with(params, field.ty, path);
                     quote!({
                         #wrapper
                         try!(_serde::de::MapAccess::next_value::<#wrapper_ty>(&mut __map)).value
                     })
@@ -2341,17 +2564,25 @@ fn deserialize_map(
                         return _serde::export::Err(<__A::Error as _serde::de::Error>::duplicate_field(#deser_name));
                     }
                     #name = _serde::export::Some(#visit);
                 }
             }
         });
 
     // Visit ignored values to consume them
-    let ignored_arm = if cattrs.deny_unknown_fields() {
+    let ignored_arm = if cattrs.has_flatten() {
+        Some(quote! {
+            __Field::__other(__name) => {
+                __collect.push(Some((
+                    __name,
+                    try!(_serde::de::MapAccess::next_value(&mut __map)))));
+            }
+        })
+    } else if cattrs.deny_unknown_fields() {
         None
     } else {
         Some(quote! {
             _ => { let _ = try!(_serde::de::MapAccess::next_value::<_serde::de::IgnoredAny>(&mut __map)); }
         })
     };
 
     let all_skipped = fields.iter().all(|field| field.attrs.skip_deserializing());
@@ -2371,35 +2602,64 @@ fn deserialize_map(
                     #ignored_arm
                 }
             }
         }
     };
 
     let extract_values = fields_names
         .iter()
-        .filter(|&&(field, _)| !field.attrs.skip_deserializing())
+        .filter(|&&(field, _)| !field.attrs.skip_deserializing() && !field.attrs.flatten())
         .map(|&(field, ref name)| {
-            let missing_expr = Match(expr_is_missing(&field, cattrs));
+            let missing_expr = Match(expr_is_missing(field, cattrs));
 
             quote! {
                 let #name = match #name {
                     _serde::export::Some(#name) => #name,
                     _serde::export::None => #missing_expr
                 };
             }
         });
 
+    let extract_collected = fields_names
+        .iter()
+        .filter(|&&(field, _)| field.attrs.flatten())
+        .map(|&(field, ref name)| {
+            let field_ty = field.ty;
+            quote! {
+                let #name: #field_ty = try!(_serde::de::Deserialize::deserialize(
+                    _serde::private::de::FlatMapDeserializer(
+                        &mut __collect,
+                        _serde::export::PhantomData)));
+            }
+        });
+
+    let collected_deny_unknown_fields = if cattrs.has_flatten() && cattrs.deny_unknown_fields() {
+        Some(quote! {
+            if let Some(Some((__key, _))) = __collect.into_iter().filter(|x| x.is_some()).next() {
+                if let Some(__key) = __key.as_str() {
+                    return _serde::export::Err(
+                        _serde::de::Error::custom(format_args!("unknown field `{}`", &__key)));
+                } else {
+                    return _serde::export::Err(
+                        _serde::de::Error::custom(format_args!("unexpected map key")));
+                }
+            }
+        })
+    } else {
+        None
+    };
+
     let result = fields_names.iter().map(|&(field, ref name)| {
-        let ident = field.ident.clone().expect("struct contains unnamed fields");
+        let ident = field.ident.expect("struct contains unnamed fields");
         if field.attrs.skip_deserializing() {
-            let value = Expr(expr_is_missing(&field, cattrs));
-            quote!(#ident: #value)
+            let value = Expr(expr_is_missing(field, cattrs));
+            quote_spanned!(Span::call_site()=> #ident: #value)
         } else {
-            quote!(#ident: #name)
+            quote_spanned!(Span::call_site()=> #ident: #name)
         }
     });
 
     let let_default = match *cattrs.default() {
         attr::Default::Default => Some(quote!(
             let __default: Self::Value = _serde::export::Default::default();
         )),
         attr::Default::Path(ref path) => Some(quote!(
@@ -2407,70 +2667,80 @@ fn deserialize_map(
         )),
         attr::Default::None => {
             // We don't need the default value, to prevent an unused variable warning
             // we'll leave the line empty.
             None
         }
     };
 
-    let mut result = quote!(#struct_path { #(#result),* });
+    let mut result = quote_spanned!(Span::call_site()=> #struct_path { #(#result),* });
     if params.has_getter {
         let this = &params.this;
         result = quote! {
             _serde::export::Into::<#this>::into(#result)
         };
     }
 
     quote_block! {
         #(#let_values)*
 
+        #let_collect
+
         #match_keys
 
         #let_default
 
         #(#extract_values)*
 
+        #(#extract_collected)*
+
+        #collected_deny_unknown_fields
+
         _serde::export::Ok(#result)
     }
 }
 
 #[cfg(feature = "deserialize_in_place")]
-fn deserialize_struct_in_place_visitor(
+fn deserialize_struct_as_struct_in_place_visitor(
     params: &Parameters,
     fields: &[Field],
     cattrs: &attr::Container,
 ) -> (Fragment, Fragment, Fragment) {
+    assert!(!cattrs.has_flatten());
+
     let field_names_idents: Vec<_> = fields
         .iter()
         .enumerate()
         .filter(|&(_, field)| !field.attrs.skip_deserializing())
         .map(|(i, field)| (field.attrs.name().deserialize_name(), field_i(i)))
         .collect();
 
     let fields_stmt = {
         let field_names = field_names_idents.iter().map(|&(ref name, _)| name);
         quote_block! {
             const FIELDS: &'static [&'static str] = &[ #(#field_names),* ];
         }
     };
 
-    let field_visitor = deserialize_generated_identifier(field_names_idents, cattrs, false);
+    let field_visitor = deserialize_generated_identifier(&field_names_idents, cattrs, false);
 
     let visit_map = deserialize_map_in_place(params, fields, cattrs);
 
     (field_visitor, fields_stmt, visit_map)
 }
 
 #[cfg(feature = "deserialize_in_place")]
 fn deserialize_map_in_place(
     params: &Parameters,
     fields: &[Field],
     cattrs: &attr::Container,
 ) -> Fragment {
+    assert!(!cattrs.has_flatten());
+
     // Create the field names for the fields.
     let fields_names: Vec<_> = fields
         .iter()
         .enumerate()
         .map(|(i, field)| (field, field_i(i)))
         .collect();
 
     // For deserialize_in_place, declare booleans for each field that will be deserialized.
@@ -2545,21 +2815,21 @@ fn deserialize_map_in_place(
             }
         }
     };
 
     let check_flags = fields_names
         .iter()
         .filter(|&&(field, _)| !field.attrs.skip_deserializing())
         .map(|&(field, ref name)| {
-            let missing_expr = expr_is_missing(&field, cattrs);
+            let missing_expr = expr_is_missing(field, cattrs);
             // If missing_expr unconditionally returns an error, don't try
             // to assign its value to self.place. Maybe this could be handled
             // more elegantly.
-            if missing_expr.as_ref().as_str().starts_with("return ") {
+            if missing_expr.as_ref().into_tokens().to_string().starts_with("return ") {
                 let missing_expr = Stmts(missing_expr);
                 quote! {
                     if !#name {
                         #missing_expr;
                     }
                 }
             } else {
                 let field_name = &field.ident;
@@ -2598,25 +2868,25 @@ fn deserialize_map_in_place(
 
         #(#check_flags)*
 
         _serde::export::Ok(())
     }
 }
 
 fn field_i(i: usize) -> Ident {
-    Ident::new(format!("__field{}", i))
+    Ident::new(&format!("__field{}", i), Span::def_site())
 }
 
 /// This function wraps the expression in `#[serde(deserialize_with = "...")]`
 /// in a trait to prevent it from accessing the internal `Deserialize` state.
 fn wrap_deserialize_with(
     params: &Parameters,
-    value_ty: Tokens,
-    deserialize_with: &syn::Path,
+    value_ty: &Tokens,
+    deserialize_with: &syn::ExprPath,
 ) -> (Tokens, Tokens) {
     let this = &params.this;
     let (de_impl_generics, de_ty_generics, ty_generics, where_clause) =
         split_with_de_lifetime(params);
     let delife = params.borrowed.de_lifetime();
 
     let wrapper = quote! {
         struct __DeserializeWith #de_impl_generics #where_clause {
@@ -2640,35 +2910,38 @@ fn wrap_deserialize_with(
 
     let wrapper_ty = quote!(__DeserializeWith #de_ty_generics);
 
     (wrapper, wrapper_ty)
 }
 
 fn wrap_deserialize_field_with(
     params: &Parameters,
-    field_ty: &syn::Ty,
-    deserialize_with: &syn::Path,
+    field_ty: &syn::Type,
+    deserialize_with: &syn::ExprPath,
 ) -> (Tokens, Tokens) {
-    wrap_deserialize_with(params, quote!(#field_ty), deserialize_with)
+    wrap_deserialize_with(params, &quote!(#field_ty), deserialize_with)
 }
 
 fn wrap_deserialize_variant_with(
     params: &Parameters,
     variant: &Variant,
-    deserialize_with: &syn::Path,
+    deserialize_with: &syn::ExprPath,
 ) -> (Tokens, Tokens, Tokens) {
     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 field_access = (0..variant.fields.len()).map(|n| Ident::new(format!("{}", n)));
+        wrap_deserialize_with(params, &quote!((#(#field_tys),*)), deserialize_with);
+
+    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 {
         Style::Struct => {
             let field_idents = variant
                 .fields
                 .iter()
                 .map(|field| field.ident.as_ref().unwrap());
             quote!({
                 |__wrap| {
@@ -2711,18 +2984,20 @@ fn expr_is_missing(field: &Field, cattrs
             return quote_expr!(__default.#ident);
         }
         attr::Default::None => { /* below */ }
     }
 
     let name = field.attrs.name().deserialize_name();
     match field.attrs.deserialize_with() {
         None => {
+            let span = Span::def_site().located_at(field.original.span());
+            let func = quote_spanned!(span=> _serde::private::de::missing_field);
             quote_expr! {
-                try!(_serde::private::de::missing_field(#name))
+                try!(#func(#name))
             }
         }
         Some(_) => {
             quote_expr! {
                 return _serde::export::Err(<__A::Error as _serde::de::Error>::missing_field(#name))
             }
         }
     }
@@ -2731,105 +3006,144 @@ fn expr_is_missing(field: &Field, cattrs
 struct DeImplGenerics<'a>(&'a Parameters);
 #[cfg(feature = "deserialize_in_place")]
 struct InPlaceImplGenerics<'a>(&'a Parameters);
 
 impl<'a> ToTokens for DeImplGenerics<'a> {
     fn to_tokens(&self, tokens: &mut Tokens) {
         let mut generics = self.0.generics.clone();
         if let Some(de_lifetime) = self.0.borrowed.de_lifetime_def() {
-            generics.lifetimes.insert(0, de_lifetime);
+            generics.params = Some(syn::GenericParam::Lifetime(de_lifetime))
+                .into_iter()
+                .chain(generics.params)
+                .collect();
         }
         let (impl_generics, _, _) = generics.split_for_impl();
         impl_generics.to_tokens(tokens);
     }
 }
 
 #[cfg(feature = "deserialize_in_place")]
 impl<'a> ToTokens for InPlaceImplGenerics<'a> {
     fn to_tokens(&self, tokens: &mut Tokens) {
         let place_lifetime = place_lifetime();
         let mut generics = self.0.generics.clone();
 
         // Add lifetime for `&'place mut Self, and `'a: 'place`
-        for lifetime in &mut generics.lifetimes {
-            lifetime.bounds.push(place_lifetime.lifetime.clone());
+        for param in &mut generics.params {
+            match *param {
+                syn::GenericParam::Lifetime(ref mut param) => {
+                    param.bounds.push(place_lifetime.lifetime);
+                }
+                syn::GenericParam::Type(ref mut param) => {
+                    param.bounds
+                        .push(syn::TypeParamBound::Lifetime(place_lifetime.lifetime));
+                }
+                syn::GenericParam::Const(_) => {}
+            }
         }
-        for generic in &mut generics.ty_params {
-            generic
-                .bounds
-                .push(syn::TyParamBound::Region(place_lifetime.lifetime.clone()));
-        }
-        generics.lifetimes.insert(0, place_lifetime);
+        generics.params = Some(syn::GenericParam::Lifetime(place_lifetime))
+            .into_iter()
+            .chain(generics.params)
+            .collect();
         if let Some(de_lifetime) = self.0.borrowed.de_lifetime_def() {
-            generics.lifetimes.insert(0, de_lifetime);
+            generics.params = Some(syn::GenericParam::Lifetime(de_lifetime))
+                .into_iter()
+                .chain(generics.params)
+                .collect();
         }
         let (impl_generics, _, _) = generics.split_for_impl();
         impl_generics.to_tokens(tokens);
     }
 }
 
 #[cfg(feature = "deserialize_in_place")]
 impl<'a> DeImplGenerics<'a> {
     fn in_place(self) -> InPlaceImplGenerics<'a> {
         InPlaceImplGenerics(self.0)
     }
 }
 
-struct DeTyGenerics<'a>(&'a Parameters);
+struct DeTypeGenerics<'a>(&'a Parameters);
 #[cfg(feature = "deserialize_in_place")]
-struct InPlaceTyGenerics<'a>(&'a Parameters);
-
-impl<'a> ToTokens for DeTyGenerics<'a> {
+struct InPlaceTypeGenerics<'a>(&'a Parameters);
+
+impl<'a> ToTokens for DeTypeGenerics<'a> {
     fn to_tokens(&self, tokens: &mut Tokens) {
         let mut generics = self.0.generics.clone();
         if self.0.borrowed.de_lifetime_def().is_some() {
-            generics.lifetimes.insert(0, syn::LifetimeDef::new("'de"));
+            let def = syn::LifetimeDef {
+                attrs: Vec::new(),
+                lifetime: syn::Lifetime::new(Term::intern("'de"), Span::def_site()),
+                colon_token: None,
+                bounds: Punctuated::new(),
+            };
+            generics.params = Some(syn::GenericParam::Lifetime(def))
+                .into_iter()
+                .chain(generics.params)
+                .collect();
         }
         let (_, ty_generics, _) = generics.split_for_impl();
         ty_generics.to_tokens(tokens);
     }
 }
 
 #[cfg(feature = "deserialize_in_place")]
-impl<'a> ToTokens for InPlaceTyGenerics<'a> {
+impl<'a> ToTokens for InPlaceTypeGenerics<'a> {
     fn to_tokens(&self, tokens: &mut Tokens) {
         let mut generics = self.0.generics.clone();
-        generics.lifetimes.insert(0, place_lifetime());
+        generics.params = Some(syn::GenericParam::Lifetime(place_lifetime()))
+            .into_iter()
+            .chain(generics.params)
+            .collect();
 
         if self.0.borrowed.de_lifetime_def().is_some() {
-            generics.lifetimes.insert(0, syn::LifetimeDef::new("'de"));
+            let def = syn::LifetimeDef {
+                attrs: Vec::new(),
+                lifetime: syn::Lifetime::new(Term::intern("'de"), Span::def_site()),
+                colon_token: None,
+                bounds: Punctuated::new(),
+            };
+            generics.params = Some(syn::GenericParam::Lifetime(def))
+                .into_iter()
+                .chain(generics.params)
+                .collect();
         }
         let (_, ty_generics, _) = generics.split_for_impl();
         ty_generics.to_tokens(tokens);
     }
 }
 
 #[cfg(feature = "deserialize_in_place")]
-impl<'a> DeTyGenerics<'a> {
-    fn in_place(self) -> InPlaceTyGenerics<'a> {
-        InPlaceTyGenerics(self.0)
+impl<'a> DeTypeGenerics<'a> {
+    fn in_place(self) -> InPlaceTypeGenerics<'a> {
+        InPlaceTypeGenerics(self.0)
     }
 }
 
 #[cfg(feature = "deserialize_in_place")]
 fn place_lifetime() -> syn::LifetimeDef {
-    syn::LifetimeDef::new("'place")
+    syn::LifetimeDef {
+        attrs: Vec::new(),
+        lifetime: syn::Lifetime::new(Term::intern("'place"), Span::def_site()),
+        colon_token: None,
+        bounds: Punctuated::new(),
+    }
 }
 
 fn split_with_de_lifetime(
     params: &Parameters,
 ) -> (
     DeImplGenerics,
-    DeTyGenerics,
-    syn::TyGenerics,
-    &syn::WhereClause,
+    DeTypeGenerics,
+    syn::TypeGenerics,
+    Option<&syn::WhereClause>,
 ) {
-    let de_impl_generics = DeImplGenerics(&params);
-    let de_ty_generics = DeTyGenerics(&params);
+    let de_impl_generics = DeImplGenerics(params);
+    let de_ty_generics = DeTypeGenerics(params);
     let (_, ty_generics, where_clause) = params.generics.split_for_impl();
     (de_impl_generics, de_ty_generics, ty_generics, where_clause)
 }
 
 fn is_unit(variant: &Variant) -> bool {
     match variant.style {
         Style::Unit => true,
         Style::Struct | Style::Tuple | Style::Newtype => false,
--- a/third_party/rust/serde_derive/src/fragment.rs
+++ b/third_party/rust/serde_derive/src/fragment.rs
@@ -2,16 +2,17 @@
 //
 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
 use quote::{ToTokens, Tokens};
+use syn::token;
 
 pub enum Fragment {
     /// Tokens that can be used as an expression.
     Expr(Tokens),
     /// Tokens that can be used inside a block. The surrounding curly braces are
     /// not part of these tokens.
     Block(Tokens),
 }
@@ -31,19 +32,17 @@ macro_rules! quote_block {
 /// Interpolate a fragment in place of an expression. This involves surrounding
 /// Block fragments in curly braces.
 pub struct Expr(pub Fragment);
 impl ToTokens for Expr {
     fn to_tokens(&self, out: &mut Tokens) {
         match self.0 {
             Fragment::Expr(ref expr) => expr.to_tokens(out),
             Fragment::Block(ref block) => {
-                out.append("{");
-                block.to_tokens(out);
-                out.append("}");
+                token::Brace::default().surround(out, |out| block.to_tokens(out));
             }
         }
     }
 }
 
 /// Interpolate a fragment as the statements of a block.
 pub struct Stmts(pub Fragment);
 impl ToTokens for Stmts {
@@ -58,22 +57,20 @@ impl ToTokens for Stmts {
 /// Interpolate a fragment as the value part of a `match` expression. This
 /// involves putting a comma after expressions and curly braces around blocks.
 pub struct Match(pub Fragment);
 impl ToTokens for Match {
     fn to_tokens(&self, out: &mut Tokens) {
         match self.0 {
             Fragment::Expr(ref expr) => {
                 expr.to_tokens(out);
-                out.append(",");
+                <Token![,]>::default().to_tokens(out);
             }
             Fragment::Block(ref block) => {
-                out.append("{");
-                block.to_tokens(out);
-                out.append("}");
+                token::Brace::default().surround(out, |out| block.to_tokens(out));
             }
         }
     }
 }
 
 impl AsRef<Tokens> for Fragment {
     fn as_ref(&self) -> &Tokens {
         match *self {
--- a/third_party/rust/serde_derive/src/lib.rs
+++ b/third_party/rust/serde_derive/src/lib.rs
@@ -17,48 +17,52 @@
 //! #
 //! # fn main() {}
 //! ```
 //!
 //! Please refer to [https://serde.rs/derive.html] for how to set this up.
 //!
 //! [https://serde.rs/derive.html]: https://serde.rs/derive.html
 
-#![doc(html_root_url = "https://docs.rs/serde_derive/1.0.27")]
-#![cfg_attr(feature = "cargo-clippy", allow(too_many_arguments))]
-#![cfg_attr(feature = "cargo-clippy", allow(used_underscore_binding))]
+#![doc(html_root_url = "https://docs.rs/serde_derive/1.0.35")]
+#![cfg_attr(feature = "cargo-clippy", allow(enum_variant_names, redundant_field_names,
+                                            too_many_arguments, used_underscore_binding))]
 // The `quote!` macro requires deep recursion.
-#![recursion_limit = "192"]
+#![recursion_limit = "512"]
 
 #[macro_use]
 extern crate quote;
+#[macro_use]
 extern crate syn;
 
 extern crate serde_derive_internals as internals;
 
 extern crate proc_macro;
+extern crate proc_macro2;
+
 use proc_macro::TokenStream;
+use syn::DeriveInput;
 
 #[macro_use]
 mod bound;
 #[macro_use]
 mod fragment;
 
 mod ser;
 mod de;
 
 #[proc_macro_derive(Serialize, attributes(serde))]
 pub fn derive_serialize(input: TokenStream) -> TokenStream {
-    let input = syn::parse_derive_input(&input.to_string()).unwrap();
+    let input: DeriveInput = syn::parse(input).unwrap();
     match ser::expand_derive_serialize(&input) {
-        Ok(expanded) => expanded.parse().unwrap(),
+        Ok(expanded) => expanded.into(),
         Err(msg) => panic!(msg),
     }
 }
 
 #[proc_macro_derive(Deserialize, attributes(serde))]
 pub fn derive_deserialize(input: TokenStream) -> TokenStream {
-    let input = syn::parse_derive_input(&input.to_string()).unwrap();
+    let input: DeriveInput = syn::parse(input).unwrap();
     match de::expand_derive_deserialize(&input) {
-        Ok(expanded) => expanded.parse().unwrap(),
+        Ok(expanded) => expanded.into(),
         Err(msg) => panic!(msg),
     }
 }
--- a/third_party/rust/serde_derive/src/ser.rs
+++ b/third_party/rust/serde_derive/src/ser.rs
@@ -1,43 +1,46 @@
 // Copyright 2017 Serde Developers
 //
 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use syn::{self, Ident};
+use syn::{self, Ident, Index, Member};
+use syn::spanned::Spanned;
 use quote::Tokens;
+use proc_macro2::Span;
 
 use bound;
 use fragment::{Fragment, Match, Stmts};
-use internals::ast::{Body, Container, Field, Style, Variant};
+use internals::ast::{Data, Container, Field, Style, Variant};
 use internals::{attr, Ctxt};
 
 use std::u32;
 
 pub fn expand_derive_serialize(input: &syn::DeriveInput) -> Result<Tokens, String> {
     let ctxt = Ctxt::new();
     let cont = Container::from_ast(&ctxt, input);
     precondition(&ctxt, &cont);
     try!(ctxt.check());
 
     let ident = &cont.ident;
     let params = Parameters::new(&cont);
     let (impl_generics, ty_generics, where_clause) = params.generics.split_for_impl();
-    let dummy_const = Ident::new(format!("_IMPL_SERIALIZE_FOR_{}", ident));
+    let dummy_const = Ident::new(&format!("_IMPL_SERIALIZE_FOR_{}", ident), Span::def_site());
     let body = Stmts(serialize_body(&cont, &params));
 
     let impl_block = if let Some(remote) = cont.attrs.remote() {
         let vis = &input.vis;
+        let fun = quote_spanned!(Span::call_site()=> serialize);
         quote! {
             impl #impl_generics #ident #ty_generics #where_clause {
-                #vis fn serialize<__S>(__self: &#remote #ty_generics, __serializer: __S) -> _serde::export::Result<__S::Ok, __S::Error>
+                #vis fn #fun<__S>(__self: &#remote #ty_generics, __serializer: __S) -> _serde::export::Result<__S::Ok, __S::Error>
                     where __S: _serde::Serializer
                 {
                     #body
                 }
             }
         }
     } else {
         quote! {
@@ -90,40 +93,40 @@ struct Parameters {
     /// Type has a `serde(remote = "...")` attribute.
     is_remote: bool,
 }
 
 impl Parameters {
     fn new(cont: &Container) -> Self {
         let is_remote = cont.attrs.remote().is_some();
         let self_var = if is_remote {
-            Ident::new("__self")
+            Ident::new("__self", Span::def_site())
         } else {
-            Ident::new("self")
+            Ident::new("self", Span::def_site())
         };
 
         let this = match cont.attrs.remote() {
             Some(remote) => remote.clone(),
-            None => cont.ident.clone().into(),
+            None => cont.ident.into(),
         };
 
         let generics = build_generics(cont);
 
         Parameters {
             self_var: self_var,
             this: this,
             generics: generics,
             is_remote: is_remote,
         }
     }
 
     /// Type name to use in error messages and `&'static str` arguments to
     /// various Serializer methods.
     fn type_name(&self) -> &str {
-        self.this.segments.last().unwrap().ident.as_ref()
+        self.this.segments.last().unwrap().value().ident.as_ref()
     }
 }
 
 // All the generics in the input, plus a bound `T: Serialize` for each generic
 // field type that will be serialized by us.
 fn build_generics(cont: &Container) -> syn::Generics {
     let generics = bound::without_defaults(cont.generics);
 
@@ -131,62 +134,62 @@ fn build_generics(cont: &Container) -> s
         bound::with_where_predicates_from_fields(cont, &generics, attr::Field::ser_bound);
 
     match cont.attrs.ser_bound() {
         Some(predicates) => bound::with_where_predicates(&generics, predicates),
         None => bound::with_bound(
             cont,
             &generics,
             needs_serialize_bound,
-            &path!(_serde::Serialize),
+            &parse_quote!(_serde::Serialize),
         ),
     }
 }
 
 // Fields with a `skip_serializing` or `serialize_with` attribute, or which
 // belong to a variant with a `serialize_with` attribute, are not serialized by
 // us so we do not generate a bound. Fields with a `bound` attribute specify
 // their own bound so we do not generate one. All other fields may need a `T:
 // Serialize` bound where T is the type of the field.
 fn needs_serialize_bound(field: &attr::Field, variant: Option<&attr::Variant>) -> bool {
     !field.skip_serializing() && field.serialize_with().is_none() && field.ser_bound().is_none()
         && variant.map_or(true, |variant| variant.serialize_with().is_none())
 }
 
 fn serialize_body(cont: &Container, params: &Parameters) -> Fragment {
-    if let Some(into_type) = cont.attrs.into_type() {
-        serialize_into(params, into_type)
+    if let Some(type_into) = cont.attrs.type_into() {
+        serialize_into(params, type_into)
     } else {
-        match cont.body {
-            Body::Enum(_, ref variants) => serialize_enum(params, variants, &cont.attrs),
-            Body::Struct(Style::Struct, ref fields) => {
+        match cont.data {
+            Data::Enum(_, ref variants) => serialize_enum(params, variants, &cont.attrs),
+            Data::Struct(Style::Struct, ref fields) => {
                 if fields.iter().any(|field| field.ident.is_none()) {
                     panic!("struct has unnamed fields");
                 }
                 serialize_struct(params, fields, &cont.attrs)
             }
-            Body::Struct(Style::Tuple, ref fields) => {
+            Data::Struct(Style::Tuple, ref fields) => {
                 if fields.iter().any(|field| field.ident.is_some()) {
                     panic!("tuple struct has named fields");
                 }
                 serialize_tuple_struct(params, fields, &cont.attrs)
             }
-            Body::Struct(Style::Newtype, ref fields) => {
+            Data::Struct(Style::Newtype, ref fields) => {
                 serialize_newtype_struct(params, &fields[0], &cont.attrs)
             }
-            Body::Struct(Style::Unit, _) => serialize_unit_struct(&cont.attrs),
+            Data::Struct(Style::Unit, _) => serialize_unit_struct(&cont.attrs),
         }
     }
 }
 
-fn serialize_into(params: &Parameters, into_type: &syn::Ty) -> Fragment {
+fn serialize_into(params: &Parameters, type_into: &syn::Type) -> Fragment {
     let self_var = &params.self_var;
     quote_block! {
         _serde::Serialize::serialize(
-            &_serde::export::Into::<#into_type>::into(_serde::export::Clone::clone(#self_var)),
+            &_serde::export::Into::<#type_into>::into(_serde::export::Clone::clone(#self_var)),
             __serializer)
     }
 }
 
 fn serialize_unit_struct(cattrs: &attr::Container) -> Fragment {
     let type_name = cattrs.name().serialize_name();
 
     quote_expr! {
@@ -196,89 +199,139 @@ fn serialize_unit_struct(cattrs: &attr::
 
 fn serialize_newtype_struct(
     params: &Parameters,
     field: &Field,
     cattrs: &attr::Container,
 ) -> Fragment {
     let type_name = cattrs.name().serialize_name();
 
-    let mut field_expr = get_field(params, field, 0);
+    let mut field_expr = get_member(params, field, &Member::Unnamed(Index {
+        index: 0,
+        span: Span::call_site(),
+    }));
     if let Some(path) = field.attrs.serialize_with() {
-        field_expr = wrap_serialize_field_with(params, field.ty, path, field_expr);
+        field_expr = wrap_serialize_field_with(params, field.ty, path, &field_expr);
     }
 
+    let span = Span::def_site().located_at(field.original.span());
+    let func = quote_spanned!(span=> _serde::Serializer::serialize_newtype_struct);
     quote_expr! {
-        _serde::Serializer::serialize_newtype_struct(__serializer, #type_name, #field_expr)
+        #func(__serializer, #type_name, #field_expr)
     }
 }
 
 fn serialize_tuple_struct(
     params: &Parameters,
     fields: &[Field],
     cattrs: &attr::Container,
 ) -> Fragment {
     let serialize_stmts = serialize_tuple_struct_visitor(
         fields,
         params,
         false,
-        quote!(_serde::ser::SerializeTupleStruct::serialize_field),
+        &TupleTrait::SerializeTupleStruct,
     );
 
     let type_name = cattrs.name().serialize_name();
     let len = serialize_stmts.len();
     let let_mut = mut_if(len > 0);
 
     quote_block! {
         let #let_mut __serde_state = try!(_serde::Serializer::serialize_tuple_struct(__serializer, #type_name, #len));
         #(#serialize_stmts)*
         _serde::ser::SerializeTupleStruct::end(__serde_state)
     }
 }
 
 fn serialize_struct(params: &Parameters, fields: &[Field], cattrs: &attr::Container) -> Fragment {
-    assert!(fields.len() as u64 <= u32::MAX as u64);
+    assert!(fields.len() as u64 <= u64::from(u32::MAX));
 
+    if cattrs.has_flatten() {
+        serialize_struct_as_map(params, fields, cattrs)
+    } else {
+        serialize_struct_as_struct(params, fields, cattrs)
+    }
+}
+
+fn serialize_struct_as_struct(params: &Parameters, fields: &[Field], cattrs: &attr::Container) -> Fragment {
     let serialize_fields = serialize_struct_visitor(
         fields,
         params,
         false,
-        quote!(_serde::ser::SerializeStruct::serialize_field),
-        quote!(_serde::ser::SerializeStruct::skip_field),
+        &StructTrait::SerializeStruct,
     );
 
     let type_name = cattrs.name().serialize_name();
 
     let mut serialized_fields = fields
         .iter()
         .filter(|&field| !field.attrs.skip_serializing())
         .peekable();
 
     let let_mut = mut_if(serialized_fields.peek().is_some());
 
     let len = serialized_fields
         .map(|field| match field.attrs.skip_serializing_if() {
             None => quote!(1),
             Some(path) => {
-                let ident = field.ident.clone().expect("struct has unnamed fields");
-                let field_expr = get_field(params, field, ident);
+                let ident = field.ident.expect("struct has unnamed fields");
+                let field_expr = get_member(params, field, &Member::Named(ident));
                 quote!(if #path(#field_expr) { 0 } else { 1 })
             }
         })
         .fold(quote!(0), |sum, expr| quote!(#sum + #expr));
 
     quote_block! {
         let #let_mut __serde_state = try!(_serde::Serializer::serialize_struct(__serializer, #type_name, #len));
         #(#serialize_fields)*
         _serde::ser::SerializeStruct::end(__serde_state)
     }
 }
 
+fn serialize_struct_as_map(params: &Parameters, fields: &[Field], cattrs: &attr::Container) -> Fragment {
+    let serialize_fields = serialize_struct_visitor(
+        fields,
+        params,
+        false,
+        &StructTrait::SerializeMap,
+    );
+
+    let mut serialized_fields = fields
+        .iter()
+        .filter(|&field| !field.attrs.skip_serializing())
+        .peekable();
+
+    let let_mut = mut_if(serialized_fields.peek().is_some());
+
+    let len = if cattrs.has_flatten() {
+        quote!(_serde::export::None)
+    } else {
+        let len = serialized_fields
+            .map(|field| match field.attrs.skip_serializing_if() {
+                None => quote!(1),
+                Some(path) => {
+                    let ident = field.ident.expect("struct has unnamed fields");
+                    let field_expr = get_member(params, field, &Member::Named(ident));
+                    quote!(if #path(#field_expr) { 0 } else { 1 })
+                }
+            })
+            .fold(quote!(0), |sum, expr| quote!(#sum + #expr));
+        quote!(_serde::export::Some(#len))
+    };
+
+    quote_block! {
+        let #let_mut __serde_state = try!(_serde::Serializer::serialize_map(__serializer, #len));
+        #(#serialize_fields)*
+        _serde::ser::SerializeMap::end(__serde_state)
+    }
+}
+
 fn serialize_enum(params: &Parameters, variants: &[Variant], cattrs: &attr::Container) -> Fragment {
-    assert!(variants.len() as u64 <= u32::MAX as u64);
+    assert!(variants.len() as u64 <= u64::from(u32::MAX));
 
     let self_var = &params.self_var;
 
     let arms: Vec<_> = variants
         .iter()
         .enumerate()
         .map(|(variant_index, variant)| {
             serialize_variant(params, variant, variant_index as u32, cattrs)
@@ -294,17 +347,17 @@ fn serialize_enum(params: &Parameters, v
 
 fn serialize_variant(
     params: &Parameters,
     variant: &Variant,
     variant_index: u32,
     cattrs: &attr::Container,
 ) -> Tokens {
     let this = &params.this;
-    let variant_ident = variant.ident.clone();
+    let variant_ident = variant.ident;
 
     if variant.attrs.skip_serializing() {
         let skipped_msg = format!(
             "the enum variant {}::{} cannot be serialized",
             params.type_name(),
             variant_ident
         );
         let skipped_err = quote! {
@@ -328,26 +381,26 @@ fn serialize_variant(
             }
             Style::Newtype => {
                 quote! {
                     #this::#variant_ident(ref __field0)
                 }
             }
             Style::Tuple => {
                 let field_names =
-                    (0..variant.fields.len()).map(|i| Ident::new(format!("__field{}", i)));
+                    (0..variant.fields.len()).map(|i| Ident::new(&format!("__field{}", i), Span::def_site()));
                 quote! {
                     #this::#variant_ident(#(ref #field_names),*)
                 }
             }
             Style::Struct => {
                 let fields = variant
                     .fields
                     .iter()
-                    .map(|f| f.ident.clone().expect("struct variant has unnamed fields"));
+                    .map(|f| f.ident.expect("struct variant has unnamed fields"));
                 quote! {
                     #this::#variant_ident { #(ref #fields),* }
                 }
             }
         };
 
         let body = Match(match *cattrs.tag() {
             attr::EnumTag::External => {
@@ -374,17 +427,17 @@ fn serialize_externally_tagged_variant(
     variant: &Variant,
     variant_index: u32,
     cattrs: &attr::Container,
 ) -> Fragment {
     let type_name = cattrs.name().serialize_name();
     let variant_name = variant.attrs.name().serialize_name();
 
     if let Some(path) = variant.attrs.serialize_with() {
-        let ser = wrap_serialize_variant_with(params, path, &variant);
+        let ser = wrap_serialize_variant_with(params, path, variant);
         return quote_expr! {
             _serde::Serializer::serialize_newtype_variant(
                 __serializer,
                 #type_name,
                 #variant_index,
                 #variant_name,
                 #ser,
             )
@@ -401,17 +454,17 @@ fn serialize_externally_tagged_variant(
                     #variant_name,
                 )
             }
         }
         Style::Newtype => {
             let field = &variant.fields[0];
             let mut field_expr = quote!(__field0);
             if let Some(path) = field.attrs.serialize_with() {
-                field_expr = wrap_serialize_field_with(params, field.ty, path, field_expr);
+                field_expr = wrap_serialize_field_with(params, field.ty, path, &field_expr);
             }
 
             quote_expr! {
                 _serde::Serializer::serialize_newtype_variant(
                     __serializer,
                     #type_name,
                     #variant_index,
                     #variant_name,
@@ -448,17 +501,17 @@ fn serialize_internally_tagged_variant(
 ) -> Fragment {
     let type_name = cattrs.name().serialize_name();
     let variant_name = variant.attrs.name().serialize_name();
 
     let enum_ident_str = params.type_name();
     let variant_ident_str = variant.ident.as_ref();
 
     if let Some(path) = variant.attrs.serialize_with() {
-        let ser = wrap_serialize_variant_with(params, path, &variant);
+        let ser = wrap_serialize_variant_with(params, path, variant);
         return quote_expr! {
             _serde::private::ser::serialize_tagged_newtype(
                 __serializer,
                 #enum_ident_str,
                 #variant_ident_str,
                 #tag,
                 #variant_name,
                 #ser,
@@ -475,17 +528,17 @@ fn serialize_internally_tagged_variant(
                     &mut __struct, #tag, #variant_name));
                 _serde::ser::SerializeStruct::end(__struct)
             }
         }
         Style::Newtype => {
             let field = &variant.fields[0];
             let mut field_expr = quote!(__field0);
             if let Some(path) = field.attrs.serialize_with() {
-                field_expr = wrap_serialize_field_with(params, field.ty, path, field_expr);
+                field_expr = wrap_serialize_field_with(params, field.ty, path, &field_expr);
             }
 
             quote_expr! {
                 _serde::private::ser::serialize_tagged_newtype(
                     __serializer,
                     #enum_ident_str,
                     #variant_ident_str,
                     #tag,
@@ -514,17 +567,17 @@ fn serialize_adjacently_tagged_variant(
     tag: &str,
     content: &str,
 ) -> Fragment {
     let this = &params.this;
     let type_name = cattrs.name().serialize_name();
     let variant_name = variant.attrs.name().serialize_name();
 
     let inner = Stmts(if let Some(path) = variant.attrs.serialize_with() {
-        let ser = wrap_serialize_variant_with(params, path, &variant);
+        let ser = wrap_serialize_variant_with(params, path, variant);
         quote_expr! {
             _serde::Serialize::serialize(#ser, __serializer)
         }
     } else {
         match variant.style {
             Style::Unit => {
                 return quote_block! {
                     let mut __struct = try!(_serde::Serializer::serialize_struct(
@@ -533,17 +586,17 @@ fn serialize_adjacently_tagged_variant(
                         &mut __struct, #tag, #variant_name));
                     _serde::ser::SerializeStruct::end(__struct)
                 };
             }
             Style::Newtype => {
                 let field = &variant.fields[0];
                 let mut field_expr = quote!(__field0);
                 if let Some(path) = field.attrs.serialize_with() {
-                    field_expr = wrap_serialize_field_with(params, field.ty, path, field_expr);
+                    field_expr = wrap_serialize_field_with(params, field.ty, path, &field_expr);
                 }
 
                 quote_expr! {
                     _serde::Serialize::serialize(#field_expr, __serializer)
                 }
             }
             Style::Tuple => {
                 serialize_tuple_variant(TupleVariant::Untagged, params, &variant.fields)
@@ -553,32 +606,32 @@ fn serialize_adjacently_tagged_variant(
                 params,
                 &variant.fields,
                 &variant_name,
             ),
         }
     });
 
     let fields_ty = variant.fields.iter().map(|f| &f.ty);
-    let ref fields_ident: Vec<_> = match variant.style {
+    let fields_ident: &Vec<_> = &match variant.style {
         Style::Unit => {
             if variant.attrs.serialize_with().is_some() {
                 vec![]
             } else {
                 unreachable!()
             }
         }
-        Style::Newtype => vec![Ident::new("__field0")],
+        Style::Newtype => vec![Ident::new("__field0", Span::def_site())],
         Style::Tuple => (0..variant.fields.len())
-            .map(|i| Ident::new(format!("__field{}", i)))
+            .map(|i| Ident::new(&format!("__field{}", i), Span::def_site()))
             .collect(),
         Style::Struct => variant
             .fields
             .iter()
-            .map(|f| f.ident.clone().expect("struct variant has unnamed fields"))
+            .map(|f| f.ident.expect("struct variant has unnamed fields"))
             .collect(),
     };
 
     let (_, ty_generics, where_clause) = params.generics.split_for_impl();
 
     let wrapper_generics = if let Style::Unit = variant.style {
         params.generics.clone()
     } else {
@@ -615,33 +668,33 @@ fn serialize_adjacently_tagged_variant(
 }
 
 fn serialize_untagged_variant(
     params: &Parameters,
     variant: &Variant,
     cattrs: &attr::Container,
 ) -> Fragment {
     if let Some(path) = variant.attrs.serialize_with() {
-        let ser = wrap_serialize_variant_with(params, path, &variant);
+        let ser = wrap_serialize_variant_with(params, path, variant);
         return quote_expr! {
             _serde::Serialize::serialize(#ser, __serializer)
         };
     }
 
     match variant.style {
         Style::Unit => {
             quote_expr! {
                 _serde::Serializer::serialize_unit(__serializer)
             }
         }
         Style::Newtype => {
             let field = &variant.fields[0];
             let mut field_expr = quote!(__field0);
             if let Some(path) = field.attrs.serialize_with() {
-                field_expr = wrap_serialize_field_with(params, field.ty, path, field_expr);
+                field_expr = wrap_serialize_field_with(params, field.ty, path, &field_expr);
             }
 
             quote_expr! {
                 _serde::Serialize::serialize(#field_expr, __serializer)
             }
         }
         Style::Tuple => serialize_tuple_variant(TupleVariant::Untagged, params, &variant.fields),
         Style::Struct => {
@@ -660,24 +713,22 @@ enum TupleVariant {
     Untagged,
 }
 
 fn serialize_tuple_variant(
     context: TupleVariant,
     params: &Parameters,
     fields: &[Field],
 ) -> Fragment {
-    let method = match context {
-        TupleVariant::ExternallyTagged { .. } => {
-            quote!(_serde::ser::SerializeTupleVariant::serialize_field)
-        }
-        TupleVariant::Untagged => quote!(_serde::ser::SerializeTuple::serialize_element),
+    let tuple_trait = match context {
+        TupleVariant::ExternallyTagged { .. } => TupleTrait::SerializeTupleVariant,
+        TupleVariant::Untagged => TupleTrait::SerializeTuple,
     };
 
-    let serialize_stmts = serialize_tuple_struct_visitor(fields, params, true, method);
+    let serialize_stmts = serialize_tuple_struct_visitor(fields, params, true, &tuple_trait);
 
     let len = serialize_stmts.len();
     let let_mut = mut_if(len > 0);
 
     match context {
         TupleVariant::ExternallyTagged {
             type_name,
             variant_index,
@@ -719,39 +770,37 @@ enum StructVariant<'a> {
 }
 
 fn serialize_struct_variant<'a>(
     context: StructVariant<'a>,
     params: &Parameters,
     fields: &[Field],
     name: &str,
 ) -> Fragment {
-    let (method, skip_method) = match context {
+    let struct_trait = match context {
         StructVariant::ExternallyTagged { .. } => (
-            quote!(_serde::ser::SerializeStructVariant::serialize_field),
-            quote!(_serde::ser::SerializeStructVariant::skip_field),
+            StructTrait::SerializeStructVariant
         ),
         StructVariant::InternallyTagged { .. } | StructVariant::Untagged => (
-            quote!(_serde::ser::SerializeStruct::serialize_field),
-            quote!(_serde::ser::SerializeStruct::skip_field),
+            StructTrait::SerializeStruct
         ),
     };
 
-    let serialize_fields = serialize_struct_visitor(fields, params, true, method, skip_method);
+    let serialize_fields = serialize_struct_visitor(fields, params, true, &struct_trait);
 
     let mut serialized_fields = fields
         .iter()
         .filter(|&field| !field.attrs.skip_serializing())
         .peekable();
 
     let let_mut = mut_if(serialized_fields.peek().is_some());
 
     let len = serialized_fields
         .map(|field| {
-            let ident = field.ident.clone().expect("struct has unnamed fields");
+            let ident = field.ident.expect("struct has unnamed fields");
 
             match field.attrs.skip_serializing_if() {
                 Some(path) => quote!(if #path(#ident) { 0 } else { 1 }),
                 None => quote!(1),
             }
         })
         .fold(quote!(0), |sum, expr| quote!(#sum + #expr));
 
@@ -801,151 +850,174 @@ fn serialize_struct_variant<'a>(
         }
     }
 }
 
 fn serialize_tuple_struct_visitor(
     fields: &[Field],
     params: &Parameters,
     is_enum: bool,
-    func: Tokens,
+    tuple_trait: &TupleTrait,
 ) -> Vec<Tokens> {
     fields
         .iter()
         .enumerate()
         .map(|(i, field)| {
             let mut field_expr = if is_enum {
-                let id = Ident::new(format!("__field{}", i));
+                let id = Ident::new(&format!("__field{}", i), Span::def_site());
                 quote!(#id)
             } else {
-                get_field(params, field, i)
+                get_member(params, field, &Member::Unnamed(Index {
+                    index: i as u32,
+                    span: Span::call_site(),
+                }))
             };
 
             let skip = field
                 .attrs
                 .skip_serializing_if()
                 .map(|path| quote!(#path(#field_expr)));
 
             if let Some(path) = field.attrs.serialize_with() {
-                field_expr = wrap_serialize_field_with(params, field.ty, path, field_expr);
+                field_expr = wrap_serialize_field_with(params, field.ty, path, &field_expr);
             }
 
+            let span = Span::def_site().located_at(field.original.span());
+            let func = tuple_trait.serialize_element(span);
             let ser = quote! {
                 try!(#func(&mut __serde_state, #field_expr));
             };
 
             match skip {
                 None => ser,
                 Some(skip) => quote!(if !#skip { #ser }),
             }
         })
         .collect()
 }
 
 fn serialize_struct_visitor(
     fields: &[Field],
     params: &Parameters,
     is_enum: bool,
-    func: Tokens,
-    skip_func: Tokens,
+    struct_trait: &StructTrait,
 ) -> Vec<Tokens> {
     fields
         .iter()
         .filter(|&field| !field.attrs.skip_serializing())
         .map(|field| {
-            let field_ident = field.ident.clone().expect("struct has unnamed field");
+            let field_ident = field.ident.expect("struct has unnamed field");
+
             let mut field_expr = if is_enum {
                 quote!(#field_ident)
             } else {
-                get_field(params, field, field_ident)
+                get_member(params, field, &Member::Named(field_ident))
             };
 
             let key_expr = field.attrs.name().serialize_name();
 
             let skip = field
                 .attrs
                 .skip_serializing_if()
                 .map(|path| quote!(#path(#field_expr)));
 
             if let Some(path) = field.attrs.serialize_with() {
-                field_expr = wrap_serialize_field_with(params, field.ty, path, field_expr);
+                field_expr = wrap_serialize_field_with(params, field.ty, path, &field_expr);
             }
 
-            let ser = quote! {
-                try!(#func(&mut __serde_state, #key_expr, #field_expr));
+            let span = Span::def_site().located_at(field.original.span());
+            let ser = if field.attrs.flatten() {
+                quote! {
+                    try!(_serde::Serialize::serialize(&#field_expr, _serde::private::ser::FlatMapSerializer(&mut __serde_state)));
+                }
+            } else {
+                let func = struct_trait.serialize_field(span);
+                quote! {
+                    try!(#func(&mut __serde_state, #key_expr, #field_expr));
+                }
             };
 
             match skip {
                 None => ser,
                 Some(skip) => {
-                    quote! {
-                        if !#skip {
-                            #ser
-                        } else {
-                            try!(#skip_func(&mut __serde_state, #key_expr));
+                    if let Some(skip_func) = struct_trait.skip_field(span) {
+                        quote! {
+                            if !#skip {
+                                #ser
+                            } else {
+                                try!(#skip_func(&mut __serde_state, #key_expr));
+                            }
+                        }
+                    } else {
+                        quote! {
+                            if !#skip {
+                                #ser
+                            }
                         }
                     }
                 }
             }
         })
         .collect()
 }
 
 fn wrap_serialize_field_with(
     params: &Parameters,
-    field_ty: &syn::Ty,
-    serialize_with: &syn::Path,
-    field_expr: Tokens,
+    field_ty: &syn::Type,
+    serialize_with: &syn::ExprPath,
+    field_expr: &Tokens,
 ) -> Tokens {
     wrap_serialize_with(params, serialize_with, &[field_ty], &[quote!(#field_expr)])
 }
 
 fn wrap_serialize_variant_with(
     params: &Parameters,
-    serialize_with: &syn::Path,
+    serialize_with: &syn::ExprPath,
     variant: &Variant,
 ) -> Tokens {
     let field_tys: Vec<_> = variant.fields.iter().map(|field| field.ty).collect();
     let field_exprs: Vec<_> = variant
         .fields
         .iter()
         .enumerate()
         .map(|(i, field)| {
             let id = field
                 .ident
-                .as_ref()
-                .map_or_else(|| Ident::new(format!("__field{}", i)), |id| id.clone());
+                .unwrap_or_else(|| Ident::new(&format!("__field{}", i), Span::def_site()));
             quote!(#id)
         })
         .collect();
     wrap_serialize_with(
         params,
         serialize_with,
         field_tys.as_slice(),
         field_exprs.as_slice(),
     )
 }
 
 fn wrap_serialize_with(
     params: &Parameters,
-    serialize_with: &syn::Path,
-    field_tys: &[&syn::Ty],
+    serialize_with: &syn::ExprPath,
+    field_tys: &[&syn::Type],
     field_exprs: &[Tokens],
 ) -> Tokens {
     let this = &params.this;
     let (_, ty_generics, where_clause) = params.generics.split_for_impl();
 
-    let wrapper_generics = if field_exprs.len() == 0 {
+    let wrapper_generics = if field_exprs.is_empty() {
         params.generics.clone()
     } else {
         bound::with_lifetime_bound(&params.generics, "'__a")
     };
     let (wrapper_impl_generics, wrapper_ty_generics, _) = wrapper_generics.split_for_impl();
 
-    let field_access = (0..field_exprs.len()).map(|n| Ident::new(format!("{}", n)));
+    let field_access = (0..field_exprs.len()).map(|n| Member::Unnamed(Index {
+        index: n as u32,
+        span: Span::call_site(),
+    }));
 
     quote!({
         struct __SerializeWith #wrapper_impl_generics #where_clause {
             values: (#(&'__a #field_tys, )*),
             phantom: _serde::export::PhantomData<#this #ty_generics>,
         }
 
         impl #wrapper_impl_generics _serde::Serialize for __SerializeWith #wrapper_ty_generics #where_clause {
@@ -972,32 +1044,84 @@ fn wrap_serialize_with(
 fn mut_if(is_mut: bool) -> Option<Tokens> {
     if is_mut {
         Some(quote!(mut))
     } else {
         None
     }
 }
 
-fn get_field<I>(params: &Parameters, field: &Field, ident: I) -> Tokens
-where
-    I: Into<Ident>,
-{
+fn get_member(params: &Parameters, field: &Field, member: &Member) -> Tokens {
     let self_var = &params.self_var;
     match (params.is_remote, field.attrs.getter()) {
         (false, None) => {
-            let ident = ident.into();
-            quote!(&#self_var.#ident)
+            quote_spanned!(Span::call_site()=> &#self_var.#member)
         }
         (true, None) => {
+            let inner = quote_spanned!(Span::call_site()=> &#self_var.#member);
             let ty = field.ty;
-            let ident = ident.into();
-            quote!(_serde::private::ser::constrain::<#ty>(&#self_var.#ident))
+            quote!(_serde::private::ser::constrain::<#ty>(#inner))
         }
         (true, Some(getter)) => {
             let ty = field.ty;
             quote!(_serde::private::ser::constrain::<#ty>(&#getter(#self_var)))
         }
         (false, Some(_)) => {
             unreachable!("getter is only allowed for remote impls");
         }
     }
 }
+
+enum StructTrait {
+    SerializeMap,
+    SerializeStruct,
+    SerializeStructVariant,
+}
+
+impl StructTrait {
+    fn serialize_field(&self, span: Span) -> Tokens {
+        match *self {
+            StructTrait::SerializeMap => {
+                quote_spanned!(span=> _serde::ser::SerializeMap::serialize_entry)
+            }
+            StructTrait::SerializeStruct => {
+                quote_spanned!(span=> _serde::ser::SerializeStruct::serialize_field)
+            }
+            StructTrait::SerializeStructVariant => {
+                quote_spanned!(span=> _serde::ser::SerializeStructVariant::serialize_field)
+            }
+        }
+    }
+
+    fn skip_field(&self, span: Span) -> Option<Tokens> {
+        match *self {
+            StructTrait::SerializeMap => None,
+            StructTrait::SerializeStruct => Some({
+                quote_spanned!(span=> _serde::ser::SerializeStruct::skip_field)
+            }),
+            StructTrait::SerializeStructVariant => Some({
+                quote_spanned!(span=> _serde::ser::SerializeStructVariant::skip_field)
+            })
+        }
+    }
+}
+
+enum TupleTrait {
+    SerializeTuple,
+    SerializeTupleStruct,
+    SerializeTupleVariant,
+}
+
+impl TupleTrait {
+    fn serialize_element(&self, span: Span) -> Tokens {
+        match *self {
+            TupleTrait::SerializeTuple => {
+                quote_spanned!(span=> _serde::ser::SerializeTuple::serialize_element)
+            }
+            TupleTrait::SerializeTupleStruct => {
+                quote_spanned!(span=> _serde::ser::SerializeTupleStruct::serialize_field)
+            }
+            TupleTrait::SerializeTupleVariant => {
+                quote_spanned!(span=> _serde::ser::SerializeTupleVariant::serialize_field)
+            }
+        }
+    }
+}
--- a/third_party/rust/serde_derive_internals/.cargo-checksum.json
+++ b/third_party/rust/serde_derive_internals/.cargo-checksum.json
@@ -1,1 +1,1 @@
-{"files":{"Cargo.toml":"714507185f11d1717d52710ca58df5c6427a808590543bb3b33e9b05bb8bbf92","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"6485b8ed310d3f0340bf1ad1f47645069ce4069dcc6bb46c7d5c6faf41de1fdb","README.md":"7dc6376a88195594cd6b43cb891aad10f57144ff737178b55d046aa04739b43a","src/ast.rs":"803beccc3b527f926596acfe555fcc0069beebb23ffe1fb8cc0d2faac44fa8f7","src/attr.rs":"af9afd1a768db4d272ff13ff06412eae8d5edc57be0a29b396de8895499436c1","src/case.rs":"8d50d3db3c74c569c75bcf4b285d21bf176940a2efae0656bef769334d62793c","src/check.rs":"dd9d9723bd4d21787cdcff00d6b672f16276088ff0373d20e3fb3eca61580518","src/ctxt.rs":"e842cc73bfd648f14f3bad73e3db321d6cd0f94d255d59e81ed768486fe5deda","src/lib.rs":"5546043bf2cc6d81c1f323df0bd391ad53125f759f217e46e18d035df422b981"},"package":null}
\ No newline at end of file
+{"files":{"Cargo.toml":"b9774130c25f51069e3d6d1617d9bbb63d89caf11a30dce332d4553f73f0d07c","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"6485b8ed310d3f0340bf1ad1f47645069ce4069dcc6bb46c7d5c6faf41de1fdb","README.md":"7dc6376a88195594cd6b43cb891aad10f57144ff737178b55d046aa04739b43a","src/ast.rs":"30d0f819638c1e7482529f3449980e116cd106ad5f1b5552f653390af5387ba3","src/attr.rs":"0a18342c91f03960620f7baa307937806c17d52564f3dbe234c3e67480242d6a","src/case.rs":"03a97fc3996614153cc5bbd33b5df9d55954407c4d37c5a656f70cbc76817708","src/check.rs":"a7f296d4ca97eee073c7104d888b15022d279a2a04c27dacd11afaf897858461","src/ctxt.rs":"30b38bc10c9d90ec1186ad4ab2159339d65bfaa5a1a51b5900b0ca52fbe526d1","src/lib.rs":"9e4fbabbdbd0a5c7fd486bfd0715eb8278cc2a07a8cf5e5fdbdf6a543d123081"},"package":null}
\ No newline at end of file
--- a/third_party/rust/serde_derive_internals/Cargo.toml
+++ b/third_party/rust/serde_derive_internals/Cargo.toml
@@ -1,19 +1,19 @@
 [package]
 name = "serde_derive_internals"
-version = "0.19.0" # remember to update html_root_url
+version = "0.22.1" # remember to update html_root_url
 authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>", "David Tolnay <dtolnay@gmail.com>"]
 license = "MIT/Apache-2.0"
 description = "AST representation used by Serde derive macros. Unstable."
 homepage = "https://serde.rs"
 repository = "https://github.com/serde-rs/serde"
 documentation = "https://docs.serde.rs/serde_derive_internals/"
 keywords = ["serde", "serialization"]
 readme = "README.md"
 include = ["Cargo.toml", "src/**/*.rs", "README.md", "LICENSE-APACHE", "LICENSE-MIT"]
 
 [dependencies]
-syn = { version = "0.11.10", default-features = false, features = ["parsing"] }
-synom = "0.11"
+proc-macro2 = "0.2"
+syn = { version = "0.12", default-features = false, features = ["derive", "parsing", "clone-impls", "extra-traits"] }
 
 [badges]
 travis-ci = { repository = "serde-rs/serde" }
--- a/third_party/rust/serde_derive_internals/src/ast.rs
+++ b/third_party/rust/serde_derive_internals/src/ast.rs
@@ -5,40 +5,42 @@
 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
 use syn;
 use attr;
 use check;
 use Ctxt;
+use syn::punctuated::Punctuated;
 
 pub struct Container<'a> {
     pub ident: syn::Ident,
     pub attrs: attr::Container,
-    pub body: Body<'a>,
+    pub data: Data<'a>,
     pub generics: &'a syn::Generics,
 }
 
-pub enum Body<'a> {
+pub enum Data<'a> {
     Enum(Repr, Vec<Variant<'a>>),
     Struct(Style, Vec<Field<'a>>),
 }
 
 pub struct Variant<'a> {
     pub ident: syn::Ident,
     pub attrs: attr::Variant,
     pub style: Style,
     pub fields: Vec<Field<'a>>,
 }
 
 pub struct Field<'a> {
     pub ident: Option<syn::Ident>,
     pub attrs: attr::Field,
-    pub ty: &'a syn::Ty,
+    pub ty: &'a syn::Type,
+    pub original: &'a syn::Field,
 }
 
 pub struct Repr {
     pub int_repr: Option<&'static str>,
     pub c_repr: bool,
     pub other_repr: bool,
 }
 
@@ -47,59 +49,70 @@ pub enum Style {
     Struct,
     Tuple,
     Newtype,
     Unit,
 }
 
 impl<'a> Container<'a> {
     pub fn from_ast(cx: &Ctxt, item: &'a syn::DeriveInput) -> Container<'a> {
-        let attrs = attr::Container::from_ast(cx, item);
+        let mut attrs = attr::Container::from_ast(cx, item);
 
-        let mut body = match item.body {
-            syn::Body::Enum(ref variants) => {
-                let (repr, variants) = enum_from_ast(cx, item, variants, &attrs.default());
-                Body::Enum(repr, variants)
+        let mut data = match item.data {
+            syn::Data::Enum(ref data) => {
+                let (repr, variants) = enum_from_ast(cx, item, &data.variants, attrs.default());
+                Data::Enum(repr, variants)
             }
-            syn::Body::Struct(ref variant_data) => {
-                let (style, fields) = struct_from_ast(cx, variant_data, None, &attrs.default());
-                Body::Struct(style, fields)
+            syn::Data::Struct(ref data) => {
+                let (style, fields) = struct_from_ast(cx, &data.fields, None, attrs.default());
+                Data::Struct(style, fields)
+            }
+            syn::Data::Union(_) => {
+                panic!("Serde does not support derive for unions");
             }
         };
 
-        match body {
-            Body::Enum(_, ref mut variants) => for ref mut variant in variants {
+        let mut has_flatten = false;
+        match data {
+            Data::Enum(_, ref mut variants) => for variant in variants {
                 variant.attrs.rename_by_rule(attrs.rename_all());
-                for ref mut field in &mut variant.fields {
+                for field in &mut variant.fields {
                     field.attrs.rename_by_rule(variant.attrs.rename_all());
                 }
             },
-            Body::Struct(_, ref mut fields) => for field in fields {
+            Data::Struct(_, ref mut fields) => for field in fields {
+                if field.attrs.flatten() {
+                    has_flatten = true;
+                }
                 field.attrs.rename_by_rule(attrs.rename_all());
             },
         }
 
+        if has_flatten {
+            attrs.mark_has_flatten();
+        }
+
         let item = Container {
-            ident: item.ident.clone(),
+            ident: item.ident,
             attrs: attrs,
-            body: body,
+            data: data,
             generics: &item.generics,
         };
         check::check(cx, &item);
         item
     }
 }
 
-impl<'a> Body<'a> {
+impl<'a> Data<'a> {
     pub fn all_fields(&'a self) -> Box<Iterator<Item = &'a Field<'a>> + 'a> {
         match *self {
-            Body::Enum(_, ref variants) => {
+            Data::Enum(_, ref variants) => {
                 Box::new(variants.iter().flat_map(|variant| variant.fields.iter()))
             }
-            Body::Struct(_, ref fields) => Box::new(fields.iter()),
+            Data::Struct(_, ref fields) => Box::new(fields.iter()),
         }
     }
 
     pub fn has_getter(&self) -> bool {
         self.all_fields().any(|f| f.attrs.getter().is_some())
     }
 }
 
@@ -121,28 +134,28 @@ impl Repr {
             self.int_repr
         }
     }
 }
 
 fn enum_from_ast<'a>(
     cx: &Ctxt, 
     item: &'a syn::DeriveInput, 
-    variants: &'a [syn::Variant], 
+    variants: &'a Punctuated<syn::Variant, Token![,]>,
     container_default: &attr::Default
 ) -> (Repr, Vec<Variant<'a>>) {
     let variants = variants
         .iter()
         .map(
             |variant| {
                 let attrs = attr::Variant::from_ast(cx, variant);
                 let (style, fields) = 
-                    struct_from_ast(cx, &variant.data, Some(&attrs), container_default);
+                    struct_from_ast(cx, &variant.fields, Some(&attrs), container_default);
                 Variant {
-                    ident: variant.ident.clone(),
+                    ident: variant.ident,
                     attrs: attrs,
                     style: style,
                     fields: fields,
                 }
             },
         )
         .collect();
 
@@ -152,21 +165,21 @@ fn enum_from_ast<'a>(
         "i8", "i16", "i32", "i64", "i128", "isize",
     ];
 
     let mut int_repr = None;
     let mut c_repr = false;
     let mut other_repr = false;
 
     for attr in &item.attrs {
-        if let syn::MetaItem::List(ref ident, ref vals) = attr.value {
-            if *ident == "repr" {
+        if let Some(syn::Meta::List(ref list)) = attr.interpret_meta() {
+            if list.ident == "repr" {
                 // has_repr = true;
-                for repr in vals {
-                    if let syn::NestedMetaItem::MetaItem(syn::MetaItem::Word(ref repr)) = *repr {
+                for repr in &list.nested {
+                    if let syn::NestedMeta::Meta(syn::Meta::Word(ref repr)) = *repr {
                         if repr == "C" {
                             c_repr = true;
                         } else if let Some(int_type) = INT_TYPES.iter().cloned().find(|int_type| repr == int_type) {
                             if int_repr.is_some() {
                                 // This shouldn't happen, but we shouldn't crash if we see it.
                                 // So just treat the enum as having a mysterious other repr,
                                 // which makes us discard any attempt to optimize based on layout.
                                 other_repr = true;
@@ -185,45 +198,46 @@ fn enum_from_ast<'a>(
 
     let repr = Repr { int_repr, c_repr, other_repr };
 
     (repr, variants)
 }
 
 fn struct_from_ast<'a>(
     cx: &Ctxt,
-    data: &'a syn::VariantData,
+    fields: &'a syn::Fields,
     attrs: Option<&attr::Variant>,
     container_default: &attr::Default,
 ) -> (Style, Vec<Field<'a>>) {
-    match *data {
-        syn::VariantData::Struct(ref fields) => (
+    match *fields {
+        syn::Fields::Named(ref fields) => (
             Style::Struct,
-            fields_from_ast(cx, fields, attrs, container_default),
+            fields_from_ast(cx, &fields.named, attrs, container_default),
         ),
-        syn::VariantData::Tuple(ref fields) if fields.len() == 1 => (
+        syn::Fields::Unnamed(ref fields) if fields.unnamed.len() == 1 => (
             Style::Newtype,
-            fields_from_ast(cx, fields, attrs, container_default),
+            fields_from_ast(cx, &fields.unnamed, attrs, container_default),
         ),
-        syn::VariantData::Tuple(ref fields) => (
+        syn::Fields::Unnamed(ref fields) => (
             Style::Tuple,
-            fields_from_ast(cx, fields, attrs, container_default),
+            fields_from_ast(cx, &fields.unnamed, attrs, container_default),
         ),
-        syn::VariantData::Unit => (Style::Unit, Vec::new()),
+        syn::Fields::Unit => (Style::Unit, Vec::new()),
     }
 }
 
 fn fields_from_ast<'a>(
     cx: &Ctxt,
-    fields: &'a [syn::Field],
+    fields: &'a Punctuated<syn::Field, Token![,]>,
     attrs: Option<&attr::Variant>,
     container_default: &attr::Default,
 ) -> Vec<Field<'a>> {
     fields
         .iter()
         .enumerate()
         .map(|(i, field)| Field {
-            ident: field.ident.clone(),
+            ident: field.ident,
             attrs: attr::Field::from_ast(cx, i, field, attrs, container_default),
             ty: &field.ty,
+            original: field,
         })
         .collect()
 }
--- a/third_party/rust/serde_derive_internals/src/attr.rs
+++ b/third_party/rust/serde_derive_internals/src/attr.rs
@@ -3,32 +3,36 @@
 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
 use Ctxt;
 use syn;
-use syn::MetaItem::{List, NameValue, Word};
-use syn::NestedMetaItem::{Literal, MetaItem};
-use synom::IResult;
+use syn::Ident;
+use syn::Meta::{List, NameValue, Word};
+use syn::NestedMeta::{Literal, Meta};
+use syn::punctuated::Punctuated;
+use syn::synom::{Synom, ParseError};
 use std::collections::BTreeSet;
 use std::str::FromStr;
+use proc_macro2::{Span, TokenStream, TokenNode, TokenTree};
 
 // This module handles parsing of `#[serde(...)]` attributes. The entrypoints
 // are `attr::Container::from_ast`, `attr::Variant::from_ast`, and
 // `attr::Field::from_ast`. Each returns an instance of the corresponding
 // struct. Note that none of them return a Result. Unrecognized, malformed, or
 // duplicated attributes result in a span_err but otherwise are ignored. The
 // user will see errors simultaneously for all bad attributes in the crate
 // rather than just the first.
 
 pub use case::RenameRule;
 
+#[derive(Copy, Clone)]
 struct Attr<'c, T> {
     cx: &'c Ctxt,
     name: &'static str,
     value: Option<T>,
 }
 
 impl<'c, T> Attr<'c, T> {
     fn none(cx: &'c Ctxt, name: &'static str) -> Self {
@@ -76,17 +80,16 @@ impl<'c> BoolAttr<'c> {
         self.0.set(());
     }
 
     fn get(&self) -> bool {
         self.0.value.is_some()
     }
 }
 
-#[derive(Debug)]
 pub struct Name {
     serialize: String,
     deserialize: String,
 }
 
 impl Name {
     /// Return the container name for the container when serializing.
     pub fn serialize_name(&self) -> String {
@@ -95,33 +98,32 @@ impl Name {
 
     /// Return the container name for the container when deserializing.
     pub fn deserialize_name(&self) -> String {
         self.deserialize.clone()
     }
 }
 
 /// Represents container (e.g. struct) attribute information
-#[derive(Debug)]
 pub struct Container {
     name: Name,
     deny_unknown_fields: bool,
     default: Default,
     rename_all: RenameRule,
     ser_bound: Option<Vec<syn::WherePredicate>>,
     de_bound: Option<Vec<syn::WherePredicate>>,
     tag: EnumTag,
-    from_type: Option<syn::Ty>,
-    into_type: Option<syn::Ty>,
+    type_from: Option<syn::Type>,
+    type_into: Option<syn::Type>,
     remote: Option<syn::Path>,
     identifier: Identifier,
+    has_flatten: bool,
 }
 
 /// Styles of representing an enum.
-#[derive(Debug)]
 pub enum EnumTag {
     /// The default.
     ///
     /// ```json
     /// {"variant1": {"key1": "value1", "key2": "value2"}}
     /// ```
     External,
 
@@ -144,17 +146,17 @@ pub enum EnumTag {
     /// ```json
     /// {"key1": "value1", "key2": "value2"}
     /// ```
     None,
 }
 
 /// Whether this enum represents the fields of a struct or the variants of an
 /// enum.
-#[derive(Copy, Clone, Debug)]
+#[derive(Copy, Clone)]
 pub enum Identifier {
     /// It does not.
     No,
 
     /// This enum represents the fields of a struct. All of the variants must be
     /// unit variants, except possibly one which is annotated with
     /// `#[serde(other)]` and is a newtype variant.
     Field,
@@ -181,175 +183,175 @@ impl Container {
         let mut deny_unknown_fields = BoolAttr::none(cx, "deny_unknown_fields");
         let mut default = Attr::none(cx, "default");
         let mut rename_all = Attr::none(cx, "rename_all");
         let mut ser_bound = Attr::none(cx, "bound");
         let mut de_bound = Attr::none(cx, "bound");
         let mut untagged = BoolAttr::none(cx, "untagged");
         let mut internal_tag = Attr::none(cx, "tag");
         let mut content = Attr::none(cx, "content");
-        let mut from_type = Attr::none(cx, "from");
-        let mut into_type = Attr::none(cx, "into");
+        let mut type_from = Attr::none(cx, "from");
+        let mut type_into = Attr::none(cx, "into");
         let mut remote = Attr::none(cx, "remote");
         let mut field_identifier = BoolAttr::none(cx, "field_identifier");
         let mut variant_identifier = BoolAttr::none(cx, "variant_identifier");
 
         for meta_items in item.attrs.iter().filter_map(get_serde_meta_items) {
             for meta_item in meta_items {
                 match meta_item {
                     // Parse `#[serde(rename = "foo")]`
-                    MetaItem(NameValue(ref name, ref lit)) if name == "rename" => {
-                        if let Ok(s) = get_string_from_lit(cx, name.as_ref(), name.as_ref(), lit) {
-                            ser_name.set(s.clone());
-                            de_name.set(s);
+                    Meta(NameValue(ref m)) if m.ident == "rename" => {
+                        if let Ok(s) = get_lit_str(cx, m.ident.as_ref(), m.ident.as_ref(), &m.lit) {
+                            ser_name.set(s.value());
+                            de_name.set(s.value());
                         }
                     }
 
                     // Parse `#[serde(rename(serialize = "foo", deserialize = "bar"))]`
-                    MetaItem(List(ref name, ref meta_items)) if name == "rename" => {
-                        if let Ok((ser, de)) = get_renames(cx, meta_items) {
-                            ser_name.set_opt(ser);
-                            de_name.set_opt(de);
+                    Meta(List(ref m)) if m.ident == "rename" => {
+                        if let Ok((ser, de)) = get_renames(cx, &m.nested) {
+                            ser_name.set_opt(ser.map(syn::LitStr::value));
+                            de_name.set_opt(de.map(syn::LitStr::value));
                         }
                     }
 
                     // Parse `#[serde(rename_all = "foo")]`
-                    MetaItem(NameValue(ref name, ref lit)) if name == "rename_all" => {
-                        if let Ok(s) = get_string_from_lit(cx, name.as_ref(), name.as_ref(), lit) {
-                            match RenameRule::from_str(&s) {
+                    Meta(NameValue(ref m)) if m.ident == "rename_all" => {
+                        if let Ok(s) = get_lit_str(cx, m.ident.as_ref(), m.ident.as_ref(), &m.lit) {
+                            match RenameRule::from_str(&s.value()) {
                                 Ok(rename_rule) => rename_all.set(rename_rule),
                                 Err(()) => cx.error(format!(
                                     "unknown rename rule for #[serde(rename_all \
                                      = {:?})]",
-                                    s
+                                    s.value()
                                 )),
                             }
                         }
                     }
 
                     // Parse `#[serde(deny_unknown_fields)]`
-                    MetaItem(Word(ref name)) if name == "deny_unknown_fields" => {
+                    Meta(Word(word)) if word == "deny_unknown_fields" => {
                         deny_unknown_fields.set_true();
                     }
 
                     // Parse `#[serde(default)]`
-                    MetaItem(Word(ref name)) if name == "default" => match item.body {
-                        syn::Body::Struct(syn::VariantData::Struct(_)) => {
+                    Meta(Word(word)) if word == "default" => match item.data {
+                        syn::Data::Struct(syn::DataStruct { fields: syn::Fields::Named(_), .. }) => {
                             default.set(Default::Default);
                         }
                         _ => cx.error(
                             "#[serde(default)] can only be used on structs \
                              with named fields",
                         ),
                     },
 
                     // Parse `#[serde(default = "...")]`
-                    MetaItem(NameValue(ref name, ref lit)) if name == "default" => {
-                        if let Ok(path) = parse_lit_into_path(cx, name.as_ref(), lit) {
-                            match item.body {
-                                syn::Body::Struct(syn::VariantData::Struct(_)) => {
+                    Meta(NameValue(ref m)) if m.ident == "default" => {
+                        if let Ok(path) = parse_lit_into_expr_path(cx, m.ident.as_ref(), &m.lit) {
+                            match item.data {
+                                syn::Data::Struct(syn::DataStruct { fields: syn::Fields::Named(_), .. }) => {
                                     default.set(Default::Path(path));
                                 }
                                 _ => cx.error(
                                     "#[serde(default = \"...\")] can only be used \
                                      on structs with named fields",
                                 ),
                             }
                         }
                     }
 
                     // Parse `#[serde(bound = "D: Serialize")]`
-                    MetaItem(NameValue(ref name, ref lit)) if name == "bound" => {
+                    Meta(NameValue(ref m)) if m.ident == "bound" => {
                         if let Ok(where_predicates) =
-                            parse_lit_into_where(cx, name.as_ref(), name.as_ref(), lit)
+                            parse_lit_into_where(cx, m.ident.as_ref(), m.ident.as_ref(), &m.lit)
                         {
                             ser_bound.set(where_predicates.clone());
                             de_bound.set(where_predicates);
                         }
                     }
 
                     // Parse `#[serde(bound(serialize = "D: Serialize", deserialize = "D: Deserialize"))]`
-                    MetaItem(List(ref name, ref meta_items)) if name == "bound" => {
-                        if let Ok((ser, de)) = get_where_predicates(cx, meta_items) {
+                    Meta(List(ref m)) if m.ident == "bound" => {
+                        if let Ok((ser, de)) = get_where_predicates(cx, &m.nested) {
                             ser_bound.set_opt(ser);
                             de_bound.set_opt(de);
                         }
                     }
 
                     // Parse `#[serde(untagged)]`
-                    MetaItem(Word(ref name)) if name == "untagged" => match item.body {
-                        syn::Body::Enum(_) => {
+                    Meta(Word(word)) if word == "untagged" => match item.data {
+                        syn::Data::Enum(_) => {
                             untagged.set_true();
                         }
-                        syn::Body::Struct(_) => {
+                        syn::Data::Struct(_) | syn::Data::Union(_) => {
                             cx.error("#[serde(untagged)] can only be used on enums")
                         }
                     },
 
                     // Parse `#[serde(tag = "type")]`
-                    MetaItem(NameValue(ref name, ref lit)) if name == "tag" => {
-                        if let Ok(s) = get_string_from_lit(cx, name.as_ref(), name.as_ref(), lit) {
-                            match item.body {
-                                syn::Body::Enum(_) => {
-                                    internal_tag.set(s);
+                    Meta(NameValue(ref m)) if m.ident == "tag" => {
+                        if let Ok(s) = get_lit_str(cx, m.ident.as_ref(), m.ident.as_ref(), &m.lit) {
+                            match item.data {
+                                syn::Data::Enum(_) => {
+                                    internal_tag.set(s.value());
                                 }
-                                syn::Body::Struct(_) => {
+                                syn::Data::Struct(_) | syn::Data::Union(_) => {
                                     cx.error("#[serde(tag = \"...\")] can only be used on enums")
                                 }
                             }
                         }
                     }
 
                     // Parse `#[serde(content = "c")]`
-                    MetaItem(NameValue(ref name, ref lit)) if name == "content" => {
-                        if let Ok(s) = get_string_from_lit(cx, name.as_ref(), name.as_ref(), lit) {
-                            match item.body {
-                                syn::Body::Enum(_) => {
-                                    content.set(s);
+                    Meta(NameValue(ref m)) if m.ident == "content" => {
+                        if let Ok(s) = get_lit_str(cx, m.ident.as_ref(), m.ident.as_ref(), &m.lit) {
+                            match item.data {
+                                syn::Data::Enum(_) => {
+                                    content.set(s.value());
                                 }
-                                syn::Body::Struct(_) => cx.error(
+                                syn::Data::Struct(_) | syn::Data::Union(_) => cx.error(
                                     "#[serde(content = \"...\")] can only be used on \
                                      enums",
                                 ),
                             }
                         }
                     }
 
                     // Parse `#[serde(from = "Type")]
-                    MetaItem(NameValue(ref name, ref lit)) if name == "from" => {
-                        if let Ok(from_ty) = parse_lit_into_ty(cx, name.as_ref(), lit) {
-                            from_type.set_opt(Some(from_ty));
+                    Meta(NameValue(ref m)) if m.ident == "from" => {
+                        if let Ok(from_ty) = parse_lit_into_ty(cx, m.ident.as_ref(), &m.lit) {
+                            type_from.set_opt(Some(from_ty));
                         }
                     }
 
                     // Parse `#[serde(into = "Type")]
-                    MetaItem(NameValue(ref name, ref lit)) if name == "into" => {
-                        if let Ok(into_ty) = parse_lit_into_ty(cx, name.as_ref(), lit) {
-                            into_type.set_opt(Some(into_ty));
+                    Meta(NameValue(ref m)) if m.ident == "into" => {
+                        if let Ok(into_ty) = parse_lit_into_ty(cx, m.ident.as_ref(), &m.lit) {
+                            type_into.set_opt(Some(into_ty));
                         }
                     }
 
                     // Parse `#[serde(remote = "...")]`
-                    MetaItem(NameValue(ref name, ref lit)) if name == "remote" => {
-                        if let Ok(path) = parse_lit_into_path(cx, name.as_ref(), lit) {
+                    Meta(NameValue(ref m)) if m.ident == "remote" => {
+                        if let Ok(path) = parse_lit_into_path(cx, m.ident.as_ref(), &m.lit) {
                             remote.set(path);
                         }
                     }
 
                     // Parse `#[serde(field_identifier)]`
-                    MetaItem(Word(ref name)) if name == "field_identifier" => {
+                    Meta(Word(word)) if word == "field_identifier" => {
                         field_identifier.set_true();
                     }
 
                     // Parse `#[serde(variant_identifier)]`
-                    MetaItem(Word(ref name)) if name == "variant_identifier" => {
+                    Meta(Word(word)) if word == "variant_identifier" => {
                         variant_identifier.set_true();
                     }
 
-                    MetaItem(ref meta_item) => {
+                    Meta(ref meta_item) => {
                         cx.error(format!(
                             "unknown serde container attribute `{}`",
                             meta_item.name()
                         ));
                     }
 
                     Literal(_) => {
                         cx.error("unexpected literal in serde container attribute");
@@ -363,21 +365,22 @@ impl Container {
                 serialize: ser_name.get().unwrap_or_else(|| item.ident.to_string()),
                 deserialize: de_name.get().unwrap_or_else(|| item.ident.to_string()),
             },
             deny_unknown_fields: deny_unknown_fields.get(),
             default: default.get().unwrap_or(Default::None),
             rename_all: rename_all.get().unwrap_or(RenameRule::None),
             ser_bound: ser_bound.get(),
             de_bound: de_bound.get(),
-            tag: decide_tag(cx, item, untagged, internal_tag, content),
-            from_type: from_type.get(),
-            into_type: into_type.get(),
+            tag: decide_tag(cx, item, &untagged, internal_tag, content),
+            type_from: type_from.get(),
+            type_into: type_into.get(),
             remote: remote.get(),
-            identifier: decide_identifier(cx, item, field_identifier, variant_identifier),
+            identifier: decide_identifier(cx, item, &field_identifier, &variant_identifier),
+            has_flatten: false,
         }
     }
 
     pub fn name(&self) -> &Name {
         &self.name
     }
 
     pub fn rename_all(&self) -> &RenameRule {
@@ -399,51 +402,59 @@ impl Container {
     pub fn de_bound(&self) -> Option<&[syn::WherePredicate]> {
         self.de_bound.as_ref().map(|vec| &vec[..])
     }
 
     pub fn tag(&self) -> &EnumTag {
         &self.tag
     }
 
-    pub fn from_type(&self) -> Option<&syn::Ty> {
-        self.from_type.as_ref()
+    pub fn type_from(&self) -> Option<&syn::Type> {
+        self.type_from.as_ref()
     }
 
-    pub fn into_type(&self) -> Option<&syn::Ty> {
-        self.into_type.as_ref()
+    pub fn type_into(&self) -> Option<&syn::Type> {
+        self.type_into.as_ref()
     }
 
     pub fn remote(&self) -> Option<&syn::Path> {
         self.remote.as_ref()
     }
 
     pub fn identifier(&self) -> Identifier {
         self.identifier
     }
+
+    pub fn has_flatten(&self) -> bool {
+        self.has_flatten
+    }
+
+    pub fn mark_has_flatten(&mut self) {
+        self.has_flatten = true;
+    }
 }
 
 fn decide_tag(
     cx: &Ctxt,
     item: &syn::DeriveInput,
-    untagged: BoolAttr,
+    untagged: &BoolAttr,
     internal_tag: Attr<String>,
     content: Attr<String>,
 ) -> EnumTag {
     match (untagged.get(), internal_tag.get(), content.get()) {
         (false, None, None) => EnumTag::External,
         (true, None, None) => EnumTag::None,
         (false, Some(tag), None) => {
             // Check that there are no tuple variants.
-            if let syn::Body::Enum(ref variants) = item.body {
-                for variant in variants {
-                    match variant.data {
-                        syn::VariantData::Struct(_) | syn::VariantData::Unit => {}
-                        syn::VariantData::Tuple(ref fields) => {
-                            if fields.len() != 1 {
+            if let syn::Data::Enum(ref data) = item.data {
+                for variant in &data.variants {
+                    match variant.fields {
+                        syn::Fields::Named(_) | syn::Fields::Unit => {}
+                        syn::Fields::Unnamed(ref fields) => {
+                            if fields.unnamed.len() != 1 {
                                 cx.error(
                                     "#[serde(tag = \"...\")] cannot be used with tuple \
                                      variants",
                                 );
                                 break;
                             }
                         }
                     }
@@ -472,51 +483,52 @@ fn decide_tag(
             EnumTag::External
         }
     }
 }
 
 fn decide_identifier(
     cx: &Ctxt,
     item: &syn::DeriveInput,
-    field_identifier: BoolAttr,
-    variant_identifier: BoolAttr,
+    field_identifier: &BoolAttr,
+    variant_identifier: &BoolAttr,
 ) -> Identifier {
-    match (&item.body, field_identifier.get(), variant_identifier.get()) {
+    match (&item.data, field_identifier.get(), variant_identifier.get()) {
         (_, false, false) => Identifier::No,
         (_, true, true) => {
             cx.error("`field_identifier` and `variant_identifier` cannot both be set");
             Identifier::No
         }
-        (&syn::Body::Struct(_), true, false) => {
+        (&syn::Data::Enum(_), true, false) => Identifier::Field,
+        (&syn::Data::Enum(_), false, true) => Identifier::Variant,
+        (&syn::Data::Struct(_), true, false)
+        | (&syn::Data::Union(_), true, false) => {
             cx.error("`field_identifier` can only be used on an enum");
             Identifier::No
         }
-        (&syn::Body::Struct(_), false, true) => {
+        (&syn::Data::Struct(_), false, true)
+        | (&syn::Data::Union(_), false, true) => {
             cx.error("`variant_identifier` can only be used on an enum");
             Identifier::No
         }
-        (&syn::Body::Enum(_), true, false) => Identifier::Field,
-        (&syn::Body::Enum(_), false, true) => Identifier::Variant,
     }
 }
 
 /// Represents variant attribute information
-#[derive(Debug)]
 pub struct Variant {
     name: Name,
     ser_renamed: bool,
     de_renamed: bool,
     rename_all: RenameRule,
     skip_deserializing: bool,
     skip_serializing: bool,
     other: bool,
-    serialize_with: Option<syn::Path>,
-    deserialize_with: Option<syn::Path>,
-    borrow: Option<syn::MetaItem>,
+    serialize_with: Option<syn::ExprPath>,
+    deserialize_with: Option<syn::ExprPath>,
+    borrow: Option<syn::Meta>,
 }
 
 impl Variant {
     pub fn from_ast(cx: &Ctxt, variant: &syn::Variant) -> Self {
         let mut ser_name = Attr::none(cx, "rename");
         let mut de_name = Attr::none(cx, "rename");
         let mut skip_deserializing = BoolAttr::none(cx, "skip_deserializing");
         let mut skip_serializing = BoolAttr::none(cx, "skip_serializing");
@@ -525,97 +537,97 @@ impl Variant {
         let mut serialize_with = Attr::none(cx, "serialize_with");
         let mut deserialize_with = Attr::none(cx, "deserialize_with");
         let mut borrow = Attr::none(cx, "borrow");
 
         for meta_items in variant.attrs.iter().filter_map(get_serde_meta_items) {
             for meta_item in meta_items {
                 match meta_item {
                     // Parse `#[serde(rename = "foo")]`
-                    MetaItem(NameValue(ref name, ref lit)) if name == "rename" => {
-                        if let Ok(s) = get_string_from_lit(cx, name.as_ref(), name.as_ref(), lit) {
-                            ser_name.set(s.clone());
-                            de_name.set(s);
+                    Meta(NameValue(ref m)) if m.ident == "rename" => {
+                        if let Ok(s) = get_lit_str(cx, m.ident.as_ref(), m.ident.as_ref(), &m.lit) {
+                            ser_name.set(s.value());
+                            de_name.set(s.value());
                         }
                     }
 
                     // Parse `#[serde(rename(serialize = "foo", deserialize = "bar"))]`
-                    MetaItem(List(ref name, ref meta_items)) if name == "rename" => {
-                        if let Ok((ser, de)) = get_renames(cx, meta_items) {
-                            ser_name.set_opt(ser);
-                            de_name.set_opt(de);
+                    Meta(List(ref m)) if m.ident == "rename" => {
+                        if let Ok((ser, de)) = get_renames(cx, &m.nested) {
+                            ser_name.set_opt(ser.map(syn::LitStr::value));
+                            de_name.set_opt(de.map(syn::LitStr::value));
                         }
                     }
 
                     // Parse `#[serde(rename_all = "foo")]`
-                    MetaItem(NameValue(ref name, ref lit)) if name == "rename_all" => {
-                        if let Ok(s) = get_string_from_lit(cx, name.as_ref(), name.as_ref(), lit) {
-                            match RenameRule::from_str(&s) {
+                    Meta(NameValue(ref m)) if m.ident == "rename_all" => {
+                        if let Ok(s) = get_lit_str(cx, m.ident.as_ref(), m.ident.as_ref(), &m.lit) {
+                            match RenameRule::from_str(&s.value()) {
                                 Ok(rename_rule) => rename_all.set(rename_rule),
                                 Err(()) => cx.error(format!(
                                     "unknown rename rule for #[serde(rename_all \
                                      = {:?})]",
-                                    s
+                                    s.value()
                                 )),
                             }
                         }
                     }
 
                     // Parse `#[serde(skip_deserializing)]`
-                    MetaItem(Word(ref name)) if name == "skip_deserializing" => {
+                    Meta(Word(word)) if word == "skip_deserializing" => {
                         skip_deserializing.set_true();
                     }
 
                     // Parse `#[serde(skip_serializing)]`
-                    MetaItem(Word(ref name)) if name == "skip_serializing" => {
+                    Meta(Word(word)) if word == "skip_serializing" => {
                         skip_serializing.set_true();
                     }
 
                     // Parse `#[serde(other)]`
-                    MetaItem(Word(ref name)) if name == "other" => {
+                    Meta(Word(word)) if word == "other" => {
                         other.set_true();
                     }
 
                     // Parse `#[serde(with = "...")]`
-                    MetaItem(NameValue(ref name, ref lit)) if name == "with" => {
-                        if let Ok(path) = parse_lit_into_path(cx, name.as_ref(), lit) {
+                    Meta(NameValue(ref m)) if m.ident == "with" => {
+                        if let Ok(path) = parse_lit_into_expr_path(cx, m.ident.as_ref(), &m.lit) {
                             let mut ser_path = path.clone();
-                            ser_path.segments.push("serialize".into());
+                            ser_path.path.segments.push(Ident::new("serialize", Span::call_site()).into());
                             serialize_with.set(ser_path);
                             let mut de_path = path;
-                            de_path.segments.push("deserialize".into());
+                            de_path.path.segments.push(Ident::new("deserialize", Span::call_site()).into());
                             deserialize_with.set(de_path);
                         }
                     }
 
                     // Parse `#[serde(serialize_with = "...")]`
-                    MetaItem(NameValue(ref name, ref lit)) if name == "serialize_with" => {
-                        if let Ok(path) = parse_lit_into_path(cx, name.as_ref(), lit) {
+                    Meta(NameValue(ref m)) if m.ident == "serialize_with" => {
+                        if let Ok(path) = parse_lit_into_expr_path(cx, m.ident.as_ref(), &m.lit) {
                             serialize_with.set(path);
                         }
                     }
 
                     // Parse `#[serde(deserialize_with = "...")]`
-                    MetaItem(NameValue(ref name, ref lit)) if name == "deserialize_with" => {
-                        if let Ok(path) = parse_lit_into_path(cx, name.as_ref(), lit) {
+                    Meta(NameValue(ref m)) if m.ident == "deserialize_with" => {
+                        if let Ok(path) = parse_lit_into_expr_path(cx, m.ident.as_ref(), &m.lit) {
                             deserialize_with.set(path);
                         }
                     }
 
                     // Defer `#[serde(borrow)]` and `#[serde(borrow = "'a + 'b")]`
-                    MetaItem(ref mi) if mi.name() == "borrow" => match variant.data {
-                        syn::VariantData::Tuple(ref fields) if fields.len() == 1 => {
-                            borrow.set(mi.clone());
+                    Meta(ref m) if m.name() == "borrow" => match variant.fields {
+                        syn::Fields::Unnamed(ref fields) if fields.unnamed.len() == 1 => {
+                            borrow.set(m.clone());
                         }
                         _ => {
                             cx.error("#[serde(borrow)] may only be used on newtype variants");
                         }
                     },
 
-                    MetaItem(ref meta_item) => {
+                    Meta(ref meta_item) => {
                         cx.error(format!(
                             "unknown serde variant attribute `{}`",
                             meta_item.name()
                         ));
                     }
 
                     Literal(_) => {
                         cx.error("unexpected literal in serde variant attribute");
@@ -669,52 +681,51 @@ impl Variant {
     pub fn skip_serializing(&self) -> bool {
         self.skip_serializing
     }
 
     pub fn other(&self) -> bool {
         self.other
     }
 
-    pub fn serialize_with(&self) -> Option<&syn::Path> {
+    pub fn serialize_with(&self) -> Option<&syn::ExprPath> {
         self.serialize_with.as_ref()
     }
 
-    pub fn deserialize_with(&self) -> Option<&syn::Path> {
+    pub fn deserialize_with(&self) -> Option<&syn::ExprPath> {
         self.deserialize_with.as_ref()
     }
 }
 
 /// Represents field attribute information
-#[derive(Debug)]
 pub struct Field {
     name: Name,
     ser_renamed: bool,
     de_renamed: bool,
     skip_serializing: bool,
     skip_deserializing: bool,
-    skip_serializing_if: Option<syn::Path>,
+    skip_serializing_if: Option<syn::ExprPath>,
     default: Default,
-    serialize_with: Option<syn::Path>,
-    deserialize_with: Option<syn::Path>,
+    serialize_with: Option<syn::ExprPath>,
+    deserialize_with: Option<syn::ExprPath>,
     ser_bound: Option<Vec<syn::WherePredicate>>,
     de_bound: Option<Vec<syn::WherePredicate>>,
     borrowed_lifetimes: BTreeSet<syn::Lifetime>,
-    getter: Option<syn::Path>,
+    getter: Option<syn::ExprPath>,
+    flatten: bool,
 }
 
 /// Represents the default to use for a field when deserializing.
-#[derive(Debug, PartialEq)]
 pub enum Default {
     /// Field must always be specified because it does not have a default.
     None,
     /// The default is given by `std::default::Default::default()`.
     Default,
     /// The default is given by this function.
-    Path(syn::Path),
+    Path(syn::ExprPath),
 }
 
 impl Field {
     /// Extract out the `#[serde(...)]` attributes from a struct field.
     pub fn from_ast(
         cx: &Ctxt,
         index: usize,
         field: &syn::Field,
@@ -728,205 +739,237 @@ impl Field {
         let mut skip_serializing_if = Attr::none(cx, "skip_serializing_if");
         let mut default = Attr::none(cx, "default");
         let mut serialize_with = Attr::none(cx, "serialize_with");
         let mut deserialize_with = Attr::none(cx, "deserialize_with");
         let mut ser_bound = Attr::none(cx, "bound");
         let mut de_bound = Attr::none(cx, "bound");
         let mut borrowed_lifetimes = Attr::none(cx, "borrow");
         let mut getter = Attr::none(cx, "getter");
+        let mut flatten = BoolAttr::none(cx, "flatten");
 
         let ident = match field.ident {
             Some(ref ident) => ident.to_string(),
             None => index.to_string(),
         };
 
         let variant_borrow = attrs
             .map(|variant| &variant.borrow)
             .unwrap_or(&None)
             .as_ref()
-            .map(|borrow| vec![MetaItem(borrow.clone())]);
+            .map(|borrow| vec![Meta(borrow.clone())]);
 
         for meta_items in field
             .attrs
             .iter()
             .filter_map(get_serde_meta_items)
             .chain(variant_borrow)
         {
             for meta_item in meta_items {
                 match meta_item {
                     // Parse `#[serde(rename = "foo")]`
-                    MetaItem(NameValue(ref name, ref lit)) if name == "rename" => {
-                        if let Ok(s) = get_string_from_lit(cx, name.as_ref(), name.as_ref(), lit) {
-                            ser_name.set(s.clone());
-                            de_name.set(s);
+                    Meta(NameValue(ref m)) if m.ident == "rename" => {
+                        if let Ok(s) = get_lit_str(cx, m.ident.as_ref(), m.ident.as_ref(), &m.lit) {
+                            ser_name.set(s.value());
+                            de_name.set(s.value());
                         }
                     }
 
                     // Parse `#[serde(rename(serialize = "foo", deserialize = "bar"))]`
-                    MetaItem(List(ref name, ref meta_items)) if name == "rename" => {
-                        if let Ok((ser, de)) = get_renames(cx, meta_items) {
-                            ser_name.set_opt(ser);
-                            de_name.set_opt(de);
+                    Meta(List(ref m)) if m.ident == "rename" => {
+                        if let Ok((ser, de)) = get_renames(cx, &m.nested) {
+                            ser_name.set_opt(ser.map(syn::LitStr::value));
+                            de_name.set_opt(de.map(syn::LitStr::value));
                         }
                     }
 
                     // Parse `#[serde(default)]`
-                    MetaItem(Word(ref name)) if name == "default" => {
+                    Meta(Word(word)) if word == "default" => {
                         default.set(Default::Default);
                     }
 
                     // Parse `#[serde(default = "...")]`
-                    MetaItem(NameValue(ref name, ref lit)) if name == "default" => {
-                        if let Ok(path) = parse_lit_into_path(cx, name.as_ref(), lit) {
+                    Meta(NameValue(ref m)) if m.ident == "default" => {
+                        if let Ok(path) = parse_lit_into_expr_path(cx, m.ident.as_ref(), &m.lit) {
                             default.set(Default::Path(path));
                         }
                     }
 
                     // Parse `#[serde(skip_serializing)]`
-                    MetaItem(Word(ref name)) if name == "skip_serializing" => {
+                    Meta(Word(word)) if word == "skip_serializing" => {
                         skip_serializing.set_true();
                     }
 
                     // Parse `#[serde(skip_deserializing)]`
-                    MetaItem(Word(ref name)) if name == "skip_deserializing" => {
+                    Meta(Word(word)) if word == "skip_deserializing" => {
                         skip_deserializing.set_true();
                     }
 
                     // Parse `#[serde(skip)]`
-                    MetaItem(Word(ref name)) if name == "skip" => {
+                    Meta(Word(word)) if word == "skip" => {
                         skip_serializing.set_true();
                         skip_deserializing.set_true();
                     }
 
                     // Parse `#[serde(skip_serializing_if = "...")]`
-                    MetaItem(NameValue(ref name, ref lit)) if name == "skip_serializing_if" => {
-                        if let Ok(path) = parse_lit_into_path(cx, name.as_ref(), lit) {
+                    Meta(NameValue(ref m)) if m.ident == "skip_serializing_if" => {
+                        if let Ok(path) = parse_lit_into_expr_path(cx, m.ident.as_ref(), &m.lit) {
                             skip_serializing_if.set(path);
                         }
                     }
 
                     // Parse `#[serde(serialize_with = "...")]`
-                    MetaItem(NameValue(ref name, ref lit)) if name == "serialize_with" => {
-                        if let Ok(path) = parse_lit_into_path(cx, name.as_ref(), lit) {
+                    Meta(NameValue(ref m)) if m.ident == "serialize_with" => {
+                        if let Ok(path) = parse_lit_into_expr_path(cx, m.ident.as_ref(), &m.lit) {
                             serialize_with.set(path);
                         }
                     }
 
                     // Parse `#[serde(deserialize_with = "...")]`
-                    MetaItem(NameValue(ref name, ref lit)) if name == "deserialize_with" => {
-                        if let Ok(path) = parse_lit_into_path(cx, name.as_ref(), lit) {
+                    Meta(NameValue(ref m)) if m.ident == "deserialize_with" => {
+                        if let Ok(path) = parse_lit_into_expr_path(cx, m.ident.as_ref(), &m.lit) {
                             deserialize_with.set(path);
                         }
                     }
 
                     // Parse `#[serde(with = "...")]`
-                    MetaItem(NameValue(ref name, ref lit)) if name == "with" => {
-                        if let Ok(path) = parse_lit_into_path(cx, name.as_ref(), lit) {
+                    Meta(NameValue(ref m)) if m.ident == "with" => {
+                        if let Ok(path) = parse_lit_into_expr_path(cx, m.ident.as_ref(), &m.lit) {
                             let mut ser_path = path.clone();
-                            ser_path.segments.push("serialize".into());
+                            ser_path.path.segments.push(Ident::new("serialize", Span::call_site()).into());
                             serialize_with.set(ser_path);
                             let mut de_path = path;
-                            de_path.segments.push("deserialize".into());
+                            de_path.path.segments.push(Ident::new("deserialize", Span::call_site()).into());
                             deserialize_with.set(de_path);
                         }
                     }
 
                     // Parse `#[serde(bound = "D: Serialize")]`
-                    MetaItem(NameValue(ref name, ref lit)) if name == "bound" => {
+                    Meta(NameValue(ref m)) if m.ident == "bound" => {
                         if let Ok(where_predicates) =
-                            parse_lit_into_where(cx, name.as_ref(), name.as_ref(), lit)
+                            parse_lit_into_where(cx, m.ident.as_ref(), m.ident.as_ref(), &m.lit)
                         {
                             ser_bound.set(where_predicates.clone());
                             de_bound.set(where_predicates);
                         }
                     }
 
                     // Parse `#[serde(bound(serialize = "D: Serialize", deserialize = "D: Deserialize"))]`
-                    MetaItem(List(ref name, ref meta_items)) if name == "bound" => {
-                        if let Ok((ser, de)) = get_where_predicates(cx, meta_items) {
+                    Meta(List(ref m)) if m.ident == "bound" => {
+                        if let Ok((ser, de)) = get_where_predicates(cx, &m.nested) {
                             ser_bound.set_opt(ser);
                             de_bound.set_opt(de);
                         }
                     }
 
                     // Parse `#[serde(borrow)]`
-                    MetaItem(Word(ref name)) if name == "borrow" => {
+                    Meta(Word(word)) if word == "borrow" => {
                         if let Ok(borrowable) = borrowable_lifetimes(cx, &ident, &field.ty) {
                             borrowed_lifetimes.set(borrowable);
                         }
                     }
 
                     // Parse `#[serde(borrow = "'a + 'b")]`
-                    MetaItem(NameValue(ref name, ref lit)) if name == "borrow" => {
-                        if let Ok(lifetimes) = parse_lit_into_lifetimes(cx, name.as_ref(), lit) {
+                    Meta(NameValue(ref m)) if m.ident == "borrow" => {
+                        if let Ok(lifetimes) = parse_lit_into_lifetimes(cx, m.ident.as_ref(), &m.lit) {
                             if let Ok(borrowable) = borrowable_lifetimes(cx, &ident, &field.ty) {
                                 for lifetime in &lifetimes {
                                     if !borrowable.contains(lifetime) {
                                         cx.error(format!(
                                             "field `{}` does not have lifetime {}",
-                                            ident, lifetime.ident
+                                            ident, lifetime
                                         ));
                                     }
                                 }
                                 borrowed_lifetimes.set(lifetimes);
                             }
                         }
                     }
 
                     // Parse `#[serde(getter = "...")]`
-                    MetaItem(NameValue(ref name, ref lit)) if name == "getter" => {
-                        if let Ok(path) = parse_lit_into_path(cx, name.as_ref(), lit) {
+                    Meta(NameValue(ref m)) if m.ident == "getter" => {
+                        if let Ok(path) = parse_lit_into_expr_path(cx, m.ident.as_ref(), &m.lit) {
                             getter.set(path);
                         }
                     }
 
-                    MetaItem(ref meta_item) => {
+                    // Parse `#[serde(flatten)]`
+                    Meta(Word(word)) if word == "flatten" => {
+                        flatten.set_true();
+                    }
+
+                    Meta(ref meta_item) => {
                         cx.error(format!(
                             "unknown serde field attribute `{}`",
                             meta_item.name()
                         ));
                     }
 
                     Literal(_) => {
                         cx.error("unexpected literal in serde field attribute");
                     }
                 }
             }
         }
 
         // Is skip_deserializing, initialize the field to Default::default() unless a different
         // default is specified by `#[serde(default = "...")]` on ourselves or our container (e.g.
         // the struct we are in).
-        if container_default == &Default::None && skip_deserializing.0.value.is_some() {
-            default.set_if_none(Default::Default);
+        if let Default::None = *container_default {
+            if skip_deserializing.0.value.is_some() {
+                default.set_if_none(Default::Default);
+            }
         }
 
         let mut borrowed_lifetimes = borrowed_lifetimes.get().unwrap_or_default();
         if !borrowed_lifetimes.is_empty() {
             // Cow<str> and Cow<[u8]> never borrow by default:
             //
             //     impl<'de, 'a, T: ?Sized> Deserialize<'de> for Cow<'a, T>
             //
             // A #[serde(borrow)] attribute enables borrowing that corresponds
             // roughly to these impls:
             //
             //     impl<'de: 'a, 'a> Deserialize<'de> for Cow<'a, str>
             //     impl<'de: 'a, 'a> Deserialize<'de> for Cow<'a, [u8]>
-            if is_cow(&field.ty, "str") {
-                let path = syn::parse_path("_serde::private::de::borrow_cow_str").unwrap();
-                deserialize_with.set_if_none(path);
-            } else if is_cow(&field.ty, "[u8]") {
-                let path = syn::parse_path("_serde::private::de::borrow_cow_bytes").unwrap();
-                deserialize_with.set_if_none(path);
+            if is_cow(&field.ty, is_str) {
+                let mut path = syn::Path {
+                    leading_colon: None,
+                    segments: Punctuated::new(),
+                };
+                path.segments.push(Ident::new("_serde", Span::def_site()).into());
+                path.segments.push(Ident::new("private", Span::def_site()).into());
+                path.segments.push(Ident::new("de", Span::def_site()).into());
+                path.segments.push(Ident::new("borrow_cow_str", Span::def_site()).into());
+                let expr = syn::ExprPath {
+                    attrs: Vec::new(),
+                    qself: None,
+                    path: path,
+                };
+                deserialize_with.set_if_none(expr);
+            } else if is_cow(&field.ty, is_slice_u8) {
+                let mut path = syn::Path {
+                    leading_colon: None,
+                    segments: Punctuated::new(),
+                };
+                path.segments.push(Ident::new("_serde", Span::def_site()).into());
+                path.segments.push(Ident::new("private", Span::def_site()).into());
+                path.segments.push(Ident::new("de", Span::def_site()).into());
+                path.segments.push(Ident::new("borrow_cow_bytes", Span::def_site()).into());
+                let expr = syn::ExprPath {
+                    attrs: Vec::new(),
+                    qself: None,
+                    path: path,
+                };
+                deserialize_with.set_if_none(expr);
             }
-        } else if is_rptr(&field.ty, "str") || is_rptr(&field.ty, "[u8]") {
+        } else if is_rptr(&field.ty, is_str) || is_rptr(&field.ty, is_slice_u8) {
             // Types &str and &[u8] are always implicitly borrowed. No need for
             // a #[serde(borrow)].
-            borrowed_lifetimes = borrowable_lifetimes(cx, &ident, &field.ty).unwrap();
+            collect_lifetimes(&field.ty, &mut borrowed_lifetimes);
         }
 
         let ser_name = ser_name.get();
         let ser_renamed = ser_name.is_some();
         let de_name = de_name.get();
         let de_renamed = de_name.is_some();
         Field {
             name: Name {
@@ -940,16 +983,17 @@ impl Field {
             skip_serializing_if: skip_serializing_if.get(),
             default: default.get().unwrap_or(Default::None),
             serialize_with: serialize_with.get(),
             deserialize_with: deserialize_with.get(),
             ser_bound: ser_bound.get(),
             de_bound: de_bound.get(),
             borrowed_lifetimes: borrowed_lifetimes,
             getter: getter.get(),
+            flatten: flatten.get(),
         }
     }
 
     pub fn name(&self) -> &Name {
         &self.name
     }
 
     pub fn rename_by_rule(&mut self, rule: &RenameRule) {
@@ -964,189 +1008,211 @@ impl Field {
     pub fn skip_serializing(&self) -> bool {
         self.skip_serializing
     }
 
     pub fn skip_deserializing(&self) -> bool {
         self.skip_deserializing
     }
 
-    pub fn skip_serializing_if(&self) -> Option<&syn::Path> {
+    pub fn skip_serializing_if(&self) -> Option<&syn::ExprPath> {
         self.skip_serializing_if.as_ref()
     }
 
     pub fn default(&self) -> &Default {
         &self.default
     }
 
-    pub fn serialize_with(&self) -> Option<&syn::Path> {
+    pub fn serialize_with(&self) -> Option<&syn::ExprPath> {
         self.serialize_with.as_ref()
     }
 
-    pub fn deserialize_with(&self) -> Option<&syn::Path> {
+    pub fn deserialize_with(&self) -> Option<&syn::ExprPath> {
         self.deserialize_with.as_ref()
     }
 
     pub fn ser_bound(&self) -> Option<&[syn::WherePredicate]> {
         self.ser_bound.as_ref().map(|vec| &vec[..])
     }
 
     pub fn de_bound(&self) -> Option<&[syn::WherePredicate]> {
         self.de_bound.as_ref().map(|vec| &vec[..])
     }
 
     pub fn borrowed_lifetimes(&self) -> &BTreeSet<syn::Lifetime> {
         &self.borrowed_lifetimes
     }
 
-    pub fn getter(&self) -> Option<&syn::Path> {
+    pub fn getter(&self) -> Option<&syn::ExprPath> {
         self.getter.as_ref()
     }
+
+    pub fn flatten(&self) -> bool {
+        self.flatten
+    }
 }
 
 type SerAndDe<T> = (Option<T>, Option<T>);
 
-fn get_ser_and_de<T, F>(
+fn get_ser_and_de<'a, T, F>(
     cx: &Ctxt,
     attr_name: &'static str,
-    items: &[syn::NestedMetaItem],
+    metas: &'a Punctuated<syn::NestedMeta, Token![,]>,
     f: F,
 ) -> Result<SerAndDe<T>, ()>
 where
-    F: Fn(&Ctxt, &str, &str, &syn::Lit) -> Result<T, ()>,
+    T: 'a,
+    F: Fn(&Ctxt, &str, &str, &'a syn::Lit) -> Result<T, ()>,
 {
-    let mut ser_item = Attr::none(cx, attr_name);
-    let mut de_item = Attr::none(cx, attr_name);
+    let mut ser_meta = Attr::none(cx, attr_name);
+    let mut de_meta = Attr::none(cx, attr_name);
 
-    for item in items {
-        match *item {
-            MetaItem(NameValue(ref name, ref lit)) if name == "serialize" => {
-                if let Ok(v) = f(cx, attr_name, name.as_ref(), lit) {
-                    ser_item.set(v);
+    for meta in metas {
+        match *meta {
+            Meta(NameValue(ref meta)) if meta.ident == "serialize" => {
+                if let Ok(v) = f(cx, attr_name, meta.ident.as_ref(), &meta.lit) {
+                    ser_meta.set(v);
                 }
             }
 
-            MetaItem(NameValue(ref name, ref lit)) if name == "deserialize" => {
-                if let Ok(v) = f(cx, attr_name, name.as_ref(), lit) {
-                    de_item.set(v);
+            Meta(NameValue(ref meta)) if meta.ident == "deserialize" => {
+                if let Ok(v) = f(cx, attr_name, meta.ident.as_ref(), &meta.lit) {
+                    de_meta.set(v);
                 }
             }
 
             _ => {
                 cx.error(format!(
                     "malformed {0} attribute, expected `{0}(serialize = ..., \
                      deserialize = ...)`",
                     attr_name
                 ));
                 return Err(());
             }
         }
     }
 
-    Ok((ser_item.get(), de_item.get()))
+    Ok((ser_meta.get(), de_meta.get()))
 }
 
-fn get_renames(cx: &Ctxt, items: &[syn::NestedMetaItem]) -> Result<SerAndDe<String>, ()> {
-    get_ser_and_de(cx, "rename", items, get_string_from_lit)
+fn get_renames<'a>(cx: &Ctxt, items: &'a Punctuated<syn::NestedMeta, Token![,]>) -> Result<SerAndDe<&'a syn::LitStr>, ()> {
+    get_ser_and_de(cx, "rename", items, get_lit_str)
 }
 
 fn get_where_predicates(
     cx: &Ctxt,
-    items: &[syn::NestedMetaItem],
+    items: &Punctuated<syn::NestedMeta, Token![,]>,
 ) -> Result<SerAndDe<Vec<syn::WherePredicate>>, ()> {
     get_ser_and_de(cx, "bound", items, parse_lit_into_where)
 }
 
-pub fn get_serde_meta_items(attr: &syn::Attribute) -> Option<Vec<syn::NestedMetaItem>> {
-    match attr.value {
-        List(ref name, ref items) if name == "serde" => Some(items.iter().cloned().collect()),
-        _ => None,
+pub fn get_serde_meta_items(attr: &syn::Attribute) -> Option<Vec<syn::NestedMeta>> {
+    if attr.path.segments.len() == 1 && attr.path.segments[0].ident == "serde" {
+        match attr.interpret_meta() {
+            Some(List(ref meta)) => Some(meta.nested.iter().cloned().collect()),
+            _ => {
+                // TODO: produce an error
+                None
+            }
+        }
+    } else {
+        None
     }
 }
 
-fn get_string_from_lit(
+fn get_lit_str<'a>(
     cx: &Ctxt,
     attr_name: &str,
     meta_item_name: &str,
-    lit: &syn::Lit,
-) -> Result<String, ()> {
-    if let syn::Lit::Str(ref s, _) = *lit {
-        Ok(s.clone())
+    lit: &'a syn::Lit,
+) -> Result<&'a syn::LitStr, ()> {
+    if let syn::Lit::Str(ref lit) = *lit {
+        Ok(lit)
     } else {
         cx.error(format!(
             "expected serde {} attribute to be a string: `{} = \"...\"`",
             attr_name, meta_item_name
         ));
         Err(())
     }
 }
 
 fn parse_lit_into_path(cx: &Ctxt, attr_name: &str, lit: &syn::Lit) -> Result<syn::Path, ()> {
-    let string = try!(get_string_from_lit(cx, attr_name, attr_name, lit));
-    syn::parse_path(&string).map_err(|err| cx.error(err))
+    let string = try!(get_lit_str(cx, attr_name, attr_name, lit));
+    parse_lit_str(string).map_err(|_| cx.error(format!("failed to parse path: {:?}", string.value())))
+}
+
+fn parse_lit_into_expr_path(cx: &Ctxt, attr_name: &str, lit: &syn::Lit) -> Result<syn::ExprPath, ()> {
+    let string = try!(get_lit_str(cx, attr_name, attr_name, lit));
+    parse_lit_str(string).map_err(|_| cx.error(format!("failed to parse path: {:?}", string.value())))
 }
 
 fn parse_lit_into_where(
     cx: &Ctxt,
     attr_name: &str,
     meta_item_name: &str,
     lit: &syn::Lit,
 ) -> Result<Vec<syn::WherePredicate>, ()> {
-    let string = try!(get_string_from_lit(cx, attr_name, meta_item_name, lit));
-    if string.is_empty() {
+    let string = try!(get_lit_str(cx, attr_name, meta_item_name, lit));
+    if string.value().is_empty() {
         return Ok(Vec::new());
     }
 
-    let where_string = format!("where {}", string);
+    let where_string = syn::LitStr::new(&format!("where {}", string.value()), string.span);
 
-    syn::parse_where_clause(&where_string)
-        .map(|wh| wh.predicates)
+    parse_lit_str::<syn::WhereClause>(&where_string)
+        .map(|wh| wh.predicates.into_iter().collect())
         .map_err(|err| cx.error(err))
 }
 
-fn parse_lit_into_ty(cx: &Ctxt, attr_name: &str, lit: &syn::Lit) -> Result<syn::Ty, ()> {
-    let string = try!(get_string_from_lit(cx, attr_name, attr_name, lit));
+fn parse_lit_into_ty(cx: &Ctxt, attr_name: &str, lit: &syn::Lit) -> Result<syn::Type, ()> {
+    let string = try!(get_lit_str(cx, attr_name, attr_name, lit));
 
-    syn::parse_type(&string).map_err(|_| {
+    parse_lit_str(string).map_err(|_| {
         cx.error(format!(
             "failed to parse type: {} = {:?}",
-            attr_name, string
+            attr_name, string.value()
         ))
     })
 }
 
 // Parses a string literal like "'a + 'b + 'c" containing a nonempty list of
 // lifetimes separated by `+`.
 fn parse_lit_into_lifetimes(
     cx: &Ctxt,
     attr_name: &str,
     lit: &syn::Lit,
 ) -> Result<BTreeSet<syn::Lifetime>, ()> {
-    let string = try!(get_string_from_lit(cx, attr_name, attr_name, lit));
-    if string.is_empty() {
+    let string = try!(get_lit_str(cx, attr_name, attr_name, lit));
+    if string.value().is_empty() {
         cx.error("at least one lifetime must be borrowed");
         return Err(());
     }
 
-    named!(lifetimes -> Vec<syn::Lifetime>,
-        separated_nonempty_list!(punct!("+"), syn::parse::lifetime)
-    );
+    struct BorrowedLifetimes(Punctuated<syn::Lifetime, Token![+]>);
+
+    impl Synom for BorrowedLifetimes {
+        named!(parse -> Self, map!(
+            call!(Punctuated::parse_separated_nonempty),
+            BorrowedLifetimes
+        ));
+    }
 
-    if let IResult::Done(rest, o) = lifetimes(&string) {
-        if rest.trim().is_empty() {
-            let mut set = BTreeSet::new();
-            for lifetime in o {
-                if !set.insert(lifetime.clone()) {
-                    cx.error(format!("duplicate borrowed lifetime `{}`", lifetime.ident));
-                }
+    if let Ok(BorrowedLifetimes(lifetimes)) = parse_lit_str(string) {
+        let mut set = BTreeSet::new();
+        for lifetime in lifetimes {
+            if !set.insert(lifetime) {
+                cx.error(format!("duplicate borrowed lifetime `{}`", lifetime));
             }
-            return Ok(set);
         }
+        return Ok(set);
     }
-    Err(cx.error(format!("failed to parse borrowed lifetimes: {:?}", string)))
+
+    cx.error(format!("failed to parse borrowed lifetimes: {:?}", string.value()));
+    Err(())
 }
 
 // Whether the type looks like it might be `std::borrow::Cow<T>` where elem="T".
 // This can have false negatives and false positives.
 //
 // False negative:
 //
 //     use std::borrow::Cow as Pig;
@@ -1161,37 +1227,43 @@ fn parse_lit_into_lifetimes(
 //
 //     type str = [i16];
 //
 //     #[derive(Deserialize)]
 //     struct S<'a> {
 //         #[serde(borrow)]
 //         cow: Cow<'a, str>,
 //     }
-fn is_cow(ty: &syn::Ty, elem: &str) -> bool {
+fn is_cow(ty: &syn::Type, elem: fn(&syn::Type) -> bool) -> bool {
     let path = match *ty {
-        syn::Ty::Path(None, ref path) => path,
+        syn::Type::Path(ref ty) => &ty.path,
         _ => {
             return false;
         }
     };
     let seg = match path.segments.last() {
-        Some(seg) => seg,
+        Some(seg) => seg.into_value(),
         None => {
             return false;
         }
     };
-    let params = match seg.parameters {
-        syn::PathParameters::AngleBracketed(ref params) => params,
+    let args = match seg.arguments {
+        syn::PathArguments::AngleBracketed(ref bracketed) => &bracketed.args,
         _ => {
             return false;
         }
     };
-    seg.ident == "Cow" && params.lifetimes.len() == 1
-        && params.types == vec![syn::parse_type(elem).unwrap()] && params.bindings.is_empty()
+    seg.ident == "Cow"
+        && args.len() == 2
+        && match (&args[0], &args[1]) {
+            (&syn::GenericArgument::Lifetime(_), &syn::GenericArgument::Type(ref arg)) => {
+                elem(arg)
+            }
+            _ => false,
+        }
 }
 
 // Whether the type looks like it might be `&T` where elem="T". This can have
 // false negatives and false positives.
 //
 // False negative:
 //
 //     type Yarn = str;
@@ -1204,78 +1276,148 @@ fn is_cow(ty: &syn::Ty, elem: &str) -> b
 // False positive:
 //
 //     type str = [i16];
 //
 //     #[derive(Deserialize)]
 //     struct S<'a> {
 //         r: &'a str,
 //     }
-fn is_rptr(ty: &syn::Ty, elem: &str) -> bool {
+fn is_rptr(ty: &syn::Type, elem: fn(&syn::Type) -> bool) -> bool {
     match *ty {
-        syn::Ty::Rptr(Some(_), ref mut_ty) => {
-            mut_ty.mutability == syn::Mutability::Immutable
-                && mut_ty.ty == syn::parse_type(elem).unwrap()
+        syn::Type::Reference(ref ty) => {
+            ty.mutability.is_none() && elem(&ty.elem)
+        }
+        _ => false,
+    }
+}
+
+fn is_str(ty: &syn::Type) -> bool {
+    is_primitive_path(ty, "str")
+}
+
+fn is_slice_u8(ty: &syn::Type) -> bool {
+    match *ty {
+        syn::Type::Slice(ref ty) => is_primitive_path(&ty.elem, "u8"),
+        _ => false,
+    }
+}
+
+fn is_primitive_path(ty: &syn::Type, primitive: &str) -> bool {
+    match *ty {
+        syn::Type::Path(ref ty) => {
+            ty.qself.is_none()
+                && ty.path.leading_colon.is_none()
+                && ty.path.segments.len() == 1
+                && ty.path.segments[0].ident == primitive
+                && ty.path.segments[0].arguments.is_empty()
         }
         _ => false,
     }
 }
 
 // All lifetimes that this type could borrow from a Deserializer.
 //
 // For example a type `S<'a, 'b>` could borrow `'a` and `'b`. On the other hand
 // a type `for<'a> fn(&'a str)` could not borrow `'a` from the Deserializer.
 //
 // This is used when there is an explicit or implicit `#[serde(borrow)]`
 // attribute on the field so there must be at least one borrowable lifetime.
 fn borrowable_lifetimes(
     cx: &Ctxt,
     name: &str,
-    ty: &syn::Ty,
+    ty: &syn::Type,
 ) -> Result<BTreeSet<syn::Lifetime>, ()> {
     let mut lifetimes = BTreeSet::new();
     collect_lifetimes(ty, &mut lifetimes);
     if lifetimes.is_empty() {
-        Err(cx.error(format!("field `{}` has no lifetimes to borrow", name)))
+        cx.error(format!("field `{}` has no lifetimes to borrow", name));
+        Err(())
     } else {
         Ok(lifetimes)
     }
 }
 
-fn collect_lifetimes(ty: &syn::Ty, out: &mut BTreeSet<syn::Lifetime>) {
+fn collect_lifetimes(ty: &syn::Type, out: &mut BTreeSet<syn::Lifetime>) {
     match *ty {
-        syn::Ty::Slice(ref elem) | syn::Ty::Array(ref elem, _) | syn::Ty::Paren(ref elem) => {
-            collect_lifetimes(elem, out);
+        syn::Type::Slice(ref ty) => {
+            collect_lifetimes(&ty.elem, out);
+        }
+        syn::Type::Array(ref ty) => {
+            collect_lifetimes(&ty.elem, out);
         }
-        syn::Ty::Ptr(ref elem) => {
-            collect_lifetimes(&elem.ty, out);
+        syn::Type::Ptr(ref ty) => {
+            collect_lifetimes(&ty.elem, out);
         }
-        syn::Ty::Rptr(ref lifetime, ref elem) => {
-            out.extend(lifetime.iter().cloned());
-            collect_lifetimes(&elem.ty, out);
+        syn::Type::Reference(ref ty) => {
+            out.extend(ty.lifetime.iter().cloned());
+            collect_lifetimes(&ty.elem, out);
         }
-        syn::Ty::Tup(ref elems) => for elem in elems {
+        syn::Type::Tuple(ref ty) => for elem in &ty.elems {
             collect_lifetimes(elem, out);
         },
-        syn::Ty::Path(ref qself, ref path) => {
-            if let Some(ref qself) = *qself {
+        syn::Type::Path(ref ty) => {
+            if let Some(ref qself) = ty.qself {
                 collect_lifetimes(&qself.ty, out);
             }
-            for seg in &path.segments {
-                if let syn::PathParameters::AngleBracketed(ref params) = seg.parameters {
-                    out.extend(params.lifetimes.iter().cloned());
-                    for ty in &params.types {
-                        collect_lifetimes(ty, out);
-                    }
-                    for binding in &params.bindings {
-                        collect_lifetimes(&binding.ty, out);
+            for seg in &ty.path.segments {
+                if let syn::PathArguments::AngleBracketed(ref bracketed) = seg.arguments {
+                    for arg in &bracketed.args {
+                        match *arg {
+                            syn::GenericArgument::Lifetime(ref lifetime) => {
+                                out.insert(lifetime.clone());
+                            }
+                            syn::GenericArgument::Type(ref ty) => {
+                                collect_lifetimes(ty, out);
+                            }
+                            syn::GenericArgument::Binding(ref binding) => {
+                                collect_lifetimes(&binding.ty, out);
+                            }
+                            syn::GenericArgument::Const(_) => {}
+                        }
                     }
                 }
             }
         }
-        syn::Ty::BareFn(_)
-        | syn::Ty::Never
-        | syn::Ty::TraitObject(_)
-        | syn::Ty::ImplTrait(_)
-        | syn::Ty::Infer
-        | syn::Ty::Mac(_) => {}
+        syn::Type::Paren(ref ty) => {
+            collect_lifetimes(&ty.elem, out);
+        }
+        syn::Type::Group(ref ty) => {
+            collect_lifetimes(&ty.elem, out);
+        }
+        syn::Type::BareFn(_)
+        | syn::Type::Never(_)
+        | syn::Type::TraitObject(_)
+        | syn::Type::ImplTrait(_)
+        | syn::Type::Infer(_)
+        | syn::Type::Macro(_)
+        | syn::Type::Verbatim(_) => {}
     }
 }
+
+fn parse_lit_str<T>(s: &syn::LitStr) -> Result<T, ParseError>
+where
+    T: Synom,
+{
+    let tokens = try!(spanned_tokens(s));
+    syn::parse2(tokens)
+}
+
+fn spanned_tokens(s: &syn::LitStr) -> Result<TokenStream, ParseError> {
+    let stream = try!(syn::parse_str(&s.value()));
+    Ok(respan_token_stream(stream, s.span))
+}
+
+fn respan_token_stream(stream: TokenStream, span: Span) -> TokenStream {
+    stream.into_iter().map(|token| respan_token_tree(token, span)).collect()
+}
+
+fn respan_token_tree(token: TokenTree, span: Span) -> TokenTree {
+    TokenTree {
+        span: span,
+        kind: match token.kind {
+            TokenNode::Group(delimiter, nested) => {
+                TokenNode::Group(delimiter, respan_token_stream(nested, span))
+            }
+            other => other,
+        },
+    }
+}
--- a/third_party/rust/serde_derive_internals/src/case.rs
+++ b/third_party/rust/serde_derive_internals/src/case.rs
@@ -2,24 +2,24 @@
 //
 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
 // See https://users.rust-lang.org/t/psa-dealing-with-warning-unused-import-std-ascii-asciiext-in-today-s-nightly/13726
-#[allow(unused_imports)]
+#[allow(deprecated, unused_imports)]
 use std::ascii::AsciiExt;
 
 use std::str::FromStr;
 
 use self::RenameRule::*;
 
-#[derive(Debug, PartialEq)]
+#[derive(PartialEq)]
 pub enum RenameRule {
     /// Don't apply a default rename rule.
     None,
     /// Rename direct children to "lowercase" style.
     LowerCase,
     /// Rename direct children to "UPPERCASE" style.
     UPPERCASE,
     /// Rename direct children to "PascalCase" style, as typically used for enum variants.
--- a/third_party/rust/serde_derive_internals/src/check.rs
+++ b/third_party/rust/serde_derive_internals/src/check.rs
@@ -1,58 +1,93 @@
 // Copyright 2017 Serde Developers
 //
 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use ast::{Body, Container, Style};
-use attr::Identifier;
+use ast::{Data, Container, Style};
+use attr::{Identifier, EnumTag};
 use Ctxt;
 
 /// 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: &Container) {
     check_getter(cx, cont);
+    check_flatten(cx, cont);
     check_identifier(cx, cont);
     check_variant_skip_attrs(cx, cont);
+    check_internal_tag_field_name_conflict(cx, cont);
+    check_adjacent_tag_conflict(cx, cont);
 }
 
 /// Getters are only allowed inside structs (not enums) with the `remote`
 /// attribute.
 fn check_getter(cx: &Ctxt, cont: &Container) {
-    match cont.body {
-        Body::Enum(_, _) => {
-            if cont.body.has_getter() {
+    match cont.data {
+        Data::Enum(_, _) => {
+            if cont.data.has_getter() {
                 cx.error("#[serde(getter = \"...\")] is not allowed in an enum");
             }
         }
-        Body::Struct(_, _) => {
-            if cont.body.has_getter() && cont.attrs.remote().is_none() {
+        Data::Struct(_, _) => {
+            if cont.data.has_getter() && cont.attrs.remote().is_none() {
                 cx.error(
                     "#[serde(getter = \"...\")] can only be used in structs \
                      that have #[serde(remote = \"...\")]",
                 );
             }
         }
     }
 }
 
+/// Flattening has some restrictions we can test.
+fn check_flatten(cx: &Ctxt, cont: &Container) {
+    match cont.data {
+        Data::Enum(_, _) => {
+            assert!(!cont.attrs.has_flatten());
+        }
+        Data::Struct(_, _) => {
+            for field in cont.data.all_fields() {
+                if !field.attrs.flatten() {
+                    continue;
+                }
+                if field.attrs.skip_serializing() {
+                    cx.error(
+                        "#[serde(flatten] can not be combined with \
+                         #[serde(skip_serializing)]"
+                    );
+                } else if field.attrs.skip_serializing_if().is_some() {
+                    cx.error(
+                        "#[serde(flatten] can not be combined with \
+                         #[serde(skip_serializing_if = \"...\")]"
+                    );
+                } else if field.attrs.skip_deserializing() {
+                    cx.error(
+                        "#[serde(flatten] can not be combined with \
+                         #[serde(skip_deserializing)]"
+                    );
+                }
+            }
+        }
+    }
+}
+
 /// The `other` attribute must be used at most once and it must be the last
 /// variant of an enum that has the `field_identifier` attribute.
 ///
 /// Inside a `variant_identifier` all variants must be unit variants. Inside a
 /// `field_identifier` all but possibly one variant must be unit variants. The
 /// last variant may be a newtype variant which is an implicit "other" case.
 fn check_identifier(cx: &Ctxt, cont: &Container) {
-    let variants = match cont.body {
-        Body::Enum(_, ref variants) => variants,
-        Body::Struct(_, _) => {
+    let variants = match cont.data {
+        Data::Enum(_, ref variants) => variants,
+        Data::Struct(_, _) => {
             return;
         }
     };
 
     for (i, variant) in variants.iter().enumerate() {
         match (
             variant.style,
             cont.attrs.identifier(),
@@ -97,19 +132,19 @@ fn check_identifier(cx: &Ctxt, cont: &Co
             }
         }
     }
 }
 
 /// Skip-(de)serializing attributes are not allowed on variants marked
 /// (de)serialize_with.
 fn check_variant_skip_attrs(cx: &Ctxt, cont: &Container) {
-    let variants = match cont.body {
-        Body::Enum(_, ref variants) => variants,
-        Body::Struct(_, _) => {
+    let variants = match cont.data {
+        Data::Enum(_, ref variants) => variants,
+        Data::Struct(_, _) => {
             return;
         }
     };
 
     for variant in variants.iter() {
         if variant.attrs.serialize_with().is_some() {
             if variant.attrs.skip_serializing() {
                 cx.error(format!(
@@ -164,8 +199,72 @@ fn check_variant_skip_attrs(cx: &Ctxt, c
                          and a field {} marked with #[serde(skip_deserializing)]",
                         variant.ident, ident
                     ));
                 }
             }
         }
     }
 }
+
+/// The tag of an internally-tagged struct variant must not be
+/// the same as either one of its fields, as this would result in
+/// duplicate keys in the serialized output and/or ambiguity in
+/// the to-be-deserialized input.
+fn check_internal_tag_field_name_conflict(
+    cx: &Ctxt,
+    cont: &Container,
+) {
+    let variants = match cont.data {
+        Data::Enum(_, ref variants) => variants,
+        Data::Struct(_, _) => return,
+    };
+
+    let tag = match *cont.attrs.tag() {
+        EnumTag::Internal { ref tag } => tag.as_str(),
+        EnumTag::External | EnumTag::Adjacent { .. } | EnumTag::None => return,
+    };
+
+    let diagnose_conflict = || {
+        let message = format!(
+            "variant field name `{}` conflicts with internal tag",
+            tag
+        );
+        cx.error(message);
+    };
+
+    for variant in variants {
+        match variant.style {
+            Style::Struct => {
+                for field in &variant.fields {
+                    let check_ser = !field.attrs.skip_serializing();
+                    let check_de = !field.attrs.skip_deserializing();
+                    let name = field.attrs.name();
+                    let ser_name = name.serialize_name();
+                    let de_name = name.deserialize_name();
+
+                    if check_ser && ser_name == tag || check_de && de_name == tag {
+                        diagnose_conflict();
+                        return;
+                    }
+                }
+            },
+            Style::Unit | Style::Newtype | Style::Tuple => {},
+        }
+    }
+}
+
+/// In the case of adjacently-tagged enums, the type and the
+/// contents tag must differ, for the same reason.
+fn check_adjacent_tag_conflict(cx: &Ctxt, cont: &Container) {
+    let (type_tag, content_tag) = match *cont.attrs.tag() {
+        EnumTag::Adjacent { ref tag, ref content } => (tag, content),
+        EnumTag::Internal { .. } | EnumTag::External | EnumTag::None => return,
+    };
+
+    if type_tag == content_tag {
+        let message = format!(
+            "enum tags `{}` for type and content conflict with each other",
+            type_tag
+        );
+        cx.error(message);
+    }
+}
--- a/third_party/rust/serde_derive_internals/src/ctxt.rs
+++ b/third_party/rust/serde_derive_internals/src/ctxt.rs
@@ -3,16 +3,17 @@
 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
 use std::fmt::Display;
 use std::cell::RefCell;
+use std::thread;
 
 #[derive(Default)]
 pub struct Ctxt {
     errors: RefCell<Option<Vec<String>>>,
 }
 
 impl Ctxt {
     pub fn new() -> Self {
@@ -43,13 +44,13 @@ impl Ctxt {
                 Err(msg)
             }
         }
     }
 }
 
 impl Drop for Ctxt {
     fn drop(&mut self) {
-        if self.errors.borrow().is_some() {
+        if !thread::panicking() && self.errors.borrow().is_some() {
             panic!("forgot to check for errors");
         }
     }
 }
--- a/third_party/rust/serde_derive_internals/src/lib.rs
+++ b/third_party/rust/serde_derive_internals/src/lib.rs
@@ -1,21 +1,24 @@
 // Copyright 2017 Serde Developers
 //
 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![doc(html_root_url = "https://docs.rs/serde_derive_internals/0.19.0")]
+#![doc(html_root_url = "https://docs.rs/serde_derive_internals/0.22.1")]
+#![cfg_attr(feature = "cargo-clippy", allow(cyclomatic_complexity, doc_markdown, match_same_arms,
+                                            redundant_field_names))]
 
+#[macro_use]
 extern crate syn;
-#[macro_use]
-extern crate synom;
+
+extern crate proc_macro2;
 
 pub mod ast;
 pub mod attr;
 
 mod ctxt;
 pub use ctxt::Ctxt;
 
 mod case;