Bug 1447998 - Update cargo lockfile and re-vendor rust dependencies. r=jrmuizel
authorKartikaya Gupta <kgupta@mozilla.com>
Wed, 28 Mar 2018 09:13:15 -0400
changeset 463947 a06708e468f98e7073c8ad25c186636d90370a8a
parent 463946 d266eaf936d460cb66378fb20b37c070db0ec07a
child 463948 f6f0e4f4e37c1e930f3d4e86db0d36d8e4021613
push id9165
push userasasaki@mozilla.com
push dateThu, 26 Apr 2018 21:04:54 +0000
treeherdermozilla-beta@064c3804de2e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjrmuizel
bugs1447998
milestone61.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
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;