Backed out 2 changesets (bug 1529117) for failures on webdriver/tests/new_session/invalid_capabilities.py. CLOSED TREE
authorCsoregi Natalia <ncsoregi@mozilla.com>
Wed, 20 Feb 2019 18:20:49 +0200
changeset 520955 31bb666768271631710ac361e5625e3492cc82b3
parent 520954 ab359d0369df423c0699fab9ff7beee7058d6f34
child 520956 aa5b7b1b30af2e70883c39955e37354757ef6699
push id2032
push userffxbld-merge
push dateMon, 13 May 2019 09:36:57 +0000
treeherdermozilla-release@455c1065dcbe [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs1529117
milestone67.0a1
backs out27882e7ca2a9fb4a48238749ce4aa1447aa6c507
fcfafe134f70eca44d7f82f60cf74a8e73236af6
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
Backed out 2 changesets (bug 1529117) for failures on webdriver/tests/new_session/invalid_capabilities.py. CLOSED TREE Backed out changeset 27882e7ca2a9 (bug 1529117) Backed out changeset fcfafe134f70 (bug 1529117)
.cargo/config.in
Cargo.lock
Cargo.toml
gfx/wr/Cargo.lock
gfx/wr/Cargo.toml
gfx/wr/webrender_api/Cargo.toml
third_party/rust/serde_derive/.cargo-checksum.json
third_party/rust/serde_derive/Cargo.toml
third_party/rust/serde_derive/LICENSE-MIT
third_party/rust/serde_derive/README.md
third_party/rust/serde_derive/crates-io.md
third_party/rust/serde_derive/src/bound.rs
third_party/rust/serde_derive/src/de.rs
third_party/rust/serde_derive/src/dummy.rs
third_party/rust/serde_derive/src/fragment.rs
third_party/rust/serde_derive/src/internals/ast.rs
third_party/rust/serde_derive/src/internals/attr.rs
third_party/rust/serde_derive/src/internals/case.rs
third_party/rust/serde_derive/src/internals/check.rs
third_party/rust/serde_derive/src/internals/ctxt.rs
third_party/rust/serde_derive/src/internals/mod.rs
third_party/rust/serde_derive/src/lib.rs
third_party/rust/serde_derive/src/pretend.rs
third_party/rust/serde_derive/src/ser.rs
--- a/.cargo/config.in
+++ b/.cargo/config.in
@@ -4,17 +4,17 @@
 # taskcluster/scripts/builder/build-sm-rust-bindings.sh
 
 [source.crates-io]
 registry = 'https://github.com/rust-lang/crates.io-index'
 replace-with = 'vendored-sources'
 
 [source."https://github.com/servo/serde"]
 git = "https://github.com/servo/serde"
-branch = "deserialize_from_enums10"
+branch = "deserialize_from_enums9"
 replace-with = "vendored-sources"
 
 [source."https://github.com/retep998/winapi-rs"]
 git = "https://github.com/froydnj/winapi-rs"
 branch = "aarch64"
 replace-with = "vendored-sources"
 
 [source."https://github.com/alexcrichton/cc-rs"]
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -1,9 +1,13 @@
-[[package]]
+# This file is automatically @generated by Cargo.
+# It is not intended for manual editing.
+# This file is automatically @generated by Cargo.
+# It is not intended for manual editing.
+[[package]]
 name = "Inflector"
 version = "0.11.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "regex 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
@@ -92,17 +96,17 @@ dependencies = [
  "error-chain 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "futures 0.1.23 (registry+https://github.com/rust-lang/crates.io-index)",
  "iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.4.6 (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.80 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_derive 1.0.88 (git+https://github.com/servo/serde?branch=deserialize_from_enums10)",
+ "serde_derive 1.0.80 (git+https://github.com/servo/serde?branch=deserialize_from_enums9)",
  "tokio-core 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)",
  "tokio-io 0.1.7 (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"
@@ -797,17 +801,17 @@ dependencies = [
 [[package]]
 name = "docopt"
 version = "0.8.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "regex 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_derive 1.0.88 (git+https://github.com/servo/serde?branch=deserialize_from_enums10)",
+ "serde_derive 1.0.80 (git+https://github.com/servo/serde?branch=deserialize_from_enums9)",
  "strsim 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "dtoa"
 version = "0.4.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
@@ -829,17 +833,17 @@ dependencies = [
 [[package]]
 name = "dwrote"
 version = "0.8.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
  "serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_derive 1.0.88 (git+https://github.com/servo/serde?branch=deserialize_from_enums10)",
+ "serde_derive 1.0.80 (git+https://github.com/servo/serde?branch=deserialize_from_enums9)",
  "winapi 0.3.6 (git+https://github.com/froydnj/winapi-rs?branch=aarch64)",
 ]
 
 [[package]]
 name = "either"
 version = "1.1.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
@@ -1039,17 +1043,17 @@ dependencies = [
  "hyper 0.12.7 (registry+https://github.com/rust-lang/crates.io-index)",
  "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "mozprofile 0.5.0",
  "mozrunner 0.9.0",
  "mozversion 0.2.0",
  "regex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_derive 1.0.88 (git+https://github.com/servo/serde?branch=deserialize_from_enums10)",
+ "serde_derive 1.0.80 (git+https://github.com/servo/serde?branch=deserialize_from_enums9)",
  "serde_json 1.0.26 (registry+https://github.com/rust-lang/crates.io-index)",
  "uuid 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
  "webdriver 0.39.0",
  "zip 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "geckoservo"
@@ -1370,17 +1374,17 @@ dependencies = [
  "ena 0.9.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "itertools 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "lalrpop-snap 0.16.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "lalrpop-util 0.16.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "petgraph 0.4.13 (registry+https://github.com/rust-lang/crates.io-index)",
  "regex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "regex-syntax 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_derive 1.0.88 (git+https://github.com/servo/serde?branch=deserialize_from_enums10)",
+ "serde_derive 1.0.80 (git+https://github.com/servo/serde?branch=deserialize_from_enums9)",
  "sha2 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "string_cache 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "term 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "lalrpop-snap"
@@ -1661,17 +1665,17 @@ dependencies = [
 [[package]]
 name = "mozilla-central-workspace-hack"
 version = "0.1.0"
 dependencies = [
  "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "proc-macro2 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
  "quote 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_derive 1.0.88 (git+https://github.com/servo/serde?branch=deserialize_from_enums10)",
+ "serde_derive 1.0.80 (git+https://github.com/servo/serde?branch=deserialize_from_enums9)",
  "syn 0.14.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "winapi 0.3.6 (git+https://github.com/froydnj/winapi-rs?branch=aarch64)",
 ]
 
 [[package]]
 name = "mozjs_sys"
 version = "0.0.0"
@@ -2186,17 +2190,17 @@ source = "registry+https://github.com/ru
 dependencies = [
  "arrayref 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
  "bincode 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "failure 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "lmdb-rkv 0.11.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "ordered-float 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_derive 1.0.88 (git+https://github.com/servo/serde?branch=deserialize_from_enums10)",
+ "serde_derive 1.0.80 (git+https://github.com/servo/serde?branch=deserialize_from_enums9)",
  "url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "uuid 0.7.1 (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"
@@ -2205,17 +2209,17 @@ dependencies = [
 ]
 
 [[package]]
 name = "rsdparsa"
 version = "0.1.0"
 dependencies = [
  "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_derive 1.0.88 (git+https://github.com/servo/serde?branch=deserialize_from_enums10)",
+ "serde_derive 1.0.80 (git+https://github.com/servo/serde?branch=deserialize_from_enums9)",
 ]
 
 [[package]]
 name = "rsdparsa_capi"
 version = "0.1.0"
 dependencies = [
  "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -2332,31 +2336,31 @@ name = "semver-parser"
 version = "0.7.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "serde"
 version = "1.0.80"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "serde_derive 1.0.88 (git+https://github.com/servo/serde?branch=deserialize_from_enums10)",
+ "serde_derive 1.0.80 (git+https://github.com/servo/serde?branch=deserialize_from_enums9)",
 ]
 
 [[package]]
 name = "serde_bytes"
 version = "0.10.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "serde_derive"
-version = "1.0.88"
-source = "git+https://github.com/servo/serde?branch=deserialize_from_enums10#84b2795d2a7b5312125a99b1ef11c67fd8d17c35"
+version = "1.0.80"
+source = "git+https://github.com/servo/serde?branch=deserialize_from_enums9#e0cc925c259cb74ce41377e4fe02713adfa6d836"
 dependencies = [
  "proc-macro2 0.4.24 (registry+https://github.com/rust-lang/crates.io-index)",
  "quote 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)",
  "syn 0.15.24 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "serde_json"
@@ -3052,17 +3056,17 @@ dependencies = [
  "cookie 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "futures 0.1.23 (registry+https://github.com/rust-lang/crates.io-index)",
  "http 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
  "hyper 0.12.7 (registry+https://github.com/rust-lang/crates.io-index)",
  "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "regex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_derive 1.0.88 (git+https://github.com/servo/serde?branch=deserialize_from_enums10)",
+ "serde_derive 1.0.80 (git+https://github.com/servo/serde?branch=deserialize_from_enums9)",
  "serde_json 1.0.26 (registry+https://github.com/rust-lang/crates.io-index)",
  "time 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)",
  "tokio 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
  "unicode-segmentation 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -3119,17 +3123,17 @@ dependencies = [
  "byteorder 1.2.7 (registry+https://github.com/rust-lang/crates.io-index)",
  "core-foundation 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "core-graphics 0.17.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "derive_more 0.13.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "euclid 0.19.5 (registry+https://github.com/rust-lang/crates.io-index)",
  "malloc_size_of_derive 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)",
  "serde_bytes 0.10.4 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_derive 1.0.88 (git+https://github.com/servo/serde?branch=deserialize_from_enums10)",
+ "serde_derive 1.0.80 (git+https://github.com/servo/serde?branch=deserialize_from_enums9)",
  "time 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)",
  "wr_malloc_size_of 0.0.1",
 ]
 
 [[package]]
 name = "webrender_bindings"
 version = "0.1.0"
 dependencies = [
@@ -3500,17 +3504,17 @@ dependencies = [
 "checksum scopeguard 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c79eb2c3ac4bc2507cda80e7f3ac5b88bd8eae4c0914d5663e6a8933994be918"
 "checksum scroll 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)" = "2f84d114ef17fd144153d608fba7c446b0145d038985e7a8cc5d08bb0ce20383"
 "checksum scroll_derive 0.9.5 (registry+https://github.com/rust-lang/crates.io-index)" = "8f1aa96c45e7f5a91cb7fabe7b279f02fea7126239fc40b732316e8b6a2d0fcb"
 "checksum semver 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7a3186ec9e65071a2095434b1f5bb24838d4e8e130f584c790f6033c79943537"
 "checksum semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403"
 "checksum semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3"
 "checksum serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)" = "15c141fc7027dd265a47c090bf864cf62b42c4d228bbcf4e51a0c9e2b0d3f7ef"
 "checksum serde_bytes 0.10.4 (registry+https://github.com/rust-lang/crates.io-index)" = "adb6e51a6b3696b301bc221d785f898b4457c619b51d7ce195a6d20baecb37b3"
-"checksum serde_derive 1.0.88 (git+https://github.com/servo/serde?branch=deserialize_from_enums10)" = "<none>"
+"checksum serde_derive 1.0.80 (git+https://github.com/servo/serde?branch=deserialize_from_enums9)" = "<none>"
 "checksum serde_json 1.0.26 (registry+https://github.com/rust-lang/crates.io-index)" = "44dd2cfde475037451fa99b7e5df77aa3cfd1536575fa8e7a538ab36dcde49ae"
 "checksum sha2 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9eb6be24e4c23a84d7184280d2722f7f2731fcdd4a9d886efbfe4413e4847ea0"
 "checksum sha2 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7b4d8bfd0e469f417657573d8451fb33d16cfe0989359b93baf3a1ffc639543d"
 "checksum simd 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "0048b17eb9577ac545c61d85c3559b41dfb4cbea41c9bd9ca6a4f73ff05fda84"
 "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 slab 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "5f9776d6b986f77b35c6cf846c11ad986ff128fe0b2b63a3628e3755e8d3102d"
 "checksum smallbitvec 2.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1764fe2b30ee783bfe3b9b37b2649d8d590b3148bb12e0079715d4d5c673562e"
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -53,11 +53,11 @@ panic = "abort"
 opt-level = 2
 rpath = false
 debug-assertions = false
 panic = "abort"
 codegen-units = 1
 
 [patch.crates-io]
 libudev-sys = { path = "dom/webauthn/libudev-sys" }
-serde_derive = { git = "https://github.com/servo/serde", branch = "deserialize_from_enums10" }
+serde_derive = { git = "https://github.com/servo/serde", branch = "deserialize_from_enums9" }
 winapi = { git = "https://github.com/froydnj/winapi-rs", branch = "aarch64" }
 cc = { git = "https://github.com/glandium/cc-rs", branch = "1.0.23-clang-cl-aarch64" }
--- a/gfx/wr/Cargo.lock
+++ b/gfx/wr/Cargo.lock
@@ -329,17 +329,17 @@ dependencies = [
 ]
 
 [[package]]
 name = "cstr-macros"
 version = "0.1.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "procedural-masquerade 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
- "syn 0.15.26 (registry+https://github.com/rust-lang/crates.io-index)",
+ "syn 0.15.17 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "deflate"
 version = "0.7.18"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "adler32 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -349,17 +349,17 @@ dependencies = [
 [[package]]
 name = "derive_more"
 version = "0.13.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "proc-macro2 0.4.25 (registry+https://github.com/rust-lang/crates.io-index)",
  "quote 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
- "syn 0.15.26 (registry+https://github.com/rust-lang/crates.io-index)",
+ "syn 0.15.17 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "digest"
 version = "0.8.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "generic-array 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -398,17 +398,17 @@ source = "registry+https://github.com/ru
 [[package]]
 name = "dwrote"
 version = "0.8.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)",
  "serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_derive 1.0.88 (git+https://github.com/servo/serde?branch=deserialize_from_enums10)",
+ "serde_derive 1.0.80 (git+https://github.com/servo/serde?branch=deserialize_from_enums9)",
  "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "either"
 version = "1.5.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
@@ -790,17 +790,17 @@ dependencies = [
 ]
 
 [[package]]
 name = "malloc_size_of_derive"
 version = "0.1.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "proc-macro2 0.4.25 (registry+https://github.com/rust-lang/crates.io-index)",
- "syn 0.15.26 (registry+https://github.com/rust-lang/crates.io-index)",
+ "syn 0.15.17 (registry+https://github.com/rust-lang/crates.io-index)",
  "synstructure 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "matches"
 version = "0.1.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
@@ -895,17 +895,17 @@ source = "registry+https://github.com/ru
 [[package]]
 name = "num-derive"
 version = "0.2.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "num-traits 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
  "proc-macro2 0.4.25 (registry+https://github.com/rust-lang/crates.io-index)",
  "quote 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)",
- "syn 0.15.26 (registry+https://github.com/rust-lang/crates.io-index)",
+ "syn 0.15.17 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "num-integer"
 version = "0.1.38"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "num-traits 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1005,17 +1005,17 @@ dependencies = [
  "core-graphics 0.17.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "core-text 13.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "euclid 0.19.4 (registry+https://github.com/rust-lang/crates.io-index)",
  "freetype 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
  "lyon_path 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_derive 1.0.88 (git+https://github.com/servo/serde?branch=deserialize_from_enums10)",
+ "serde_derive 1.0.80 (git+https://github.com/servo/serde?branch=deserialize_from_enums9)",
  "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "pathfinder_gfx_utils"
 version = "0.2.0"
 source = "git+https://github.com/pcwalton/pathfinder?branch=webrender#e8805413321edf85870deee5678751746ed61316"
 dependencies = [
@@ -1034,28 +1034,28 @@ dependencies = [
  "env_logger 0.5.10 (registry+https://github.com/rust-lang/crates.io-index)",
  "euclid 0.19.4 (registry+https://github.com/rust-lang/crates.io-index)",
  "half 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
  "lyon_geom 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "lyon_path 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "pathfinder_path_utils 0.2.0 (git+https://github.com/pcwalton/pathfinder?branch=webrender)",
  "serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_derive 1.0.88 (git+https://github.com/servo/serde?branch=deserialize_from_enums10)",
+ "serde_derive 1.0.80 (git+https://github.com/servo/serde?branch=deserialize_from_enums9)",
 ]
 
 [[package]]
 name = "pathfinder_path_utils"
 version = "0.2.0"
 source = "git+https://github.com/pcwalton/pathfinder?branch=webrender#e8805413321edf85870deee5678751746ed61316"
 dependencies = [
  "arrayvec 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)",
  "lyon_path 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_derive 1.0.88 (git+https://github.com/servo/serde?branch=deserialize_from_enums10)",
+ "serde_derive 1.0.80 (git+https://github.com/servo/serde?branch=deserialize_from_enums9)",
 ]
 
 [[package]]
 name = "percent-encoding"
 version = "1.0.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
@@ -1254,35 +1254,35 @@ name = "semver-parser"
 version = "0.7.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "serde"
 version = "1.0.80"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "serde_derive 1.0.88 (git+https://github.com/servo/serde?branch=deserialize_from_enums10)",
+ "serde_derive 1.0.80 (git+https://github.com/servo/serde?branch=deserialize_from_enums9)",
 ]
 
 [[package]]
 name = "serde_bytes"
 version = "0.10.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "serde_derive"
-version = "1.0.88"
-source = "git+https://github.com/servo/serde?branch=deserialize_from_enums10#84b2795d2a7b5312125a99b1ef11c67fd8d17c35"
+version = "1.0.80"
+source = "git+https://github.com/servo/serde?branch=deserialize_from_enums9#e0cc925c259cb74ce41377e4fe02713adfa6d836"
 dependencies = [
  "proc-macro2 0.4.25 (registry+https://github.com/rust-lang/crates.io-index)",
  "quote 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)",
- "syn 0.15.26 (registry+https://github.com/rust-lang/crates.io-index)",
+ "syn 0.15.17 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "serde_json"
 version = "1.0.17"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "dtoa 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1381,32 +1381,32 @@ source = "registry+https://github.com/ru
 
 [[package]]
 name = "strsim"
 version = "0.7.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "syn"
-version = "0.15.26"
+version = "0.15.17"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "proc-macro2 0.4.25 (registry+https://github.com/rust-lang/crates.io-index)",
  "quote 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "synstructure"
 version = "0.10.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "proc-macro2 0.4.25 (registry+https://github.com/rust-lang/crates.io-index)",
  "quote 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)",
- "syn 0.15.26 (registry+https://github.com/rust-lang/crates.io-index)",
+ "syn 0.15.17 (registry+https://github.com/rust-lang/crates.io-index)",
  "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "tempfile"
 version = "3.0.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
@@ -1688,17 +1688,17 @@ dependencies = [
  "core-foundation 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "core-graphics 0.17.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "derive_more 0.13.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "euclid 0.19.4 (registry+https://github.com/rust-lang/crates.io-index)",
  "ipc-channel 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "malloc_size_of_derive 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)",
  "serde_bytes 0.10.4 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_derive 1.0.88 (git+https://github.com/servo/serde?branch=deserialize_from_enums10)",
+ "serde_derive 1.0.80 (git+https://github.com/servo/serde?branch=deserialize_from_enums9)",
  "time 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)",
  "wr_malloc_size_of 0.0.1",
 ]
 
 [[package]]
 name = "webrender_build"
 version = "0.0.1"
 dependencies = [
@@ -2013,30 +2013,30 @@ dependencies = [
 "checksum rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a"
 "checksum safe-transmute 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9604873ffe1980bc1f179103704a65c8aca141c248d9e52b7af95ff10578166e"
 "checksum scoped_threadpool 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "1d51f5df5af43ab3f1360b429fa5e0152ac5ce8c0bd6485cae490332e96846a8"
 "checksum scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "94258f53601af11e6a49f722422f6e3425c52b06245a5cf9bc09908b174f5e27"
 "checksum semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403"
 "checksum semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3"
 "checksum serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)" = "15c141fc7027dd265a47c090bf864cf62b42c4d228bbcf4e51a0c9e2b0d3f7ef"
 "checksum serde_bytes 0.10.4 (registry+https://github.com/rust-lang/crates.io-index)" = "adb6e51a6b3696b301bc221d785f898b4457c619b51d7ce195a6d20baecb37b3"
-"checksum serde_derive 1.0.88 (git+https://github.com/servo/serde?branch=deserialize_from_enums10)" = "<none>"
+"checksum serde_derive 1.0.80 (git+https://github.com/servo/serde?branch=deserialize_from_enums9)" = "<none>"
 "checksum serde_json 1.0.17 (registry+https://github.com/rust-lang/crates.io-index)" = "f3ad6d546e765177cf3dded3c2e424a8040f870083a0e64064746b958ece9cb1"
 "checksum servo-fontconfig 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a088f8d775a5c5314aae09bd77340bc9c67d72b9a45258be34c83548b4814cd9"
 "checksum servo-fontconfig-sys 4.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "38b494f03009ee81914b0e7d387ad7c145cafcd69747c2ec89b0e17bb94f303a"
 "checksum servo-freetype-sys 4.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "2c4ccb6d0d32d277d3ef7dea86203d8210945eb7a45fba89dd445b3595dd0dfc"
 "checksum sha1 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "cc30b1e1e8c40c121ca33b86c23308a090d19974ef001b4bf6e61fd1a0fb095c"
 "checksum sha2 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7b4d8bfd0e469f417657573d8451fb33d16cfe0989359b93baf3a1ffc639543d"
 "checksum shared_library 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "8254bf098ce4d8d7cc7cc6de438c5488adc5297e5b7ffef88816c0a91bd289c1"
 "checksum slab 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "17b4fcaed89ab08ef143da37bc52adbcc04d4a69014f4c1208d6b51f0c47bc23"
 "checksum smallvec 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)" = "26df3bb03ca5eac2e64192b723d51f56c1b1e0860e7c766281f4598f181acdc8"
 "checksum smithay-client-toolkit 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "428d6c019bb92753be9670367e3f483e4fcef396180a9b59e813b69b20014881"
 "checksum stable_deref_trait 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ffbc596e092fe5f598b12ef46cc03754085ac2f4d8c739ad61c4ae266cc3b3fa"
 "checksum strsim 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bb4f380125926a99e52bc279241539c018323fab05ad6368b56f93d9369ff550"
-"checksum syn 0.15.26 (registry+https://github.com/rust-lang/crates.io-index)" = "f92e629aa1d9c827b2bb8297046c1ccffc57c99b947a680d3ccff1f136a3bee9"
+"checksum syn 0.15.17 (registry+https://github.com/rust-lang/crates.io-index)" = "3391038ebc3e4ab24eb028cb0ef2f2dc4ba0cbf72ee895ed6a6fad730640b5bc"
 "checksum synstructure 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)" = "73687139bf99285483c96ac0add482c3776528beac1d97d444f6e91f203a2015"
 "checksum tempfile 3.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "47776f63b85777d984a50ce49d6b9e58826b6a3766a449fc95bc66cd5663c15b"
 "checksum termcolor 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "adc4587ead41bf016f11af03e55a624c06568b5a19db4e90fde573d805074f83"
 "checksum termion 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "689a3bdfaab439fd92bc87df5c4c78417d3cbe537487274e9b0b2dce76e92096"
 "checksum textwrap 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c0b59b6b4b44d867f1370ef1bd91bfb262bf07bf0ae65c202ea2fbc16153b693"
 "checksum thread_local 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "279ef31c19ededf577bfd12dfae728040a21f635b06a24cd670ff510edd38963"
 "checksum thread_profiler 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "5920e77802b177479ab5795767fa48e68f61b2f516c2ac0041e2978dd8efe483"
 "checksum tiff 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a2cc6c4fd13cb1cfd20abdb196e794ceccb29371855b7e7f575945f920a5b3c2"
--- a/gfx/wr/Cargo.toml
+++ b/gfx/wr/Cargo.toml
@@ -8,9 +8,9 @@ members = [
     "wrench",
 ]
 
 [profile.release]
 debug = true
 panic = "abort"
 
 [patch.crates-io]
-serde_derive = { git = "https://github.com/servo/serde", branch = "deserialize_from_enums10", feature="deserialize_in_place" }
+serde_derive = { git = "https://github.com/servo/serde", branch = "deserialize_from_enums9", feature="deserialize_in_place" }
--- a/gfx/wr/webrender_api/Cargo.toml
+++ b/gfx/wr/webrender_api/Cargo.toml
@@ -17,16 +17,16 @@ app_units = "0.7"
 bincode = "1.0"
 bitflags = "1.0"
 byteorder = "1.2.1"
 derive_more = "0.13"
 ipc-channel = {version = "0.11.0", optional = true}
 euclid = { version = "0.19.4", features = ["serde"] }
 malloc_size_of_derive = "0.1"
 serde = { version = "=1.0.80", features = ["rc"] }
-serde_derive = { version = "=1.0.88", features = ["deserialize_in_place"] }
+serde_derive = { version = "=1.0.80", features = ["deserialize_in_place"] }
 serde_bytes = "0.10"
 time = "0.1"
 wr_malloc_size_of = { version = "0.0.1", path = "../wr_malloc_size_of" }
 
 [target.'cfg(target_os = "macos")'.dependencies]
 core-foundation = "0.6"
 core-graphics = "0.17.1"
--- 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":"071ea0d1ef1e899f01b0e90383b7dfefdf1b23c733444c59815ce345e7833054","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"23f18e03dc49df91622fe2a76176497404e46ced8a715d9d2b67a7446571cca3","README.md":"11f6eec1a694070311f8ff191c53e67b90bf1d5064f32d684a1b73b1c3264ac1","crates-io.md":"131dee2d4beaf83485aed22942b98815ef65af9bcfb65f02b5b90c59b8bc7b8b","src/bound.rs":"47b4018d54220862c2546589fe3cbccdd72c5d90438c265c258c1a2ee98e9210","src/de.rs":"09ba5a4cab60dfc713ea66f69d1989786a913e060f1ec6f9b701e83f37448931","src/dummy.rs":"413f639118681cecff6188e790c88636e34dd8e1b247bbbaa7b6a121b5cf6921","src/fragment.rs":"5819ac5b16f5945c05ce47c3370745f2e73deb415367ae6afbd8208867f611d2","src/internals/ast.rs":"64cd449a627a3489053407735f0d1de669272d879a75afc66051e323a1c1ebd4","src/internals/attr.rs":"f95eb8481822f4b5eca5e28483469c020d73335d60980cb20e1c28a073b90f52","src/internals/case.rs":"b2024f414f5d832bafa53b9ae7924b2d43a29175b19bb3da36f15c9071666558","src/internals/check.rs":"d101f08b2bd007602c4a7b3f6ae2d4cb9fbe0c179cde55809a666ed4a7043a12","src/internals/ctxt.rs":"ceb74c96802f89de896a30b774b49d4954d6c3344596cbbc1ff8fad2ac754fe1","src/internals/mod.rs":"8e363739bbfcd43bcaedd1746b2d17cebd5964167c145bd0db473f0ff4521edc","src/lib.rs":"fd6883d899ea98448aee074374388fdfd8792363928cc1ddd3812737c5921a76","src/pretend.rs":"ea5aa1b338038ce1791cef34fd20091abb062cd61c0384ac931d0069413a5302","src/ser.rs":"843b2a66a17511640c4e5ebd08e16b8f58f9772c7a8283e1bb2f043b302f21be","src/try.rs":"b9a10c8690d442a57fc7097d42c9a4f13034c7b4a30b7eb02d538fdbf8ae0a8d"},"package":null}
\ No newline at end of file
+{"files":{"Cargo.toml":"32062c9ba07dc467d292a81d4843923933ef60006849646df3f15ea1a9329762","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"6485b8ed310d3f0340bf1ad1f47645069ce4069dcc6bb46c7d5c6faf41de1fdb","README.md":"c4218d07d775c036cd50495b0354c5b59435472b12e159042cacb30b6ef1a7c1","crates-io.md":"8dce715dfbd2e9bbdd87e401d1f7974a60089f0673f7a84f4c5d840411075d14","src/bound.rs":"3f52688c06ee268f5cea4003acba1dce1631cf2ca04384a1b96845e100a7b5b3","src/de.rs":"534ddd51f8b2b0c29f30319ec553fe20aa717b87e0f5cecf21bbdcdc600c3724","src/fragment.rs":"9a8539d2bda80c62e4fdaf42816f371a2add62f9cf27b4646d90b636de40f56f","src/internals/ast.rs":"3260313fbbd7c8fab2b93710a7b4c806ac3aa4ce364a8bf7e83a5c38006b3f2f","src/internals/attr.rs":"70a87942eee113eadbec9c04cc9a0b7860afe1d25c839a4245ad48322ad11975","src/internals/case.rs":"868d8ddc4adfcd0d55ece44ae7d4de8445cb65ddfd8b0e6b90dd5ab3d23c1e57","src/internals/check.rs":"c325d8b42647689c1eb982e8c878d75a547c698f6040b72ef47d93e312518494","src/internals/ctxt.rs":"1f9d7e385ab188c7716c4d3f1e4c943f45dcb29bab8c42812b9e537deeee0889","src/internals/mod.rs":"414477f6fb187268ec87f917c0db9d328f4e6d188dfde93ab7479763e93e2aca","src/lib.rs":"f1a606372aa7dfaf40791f98e357fa4d4911d6d5b735605dd27db4f481787aed","src/pretend.rs":"2b51a8c14b62735cfc80b3624522a02465820a14a1eab55abebf3a63fd5f150a","src/ser.rs":"9a8e01afdd47641377a24442d92c637eaba061d56a9ff499d91294bba21f2f69","src/try.rs":"b9a10c8690d442a57fc7097d42c9a4f13034c7b4a30b7eb02d538fdbf8ae0a8d"},"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.88" # remember to update html_root_url
+version = "1.0.80" # 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/derive.html"
 keywords = ["serde", "serialization", "no_std"]
 readme = "crates-io.md"
@@ -21,12 +21,12 @@ deserialize_in_place = []
 
 [lib]
 name = "serde_derive"
 proc-macro = true
 
 [dependencies]
 proc-macro2 = "0.4"
 quote = "0.6.3"
-syn = { version = "0.15.22", features = ["visit", "extra-traits"] }
+syn = { version = "0.15", features = ["visit", "extra-traits"] }
 
 [dev-dependencies]
 serde = { version = "1.0", path = "../serde" }
--- a/third_party/rust/serde_derive/LICENSE-MIT
+++ b/third_party/rust/serde_derive/LICENSE-MIT
@@ -1,8 +1,10 @@
+Copyright (c) 2014 The Rust Project Developers
+
 Permission is hereby granted, free of charge, to any
 person obtaining a copy of this software and associated
 documentation files (the "Software"), to deal in the
 Software without restriction, including without
 limitation the rights to use, copy, modify, merge,
 publish, distribute, sublicense, and/or sell copies of
 the Software, and to permit persons to whom the Software
 is furnished to do so, subject to the following
--- a/third_party/rust/serde_derive/README.md
+++ b/third_party/rust/serde_derive/README.md
@@ -20,38 +20,44 @@ You may be looking for:
 - [API documentation](https://docs.serde.rs/serde/)
 - [Release notes](https://github.com/serde-rs/serde/releases)
 
 ## Serde in action
 
 <details>
 <summary>
 Click to show Cargo.toml.
-<a href="https://play.rust-lang.org/?edition=2018&gist=72755f28f99afc95e01d63174b28c1f5" target="_blank">Run this code in the playground.</a>
+<a href="https://play.rust-lang.org/?gist=9003c5b88c1f4989941925d7190c6eec" target="_blank">Run this code in the playground.</a>
 </summary>
 
 ```toml
 [dependencies]
 
 # The core APIs, including the Serialize and Deserialize traits. Always
-# required when using Serde. The "derive" feature is only required when
-# using #[derive(Serialize, Deserialize)] to make Serde work with structs
-# and enums defined in your crate.
-serde = { version = "1.0", features = ["derive"] }
+# required when using Serde.
+serde = "1.0"
+
+# Support for #[derive(Serialize, Deserialize)]. Required if you want Serde
+# to work for structs and enums defined in your crate.
+serde_derive = "1.0"
 
 # Each data format lives in its own crate; the sample code below uses JSON
 # but you may be using a different one.
 serde_json = "1.0"
 ```
 
 </details>
 <p></p>
 
 ```rust
-use serde::{Serialize, Deserialize};
+#[macro_use]
+extern crate serde_derive;
+
+extern crate serde;
+extern crate serde_json;
 
 #[derive(Serialize, Deserialize, Debug)]
 struct Point {
     x: i32,
     y: i32,
 }
 
 fn main() {
--- a/third_party/rust/serde_derive/crates-io.md
+++ b/third_party/rust/serde_derive/crates-io.md
@@ -11,17 +11,21 @@ You may be looking for:
 - [Setting up `#[derive(Serialize, Deserialize)]`](https://serde.rs/derive.html)
 - [Examples](https://serde.rs/examples.html)
 - [API documentation](https://docs.serde.rs/serde/)
 - [Release notes](https://github.com/serde-rs/serde/releases)
 
 ## Serde in action
 
 ```rust
-use serde::{Serialize, Deserialize};
+#[macro_use]
+extern crate serde_derive;
+
+extern crate serde;
+extern crate serde_json;
 
 #[derive(Serialize, Deserialize, Debug)]
 struct Point {
     x: i32,
     y: i32,
 }
 
 fn main() {
--- a/third_party/rust/serde_derive/src/bound.rs
+++ b/third_party/rust/serde_derive/src/bound.rs
@@ -1,8 +1,16 @@
+// 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 std::collections::HashSet;
 
 use syn;
 use syn::punctuated::{Pair, Punctuated};
 use syn::visit::{self, Visit};
 
 use internals::ast::{Container, Data};
 use internals::attr;
@@ -19,31 +27,30 @@ pub fn without_defaults(generics: &syn::
             .iter()
             .map(|param| match *param {
                 syn::GenericParam::Type(ref param) => syn::GenericParam::Type(syn::TypeParam {
                     eq_token: None,
                     default: None,
                     ..param.clone()
                 }),
                 _ => param.clone(),
-            })
-            .collect(),
+            }).collect(),
         ..generics.clone()
     }
 }
 
 pub fn with_where_predicates(
     generics: &syn::Generics,
     predicates: &[syn::WherePredicate],
 ) -> syn::Generics {
     let mut generics = generics.clone();
     generics
         .make_where_clause()
         .predicates
-        .extend(predicates.iter().cloned());
+        .extend(predicates.into_iter().cloned());
     generics
 }
 
 pub fn with_where_predicates_from_fields(
     cont: &Container,
     generics: &syn::Generics,
     from_field: fn(&attr::Field) -> Option<&[syn::WherePredicate]>,
 ) -> syn::Generics {
@@ -156,59 +163,55 @@ pub fn with_bound(
         .collect();
 
     let mut visitor = FindTyParams {
         all_type_params: all_type_params,
         relevant_type_params: HashSet::new(),
         associated_type_usage: Vec::new(),
     };
     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 {
-                    visitor.visit_field(field.original);
-                }
+        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 {
+                visitor.visit_field(field.original);
             }
-        }
+        },
         Data::Struct(_, ref fields) => {
             for field in fields.iter().filter(|field| filter(&field.attrs, None)) {
                 visitor.visit_field(field.original);
             }
         }
     }
 
     let relevant_type_params = visitor.relevant_type_params;
     let associated_type_usage = visitor.associated_type_usage;
     let new_predicates = generics
         .type_params()
         .map(|param| param.ident.clone())
         .filter(|id| relevant_type_params.contains(id))
         .map(|id| syn::TypePath {
             qself: None,
             path: id.into(),
-        })
-        .chain(associated_type_usage.into_iter().cloned())
+        }).chain(associated_type_usage.into_iter().cloned())
         .map(|bounded_ty| {
             syn::WherePredicate::Type(syn::PredicateType {
                 lifetimes: None,
                 // the type parameter that is being bounded e.g. T
                 bounded_ty: syn::Type::Path(bounded_ty),
                 colon_token: <Token![:]>::default(),
                 // the bound e.g. Serialize
                 bounds: vec![syn::TypeParamBound::Trait(syn::TraitBound {
                     paren_token: None,
                     modifier: syn::TraitBoundModifier::None,
                     lifetimes: None,
                     path: bound.clone(),
-                })]
-                .into_iter()
+                })].into_iter()
                 .collect(),
             })
         });
 
     let mut generics = generics.clone();
     generics
         .make_where_clause()
         .predicates
@@ -231,18 +234,17 @@ pub fn with_self_bound(
             bounded_ty: type_of_item(cont),
             colon_token: <Token![:]>::default(),
             // the bound e.g. Default
             bounds: vec![syn::TypeParamBound::Trait(syn::TraitBound {
                 paren_token: None,
                 modifier: syn::TraitBoundModifier::None,
                 lifetimes: None,
                 path: bound.clone(),
-            })]
-            .into_iter()
+            })].into_iter()
             .collect(),
         }));
     generics
 }
 
 pub fn with_lifetime_bound(generics: &syn::Generics, lifetime: &str) -> syn::Generics {
     let bound = syn::Lifetime::new(lifetime, Span::call_site());
     let def = syn::LifetimeDef {
@@ -262,18 +264,17 @@ pub fn with_lifetime_bound(generics: &sy
                 syn::GenericParam::Type(ref mut param) => {
                     param
                         .bounds
                         .push(syn::TypeParamBound::Lifetime(bound.clone()));
                 }
                 syn::GenericParam::Const(_) => {}
             }
             param
-        }))
-        .collect();
+        })).collect();
 
     syn::Generics {
         params: params,
         ..generics.clone()
     }
 }
 
 fn type_of_item(cont: &Container) -> syn::Type {
@@ -299,19 +300,17 @@ fn type_of_item(cont: &Container) -> syn
                                     }))
                                 }
                                 syn::GenericParam::Lifetime(ref param) => {
                                     syn::GenericArgument::Lifetime(param.lifetime.clone())
                                 }
                                 syn::GenericParam::Const(_) => {
                                     panic!("Serde does not support const generics yet");
                                 }
-                            })
-                            .collect(),
+                            }).collect(),
                         gt_token: <Token![>]>::default(),
                     },
                 ),
-            }]
-            .into_iter()
+            }].into_iter()
             .collect(),
         },
     })
 }
--- a/third_party/rust/serde_derive/src/de.rs
+++ b/third_party/rust/serde_derive/src/de.rs
@@ -1,39 +1,49 @@
+// 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 proc_macro2::{Literal, Span, TokenStream};
 use quote::ToTokens;
 use syn::punctuated::Punctuated;
 use syn::spanned::Spanned;
 use syn::{self, Ident, Index, Member};
 
 use bound;
-use dummy;
 use fragment::{Expr, Fragment, Match, Stmts};
 use internals::ast::{Container, Data, Field, Style, Variant};
 use internals::{attr, Ctxt, Derive};
 use pretend;
+use try;
 
 #[cfg(feature = "deserialize_in_place")]
 use internals::ast::Repr;
 
 
 use std::collections::BTreeSet;
 
-pub fn expand_derive_deserialize(input: &syn::DeriveInput) -> Result<TokenStream, Vec<syn::Error>> {
+pub fn expand_derive_deserialize(input: &syn::DeriveInput) -> Result<TokenStream, String> {
     let ctxt = Ctxt::new();
-    let cont = match Container::from_ast(&ctxt, input, Derive::Deserialize) {
-        Some(cont) => cont,
-        None => return Err(ctxt.check().unwrap_err()),
-    };
+    let cont = Container::from_ast(&ctxt, input, Derive::Deserialize);
     precondition(&ctxt, &cont);
     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 suffix = ident.to_string().trim_left_matches("r#").to_owned();
+    let dummy_const = Ident::new(
+        &format!("_IMPL_DESERIALIZE_FOR_{}", suffix),
+        Span::call_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 used = pretend::pretend_used(&cont);
         quote! {
             impl #de_impl_generics #ident #ty_generics #where_clause {
@@ -59,45 +69,51 @@ pub fn expand_derive_deserialize(input: 
                     #body
                 }
 
                 #fn_deserialize_in_place
             }
         }
     };
 
-    Ok(dummy::wrap_in_const("DESERIALIZE", ident, impl_block))
+    let try_replacement = try::replacement();
+    let generated = quote! {
+        #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)]
+        const #dummy_const: () = {
+            #[allow(unknown_lints)]
+            #[cfg_attr(feature = "cargo-clippy", allow(useless_attribute))]
+            #[allow(rust_2018_idioms)]
+            extern crate serde as _serde;
+            #try_replacement
+            #impl_block
+        };
+    };
+    Ok(generated)
 }
 
 fn precondition(cx: &Ctxt, cont: &Container) {
     precondition_sized(cx, cont);
     precondition_no_de_lifetime(cx, cont);
 }
 
 fn precondition_sized(cx: &Ctxt, cont: &Container) {
     if let Data::Struct(_, ref fields) = cont.data {
         if let Some(last) = fields.last() {
             if let syn::Type::Slice(_) = *last.ty {
-                cx.error_spanned_by(
-                    cont.original,
-                    "cannot deserialize a dynamically sized struct",
-                );
+                cx.error("cannot deserialize a dynamically sized struct");
             }
         }
     }
 }
 
 fn precondition_no_de_lifetime(cx: &Ctxt, cont: &Container) {
     if let BorrowedLifetimes::Borrowed(_) = borrowed_lifetimes(cont) {
         for param in cont.generics.lifetimes() {
             if param.lifetime.to_string() == "'de" {
-                cx.error_spanned_by(
-                    &param.lifetime,
-                    "cannot deserialize when there is a lifetime parameter called 'de",
-                );
+                cx.error("cannot deserialize when there is a lifetime parameter called 'de");
                 return;
             }
         }
     }
 }
 
 #[derive(Clone)]
 struct Parameters {
@@ -357,20 +373,17 @@ fn deserialize_transparent(cont: &Contai
         Data::Enum(_, _) => unreachable!(),
     };
 
     let this = &params.this;
     let transparent_field = fields.iter().find(|f| f.attrs.transparent()).unwrap();
 
     let path = match transparent_field.attrs.deserialize_with() {
         Some(path) => quote!(#path),
-        None => {
-            let span = transparent_field.original.span();
-            quote_spanned!(span=> _serde::Deserialize::deserialize)
-        }
+        None => quote!(_serde::Deserialize::deserialize),
     };
 
     let assign = fields.iter().map(|field| {
         let member = &field.member;
         if field as *const Field == transparent_field as *const Field {
             quote!(#member: __transparent)
         } else {
             let value = match *field.attrs.default() {
@@ -664,28 +677,21 @@ fn deserialize_seq(
                     quote!({
                         #wrapper
                         _serde::export::Option::map(
                             try!(_serde::de::SeqAccess::next_element::<#wrapper_ty>(&mut __seq)),
                             |__wrap| __wrap.value)
                     })
                 }
             };
-            let value_if_none = match *field.attrs.default() {
-                attr::Default::Default => quote!(_serde::export::Default::default()),
-                attr::Default::Path(ref path) => quote!(#path()),
-                attr::Default::None => quote!(
-                    return _serde::export::Err(_serde::de::Error::invalid_length(#index_in_seq, &#expecting));
-                ),
-            };
             let assign = quote! {
                 let #var = match #visit {
                     _serde::export::Some(__value) => __value,
                     _serde::export::None => {
-                        #value_if_none
+                        return _serde::export::Err(_serde::de::Error::invalid_length(#index_in_seq, &#expecting));
                     }
                 };
             };
             index_in_seq += 1;
             assign
         }
     });
 
@@ -752,50 +758,42 @@ fn deserialize_seq_in_place(
         let member = &field.member;
 
         if field.attrs.skip_deserializing() {
             let default = Expr(expr_is_missing(field, cattrs));
             quote! {
                 self.place.#member = #default;
             }
         } else {
-            let value_if_none = match *field.attrs.default() {
-                attr::Default::Default => quote!(
-                    self.place.#member = _serde::export::Default::default();
-                ),
-                attr::Default::Path(ref path) => quote!(
-                    self.place.#member = #path();
-                ),
-                attr::Default::None => quote!(
-                    return _serde::export::Err(_serde::de::Error::invalid_length(#index_in_seq, &#expecting));
-                ),
+            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.#member)))
                         {
-                            #value_if_none
+                            #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.#member = __wrap.value;
+                            #wrapper
+                            match try!(_serde::de::SeqAccess::next_element::<#wrapper_ty>(&mut __seq)) {
+                                _serde::export::Some(__wrap) => {
+                                    self.place.#member = __wrap.value;
+                                }
+                                _serde::export::None => {
+                                    #return_invalid_length
+                                }
                             }
-                            _serde::export::None => {
-                                #value_if_none
-                            }
-                        }
-                    })
+                        })
                 }
             };
             index_in_seq += 1;
             write
         }
     });
 
     let this = &params.this;
@@ -826,20 +824,18 @@ fn deserialize_newtype_struct(
     params: &Parameters,
     field: &Field,
 ) -> TokenStream {
     let delife = params.borrowed.de_lifetime();
     let field_ty = field.ty;
 
     let value = match field.attrs.deserialize_with() {
         None => {
-            let span = field.original.span();
-            let func = quote_spanned!(span=> <#field_ty as _serde::Deserialize>::deserialize);
             quote! {
-                try!(#func(__e))
+                try!(<#field_ty as _serde::Deserialize>::deserialize(__e))
             }
         }
         Some(path) => {
             quote! {
                 try!(#path(__e))
             }
         }
     };
@@ -1147,93 +1143,79 @@ fn deserialize_struct_in_place(
 }
 
 fn deserialize_enum(
     params: &Parameters,
     variants: &[Variant],
     cattrs: &attr::Container,
 ) -> Fragment {
     match *cattrs.tag() {
-        attr::TagType::External => deserialize_externally_tagged_enum(params, variants, cattrs),
-        attr::TagType::Internal { ref tag } => {
+        attr::EnumTag::External => deserialize_externally_tagged_enum(params, variants, cattrs),
+        attr::EnumTag::Internal { ref tag } => {
             deserialize_internally_tagged_enum(params, variants, cattrs, tag)
         }
-        attr::TagType::Adjacent {
+        attr::EnumTag::Adjacent {
             ref tag,
             ref content,
         } => deserialize_adjacently_tagged_enum(params, variants, cattrs, tag, content),
-        attr::TagType::None => deserialize_untagged_enum(params, variants, cattrs),
+        attr::EnumTag::None => deserialize_untagged_enum(params, variants, cattrs),
     }
 }
 
 #[cfg(feature = "deserialize_in_place")]
 fn deserialize_enum_in_place(
     params: &Parameters,
     repr: &Repr,
     variants: &[Variant],
     cattrs: &attr::Container,
 ) -> Option<Fragment> {
     match *cattrs.tag() {
-        attr::TagType::External => deserialize_externally_tagged_enum_in_place(params, repr, variants, cattrs),
+        attr::EnumTag::External => deserialize_externally_tagged_enum_in_place(params, repr, variants, cattrs),
         _ => None,
     }
 }
 
-fn prepare_enum_variant_enum(
-    variants: &[Variant],
-    cattrs: &attr::Container,
-) -> (TokenStream, Stmts) {
-    let variant_names_idents: Vec<_> = variants
-        .iter()
-        .enumerate()
-        .filter(|&(_, variant)| !variant.attrs.skip_deserializing())
-        .map(|(i, variant)| {
-            (
-                variant.attrs.name().deserialize_name(),
-                field_i(i),
-                variant.attrs.aliases(),
-            )
-        })
-        .collect();
-
-    let other_idx = variants
-        .iter()
-        .position(|ref variant| variant.attrs.other());
-
-    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,
-        other_idx,
-    ));
-
-    (variants_stmt, variant_visitor)
-}
-
 fn deserialize_externally_tagged_enum(
     params: &Parameters,
     variants: &[Variant],
     cattrs: &attr::Container,
 ) -> 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();
 
     let type_name = cattrs.name().deserialize_name();
+
     let expecting = format!("enum {}", params.type_name());
 
-    let (variants_stmt, variant_visitor) = prepare_enum_variant_enum(variants, cattrs);
+    let variant_names_idents: Vec<_> = variants
+        .iter()
+        .enumerate()
+        .filter(|&(_, variant)| !variant.attrs.skip_deserializing())
+        .map(|(i, variant)| (variant.attrs.name().deserialize_name(), field_i(i)))
+        .collect();
+
+    let other_idx = variants
+        .iter()
+        .position(|ref variant| variant.attrs.other());
+
+    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,
+        other_idx,
+    ));
 
     // Match arms to extract a variant from a string
     let variant_arms = variants
         .iter()
         .enumerate()
         .filter(|&(_, variant)| !variant.attrs.skip_deserializing())
         .map(|(i, variant)| {
             let variant_name = field_i(i);
@@ -1289,25 +1271,21 @@ fn deserialize_externally_tagged_enum(
                 __A: _serde::de::EnumAccess<#delife>,
             {
                 #match_variant
             }
         }
 
         #variants_stmt
 
-        _serde::Deserializer::deserialize_enum(
-            __deserializer,
-            #type_name,
-            VARIANTS,
-            __Visitor {
-                marker: _serde::export::PhantomData::<#this #ty_generics>,
-                lifetime: _serde::export::PhantomData,
-            },
-        )
+        _serde::Deserializer::deserialize_enum(__deserializer, #type_name, VARIANTS,
+                                               __Visitor {
+                                                   marker: _serde::export::PhantomData::<#this #ty_generics>,
+                                                   lifetime: _serde::export::PhantomData,
+                                               })
     }
 }
 
 #[cfg(feature = "deserialize_in_place")]
 fn deserialize_externally_tagged_enum_in_place(
     params: &Parameters,
     repr: &Repr,
     variants: &[Variant],
@@ -1337,27 +1315,21 @@ fn deserialize_externally_tagged_enum_in
     let type_name = cattrs.name().deserialize_name();
 
     let expecting = format!("enum {}", params.type_name());
 
     let variant_names_idents: Vec<_> = variants
         .iter()
         .enumerate()
         .filter(|&(_, variant)| !variant.attrs.skip_deserializing())
-        .map(|(i, variant)| {
-            (
-                variant.attrs.name().deserialize_name(),
-                field_i(i),
-                variant.attrs.aliases(),
-            )
-        })
+        .map(|(i, variant)| (variant.attrs.name().deserialize_name(), field_i(i)),)
         .collect();
 
     let variants_stmt = {
-        let variant_names = variant_names_idents.iter().map(|&(ref name, _, _)| name);
+        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, None),);
 
     let non_unit_field = field_i(non_unit_index);
@@ -1560,17 +1532,40 @@ fn deserialize_externally_tagged_enum_in
 }
 
 fn deserialize_internally_tagged_enum(
     params: &Parameters,
     variants: &[Variant],
     cattrs: &attr::Container,
     tag: &str,
 ) -> Fragment {
-    let (variants_stmt, variant_visitor) = prepare_enum_variant_enum(variants, cattrs);
+    let variant_names_idents: Vec<_> = variants
+        .iter()
+        .enumerate()
+        .filter(|&(_, variant)| !variant.attrs.skip_deserializing())
+        .map(|(i, variant)| (variant.attrs.name().deserialize_name(), field_i(i)))
+        .collect();
+
+    let other_idx = variants
+        .iter()
+        .position(|ref variant| variant.attrs.other());
+
+    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,
+        other_idx,
+    ));
 
     // Match arms to extract a variant from a string
     let variant_arms = variants
         .iter()
         .enumerate()
         .filter(|&(_, variant)| !variant.attrs.skip_deserializing())
         .map(|(i, variant)| {
             let variant_name = field_i(i);
@@ -1611,17 +1606,40 @@ fn deserialize_adjacently_tagged_enum(
     tag: &str,
     content: &str,
 ) -> 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();
 
-    let (variants_stmt, variant_visitor) = prepare_enum_variant_enum(variants, cattrs);
+    let variant_names_idents: Vec<_> = variants
+        .iter()
+        .enumerate()
+        .filter(|&(_, variant)| !variant.attrs.skip_deserializing())
+        .map(|(i, variant)| (variant.attrs.name().deserialize_name(), field_i(i)))
+        .collect();
+
+    let other_idx = variants
+        .iter()
+        .position(|ref variant| variant.attrs.other());
+
+    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,
+        other_idx,
+    ));
 
     let variant_arms: &Vec<_> = &variants
         .iter()
         .enumerate()
         .filter(|&(_, variant)| !variant.attrs.skip_deserializing())
         .map(|(i, variant)| {
             let variant_index = field_i(i);
 
@@ -1630,18 +1648,17 @@ fn deserialize_adjacently_tagged_enum(
                 variant,
                 cattrs,
                 quote!(__deserializer),
             ));
 
             quote! {
                 __Field::#variant_index => #block
             }
-        })
-        .collect();
+        }).collect();
 
     let expecting = format!("adjacently tagged enum {}", params.type_name());
     let type_name = cattrs.name().deserialize_name();
     let deny_unknown_fields = cattrs.deny_unknown_fields();
 
     // If unknown fields are allowed, we pick the visitor that can step over
     // those. Otherwise we pick the visitor that fails on unknown keys.
     let field_visitor_ty = if deny_unknown_fields {
@@ -1848,49 +1865,43 @@ fn deserialize_adjacently_tagged_enum(
             fn visit_seq<__A>(self, mut __seq: __A) -> _serde::export::Result<Self::Value, __A::Error>
             where
                 __A: _serde::de::SeqAccess<#delife>,
             {
                 // Visit the first element - the tag.
                 match try!(_serde::de::SeqAccess::next_element(&mut __seq)) {
                     _serde::export::Some(__field) => {
                         // Visit the second element - the content.
-                        match try!(_serde::de::SeqAccess::next_element_seed(
-                            &mut __seq,
-                            __Seed {
-                                field: __field,
-                                marker: _serde::export::PhantomData,
-                                lifetime: _serde::export::PhantomData,
-                            },
-                        )) {
+                        match try!(_serde::de::SeqAccess::next_element_seed(&mut __seq,
+                                __Seed {
+                                    field: __field,
+                                    marker: _serde::export::PhantomData,
+                                    lifetime: _serde::export::PhantomData,
+                                })) {
                             _serde::export::Some(__ret) => _serde::export::Ok(__ret),
                             // There is no second element.
                             _serde::export::None => {
                                 _serde::export::Err(_serde::de::Error::invalid_length(1, &self))
                             }
                         }
                     }
                     // There is no first element.
                     _serde::export::None => {
                         _serde::export::Err(_serde::de::Error::invalid_length(0, &self))
                     }
                 }
             }
         }
 
         const FIELDS: &'static [&'static str] = &[#tag, #content];
-        _serde::Deserializer::deserialize_struct(
-            __deserializer,
-            #type_name,
-            FIELDS,
+        _serde::Deserializer::deserialize_struct(__deserializer, #type_name, FIELDS,
             __Visitor {
                 marker: _serde::export::PhantomData::<#this #ty_generics>,
                 lifetime: _serde::export::PhantomData,
-            },
-        )
+            })
     }
 }
 
 fn deserialize_untagged_enum(
     params: &Parameters,
     variants: &[Variant],
     cattrs: &attr::Container,
 ) -> Fragment {
@@ -2111,21 +2122,20 @@ fn deserialize_externally_tagged_newtype
     variant_ident: &syn::Ident,
     params: &Parameters,
     field: &Field,
 ) -> Fragment {
     let this = &params.this;
     match field.attrs.deserialize_with() {
         None => {
             let field_ty = field.ty;
-            let span = field.original.span();
-            let func =
-                quote_spanned!(span=> _serde::de::VariantAccess::newtype_variant::<#field_ty>);
             quote_expr! {
-                _serde::export::Result::map(#func(__variant), #this::#variant_ident)
+                _serde::export::Result::map(
+                    _serde::de::VariantAccess::newtype_variant::<#field_ty>(__variant),
+                    #this::#variant_ident)
             }
         }
         Some(path) => {
             let (wrapper, wrapper_ty) = wrap_deserialize_field_with(params, field.ty, path);
             quote_block! {
                 #wrapper
                 _serde::export::Result::map(
                     _serde::de::VariantAccess::newtype_variant::<#wrapper_ty>(__variant),
@@ -2168,39 +2178,39 @@ fn deserialize_untagged_newtype_variant(
     params: &Parameters,
     field: &Field,
     deserializer: &TokenStream,
 ) -> Fragment {
     let this = &params.this;
     let field_ty = field.ty;
     match field.attrs.deserialize_with() {
         None => {
-            let span = field.original.span();
-            let func = quote_spanned!(span=> <#field_ty as _serde::Deserialize>::deserialize);
             quote_expr! {
-                _serde::export::Result::map(#func(#deserializer), #this::#variant_ident)
+                _serde::export::Result::map(
+                    <#field_ty as _serde::Deserialize>::deserialize(#deserializer),
+                    #this::#variant_ident)
             }
         }
         Some(path) => {
             quote_block! {
                 let __value: _serde::export::Result<#field_ty, _> = #path(#deserializer);
                 _serde::export::Result::map(__value, #this::#variant_ident)
             }
         }
     }
 }
 
 fn deserialize_generated_identifier(
-    fields: &[(String, Ident, Vec<String>)],
+    fields: &[(String, Ident)],
     cattrs: &attr::Container,
     is_variant: bool,
     other_idx: Option<usize>,
 ) -> Fragment {
     let this = quote!(__Field);
-    let field_idents: &Vec<_> = &fields.iter().map(|&(_, ref ident, _)| ident).collect();
+    let field_idents: &Vec<_> = &fields.iter().map(|&(_, ref ident)| ident).collect();
 
     let (ignore_variant, fallthrough) = if !is_variant && 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 let Some(other_idx) = other_idx {
         let ignore_variant = fields[other_idx].1.clone();
         let fallthrough = quote!(_serde::export::Ok(__Field::#ignore_variant));
@@ -2291,22 +2301,20 @@ fn deserialize_custom_identifier(
     };
 
     let names_idents: Vec<_> = ordinary
         .iter()
         .map(|variant| {
             (
                 variant.attrs.name().deserialize_name(),
                 variant.ident.clone(),
-                variant.attrs.aliases(),
             )
-        })
-        .collect();
-
-    let names = names_idents.iter().map(|&(ref name, _, _)| name);
+        }).collect();
+
+    let names = names_idents.iter().map(|&(ref name, _)| name);
 
     let names_const = if fallthrough.is_some() {
         None
     } else if is_variant {
         let variants = quote! {
             const VARIANTS: &'static [&'static str] = &[ #(#names),* ];
         };
         Some(variants)
@@ -2347,43 +2355,34 @@ fn deserialize_custom_identifier(
             lifetime: _serde::export::PhantomData,
         };
         _serde::Deserializer::deserialize_identifier(__deserializer, __visitor)
     }
 }
 
 fn deserialize_identifier(
     this: &TokenStream,
-    fields: &[(String, Ident, Vec<String>)],
+    fields: &[(String, Ident)],
     is_variant: bool,
     fallthrough: Option<TokenStream>,
     collect_other_fields: bool,
 ) -> Fragment {
-    let mut flat_fields = Vec::new();
-    for &(_, ref ident, ref aliases) in fields {
-        flat_fields.extend(aliases.iter().map(|alias| (alias, ident)))
-    }
-
-    let field_strs = flat_fields.iter().map(|&(ref name, _)| name);
-    let field_borrowed_strs = flat_fields.iter().map(|&(ref name, _)| name);
-    let field_bytes = flat_fields
+    let field_strs = fields.iter().map(|&(ref name, _)| 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 = flat_fields
+    let field_borrowed_bytes = fields
         .iter()
         .map(|&(ref name, _)| Literal::byte_string(name.as_bytes()));
 
-    let constructors: &Vec<_> = &flat_fields
+    let constructors: &Vec<_> = &fields
         .iter()
         .map(|&(_, ref ident)| quote!(#this::#ident))
         .collect();
-    let main_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" };
@@ -2561,22 +2560,21 @@ fn deserialize_identifier(
     } else {
         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(#main_constructors),
+                        #variant_indices => _serde::export::Ok(#constructors),
                     )*
                     _ => _serde::export::Err(_serde::de::Error::invalid_value(
-                        _serde::de::Unexpected::Unsigned(__value),
-                        &#fallthrough_msg,
-                    ))
+                                _serde::de::Unexpected::Unsigned(__value),
+                                &#fallthrough_msg))
                 }
             }
         }
     };
 
     quote_block! {
         fn expecting(&self, __formatter: &mut _serde::export::Formatter) -> _serde::export::fmt::Result {
             _serde::export::Formatter::write_str(__formatter, #expecting)
@@ -2624,27 +2622,21 @@ fn deserialize_struct_as_struct_visitor(
     cattrs: &attr::Container,
 ) -> (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),
-                field.attrs.aliases(),
-            )
-        })
+        .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);
+        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, None);
 
     let visit_map = deserialize_map(struct_path, params, fields, cattrs);
@@ -2657,23 +2649,17 @@ fn deserialize_struct_as_map_visitor(
     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),
-                field.attrs.aliases(),
-            )
-        })
+        .map(|(i, field)| (field.attrs.name().deserialize_name(), field_i(i)))
         .collect();
 
     let field_visitor = deserialize_generated_identifier(&field_names_idents, cattrs, false, None);
 
     let visit_map = deserialize_map(struct_path, params, fields, cattrs);
 
     (field_visitor, None, visit_map)
 }
@@ -2730,22 +2716,17 @@ fn deserialize_map(
                     quote! {
                         try!(#func(&mut __map))
                     }
                 }
                 Some(path) => {
                     let (wrapper, wrapper_ty) = wrap_deserialize_field_with(params, field.ty, path);
                     quote!({
                         #wrapper
-                        match _serde::de::MapAccess::next_value::<#wrapper_ty>(&mut __map) {
-                            _serde::export::Ok(__wrapper) => __wrapper.value,
-                            _serde::export::Err(__err) => {
-                                return _serde::export::Err(__err);
-                            }
-                        }
+                        try!(_serde::de::MapAccess::next_value::<#wrapper_ty>(&mut __map)).value
                     })
                 }
             };
             quote! {
                 __Field::#name => {
                     if _serde::export::Option::is_some(&#name) {
                         return _serde::export::Err(<__A::Error as _serde::de::Error>::duplicate_field(#deser_name));
                     }
@@ -2802,24 +2783,21 @@ fn deserialize_map(
                     _serde::export::Some(#name) => #name,
                     _serde::export::None => #missing_expr
                 };
             }
         });
 
     let extract_collected = fields_names
         .iter()
-        .filter(|&&(field, _)| field.attrs.flatten() && !field.attrs.skip_deserializing())
+        .filter(|&&(field, _)| field.attrs.flatten())
         .map(|&(field, ref name)| {
             let field_ty = field.ty;
             let func = match field.attrs.deserialize_with() {
-                None => {
-                    let span = field.original.span();
-                    quote_spanned!(span=> _serde::de::Deserialize::deserialize)
-                }
+                None => quote!(_serde::de::Deserialize::deserialize),
                 Some(path) => quote!(#path),
             };
             quote! {
                 let #name: #field_ty = try!(#func(
                     _serde::private::de::FlatMapDeserializer(
                         &mut __collect,
                         _serde::export::PhantomData)));
             }
@@ -2899,27 +2877,21 @@ fn deserialize_struct_as_struct_in_place
     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),
-                field.attrs.aliases(),
-            )
-        })
+        .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);
+        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, None);
 
     let visit_map = deserialize_map_in_place(params, fields, cattrs);
@@ -2966,22 +2938,17 @@ fn deserialize_map_in_place(
                     quote! {
                         try!(_serde::de::MapAccess::next_value_seed(&mut __map, _serde::private::de::InPlaceSeed(&mut self.place.#member)))
                     }
                 }
                 Some(path) => {
                     let (wrapper, wrapper_ty) = wrap_deserialize_field_with(params, field.ty, path);
                     quote!({
                         #wrapper
-                        self.place.#member = match _serde::de::MapAccess::next_value::<#wrapper_ty>(&mut __map) {
-                            _serde::export::Ok(__wrapper) => __wrapper.value,
-                            _serde::export::Err(__err) => {
-                                return _serde::export::Err(__err);
-                            }
-                        };
+                        self.place.#member = try!(_serde::de::MapAccess::next_value::<#wrapper_ty>(&mut __map)).value
                     })
                 }
             };
             quote! {
                 __Field::#name => {
                     if #name {
                         return _serde::export::Err(<__A::Error as _serde::de::Error>::duplicate_field(#deser_name));
                     }
@@ -3172,19 +3139,17 @@ fn wrap_deserialize_variant_with(
     };
 
     (wrapper, wrapper_ty, unwrap_fn)
 }
 
 fn expr_is_missing(field: &Field, cattrs: &attr::Container) -> Fragment {
     match *field.attrs.default() {
         attr::Default::Default => {
-            let span = field.original.span();
-            let func = quote_spanned!(span=> _serde::export::Default::default);
-            return quote_expr!(#func());
+            return quote_expr!(_serde::export::Default::default());
         }
         attr::Default::Path(ref path) => {
             return quote_expr!(#path());
         }
         attr::Default::None => { /* below */ }
     }
 
     match *cattrs.default() {
deleted file mode 100644
--- a/third_party/rust/serde_derive/src/dummy.rs
+++ /dev/null
@@ -1,32 +0,0 @@
-use proc_macro2::{Ident, Span, TokenStream};
-
-use try;
-
-pub fn wrap_in_const(trait_: &str, ty: &Ident, code: TokenStream) -> TokenStream {
-    let try_replacement = try::replacement();
-
-    let dummy_const = Ident::new(
-        &format!("_IMPL_{}_FOR_{}", trait_, unraw(ty)),
-        Span::call_site(),
-    );
-
-    quote! {
-        #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)]
-        const #dummy_const: () = {
-            #[allow(unknown_lints)]
-            #[cfg_attr(feature = "cargo-clippy", allow(useless_attribute))]
-            #[allow(rust_2018_idioms)]
-            extern crate serde as _serde;
-            #try_replacement
-            #code
-        };
-    }
-}
-
-#[allow(deprecated)]
-fn unraw(ident: &Ident) -> String {
-    // str::trim_start_matches was added in 1.30, trim_left_matches deprecated
-    // in 1.33. We currently support rustc back to 1.15 so we need to continue
-    // to use the deprecated one.
-    ident.to_string().trim_left_matches("r#").to_owned()
-}
--- a/third_party/rust/serde_derive/src/fragment.rs
+++ b/third_party/rust/serde_derive/src/fragment.rs
@@ -1,8 +1,16 @@
+// 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 proc_macro2::TokenStream;
 use quote::ToTokens;
 use syn::token;
 
 pub enum Fragment {
     /// Tokens that can be used as an expression.
     Expr(TokenStream),
     /// Tokens that can be used inside a block. The surrounding curly braces are
--- a/third_party/rust/serde_derive/src/internals/ast.rs
+++ b/third_party/rust/serde_derive/src/internals/ast.rs
@@ -1,8 +1,16 @@
+// 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.
+
 //! A Serde ast, parsed from the Syn ast and ready to generate Rust code.
 
 use internals::attr;
 use internals::check;
 use internals::{Ctxt, Derive};
 use syn;
 use syn::punctuated::Punctuated;
 
@@ -12,35 +20,32 @@ pub struct Container<'a> {
     /// The struct or enum name (without generics).
     pub ident: syn::Ident,
     /// Attributes on the structure, parsed for Serde.
     pub attrs: attr::Container,
     /// The contents of the struct or enum.
     pub data: Data<'a>,
     /// Any generics on the struct or enum.
     pub generics: &'a syn::Generics,
-    /// Original input.
-    pub original: &'a syn::DeriveInput,
 }
 
 /// The fields of a struct or enum.
 ///
 /// Analagous to `syn::Data`.
 pub enum Data<'a> {
     Enum(Repr, Vec<Variant<'a>>),
     Struct(Style, Vec<Field<'a>>),
 }
 
 /// A variant of an enum.
 pub struct Variant<'a> {
     pub ident: syn::Ident,
     pub attrs: attr::Variant,
     pub style: Style,
     pub fields: Vec<Field<'a>>,
-    pub original: &'a syn::Variant,
 }
 
 /// A field of a struct.
 pub struct Field<'a> {
     pub member: syn::Member,
     pub attrs: attr::Field,
     pub ty: &'a syn::Type,
     pub original: &'a syn::Field,
@@ -61,76 +66,64 @@ pub enum Style {
     /// One unnamed field.
     Newtype,
     /// No fields.
     Unit,
 }
 
 impl<'a> Container<'a> {
     /// Convert the raw Syn ast into a parsed container object, collecting errors in `cx`.
-    pub fn from_ast(
-        cx: &Ctxt,
-        item: &'a syn::DeriveInput,
-        derive: Derive,
-    ) -> Option<Container<'a>> {
+    pub fn from_ast(cx: &Ctxt, item: &'a syn::DeriveInput, derive: Derive) -> Container<'a> {
         let mut attrs = attr::Container::from_ast(cx, item);
 
         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::Data::Struct(ref data) => {
                 let (style, fields) = struct_from_ast(cx, &data.fields, None, attrs.default());
                 Data::Struct(style, fields)
             }
             syn::Data::Union(_) => {
-                cx.error_spanned_by(item, "Serde does not support derive for unions");
-                return None;
+                panic!("Serde does not support derive for unions");
             }
         };
 
         let mut has_flatten = false;
         match data {
-            Data::Enum(_, ref mut variants) => {
-                for variant in variants {
-                    variant.attrs.rename_by_rules(attrs.rename_all_rules());
-                    for field in &mut variant.fields {
-                        if field.attrs.flatten() {
-                            has_flatten = true;
-                        }
-                        field
-                            .attrs
-                            .rename_by_rules(variant.attrs.rename_all_rules());
-                    }
-                }
-            }
-            Data::Struct(_, ref mut fields) => {
-                for field in fields {
+            Data::Enum(_, ref mut variants) => for variant in variants {
+                variant.attrs.rename_by_rule(attrs.rename_all());
+                for field in &mut variant.fields {
                     if field.attrs.flatten() {
                         has_flatten = true;
                     }
-                    field.attrs.rename_by_rules(attrs.rename_all_rules());
+                    field.attrs.rename_by_rule(variant.attrs.rename_all());
                 }
-            }
+            },
+            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 mut item = Container {
             ident: item.ident.clone(),
             attrs: attrs,
             data: data,
             generics: &item.generics,
-            original: item,
         };
         check::check(cx, &mut item, derive);
-        Some(item)
+        item
     }
 }
 
 impl<'a> Data<'a> {
     pub fn all_fields(&'a self) -> Box<Iterator<Item = &'a Field<'a>> + 'a> {
         match *self {
             Data::Enum(_, ref variants) => {
                 Box::new(variants.iter().flat_map(|variant| variant.fields.iter()))
@@ -160,35 +153,36 @@ impl Repr {
             None
         } else {
             self.int_repr
         }
     }
 }
 
 fn enum_from_ast<'a>(
-    cx: &Ctxt,
-    item: &'a syn::DeriveInput,
+    cx: &Ctxt, 
+    item: &'a syn::DeriveInput, 
     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.fields, Some(&attrs), container_default);
-            Variant {
-                ident: variant.ident.clone(),
-                attrs: attrs,
-                style: style,
-                fields: fields,
-                original: variant,
-            }
-        })
+        .map(
+            |variant| {
+                let attrs = attr::Variant::from_ast(cx, variant);
+                let (style, fields) = 
+                    struct_from_ast(cx, &variant.fields, Some(&attrs), container_default);
+                Variant {
+                    ident: variant.ident.clone(),
+                    attrs: attrs,
+                    style: style,
+                    fields: fields,
+                }
+            },
+        )
         .collect();
 
     // Compute repr info for enum optimizations
     static INT_TYPES: [&'static str; 12] = [
         "u8", "u16", "u32", "u64", "u128", "usize",
         "i8", "i16", "i32", "i64", "i128", "isize",
     ];
 
@@ -263,11 +257,10 @@ fn fields_from_ast<'a>(
         .map(|(i, field)| Field {
             member: match field.ident {
                 Some(ref ident) => syn::Member::Named(ident.clone()),
                 None => syn::Member::Unnamed(i.into()),
             },
             attrs: attr::Field::from_ast(cx, i, field, attrs, container_default),
             ty: &field.ty,
             original: field,
-        })
-        .collect()
+        }).collect()
 }
--- a/third_party/rust/serde_derive/src/internals/attr.rs
+++ b/third_party/rust/serde_derive/src/internals/attr.rs
@@ -1,11 +1,18 @@
+// 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 internals::Ctxt;
 use proc_macro2::{Group, Span, TokenStream, TokenTree};
-use quote::ToTokens;
 use std::collections::BTreeSet;
 use std::str::FromStr;
 use syn;
 use syn::parse::{self, Parse, ParseStream};
 use syn::punctuated::Punctuated;
 use syn::Ident;
 use syn::Meta::{List, NameValue, Word};
 use syn::NestedMeta::{Literal, Meta};
@@ -15,218 +22,114 @@ use syn::NestedMeta::{Literal, Meta};
 // `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 internals::case::RenameRule;
 
+#[derive(Copy, Clone)]
 struct Attr<'c, T> {
     cx: &'c Ctxt,
     name: &'static str,
-    tokens: TokenStream,
     value: Option<T>,
 }
 
 impl<'c, T> Attr<'c, T> {
     fn none(cx: &'c Ctxt, name: &'static str) -> Self {
         Attr {
             cx: cx,
             name: name,
-            tokens: TokenStream::new(),
             value: None,
         }
     }
 
-    fn set<A: ToTokens>(&mut self, obj: A, value: T) {
-        let tokens = obj.into_token_stream();
-
+    fn set(&mut self, value: T) {
         if self.value.is_some() {
             self.cx
-                .error_spanned_by(tokens, format!("duplicate serde attribute `{}`", self.name));
+                .error(format!("duplicate serde attribute `{}`", self.name));
         } else {
-            self.tokens = tokens;
             self.value = Some(value);
         }
     }
 
-    fn set_opt<A: ToTokens>(&mut self, obj: A, value: Option<T>) {
+    fn set_opt(&mut self, value: Option<T>) {
         if let Some(value) = value {
-            self.set(obj, value);
+            self.set(value);
         }
     }
 
     fn set_if_none(&mut self, value: T) {
         if self.value.is_none() {
             self.value = Some(value);
         }
     }
 
     fn get(self) -> Option<T> {
         self.value
     }
-
-    fn get_with_tokens(self) -> Option<(TokenStream, T)> {
-        match self.value {
-            Some(v) => Some((self.tokens, v)),
-            None => None,
-        }
-    }
 }
 
 struct BoolAttr<'c>(Attr<'c, ()>);
 
 impl<'c> BoolAttr<'c> {
     fn none(cx: &'c Ctxt, name: &'static str) -> Self {
         BoolAttr(Attr::none(cx, name))
     }
 
-    fn set_true<A: ToTokens>(&mut self, obj: A) {
-        self.0.set(obj, ());
+    fn set_true(&mut self) {
+        self.0.set(());
     }
 
     fn get(&self) -> bool {
         self.0.value.is_some()
     }
 }
 
-struct VecAttr<'c, T> {
-    cx: &'c Ctxt,
-    name: &'static str,
-    first_dup_tokens: TokenStream,
-    values: Vec<T>,
+pub struct Name {
+    serialize: String,
+    deserialize: String,
 }
 
-impl<'c, T> VecAttr<'c, T> {
-    fn none(cx: &'c Ctxt, name: &'static str) -> Self {
-        VecAttr {
-            cx: cx,
-            name: name,
-            first_dup_tokens: TokenStream::new(),
-            values: Vec::new(),
-        }
-    }
-
-    fn insert<A: ToTokens>(&mut self, obj: A, value: T) {
-        if self.values.len() == 1 {
-            self.first_dup_tokens = obj.into_token_stream();
-        }
-        self.values.push(value);
-    }
-
-    fn at_most_one(mut self) -> Result<Option<T>, ()> {
-        if self.values.len() > 1 {
-            let dup_token = self.first_dup_tokens;
-            self.cx.error_spanned_by(
-                dup_token,
-                format!("duplicate serde attribute `{}`", self.name),
-            );
-            Err(())
-        } else {
-            Ok(self.values.pop())
-        }
-    }
-
-    fn get(self) -> Vec<T> {
-        self.values
-    }
-}
-
-pub struct Name {
-    serialize: String,
-    serialize_renamed: bool,
-    deserialize: String,
-    deserialize_renamed: bool,
-    deserialize_aliases: Vec<String>,
-}
-
-#[allow(deprecated)]
 fn unraw(ident: &Ident) -> String {
-    // str::trim_start_matches was added in 1.30, trim_left_matches deprecated
-    // in 1.33. We currently support rustc back to 1.15 so we need to continue
-    // to use the deprecated one.
     ident.to_string().trim_left_matches("r#").to_owned()
 }
 
 impl Name {
-    fn from_attrs(
-        source_name: String,
-        ser_name: Attr<String>,
-        de_name: Attr<String>,
-        de_aliases: Option<VecAttr<String>>,
-    ) -> Name {
-        let deserialize_aliases = match de_aliases {
-            Some(de_aliases) => {
-                let mut alias_list = BTreeSet::new();
-                for alias_name in de_aliases.get() {
-                    alias_list.insert(alias_name);
-                }
-                alias_list.into_iter().collect()
-            }
-            None => Vec::new(),
-        };
-
-        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();
-        Name {
-            serialize: ser_name.unwrap_or_else(|| source_name.clone()),
-            serialize_renamed: ser_renamed,
-            deserialize: de_name.unwrap_or(source_name),
-            deserialize_renamed: de_renamed,
-            deserialize_aliases: deserialize_aliases,
-        }
-    }
-
     /// Return the container name for the container when serializing.
     pub fn serialize_name(&self) -> String {
         self.serialize.clone()
     }
 
     /// Return the container name for the container when deserializing.
     pub fn deserialize_name(&self) -> String {
         self.deserialize.clone()
     }
-
-    fn deserialize_aliases(&self) -> Vec<String> {
-        let mut aliases = self.deserialize_aliases.clone();
-        let main_name = self.deserialize_name();
-        if !aliases.contains(&main_name) {
-            aliases.push(main_name);
-        }
-        aliases
-    }
-}
-
-pub struct RenameAllRules {
-    serialize: RenameRule,
-    deserialize: RenameRule,
 }
 
 /// Represents struct or enum attribute information.
 pub struct Container {
     name: Name,
     transparent: bool,
     deny_unknown_fields: bool,
     default: Default,
-    rename_all_rules: RenameAllRules,
+    rename_all: RenameRule,
     ser_bound: Option<Vec<syn::WherePredicate>>,
     de_bound: Option<Vec<syn::WherePredicate>>,
-    tag: TagType,
+    tag: EnumTag,
     type_from: Option<syn::Type>,
     type_into: Option<syn::Type>,
     remote: Option<syn::Path>,
     identifier: Identifier,
     has_flatten: bool,
 }
 
 /// Styles of representing an enum.
-pub enum TagType {
+pub enum EnumTag {
     /// The default.
     ///
     /// ```json
     /// {"variant1": {"key1": "value1", "key2": "value2"}}
     /// ```
     External,
 
     /// `#[serde(tag = "type")]`
@@ -281,18 +184,17 @@ impl Identifier {
 impl Container {
     /// Extract out the `#[serde(...)]` attributes from an item.
     pub fn from_ast(cx: &Ctxt, item: &syn::DeriveInput) -> Self {
         let mut ser_name = Attr::none(cx, "rename");
         let mut de_name = Attr::none(cx, "rename");
         let mut transparent = BoolAttr::none(cx, "transparent");
         let mut deny_unknown_fields = BoolAttr::none(cx, "deny_unknown_fields");
         let mut default = Attr::none(cx, "default");
-        let mut rename_all_ser_rule = Attr::none(cx, "rename_all");
-        let mut rename_all_de_rule = Attr::none(cx, "rename_all");
+        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 type_from = Attr::none(cx, "from");
         let mut type_into = Attr::none(cx, "into");
         let mut remote = Attr::none(cx, "remote");
@@ -300,333 +202,217 @@ impl Container {
         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")]`
                     Meta(NameValue(ref m)) if m.ident == "rename" => {
                         if let Ok(s) = get_lit_str(cx, &m.ident, &m.ident, &m.lit) {
-                            ser_name.set(&m.ident, s.value());
-                            de_name.set(&m.ident, s.value());
+                            ser_name.set(s.value());
+                            de_name.set(s.value());
                         }
                     }
 
                     // Parse `#[serde(rename(serialize = "foo", deserialize = "bar"))]`
                     Meta(List(ref m)) if m.ident == "rename" => {
                         if let Ok((ser, de)) = get_renames(cx, &m.nested) {
-                            ser_name.set_opt(&m.ident, ser.map(syn::LitStr::value));
-                            de_name.set_opt(&m.ident, de.map(syn::LitStr::value));
+                            ser_name.set_opt(ser.map(syn::LitStr::value));
+                            de_name.set_opt(de.map(syn::LitStr::value));
                         }
                     }
 
                     // Parse `#[serde(rename_all = "foo")]`
                     Meta(NameValue(ref m)) if m.ident == "rename_all" => {
                         if let Ok(s) = get_lit_str(cx, &m.ident, &m.ident, &m.lit) {
                             match RenameRule::from_str(&s.value()) {
-                                Ok(rename_rule) => {
-                                    rename_all_ser_rule.set(&m.ident, rename_rule);
-                                    rename_all_de_rule.set(&m.ident, rename_rule);
-                                }
-                                Err(()) => cx.error_spanned_by(
-                                    s,
-                                    format!(
-                                        "unknown rename rule for #[serde(rename_all \
-                                         = {:?})]",
-                                        s.value(),
-                                    ),
-                                ),
-                            }
-                        }
-                    }
-
-                    // Parse `#[serde(rename_all(serialize = "foo", deserialize = "bar"))]`
-                    Meta(List(ref m)) if m.ident == "rename_all" => {
-                        if let Ok((ser, de)) = get_renames(cx, &m.nested) {
-                            if let Some(ser) = ser {
-                                match RenameRule::from_str(&ser.value()) {
-                                    Ok(rename_rule) => {
-                                        rename_all_ser_rule.set(&m.ident, rename_rule)
-                                    }
-                                    Err(()) => cx.error_spanned_by(
-                                        ser,
-                                        format!(
-                                            "unknown rename rule for #[serde(rename_all \
-                                             = {:?})]",
-                                            ser.value(),
-                                        ),
-                                    ),
-                                }
-                            }
-                            if let Some(de) = de {
-                                match RenameRule::from_str(&de.value()) {
-                                    Ok(rename_rule) => {
-                                        rename_all_de_rule.set(&m.ident, rename_rule)
-                                    }
-                                    Err(()) => cx.error_spanned_by(
-                                        de,
-                                        format!(
-                                            "unknown rename rule for #[serde(rename_all \
-                                             = {:?})]",
-                                            de.value(),
-                                        ),
-                                    ),
-                                }
+                                Ok(rename_rule) => rename_all.set(rename_rule),
+                                Err(()) => cx.error(format!(
+                                    "unknown rename rule for #[serde(rename_all \
+                                     = {:?})]",
+                                    s.value()
+                                )),
                             }
                         }
                     }
 
                     // Parse `#[serde(transparent)]`
                     Meta(Word(ref word)) if word == "transparent" => {
-                        transparent.set_true(word);
+                        transparent.set_true();
                     }
 
                     // Parse `#[serde(deny_unknown_fields)]`
                     Meta(Word(ref word)) if word == "deny_unknown_fields" => {
-                        deny_unknown_fields.set_true(word);
+                        deny_unknown_fields.set_true();
                     }
 
                     // Parse `#[serde(default)]`
                     Meta(Word(ref word)) if word == "default" => match item.data {
-                        syn::Data::Struct(syn::DataStruct { ref fields, .. }) => match *fields {
-                            syn::Fields::Named(_) => {
-                                default.set(word, Default::Default);
-                            }
-                            syn::Fields::Unnamed(_) | syn::Fields::Unit => cx.error_spanned_by(
-                                fields,
-                                "#[serde(default)] can only be used on structs \
-                                 with named fields",
-                            ),
-                        },
-                        syn::Data::Enum(syn::DataEnum { ref enum_token, .. }) => cx
-                            .error_spanned_by(
-                                enum_token,
-                                "#[serde(default)] can only be used on structs \
-                                 with named fields",
-                            ),
-                        syn::Data::Union(syn::DataUnion {
-                            ref union_token, ..
-                        }) => cx.error_spanned_by(
-                            union_token,
+                        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 = "...")]`
                     Meta(NameValue(ref m)) if m.ident == "default" => {
                         if let Ok(path) = parse_lit_into_expr_path(cx, &m.ident, &m.lit) {
                             match item.data {
-                                syn::Data::Struct(syn::DataStruct { ref fields, .. }) => {
-                                    match *fields {
-                                        syn::Fields::Named(_) => {
-                                            default.set(&m.ident, Default::Path(path));
-                                        }
-                                        syn::Fields::Unnamed(_) | syn::Fields::Unit => cx
-                                            .error_spanned_by(
-                                                fields,
-                                                "#[serde(default = \"...\")] can only be used \
-                                                 on structs with named fields",
-                                            ),
-                                    }
+                                syn::Data::Struct(syn::DataStruct {
+                                    fields: syn::Fields::Named(_),
+                                    ..
+                                }) => {
+                                    default.set(Default::Path(path));
                                 }
-                                syn::Data::Enum(syn::DataEnum { ref enum_token, .. }) => cx
-                                    .error_spanned_by(
-                                        enum_token,
-                                        "#[serde(default = \"...\")] can only be used \
-                                         on structs with named fields",
-                                    ),
-                                syn::Data::Union(syn::DataUnion {
-                                    ref union_token, ..
-                                }) => cx.error_spanned_by(
-                                    union_token,
+                                _ => cx.error(
                                     "#[serde(default = \"...\")] can only be used \
                                      on structs with named fields",
                                 ),
                             }
                         }
                     }
 
                     // Parse `#[serde(bound = "T: SomeBound")]`
                     Meta(NameValue(ref m)) if m.ident == "bound" => {
                         if let Ok(where_predicates) =
                             parse_lit_into_where(cx, &m.ident, &m.ident, &m.lit)
                         {
-                            ser_bound.set(&m.ident, where_predicates.clone());
-                            de_bound.set(&m.ident, where_predicates);
+                            ser_bound.set(where_predicates.clone());
+                            de_bound.set(where_predicates);
                         }
                     }
 
                     // Parse `#[serde(bound(serialize = "...", deserialize = "..."))]`
                     Meta(List(ref m)) if m.ident == "bound" => {
                         if let Ok((ser, de)) = get_where_predicates(cx, &m.nested) {
-                            ser_bound.set_opt(&m.ident, ser);
-                            de_bound.set_opt(&m.ident, de);
+                            ser_bound.set_opt(ser);
+                            de_bound.set_opt(de);
                         }
                     }
 
                     // Parse `#[serde(untagged)]`
                     Meta(Word(ref word)) if word == "untagged" => match item.data {
                         syn::Data::Enum(_) => {
-                            untagged.set_true(word);
+                            untagged.set_true();
                         }
-                        syn::Data::Struct(syn::DataStruct {
-                            ref struct_token, ..
-                        }) => {
-                            cx.error_spanned_by(
-                                struct_token,
-                                "#[serde(untagged)] can only be used on enums",
-                            );
-                        }
-                        syn::Data::Union(syn::DataUnion {
-                            ref union_token, ..
-                        }) => {
-                            cx.error_spanned_by(
-                                union_token,
-                                "#[serde(untagged)] can only be used on enums",
-                            );
+                        syn::Data::Struct(_) | syn::Data::Union(_) => {
+                            cx.error("#[serde(untagged)] can only be used on enums")
                         }
                     },
 
                     // Parse `#[serde(tag = "type")]`
                     Meta(NameValue(ref m)) if m.ident == "tag" => {
                         if let Ok(s) = get_lit_str(cx, &m.ident, &m.ident, &m.lit) {
                             match item.data {
                                 syn::Data::Enum(_) => {
-                                    internal_tag.set(&m.ident, s.value());
+                                    internal_tag.set(s.value());
                                 }
-                                syn::Data::Struct(syn::DataStruct { ref fields, .. }) => {
-                                    match *fields {
-                                        syn::Fields::Named(_) => {
-                                            internal_tag.set(&m.ident, s.value());
-                                        }
-                                        syn::Fields::Unnamed(_) | syn::Fields::Unit => {
-                                            cx.error_spanned_by(
-                                                fields,
-                                                "#[serde(tag = \"...\")] can only be used on enums \
-                                                and structs with named fields",
-                                            );
-                                        }
-                                    }
-                                }
-                                syn::Data::Union(syn::DataUnion {
-                                    ref union_token, ..
-                                }) => {
-                                    cx.error_spanned_by(
-                                        union_token,
-                                        "#[serde(tag = \"...\")] can only be used on enums \
-                                         and structs with named fields",
-                                    );
+                                syn::Data::Struct(_) | syn::Data::Union(_) => {
+                                    cx.error("#[serde(tag = \"...\")] can only be used on enums")
                                 }
                             }
                         }
                     }
 
                     // Parse `#[serde(content = "c")]`
                     Meta(NameValue(ref m)) if m.ident == "content" => {
                         if let Ok(s) = get_lit_str(cx, &m.ident, &m.ident, &m.lit) {
                             match item.data {
                                 syn::Data::Enum(_) => {
-                                    content.set(&m.ident, s.value());
+                                    content.set(s.value());
                                 }
-                                syn::Data::Struct(syn::DataStruct {
-                                    ref struct_token, ..
-                                }) => {
-                                    cx.error_spanned_by(
-                                        struct_token,
-                                        "#[serde(content = \"...\")] can only be used on enums",
-                                    );
-                                }
-                                syn::Data::Union(syn::DataUnion {
-                                    ref union_token, ..
-                                }) => {
-                                    cx.error_spanned_by(
-                                        union_token,
-                                        "#[serde(content = \"...\")] can only be used on enums",
-                                    );
-                                }
+                                syn::Data::Struct(_) | syn::Data::Union(_) => cx.error(
+                                    "#[serde(content = \"...\")] can only be used on \
+                                     enums",
+                                ),
                             }
                         }
                     }
 
                     // Parse `#[serde(from = "Type")]
                     Meta(NameValue(ref m)) if m.ident == "from" => {
                         if let Ok(from_ty) = parse_lit_into_ty(cx, &m.ident, &m.lit) {
-                            type_from.set_opt(&m.ident, Some(from_ty));
+                            type_from.set_opt(Some(from_ty));
                         }
                     }
 
                     // Parse `#[serde(into = "Type")]
                     Meta(NameValue(ref m)) if m.ident == "into" => {
                         if let Ok(into_ty) = parse_lit_into_ty(cx, &m.ident, &m.lit) {
-                            type_into.set_opt(&m.ident, Some(into_ty));
+                            type_into.set_opt(Some(into_ty));
                         }
                     }
 
                     // Parse `#[serde(remote = "...")]`
                     Meta(NameValue(ref m)) if m.ident == "remote" => {
                         if let Ok(path) = parse_lit_into_path(cx, &m.ident, &m.lit) {
                             if is_primitive_path(&path, "Self") {
-                                remote.set(&m.ident, item.ident.clone().into());
+                                remote.set(item.ident.clone().into());
                             } else {
-                                remote.set(&m.ident, path);
+                                remote.set(path);
                             }
                         }
                     }
 
                     // Parse `#[serde(field_identifier)]`
                     Meta(Word(ref word)) if word == "field_identifier" => {
-                        field_identifier.set_true(word);
+                        field_identifier.set_true();
                     }
 
                     // Parse `#[serde(variant_identifier)]`
                     Meta(Word(ref word)) if word == "variant_identifier" => {
-                        variant_identifier.set_true(word);
+                        variant_identifier.set_true();
                     }
 
                     Meta(ref meta_item) => {
-                        cx.error_spanned_by(
-                            meta_item.name(),
-                            format!("unknown serde container attribute `{}`", meta_item.name()),
-                        );
+                        cx.error(format!(
+                            "unknown serde container attribute `{}`",
+                            meta_item.name()
+                        ));
                     }
 
-                    Literal(ref lit) => {
-                        cx.error_spanned_by(lit, "unexpected literal in serde container attribute");
+                    Literal(_) => {
+                        cx.error("unexpected literal in serde container attribute");
                     }
                 }
             }
         }
 
         Container {
-            name: Name::from_attrs(unraw(&item.ident), ser_name, de_name, None),
+            name: Name {
+                serialize: ser_name.get().unwrap_or_else(|| unraw(&item.ident)),
+                deserialize: de_name.get().unwrap_or_else(|| unraw(&item.ident)),
+            },
             transparent: transparent.get(),
             deny_unknown_fields: deny_unknown_fields.get(),
             default: default.get().unwrap_or(Default::None),
-            rename_all_rules: RenameAllRules {
-                serialize: rename_all_ser_rule.get().unwrap_or(RenameRule::None),
-                deserialize: rename_all_de_rule.get().unwrap_or(RenameRule::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),
+            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_rules(&self) -> &RenameAllRules {
-        &self.rename_all_rules
+    pub fn rename_all(&self) -> &RenameRule {
+        &self.rename_all
     }
 
     pub fn transparent(&self) -> bool {
         self.transparent
     }
 
     pub fn deny_unknown_fields(&self) -> bool {
         self.deny_unknown_fields
@@ -639,17 +425,17 @@ impl Container {
     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 tag(&self) -> &TagType {
+    pub fn tag(&self) -> &EnumTag {
         &self.tag
     }
 
     pub fn type_from(&self) -> Option<&syn::Type> {
         self.type_from.as_ref()
     }
 
     pub fn type_into(&self) -> Option<&syn::Type> {
@@ -671,429 +457,287 @@ impl Container {
     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>,
-) -> TagType {
-    match (
-        untagged.0.get_with_tokens(),
-        internal_tag.get_with_tokens(),
-        content.get_with_tokens(),
-    ) {
-        (None, None, None) => TagType::External,
-        (Some(_), None, None) => TagType::None,
-        (None, Some((_, tag)), None) => {
+) -> 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::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_spanned_by(
-                                    variant,
+                                cx.error(
                                     "#[serde(tag = \"...\")] cannot be used with tuple \
                                      variants",
                                 );
                                 break;
                             }
                         }
                     }
                 }
             }
-            TagType::Internal { tag: tag }
+            EnumTag::Internal { tag: tag }
         }
-        (Some((untagged_tokens, _)), Some((tag_tokens, _)), None) => {
-            cx.error_spanned_by(
-                untagged_tokens,
-                "enum cannot be both untagged and internally tagged",
-            );
-            cx.error_spanned_by(
-                tag_tokens,
-                "enum cannot be both untagged and internally tagged",
-            );
-            TagType::External // doesn't matter, will error
+        (true, Some(_), None) => {
+            cx.error("enum cannot be both untagged and internally tagged");
+            EnumTag::External // doesn't matter, will error
         }
-        (None, None, Some((content_tokens, _))) => {
-            cx.error_spanned_by(
-                content_tokens,
-                "#[serde(tag = \"...\", content = \"...\")] must be used together",
-            );
-            TagType::External
+        (false, None, Some(_)) => {
+            cx.error("#[serde(tag = \"...\", content = \"...\")] must be used together");
+            EnumTag::External
         }
-        (Some((untagged_tokens, _)), None, Some((content_tokens, _))) => {
-            cx.error_spanned_by(
-                untagged_tokens,
-                "untagged enum cannot have #[serde(content = \"...\")]",
-            );
-            cx.error_spanned_by(
-                content_tokens,
-                "untagged enum cannot have #[serde(content = \"...\")]",
-            );
-            TagType::External
+        (true, None, Some(_)) => {
+            cx.error("untagged enum cannot have #[serde(content = \"...\")]");
+            EnumTag::External
         }
-        (None, Some((_, tag)), Some((_, content))) => TagType::Adjacent {
+        (false, Some(tag), Some(content)) => EnumTag::Adjacent {
             tag: tag,
             content: content,
         },
-        (Some((untagged_tokens, _)), Some((tag_tokens, _)), Some((content_tokens, _))) => {
-            cx.error_spanned_by(
-                untagged_tokens,
-                "untagged enum cannot have #[serde(tag = \"...\", content = \"...\")]",
-            );
-            cx.error_spanned_by(
-                tag_tokens,
-                "untagged enum cannot have #[serde(tag = \"...\", content = \"...\")]",
-            );
-            cx.error_spanned_by(
-                content_tokens,
-                "untagged enum cannot have #[serde(tag = \"...\", content = \"...\")]",
-            );
-            TagType::External
+        (true, Some(_), Some(_)) => {
+            cx.error("untagged enum cannot have #[serde(tag = \"...\", content = \"...\")]");
+            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.data,
-        field_identifier.0.get_with_tokens(),
-        variant_identifier.0.get_with_tokens(),
-    ) {
-        (_, None, None) => Identifier::No,
-        (_, Some((field_identifier_tokens, _)), Some((variant_identifier_tokens, _))) => {
-            cx.error_spanned_by(
-                field_identifier_tokens,
-                "#[serde(field_identifier)] and #[serde(variant_identifier)] cannot both be set",
-            );
-            cx.error_spanned_by(
-                variant_identifier_tokens,
-                "#[serde(field_identifier)] and #[serde(variant_identifier)] cannot both be set",
-            );
-            Identifier::No
-        }
-        (&syn::Data::Enum(_), Some(_), None) => Identifier::Field,
-        (&syn::Data::Enum(_), None, Some(_)) => Identifier::Variant,
-        (
-            &syn::Data::Struct(syn::DataStruct {
-                ref struct_token, ..
-            }),
-            Some(_),
-            None,
-        ) => {
-            cx.error_spanned_by(
-                struct_token,
-                "#[serde(field_identifier)] can only be used on an enum",
-            );
+    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::Data::Union(syn::DataUnion {
-                ref union_token, ..
-            }),
-            Some(_),
-            None,
-        ) => {
-            cx.error_spanned_by(
-                union_token,
-                "#[serde(field_identifier)] can only be used on an enum",
-            );
+        (&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::Data::Struct(syn::DataStruct {
-                ref struct_token, ..
-            }),
-            None,
-            Some(_),
-        ) => {
-            cx.error_spanned_by(
-                struct_token,
-                "#[serde(variant_identifier)] can only be used on an enum",
-            );
-            Identifier::No
-        }
-        (
-            &syn::Data::Union(syn::DataUnion {
-                ref union_token, ..
-            }),
-            None,
-            Some(_),
-        ) => {
-            cx.error_spanned_by(
-                union_token,
-                "#[serde(variant_identifier)] can only be used on an enum",
-            );
+        (&syn::Data::Struct(_), false, true) | (&syn::Data::Union(_), false, true) => {
+            cx.error("`variant_identifier` can only be used on an enum");
             Identifier::No
         }
     }
 }
 
 /// Represents variant attribute information
 pub struct Variant {
     name: Name,
-    rename_all_rules: RenameAllRules,
+    ser_renamed: bool,
+    de_renamed: bool,
+    rename_all: RenameRule,
     ser_bound: Option<Vec<syn::WherePredicate>>,
     de_bound: Option<Vec<syn::WherePredicate>>,
     skip_deserializing: bool,
     skip_serializing: bool,
     other: bool,
     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 de_aliases = VecAttr::none(cx, "rename");
         let mut skip_deserializing = BoolAttr::none(cx, "skip_deserializing");
         let mut skip_serializing = BoolAttr::none(cx, "skip_serializing");
-        let mut rename_all_ser_rule = Attr::none(cx, "rename_all");
-        let mut rename_all_de_rule = Attr::none(cx, "rename_all");
+        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 other = BoolAttr::none(cx, "other");
         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")]`
                     Meta(NameValue(ref m)) if m.ident == "rename" => {
                         if let Ok(s) = get_lit_str(cx, &m.ident, &m.ident, &m.lit) {
-                            ser_name.set(&m.ident, s.value());
-                            de_name.set_if_none(s.value());
-                            de_aliases.insert(&m.ident, s.value());
+                            ser_name.set(s.value());
+                            de_name.set(s.value());
                         }
                     }
 
                     // Parse `#[serde(rename(serialize = "foo", deserialize = "bar"))]`
                     Meta(List(ref m)) if m.ident == "rename" => {
-                        if let Ok((ser, de)) = get_multiple_renames(cx, &m.nested) {
-                            ser_name.set_opt(&m.ident, ser.map(syn::LitStr::value));
-                            for de_value in de {
-                                de_name.set_if_none(de_value.value());
-                                de_aliases.insert(&m.ident, de_value.value());
-                            }
-                        }
-                    }
-
-                    // Parse `#[serde(alias = "foo")]`
-                    Meta(NameValue(ref m)) if m.ident == "alias" => {
-                        if let Ok(s) = get_lit_str(cx, &m.ident, &m.ident, &m.lit) {
-                            de_aliases.insert(&m.ident, s.value());
+                        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")]`
                     Meta(NameValue(ref m)) if m.ident == "rename_all" => {
                         if let Ok(s) = get_lit_str(cx, &m.ident, &m.ident, &m.lit) {
                             match RenameRule::from_str(&s.value()) {
-                                Ok(rename_rule) => {
-                                    rename_all_ser_rule.set(&m.ident, rename_rule);
-                                    rename_all_de_rule.set(&m.ident, rename_rule);
-                                }
-                                Err(()) => cx.error_spanned_by(
-                                    s,
-                                    format!(
-                                        "unknown rename rule for #[serde(rename_all \
-                                         = {:?})]",
-                                        s.value()
-                                    ),
-                                ),
-                            }
-                        }
-                    }
-
-                    // Parse `#[serde(rename_all(serialize = "foo", deserialize = "bar"))]`
-                    Meta(List(ref m)) if m.ident == "rename_all" => {
-                        if let Ok((ser, de)) = get_renames(cx, &m.nested) {
-                            if let Some(ser) = ser {
-                                match RenameRule::from_str(&ser.value()) {
-                                    Ok(rename_rule) => {
-                                        rename_all_ser_rule.set(&m.ident, rename_rule)
-                                    }
-                                    Err(()) => cx.error_spanned_by(
-                                        ser,
-                                        format!(
-                                            "unknown rename rule for #[serde(rename_all \
-                                             = {:?})]",
-                                            ser.value(),
-                                        ),
-                                    ),
-                                }
-                            }
-                            if let Some(de) = de {
-                                match RenameRule::from_str(&de.value()) {
-                                    Ok(rename_rule) => {
-                                        rename_all_de_rule.set(&m.ident, rename_rule)
-                                    }
-                                    Err(()) => cx.error_spanned_by(
-                                        de,
-                                        format!(
-                                            "unknown rename rule for #[serde(rename_all \
-                                             = {:?})]",
-                                            de.value(),
-                                        ),
-                                    ),
-                                }
+                                Ok(rename_rule) => rename_all.set(rename_rule),
+                                Err(()) => cx.error(format!(
+                                    "unknown rename rule for #[serde(rename_all \
+                                     = {:?})]",
+                                    s.value()
+                                )),
                             }
                         }
                     }
 
                     // Parse `#[serde(skip)]`
                     Meta(Word(ref word)) if word == "skip" => {
-                        skip_serializing.set_true(word);
-                        skip_deserializing.set_true(word);
+                        skip_serializing.set_true();
+                        skip_deserializing.set_true();
                     }
 
                     // Parse `#[serde(skip_deserializing)]`
                     Meta(Word(ref word)) if word == "skip_deserializing" => {
-                        skip_deserializing.set_true(word);
+                        skip_deserializing.set_true();
                     }
 
                     // Parse `#[serde(skip_serializing)]`
                     Meta(Word(ref word)) if word == "skip_serializing" => {
-                        skip_serializing.set_true(word);
+                        skip_serializing.set_true();
                     }
 
                     // Parse `#[serde(other)]`
                     Meta(Word(ref word)) if word == "other" => {
-                        other.set_true(word);
+                        other.set_true();
                     }
 
                     // Parse `#[serde(bound = "T: SomeBound")]`
                     Meta(NameValue(ref m)) if m.ident == "bound" => {
                         if let Ok(where_predicates) =
                             parse_lit_into_where(cx, &m.ident, &m.ident, &m.lit)
                         {
-                            ser_bound.set(&m.ident, where_predicates.clone());
-                            de_bound.set(&m.ident, where_predicates);
+                            ser_bound.set(where_predicates.clone());
+                            de_bound.set(where_predicates);
                         }
                     }
 
                     // Parse `#[serde(bound(serialize = "...", deserialize = "..."))]`
                     Meta(List(ref m)) if m.ident == "bound" => {
                         if let Ok((ser, de)) = get_where_predicates(cx, &m.nested) {
-                            ser_bound.set_opt(&m.ident, ser);
-                            de_bound.set_opt(&m.ident, de);
+                            ser_bound.set_opt(ser);
+                            de_bound.set_opt(de);
                         }
                     }
 
                     // Parse `#[serde(with = "...")]`
                     Meta(NameValue(ref m)) if m.ident == "with" => {
                         if let Ok(path) = parse_lit_into_expr_path(cx, &m.ident, &m.lit) {
                             let mut ser_path = path.clone();
                             ser_path
                                 .path
                                 .segments
                                 .push(Ident::new("serialize", Span::call_site()).into());
-                            serialize_with.set(&m.ident, ser_path);
+                            serialize_with.set(ser_path);
                             let mut de_path = path;
                             de_path
                                 .path
                                 .segments
                                 .push(Ident::new("deserialize", Span::call_site()).into());
-                            deserialize_with.set(&m.ident, de_path);
+                            deserialize_with.set(de_path);
                         }
                     }
 
                     // Parse `#[serde(serialize_with = "...")]`
                     Meta(NameValue(ref m)) if m.ident == "serialize_with" => {
                         if let Ok(path) = parse_lit_into_expr_path(cx, &m.ident, &m.lit) {
-                            serialize_with.set(&m.ident, path);
+                            serialize_with.set(path);
                         }
                     }
 
                     // Parse `#[serde(deserialize_with = "...")]`
                     Meta(NameValue(ref m)) if m.ident == "deserialize_with" => {
                         if let Ok(path) = parse_lit_into_expr_path(cx, &m.ident, &m.lit) {
-                            deserialize_with.set(&m.ident, path);
+                            deserialize_with.set(path);
                         }
                     }
 
                     // Defer `#[serde(borrow)]` and `#[serde(borrow = "'a + 'b")]`
                     Meta(ref m) if m.name() == "borrow" => match variant.fields {
                         syn::Fields::Unnamed(ref fields) if fields.unnamed.len() == 1 => {
-                            borrow.set(m.name(), m.clone());
+                            borrow.set(m.clone());
                         }
                         _ => {
-                            cx.error_spanned_by(
-                                variant,
-                                "#[serde(borrow)] may only be used on newtype variants",
-                            );
+                            cx.error("#[serde(borrow)] may only be used on newtype variants");
                         }
                     },
 
                     Meta(ref meta_item) => {
-                        cx.error_spanned_by(
-                            meta_item.name(),
-                            format!("unknown serde variant attribute `{}`", meta_item.name()),
-                        );
+                        cx.error(format!(
+                            "unknown serde variant attribute `{}`",
+                            meta_item.name()
+                        ));
                     }
 
-                    Literal(ref lit) => {
-                        cx.error_spanned_by(lit, "unexpected literal in serde variant attribute");
+                    Literal(_) => {
+                        cx.error("unexpected literal in serde variant attribute");
                     }
                 }
             }
         }
 
+        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();
         Variant {
-            name: Name::from_attrs(unraw(&variant.ident), ser_name, de_name, Some(de_aliases)),
-            rename_all_rules: RenameAllRules {
-                serialize: rename_all_ser_rule.get().unwrap_or(RenameRule::None),
-                deserialize: rename_all_de_rule.get().unwrap_or(RenameRule::None),
+            name: Name {
+                serialize: ser_name.unwrap_or_else(|| unraw(&variant.ident)),
+                deserialize: de_name.unwrap_or_else(|| unraw(&variant.ident)),
             },
+            ser_renamed: ser_renamed,
+            de_renamed: de_renamed,
+            rename_all: rename_all.get().unwrap_or(RenameRule::None),
             ser_bound: ser_bound.get(),
             de_bound: de_bound.get(),
             skip_deserializing: skip_deserializing.get(),
             skip_serializing: skip_serializing.get(),
             other: other.get(),
             serialize_with: serialize_with.get(),
             deserialize_with: deserialize_with.get(),
             borrow: borrow.get(),
         }
     }
 
     pub fn name(&self) -> &Name {
         &self.name
     }
 
-    pub fn aliases(&self) -> Vec<String> {
-        self.name.deserialize_aliases()
-    }
-
-    pub fn rename_by_rules(&mut self, rules: &RenameAllRules) {
-        if !self.name.serialize_renamed {
-            self.name.serialize = rules.serialize.apply_to_variant(&self.name.serialize);
+    pub fn rename_by_rule(&mut self, rule: &RenameRule) {
+        if !self.ser_renamed {
+            self.name.serialize = rule.apply_to_variant(&self.name.serialize);
         }
-        if !self.name.deserialize_renamed {
-            self.name.deserialize = rules.deserialize.apply_to_variant(&self.name.deserialize);
+        if !self.de_renamed {
+            self.name.deserialize = rule.apply_to_variant(&self.name.deserialize);
         }
     }
 
-    pub fn rename_all_rules(&self) -> &RenameAllRules {
-        &self.rename_all_rules
+    pub fn rename_all(&self) -> &RenameRule {
+        &self.rename_all
     }
 
     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[..])
@@ -1118,16 +762,18 @@ impl Variant {
     pub fn deserialize_with(&self) -> Option<&syn::ExprPath> {
         self.deserialize_with.as_ref()
     }
 }
 
 /// Represents field attribute information
 pub struct Field {
     name: Name,
+    ser_renamed: bool,
+    de_renamed: bool,
     skip_serializing: bool,
     skip_deserializing: bool,
     skip_serializing_if: Option<syn::ExprPath>,
     default: Default,
     serialize_with: Option<syn::ExprPath>,
     deserialize_with: Option<syn::ExprPath>,
     ser_bound: Option<Vec<syn::WherePredicate>>,
     de_bound: Option<Vec<syn::WherePredicate>>,
@@ -1162,17 +808,16 @@ impl Field {
         cx: &Ctxt,
         index: usize,
         field: &syn::Field,
         attrs: Option<&Variant>,
         container_default: &Default,
     ) -> Self {
         let mut ser_name = Attr::none(cx, "rename");
         let mut de_name = Attr::none(cx, "rename");
-        let mut de_aliases = VecAttr::none(cx, "rename");
         let mut skip_serializing = BoolAttr::none(cx, "skip_serializing");
         let mut skip_deserializing = BoolAttr::none(cx, "skip_deserializing");
         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");
@@ -1195,173 +840,159 @@ impl Field {
             .filter_map(get_serde_meta_items)
             .chain(variant_borrow)
         {
             for meta_item in meta_items {
                 match meta_item {
                     // Parse `#[serde(rename = "foo")]`
                     Meta(NameValue(ref m)) if m.ident == "rename" => {
                         if let Ok(s) = get_lit_str(cx, &m.ident, &m.ident, &m.lit) {
-                            ser_name.set(&m.ident, s.value());
-                            de_name.set_if_none(s.value());
-                            de_aliases.insert(&m.ident, s.value());
+                            ser_name.set(s.value());
+                            de_name.set(s.value());
                         }
                     }
 
                     // Parse `#[serde(rename(serialize = "foo", deserialize = "bar"))]`
                     Meta(List(ref m)) if m.ident == "rename" => {
-                        if let Ok((ser, de)) = get_multiple_renames(cx, &m.nested) {
-                            ser_name.set_opt(&m.ident, ser.map(syn::LitStr::value));
-                            for de_value in de {
-                                de_name.set_if_none(de_value.value());
-                                de_aliases.insert(&m.ident, de_value.value());
-                            }
-                        }
-                    }
-
-                    // Parse `#[serde(alias = "foo")]`
-                    Meta(NameValue(ref m)) if m.ident == "alias" => {
-                        if let Ok(s) = get_lit_str(cx, &m.ident, &m.ident, &m.lit) {
-                            de_aliases.insert(&m.ident, s.value());
+                        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)]`
                     Meta(Word(ref word)) if word == "default" => {
-                        default.set(word, Default::Default);
+                        default.set(Default::Default);
                     }
 
                     // Parse `#[serde(default = "...")]`
                     Meta(NameValue(ref m)) if m.ident == "default" => {
                         if let Ok(path) = parse_lit_into_expr_path(cx, &m.ident, &m.lit) {
-                            default.set(&m.ident, Default::Path(path));
+                            default.set(Default::Path(path));
                         }
                     }
 
                     // Parse `#[serde(skip_serializing)]`
                     Meta(Word(ref word)) if word == "skip_serializing" => {
-                        skip_serializing.set_true(word);
+                        skip_serializing.set_true();
                     }
 
                     // Parse `#[serde(skip_deserializing)]`
                     Meta(Word(ref word)) if word == "skip_deserializing" => {
-                        skip_deserializing.set_true(word);
+                        skip_deserializing.set_true();
                     }
 
                     // Parse `#[serde(skip)]`
                     Meta(Word(ref word)) if word == "skip" => {
-                        skip_serializing.set_true(word);
-                        skip_deserializing.set_true(word);
+                        skip_serializing.set_true();
+                        skip_deserializing.set_true();
                     }
 
                     // Parse `#[serde(skip_serializing_if = "...")]`
                     Meta(NameValue(ref m)) if m.ident == "skip_serializing_if" => {
                         if let Ok(path) = parse_lit_into_expr_path(cx, &m.ident, &m.lit) {
-                            skip_serializing_if.set(&m.ident, path);
+                            skip_serializing_if.set(path);
                         }
                     }
 
                     // Parse `#[serde(serialize_with = "...")]`
                     Meta(NameValue(ref m)) if m.ident == "serialize_with" => {
                         if let Ok(path) = parse_lit_into_expr_path(cx, &m.ident, &m.lit) {
-                            serialize_with.set(&m.ident, path);
+                            serialize_with.set(path);
                         }
                     }
 
                     // Parse `#[serde(deserialize_with = "...")]`
                     Meta(NameValue(ref m)) if m.ident == "deserialize_with" => {
                         if let Ok(path) = parse_lit_into_expr_path(cx, &m.ident, &m.lit) {
-                            deserialize_with.set(&m.ident, path);
+                            deserialize_with.set(path);
                         }
                     }
 
                     // Parse `#[serde(with = "...")]`
                     Meta(NameValue(ref m)) if m.ident == "with" => {
                         if let Ok(path) = parse_lit_into_expr_path(cx, &m.ident, &m.lit) {
                             let mut ser_path = path.clone();
                             ser_path
                                 .path
                                 .segments
                                 .push(Ident::new("serialize", Span::call_site()).into());
-                            serialize_with.set(&m.ident, ser_path);
+                            serialize_with.set(ser_path);
                             let mut de_path = path;
                             de_path
                                 .path
                                 .segments
                                 .push(Ident::new("deserialize", Span::call_site()).into());
-                            deserialize_with.set(&m.ident, de_path);
+                            deserialize_with.set(de_path);
                         }
                     }
 
                     // Parse `#[serde(bound = "T: SomeBound")]`
                     Meta(NameValue(ref m)) if m.ident == "bound" => {
                         if let Ok(where_predicates) =
                             parse_lit_into_where(cx, &m.ident, &m.ident, &m.lit)
                         {
-                            ser_bound.set(&m.ident, where_predicates.clone());
-                            de_bound.set(&m.ident, where_predicates);
+                            ser_bound.set(where_predicates.clone());
+                            de_bound.set(where_predicates);
                         }
                     }
 
                     // Parse `#[serde(bound(serialize = "...", deserialize = "..."))]`
                     Meta(List(ref m)) if m.ident == "bound" => {
                         if let Ok((ser, de)) = get_where_predicates(cx, &m.nested) {
-                            ser_bound.set_opt(&m.ident, ser);
-                            de_bound.set_opt(&m.ident, de);
+                            ser_bound.set_opt(ser);
+                            de_bound.set_opt(de);
                         }
                     }
 
                     // Parse `#[serde(borrow)]`
                     Meta(Word(ref word)) if word == "borrow" => {
-                        if let Ok(borrowable) = borrowable_lifetimes(cx, &ident, field) {
-                            borrowed_lifetimes.set(word, borrowable);
+                        if let Ok(borrowable) = borrowable_lifetimes(cx, &ident, &field.ty) {
+                            borrowed_lifetimes.set(borrowable);
                         }
                     }
 
                     // Parse `#[serde(borrow = "'a + 'b")]`
                     Meta(NameValue(ref m)) if m.ident == "borrow" => {
                         if let Ok(lifetimes) = parse_lit_into_lifetimes(cx, &m.ident, &m.lit) {
-                            if let Ok(borrowable) = borrowable_lifetimes(cx, &ident, field) {
+                            if let Ok(borrowable) = borrowable_lifetimes(cx, &ident, &field.ty) {
                                 for lifetime in &lifetimes {
                                     if !borrowable.contains(lifetime) {
-                                        cx.error_spanned_by(
-                                            field,
-                                            format!(
-                                                "field `{}` does not have lifetime {}",
-                                                ident, lifetime
-                                            ),
-                                        );
+                                        cx.error(format!(
+                                            "field `{}` does not have lifetime {}",
+                                            ident, lifetime
+                                        ));
                                     }
                                 }
-                                borrowed_lifetimes.set(&m.ident, lifetimes);
+                                borrowed_lifetimes.set(lifetimes);
                             }
                         }
                     }
 
                     // Parse `#[serde(getter = "...")]`
                     Meta(NameValue(ref m)) if m.ident == "getter" => {
                         if let Ok(path) = parse_lit_into_expr_path(cx, &m.ident, &m.lit) {
-                            getter.set(&m.ident, path);
+                            getter.set(path);
                         }
                     }
 
                     // Parse `#[serde(flatten)]`
                     Meta(Word(ref word)) if word == "flatten" => {
-                        flatten.set_true(word);
+                        flatten.set_true();
                     }
 
                     Meta(ref meta_item) => {
-                        cx.error_spanned_by(
-                            meta_item.name(),
-                            format!("unknown serde field attribute `{}`", meta_item.name()),
-                        );
+                        cx.error(format!(
+                            "unknown serde field attribute `{}`",
+                            meta_item.name()
+                        ));
                     }
 
-                    Literal(ref lit) => {
-                        cx.error_spanned_by(lit, "unexpected literal in serde field attribute");
+                    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).
@@ -1422,18 +1053,27 @@ impl Field {
                 deserialize_with.set_if_none(expr);
             }
         } else if is_implicitly_borrowed(&field.ty) {
             // Types &str and &[u8] are always implicitly borrowed. No need for
             // a #[serde(borrow)].
             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::from_attrs(ident, ser_name, de_name, Some(de_aliases)),
+            name: Name {
+                serialize: ser_name.unwrap_or_else(|| ident.clone()),
+                deserialize: de_name.unwrap_or(ident),
+            },
+            ser_renamed: ser_renamed,
+            de_renamed: de_renamed,
             skip_serializing: skip_serializing.get(),
             skip_deserializing: skip_deserializing.get(),
             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(),
@@ -1443,26 +1083,22 @@ impl Field {
             transparent: false,
         }
     }
 
     pub fn name(&self) -> &Name {
         &self.name
     }
 
-    pub fn aliases(&self) -> Vec<String> {
-        self.name.deserialize_aliases()
-    }
-
-    pub fn rename_by_rules(&mut self, rules: &RenameAllRules) {
-        if !self.name.serialize_renamed {
-            self.name.serialize = rules.serialize.apply_to_field(&self.name.serialize);
+    pub fn rename_by_rule(&mut self, rule: &RenameRule) {
+        if !self.ser_renamed {
+            self.name.serialize = rule.apply_to_field(&self.name.serialize);
         }
-        if !self.name.deserialize_renamed {
-            self.name.deserialize = rules.deserialize.apply_to_field(&self.name.deserialize);
+        if !self.de_renamed {
+            self.name.deserialize = rule.apply_to_field(&self.name.deserialize);
         }
     }
 
     pub fn skip_serializing(&self) -> bool {
         self.skip_serializing
     }
 
     pub fn skip_deserializing(&self) -> bool {
@@ -1511,83 +1147,70 @@ impl Field {
 
     pub fn mark_transparent(&mut self) {
         self.transparent = true;
     }
 }
 
 type SerAndDe<T> = (Option<T>, Option<T>);
 
-fn get_ser_and_de<'a, 'b, T, F>(
-    cx: &'b Ctxt,
+fn get_ser_and_de<'a, T, F>(
+    cx: &Ctxt,
     attr_name: &'static str,
     metas: &'a Punctuated<syn::NestedMeta, Token![,]>,
     f: F,
-) -> Result<(VecAttr<'b, T>, VecAttr<'b, T>), ()>
+) -> Result<SerAndDe<T>, ()>
 where
     T: 'a,
     F: Fn(&Ctxt, &Ident, &Ident, &'a syn::Lit) -> Result<T, ()>,
 {
-    let mut ser_meta = VecAttr::none(cx, attr_name);
-    let mut de_meta = VecAttr::none(cx, attr_name);
+    let mut ser_meta = Attr::none(cx, attr_name);
+    let mut de_meta = Attr::none(cx, attr_name);
     let attr_name = Ident::new(attr_name, Span::call_site());
 
     for meta in metas {
         match *meta {
             Meta(NameValue(ref meta)) if meta.ident == "serialize" => {
                 if let Ok(v) = f(cx, &attr_name, &meta.ident, &meta.lit) {
-                    ser_meta.insert(&meta.ident, v);
+                    ser_meta.set(v);
                 }
             }
 
             Meta(NameValue(ref meta)) if meta.ident == "deserialize" => {
                 if let Ok(v) = f(cx, &attr_name, &meta.ident, &meta.lit) {
-                    de_meta.insert(&meta.ident, v);
+                    de_meta.set(v);
                 }
             }
 
             _ => {
-                cx.error_spanned_by(
-                    meta,
-                    format!(
-                        "malformed {0} attribute, expected `{0}(serialize = ..., \
-                         deserialize = ...)`",
-                        attr_name
-                    ),
-                );
+                cx.error(format!(
+                    "malformed {0} attribute, expected `{0}(serialize = ..., \
+                     deserialize = ...)`",
+                    attr_name
+                ));
                 return Err(());
             }
         }
     }
 
-    Ok((ser_meta, de_meta))
+    Ok((ser_meta.get(), de_meta.get()))
 }
 
 fn get_renames<'a>(
     cx: &Ctxt,
     items: &'a Punctuated<syn::NestedMeta, Token![,]>,
 ) -> Result<SerAndDe<&'a syn::LitStr>, ()> {
-    let (ser, de) = try!(get_ser_and_de(cx, "rename", items, get_lit_str));
-    Ok((try!(ser.at_most_one()), try!(de.at_most_one())))
-}
-
-fn get_multiple_renames<'a>(
-    cx: &Ctxt,
-    items: &'a Punctuated<syn::NestedMeta, Token![,]>,
-) -> Result<(Option<&'a syn::LitStr>, Vec<&'a syn::LitStr>), ()> {
-    let (ser, de) = try!(get_ser_and_de(cx, "rename", items, get_lit_str));
-    Ok((try!(ser.at_most_one()), de.get()))
+    get_ser_and_de(cx, "rename", items, get_lit_str)
 }
 
 fn get_where_predicates(
     cx: &Ctxt,
     items: &Punctuated<syn::NestedMeta, Token![,]>,
 ) -> Result<SerAndDe<Vec<syn::WherePredicate>>, ()> {
-    let (ser, de) = try!(get_ser_and_de(cx, "bound", items, parse_lit_into_where));
-    Ok((try!(ser.at_most_one()), try!(de.at_most_one())))
+    get_ser_and_de(cx, "bound", items, parse_lit_into_where)
 }
 
 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
@@ -1603,43 +1226,38 @@ fn get_lit_str<'a>(
     cx: &Ctxt,
     attr_name: &Ident,
     meta_item_name: &Ident,
     lit: &'a syn::Lit,
 ) -> Result<&'a syn::LitStr, ()> {
     if let syn::Lit::Str(ref lit) = *lit {
         Ok(lit)
     } else {
-        cx.error_spanned_by(
-            lit,
-            format!(
-                "expected serde {} attribute to be a string: `{} = \"...\"`",
-                attr_name, meta_item_name
-            ),
-        );
+        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: &Ident, lit: &syn::Lit) -> Result<syn::Path, ()> {
     let string = try!(get_lit_str(cx, attr_name, attr_name, lit));
-    parse_lit_str(string).map_err(|_| {
-        cx.error_spanned_by(lit, format!("failed to parse path: {:?}", string.value()))
-    })
+    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: &Ident,
     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_spanned_by(lit, format!("failed to parse path: {:?}", string.value()))
-    })
+    parse_lit_str(string)
+        .map_err(|_| cx.error(format!("failed to parse path: {:?}", string.value())))
 }
 
 fn parse_lit_into_where(
     cx: &Ctxt,
     attr_name: &Ident,
     meta_item_name: &Ident,
     lit: &syn::Lit,
 ) -> Result<Vec<syn::WherePredicate>, ()> {
@@ -1647,65 +1265,66 @@ fn parse_lit_into_where(
     if string.value().is_empty() {
         return Ok(Vec::new());
     }
 
     let where_string = syn::LitStr::new(&format!("where {}", string.value()), string.span());
 
     parse_lit_str::<syn::WhereClause>(&where_string)
         .map(|wh| wh.predicates.into_iter().collect())
-        .map_err(|err| cx.error_spanned_by(lit, err))
+        .map_err(|err| cx.error(err))
 }
 
 fn parse_lit_into_ty(cx: &Ctxt, attr_name: &Ident, lit: &syn::Lit) -> Result<syn::Type, ()> {
     let string = try!(get_lit_str(cx, attr_name, attr_name, lit));
 
     parse_lit_str(string).map_err(|_| {
-        cx.error_spanned_by(
-            lit,
-            format!("failed to parse type: {} = {:?}", attr_name, string.value()),
-        )
+        cx.error(format!(
+            "failed to parse type: {} = {:?}",
+            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: &Ident,
     lit: &syn::Lit,
 ) -> Result<BTreeSet<syn::Lifetime>, ()> {
     let string = try!(get_lit_str(cx, attr_name, attr_name, lit));
     if string.value().is_empty() {
-        cx.error_spanned_by(lit, "at least one lifetime must be borrowed");
+        cx.error("at least one lifetime must be borrowed");
         return Err(());
     }
 
     struct BorrowedLifetimes(Punctuated<syn::Lifetime, Token![+]>);
 
     impl Parse for BorrowedLifetimes {
         fn parse(input: ParseStream) -> parse::Result<Self> {
             Punctuated::parse_separated_nonempty(input).map(BorrowedLifetimes)
         }
     }
 
     if let Ok(BorrowedLifetimes(lifetimes)) = parse_lit_str(string) {
         let mut set = BTreeSet::new();
         for lifetime in lifetimes {
             if !set.insert(lifetime.clone()) {
-                cx.error_spanned_by(lit, format!("duplicate borrowed lifetime `{}`", lifetime));
+                cx.error(format!("duplicate borrowed lifetime `{}`", lifetime));
             }
         }
         return Ok(set);
     }
 
-    cx.error_spanned_by(
-        lit,
-        format!("failed to parse borrowed lifetimes: {:?}", string.value()),
-    );
+    cx.error(format!(
+        "failed to parse borrowed lifetimes: {:?}",
+        string.value()
+    ));
     Err(())
 }
 
 fn is_implicitly_borrowed(ty: &syn::Type) -> bool {
     is_implicitly_borrowed_reference(ty) || is_option(ty, is_implicitly_borrowed_reference)
 }
 
 fn is_implicitly_borrowed_reference(ty: &syn::Type) -> bool {
@@ -1748,22 +1367,20 @@ fn is_cow(ty: &syn::Type, elem: fn(&syn:
         }
     };
     let args = match seg.arguments {
         syn::PathArguments::AngleBracketed(ref bracketed) => &bracketed.args,
         _ => {
             return false;
         }
     };
-    seg.ident == "Cow"
-        && args.len() == 2
-        && match (&args[0], &args[1]) {
-            (&syn::GenericArgument::Lifetime(_), &syn::GenericArgument::Type(ref arg)) => elem(arg),
-            _ => false,
-        }
+    seg.ident == "Cow" && args.len() == 2 && match (&args[0], &args[1]) {
+        (&syn::GenericArgument::Lifetime(_), &syn::GenericArgument::Type(ref arg)) => elem(arg),
+        _ => false,
+    }
 }
 
 fn is_option(ty: &syn::Type, elem: fn(&syn::Type) -> bool) -> bool {
     let path = match *ty {
         syn::Type::Path(ref ty) => &ty.path,
         _ => {
             return false;
         }
@@ -1775,22 +1392,20 @@ fn is_option(ty: &syn::Type, elem: fn(&s
         }
     };
     let args = match seg.arguments {
         syn::PathArguments::AngleBracketed(ref bracketed) => &bracketed.args,
         _ => {
             return false;
         }
     };
-    seg.ident == "Option"
-        && args.len() == 1
-        && match args[0] {
-            syn::GenericArgument::Type(ref arg) => elem(arg),
-            _ => false,
-        }
+    seg.ident == "Option" && args.len() == 1 && match args[0] {
+        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;
@@ -1845,25 +1460,22 @@ fn is_primitive_path(path: &syn::Path, p
 // 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,
-    field: &syn::Field,
+    ty: &syn::Type,
 ) -> Result<BTreeSet<syn::Lifetime>, ()> {
     let mut lifetimes = BTreeSet::new();
-    collect_lifetimes(&field.ty, &mut lifetimes);
+    collect_lifetimes(ty, &mut lifetimes);
     if lifetimes.is_empty() {
-        cx.error_spanned_by(
-            field,
-            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::Type, out: &mut BTreeSet<syn::Lifetime>) {
     match *ty {
@@ -1875,21 +1487,19 @@ fn collect_lifetimes(ty: &syn::Type, out
         }
         syn::Type::Ptr(ref ty) => {
             collect_lifetimes(&ty.elem, out);
         }
         syn::Type::Reference(ref ty) => {
             out.extend(ty.lifetime.iter().cloned());
             collect_lifetimes(&ty.elem, out);
         }
-        syn::Type::Tuple(ref ty) => {
-            for elem in &ty.elems {
-                collect_lifetimes(elem, out);
-            }
-        }
+        syn::Type::Tuple(ref ty) => for elem in &ty.elems {
+            collect_lifetimes(elem, out);
+        },
         syn::Type::Path(ref ty) => {
             if let Some(ref qself) = ty.qself {
                 collect_lifetimes(&qself.ty, out);
             }
             for seg in &ty.path.segments {
                 if let syn::PathArguments::AngleBracketed(ref bracketed) = seg.arguments {
                     for arg in &bracketed.args {
                         match *arg {
--- a/third_party/rust/serde_derive/src/internals/case.rs
+++ b/third_party/rust/serde_derive/src/internals/case.rs
@@ -1,21 +1,29 @@
+// 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.
+
 //! Code to convert the Rust-styled field/variant (e.g. `my_field`, `MyType`) to the
 //! case of the source (e.g. `my-field`, `MY_FIELD`).
 
 // See https://users.rust-lang.org/t/psa-dealing-with-warning-unused-import-std-ascii-asciiext-in-today-s-nightly/13726
 #[allow(deprecated, unused_imports)]
 use std::ascii::AsciiExt;
 
 use std::str::FromStr;
 
 use self::RenameRule::*;
 
 /// The different possible ways to change case of fields in a struct, or variants in an enum.
-#[derive(Copy, Clone, 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
--- a/third_party/rust/serde_derive/src/internals/check.rs
+++ b/third_party/rust/serde_derive/src/internals/check.rs
@@ -1,10 +1,18 @@
+// 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 internals::ast::{Container, Data, Field, Style};
-use internals::attr::{Identifier, TagType};
+use internals::attr::{EnumTag, Identifier};
 use internals::{Ctxt, Derive};
 use syn::{Member, Type};
 
 /// Cross-cutting checks that require looking at more than a single attrs
 /// object. Simpler checks should happen when parsing and building the attrs.
 pub fn check(cx: &Ctxt, cont: &mut Container, derive: Derive) {
     check_getter(cx, cont);
     check_flatten(cx, cont);
@@ -16,26 +24,22 @@ pub fn check(cx: &Ctxt, cont: &mut Conta
 }
 
 /// Getters are only allowed inside structs (not enums) with the `remote`
 /// attribute.
 fn check_getter(cx: &Ctxt, cont: &Container) {
     match cont.data {
         Data::Enum(_, _) => {
             if cont.data.has_getter() {
-                cx.error_spanned_by(
-                    cont.original,
-                    "#[serde(getter = \"...\")] is not allowed in an enum",
-                );
+                cx.error("#[serde(getter = \"...\")] is not allowed in an enum");
             }
         }
         Data::Struct(_, _) => {
             if cont.data.has_getter() && cont.attrs.remote().is_none() {
-                cx.error_spanned_by(
-                    cont.original,
+                cx.error(
                     "#[serde(getter = \"...\")] can only be used in structs \
                      that have #[serde(remote = \"...\")]",
                 );
             }
         }
     }
 }
 
@@ -58,29 +62,39 @@ fn check_flatten(cx: &Ctxt, cont: &Conta
 }
 
 fn check_flatten_field(cx: &Ctxt, style: Style, field: &Field) {
     if !field.attrs.flatten() {
         return;
     }
     match style {
         Style::Tuple => {
-            cx.error_spanned_by(
-                field.original,
-                "#[serde(flatten)] cannot be used on tuple structs",
-            );
+            cx.error("#[serde(flatten)] cannot be used on tuple structs");
         }
         Style::Newtype => {
-            cx.error_spanned_by(
-                field.original,
-                "#[serde(flatten)] cannot be used on newtype structs",
-            );
+            cx.error("#[serde(flatten)] cannot be used on newtype structs");
         }
         _ => {}
     }
+    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.
 ///
 /// 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.
@@ -96,76 +110,55 @@ fn check_identifier(cx: &Ctxt, cont: &Co
         match (
             variant.style,
             cont.attrs.identifier(),
             variant.attrs.other(),
             cont.attrs.tag(),
         ) {
             // The `other` attribute may not be used in a variant_identifier.
             (_, Identifier::Variant, true, _) => {
-                cx.error_spanned_by(
-                    variant.original,
-                    "#[serde(other)] may not be used on a variant identifier",
-                );
+                cx.error("#[serde(other)] may not be used on a variant_identifier");
             }
 
             // Variant with `other` attribute cannot appear in untagged enum
-            (_, Identifier::No, true, &TagType::None) => {
-                cx.error_spanned_by(
-                    variant.original,
-                    "#[serde(other)] cannot appear on untagged enum",
-                );
+            (_, Identifier::No, true, &EnumTag::None) => {
+                cx.error("#[serde(other)] cannot appear on untagged enum");
             }
 
             // Variant with `other` attribute must be the last one.
             (Style::Unit, Identifier::Field, true, _) | (Style::Unit, Identifier::No, true, _) => {
                 if i < variants.len() - 1 {
-                    cx.error_spanned_by(
-                        variant.original,
-                        "#[serde(other)] must be on the last variant",
-                    );
+                    cx.error("#[serde(other)] must be the last variant");
                 }
             }
 
             // Variant with `other` attribute must be a unit variant.
             (_, Identifier::Field, true, _) | (_, Identifier::No, true, _) => {
-                cx.error_spanned_by(
-                    variant.original,
-                    "#[serde(other)] must be on a unit variant",
-                );
+                cx.error("#[serde(other)] must be on a unit variant");
             }
 
             // Any sort of variant is allowed if this is not an identifier.
             (_, Identifier::No, false, _) => {}
 
             // Unit variant without `other` attribute is always fine.
             (Style::Unit, _, false, _) => {}
 
             // The last field is allowed to be a newtype catch-all.
             (Style::Newtype, Identifier::Field, false, _) => {
                 if i < variants.len() - 1 {
-                    cx.error_spanned_by(
-                        variant.original,
-                        format!("`{}` must be the last variant", variant.ident),
-                    );
+                    cx.error(format!("`{}` must be the last variant", variant.ident));
                 }
             }
 
             (_, Identifier::Field, false, _) => {
-                cx.error_spanned_by(
-                    variant.original,
-                    "#[serde(field_identifier)] may only contain unit variants",
-                );
+                cx.error("field_identifier may only contain unit variants");
             }
 
             (_, Identifier::Variant, false, _) => {
-                cx.error_spanned_by(
-                    variant.original,
-                    "#[serde(variant_identifier)] may only contain unit variants",
-                );
+                cx.error("variant_identifier may only contain unit variants");
             }
         }
     }
 }
 
 /// Skip-(de)serializing attributes are not allowed on variants marked
 /// (de)serialize_with.
 fn check_variant_skip_attrs(cx: &Ctxt, cont: &Container) {
@@ -174,77 +167,62 @@ fn check_variant_skip_attrs(cx: &Ctxt, c
         Data::Struct(_, _) => {
             return;
         }
     };
 
     for variant in variants.iter() {
         if variant.attrs.serialize_with().is_some() {
             if variant.attrs.skip_serializing() {
-                cx.error_spanned_by(
-                    variant.original,
-                    format!(
-                        "variant `{}` cannot have both #[serde(serialize_with)] and \
-                         #[serde(skip_serializing)]",
-                        variant.ident
-                    ),
-                );
+                cx.error(format!(
+                    "variant `{}` cannot have both #[serde(serialize_with)] and \
+                     #[serde(skip_serializing)]",
+                    variant.ident
+                ));
             }
 
             for field in &variant.fields {
                 let member = member_message(&field.member);
 
                 if field.attrs.skip_serializing() {
-                    cx.error_spanned_by(
-                        variant.original,
-                        format!(
-                            "variant `{}` cannot have both #[serde(serialize_with)] and \
-                             a field {} marked with #[serde(skip_serializing)]",
-                            variant.ident, member
-                        ),
-                    );
+                    cx.error(format!(
+                        "variant `{}` cannot have both #[serde(serialize_with)] and \
+                         a field {} marked with #[serde(skip_serializing)]",
+                        variant.ident, member
+                    ));
                 }
 
                 if field.attrs.skip_serializing_if().is_some() {
-                    cx.error_spanned_by(
-                        variant.original,
-                        format!(
-                            "variant `{}` cannot have both #[serde(serialize_with)] and \
-                             a field {} marked with #[serde(skip_serializing_if)]",
-                            variant.ident, member
-                        ),
-                    );
+                    cx.error(format!(
+                        "variant `{}` cannot have both #[serde(serialize_with)] and \
+                         a field {} marked with #[serde(skip_serializing_if)]",
+                        variant.ident, member
+                    ));
                 }
             }
         }
 
         if variant.attrs.deserialize_with().is_some() {
             if variant.attrs.skip_deserializing() {
-                cx.error_spanned_by(
-                    variant.original,
-                    format!(
-                        "variant `{}` cannot have both #[serde(deserialize_with)] and \
-                         #[serde(skip_deserializing)]",
-                        variant.ident
-                    ),
-                );
+                cx.error(format!(
+                    "variant `{}` cannot have both #[serde(deserialize_with)] and \
+                     #[serde(skip_deserializing)]",
+                    variant.ident
+                ));
             }
 
             for field in &variant.fields {
                 if field.attrs.skip_deserializing() {
                     let member = member_message(&field.member);
 
-                    cx.error_spanned_by(
-                        variant.original,
-                        format!(
-                            "variant `{}` cannot have both #[serde(deserialize_with)] \
-                             and a field {} marked with #[serde(skip_deserializing)]",
-                            variant.ident, member
-                        ),
-                    );
+                    cx.error(format!(
+                        "variant `{}` cannot have both #[serde(deserialize_with)] \
+                         and a field {} marked with #[serde(skip_deserializing)]",
+                        variant.ident, member
+                    ));
                 }
             }
         }
     }
 }
 
 /// The tag of an internally-tagged struct variant must not be
 /// the same as either one of its fields, as this would result in
@@ -252,152 +230,123 @@ fn check_variant_skip_attrs(cx: &Ctxt, c
 /// 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() {
-        TagType::Internal { ref tag } => tag.as_str(),
-        TagType::External | TagType::Adjacent { .. } | TagType::None => return,
+        EnumTag::Internal { ref tag } => tag.as_str(),
+        EnumTag::External | EnumTag::Adjacent { .. } | EnumTag::None => return,
     };
 
     let diagnose_conflict = || {
-        cx.error_spanned_by(
-            cont.original,
-            format!("variant field name `{}` conflicts with internal tag", tag),
-        )
+        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 {
+                    if check_ser && ser_name == tag || check_de && de_name == tag {
                         diagnose_conflict();
                         return;
                     }
-
-                    for de_name in field.attrs.aliases() {
-                        if 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() {
-        TagType::Adjacent {
+        EnumTag::Adjacent {
             ref tag,
             ref content,
         } => (tag, content),
-        TagType::Internal { .. } | TagType::External | TagType::None => return,
+        EnumTag::Internal { .. } | EnumTag::External | EnumTag::None => return,
     };
 
     if type_tag == content_tag {
-        cx.error_spanned_by(
-            cont.original,
-            format!(
-                "enum tags `{}` for type and content conflict with each other",
-                type_tag
-            ),
+        let message = format!(
+            "enum tags `{}` for type and content conflict with each other",
+            type_tag
         );
+        cx.error(message);
     }
 }
 
 /// Enums and unit structs cannot be transparent.
 fn check_transparent(cx: &Ctxt, cont: &mut Container, derive: Derive) {
     if !cont.attrs.transparent() {
         return;
     }
 
     if cont.attrs.type_from().is_some() {
-        cx.error_spanned_by(
-            cont.original,
-            "#[serde(transparent)] is not allowed with #[serde(from = \"...\")]",
-        );
+        cx.error("#[serde(transparent)] is not allowed with #[serde(from = \"...\")]");
     }
 
     if cont.attrs.type_into().is_some() {
-        cx.error_spanned_by(
-            cont.original,
-            "#[serde(transparent)] is not allowed with #[serde(into = \"...\")]",
-        );
+        cx.error("#[serde(transparent)] is not allowed with #[serde(into = \"...\")]");
     }
 
     let fields = match cont.data {
         Data::Enum(_, _) => {
-            cx.error_spanned_by(
-                cont.original,
-                "#[serde(transparent)] is not allowed on an enum",
-            );
+            cx.error("#[serde(transparent)] is not allowed on an enum");
             return;
         }
         Data::Struct(Style::Unit, _) => {
-            cx.error_spanned_by(
-                cont.original,
-                "#[serde(transparent)] is not allowed on a unit struct",
-            );
+            cx.error("#[serde(transparent)] is not allowed on a unit struct");
             return;
         }
         Data::Struct(_, ref mut fields) => fields,
     };
 
     let mut transparent_field = None;
 
     for field in fields {
         if allow_transparent(field, derive) {
             if transparent_field.is_some() {
-                cx.error_spanned_by(
-                    cont.original,
+                cx.error(
                     "#[serde(transparent)] requires struct to have at most one transparent field",
                 );
                 return;
             }
             transparent_field = Some(field);
         }
     }
 
     match transparent_field {
         Some(transparent_field) => transparent_field.attrs.mark_transparent(),
         None => match derive {
             Derive::Serialize => {
-                cx.error_spanned_by(
-                    cont.original,
-                    "#[serde(transparent)] requires at least one field that is not skipped",
-                );
+                cx.error("#[serde(transparent)] requires at least one field that is not skipped");
             }
             Derive::Deserialize => {
-                cx.error_spanned_by(
-                    cont.original,
-                    "#[serde(transparent)] requires at least one field that is neither skipped nor has a default",
-                );
+                cx.error("#[serde(transparent)] requires at least one field that is neither skipped nor has a default");
             }
         },
     }
 }
 
 fn member_message(member: &Member) -> String {
     match *member {
         Member::Named(ref ident) => format!("`{}`", ident),
-        Member::Unnamed(ref i) => format!("#{}", i.index),
+        Member::Unnamed(ref i) => i.index.to_string(),
     }
 }
 
 fn allow_transparent(field: &Field, derive: Derive) -> bool {
     if let Type::Path(ref ty) = *field.ty {
         if let Some(seg) = ty.path.segments.last() {
             if seg.into_value().ident == "PhantomData" {
                 return false;
--- a/third_party/rust/serde_derive/src/internals/ctxt.rs
+++ b/third_party/rust/serde_derive/src/internals/ctxt.rs
@@ -1,54 +1,65 @@
-use quote::ToTokens;
+// 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 std::cell::RefCell;
 use std::fmt::Display;
 use std::thread;
-use syn;
 
 /// A type to collect errors together and format them.
 ///
 /// Dropping this object will cause a panic. It must be consumed using `check`.
 ///
 /// References can be shared since this type uses run-time exclusive mut checking.
 #[derive(Default)]
 pub struct Ctxt {
     // The contents will be set to `None` during checking. This is so that checking can be
     // enforced.
-    errors: RefCell<Option<Vec<syn::Error>>>,
+    errors: RefCell<Option<Vec<String>>>,
 }
 
 impl Ctxt {
     /// Create a new context object.
     ///
     /// This object contains no errors, but will still trigger a panic if it is not `check`ed.
     pub fn new() -> Self {
         Ctxt {
             errors: RefCell::new(Some(Vec::new())),
         }
     }
 
-    /// Add an error to the context object with a tokenenizable object.
-    ///
-    /// The object is used for spanning in error messages.
-    pub fn error_spanned_by<A: ToTokens, T: Display>(&self, obj: A, msg: T) {
+    /// Add an error to the context object.
+    pub fn error<T: Display>(&self, msg: T) {
         self.errors
             .borrow_mut()
             .as_mut()
             .unwrap()
-            // Curb monomorphization from generating too many identical methods.
-            .push(syn::Error::new_spanned(obj.into_token_stream(), msg));
+            .push(msg.to_string());
     }
 
     /// Consume this object, producing a formatted error string if there are errors.
-    pub fn check(self) -> Result<(), Vec<syn::Error>> {
-        let errors = self.errors.borrow_mut().take().unwrap();
+    pub fn check(self) -> Result<(), String> {
+        let mut errors = self.errors.borrow_mut().take().unwrap();
         match errors.len() {
             0 => Ok(()),
-            _ => Err(errors),
+            1 => Err(errors.pop().unwrap()),
+            n => {
+                let mut msg = format!("{} errors:", n);
+                for err in errors {
+                    msg.push_str("\n\t# ");
+                    msg.push_str(&err);
+                }
+                Err(msg)
+            }
         }
     }
 }
 
 impl Drop for Ctxt {
     fn drop(&mut self) {
         if !thread::panicking() && self.errors.borrow().is_some() {
             panic!("forgot to check for errors");
--- a/third_party/rust/serde_derive/src/internals/mod.rs
+++ b/third_party/rust/serde_derive/src/internals/mod.rs
@@ -1,8 +1,16 @@
+// 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.
+
 pub mod ast;
 pub mod attr;
 
 mod ctxt;
 pub use self::ctxt::Ctxt;
 
 mod case;
 mod check;
--- a/third_party/rust/serde_derive/src/lib.rs
+++ b/third_party/rust/serde_derive/src/lib.rs
@@ -1,53 +1,61 @@
+// 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.
+
 //! This crate provides Serde's two derive macros.
 //!
-//! ```edition2018
-//! # use serde_derive::{Serialize, Deserialize};
+//! ```rust
+//! # #[macro_use]
+//! # extern crate serde_derive;
 //! #
 //! #[derive(Serialize, Deserialize)]
 //! # struct S;
 //! #
 //! # 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.88")]
+#![doc(html_root_url = "https://docs.rs/serde_derive/1.0.80")]
 #![cfg_attr(feature = "cargo-clippy", allow(renamed_and_removed_lints))]
 #![cfg_attr(feature = "cargo-clippy", deny(clippy, clippy_pedantic))]
-// Ignored clippy lints
+// Whitelisted clippy lints
 #![cfg_attr(
     feature = "cargo-clippy",
     allow(
         cyclomatic_complexity,
         enum_variant_names,
         needless_pass_by_value,
         redundant_field_names,
         too_many_arguments,
-        trivially_copy_pass_by_ref,
         used_underscore_binding,
     )
 )]
-// Ignored clippy_pedantic lints
+// Whitelisted clippy_pedantic lints
 #![cfg_attr(
     feature = "cargo-clippy",
     allow(
         cast_possible_truncation,
         doc_markdown,
         enum_glob_use,
         filter_map,
         indexing_slicing,
         items_after_statements,
         match_same_arms,
-        module_name_repetitions,
         similar_names,
         single_match_else,
+        stutter,
         unseparated_literal_suffix,
         use_self,
     )
 )]
 // The `quote!` macro requires deep recursion.
 #![recursion_limit = "512"]
 
 #[macro_use]
@@ -64,33 +72,33 @@ use proc_macro::TokenStream;
 use syn::DeriveInput;
 
 #[macro_use]
 mod bound;
 #[macro_use]
 mod fragment;
 
 mod de;
-mod dummy;
 mod pretend;
 mod ser;
 mod try;
 
 #[proc_macro_derive(Serialize, attributes(serde))]
 pub fn derive_serialize(input: TokenStream) -> TokenStream {
     let input = parse_macro_input!(input as DeriveInput);
     ser::expand_derive_serialize(&input)
-        .unwrap_or_else(to_compile_errors)
+        .unwrap_or_else(compile_error)
         .into()
 }
 
 #[proc_macro_derive(Deserialize, attributes(serde))]
 pub fn derive_deserialize(input: TokenStream) -> TokenStream {
     let input = parse_macro_input!(input as DeriveInput);
     de::expand_derive_deserialize(&input)
-        .unwrap_or_else(to_compile_errors)
+        .unwrap_or_else(compile_error)
         .into()
 }
 
-fn to_compile_errors(errors: Vec<syn::Error>) -> proc_macro2::TokenStream {
-    let compile_errors = errors.iter().map(syn::Error::to_compile_error);
-    quote!(#(#compile_errors)*)
+fn compile_error(message: String) -> proc_macro2::TokenStream {
+    quote! {
+        compile_error!(#message);
+    }
 }
--- a/third_party/rust/serde_derive/src/pretend.rs
+++ b/third_party/rust/serde_derive/src/pretend.rs
@@ -57,18 +57,17 @@ fn pretend_fields_used(cont: &Container)
             .iter()
             .filter_map(|variant| match variant.style {
                 Style::Struct => {
                     let variant_ident = &variant.ident;
                     let pat = struct_pattern(&variant.fields);
                     Some(quote!(#type_ident::#variant_ident #pat))
                 }
                 _ => None,
-            })
-            .collect::<Vec<_>>(),
+            }).collect::<Vec<_>>(),
         Data::Struct(Style::Struct, ref fields) => {
             let pat = struct_pattern(fields);
             vec![quote!(#type_ident #pat)]
         }
         Data::Struct(_, _) => {
             return quote!();
         }
     };
--- a/third_party/rust/serde_derive/src/ser.rs
+++ b/third_party/rust/serde_derive/src/ser.rs
@@ -1,31 +1,41 @@
+// 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 proc_macro2::{Span, TokenStream};
 use syn::spanned::Spanned;
 use syn::{self, Ident, Index, Member};
 
 use bound;
-use dummy;
 use fragment::{Fragment, Match, Stmts};
 use internals::ast::{Container, Data, Field, Style, Variant};
 use internals::{attr, Ctxt, Derive};
 use pretend;
+use try;
 
-pub fn expand_derive_serialize(input: &syn::DeriveInput) -> Result<TokenStream, Vec<syn::Error>> {
+pub fn expand_derive_serialize(input: &syn::DeriveInput) -> Result<TokenStream, String> {
     let ctxt = Ctxt::new();
-    let cont = match Container::from_ast(&ctxt, input, Derive::Serialize) {
-        Some(cont) => cont,
-        None => return Err(ctxt.check().unwrap_err()),
-    };
+    let cont = Container::from_ast(&ctxt, input, Derive::Serialize);
     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 suffix = ident.to_string().trim_left_matches("r#").to_owned();
+    let dummy_const = Ident::new(
+        &format!("_IMPL_SERIALIZE_FOR_{}", suffix),
+        Span::call_site(),
+    );
     let body = Stmts(serialize_body(&cont, &params));
 
     let impl_block = if let Some(remote) = cont.attrs.remote() {
         let vis = &input.vis;
         let used = pretend::pretend_used(&cont);
         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>
@@ -46,27 +56,39 @@ pub fn expand_derive_serialize(input: &s
                     __S: _serde::Serializer,
                 {
                     #body
                 }
             }
         }
     };
 
-    Ok(dummy::wrap_in_const("SERIALIZE", ident, impl_block))
+    let try_replacement = try::replacement();
+    let generated = quote! {
+        #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)]
+        const #dummy_const: () = {
+            #[allow(unknown_lints)]
+            #[cfg_attr(feature = "cargo-clippy", allow(useless_attribute))]
+            #[allow(rust_2018_idioms)]
+            extern crate serde as _serde;
+            #try_replacement
+            #impl_block
+        };
+    };
+    Ok(generated)
 }
 
 fn precondition(cx: &Ctxt, cont: &Container) {
     match cont.attrs.identifier() {
         attr::Identifier::No => {}
         attr::Identifier::Field => {
-            cx.error_spanned_by(cont.original, "field identifiers cannot be serialized");
+            cx.error("field identifiers cannot be serialized");
         }
         attr::Identifier::Variant => {
-            cx.error_spanned_by(cont.original, "variant identifiers cannot be serialized");
+            cx.error("variant identifiers cannot be serialized");
         }
     }
 }
 
 struct Parameters {
     /// Variable holding the value being serialized. Either `self` for local
     /// types or `__self` for remote types.
     self_var: Ident,
@@ -181,20 +203,17 @@ fn serialize_transparent(cont: &Containe
     };
 
     let self_var = &params.self_var;
     let transparent_field = fields.iter().find(|f| f.attrs.transparent()).unwrap();
     let member = &transparent_field.member;
 
     let path = match transparent_field.attrs.serialize_with() {
         Some(path) => quote!(#path),
-        None => {
-            let span = transparent_field.original.span();
-            quote_spanned!(span=> _serde::Serialize::serialize)
-        }
+        None => quote!(_serde::Serialize::serialize),
     };
 
     quote_block! {
         #path(&#self_var.#member, __serializer)
     }
 }
 
 fn serialize_into(params: &Parameters, type_into: &syn::Type) -> Fragment {
@@ -264,18 +283,17 @@ fn serialize_tuple_struct(
             Some(path) => {
                 let index = syn::Index {
                     index: i as u32,
                     span: Span::call_site(),
                 };
                 let field_expr = get_member(params, field, &Member::Unnamed(index));
                 quote!(if #path(#field_expr) { 0 } else { 1 })
             }
-        })
-        .fold(quote!(0), |sum, expr| quote!(#sum + #expr));
+        }).fold(quote!(0), |sum, expr| quote!(#sum + #expr));
 
     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)
     }
 }
 
@@ -284,126 +302,96 @@ fn serialize_struct(params: &Parameters,
 
     if cattrs.has_flatten() {
         serialize_struct_as_map(params, fields, cattrs)
     } else {
         serialize_struct_as_struct(params, fields, cattrs)
     }
 }
 
-fn serialize_struct_tag_field(cattrs: &attr::Container, struct_trait: &StructTrait) -> TokenStream {
-    match *cattrs.tag() {
-        attr::TagType::Internal { ref tag } => {
-            let type_name = cattrs.name().serialize_name();
-            let func = struct_trait.serialize_field(Span::call_site());
-            quote! {
-                try!(#func(&mut __serde_state, #tag, #type_name));
-            }
-        }
-        _ => quote! {},
-    }
-}
-
 fn serialize_struct_as_struct(
     params: &Parameters,
     fields: &[Field],
     cattrs: &attr::Container,
 ) -> Fragment {
     let serialize_fields =
         serialize_struct_visitor(fields, params, false, &StructTrait::SerializeStruct);
 
     let type_name = cattrs.name().serialize_name();
 
-    let tag_field = serialize_struct_tag_field(cattrs, &StructTrait::SerializeStruct);
-    let tag_field_exists = !tag_field.is_empty();
-
     let mut serialized_fields = fields
         .iter()
         .filter(|&field| !field.attrs.skip_serializing())
         .peekable();
 
-    let let_mut = mut_if(serialized_fields.peek().is_some() || tag_field_exists);
+    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 field_expr = get_member(params, field, &field.member);
                 quote!(if #path(#field_expr) { 0 } else { 1 })
             }
-        })
-        .fold(
-            quote!(#tag_field_exists as usize),
-            |sum, expr| quote!(#sum + #expr),
-        );
+        }).fold(quote!(0), |sum, expr| quote!(#sum + #expr));
 
     quote_block! {
         let #let_mut __serde_state = try!(_serde::Serializer::serialize_struct(__serializer, #type_name, #len));
-        #tag_field
         #(#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 tag_field = serialize_struct_tag_field(cattrs, &StructTrait::SerializeMap);
-    let tag_field_exists = !tag_field.is_empty();
-
     let mut serialized_fields = fields
         .iter()
         .filter(|&field| !field.attrs.skip_serializing())
         .peekable();
 
-    let let_mut = mut_if(serialized_fields.peek().is_some() || tag_field_exists);
+    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 field_expr = get_member(params, field, &field.member);
                     quote!(if #path(#field_expr) { 0 } else { 1 })
                 }
-            })
-            .fold(
-                quote!(#tag_field_exists as usize),
-                |sum, expr| quote!(#sum + #expr),
-            );
+            }).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));
-        #tag_field
         #(#serialize_fields)*
         _serde::ser::SerializeMap::end(__serde_state)
     }
 }
 
 fn serialize_enum(params: &Parameters, variants: &[Variant], cattrs: &attr::Container) -> Fragment {
     assert!(variants.len() as u64 <= u64::from(u32::max_value()));
 
     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)
-        })
-        .collect();
+        }).collect();
 
     quote_expr! {
         match *#self_var {
             #(#arms)*
         }
     }
 }
 
@@ -457,27 +445,27 @@ fn serialize_variant(
                 let members = variant.fields.iter().map(|f| &f.member);
                 quote! {
                     #this::#variant_ident { #(ref #members),* }
                 }
             }
         };
 
         let body = Match(match *cattrs.tag() {
-            attr::TagType::External => {
+            attr::EnumTag::External => {
                 serialize_externally_tagged_variant(params, variant, variant_index, cattrs)
             }
-            attr::TagType::Internal { ref tag } => {
+            attr::EnumTag::Internal { ref tag } => {
                 serialize_internally_tagged_variant(params, variant, cattrs, tag)
             }
-            attr::TagType::Adjacent {
+            attr::EnumTag::Adjacent {
                 ref tag,
                 ref content,
             } => serialize_adjacently_tagged_variant(params, variant, cattrs, tag, content),
-            attr::TagType::None => serialize_untagged_variant(params, variant, cattrs),
+            attr::EnumTag::None => serialize_untagged_variant(params, variant, cattrs),
         });
 
         quote! {
             #case => #body
         }
     }
 }
 
@@ -516,20 +504,18 @@ fn serialize_externally_tagged_variant(
         }
         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);
             }
 
-            let span = field.original.span();
-            let func = quote_spanned!(span=> _serde::Serializer::serialize_newtype_variant);
             quote_expr! {
-                #func(
+                _serde::Serializer::serialize_newtype_variant(
                     __serializer,
                     #type_name,
                     #variant_index,
                     #variant_name,
                     #field_expr,
                 )
             }
         }
@@ -592,20 +578,18 @@ fn serialize_internally_tagged_variant(
         }
         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);
             }
 
-            let span = field.original.span();
-            let func = quote_spanned!(span=> _serde::private::ser::serialize_tagged_newtype);
             quote_expr! {
-                #func(
+                _serde::private::ser::serialize_tagged_newtype(
                     __serializer,
                     #enum_ident_str,
                     #variant_ident_str,
                     #tag,
                     #variant_name,
                     #field_expr,
                 )
             }
@@ -652,24 +636,22 @@ fn serialize_adjacently_tagged_variant(
             }
             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);
                 }
 
-                let span = field.original.span();
-                let func = quote_spanned!(span=> _serde::ser::SerializeStruct::serialize_field);
                 return quote_block! {
                     let mut __struct = try!(_serde::Serializer::serialize_struct(
                         __serializer, #type_name, 2));
                     try!(_serde::ser::SerializeStruct::serialize_field(
                         &mut __struct, #tag, #variant_name));
-                    try!(#func(
+                    try!(_serde::ser::SerializeStruct::serialize_field(
                         &mut __struct, #content, #field_expr));
                     _serde::ser::SerializeStruct::end(__struct)
                 };
             }
             Style::Tuple => {
                 serialize_tuple_variant(TupleVariant::Untagged, params, &variant.fields)
             }
             Style::Struct => serialize_struct_variant(
@@ -755,20 +737,18 @@ fn serialize_untagged_variant(
         }
         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);
             }
 
-            let span = field.original.span();
-            let func = quote_spanned!(span=> _serde::Serialize::serialize);
             quote_expr! {
-                #func(#field_expr, __serializer)
+                _serde::Serialize::serialize(#field_expr, __serializer)
             }
         }
         Style::Tuple => serialize_tuple_variant(TupleVariant::Untagged, params, &variant.fields),
         Style::Struct => {
             let type_name = cattrs.name().serialize_name();
             serialize_struct_variant(StructVariant::Untagged, params, &variant.fields, &type_name)
         }
     }
@@ -805,18 +785,17 @@ fn serialize_tuple_variant(
 
     let len = serialized_fields
         .map(|(i, field)| match field.attrs.skip_serializing_if() {
             None => quote!(1),
             Some(path) => {
                 let field_expr = Ident::new(&format!("__field{}", i), Span::call_site());
                 quote!(if #path(#field_expr) { 0 } else { 1 })
             }
-        })
-        .fold(quote!(0), |sum, expr| quote!(#sum + #expr));
+        }).fold(quote!(0), |sum, expr| quote!(#sum + #expr));
 
     match context {
         TupleVariant::ExternallyTagged {
             type_name,
             variant_index,
             variant_name,
         } => {
             quote_block! {
@@ -883,18 +862,17 @@ fn serialize_struct_variant<'a>(
     let len = serialized_fields
         .map(|field| {
             let member = &field.member;
 
             match field.attrs.skip_serializing_if() {
                 Some(path) => quote!(if #path(#member) { 0 } else { 1 }),
                 None => quote!(1),
             }
-        })
-        .fold(quote!(0), |sum, expr| quote!(#sum + #expr));
+        }).fold(quote!(0), |sum, expr| quote!(#sum + #expr));
 
     match context {
         StructVariant::ExternallyTagged {
             variant_index,
             variant_name,
         } => {
             quote_block! {
                 let #let_mut __serde_state = try!(_serde::Serializer::serialize_struct_variant(
@@ -1063,18 +1041,17 @@ fn serialize_tuple_struct_visitor(
             let ser = quote! {
                 try!(#func(&mut __serde_state, #field_expr));
             };
 
             match skip {
                 None => ser,
                 Some(skip) => quote!(if !#skip { #ser }),
             }
-        })
-        .collect()
+        }).collect()
 }
 
 fn serialize_struct_visitor(
     fields: &[Field],
     params: &Parameters,
     is_enum: bool,
     struct_trait: &StructTrait,
 ) -> Vec<TokenStream> {
@@ -1098,19 +1075,18 @@ fn serialize_struct_visitor(
                 .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);
             }
 
             let span = field.original.span();
             let ser = if field.attrs.flatten() {
-                let func = quote_spanned!(span=> _serde::Serialize::serialize);
                 quote! {
-                    try!(#func(&#field_expr, _serde::private::ser::FlatMapSerializer(&mut __serde_state)));
+                    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));
                 }
             };
 
@@ -1159,18 +1135,17 @@ fn wrap_serialize_variant_with(
         .map(|field| {
             let id = match field.member {
                 Member::Named(ref ident) => ident.clone(),
                 Member::Unnamed(ref member) => {
                     Ident::new(&format!("__field{}", member.index), Span::call_site())
                 }
             };
             quote!(#id)
-        })
-        .collect();
+        }).collect();
     wrap_serialize_with(
         params,
         serialize_with,
         field_tys.as_slice(),
         field_exprs.as_slice(),
     )
 }