Bug 1472538: Revendor dependencies.
authorEmilio Cobos Álvarez <emilio@crisal.io>
Sun, 01 Jul 2018 14:29:35 +0200
changeset 424590 ad59c8bf30b4674ca7889e0b00793e40dcd64883
parent 424589 2e71ff3c9bd3dd0a665b0f83ca243e57b2358c87
child 424591 da2d9d2b562e04ce033b371be0716208658a1808
push id34217
push userrgurzau@mozilla.com
push dateSun, 01 Jul 2018 21:50:17 +0000
treeherdermozilla-central@3cfc35010196 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs1472538
milestone63.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1472538: Revendor dependencies. MozReview-Commit-ID: 453LPDCC88b
third_party/rust/bindgen/.cargo-checksum.json
third_party/rust/bindgen/Cargo.toml
third_party/rust/bindgen/LICENSE
third_party/rust/bindgen/README.md
third_party/rust/bindgen/src/callbacks.rs
third_party/rust/bindgen/src/clang.rs
third_party/rust/bindgen/src/codegen/bitfield_unit.rs
third_party/rust/bindgen/src/codegen/helpers.rs
third_party/rust/bindgen/src/codegen/impl_partialeq.rs
third_party/rust/bindgen/src/codegen/mod.rs
third_party/rust/bindgen/src/codegen/struct_layout.rs
third_party/rust/bindgen/src/features.rs
third_party/rust/bindgen/src/ir/analysis/derive_copy.rs
third_party/rust/bindgen/src/ir/analysis/derive_debug.rs
third_party/rust/bindgen/src/ir/analysis/derive_default.rs
third_party/rust/bindgen/src/ir/analysis/derive_hash.rs
third_party/rust/bindgen/src/ir/analysis/derive_partialeq_or_partialord.rs
third_party/rust/bindgen/src/ir/analysis/template_params.rs
third_party/rust/bindgen/src/ir/comment.rs
third_party/rust/bindgen/src/ir/comp.rs
third_party/rust/bindgen/src/ir/context.rs
third_party/rust/bindgen/src/ir/derive.rs
third_party/rust/bindgen/src/ir/enum_ty.rs
third_party/rust/bindgen/src/ir/function.rs
third_party/rust/bindgen/src/ir/item.rs
third_party/rust/bindgen/src/ir/layout.rs
third_party/rust/bindgen/src/ir/objc.rs
third_party/rust/bindgen/src/ir/template.rs
third_party/rust/bindgen/src/ir/traversal.rs
third_party/rust/bindgen/src/ir/ty.rs
third_party/rust/bindgen/src/lib.rs
third_party/rust/bindgen/src/options.rs
third_party/rust/bindgen/src/time.rs
third_party/rust/clang-sys/.cargo-checksum.json
third_party/rust/clang-sys/CHANGELOG.md
third_party/rust/clang-sys/CONTRIBUTING.md
third_party/rust/clang-sys/Cargo.toml
third_party/rust/clang-sys/build.rs
third_party/rust/clang-sys/src/lib.rs
third_party/rust/clang-sys/src/link.rs
third_party/rust/clang-sys/src/support.rs
third_party/rust/proc-macro2-0.3.5/.cargo-checksum.json
third_party/rust/proc-macro2-0.3.5/.travis.yml
third_party/rust/proc-macro2-0.3.5/Cargo.toml
third_party/rust/proc-macro2-0.3.5/LICENSE-APACHE
third_party/rust/proc-macro2-0.3.5/LICENSE-MIT
third_party/rust/proc-macro2-0.3.5/README.md
third_party/rust/proc-macro2-0.3.5/src/lib.rs
third_party/rust/proc-macro2-0.3.5/src/stable.rs
third_party/rust/proc-macro2-0.3.5/src/strnom.rs
third_party/rust/proc-macro2-0.3.5/src/unstable.rs
third_party/rust/proc-macro2-0.3.5/tests/test.rs
third_party/rust/proc-macro2-0.3.6/.cargo-checksum.json
third_party/rust/proc-macro2-0.3.6/.travis.yml
third_party/rust/proc-macro2-0.3.6/Cargo.toml
third_party/rust/proc-macro2-0.3.6/LICENSE-APACHE
third_party/rust/proc-macro2-0.3.6/LICENSE-MIT
third_party/rust/proc-macro2-0.3.6/README.md
third_party/rust/proc-macro2-0.3.6/src/lib.rs
third_party/rust/proc-macro2-0.3.6/src/stable.rs
third_party/rust/proc-macro2-0.3.6/src/strnom.rs
third_party/rust/proc-macro2-0.3.6/src/unstable.rs
third_party/rust/proc-macro2-0.3.6/tests/test.rs
--- a/third_party/rust/bindgen/.cargo-checksum.json
+++ b/third_party/rust/bindgen/.cargo-checksum.json
@@ -1,1 +1,1 @@
-{"files":{"Cargo.toml":"d2d15d8518f87e50143184b13e14139095b0a6aa627d4d5d3a2d12893e765f50","build.rs":"032a1c51963894a421b0535f9227796d88768ac5f665a81d2edced69dc6d106a","src/callbacks.rs":"49f382ebdb94c8f0aba5496f5283ae3cdcf6666a5c41c604e6356e674f9a072b","src/clang.rs":"33d94fa699f052b52a2804b85f49fa5de3a2404ae05801ef9eae16016bc841f1","src/codegen/bitfield_unit.rs":"bd1a19701f1766d0bae3bcb97d7c3cb3881d4b182c56b8f4dfd24b7cc87b5338","src/codegen/bitfield_unit_tests.rs":"2073ac6a36e0bc9afaef5b1207966817c8fb7a1a9f6368c3b1b8f79822efbfba","src/codegen/error.rs":"2613af1d833377fd4a70719f4a09951d9d45dc9227827b9a2a938a1bcaaea2dd","src/codegen/helpers.rs":"bcb951f320fd0948e341d8eabdb58567296d77bf1ae5040c05d967e6435a15d5","src/codegen/impl_debug.rs":"e2ffd5b6ed936698aa4b9e7e3459d353383792707ad51f829a18a822f69cab0e","src/codegen/impl_partialeq.rs":"e86050b98f57fa4496dbde0beea319a89e46290309d274f626361779549b95bd","src/codegen/mod.rs":"74e818d857fb5147f623e9287632d23c4bd0cf87de840034809992b74ff88bdc","src/codegen/struct_layout.rs":"698ed7340242d1cbedd38d400c7c83c32e2fa043c35dbc9a2eea4022251ffdb0","src/extra_assertions.rs":"449549c4a7a50c3f0b06332452b2fb6c9b23f31ca8e5e1656fe6c7f21e8ef7fa","src/features.rs":"8c2148a6f922ca9cb0de2dd3ad77c4dd5734c4c219a5bea9d6b22c4367acb187","src/ir/analysis/derive_copy.rs":"14b53c53b337be00d59424371c07c6712d7cfc9a6735f9d913cda043fddce797","src/ir/analysis/derive_debug.rs":"1d6621c0fa5d899310cc175cb99703606ed34fd7f7ad77bb60f012f25ba504af","src/ir/analysis/derive_default.rs":"4fac04fc3019562cd213586680ecdcf8a3b3544ca3a5c5117f68e5c26e7ee0d9","src/ir/analysis/derive_hash.rs":"a50e849b4388115264c2d6afef5ab07e309d2469f4c3342fb683c799451e9e19","src/ir/analysis/derive_partialeq_or_partialord.rs":"46611c7f3caa0fe78243187742c4a36003dbc266de4c4390642e136bb889c43f","src/ir/analysis/has_destructor.rs":"d9aaaceba580b48eb0df4e5537b34b417c51ccdfeb8f6b72484f3bf4992317fe","src/ir/analysis/has_float.rs":"2a0465503d2c8247eaf916bd6a03594f3dc0370533d9a7c58cc5afb86693816c","src/ir/analysis/has_type_param_in_array.rs":"fcb1c78b6000f1f5eb8d8147e2afdaba9eb0e3a81b61e72537048dfdbeea7bcd","src/ir/analysis/has_vtable.rs":"37765e954ef792e369a58ccfe1d827a00fe9bce680466da1d6523671b94b6c92","src/ir/analysis/mod.rs":"ea5ace45c77e855674bb565ba0fef556f60e3293b0ddcf11d3a5a6ec15ab0648","src/ir/analysis/sizedness.rs":"3d3c8bde40604d53bb64273a3cbd8c55936a7dfe1de9b2ba92fc2c45572624b4","src/ir/analysis/template_params.rs":"5c6ee7a251a321ef5733e2e7ac3264621b4181268babcc008b69dbfc37691fb1","src/ir/annotations.rs":"ef106afcbe6084c18bd13a37ee3c1cdc9596bfb055db8c773d81f8f15fec3208","src/ir/comment.rs":"36f2a1d3970fdbf3d72c1f094043902747cde395215bdf7e9103926d9df011fd","src/ir/comp.rs":"b24e6ab76235b46bb5a262e3a3f2fc685c26bd7482aea113231a942eeffd0cf5","src/ir/context.rs":"ccd99c814f1a8ba1f3a30667a8d90db13a50adc26620be08f907283d1c5f08a3","src/ir/derive.rs":"1fd6ad621e3c60b950acbd51fbe386d1f0fadb7c1889c723245afff45e42e143","src/ir/dot.rs":"d01f1621ab67e368d854a82bd6bb0b8dd52f3c2c733de8eaf81aece9543818cb","src/ir/enum_ty.rs":"98a4aa58e598b31e4dc2c052c90029f37b53b5c5cfcbd216d4b0e8c73454813f","src/ir/function.rs":"cce97e7cd6ffb7d5ae40e6be1b82e7ae899d9ea9cf7c8f97380486ac7cc120e6","src/ir/int.rs":"1f61a472288afe489d9320bc8b13920333ece57891ae8570b4c4f25ab50688e6","src/ir/item.rs":"03477f4f4abfebc92ce4c9a202e33c86615dfffe3e6d1e0a201d2e85eecb9917","src/ir/item_kind.rs":"dbeae8c4fd0e5c9485d325aea040e056a1f2cd6d43fc927dee8fe1c0c59a7197","src/ir/layout.rs":"e3d1adf1ad2fa5bd96530cdd5097db3d9cc7b44d33ec23a04fcfccecd9cf4469","src/ir/mod.rs":"2eae90f207fad2e45957ec9287064992a419e3fc916aba84faff2ea25cbeb5ee","src/ir/module.rs":"c4d90bf38fe3672e01923734ccbdb7951ea929949d5f413a9c2aee12395a5094","src/ir/objc.rs":"05068c4fbf42429c4ac2a233c874f18ffcf7dc1744398e400a5a48d0e7a972f2","src/ir/template.rs":"bcd750450a4df0200a6e7958f9c96a09b91e3ccd29c60712f2b9d3458f1234aa","src/ir/traversal.rs":"da73d3fafa594fb12c13136f5c9d6e6ee0d6c7fa4b6e57863638d4ba5ef55dfa","src/ir/ty.rs":"7d16711a053f1b4e9d11d3c5665062a58278a869b196a24b7b2a62227eb3a38f","src/ir/var.rs":"57c8aa9f834c6f06418f7d471b1771bbb915821ef0d194b383be60092edca5f7","src/lib.rs":"99ed57a26e794ce724e434af0bf4f72b199bd0e1c42833324beb939acda9af33","src/log_stubs.rs":"6dfdd908b7c6453da416cf232893768f9480e551ca4add0858ef88bf71ee6ceb","src/main.rs":"e519053bcdde6bc88f60f955246a02d53b3db1cc5ccd1612e6675b790b7460b0","src/options.rs":"3df0214f428c221604420f8eb511b1c1e6d9326d1c6d3d2dea48278f833f9b77","src/parse.rs":"be7d13cc84fae79ec7b3aa9e77063fa475a48d74a854423e2c72d75006a25202","src/regex_set.rs":"a55241f2117f15729d174790f386e255fcb224b692325bbe6716dbb1d6874881","src/time.rs":"a02befb48d10dcc31e3f9571b2fa1c40f97fafe6f6ae7d7fc4f8fd01f1a169ba"},"package":"603ed8d8392ace9581e834e26bd09799bf1e989a79bd1aedbb893e72962bdc6e"}
\ No newline at end of file
+{"files":{"Cargo.toml":"3080fa2631c58e35cb1b32642139d8c303a609f8b554bfe69cd659a5374f18b9","LICENSE":"1d2e4bdb9d94ab020e9550136cae9ec73fc699c3c96a9d98078c542e9b93d294","README.md":"630d1a1d123c131bad0fec23173e263ba8ecc064b5cd8446d4cab7ffd197db45","build.rs":"032a1c51963894a421b0535f9227796d88768ac5f665a81d2edced69dc6d106a","src/callbacks.rs":"9d41b7848cea37e8741fa7bc947ba58a83647824b1a0bbe7ff75012c412eab13","src/clang.rs":"5ce27d0772e66f9f2f94a55afd18c98d4a57aed4c1d57da53b025fbbbb81a287","src/codegen/bitfield_unit.rs":"88b0604322dc449fc9284850eadc1f5d14b42fa747d4258bae0b6b9535f52dfd","src/codegen/bitfield_unit_tests.rs":"2073ac6a36e0bc9afaef5b1207966817c8fb7a1a9f6368c3b1b8f79822efbfba","src/codegen/error.rs":"2613af1d833377fd4a70719f4a09951d9d45dc9227827b9a2a938a1bcaaea2dd","src/codegen/helpers.rs":"8badd4b5ba38b83477c3ee3fc6f9ca79059b5650f5b489b2723c335037e27d92","src/codegen/impl_debug.rs":"e2ffd5b6ed936698aa4b9e7e3459d353383792707ad51f829a18a822f69cab0e","src/codegen/impl_partialeq.rs":"d69e2a9cdf2fdea74a60532109c0a1a75791f5a5ef931b28c5d447fa2915e5d3","src/codegen/mod.rs":"c923594d8d27dede9192dd1081acdedf97d67430f780e3dc4db39b8928a55d71","src/codegen/struct_layout.rs":"9bd0e3455e55e2a1faa4f332a327c2529a21bdfdd0fcb3a45bc5cdd7801d288f","src/extra_assertions.rs":"449549c4a7a50c3f0b06332452b2fb6c9b23f31ca8e5e1656fe6c7f21e8ef7fa","src/features.rs":"a437e6f736c8fba81ff74d90e7ddd142192ae5ffb9240d8c885eb84be6f2fe45","src/ir/analysis/derive_copy.rs":"59c21e299af3a36c6c82d4d16454700238269abd5929ec2d67c8414aebf82c3b","src/ir/analysis/derive_debug.rs":"3530e27ab0e260ec013cee3ad78a81497970c656a8eed589b755cce8caf53040","src/ir/analysis/derive_default.rs":"20e9dac151fadc59a7926ed9276ee8ced47e59c3f0c43f69fdafb75706045aca","src/ir/analysis/derive_hash.rs":"85c73c5660dc311ab6c15a21b69c4c5d2aa380d740decaf59ad594a6728cbe1f","src/ir/analysis/derive_partialeq_or_partialord.rs":"fb9540c324fdfcc9b0ae816e7713af000b11f5e2768c512c22a3082f263bb6bc","src/ir/analysis/has_destructor.rs":"d9aaaceba580b48eb0df4e5537b34b417c51ccdfeb8f6b72484f3bf4992317fe","src/ir/analysis/has_float.rs":"2a0465503d2c8247eaf916bd6a03594f3dc0370533d9a7c58cc5afb86693816c","src/ir/analysis/has_type_param_in_array.rs":"fcb1c78b6000f1f5eb8d8147e2afdaba9eb0e3a81b61e72537048dfdbeea7bcd","src/ir/analysis/has_vtable.rs":"37765e954ef792e369a58ccfe1d827a00fe9bce680466da1d6523671b94b6c92","src/ir/analysis/mod.rs":"ea5ace45c77e855674bb565ba0fef556f60e3293b0ddcf11d3a5a6ec15ab0648","src/ir/analysis/sizedness.rs":"3d3c8bde40604d53bb64273a3cbd8c55936a7dfe1de9b2ba92fc2c45572624b4","src/ir/analysis/template_params.rs":"6554dd1240142ec0e7299e678b696725f5cba99243d1c3d1cbf58d4764082fd6","src/ir/annotations.rs":"ef106afcbe6084c18bd13a37ee3c1cdc9596bfb055db8c773d81f8f15fec3208","src/ir/comment.rs":"000481754e5433d7c0886b9ce8b93b64c7ab1ae52867d211c73c7c4b336649a2","src/ir/comp.rs":"7b22f3ff19ca45a6fbfe7ea015109d43f4ddf65b33b47b1c37829fcb87cdff9b","src/ir/context.rs":"80679859b4efa52d74b0c7501bb5951b58c9705a97b96c9fc05134d1abe401c6","src/ir/derive.rs":"9550d01731ca66be28124c91fd0211a618743a065bec7b00e27c934afff82a84","src/ir/dot.rs":"d01f1621ab67e368d854a82bd6bb0b8dd52f3c2c733de8eaf81aece9543818cb","src/ir/enum_ty.rs":"3611100df8ddf01b010d2eae1d26a67df022e47b6236b0ed9d1b9b42340ebafd","src/ir/function.rs":"b86e665c6659c32bce39194240e7da6221c5a2ec51b362ad9f6e34f1bc396a6f","src/ir/int.rs":"1f61a472288afe489d9320bc8b13920333ece57891ae8570b4c4f25ab50688e6","src/ir/item.rs":"6f0d13615c6883b5e64c75f6d18d79b978b47aa3599ae1f4c196903d2d2cda68","src/ir/item_kind.rs":"dbeae8c4fd0e5c9485d325aea040e056a1f2cd6d43fc927dee8fe1c0c59a7197","src/ir/layout.rs":"17daab0a80564006de1f6b6190e7d9e6c5eb96990242fe707f8dc676f7110c18","src/ir/mod.rs":"2eae90f207fad2e45957ec9287064992a419e3fc916aba84faff2ea25cbeb5ee","src/ir/module.rs":"c4d90bf38fe3672e01923734ccbdb7951ea929949d5f413a9c2aee12395a5094","src/ir/objc.rs":"828a890acdc8b10c44e69e2ed4a4f5d8c0e734606d3a8cc71658dcf43a49acf4","src/ir/template.rs":"21ba4cbacafce39b4a8013bc97e8054a906a8bc2f45a51aeef3b007caadde221","src/ir/traversal.rs":"eaca9aa6deb3eea9b8d7adc696781c70038796ff43e536bda47e90f84fe87d61","src/ir/ty.rs":"daa95f757288e4bfe84f9724c5f5df127b6f3a4452330691a24a94369db7d993","src/ir/var.rs":"57c8aa9f834c6f06418f7d471b1771bbb915821ef0d194b383be60092edca5f7","src/lib.rs":"d4217ac878659794c5990b1612f1de12f94f975257ea14307fb7dc63ac3a76da","src/log_stubs.rs":"6dfdd908b7c6453da416cf232893768f9480e551ca4add0858ef88bf71ee6ceb","src/main.rs":"e519053bcdde6bc88f60f955246a02d53b3db1cc5ccd1612e6675b790b7460b0","src/options.rs":"f1be872e418a96582b048c095ceeeba012b92ffed8a9658cd1fd9ae0e192372d","src/parse.rs":"be7d13cc84fae79ec7b3aa9e77063fa475a48d74a854423e2c72d75006a25202","src/regex_set.rs":"a55241f2117f15729d174790f386e255fcb224b692325bbe6716dbb1d6874881","src/time.rs":"3b763e6fee51d0eb01228dfe28bc28a9f692aff73b2a7b90a030902e0238fca6"},"package":"1b25ab82877ea8fe6ce1ce1f8ac54361f0218bad900af9eb11803994bf67c221"}
\ No newline at end of file
--- a/third_party/rust/bindgen/Cargo.toml
+++ b/third_party/rust/bindgen/Cargo.toml
@@ -7,21 +7,22 @@
 #
 # If you believe there's an error in this file please file an
 # issue against the rust-lang/cargo repository. If you're
 # editing this file be aware that the upstream Cargo.toml
 # will likely look very different (and much more reasonable)
 
 [package]
 name = "bindgen"
-version = "0.33.2"
+version = "0.37.4"
 authors = ["Jyun-Yan You <jyyou.tw@gmail.com>", "Emilio Cobos Álvarez <emilio@crisal.io>", "Nick Fitzgerald <fitzgen@gmail.com>", "The Servo project developers"]
 build = "build.rs"
-include = ["Cargo.toml", "build.rs", "src/*.rs", "src/**/*.rs"]
+include = ["LICENSE", "README.md", "Cargo.toml", "build.rs", "src/*.rs", "src/**/*.rs"]
 description = "Automatically generates Rust FFI bindings to C and C++ libraries."
+homepage = "https://rust-lang-nursery.github.io/rust-bindgen/"
 documentation = "https://docs.rs/bindgen"
 readme = "README.md"
 keywords = ["bindings", "ffi", "code-generation"]
 categories = ["external-ffi-bindings", "development-tools::ffi"]
 license = "BSD-3-Clause"
 repository = "https://github.com/rust-lang-nursery/rust-bindgen"
 
 [lib]
@@ -33,18 +34,18 @@ path = "src/main.rs"
 doc = false
 [dependencies.cexpr]
 version = "0.2"
 
 [dependencies.cfg-if]
 version = "0.1.0"
 
 [dependencies.clang-sys]
-version = "0.22.0"
-features = ["runtime", "clang_3_9"]
+version = "0.23"
+features = ["runtime", "clang_6_0"]
 
 [dependencies.clap]
 version = "2"
 
 [dependencies.env_logger]
 version = "0.5"
 optional = true
 
@@ -53,21 +54,26 @@ version = "1"
 
 [dependencies.log]
 version = "0.4"
 optional = true
 
 [dependencies.peeking_take_while]
 version = "0.1.2"
 
+[dependencies.proc-macro2]
+version = "0.3.2, < 0.3.6"
+default-features = false
+
 [dependencies.quote]
-version = "0.3.15"
+version = "0.5"
+default-features = false
 
 [dependencies.regex]
-version = "0.2"
+version = "1.0"
 
 [dependencies.which]
 version = "1.0.2"
 [dev-dependencies.clap]
 version = "2"
 
 [dev-dependencies.diff]
 version = "0.1"
@@ -79,10 +85,11 @@ version = "0.1"
 default = ["logging"]
 logging = ["env_logger", "log"]
 static = []
 testing_only_docs = []
 testing_only_extra_assertions = []
 testing_only_libclang_3_8 = []
 testing_only_libclang_3_9 = []
 testing_only_libclang_4 = []
+testing_only_libclang_5 = []
 [badges.travis-ci]
 repository = "rust-lang-nursery/rust-bindgen"
new file mode 100644
--- /dev/null
+++ b/third_party/rust/bindgen/LICENSE
@@ -0,0 +1,28 @@
+Copyright (c) 2013, Jyun-Yan You
+
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+
+1. Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions and the following disclaimer in the
+   documentation and/or other materials provided with the distribution.
+3. Neither the name of the author nor the names of his contributors
+   may be used to endorse or promote products derived from this software
+   without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE AUTHORS "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGE.
new file mode 100644
--- /dev/null
+++ b/third_party/rust/bindgen/README.md
@@ -0,0 +1,45 @@
+# `bindgen`
+
+[`impl period`](https://blog.rust-lang.org/2017/09/18/impl-future-for-rust.html) has been started! Join us at [Gitter.im](https://gitter.im/rust-impl-period/WG-dev-tools-bindgen).
+
+**`bindgen` automatically generates Rust FFI bindings to C (and some C++) libraries.**
+
+For example, given the C header `doggo.h`:
+
+```c
+typedef struct Doggo {
+    int many;
+    char wow;
+} Doggo;
+
+void eleven_out_of_ten_majestic_af(Doggo* pupper);
+```
+
+`bindgen` produces Rust FFI code allowing you to call into the `doggo` library's
+functions and use its types:
+
+```rust
+/* automatically generated by rust-bindgen */
+
+#[repr(C)]
+pub struct Doggo {
+    pub many: ::std::os::raw::c_int,
+    pub wow: ::std::os::raw::c_char,
+}
+
+extern "C" {
+    pub fn eleven_out_of_ten_majestic_af(pupper: *mut Doggo);
+}
+```
+
+## Users Guide
+
+[📚 Read the `bindgen` users guide here! 📚](https://rust-lang-nursery.github.io/rust-bindgen)
+
+## API Reference
+
+[API reference documentation is on docs.rs](https://docs.rs/bindgen)
+
+## Contributing
+
+[See `CONTRIBUTING.md` for hacking on `bindgen`!](./CONTRIBUTING.md)
--- a/third_party/rust/bindgen/src/callbacks.rs
+++ b/third_party/rust/bindgen/src/callbacks.rs
@@ -30,17 +30,17 @@ pub trait ParseCallbacks: fmt::Debug + U
     }
 
     /// The integer kind an integer macro should have, given a name and the
     /// value of that macro, or `None` if you want the default to be chosen.
     fn int_macro(&self, _name: &str, _value: i64) -> Option<IntKind> {
         None
     }
 
-    /// This function should return whether, given the a given enum variant
+    /// This function should return whether, given an enum variant
     /// name, and value, this enum variant will forcibly be a constant.
     fn enum_variant_behavior(
         &self,
         _enum_name: Option<&str>,
         _original_variant_name: &str,
         _variant_value: EnumVariantValue,
     ) -> Option<EnumVariantCustomBehavior> {
         None
--- a/third_party/rust/bindgen/src/clang.rs
+++ b/third_party/rust/bindgen/src/clang.rs
@@ -906,16 +906,23 @@ impl Type {
         let size = self.fallible_size()?;
         let align = self.fallible_align()?;
         Ok(Layout::new(size, align))
     }
 
     /// Get the number of template arguments this type has, or `None` if it is
     /// not some kind of template.
     pub fn num_template_args(&self) -> Option<u32> {
+        // If an old libclang is loaded, we have no hope of answering this
+        // question correctly. However, that's no reason to panic when
+        // generating bindings for simple C headers with an old libclang.
+        if !clang_Type_getNumTemplateArguments::is_loaded() {
+            return None
+        }
+
         let n = unsafe { clang_Type_getNumTemplateArguments(self.x) };
         if n >= 0 {
             Some(n as u32)
         } else {
             debug_assert_eq!(n, -1);
             None
         }
     }
@@ -970,17 +977,17 @@ impl Type {
         let num_elements_returned = unsafe { clang_getNumElements(self.x) };
         if num_elements_returned != -1 {
             Some(num_elements_returned as usize)
         } else {
             None
         }
     }
 
-    /// Get the canonical version of this type. This sees through `typdef`s and
+    /// Get the canonical version of this type. This sees through `typedef`s and
     /// aliases to get the underlying, canonical type.
     pub fn canonical_type(&self) -> Type {
         unsafe {
             Type {
                 x: clang_getCanonicalType(self.x),
             }
         }
     }
@@ -1634,18 +1641,21 @@ pub fn ast_dump(c: &Cursor, depth: isize
         }
 
         print_indent(depth, format!(" {}cconv = {}", prefix, ty.call_conv()));
 
         print_indent(
             depth,
             format!(" {}spelling = \"{}\"", prefix, ty.spelling()),
         );
-        let num_template_args =
-            unsafe { clang_Type_getNumTemplateArguments(ty.x) };
+        let num_template_args = if clang_Type_getNumTemplateArguments::is_loaded() {
+            unsafe { clang_Type_getNumTemplateArguments(ty.x) }
+        } else {
+            -1
+        };
         if num_template_args >= 0 {
             print_indent(
                 depth,
                 format!(
                     " {}number-of-template-args = {}",
                     prefix,
                     num_template_args
                 ),
@@ -1807,8 +1817,40 @@ impl EvalResult {
     }
 }
 
 impl Drop for EvalResult {
     fn drop(&mut self) {
         unsafe { clang_EvalResult_dispose(self.x) };
     }
 }
+
+/// Target information obtained from libclang.
+#[derive(Debug)]
+pub struct TargetInfo {
+    /// The target triple.
+    pub triple: String,
+    /// The width of the pointer _in bits_.
+    pub pointer_width: usize,
+}
+
+impl TargetInfo {
+    /// Tries to obtain target information from libclang.
+    pub fn new(tu: &TranslationUnit) -> Option<Self> {
+        if !clang_getTranslationUnitTargetInfo::is_loaded() {
+            return None;
+        }
+        let triple;
+        let pointer_width;
+        unsafe {
+            let ti = clang_getTranslationUnitTargetInfo(tu.x);
+            triple = cxstring_into_string(clang_TargetInfo_getTriple(ti));
+            pointer_width = clang_TargetInfo_getPointerWidth(ti);
+            clang_TargetInfo_dispose(ti);
+        }
+        assert!(pointer_width > 0);
+        assert_eq!(pointer_width % 8, 0);
+        Some(TargetInfo {
+            triple,
+            pointer_width: pointer_width as usize,
+        })
+    }
+}
--- a/third_party/rust/bindgen/src/codegen/bitfield_unit.rs
+++ b/third_party/rust/bindgen/src/codegen/bitfield_unit.rs
@@ -22,32 +22,43 @@ where
 
     #[inline]
     pub fn get_bit(&self, index: usize) -> bool {
         debug_assert!(index / 8 < self.storage.as_ref().len());
 
         let byte_index = index / 8;
         let byte = self.storage.as_ref()[byte_index];
 
-        let bit_index = index % 8;
+        let bit_index =
+            if cfg!(target_endian = "big") {
+                7 - (index % 8)
+            } else {
+                index % 8
+            };
+
         let mask = 1 << bit_index;
 
         byte & mask == mask
     }
 
     #[inline]
     pub fn set_bit(&mut self, index: usize, val: bool) {
         debug_assert!(index / 8 < self.storage.as_ref().len());
 
         let byte_index = index / 8;
         let byte = &mut self.storage.as_mut()[byte_index];
 
-        let bit_index = index % 8;
+        let bit_index =
+            if cfg!(target_endian = "big") {
+                7 - (index % 8)
+            } else {
+                index % 8
+            };
+
         let mask = 1 << bit_index;
-
         if val {
             *byte |= mask;
         } else {
             *byte &= !mask;
         }
     }
 
     #[inline]
@@ -55,28 +66,40 @@ where
         debug_assert!(bit_width <= 64);
         debug_assert!(bit_offset / 8 < self.storage.as_ref().len());
         debug_assert!((bit_offset + (bit_width as usize)) / 8 <= self.storage.as_ref().len());
 
         let mut val = 0;
 
         for i in 0..(bit_width as usize) {
             if self.get_bit(i + bit_offset) {
-                val |= 1 << i;
+                let index =
+                    if cfg!(target_endian = "big") {
+                        bit_width as usize - 1 - i
+                    } else {
+                        i
+                    };
+                val |= 1 << index;
             }
         }
 
         val
     }
 
     #[inline]
     pub fn set(&mut self, bit_offset: usize, bit_width: u8, val: u64) {
         debug_assert!(bit_width <= 64);
         debug_assert!(bit_offset / 8 < self.storage.as_ref().len());
         debug_assert!((bit_offset + (bit_width as usize)) / 8 <= self.storage.as_ref().len());
 
         for i in 0..(bit_width as usize) {
             let mask = 1 << i;
             let val_bit_is_set = val & mask == mask;
-            self.set_bit(i + bit_offset, val_bit_is_set);
+            let index =
+                if cfg!(target_endian = "big") {
+                    bit_width as usize - 1 - i
+                } else {
+                    i
+                };
+            self.set_bit(index + bit_offset, val_bit_is_set);
         }
     }
 }
--- a/third_party/rust/bindgen/src/codegen/helpers.rs
+++ b/third_party/rust/bindgen/src/codegen/helpers.rs
@@ -1,53 +1,55 @@
 //! Helpers for code generation that don't need macro expansion.
 
 use ir::context::BindgenContext;
 use ir::layout::Layout;
 use quote;
 use std::mem;
+use proc_macro2::{Term, Span};
 
 pub mod attributes {
     use quote;
+    use proc_macro2::{Term, Span};
 
     pub fn repr(which: &str) -> quote::Tokens {
-        let which = quote::Ident::new(which);
+        let which = Term::new(which, Span::call_site());
         quote! {
             #[repr( #which )]
         }
     }
 
     pub fn repr_list(which_ones: &[&str]) -> quote::Tokens {
-        let which_ones = which_ones.iter().cloned().map(quote::Ident::new);
+        let which_ones = which_ones.iter().cloned().map(|one| Term::new(one, Span::call_site()));
         quote! {
             #[repr( #( #which_ones ),* )]
         }
     }
 
     pub fn derives(which_ones: &[&str]) -> quote::Tokens {
-        let which_ones = which_ones.iter().cloned().map(quote::Ident::new);
+        let which_ones = which_ones.iter().cloned().map(|one| Term::new(one, Span::call_site()));
         quote! {
             #[derive( #( #which_ones ),* )]
         }
     }
 
     pub fn inline() -> quote::Tokens {
         quote! {
             #[inline]
         }
     }
 
     pub fn doc(comment: String) -> quote::Tokens {
         // Doc comments are already preprocessed into nice `///` formats by the
         // time they get here. Just make sure that we have newlines around it so
         // that nothing else gets wrapped into the comment.
         let mut tokens = quote! {};
-        tokens.append("\n");
-        tokens.append(comment);
-        tokens.append("\n");
+        tokens.append(Term::new("\n", Span::call_site()));
+        tokens.append(Term::new(&comment, Span::call_site()));
+        tokens.append(Term::new("\n", Span::call_site()));
         tokens
     }
 
     pub fn link_name(name: &str) -> quote::Tokens {
         // LLVM mangles the name by default but it's already mangled.
         // Prefixing the name with \u{1} should tell LLVM to not mangle it.
         let name = format!("\u{1}{}", name);
         quote! {
@@ -68,17 +70,17 @@ pub fn blob(layout: Layout) -> quote::To
     let ty_name = match opaque.known_rust_type_for_array() {
         Some(ty) => ty,
         None => {
             warn!("Found unknown alignment on code generation!");
             "u8"
         }
     };
 
-    let ty_name = quote::Ident::new(ty_name);
+    let ty_name = Term::new(ty_name, Span::call_site());
 
     let data_len = opaque.array_size().unwrap_or(layout.size);
 
     if data_len == 1 {
         quote! {
             #ty_name
         }
     } else {
@@ -98,39 +100,40 @@ pub fn integer_type(layout: Layout) -> O
     }
 }
 
 /// Generates a bitfield allocation unit type for a type with the given `Layout`.
 pub fn bitfield_unit(ctx: &BindgenContext, layout: Layout) -> quote::Tokens {
     let mut tokens = quote! {};
 
     if ctx.options().enable_cxx_namespaces {
-        tokens.append(quote! { root:: });
+        tokens.append_all(quote! { root:: });
     }
 
     let align = match layout.align {
         n if n >= 8 => quote! { u64 },
         4 => quote! { u32 },
         2 => quote! { u16 },
         _ => quote! { u8  },
     };
 
     let size = layout.size;
-    tokens.append(quote! {
+    tokens.append_all(quote! {
         __BindgenBitfieldUnit<[u8; #size], #align>
     });
 
     tokens
 }
 
 pub mod ast_ty {
     use ir::context::BindgenContext;
     use ir::function::FunctionSig;
     use ir::ty::FloatKind;
     use quote;
+    use proc_macro2;
 
     pub fn raw_type(ctx: &BindgenContext, name: &str) -> quote::Tokens {
         let ident = ctx.rust_ident_raw(name);
         match ctx.options().ctypes_prefix {
             Some(ref prefix) => {
                 let prefix = ctx.rust_ident_raw(prefix.as_str());
                 quote! {
                     #prefix::#ident
@@ -161,59 +164,48 @@ pub mod ast_ty {
             (FloatKind::Double, false) |
             (FloatKind::LongDouble, false) => raw_type(ctx, "c_double"),
             (FloatKind::Float128, _) => quote! { [u8; 16] },
         }
     }
 
     pub fn int_expr(val: i64) -> quote::Tokens {
         // Don't use quote! { #val } because that adds the type suffix.
-        let mut tokens = quote! {};
-        tokens.append(val.to_string());
-        tokens
+        let val = proc_macro2::Literal::i64_unsuffixed(val);
+        quote!(#val)
     }
 
     pub fn uint_expr(val: u64) -> quote::Tokens {
         // Don't use quote! { #val } because that adds the type suffix.
-        let mut tokens = quote! {};
-        tokens.append(val.to_string());
-        tokens
+        let val = proc_macro2::Literal::u64_unsuffixed(val);
+        quote!(#val)
     }
 
     pub fn byte_array_expr(bytes: &[u8]) -> quote::Tokens {
         let mut bytes: Vec<_> = bytes.iter().cloned().collect();
         bytes.push(0);
-        quote! {
-            #bytes
-        }
+        quote! { [ #(#bytes),* ] }
     }
 
     pub fn cstr_expr(mut string: String) -> quote::Tokens {
         string.push('\0');
-        let b = quote::ByteStr(&string);
+        let b = proc_macro2::Literal::byte_string(&string.as_bytes());
         quote! {
             #b
         }
     }
 
     pub fn float_expr(
         ctx: &BindgenContext,
         f: f64,
     ) -> Result<quote::Tokens, ()> {
         if f.is_finite() {
-            let mut string = f.to_string();
+            let val = proc_macro2::Literal::f64_unsuffixed(f);
 
-            // So it gets properly recognised as a floating point constant.
-            if !string.contains('.') {
-                string.push('.');
-            }
-
-            let mut tokens = quote! {};
-            tokens.append(string);
-            return Ok(tokens);
+            return Ok(quote!(#val));
         }
 
         let prefix = ctx.trait_prefix();
 
         if f.is_nan() {
             return Ok(quote! {
                 ::#prefix::f64::NAN
             });
--- a/third_party/rust/bindgen/src/codegen/impl_partialeq.rs
+++ b/third_party/rust/bindgen/src/codegen/impl_partialeq.rs
@@ -1,31 +1,32 @@
 
 use ir::comp::{CompInfo, CompKind, Field, FieldMethods};
 use ir::context::BindgenContext;
 use ir::item::{IsOpaque, Item};
 use ir::ty::{TypeKind, RUST_DERIVE_IN_ARRAY_LIMIT};
 use quote;
+use proc_macro2;
 
 /// Generate a manual implementation of `PartialEq` trait for the
 /// specified compound type.
 pub fn gen_partialeq_impl(
     ctx: &BindgenContext,
     comp_info: &CompInfo,
     item: &Item,
     ty_for_impl: &quote::Tokens,
 ) -> Option<quote::Tokens> {
     let mut tokens = vec![];
 
     if item.is_opaque(ctx, &()) {
         tokens.push(quote! {
             &self._bindgen_opaque_blob[..] == &other._bindgen_opaque_blob[..]
         });
     } else if comp_info.kind() == CompKind::Union {
-        assert!(!ctx.options().rust_features().untagged_union());
+        assert!(!ctx.options().rust_features().untagged_union);
         tokens.push(quote! {
             &self.bindgen_union_field[..] == &other.bindgen_union_field[..]
         });
     } else {
         for base in comp_info.base_members().iter() {
             if !base.requires_storage(ctx) {
                 continue;
             }
@@ -66,17 +67,17 @@ pub fn gen_partialeq_impl(
     Some(quote! {
         fn eq(&self, other: & #ty_for_impl) -> bool {
             #( #tokens )&&*
         }
     })
 }
 
 fn gen_field(ctx: &BindgenContext, ty_item: &Item, name: &str) -> quote::Tokens {
-    fn quote_equals(name_ident: quote::Ident) -> quote::Tokens {
+    fn quote_equals(name_ident: proc_macro2::Term) -> quote::Tokens {
         quote! { self.#name_ident == other.#name_ident }
     }
 
     let name_ident = ctx.rust_ident(name);
     let ty = ty_item.expect_type();
 
     match *ty.kind() {
         TypeKind::Void |
--- a/third_party/rust/bindgen/src/codegen/mod.rs
+++ b/third_party/rust/bindgen/src/codegen/mod.rs
@@ -33,24 +33,25 @@ use ir::item_kind::ItemKind;
 use ir::layout::Layout;
 use ir::module::Module;
 use ir::objc::{ObjCInterface, ObjCMethod};
 use ir::template::{AsTemplateParam, TemplateInstantiation, TemplateParameters};
 use ir::ty::{Type, TypeKind};
 use ir::var::Var;
 
 use quote;
-
+use proc_macro2::{self, Term, Span};
+
+use std;
 use std::borrow::Cow;
 use std::cell::Cell;
 use std::collections::{HashSet, VecDeque};
 use std::collections::hash_map::{Entry, HashMap};
 use std::fmt::Write;
 use std::iter;
-use std::mem;
 use std::ops;
 
 // Name of type defined in constified enum module
 pub static CONSTIFIED_ENUM_MODULE_REPR_NAME: &'static str = "Type";
 
 fn top_level_path(ctx: &BindgenContext, item: &Item) -> Vec<quote::Tokens> {
     let mut path = vec![quote! { self }];
 
@@ -70,17 +71,17 @@ fn root_import(ctx: &BindgenContext, mod
     let mut path = top_level_path(ctx, module);
 
     let root = ctx.root_module().canonical_name(ctx);
     let root_ident = ctx.rust_ident(&root);
     path.push(quote! { #root_ident });
 
 
     let mut tokens = quote! {};
-    tokens.append_separated(path, "::");
+    tokens.append_separated(path, Term::new("::", Span::call_site()));
 
     quote! {
         #[allow(unused_imports)]
         use #tokens ;
     }
 }
 
 struct CodegenResult<'a> {
@@ -294,27 +295,22 @@ impl AppendImplicitTemplateParams for qu
             TypeKind::Enum(..) |
             TypeKind::BlockPointer |
             TypeKind::ObjCId |
             TypeKind::ObjCSel |
             TypeKind::TemplateInstantiation(..) => return,
             _ => {},
         }
 
-        if let Some(params) = item.used_template_params(ctx) {
-            if params.is_empty() {
-                return;
-            }
-
-            let params = params.into_iter().map(|p| {
-                p.try_to_rust_ty(ctx, &())
-                    .expect("template params cannot fail to be a rust type")
-            });
-
-            self.append(quote! {
+        let params: Vec<_> = item.used_template_params(ctx).iter().map(|p| {
+            p.try_to_rust_ty(ctx, &())
+                .expect("template params cannot fail to be a rust type")
+        }).collect();
+        if !params.is_empty() {
+            self.append_all(quote! {
                 < #( #params ),* >
             });
         }
     }
 }
 
 trait CodeGenerator {
     /// Extra information from the caller.
@@ -399,17 +395,17 @@ impl CodeGenerator for Module {
 
             if item.id() == ctx.root_module() {
                 if result.saw_bindgen_union {
                     utils::prepend_union_types(ctx, &mut *result);
                 }
                 if result.saw_incomplete_array {
                     utils::prepend_incomplete_array_types(ctx, &mut *result);
                 }
-                if ctx.need_bindegen_complex_type() {
+                if ctx.need_bindgen_complex_type() {
                     utils::prepend_complex_type(&mut *result);
                 }
                 if result.saw_objc {
                     utils::prepend_objc_header(ctx, &mut *result);
                 }
                 if result.saw_bitfield_unit {
                     utils::prepend_bitfield_unit_type(&mut *result);
                 }
@@ -422,35 +418,46 @@ impl CodeGenerator for Module {
         {
             codegen_self(result, &mut false);
             return;
         }
 
         let mut found_any = false;
         let inner_items = result.inner(|result| {
             result.push(root_import(ctx, item));
+
+            let path = item.namespace_aware_canonical_path(ctx).join("::");
+            if let Some(raw_lines) = ctx.options().module_lines.get(&path) {
+                for raw_line in raw_lines {
+                    found_any = true;
+                    // FIXME(emilio): The use of `Term` is an abuse, but we abuse it
+                    // in a bunch more places.
+                    let line = Term::new(raw_line, Span::call_site());
+                    result.push(quote! { #line });
+                }
+            }
+
             codegen_self(result, &mut found_any);
         });
 
         // Don't bother creating an empty module.
         if !found_any {
             return;
         }
 
         let name = item.canonical_name(ctx);
-
-        result.push(if name == "root" {
+        let ident = ctx.rust_ident(name);
+        result.push(if item.id() == ctx.root_module() {
             quote! {
                 #[allow(non_snake_case, non_camel_case_types, non_upper_case_globals)]
-                pub mod root {
+                pub mod #ident {
                     #( #inner_items )*
                 }
             }
         } else {
-            let ident = ctx.rust_ident(name);
             quote! {
                 pub mod #ident {
                     #( #inner_items )*
                 }
             }
         });
     }
 }
@@ -474,21 +481,18 @@ impl CodeGenerator for Var {
         }
         result.saw_var(&canonical_name);
 
         let canonical_ident = ctx.rust_ident(&canonical_name);
 
         // We can't generate bindings to static variables of templates. The
         // number of actual variables for a single declaration are open ended
         // and we don't know what instantiations do or don't exist.
-        let type_params = item.all_template_params(ctx);
-        if let Some(params) = type_params {
-            if !params.is_empty() {
-                return;
-            }
+        if !item.all_template_params(ctx).is_empty() {
+            return;
         }
 
         let ty = self.ty().to_rust_ty_or_opaque(ctx, &());
 
         if let Some(val) = self.val() {
             match *val {
                 VarType::Bool(val) => {
                     result.push(quote! {
@@ -631,25 +635,20 @@ impl CodeGenerator for Type {
 
                 // If this is a known named type, disallow generating anything
                 // for it too.
                 let spelling = self.name().expect("Unnamed alias?");
                 if utils::type_from_named(ctx, spelling).is_some() {
                     return;
                 }
 
-                let mut outer_params = item.used_template_params(ctx)
-                    .and_then(|ps| if ps.is_empty() {
-                        None
-                    } else {
-                        Some(ps)
-                    });
+                let mut outer_params = item.used_template_params(ctx);
 
                 let inner_rust_type = if item.is_opaque(ctx, &()) {
-                    outer_params = None;
+                    outer_params = vec![];
                     self.to_opaque(ctx, item)
                 } else {
                     // Its possible that we have better layout information than
                     // the inner type does, so fall back to an opaque blob based
                     // on our layout if converting the inner item fails.
                     let mut inner_ty = inner_item
                         .try_to_rust_ty_or_opaque(ctx, &())
                         .unwrap_or_else(|_| self.to_opaque(ctx, item));
@@ -686,68 +685,66 @@ impl CodeGenerator for Type {
                 let mut tokens = if let Some(comment) = item.comment(ctx) {
                     attributes::doc(comment)
                 } else {
                     quote! {}
                 };
 
                 // We prefer using `pub use` over `pub type` because of:
                 // https://github.com/rust-lang/rust/issues/26264
-                if inner_rust_type.as_str()
+                if inner_rust_type.to_string()
                     .chars()
                     .all(|c| match c {
                         // These are the only characters allowed in simple
                         // paths, eg `good::dogs::Bront`.
                         'A'...'Z' | 'a'...'z' | '0'...'9' | ':' | '_' | ' ' => true,
                         _ => false,
                     }) &&
-                    outer_params.is_none() &&
+                    outer_params.is_empty() &&
                     inner_item.expect_type().canonical_type(ctx).is_enum()
                 {
-                    tokens.append(quote! {
+                    tokens.append_all(quote! {
                         pub use
                     });
                     let path = top_level_path(ctx, item);
-                    tokens.append_separated(path, "::");
-                    tokens.append(quote! {
+                    tokens.append_separated(path, Term::new("::", Span::call_site()));
+                    tokens.append_all(quote! {
                         :: #inner_rust_type  as #rust_name ;
                     });
                     result.push(tokens);
                     return;
                 }
 
-                tokens.append(quote! {
+                tokens.append_all(quote! {
                     pub type #rust_name
                 });
 
-                if let Some(params) = outer_params {
-                    let params: Vec<_> = params.into_iter()
-                        .filter_map(|p| p.as_template_param(ctx, &()))
-                        .collect();
-                    if params.iter().any(|p| ctx.resolve_type(*p).is_invalid_type_param()) {
-                        warn!(
-                            "Item contained invalid template \
-                             parameter: {:?}",
-                            item
-                        );
-                        return;
-                    }
-
-                    let params = params.iter()
-                        .map(|p| {
-                            p.try_to_rust_ty(ctx, &())
-                                .expect("type parameters can always convert to rust ty OK")
-                        });
-
-                    tokens.append(quote! {
+                let params: Vec<_> = outer_params.into_iter()
+                    .filter_map(|p| p.as_template_param(ctx, &()))
+                    .collect();
+                if params.iter().any(|p| ctx.resolve_type(*p).is_invalid_type_param()) {
+                    warn!(
+                        "Item contained invalid template \
+                         parameter: {:?}",
+                        item
+                    );
+                    return;
+                }
+                let params: Vec<_> = params.iter().map(|p| {
+                    p.try_to_rust_ty(ctx, &())
+                        .expect("type parameters can always convert to rust ty OK")
+                }).collect();
+
+                if !params.is_empty() {
+                    tokens.append_all(quote! {
                         < #( #params ),* >
                     });
                 }
 
-                tokens.append(quote! {
+                tokens.append_all(quote! {
                     = #inner_rust_type ;
                 });
 
                 result.push(tokens);
             }
             TypeKind::Enum(ref ei) => ei.codegen(ctx, result, item),
             TypeKind::ObjCId | TypeKind::ObjCSel => {
                 result.saw_objc();
@@ -1054,21 +1051,21 @@ impl<'a> FieldCodegen<'a> for FieldData 
         let is_private = self.annotations().private_fields().unwrap_or(
             fields_should_be_private,
         );
 
         let accessor_kind =
             self.annotations().accessor_kind().unwrap_or(accessor_kind);
 
         if is_private {
-            field.append(quote! {
+            field.append_all(quote! {
                 #field_ident : #ty ,
             });
         } else {
-            field.append(quote! {
+            field.append_all(quote! {
                 pub #field_ident : #ty ,
             });
         }
 
         fields.extend(Some(field));
 
         // TODO: Factor the following code out, please!
         if accessor_kind == FieldAccessorKind::None {
@@ -1118,17 +1115,17 @@ impl<'a> FieldCodegen<'a> for FieldData 
             }
         }));
     }
 }
 
 impl BitfieldUnit {
     /// Get the constructor name for this bitfield unit.
     fn ctor_name(&self) -> quote::Tokens {
-        let ctor_name = quote::Ident::new(format!("new_bitfield_{}", self.nth()));
+        let ctor_name = Term::new(&format!("new_bitfield_{}", self.nth()), Span::call_site());
         quote! {
             #ctor_name
         }
     }
 }
 
 impl Bitfield {
     /// Extend an under construction bitfield unit constructor with this
@@ -1149,17 +1146,17 @@ impl Bitfield {
             "Bitfield without layout? Gah!",
         );
         let bitfield_int_ty = helpers::blob(bitfield_ty_layout);
 
         let offset = self.offset_into_unit();
         let width = self.width() as u8;
         let prefix = ctx.trait_prefix();
 
-        ctor_impl.append(quote! {
+        ctor_impl.append_all(quote! {
             __bindgen_bitfield_unit.set(
                 #offset,
                 #width,
                 {
                     let #param_name: #bitfield_int_ty = unsafe {
                         ::#prefix::mem::transmute(#param_name)
                     };
                     #param_name as u64
@@ -1317,17 +1314,17 @@ impl<'a> FieldCodegen<'a> for Bitfield {
         (unit_field_name, bitfield_representable_as_int): (&'a str, &mut bool),
     ) where
         F: Extend<quote::Tokens>,
         M: Extend<quote::Tokens>,
     {
         let prefix = ctx.trait_prefix();
         let getter_name = bitfield_getter_name(ctx, self);
         let setter_name = bitfield_setter_name(ctx, self);
-        let unit_field_ident = quote::Ident::new(unit_field_name);
+        let unit_field_ident = Term::new(unit_field_name, Span::call_site());
 
         let bitfield_ty_item = ctx.resolve_item(self.ty());
         let bitfield_ty = bitfield_ty_item.expect_type();
 
         let bitfield_ty_layout = bitfield_ty.layout(ctx).expect(
             "Bitfield without layout? Gah!",
         );
         let bitfield_int_ty = match helpers::integer_type(bitfield_ty_layout) {
@@ -1413,18 +1410,16 @@ impl CodeGenerator for CompInfo {
         debug_assert!(item.is_enabled_for_codegen(ctx));
 
         // Don't output classes with template parameters that aren't types, and
         // also don't output template specializations, neither total or partial.
         if self.has_non_type_template_params() {
             return;
         }
 
-        let used_template_params = item.used_template_params(ctx);
-
         let ty = item.expect_type();
         let layout = ty.layout(ctx);
         let mut packed = self.is_packed(ctx, &layout);
 
         let canonical_name = item.canonical_name(ctx);
         let canonical_ident = ctx.rust_ident(&canonical_name);
 
         // Generate the vtable from the method list if appropriate.
@@ -1522,23 +1517,26 @@ impl CodeGenerator for CompInfo {
                 struct_layout.saw_union(layout);
 
                 quote! {
                     pub bindgen_union_field: #ty ,
                 }
             });
         }
 
+        let mut explicit_align = None;
         if is_opaque {
             // Opaque item should not have generated methods, fields.
             debug_assert!(fields.is_empty());
             debug_assert!(methods.is_empty());
 
             match layout {
                 Some(l) => {
+                    explicit_align = Some(l.align);
+
                     let ty = helpers::blob(l);
                     fields.push(quote! {
                         pub _bindgen_opaque_blob: #ty ,
                     });
                 }
                 None => {
                     warn!("Opaque type without layout! Expect dragons!");
                 }
@@ -1550,16 +1548,17 @@ impl CodeGenerator for CompInfo {
                 fields.push(padding_field);
             }
 
             if let Some(layout) = layout {
                 if struct_layout.requires_explicit_align(layout) {
                     if layout.align == 1 {
                         packed = true;
                     } else {
+                        explicit_align = Some(layout.align);
                         let ty = helpers::blob(Layout::new(0, layout.align));
                         fields.push(quote! {
                             pub __bindgen_align: #ty ,
                         });
                     }
                 }
             }
         }
@@ -1592,31 +1591,29 @@ impl CodeGenerator for CompInfo {
                 fields.push(quote! {
                     pub _address: #ty,
                 });
             }
         }
 
         let mut generic_param_names = vec![];
 
-        if let Some(ref params) = used_template_params {
-            for (idx, ty) in params.iter().enumerate() {
-                let param = ctx.resolve_type(*ty);
-                let name = param.name().unwrap();
-                let ident = ctx.rust_ident(name);
-                generic_param_names.push(ident.clone());
-
-                let prefix = ctx.trait_prefix();
-                let field_name = ctx.rust_ident(format!("_phantom_{}", idx));
-                fields.push(quote! {
-                    pub #field_name : ::#prefix::marker::PhantomData<
-                        ::#prefix::cell::UnsafeCell<#ident>
-                    > ,
-                });
-            }
+        for (idx, ty) in item.used_template_params(ctx).iter().enumerate() {
+            let param = ctx.resolve_type(*ty);
+            let name = param.name().unwrap();
+            let ident = ctx.rust_ident(name);
+            generic_param_names.push(ident.clone());
+
+            let prefix = ctx.trait_prefix();
+            let field_name = ctx.rust_ident(format!("_phantom_{}", idx));
+            fields.push(quote! {
+                pub #field_name : ::#prefix::marker::PhantomData<
+                    ::#prefix::cell::UnsafeCell<#ident>
+                > ,
+            });
         }
 
         let generics = if !generic_param_names.is_empty() {
             let generic_param_names = generic_param_names.clone();
             quote! {
                 < #( #generic_param_names ),* >
             }
         } else {
@@ -1632,36 +1629,50 @@ impl CodeGenerator for CompInfo {
             attributes.push(attributes::doc(comment));
         }
         if packed && !is_opaque {
             attributes.push(attributes::repr_list(&["C", "packed"]));
         } else {
             attributes.push(attributes::repr("C"));
         }
 
+        if ctx.options().rust_features().repr_align {
+            if let Some(explicit) = explicit_align {
+                // Ensure that the struct has the correct alignment even in
+                // presence of alignas.
+                let explicit = helpers::ast_ty::int_expr(explicit as i64);
+                attributes.push(quote! {
+                    #[repr(align(#explicit))]
+                });
+            }
+        }
+
+
         let mut derives = vec![];
         if item.can_derive_debug(ctx) {
             derives.push("Debug");
         } else {
             needs_debug_impl = ctx.options().derive_debug &&
                 ctx.options().impl_debug
         }
 
         if item.can_derive_default(ctx) {
             derives.push("Default");
         } else {
             needs_default_impl =
                 ctx.options().derive_default && !self.is_forward_declaration();
         }
 
+        let all_template_params = item.all_template_params(ctx);
+
         if item.can_derive_copy(ctx) && !item.annotations().disallow_copy() {
             derives.push("Copy");
 
-            if ctx.options().rust_features().builtin_clone_impls() ||
-                used_template_params.is_some()
+            if ctx.options().rust_features().builtin_clone_impls ||
+                !all_template_params.is_empty()
             {
                 // FIXME: This requires extra logic if you have a big array in a
                 // templated struct. The reason for this is that the magic:
                 //     fn clone(&self) -> Self { *self }
                 // doesn't work for templates.
                 //
                 // It's not hard to fix though.
                 derives.push("Clone");
@@ -1706,17 +1717,17 @@ impl CodeGenerator for CompInfo {
             }
         } else {
             quote! {
                 #( #attributes )*
                 pub struct #canonical_ident
             }
         };
 
-        tokens.append(quote! {
+        tokens.append_all(quote! {
             #generics {
                 #( #fields )*
             }
         });
         result.push(tokens);
 
         // Generate the inner types and all that stuff.
         //
@@ -1729,45 +1740,46 @@ impl CodeGenerator for CompInfo {
         }
 
         // NOTE: Some unexposed attributes (like alignment attributes) may
         // affect layout, so we're bad and pray to the gods for avoid sending
         // all the tests to shit when parsing things like max_align_t.
         if self.found_unknown_attr() {
             warn!(
                 "Type {} has an unkown attribute that may affect layout",
-                canonical_ident
+                canonical_ident.as_str()
             );
         }
 
-        if used_template_params.is_none() {
+        if all_template_params.is_empty() {
             if !is_opaque {
                 for var in self.inner_vars() {
                     ctx.resolve_item(*var).codegen(ctx, result, &());
                 }
             }
 
             if ctx.options().layout_tests && !self.is_forward_declaration() {
                 if let Some(layout) = layout {
                     let fn_name =
-                        format!("bindgen_test_layout_{}", canonical_ident);
+                        format!("bindgen_test_layout_{}", canonical_ident.as_str());
                     let fn_name = ctx.rust_ident_raw(fn_name);
                     let prefix = ctx.trait_prefix();
                     let size_of_expr = quote! {
                         ::#prefix::mem::size_of::<#canonical_ident>()
                     };
                     let align_of_expr = quote! {
                         ::#prefix::mem::align_of::<#canonical_ident>()
                     };
                     let size = layout.size;
                     let align = layout.align;
 
                     let check_struct_align =
-                        if align > mem::size_of::<*mut ()>() {
-                            // FIXME when [RFC 1358](https://github.com/rust-lang/rust/issues/33626) ready
+                        if align > ctx.target_pointer_size() &&
+                            !ctx.options().rust_features().repr_align
+                        {
                             None
                         } else {
                             Some(quote! {
                                 assert_eq!(#align_of_expr,
                                        #align,
                                        concat!("Alignment of ", stringify!(#canonical_ident)));
 
                             })
@@ -1991,17 +2003,17 @@ impl MethodCodegen for Method {
             _ => function.name().to_owned(),
         };
 
         let signature = match *signature_item.expect_type().kind() {
             TypeKind::Function(ref sig) => sig,
             _ => panic!("How in the world?"),
         };
 
-        if let (Abi::ThisCall, false) = (signature.abi(), ctx.options().rust_features().thiscall_abi()) {
+        if let (Abi::ThisCall, false) = (signature.abi(), ctx.options().rust_features().thiscall_abi) {
             return;
         }
 
         // Do not generate variadic methods, since rust does not allow
         // implementing them, and we don't do a good job at it anyway.
         if signature.is_variadic() {
             return;
         }
@@ -2087,55 +2099,84 @@ impl MethodCodegen for Method {
             pub unsafe fn #name ( #( #args ),* ) #ret {
                 #block
             }
         });
     }
 }
 
 /// A helper type that represents different enum variations.
-#[derive(Copy, Clone)]
-enum EnumVariation {
+#[derive(Copy, Clone, PartialEq, Debug)]
+pub enum EnumVariation {
+    /// The code for this enum will use a Rust enum
     Rust,
+    /// The code for this enum will use a bitfield
     Bitfield,
+    /// The code for this enum will use consts
     Consts,
+    /// The code for this enum will use a module containing consts
     ModuleConsts
 }
 
 impl EnumVariation {
     fn is_rust(&self) -> bool {
         match *self {
             EnumVariation::Rust => true,
             _ => false
         }
     }
 
     fn is_bitfield(&self) -> bool {
         match *self {
-            EnumVariation::Bitfield => true,
+            EnumVariation::Bitfield {..} => true,
             _ => false
         }
     }
 
     /// Both the `Const` and `ModuleConsts` variants will cause this to return
     /// true.
     fn is_const(&self) -> bool {
         match *self {
             EnumVariation::Consts | EnumVariation::ModuleConsts => true,
             _ => false
         }
     }
 }
 
+impl Default for EnumVariation {
+    fn default() -> EnumVariation {
+        EnumVariation::Consts
+    }
+}
+
+impl std::str::FromStr for EnumVariation {
+    type Err = std::io::Error;
+
+    /// Create a `EnumVariation` from a string.
+    fn from_str(s: &str) -> Result<Self, Self::Err> {
+        match s {
+            "rust" => Ok(EnumVariation::Rust),
+            "bitfield" => Ok(EnumVariation::Bitfield),
+            "consts" => Ok(EnumVariation::Consts),
+            "moduleconsts" => Ok(EnumVariation::ModuleConsts),
+            _ => Err(std::io::Error::new(std::io::ErrorKind::InvalidInput,
+                                         concat!("Got an invalid EnumVariation. Accepted values ",
+                                                 "are 'rust', 'bitfield', 'consts', and ",
+                                                 "'moduleconsts'."))),
+        }
+    }
+}
+
+
 /// A helper type to construct different enum variations.
 enum EnumBuilder<'a> {
     Rust {
         codegen_depth: usize,
         attrs: Vec<quote::Tokens>,
-        ident: quote::Ident,
+        ident: Term,
         tokens: quote::Tokens,
         emitted_any_variants: bool,
     },
     Bitfield {
         codegen_depth: usize,
         canonical_name: &'a str,
         tokens: quote::Tokens,
     },
@@ -2165,32 +2206,32 @@ impl<'a> EnumBuilder<'a> {
     /// the representation, and which variation it should be generated as.
     fn new(
         name: &'a str,
         attrs: Vec<quote::Tokens>,
         repr: quote::Tokens,
         enum_variation: EnumVariation,
         enum_codegen_depth: usize,
     ) -> Self {
-        let ident = quote::Ident::new(name);
+        let ident = Term::new(name, Span::call_site());
 
         match enum_variation {
             EnumVariation::Bitfield => {
                 EnumBuilder::Bitfield {
                     codegen_depth: enum_codegen_depth,
                     canonical_name: name,
                     tokens: quote! {
                         #( #attrs )*
                         pub struct #ident (pub #repr);
                     },
                 }
             }
 
             EnumVariation::Rust => {
-                let tokens = quote!{};
+                let tokens = quote!();
                 EnumBuilder::Rust {
                     codegen_depth: enum_codegen_depth + 1,
                     attrs,
                     ident,
                     tokens,
                     emitted_any_variants: false,
                 }
             }
@@ -2203,17 +2244,17 @@ impl<'a> EnumBuilder<'a> {
                             pub type #ident = #repr;
                         }
                     ],
                     codegen_depth: enum_codegen_depth,
                 }
             }
 
             EnumVariation::ModuleConsts => {
-                let ident = quote::Ident::new(CONSTIFIED_ENUM_MODULE_REPR_NAME);
+                let ident = Term::new(CONSTIFIED_ENUM_MODULE_REPR_NAME, Span::call_site());
                 let type_definition = quote! {
                     #( #attrs )*
                     pub type #ident = #repr;
                 };
 
                 EnumBuilder::ModuleConsts {
                     codegen_depth: enum_codegen_depth + 1,
                     module_name: name,
@@ -2226,16 +2267,17 @@ impl<'a> EnumBuilder<'a> {
     /// Add a variant to this enum.
     fn with_variant<'b>(
         self,
         ctx: &BindgenContext,
         variant: &EnumVariant,
         mangling_prefix: Option<&str>,
         rust_ty: quote::Tokens,
         result: &mut CodegenResult<'b>,
+        is_ty_named: bool,
     ) -> Self {
         let variant_name = ctx.rust_mangle(variant.name());
         let expr = match variant.val() {
             EnumVariantValue::Signed(v) => helpers::ast_ty::int_expr(v),
             EnumVariantValue::Unsigned(v) => helpers::ast_ty::uint_expr(v),
         };
 
         let mut doc = quote! {};
@@ -2257,29 +2299,38 @@ impl<'a> EnumBuilder<'a> {
                         #tokens
                         #doc
                         #name = #expr,
                     },
                     emitted_any_variants: true,
                 }
             }
 
-            EnumBuilder::Bitfield { .. } => {
-                let constant_name = match mangling_prefix {
-                    Some(prefix) => {
-                        Cow::Owned(format!("{}_{}", prefix, variant_name))
-                    }
-                    None => variant_name,
-                };
-
-                let ident = ctx.rust_ident(constant_name);
-                result.push(quote! {
-                    #doc
-                    pub const #ident : #rust_ty = #rust_ty ( #expr );
-                });
+            EnumBuilder::Bitfield { canonical_name, .. } => {
+                if ctx.options().rust_features().associated_const && is_ty_named {
+                    let enum_ident = ctx.rust_ident(canonical_name);
+                    let variant_ident = ctx.rust_ident(variant_name);
+                    result.push(quote! {
+                        impl #enum_ident {
+                            #doc
+                            pub const #variant_ident : #rust_ty = #rust_ty ( #expr );
+                        }
+                    });
+                } else {
+                    let ident = ctx.rust_ident(match mangling_prefix {
+                        Some(prefix) => {
+                            Cow::Owned(format!("{}_{}", prefix, variant_name))
+                        }
+                        None => variant_name,
+                    });
+                    result.push(quote! {
+                        #doc
+                        pub const #ident : #rust_ty = #rust_ty ( #expr );
+                    });
+                }
 
                 self
             }
 
             EnumBuilder::Consts {
                 ..
             } => {
                 let constant_name = match mangling_prefix {
@@ -2456,25 +2507,28 @@ impl CodeGenerator for Enum {
             (true, 8) => "i64",
             (false, 8) => "u64",
             _ => {
                 warn!("invalid enum decl: signed: {}, size: {}", signed, size);
                 "i32"
             }
         };
 
-        let variation = if self.is_bitfield(ctx, item) {
+        // ModuleConsts has higher precedence before Rust in order to avoid problems with
+        // overlapping match patterns
+        let variation = if self.is_constified_enum_module(ctx, item) {
+            EnumVariation::ModuleConsts
+        } else if self.is_bitfield(ctx, item) {
             EnumVariation::Bitfield
         } else if self.is_rustified_enum(ctx, item) {
             EnumVariation::Rust
-        } else if self.is_constified_enum_module(ctx, item) {
-            EnumVariation::ModuleConsts
+        } else if self.is_constified_enum(ctx, item) {
+            EnumVariation::Consts
         } else {
-            // We generate consts by default
-            EnumVariation::Consts
+            ctx.options().default_enum_style
         };
 
         let mut attrs = vec![];
 
         // TODO(emilio): Delegate this to the builders?
         if variation.is_rust() {
             attrs.push(attributes::repr(repr_name));
         } else if variation.is_bitfield() {
@@ -2490,28 +2544,28 @@ impl CodeGenerator for Enum {
                 &["Debug", "Copy", "Clone", "PartialEq", "Eq", "Hash"],
             ));
         }
 
         fn add_constant<'a>(
             ctx: &BindgenContext,
             enum_: &Type,
             // Only to avoid recomputing every time.
-            enum_canonical_name: &quote::Ident,
+            enum_canonical_name: &Term,
             // May be the same as "variant" if it's because the
             // enum is unnamed and we still haven't seen the
             // value.
             variant_name: &str,
-            referenced_name: &quote::Ident,
+            referenced_name: &Term,
             enum_rust_ty: quote::Tokens,
             result: &mut CodegenResult<'a>,
         ) {
             let constant_name = if enum_.name().is_some() {
                 if ctx.options().prepend_enum_name {
-                    format!("{}_{}", enum_canonical_name, variant_name)
+                    format!("{}_{}", enum_canonical_name.as_str(), variant_name)
                 } else {
                     variant_name.into()
                 }
             } else {
                 variant_name.into()
             };
             let constant_name = ctx.rust_ident(constant_name);
 
@@ -2530,17 +2584,17 @@ impl CodeGenerator for Enum {
             &name,
             attrs,
             repr,
             variation,
             item.codegen_depth(ctx),
         );
 
         // A map where we keep a value -> variant relation.
-        let mut seen_values = HashMap::<_, quote::Ident>::new();
+        let mut seen_values = HashMap::<_, Term>::new();
         let enum_rust_ty = item.to_rust_ty_or_opaque(ctx, &());
         let is_toplevel = item.is_toplevel(ctx);
 
         // Used to mangle the constants we generate in the unnamed-enum case.
         let parent_canonical_name = if is_toplevel {
             None
         } else {
             Some(item.parent_id().canonical_name(ctx))
@@ -2602,63 +2656,66 @@ impl CodeGenerator for Enum {
                         );
                     } else {
                         builder = builder.with_variant(
                             ctx,
                             variant,
                             constant_mangling_prefix,
                             enum_rust_ty.clone(),
                             result,
+                            enum_ty.name().is_some(),
                         );
                     }
                 }
                 Entry::Vacant(entry) => {
                     builder = builder.with_variant(
                         ctx,
                         variant,
                         constant_mangling_prefix,
                         enum_rust_ty.clone(),
                         result,
+                        enum_ty.name().is_some(),
                     );
 
                     let variant_name = ctx.rust_ident(variant.name());
 
                     // If it's an unnamed enum, or constification is enforced,
                     // we also generate a constant so it can be properly
                     // accessed.
                     if (variation.is_rust() && enum_ty.name().is_none()) ||
                         variant.force_constification()
                     {
                         let mangled_name = if is_toplevel {
                             variant_name.clone()
                         } else {
                             let parent_name =
                                 parent_canonical_name.as_ref().unwrap();
 
-                            quote::Ident::new(
-                                format!(
+                            Term::new(
+                                &format!(
                                     "{}_{}",
                                     parent_name,
-                                    variant_name
-                                )
+                                    variant_name.as_str()
+                                ),
+                                Span::call_site()
                             )
                         };
 
                         add_constant(
                             ctx,
                             enum_ty,
                             &ident,
-                            mangled_name.as_ref(),
+                            mangled_name.as_str(),
                             &variant_name,
                             enum_rust_ty.clone(),
                             result,
                         );
                     }
 
-                    entry.insert(quote::Ident::new(variant_name));
+                    entry.insert(variant_name);
                 }
             }
         }
 
         let item = builder.build(ctx, enum_rust_ty, result);
         result.push(item);
     }
 }
@@ -2697,19 +2754,18 @@ trait TryToOpaque {
 /// last resort, because C++ does not permit zero-sized types. See the note in
 /// the `ToRustTyOrOpaque` doc comment about fallible versus infallible traits
 /// and when each is appropriate.
 ///
 /// Don't implement this directly. Instead implement `TryToOpaque`, and then
 /// leverage the blanket impl for this trait.
 trait ToOpaque: TryToOpaque {
     fn get_layout(&self, ctx: &BindgenContext, extra: &Self::Extra) -> Layout {
-        self.try_get_layout(ctx, extra).unwrap_or_else(
-            |_| Layout::for_size(1),
-        )
+        self.try_get_layout(ctx, extra)
+            .unwrap_or_else(|_| Layout::for_size(ctx, 1))
     }
 
     fn to_opaque(
         &self,
         ctx: &BindgenContext,
         extra: &Self::Extra,
     ) -> quote::Tokens {
         let layout = self.get_layout(ctx, extra);
@@ -2946,17 +3002,17 @@ impl TryToRustTy for Type {
                         Ok(quote! { [u64; 2] })
                     }
                 }
             }
             TypeKind::Float(fk) => Ok(float_kind_rust_type(ctx, fk)),
             TypeKind::Complex(fk) => {
                 let float_path = float_kind_rust_type(ctx, fk);
 
-                ctx.generated_bindegen_complex();
+                ctx.generated_bindgen_complex();
                 Ok(if ctx.options().enable_cxx_namespaces {
                     quote! {
                         root::__BindgenComplex<#float_path>
                     }
                 } else {
                     quote! {
                         __BindgenComplex<#float_path>
                     }
@@ -2976,29 +3032,27 @@ impl TryToRustTy for Type {
             }
             TypeKind::Array(item, len) => {
                 let ty = item.try_to_rust_ty(ctx, &())?;
                 Ok(quote! {
                     [ #ty ; #len ]
                 })
             }
             TypeKind::Enum(..) => {
-                let mut tokens = quote! {};
                 let path = item.namespace_aware_canonical_path(ctx);
-                tokens.append_separated(path.into_iter().map(quote::Ident::new), "::");
-                Ok(tokens)
+                let path = Term::new(&path.join("::"), Span::call_site());
+                Ok(quote!(#path))
             }
             TypeKind::TemplateInstantiation(ref inst) => {
                 inst.try_to_rust_ty(ctx, item)
             }
             TypeKind::ResolvedTypeRef(inner) => inner.try_to_rust_ty(ctx, &()),
             TypeKind::TemplateAlias(..) |
             TypeKind::Alias(..) => {
                 let template_params = item.used_template_params(ctx)
-                    .unwrap_or(vec![])
                     .into_iter()
                     .filter(|param| param.is_template_param(ctx, &()))
                     .collect::<Vec<_>>();
 
                 let spelling = self.name().expect("Unnamed alias?");
                 if item.is_opaque(ctx, &()) && !template_params.is_empty() {
                     self.try_to_opaque(ctx, item)
                 } else if let Some(ty) = utils::type_from_named(
@@ -3007,36 +3061,36 @@ impl TryToRustTy for Type {
                 )
                 {
                     Ok(ty)
                 } else {
                     utils::build_path(item, ctx)
                 }
             }
             TypeKind::Comp(ref info) => {
-                let template_params = item.used_template_params(ctx);
+                let template_params = item.all_template_params(ctx);
                 if info.has_non_type_template_params() ||
-                    (item.is_opaque(ctx, &()) && template_params.is_some())
+                    (item.is_opaque(ctx, &()) && !template_params.is_empty())
                 {
                     return self.try_to_opaque(ctx, item);
                 }
 
                 utils::build_path(item, ctx)
             }
             TypeKind::Opaque => self.try_to_opaque(ctx, item),
             TypeKind::BlockPointer => {
                 let void = raw_type(ctx, "c_void");
                 Ok(void.to_ptr(
                     /* is_const = */
                     false
                 ))
             }
             TypeKind::Pointer(inner) |
             TypeKind::Reference(inner) => {
-                let is_const = self.is_const() || ctx.resolve_type(inner).is_const();
+                let is_const = ctx.resolve_type(inner).is_const();
 
                 let inner = inner.into_resolver().through_type_refs().resolve(ctx);
                 let inner_ty = inner.expect_type();
 
                 // Regardless if we can properly represent the inner type, we
                 // should always generate a proper pointer here, so use
                 // infallible conversion of the inner type.
                 let mut ty = inner.to_rust_ty_or_opaque(ctx, &());
@@ -3101,30 +3155,28 @@ impl TryToRustTy for TemplateInstantiati
 
         let def = self.template_definition()
             .into_resolver()
             .through_type_refs()
             .resolve(ctx);
 
         let mut ty = quote! {};
         let def_path = def.namespace_aware_canonical_path(ctx);
-        ty.append_separated(def_path.into_iter().map(|p| ctx.rust_ident(p)), "::");
-
-        let def_params = match def.self_template_params(ctx) {
-            Some(params) => params,
-            None => {
-                // This can happen if we generated an opaque type for a partial
-                // template specialization, and we've hit an instantiation of
-                // that partial specialization.
-                extra_assert!(
-                    def.is_opaque(ctx, &())
-                );
-                return Err(error::Error::InstantiationOfOpaqueType);
-            }
-        };
+        ty.append_separated(def_path.into_iter().map(|p| ctx.rust_ident(p)), Term::new("::", Span::call_site()));
+
+        let def_params = def.self_template_params(ctx);
+        if def_params.is_empty() {
+            // This can happen if we generated an opaque type for a partial
+            // template specialization, and we've hit an instantiation of
+            // that partial specialization.
+            extra_assert!(
+                def.is_opaque(ctx, &())
+            );
+            return Err(error::Error::InstantiationOfOpaqueType);
+        }
 
         // TODO: If the definition type is a template class/struct
         // definition's member template definition, it could rely on
         // generic template parameters from its outer template
         // class/struct. When we emit bindings for it, it could require
         // *more* type arguments than we have here, and we will need to
         // reconstruct them somehow. We don't have any means of doing
         // that reconstruction at this time.
@@ -3162,17 +3214,17 @@ impl TryToRustTy for FunctionSig {
         _: &(),
     ) -> error::Result<quote::Tokens> {
         // TODO: we might want to consider ignoring the reference return value.
         let ret = utils::fnsig_return_ty(ctx, &self);
         let arguments = utils::fnsig_arguments(ctx, &self);
         let abi = self.abi();
 
         match abi {
-            Abi::ThisCall if !ctx.options().rust_features().thiscall_abi() => {
+            Abi::ThisCall if !ctx.options().rust_features().thiscall_abi => {
                 warn!("Skipping function with thiscall ABI that isn't supported by the configured Rust target");
                 Ok(quote::Tokens::new())
             }
             _ => {
                 Ok(quote! {
                     unsafe extern #abi fn ( #( #arguments ),* ) #ret
                 })
             }
@@ -3207,21 +3259,18 @@ impl CodeGenerator for Function {
             }
             _ => {},
         }
 
         // Similar to static member variables in a class template, we can't
         // generate bindings to template functions, because the set of
         // instantiations is open ended and we have no way of knowing which
         // monomorphizations actually exist.
-        let type_params = item.all_template_params(ctx);
-        if let Some(params) = type_params {
-            if !params.is_empty() {
-                return;
-            }
+        if !item.all_template_params(ctx).is_empty() {
+            return;
         }
 
         let name = self.name();
         let mut canonical_name = item.canonical_name(ctx);
         let mangled_name = self.mangled_name();
 
         {
             let seen_symbol_name = mangled_name.unwrap_or(&canonical_name);
@@ -3259,17 +3308,17 @@ impl CodeGenerator for Function {
         // Handle overloaded functions by giving each overload its own unique
         // suffix.
         let times_seen = result.overload_number(&canonical_name);
         if times_seen > 0 {
             write!(&mut canonical_name, "{}", times_seen).unwrap();
         }
 
         let abi = match signature.abi() {
-            Abi::ThisCall if !ctx.options().rust_features().thiscall_abi() => {
+            Abi::ThisCall if !ctx.options().rust_features().thiscall_abi => {
                 warn!("Skipping function with thiscall ABI that isn't supported by the configured Rust target");
                 return;
             }
             Abi::Unknown(unknown_abi) => {
                 panic!(
                     "Invalid or unknown abi {:?} for function {:?} ({:?})",
                     unknown_abi,
                     canonical_name,
@@ -3314,17 +3363,17 @@ fn objc_method_codegen(
     };
 
     let methods_and_args = method.format_method_call(&fn_args);
 
     let body = if method.is_class_method() {
         let class_name = class_name
             .expect("Generating a class method without class name?")
             .to_owned();
-        let expect_msg = format!("Couldn't find {}", class_name);
+        let expect_msg = proc_macro2::Literal::string(&format!("Couldn't find {}", class_name));
         quote! {
             msg_send!(objc::runtime::Class::get(#class_name).expect(#expect_msg), #methods_and_args)
         }
     } else {
         quote! {
             msg_send!(self, #methods_and_args)
         }
     };
@@ -3440,21 +3489,22 @@ pub(crate) fn codegen(context: BindgenCo
 
 mod utils {
     use super::{ToRustTyOrOpaque, error};
     use ir::context::BindgenContext;
     use ir::function::FunctionSig;
     use ir::item::{Item, ItemCanonicalPath};
     use ir::ty::TypeKind;
     use quote;
+    use proc_macro2::{Term, Span};
     use std::mem;
 
     pub fn prepend_bitfield_unit_type(result: &mut Vec<quote::Tokens>) {
-        let mut bitfield_unit_type = quote! {};
-        bitfield_unit_type.append(include_str!("./bitfield_unit.rs"));
+        let bitfield_unit_type = Term::new(include_str!("./bitfield_unit.rs"), Span::call_site());
+        let bitfield_unit_type = quote!(#bitfield_unit_type);
 
         let items = vec![bitfield_unit_type];
         let old_items = mem::replace(result, items);
         result.extend(old_items);
     }
 
     pub fn prepend_objc_header(
         ctx: &BindgenContext,
@@ -3670,20 +3720,22 @@ mod utils {
         let old_items = mem::replace(result, items);
         result.extend(old_items.into_iter());
     }
 
     pub fn build_path(
         item: &Item,
         ctx: &BindgenContext,
     ) -> error::Result<quote::Tokens> {
+        use proc_macro2::{Term, Span};
+
         let path = item.namespace_aware_canonical_path(ctx);
-
-        let mut tokens = quote! {};
-        tokens.append_separated(path.into_iter().map(quote::Ident::new), "::");
+        let path = Term::new(&path.join("::"), Span::call_site());
+        let tokens = quote! {#path};
+        //tokens.append_separated(path, "::");
 
         Ok(tokens)
     }
 
     fn primitive_ty(ctx: &BindgenContext, name: &str) -> quote::Tokens {
         let ident = ctx.rust_ident_raw(name);
         quote! {
             #ident
--- a/third_party/rust/bindgen/src/codegen/struct_layout.rs
+++ b/third_party/rust/bindgen/src/codegen/struct_layout.rs
@@ -2,18 +2,18 @@
 
 use super::helpers;
 
 use ir::comp::CompInfo;
 use ir::context::BindgenContext;
 use ir::layout::Layout;
 use ir::ty::{Type, TypeKind};
 use quote;
+use proc_macro2::{Term, Span};
 use std::cmp;
-use std::mem;
 
 /// Trace the layout of struct.
 #[derive(Debug)]
 pub struct StructLayoutTracker<'a> {
     name: &'a str,
     ctx: &'a BindgenContext,
     comp: &'a CompInfo,
     is_packed: bool,
@@ -96,17 +96,17 @@ impl<'a> StructLayoutTracker<'a> {
             max_field_align: 0,
             last_field_was_bitfield: false,
         }
     }
 
     pub fn saw_vtable(&mut self) {
         debug!("saw vtable for {}", self.name);
 
-        let ptr_size = mem::size_of::<*mut ()>();
+        let ptr_size = self.ctx.target_pointer_size();
         self.latest_offset += ptr_size;
         self.latest_field_layout = Some(Layout::new(ptr_size, ptr_size));
         self.max_field_align = ptr_size;
     }
 
     pub fn saw_base(&mut self, base_ty: &Type) {
         debug!("saw base for {}", self.name);
         if let Some(layout) = base_ty.layout(self.ctx) {
@@ -160,25 +160,23 @@ impl<'a> StructLayoutTracker<'a> {
         if let TypeKind::Array(inner, len) =
             *field_ty.canonical_type(self.ctx).kind()
         {
             // FIXME(emilio): As an _ultra_ hack, we correct the layout returned
             // by arrays of structs that have a bigger alignment than what we
             // can support.
             //
             // This means that the structs in the array are super-unsafe to
-            // access, since they won't be properly aligned, but *shrug*.
-            if let Some(layout) = self.ctx.resolve_type(inner).layout(
-                self.ctx,
-            )
-            {
-                if layout.align > mem::size_of::<*mut ()>() {
-                    field_layout.size = align_to(layout.size, layout.align) *
-                        len;
-                    field_layout.align = mem::size_of::<*mut ()>();
+            // access, since they won't be properly aligned, but there's not too
+            // much we can do about it.
+            if let Some(layout) = self.ctx.resolve_type(inner).layout(self.ctx) {
+                if layout.align > self.ctx.target_pointer_size() {
+                    field_layout.size =
+                        align_to(layout.size, layout.align) * len;
+                    field_layout.align = self.ctx.target_pointer_size();
                 }
             }
         }
 
         let will_merge_with_bitfield = self.align_to_latest_field(field_layout);
 
         let padding_layout = if self.is_packed {
             None
@@ -188,17 +186,17 @@ impl<'a> StructLayoutTracker<'a> {
                     offset / 8 - self.latest_offset
                 }
                 _ if will_merge_with_bitfield || field_layout.align == 0 => 0,
                 _ => self.padding_bytes(field_layout),
             };
 
             // Otherwise the padding is useless.
             let need_padding = padding_bytes >= field_layout.align ||
-                field_layout.align > mem::size_of::<*mut ()>();
+                field_layout.align > self.ctx.target_pointer_size();
 
             self.latest_offset += padding_bytes;
 
             debug!(
                 "Offset: <padding>: {} -> {}",
                 self.latest_offset - padding_bytes,
                 self.latest_offset
             );
@@ -210,17 +208,17 @@ impl<'a> StructLayoutTracker<'a> {
                 field_offset.unwrap_or(0) / 8,
                 padding_bytes,
                 field_layout
             );
 
             if need_padding && padding_bytes != 0 {
                 Some(Layout::new(
                     padding_bytes,
-                    cmp::min(field_layout.align, mem::size_of::<*mut ()>()),
+                    cmp::min(field_layout.align, self.ctx.target_pointer_size())
                 ))
             } else {
                 None
             }
         };
 
         self.latest_offset += field_layout.size;
         self.latest_field_layout = Some(field_layout);
@@ -262,53 +260,63 @@ impl<'a> StructLayoutTracker<'a> {
         // Note that if the last field we saw was a bitfield, we may need to pad
         // regardless, because bitfields don't respect alignment as strictly as
         // other fields.
         if padding_bytes > 0 &&
             (padding_bytes >= layout.align ||
                  (self.last_field_was_bitfield &&
                       padding_bytes >=
                           self.latest_field_layout.unwrap().align) ||
-                 layout.align > mem::size_of::<*mut ()>())
+                 layout.align > self.ctx.target_pointer_size())
         {
             let layout = if self.is_packed {
                 Layout::new(padding_bytes, 1)
             } else if self.last_field_was_bitfield ||
-                       layout.align > mem::size_of::<*mut ()>()
+                       layout.align > self.ctx.target_pointer_size()
             {
                 // We've already given up on alignment here.
-                Layout::for_size(padding_bytes)
+                Layout::for_size(self.ctx, padding_bytes)
             } else {
                 Layout::new(padding_bytes, layout.align)
             };
 
             debug!("pad bytes to struct {}, {:?}", self.name, layout);
 
             Some(self.padding_field(layout))
         } else {
             None
         }
     }
 
     pub fn requires_explicit_align(&self, layout: Layout) -> bool {
-        self.max_field_align < layout.align &&
-            layout.align <= mem::size_of::<*mut ()>()
+        if self.max_field_align >= layout.align {
+            return false;
+        }
+        // At this point we require explicit alignment, but we may not be able
+        // to generate the right bits, let's double check.
+        if self.ctx.options().rust_features().repr_align {
+            return true;
+        }
+
+        // We can only generate up-to a word of alignment unless we support
+        // repr(align).
+        layout.align <= self.ctx.target_pointer_size()
     }
 
     fn padding_bytes(&self, layout: Layout) -> usize {
         align_to(self.latest_offset, layout.align) - self.latest_offset
     }
 
     fn padding_field(&mut self, layout: Layout) -> quote::Tokens {
         let ty = helpers::blob(layout);
         let padding_count = self.padding_count;
 
         self.padding_count += 1;
 
-        let padding_field_name = quote::Ident::new(format!("__bindgen_padding_{}", padding_count));
+        let padding_field_name = Term::new(&format!("__bindgen_padding_{}", padding_count), Span::call_site());
 
         self.max_field_align = cmp::max(self.max_field_align, layout.align);
 
         quote! {
             pub #padding_field_name : #ty ,
         }
     }
 
--- a/third_party/rust/bindgen/src/features.rs
+++ b/third_party/rust/bindgen/src/features.rs
@@ -85,18 +85,22 @@ macro_rules! rust_target_values_def {
 /// Defines macro which takes a macro
 macro_rules! rust_target_base {
     ( $x_macro:ident ) => {
         $x_macro!(
             /// Rust stable 1.0
             => Stable_1_0 => 1.0;
             /// Rust stable 1.19
             => Stable_1_19 => 1.19;
+            /// Rust stable 1.20
+            => Stable_1_20 => 1.20;
             /// Rust stable 1.21
             => Stable_1_21 => 1.21;
+            /// Rust stable 1.25
+            => Stable_1_25 => 1.25;
             /// Nightly rust
             => Nightly => nightly;
         );
     }
 }
 
 rust_target_base!(rust_target_def);
 rust_target_base!(rust_target_values_def);
@@ -106,63 +110,69 @@ pub const LATEST_STABLE_RUST: RustTarget
 
 /// Create RustFeatures struct definition, new(), and a getter for each field
 macro_rules! rust_feature_def {
     ( $( $( #[$attr:meta] )* => $feature:ident; )* ) => {
         /// Features supported by a rust target
         #[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
         pub struct RustFeatures {
             $(
-                $feature: bool,
+                $(
+                    #[$attr]
+                )*
+                pub $feature: bool,
             )*
         }
 
         impl RustFeatures {
             /// Gives a RustFeatures struct with all features disabled
             fn new() -> Self {
                 RustFeatures {
                     $(
                         $feature: false,
                     )*
                 }
             }
-
-            $(
-                $(
-                    #[$attr]
-                )*
-                pub fn $feature(&self) -> bool {
-                    self.$feature
-                }
-            )*
         }
     }
 }
 
 rust_feature_def!(
     /// Untagged unions ([RFC 1444](https://github.com/rust-lang/rfcs/blob/master/text/1444-union.md))
     => untagged_union;
     /// `thiscall` calling convention ([Tracking issue](https://github.com/rust-lang/rust/issues/42202))
     => thiscall_abi;
     /// builtin impls for `Clone` ([PR](https://github.com/rust-lang/rust/pull/43690))
     => builtin_clone_impls;
+    /// repr(align) https://github.com/rust-lang/rust/pull/47006
+    => repr_align;
+    /// associated constants https://github.com/rust-lang/rust/issues/29646
+    => associated_const;
 );
 
 impl From<RustTarget> for RustFeatures {
     fn from(rust_target: RustTarget) -> Self {
         let mut features = RustFeatures::new();
 
         if rust_target >= RustTarget::Stable_1_19 {
             features.untagged_union = true;
         }
 
+        if rust_target >= RustTarget::Stable_1_20 {
+            features.associated_const = true;
+        }
+
         if rust_target >= RustTarget::Stable_1_21 {
             features.builtin_clone_impls = true;
         }
 
+        if rust_target >= RustTarget::Stable_1_25 {
+            features.repr_align = true;
+        }
+
         if rust_target >= RustTarget::Nightly {
             features.thiscall_abi = true;
         }
 
         features
     }
 }
 
@@ -184,11 +194,12 @@ mod test {
         assert_eq!(target, RustTarget::from_str(target_str).unwrap());
     }
 
     #[test]
     fn str_to_target() {
         test_target("1.0", RustTarget::Stable_1_0);
         test_target("1.19", RustTarget::Stable_1_19);
         test_target("1.21", RustTarget::Stable_1_21);
+        test_target("1.25", RustTarget::Stable_1_25);
         test_target("nightly", RustTarget::Nightly);
     }
 }
--- a/third_party/rust/bindgen/src/ir/analysis/derive_copy.rs
+++ b/third_party/rust/bindgen/src/ir/analysis/derive_copy.rs
@@ -229,30 +229,30 @@ impl<'ctx> MonotoneFramework for CannotD
                 // default, the may have an explicit destructor in C++, so we can't
                 // defer this check just for the union case.
                 if self.ctx.lookup_has_destructor(id.expect_type_id(self.ctx)) {
                     trace!("    comp has destructor which cannot derive copy");
                     return self.insert(id);
                 }
 
                 if info.kind() == CompKind::Union {
-                    if !self.ctx.options().rust_features().untagged_union() {
+                    if !self.ctx.options().rust_features().untagged_union {
                         // NOTE: If there's no template parameters we can derive
                         // copy unconditionally, since arrays are magical for
                         // rustc, and __BindgenUnionField always implements
                         // copy.
                         trace!(
                             "    comp can always derive debug if it's a Union and no template parameters"
                         );
                         return ConstrainResult::Same;
                     }
 
                     // https://github.com/rust-lang/rust/issues/36640
-                    if info.self_template_params(self.ctx).is_some() ||
-                        item.used_template_params(self.ctx).is_some()
+                    if !info.self_template_params(self.ctx).is_empty() ||
+                        !item.all_template_params(self.ctx).is_empty()
                     {
                         trace!(
                             "    comp cannot derive copy because issue 36640"
                         );
                         return self.insert(id);
                     }
                 }
 
--- a/third_party/rust/bindgen/src/ir/analysis/derive_debug.rs
+++ b/third_party/rust/bindgen/src/ir/analysis/derive_debug.rs
@@ -145,17 +145,17 @@ impl<'ctx> MonotoneFramework for CannotD
         };
 
         if item.is_opaque(self.ctx, &()) {
             let layout_can_derive = ty.layout(self.ctx).map_or(true, |l| {
                 l.opaque().can_trivially_derive_debug()
             });
             return if layout_can_derive &&
                       !(ty.is_union() &&
-                        self.ctx.options().rust_features().untagged_union()) {
+                        self.ctx.options().rust_features().untagged_union) {
                 trace!("    we can trivially derive Debug for the layout");
                 ConstrainResult::Same
             } else {
                 trace!("    we cannot derive Debug for the layout");
                 self.insert(id)
             };
         }
 
@@ -230,17 +230,17 @@ impl<'ctx> MonotoneFramework for CannotD
 
             TypeKind::Comp(ref info) => {
                 assert!(
                     !info.has_non_type_template_params(),
                     "The early ty.is_opaque check should have handled this case"
                 );
 
                 if info.kind() == CompKind::Union {
-                    if self.ctx.options().rust_features().untagged_union() {
+                    if self.ctx.options().rust_features().untagged_union {
                         trace!("    cannot derive Debug for Rust unions");
                         return self.insert(id);
                     }
 
                     if ty.layout(self.ctx).map_or(true, |l| {
                         l.opaque().can_trivially_derive_debug()
                     })
                     {
--- a/third_party/rust/bindgen/src/ir/analysis/derive_default.rs
+++ b/third_party/rust/bindgen/src/ir/analysis/derive_default.rs
@@ -172,17 +172,17 @@ impl<'ctx> MonotoneFramework for CannotD
         };
 
         if item.is_opaque(self.ctx, &()) {
             let layout_can_derive = ty.layout(self.ctx).map_or(true, |l| {
                 l.opaque().can_trivially_derive_default()
             });
             return if layout_can_derive &&
                       !(ty.is_union() &&
-                        self.ctx.options().rust_features().untagged_union()) {
+                        self.ctx.options().rust_features().untagged_union) {
                 trace!("    we can trivially derive Default for the layout");
                 ConstrainResult::Same
             } else {
                 trace!("    we cannot derive Default for the layout");
                 self.insert(id)
             };
         }
 
@@ -266,17 +266,17 @@ impl<'ctx> MonotoneFramework for CannotD
                 );
 
                 if info.is_forward_declaration() {
                     trace!("    cannot derive Default for forward decls");
                     return self.insert(id);
                 }
 
                 if info.kind() == CompKind::Union {
-                    if self.ctx.options().rust_features().untagged_union() {
+                    if self.ctx.options().rust_features().untagged_union {
                         trace!("    cannot derive Default for Rust unions");
                         return self.insert(id);
                     }
 
                     if ty.layout(self.ctx).map_or(true, |l| {
                         l.opaque().can_trivially_derive_default()
                     })
                     {
--- a/third_party/rust/bindgen/src/ir/analysis/derive_hash.rs
+++ b/third_party/rust/bindgen/src/ir/analysis/derive_hash.rs
@@ -132,17 +132,17 @@ impl<'ctx> MonotoneFramework for CannotD
         }
 
         if item.is_opaque(self.ctx, &()) {
             let layout_can_derive = ty.layout(self.ctx).map_or(true, |l| {
                 l.opaque().can_trivially_derive_hash()
             });
             return if layout_can_derive &&
                 !(ty.is_union() &&
-                  self.ctx.options().rust_features().untagged_union()) {
+                  self.ctx.options().rust_features().untagged_union) {
                 trace!("    we can trivially derive Hash for the layout");
                 ConstrainResult::Same
             } else {
                 trace!("    we cannot derive Hash for the layout");
                 self.insert(id)
             };
         }
 
@@ -252,17 +252,17 @@ impl<'ctx> MonotoneFramework for CannotD
                 );
 
                 if info.is_forward_declaration() {
                     trace!("    cannot derive Hash for forward decls");
                     return self.insert(id);
                 }
 
                 if info.kind() == CompKind::Union {
-                    if self.ctx.options().rust_features().untagged_union() {
+                    if self.ctx.options().rust_features().untagged_union {
                         trace!("    cannot derive Hash for Rust unions");
                         return self.insert(id);
                     }
 
                     if ty.layout(self.ctx).map_or(true, |l| {
                         l.opaque().can_trivially_derive_hash()
                     })
                     {
--- a/third_party/rust/bindgen/src/ir/analysis/derive_partialeq_or_partialord.rs
+++ b/third_party/rust/bindgen/src/ir/analysis/derive_partialeq_or_partialord.rs
@@ -114,17 +114,17 @@ impl<'ctx> CannotDerivePartialEqOrPartia
 
         if self.ctx.no_partialeq_by_name(&item) {
             return CanDerive::No;
         }
 
         trace!("ty: {:?}", ty);
         if item.is_opaque(self.ctx, &()) {
             if ty.is_union()
-                && self.ctx.options().rust_features().untagged_union()
+                && self.ctx.options().rust_features().untagged_union
             {
                 trace!(
                     "    cannot derive `PartialEq`/`PartialOrd` for Rust unions"
                 );
                 return CanDerive::No;
             }
 
             let layout_can_derive = ty.layout(self.ctx)
@@ -237,17 +237,17 @@ impl<'ctx> CannotDerivePartialEqOrPartia
                 );
 
                 if info.is_forward_declaration() {
                     trace!("    cannot derive for forward decls");
                     return CanDerive::No;
                 }
 
                 if info.kind() == CompKind::Union {
-                    if self.ctx.options().rust_features().untagged_union() {
+                    if self.ctx.options().rust_features().untagged_union {
                         trace!(
                             "    cannot derive `PartialEq`/`PartialOrd` for Rust unions"
                         );
                         return CanDerive::No;
                     }
 
                     let layout_can_derive =
                         ty.layout(self.ctx).map_or(CanDerive::Yes, |l| {
--- a/third_party/rust/bindgen/src/ir/analysis/template_params.rs
+++ b/third_party/rust/bindgen/src/ir/analysis/template_params.rs
@@ -270,17 +270,17 @@ impl<'ctx> UsedTemplateParameters<'ctx> 
         used_by_this_id: &mut ItemSet,
         instantiation: &TemplateInstantiation,
     ) {
         trace!("    template instantiation");
 
         let decl = self.ctx.resolve_type(instantiation.template_definition());
         let args = instantiation.template_arguments();
 
-        let params = decl.self_template_params(self.ctx).unwrap_or(vec![]);
+        let params = decl.self_template_params(self.ctx);
 
         debug_assert!(this_id != instantiation.template_definition());
         let used_by_def = self.used
             .get(&instantiation.template_definition().into())
             .expect("Should have a used entry for instantiation's template definition")
             .as_ref()
             .expect("And it should be Some because only this_id's set is None, and an \
                      instantiation's template definition should never be the \
@@ -414,17 +414,17 @@ impl<'ctx> MonotoneFramework for UsedTem
                 &TypeKind::TemplateInstantiation(ref inst) => {
                     let decl = ctx.resolve_type(inst.template_definition());
                     let args = inst.template_arguments();
 
                     // Although template definitions should always have
                     // template parameters, there is a single exception:
                     // opaque templates. Hence the unwrap_or.
                     let params =
-                        decl.self_template_params(ctx).unwrap_or(vec![]);
+                        decl.self_template_params(ctx);
 
                     for (arg, param) in args.iter().zip(params.iter()) {
                         let arg = arg.into_resolver()
                             .through_type_aliases()
                             .through_type_refs()
                             .resolve(ctx)
                             .id();
 
--- a/third_party/rust/bindgen/src/ir/comment.rs
+++ b/third_party/rust/bindgen/src/ir/comment.rs
@@ -34,17 +34,17 @@ fn kind(comment: &str) -> Option<Kind> {
 }
 
 fn make_indent(indent: usize) -> String {
     const RUST_INDENTATION: usize = 4;
 
     iter::repeat(' ').take(indent * RUST_INDENTATION).collect()
 }
 
-/// Preprocesses mulitple single line comments.
+/// Preprocesses multiple single line comments.
 ///
 /// Handles lines starting with both `//` and `///`.
 fn preprocess_single_lines(comment: &str, indent: usize) -> String {
     debug_assert!(comment.starts_with("//"), "comment is not single line");
 
     let indent = make_indent(indent);
     let mut is_first = true;
     let lines: Vec<_> = comment
--- a/third_party/rust/bindgen/src/ir/comp.rs
+++ b/third_party/rust/bindgen/src/ir/comp.rs
@@ -1285,19 +1285,20 @@ impl CompInfo {
                     //
                     // [1]: https://github.com/rust-lang-nursery/rust-bindgen/issues/482
                     let is_inner_struct = cur.semantic_parent() == cursor ||
                                           cur.is_definition();
                     if !is_inner_struct {
                         return CXChildVisit_Continue;
                     }
 
+                    // Even if this is a definition, we may not be the semantic
+                    // parent, see #1281.
                     let inner = Item::parse(cur, Some(potential_id), ctx)
                         .expect("Inner ClassDecl");
-                    assert_eq!(ctx.resolve_item(inner).parent_id(), potential_id);
 
                     let inner = inner.expect_type_id(ctx);
 
                     ci.inner_types.push(inner);
 
                     // A declaration of an union or a struct without name could
                     // also be an unnamed field, unfortunately.
                     if cur.spelling().is_empty() &&
@@ -1350,17 +1351,17 @@ impl CompInfo {
 
                     // This used to not be here, but then I tried generating
                     // stylo bindings with this (without path filters), and
                     // cried a lot with a method in gfx/Point.h
                     // (ToUnknownPoint), that somehow was causing the same type
                     // to be inserted in the map two times.
                     //
                     // I couldn't make a reduced test case, but anyway...
-                    // Methods of template functions not only use to be inlined,
+                    // Methods of template functions not only used to be inlined,
                     // but also instantiated, and we wouldn't be able to call
                     // them, so just bail out.
                     if !ci.template_params.is_empty() {
                         return CXChildVisit_Continue;
                     }
 
                     // NB: This gets us an owned `Function`, not a
                     // `FunctionSig`.
@@ -1538,17 +1539,17 @@ impl CompInfo {
     }
 
     /// Returns whether the current union can be represented as a Rust `union`
     ///
     /// Requirements:
     ///     1. Current RustTarget allows for `untagged_union`
     ///     2. Each field can derive `Copy`
     pub fn can_be_rust_union(&self, ctx: &BindgenContext) -> bool {
-        if !ctx.options().rust_features().untagged_union() {
+        if !ctx.options().rust_features().untagged_union {
             return false;
         }
 
         if self.is_forward_declaration() {
             return false;
         }
 
         self.fields().iter().all(|f| match *f {
@@ -1663,34 +1664,29 @@ impl IsOpaque for CompInfo {
         false
     }
 }
 
 impl TemplateParameters for CompInfo {
     fn self_template_params(
         &self,
         _ctx: &BindgenContext,
-    ) -> Option<Vec<TypeId>> {
-        if self.template_params.is_empty() {
-            None
-        } else {
-            Some(self.template_params.clone())
-        }
+    ) -> Vec<TypeId> {
+        self.template_params.clone()
     }
 }
 
 impl Trace for CompInfo {
     type Extra = Item;
 
     fn trace<T>(&self, context: &BindgenContext, tracer: &mut T, item: &Item)
     where
         T: Tracer,
     {
-        let params = item.all_template_params(context).unwrap_or(vec![]);
-        for p in params {
+        for p in item.all_template_params(context) {
             tracer.visit_kind(p.into(), EdgeKind::TemplateParameterDefinition);
         }
 
         for ty in self.inner_types() {
             tracer.visit_kind(ty.into(), EdgeKind::InnerType);
         }
 
         for &var in self.inner_vars() {
--- a/third_party/rust/bindgen/src/ir/context.rs
+++ b/third_party/rust/bindgen/src/ir/context.rs
@@ -19,17 +19,17 @@ use super::ty::{FloatKind, Type, TypeKin
 use super::function::Function;
 use super::super::time::Timer;
 use BindgenOptions;
 use callbacks::ParseCallbacks;
 use cexpr;
 use clang::{self, Cursor};
 use clang_sys;
 use parse::ClangItemParser;
-use quote;
+use proc_macro2::{Term, Span};
 use std::borrow::Cow;
 use std::cell::Cell;
 use std::collections::{HashMap, HashSet, hash_map};
 use std::collections::btree_map::{self, BTreeMap};
 use std::iter::IntoIterator;
 use std::mem;
 
 /// An identifier for some kind of IR item.
@@ -361,21 +361,24 @@ pub struct BindgenContext {
     in_codegen: bool,
 
     /// The clang index for parsing.
     index: clang::Index,
 
     /// The translation unit for parsing.
     translation_unit: clang::TranslationUnit,
 
+    /// Target information that can be useful for some stuff.
+    target_info: Option<clang::TargetInfo>,
+
     /// The options given by the user via cli or other medium.
     options: BindgenOptions,
 
     /// Whether a bindgen complex was generated
-    generated_bindegen_complex: Cell<bool>,
+    generated_bindgen_complex: Cell<bool>,
 
     /// The set of `ItemId`s that are whitelisted. This the very first thing
     /// computed after parsing our IR, and before running any of our analyses.
     whitelisted: Option<ItemSet>,
 
     /// The set of `ItemId`s that are whitelisted for code generation _and_ that
     /// we should generate accounting for the codegen options.
     ///
@@ -498,16 +501,19 @@ impl<'ctx> WhitelistedItemsTraversal<'ct
     {
         WhitelistedItemsTraversal {
             ctx,
             traversal: ItemTraversal::new(ctx, roots, predicate),
         }
     }
 }
 
+const HOST_TARGET: &'static str =
+    include_str!(concat!(env!("OUT_DIR"), "/host-target.txt"));
+
 /// Returns the effective target, and whether it was explicitly specified on the
 /// clang flags.
 fn find_effective_target(clang_args: &[String]) -> (String, bool) {
     use std::env;
 
     for opt in clang_args {
         if opt.starts_with("--target=") {
             let mut split = opt.split('=');
@@ -516,18 +522,16 @@ fn find_effective_target(clang_args: &[S
         }
     }
 
     // If we're running from a build script, try to find the cargo target.
     if let Ok(t) = env::var("TARGET") {
         return (t, false)
     }
 
-    const HOST_TARGET: &'static str =
-        include_str!(concat!(env!("OUT_DIR"), "/host-target.txt"));
     (HOST_TARGET.to_owned(), false)
 }
 
 impl BindgenContext {
     /// Construct the context for the given `options`.
     pub(crate) fn new(options: BindgenOptions) -> Self {
         use clang_sys;
 
@@ -556,16 +560,27 @@ impl BindgenContext {
                 &index,
                 "",
                 &clang_args,
                 &options.input_unsaved_files,
                 parse_options,
             ).expect("TranslationUnit::parse failed")
         };
 
+        let target_info = clang::TargetInfo::new(&translation_unit);
+
+        #[cfg(debug_assertions)]
+        {
+            if let Some(ref ti) = target_info {
+                if effective_target == HOST_TARGET {
+                    assert_eq!(ti.pointer_width / 8, mem::size_of::<*mut ()>());
+                }
+            }
+        }
+
         let root_module = Self::build_root_module(ItemId(0));
         let root_module_id = root_module.id().as_module_id_unchecked();
 
         let mut me = BindgenContext {
             items: Default::default(),
             types: Default::default(),
             type_params: Default::default(),
             modules: Default::default(),
@@ -573,20 +588,21 @@ impl BindgenContext {
             root_module: root_module_id,
             current_module: root_module_id,
             semantic_parents: Default::default(),
             currently_parsed_types: vec![],
             parsed_macros: Default::default(),
             replacements: Default::default(),
             collected_typerefs: false,
             in_codegen: false,
-            index: index,
-            translation_unit: translation_unit,
-            options: options,
-            generated_bindegen_complex: Cell::new(false),
+            index,
+            translation_unit,
+            target_info,
+            options,
+            generated_bindgen_complex: Cell::new(false),
             whitelisted: None,
             codegen_items: None,
             used_template_parameters: None,
             need_bitfield_allocation: Default::default(),
             cannot_derive_debug: None,
             cannot_derive_default: None,
             cannot_derive_copy: None,
             cannot_derive_copy_in_array: None,
@@ -606,16 +622,25 @@ impl BindgenContext {
 
     /// Creates a timer for the current bindgen phase. If time_phases is `true`,
     /// the timer will print to stderr when it is dropped, otherwise it will do
     /// nothing.
     pub fn timer<'a>(&self, name: &'a str) -> Timer<'a> {
         Timer::new(name).with_output(self.options.time_phases)
     }
 
+    /// Returns the pointer width to use for the target for the current
+    /// translation.
+    pub fn target_pointer_size(&self) -> usize {
+        if let Some(ref ti) = self.target_info {
+            return ti.pointer_width / 8;
+        }
+        mem::size_of::<*mut ()>()
+    }
+
     /// Get the stack of partially parsed types that we are in the middle of
     /// parsing.
     pub fn currently_parsed_types(&self) -> &[PartialType] {
         &self.currently_parsed_types[..]
     }
 
     /// Begin parsing the given partial type, and push it onto the
     /// `currently_parsed_types` stack so that we won't infinite recurse if we
@@ -875,29 +900,29 @@ impl BindgenContext {
             s = s.replace("$", "_");
             s.push_str("_");
             return Cow::Owned(s);
         }
         Cow::Borrowed(name)
     }
 
     /// Returns a mangled name as a rust identifier.
-    pub fn rust_ident<S>(&self, name: S) -> quote::Ident
+    pub fn rust_ident<S>(&self, name: S) -> Term
     where
         S: AsRef<str>
     {
         self.rust_ident_raw(self.rust_mangle(name.as_ref()))
     }
 
     /// Returns a mangled name as a rust identifier.
-    pub fn rust_ident_raw<T>(&self, name: T) -> quote::Ident
+    pub fn rust_ident_raw<T>(&self, name: T) -> Term
     where
-        T: Into<quote::Ident>
+        T: AsRef<str>
     {
-        name.into()
+        Term::new(name.as_ref(), Span::call_site())
     }
 
     /// Iterate over all items that have been defined.
     pub fn items<'a>(&'a self) -> btree_map::Iter<'a, ItemId, Item> {
         self.items.iter()
     }
 
     /// Have we collected all unresolved type references yet?
@@ -1336,20 +1361,17 @@ impl BindgenContext {
             let used_params = analyze::<UsedTemplateParameters>(self);
             self.used_template_parameters = Some(used_params);
         } else {
             // If you aren't recursively whitelisting, then we can't really make
             // any sense of template parameter usage, and you're on your own.
             let mut used_params = HashMap::new();
             for &id in self.whitelisted_items() {
                 used_params.entry(id).or_insert(
-                    id.self_template_params(self).map_or(
-                        Default::default(),
-                        |params| params.into_iter().map(|p| p.into()).collect(),
-                    ),
+                    id.self_template_params(self).into_iter().map(|p| p.into()).collect()
                 );
             }
             self.used_template_parameters = Some(used_params);
         }
     }
 
     /// Return `true` if `item` uses the given `template_param`, `false`
     /// otherwise.
@@ -1511,36 +1533,37 @@ impl BindgenContext {
 
 
     /// Given a cursor pointing to the location of a template instantiation,
     /// return a tuple of the form `(declaration_cursor, declaration_id,
     /// num_expected_template_args)`.
     ///
     /// Note that `declaration_id` is not guaranteed to be in the context's item
     /// set! It is possible that it is a partial type that we are still in the
-    /// middle of parsign.
+    /// middle of parsing.
     fn get_declaration_info_for_template_instantiation(
         &self,
         instantiation: &Cursor,
     ) -> Option<(Cursor, ItemId, usize)> {
         instantiation
             .cur_type()
             .canonical_declaration(Some(instantiation))
             .and_then(|canon_decl| {
                 self.get_resolved_type(&canon_decl).and_then(
                     |template_decl_id| {
-                        template_decl_id.num_self_template_params(self).map(
-                            |num_params| {
-                                (
-                                    *canon_decl.cursor(),
-                                    template_decl_id.into(),
-                                    num_params,
-                                )
-                            },
-                        )
+                        let num_params = template_decl_id.num_self_template_params(self);
+                        if num_params == 0 {
+                            None
+                        } else {
+                            Some((
+                                *canon_decl.cursor(),
+                                template_decl_id.into(),
+                                num_params,
+                            ))
+                        }
                     },
                 )
             })
             .or_else(|| {
                 // If we haven't already parsed the declaration of
                 // the template being instantiated, then it *must*
                 // be on the stack of types we are currently
                 // parsing. If it wasn't then clang would have
@@ -1551,25 +1574,26 @@ impl BindgenContext {
                     .referenced()
                     .and_then(|referenced| {
                         self.currently_parsed_types()
                             .iter()
                             .find(|partial_ty| *partial_ty.decl() == referenced)
                             .cloned()
                     })
                     .and_then(|template_decl| {
-                        template_decl.num_self_template_params(self).map(
-                            |num_template_params| {
-                                (
-                                    *template_decl.decl(),
-                                    template_decl.id(),
-                                    num_template_params,
-                                )
-                            },
-                        )
+                        let num_template_params = template_decl.num_self_template_params(self);
+                        if num_template_params == 0 {
+                            None
+                        } else {
+                            Some((
+                                *template_decl.decl(),
+                                template_decl.id(),
+                                num_template_params,
+                            ))
+                        }
                     })
             })
     }
 
     /// Parse a template instantiation, eg `Foo<int>`.
     ///
     /// This is surprisingly difficult to do with libclang, due to the fact that
     /// it doesn't provide explicit template argument information, except for
@@ -1606,27 +1630,24 @@ impl BindgenContext {
         &mut self,
         with_id: ItemId,
         template: TypeId,
         ty: &clang::Type,
         location: clang::Cursor,
     ) -> Option<TypeId> {
         use clang_sys;
 
-        let num_expected_args = match self.resolve_type(template)
-            .num_self_template_params(self) {
-            Some(n) => n,
-            None => {
-                warn!(
-                    "Tried to instantiate a template for which we could not \
-                       determine any template parameters"
-                );
-                return None;
-            }
-        };
+        let num_expected_args = self.resolve_type(template).num_self_template_params(self);
+        if num_expected_args == 0 {
+            warn!(
+                "Tried to instantiate a template for which we could not \
+                   determine any template parameters"
+            );
+            return None;
+        }
 
         let mut args = vec![];
         let mut found_const_arg = false;
         let mut children = location.collect_children();
 
         if children.iter().all(|c| !c.has_children()) {
             // This is insanity... If clang isn't giving us a properly nested
             // AST for which template arguments belong to which template we are
@@ -1888,30 +1909,65 @@ impl BindgenContext {
 
         debug!("Not resolved, maybe builtin?");
         self.build_builtin_ty(ty)
     }
 
     /// Make a new item that is a resolved type reference to the `wrapped_id`.
     ///
     /// This is unfortunately a lot of bloat, but is needed to properly track
-    /// constness et. al.
+    /// constness et al.
     ///
     /// We should probably make the constness tracking separate, so it doesn't
     /// bloat that much, but hey, we already bloat the heck out of builtin
     /// types.
     pub fn build_ty_wrapper(
         &mut self,
         with_id: ItemId,
         wrapped_id: TypeId,
         parent_id: Option<ItemId>,
         ty: &clang::Type,
     ) -> TypeId {
+        self.build_wrapper(
+            with_id,
+            wrapped_id,
+            parent_id,
+            ty,
+            ty.is_const(),
+        )
+    }
+
+    /// A wrapper over a type that adds a const qualifier explicitly.
+    ///
+    /// Needed to handle const methods in C++, wrapping the type .
+    pub fn build_const_wrapper(
+        &mut self,
+        with_id: ItemId,
+        wrapped_id: TypeId,
+        parent_id: Option<ItemId>,
+        ty: &clang::Type,
+    ) -> TypeId {
+        self.build_wrapper(
+            with_id,
+            wrapped_id,
+            parent_id,
+            ty,
+            /* is_const = */ true,
+        )
+    }
+
+    fn build_wrapper(
+        &mut self,
+        with_id: ItemId,
+        wrapped_id: TypeId,
+        parent_id: Option<ItemId>,
+        ty: &clang::Type,
+        is_const: bool,
+    ) -> TypeId {
         let spelling = ty.spelling();
-        let is_const = ty.is_const();
         let layout = ty.fallible_layout().ok();
         let type_kind = TypeKind::ResolvedTypeRef(wrapped_id);
         let ty = Type::new(Some(spelling), layout, type_kind, is_const);
         let item = Item::new(
             with_id,
             None,
             None,
             parent_id.unwrap_or(self.current_module.into()),
@@ -2286,17 +2342,21 @@ impl BindgenContext {
             roots.reverse();
             roots
         };
 
         let whitelisted_items_predicate =
             if self.options().whitelist_recursively {
                 traversal::all_edges
             } else {
-                traversal::no_edges
+                // Only follow InnerType edges from the whitelisted roots.
+                // Such inner types (e.g. anonymous structs/unions) are
+                // always emitted by codegen, and they need to be whitelisted
+                // to make sure they are processed by e.g. the derive analysis.
+                traversal::only_inner_type_edges
             };
 
         let whitelisted = WhitelistedItemsTraversal::new(
             self,
             roots.clone(),
             whitelisted_items_predicate,
         ).collect::<ItemSet>();
 
@@ -2311,32 +2371,32 @@ impl BindgenContext {
         };
 
         self.whitelisted = Some(whitelisted);
         self.codegen_items = Some(codegen_items);
     }
 
     /// Convenient method for getting the prefix to use for most traits in
     /// codegen depending on the `use_core` option.
-    pub fn trait_prefix(&self) -> quote::Ident {
+    pub fn trait_prefix(&self) -> Term {
         if self.options().use_core {
             self.rust_ident_raw("core")
         } else {
             self.rust_ident_raw("std")
         }
     }
 
-    /// Call if a binden complex is generated
-    pub fn generated_bindegen_complex(&self) {
-        self.generated_bindegen_complex.set(true)
+    /// Call if a bindgen complex is generated
+    pub fn generated_bindgen_complex(&self) {
+        self.generated_bindgen_complex.set(true)
     }
 
-    /// Whether we need to generate the binden complex type
-    pub fn need_bindegen_complex_type(&self) -> bool {
-        self.generated_bindegen_complex.get()
+    /// Whether we need to generate the bindgen complex type
+    pub fn need_bindgen_complex_type(&self) -> bool {
+        self.generated_bindgen_complex.get()
     }
 
     /// Compute whether we can derive debug.
     fn compute_cannot_derive_debug(&mut self) {
         let _t = self.timer("compute_cannot_derive_debug");
         assert!(self.cannot_derive_debug.is_none());
         if self.options.derive_debug {
             self.cannot_derive_debug = Some(analyze::<CannotDeriveDebug>(self));
@@ -2498,17 +2558,17 @@ impl BindgenContext {
     }
 
     /// Check if `--no-copy` flag is enabled for this item.
     pub fn no_copy_by_name(&self, item: &Item) -> bool {
         let name = item.canonical_path(self)[1..].join("::");
         self.options().no_copy_types.matches(&name)
     }
 
-    /// Chech if `--no-hash` flag is enabled for this item.
+    /// Check if `--no-hash` flag is enabled for this item.
     pub fn no_hash_by_name(&self, item: &Item) -> bool {
         let name = item.canonical_path(self)[1..].join("::");
         self.options().no_hash_types.matches(&name)
     }
 }
 
 /// A builder struct for configuring item resolution options.
 #[derive(Debug, Copy, Clone)]
@@ -2613,23 +2673,23 @@ impl PartialType {
         self.id
     }
 }
 
 impl TemplateParameters for PartialType {
     fn self_template_params(
         &self,
         _ctx: &BindgenContext,
-    ) -> Option<Vec<TypeId>> {
+    ) -> Vec<TypeId> {
         // Maybe at some point we will eagerly parse named types, but for now we
         // don't and this information is unavailable.
-        None
+        vec![]
     }
 
-    fn num_self_template_params(&self, _ctx: &BindgenContext) -> Option<usize> {
+    fn num_self_template_params(&self, _ctx: &BindgenContext) -> usize {
         // Wouldn't it be nice if libclang would reliably give us this
         // information‽
         match self.decl().kind() {
             clang_sys::CXCursor_ClassTemplate |
             clang_sys::CXCursor_FunctionTemplate |
             clang_sys::CXCursor_TypeAliasTemplateDecl => {
                 let mut num_params = 0;
                 self.decl().visit(|c| {
@@ -2638,14 +2698,14 @@ impl TemplateParameters for PartialType 
                         clang_sys::CXCursor_TemplateTemplateParameter |
                         clang_sys::CXCursor_NonTypeTemplateParameter => {
                             num_params += 1;
                         }
                         _ => {}
                     };
                     clang_sys::CXChildVisit_Continue
                 });
-                Some(num_params)
+                num_params
             }
-            _ => None,
+            _ => 0,
         }
     }
 }
--- a/third_party/rust/bindgen/src/ir/derive.rs
+++ b/third_party/rust/bindgen/src/ir/derive.rs
@@ -38,17 +38,17 @@ pub trait CanTriviallyDeriveDebug {
 pub trait CanDeriveCopy<'a> {
     /// Return `true` if `Copy` can be derived for this thing, `false`
     /// otherwise.
     fn can_derive_copy(&'a self, ctx: &'a BindgenContext) -> bool;
 }
 
 /// A trait that encapsulates the logic for whether or not we can trivially
 /// derive `Copy` without looking at any other types or results of fix point
-/// analsyses. This is a helper trait for fix point analysis.
+/// analyses. This is a helper trait for fix point analysis.
 pub trait CanTriviallyDeriveCopy {
     /// Return `true` if `Copy` can be trivially derived for this thing, `false`
     /// otherwise.
     fn can_trivially_derive_copy(&self) -> bool;
 }
 
 /// A trait that encapsulates the logic for whether or not we can derive
 /// `Default` for a given thing.
--- a/third_party/rust/bindgen/src/ir/enum_ty.rs
+++ b/third_party/rust/bindgen/src/ir/enum_ty.rs
@@ -2,16 +2,17 @@
 
 use super::context::{BindgenContext, TypeId};
 use super::item::Item;
 use super::ty::TypeKind;
 use clang;
 use ir::annotations::Annotations;
 use ir::item::ItemCanonicalPath;
 use parse::{ClangItemParser, ParseError};
+use regex_set::RegexSet;
 
 /// An enum representing custom handling that can be given to a variant.
 #[derive(Copy, Clone, Debug, PartialEq, Eq)]
 pub enum EnumVariantCustomBehavior {
     /// This variant will be a module containing constants.
     ModuleConstify,
     /// This variant will be constified, that is, forced to generate a constant.
     Constify,
@@ -132,54 +133,46 @@ impl Enum {
                     ));
                 }
             }
             CXChildVisit_Continue
         });
         Ok(Enum::new(repr, variants))
     }
 
-    /// Whether the enum should be a bitfield
-    pub fn is_bitfield(&self, ctx: &BindgenContext, item: &Item) -> bool {
+    fn is_matching_enum(&self, ctx: &BindgenContext, enums: &RegexSet, item: &Item) -> bool {
         let path = item.canonical_path(ctx);
         let enum_ty = item.expect_type();
 
-        ctx.options().bitfield_enums.matches(&path[1..].join("::")) ||
-            (enum_ty.name().is_none() &&
-                    self.variants().iter().any(|v| {
-                    ctx.options().bitfield_enums.matches(&v.name())
-                }))
+        let path_matches = enums.matches(&path[1..].join("::"));
+        let enum_is_anon = enum_ty.name().is_none();
+        let a_variant_matches = self.variants().iter().any(|v| {
+            enums.matches(&v.name())
+        });
+        path_matches || (enum_is_anon && a_variant_matches)
+    }
+
+    /// Whether the enum should be a bitfield
+    pub fn is_bitfield(&self, ctx: &BindgenContext, item: &Item) -> bool {
+        self.is_matching_enum(ctx, &ctx.options().bitfield_enums, item)
     }
 
     /// Whether the enum should be an constified enum module
-    pub fn is_constified_enum_module(
-        &self,
-        ctx: &BindgenContext,
-        item: &Item,
-    ) -> bool {
-        let path = item.canonical_path(ctx);
-        let enum_ty = item.expect_type();
+    pub fn is_constified_enum_module(&self, ctx: &BindgenContext, item: &Item) -> bool {
+        self.is_matching_enum(ctx, &ctx.options().constified_enum_modules, item)
+    }
 
-        ctx.options().constified_enum_modules.matches(&path[1..].join("::")) ||
-            (enum_ty.name().is_none() &&
-                 self.variants().iter().any(|v| {
-                    ctx.options().constified_enum_modules.matches(&v.name())
-                }))
+    /// Whether the enum should be an set of constants
+    pub fn is_constified_enum(&self, ctx: &BindgenContext, item: &Item) -> bool {
+        self.is_matching_enum(ctx, &ctx.options().constified_enums, item)
     }
 
     /// Whether the enum should be a Rust enum
     pub fn is_rustified_enum(&self, ctx: &BindgenContext, item: &Item) -> bool {
-        let path = item.canonical_path(ctx);
-        let enum_ty = item.expect_type();
-
-        ctx.options().rustified_enums.matches(&path[1..].join("::")) ||
-            (enum_ty.name().is_none() &&
-                self.variants().iter().any(|v| {
-                    ctx.options().rustified_enums.matches(&v.name())
-            }))
+        self.is_matching_enum(ctx, &ctx.options().rustified_enums, item)
     }
 }
 
 /// A single enum variant, to be contained only in an enum.
 #[derive(Debug)]
 pub struct EnumVariant {
     /// The name of the variant.
     name: String,
--- a/third_party/rust/bindgen/src/ir/function.rs
+++ b/third_party/rust/bindgen/src/ir/function.rs
@@ -188,17 +188,17 @@ impl Abi {
             Abi::Unknown(..) => true,
             _ => false,
         }
     }
 }
 
 impl quote::ToTokens for Abi {
     fn to_tokens(&self, tokens: &mut quote::Tokens) {
-        tokens.append(match *self {
+        tokens.append_all(match *self {
             Abi::C => quote! { "C" },
             Abi::Stdcall => quote! { "stdcall" },
             Abi::Fastcall => quote! { "fastcall" },
             Abi::ThisCall => quote! { "thiscall" },
             Abi::Aapcs => quote! { "aapcs" },
             Abi::Win64 => quote! { "win64" },
             Abi::Unknown(cc) => panic!(
                 "Cannot turn unknown calling convention to tokens: {:?}",
@@ -397,24 +397,37 @@ impl FunctionSig {
             return Err(ParseError::Continue);
         }
 
         if is_method || is_constructor || is_destructor {
             let is_const = is_method && cursor.method_is_const();
             let is_virtual = is_method && cursor.method_is_virtual();
             let is_static = is_method && cursor.method_is_static();
             if !is_static && !is_virtual {
-                let class = Item::parse(cursor.semantic_parent(), None, ctx)
+                let parent = cursor.semantic_parent();
+                let class = Item::parse(parent, None, ctx)
                     .expect("Expected to parse the class");
                 // The `class` most likely is not finished parsing yet, so use
                 // the unchecked variant.
                 let class = class.as_type_id_unchecked();
 
+                let class = if is_const {
+                    let const_class_id = ctx.next_item_id();
+                    ctx.build_const_wrapper(
+                        const_class_id,
+                        class,
+                        None,
+                        &parent.cur_type(),
+                    )
+                } else {
+                    class
+                };
+
                 let ptr =
-                    Item::builtin_type(TypeKind::Pointer(class), is_const, ctx);
+                    Item::builtin_type(TypeKind::Pointer(class), false, ctx);
                 args.insert(0, (Some("this".into()), ptr));
             } else if is_virtual {
                 let void = Item::builtin_type(TypeKind::Void, false, ctx);
                 let ptr =
                     Item::builtin_type(TypeKind::Pointer(void), false, ctx);
                 args.insert(0, (Some("this".into()), ptr));
             }
         }
--- a/third_party/rust/bindgen/src/ir/item.rs
+++ b/third_party/rust/bindgen/src/ir/item.rs
@@ -1107,45 +1107,45 @@ impl DotAttributes for Item {
 
 impl<T> TemplateParameters for T
 where
     T: Copy + Into<ItemId>
 {
     fn self_template_params(
         &self,
         ctx: &BindgenContext,
-    ) -> Option<Vec<TypeId>> {
-        ctx.resolve_item_fallible(*self).and_then(|item| {
+    ) -> Vec<TypeId> {
+        ctx.resolve_item_fallible(*self).map_or(vec![], |item| {
             item.self_template_params(ctx)
         })
     }
 }
 
 impl TemplateParameters for Item {
     fn self_template_params(
         &self,
         ctx: &BindgenContext,
-    ) -> Option<Vec<TypeId>> {
+    ) -> Vec<TypeId> {
         self.kind.self_template_params(ctx)
     }
 }
 
 impl TemplateParameters for ItemKind {
     fn self_template_params(
         &self,
         ctx: &BindgenContext,
-    ) -> Option<Vec<TypeId>> {
+    ) -> Vec<TypeId> {
         match *self {
             ItemKind::Type(ref ty) => ty.self_template_params(ctx),
             // If we start emitting bindings to explicitly instantiated
             // functions, then we'll need to check ItemKind::Function for
             // template params.
             ItemKind::Function(_) |
             ItemKind::Module(_) |
-            ItemKind::Var(_) => None,
+            ItemKind::Var(_) => vec![],
         }
     }
 }
 
 // An utility function to handle recursing inside nested types.
 fn visit_child(
     cur: clang::Cursor,
     id: ItemId,
@@ -1444,18 +1444,18 @@ impl ClangItemParser for Item {
         {
 
             if ty.is_associated_type() ||
                 location.cur_type().is_associated_type()
             {
                 return Ok(Item::new_opaque_type(id, ty, ctx));
             }
 
-            if let Some(id) = Item::type_param(Some(id), location, ctx) {
-                return Ok(id);
+            if let Some(param_id) = Item::type_param(None, location, ctx) {
+                return Ok(ctx.build_ty_wrapper(id, param_id, None, ty));
             }
         }
 
         let decl = {
             let decl = ty.declaration();
             decl.definition().unwrap_or(decl)
         };
 
--- a/third_party/rust/bindgen/src/ir/layout.rs
+++ b/third_party/rust/bindgen/src/ir/layout.rs
@@ -1,65 +1,73 @@
 //! Intermediate representation for the physical layout of some type.
 
 use super::derive::{CanTriviallyDeriveCopy, CanTriviallyDeriveDebug,
                     CanTriviallyDeriveDefault, CanTriviallyDeriveHash,
                     CanTriviallyDerivePartialEqOrPartialOrd, CanDerive};
 use super::ty::{RUST_DERIVE_IN_ARRAY_LIMIT, Type, TypeKind};
+use ir::context::BindgenContext;
 use clang;
-use std::{cmp, mem};
+use std::cmp;
 
 /// A type that represents the struct layout of a type.
 #[derive(Debug, Clone, Copy, PartialEq)]
 pub struct Layout {
     /// The size (in bytes) of this layout.
     pub size: usize,
     /// The alignment (in bytes) of this layout.
     pub align: usize,
     /// Whether this layout's members are packed or not.
     pub packed: bool,
 }
 
 #[test]
 fn test_layout_for_size() {
+    use std::mem;
+
     let ptr_size = mem::size_of::<*mut ()>();
-    assert_eq!(Layout::for_size(ptr_size), Layout::new(ptr_size, ptr_size));
     assert_eq!(
-        Layout::for_size(3 * ptr_size),
+        Layout::for_size_internal(ptr_size, ptr_size),
+        Layout::new(ptr_size, ptr_size)
+    );
+    assert_eq!(
+        Layout::for_size_internal(ptr_size, 3 * ptr_size),
         Layout::new(3 * ptr_size, ptr_size)
     );
 }
 
 impl Layout {
     /// Construct a new `Layout` with the given `size` and `align`. It is not
     /// packed.
     pub fn new(size: usize, align: usize) -> Self {
         Layout {
             size,
             align,
             packed: false,
         }
     }
 
-    /// Creates a non-packed layout for a given size, trying to use the maximum
-    /// alignment possible.
-    pub fn for_size(size: usize) -> Self {
+    fn for_size_internal(ptr_size: usize, size: usize) -> Self {
         let mut next_align = 2;
-        while size % next_align == 0 &&
-            next_align <= mem::size_of::<*mut ()>()
-        {
+        while size % next_align == 0 && next_align <= ptr_size {
             next_align *= 2;
         }
         Layout {
             size: size,
             align: next_align / 2,
             packed: false,
         }
     }
 
+    /// Creates a non-packed layout for a given size, trying to use the maximum
+    /// alignment possible.
+    pub fn for_size(ctx: &BindgenContext, size: usize) -> Self {
+        Self::for_size_internal(ctx.target_pointer_size(), size)
+    }
+
     /// Is this a zero-sized layout?
     pub fn is_zero(&self) -> bool {
         self.size == 0 && self.align == 0
     }
 
     /// Construct a zero-sized layout.
     pub fn zero() -> Self {
         Self::new(0, 0)
@@ -75,17 +83,18 @@ impl Layout {
 #[derive(Clone, Debug, PartialEq)]
 pub struct Opaque(pub Layout);
 
 impl Opaque {
     /// Construct a new opaque type from the given clang type.
     pub fn from_clang_ty(ty: &clang::Type) -> Type {
         let layout = Layout::new(ty.size(), ty.align());
         let ty_kind = TypeKind::Opaque;
-        Type::new(None, Some(layout), ty_kind, false)
+        let is_const = ty.is_const();
+        Type::new(None, Some(layout), ty_kind, is_const)
     }
 
     /// Return the known rust type we should use to create a correctly-aligned
     /// field with this layout.
     pub fn known_rust_type_for_array(&self) -> Option<&'static str> {
         Some(match self.0.align {
             8 => "u64",
             4 => "u32",
--- a/third_party/rust/bindgen/src/ir/objc.rs
+++ b/third_party/rust/bindgen/src/ir/objc.rs
@@ -8,16 +8,17 @@ use clang;
 use clang_sys::CXChildVisit_Continue;
 use clang_sys::CXCursor_ObjCCategoryDecl;
 use clang_sys::CXCursor_ObjCClassMethodDecl;
 use clang_sys::CXCursor_ObjCClassRef;
 use clang_sys::CXCursor_ObjCInstanceMethodDecl;
 use clang_sys::CXCursor_ObjCProtocolDecl;
 use clang_sys::CXCursor_ObjCProtocolRef;
 use quote;
+use proc_macro2::{Term, Span};
 
 /// Objective C interface as used in TypeKind
 ///
 /// Also protocols and categories are parsed as this type
 #[derive(Debug)]
 pub struct ObjCInterface {
     /// The name
     /// like, NSObject
@@ -211,17 +212,17 @@ impl ObjCMethod {
         self.is_class_method
     }
 
     /// Formats the method call
     pub fn format_method_call(&self, args: &[quote::Tokens]) -> quote::Tokens {
         let split_name: Vec<_> = self.name
             .split(':')
             .filter(|p| !p.is_empty())
-            .map(quote::Ident::new)
+            .map(|name| Term::new(name, Span::call_site()))
             .collect();
 
         // No arguments
         if args.len() == 0 && split_name.len() == 1 {
             let name = &split_name[0];
             return quote! {
                 #name
             };
@@ -234,19 +235,20 @@ impl ObjCMethod {
                 args,
                 split_name
             );
         }
 
         // Get arguments without type signatures to pass to `msg_send!`
         let mut args_without_types = vec![];
         for arg in args.iter() {
-            let name_and_sig: Vec<&str> = arg.as_str().split(' ').collect();
+            let arg = arg.to_string();
+            let name_and_sig: Vec<&str> = arg.split(' ').collect();
             let name = name_and_sig[0];
-            args_without_types.push(quote::Ident::new(name))
+            args_without_types.push(Term::new(name, Span::call_site()))
         };
 
         let args = split_name
             .into_iter()
             .zip(args_without_types)
             .map(|(arg, arg_val)| quote! { #arg : #arg_val });
 
         quote! {
--- a/third_party/rust/bindgen/src/ir/template.rs
+++ b/third_party/rust/bindgen/src/ir/template.rs
@@ -76,112 +76,93 @@ use parse::ClangItemParser;
 /// ```
 ///
 /// The following table depicts the results of each trait method when invoked on
 /// each of the declarations above:
 ///
 /// +------+----------------------+--------------------------+------------------------+----
 /// |Decl. | self_template_params | num_self_template_params | all_template_parameters| ...
 /// +------+----------------------+--------------------------+------------------------+----
-/// |Foo   | Some([T, U])         | Some(2)                  | Some([T, U])           | ...
-/// |Bar   | Some([V])            | Some(1)                  | Some([T, U, V])        | ...
-/// |Inner | None                 | None                     | Some([T, U])           | ...
-/// |Lol   | Some([W])            | Some(1)                  | Some([T, U, W])        | ...
-/// |Wtf   | Some([X])            | Some(1)                  | Some([T, U, X])        | ...
-/// |Qux   | None                 | None                     | None                   | ...
+/// |Foo   | [T, U]               | 2                        | [T, U]                 | ...
+/// |Bar   | [V]                  | 1                        | [T, U, V]              | ...
+/// |Inner | []                   | 0                        | [T, U]                 | ...
+/// |Lol   | [W]                  | 1                        | [T, U, W]              | ...
+/// |Wtf   | [X]                  | 1                        | [T, U, X]              | ...
+/// |Qux   | []                   | 0                        | []                     | ...
 /// +------+----------------------+--------------------------+------------------------+----
 ///
 /// ----+------+-----+----------------------+
 /// ... |Decl. | ... | used_template_params |
 /// ----+------+-----+----------------------+
-/// ... |Foo   | ... | Some([T, U])         |
-/// ... |Bar   | ... | Some([V])            |
-/// ... |Inner | ... | None                 |
-/// ... |Lol   | ... | Some([T])            |
-/// ... |Wtf   | ... | Some([T])            |
-/// ... |Qux   | ... | None                 |
+/// ... |Foo   | ... | [T, U]               |
+/// ... |Bar   | ... | [V]                  |
+/// ... |Inner | ... | []                   |
+/// ... |Lol   | ... | [T]                  |
+/// ... |Wtf   | ... | [T]                  |
+/// ... |Qux   | ... | []                   |
 /// ----+------+-----+----------------------+
 pub trait TemplateParameters {
     /// Get the set of `ItemId`s that make up this template declaration's free
     /// template parameters.
     ///
     /// Note that these might *not* all be named types: C++ allows
     /// constant-value template parameters as well as template-template
     /// parameters. Of course, Rust does not allow generic parameters to be
     /// anything but types, so we must treat them as opaque, and avoid
     /// instantiating them.
     fn self_template_params(&self, ctx: &BindgenContext)
-        -> Option<Vec<TypeId>>;
+        -> Vec<TypeId>;
 
     /// Get the number of free template parameters this template declaration
     /// has.
-    ///
-    /// Implementations *may* return `Some` from this method when
-    /// `template_params` returns `None`. This is useful when we only have
-    /// partial information about the template declaration, such as when we are
-    /// in the middle of parsing it.
-    fn num_self_template_params(&self, ctx: &BindgenContext) -> Option<usize> {
-        self.self_template_params(ctx).map(|params| params.len())
+    fn num_self_template_params(&self, ctx: &BindgenContext) -> usize {
+        self.self_template_params(ctx).len()
     }
 
     /// Get the complete set of template parameters that can affect this
     /// declaration.
     ///
     /// Note that this item doesn't need to be a template declaration itself for
     /// `Some` to be returned here (in contrast to `self_template_params`). If
     /// this item is a member of a template declaration, then the parent's
     /// template parameters are included here.
     ///
     /// In the example above, `Inner` depends on both of the `T` and `U` type
     /// parameters, even though it is not itself a template declaration and
     /// therefore has no type parameters itself. Perhaps it helps to think about
     /// how we would fully reference such a member type in C++:
     /// `Foo<int,char>::Inner`. `Foo` *must* be instantiated with template
     /// arguments before we can gain access to the `Inner` member type.
-    fn all_template_params(&self, ctx: &BindgenContext) -> Option<Vec<TypeId>>
+    fn all_template_params(&self, ctx: &BindgenContext) -> Vec<TypeId>
     where
         Self: ItemAncestors,
     {
-        let each_self_params: Vec<Vec<_>> = self.ancestors(ctx)
-            .filter_map(|id| id.self_template_params(ctx))
-            .collect();
-        if each_self_params.is_empty() {
-            None
-        } else {
-            Some(
-                each_self_params
-                    .into_iter()
-                    .rev()
-                    .flat_map(|params| params)
-                    .collect(),
-            )
-        }
+        let ancestors: Vec<_> = self.ancestors(ctx).collect();
+        ancestors.into_iter().rev().flat_map(|id| {
+            id.self_template_params(ctx).into_iter()
+        }).collect()
     }
 
     /// Get only the set of template parameters that this item uses. This is a
     /// subset of `all_template_params` and does not necessarily contain any of
     /// `self_template_params`.
-    fn used_template_params(&self, ctx: &BindgenContext) -> Option<Vec<TypeId>>
+    fn used_template_params(&self, ctx: &BindgenContext) -> Vec<TypeId>
     where
         Self: AsRef<ItemId>,
     {
         assert!(
             ctx.in_codegen_phase(),
             "template parameter usage is not computed until codegen"
         );
 
         let id = *self.as_ref();
-        ctx.resolve_item(id).all_template_params(ctx).map(
-            |all_params| {
-                all_params
+        ctx.resolve_item(id).all_template_params(ctx)
                     .into_iter()
                     .filter(|p| ctx.uses_template_parameter(id, *p))
                     .collect()
-            },
-        )
     }
 }
 
 /// A trait for things which may or may not be a named template type parameter.
 pub trait AsTemplateParam {
     /// Any extra information the implementor might need to make this decision.
     type Extra;
 
--- a/third_party/rust/bindgen/src/ir/traversal.rs
+++ b/third_party/rust/bindgen/src/ir/traversal.rs
@@ -196,21 +196,23 @@ impl TraversalPredicate for for<'a> fn(&
 
 /// A `TraversalPredicate` implementation that follows all edges, and therefore
 /// traversals using this predicate will see the whole IR graph reachable from
 /// the traversal's roots.
 pub fn all_edges(_: &BindgenContext, _: Edge) -> bool {
     true
 }
 
-/// A `TraversalPredicate` implementation that never follows any edges, and
-/// therefore traversals using this predicate will only visit the traversal's
-/// roots.
-pub fn no_edges(_: &BindgenContext, _: Edge) -> bool {
-    false
+/// A `TraversalPredicate` implementation that only follows
+/// `EdgeKind::InnerType` edges, and therefore traversals using this predicate
+/// will only visit the traversal's roots and their inner types. This is used
+/// in no-recursive-whitelist mode, where inner types such as anonymous
+/// structs/unions still need to be processed.
+pub fn only_inner_type_edges(_: &BindgenContext, edge: Edge) -> bool {
+    edge.kind == EdgeKind::InnerType
 }
 
 /// A `TraversalPredicate` implementation that only follows edges to items that
 /// are enabled for code generation. This lets us skip considering items for
 /// which are not reachable from code generation.
 pub fn codegen_edges(ctx: &BindgenContext, edge: Edge) -> bool {
     let cc = &ctx.options().codegen_config;
     match edge.kind {
--- a/third_party/rust/bindgen/src/ir/ty.rs
+++ b/third_party/rust/bindgen/src/ir/ty.rs
@@ -11,17 +11,16 @@ use super::layout::{Layout, Opaque};
 use super::objc::ObjCInterface;
 use super::template::{AsTemplateParam, TemplateInstantiation,
                       TemplateParameters};
 use super::traversal::{EdgeKind, Trace, Tracer};
 use clang::{self, Cursor};
 use parse::{ClangItemParser, ParseError, ParseResult};
 use std::borrow::Cow;
 use std::io;
-use std::mem;
 
 /// The base representation of a type in bindgen.
 ///
 /// A type has an optional name, which if present cannot be empty, a `layout`
 /// (size, alignment and packedness) if known, a `Kind`, which determines which
 /// kind of type it is, and whether the type is const.
 #[derive(Debug)]
 pub struct Type {
@@ -227,28 +226,26 @@ impl Type {
                 ctx.resolve_type(inner).is_incomplete_array(ctx)
             }
             _ => None,
         }
     }
 
     /// What is the layout of this type?
     pub fn layout(&self, ctx: &BindgenContext) -> Option<Layout> {
-        use std::mem;
-
         self.layout.or_else(|| {
             match self.kind {
                 TypeKind::Comp(ref ci) => ci.layout(ctx),
                 // FIXME(emilio): This is a hack for anonymous union templates.
                 // Use the actual pointer size!
                 TypeKind::Pointer(..) |
                 TypeKind::BlockPointer => {
                     Some(Layout::new(
-                        mem::size_of::<*mut ()>(),
-                        mem::align_of::<*mut ()>(),
+                        ctx.target_pointer_size(),
+                        ctx.target_pointer_size(),
                     ))
                 }
                 TypeKind::ResolvedTypeRef(inner) => {
                     ctx.resolve_type(inner).layout(ctx)
                 }
                 _ => None,
             }
         })
@@ -538,32 +535,32 @@ fn is_invalid_type_param_empty_name() {
     let ty = Type::new(Some("".into()), None, TypeKind::TypeParam, false);
     assert!(ty.is_invalid_type_param())
 }
 
 impl TemplateParameters for Type {
     fn self_template_params(
         &self,
         ctx: &BindgenContext,
-    ) -> Option<Vec<TypeId>> {
+    ) -> Vec<TypeId> {
         self.kind.self_template_params(ctx)
     }
 }
 
 impl TemplateParameters for TypeKind {
     fn self_template_params(
         &self,
         ctx: &BindgenContext,
-    ) -> Option<Vec<TypeId>> {
+    ) -> Vec<TypeId> {
         match *self {
             TypeKind::ResolvedTypeRef(id) => {
                 ctx.resolve_type(id).self_template_params(ctx)
             }
             TypeKind::Comp(ref comp) => comp.self_template_params(ctx),
-            TypeKind::TemplateAlias(_, ref args) => Some(args.clone()),
+            TypeKind::TemplateAlias(_, ref args) => args.clone(),
 
             TypeKind::Opaque |
             TypeKind::TemplateInstantiation(..) |
             TypeKind::Void |
             TypeKind::NullPtr |
             TypeKind::Int(_) |
             TypeKind::Float(_) |
             TypeKind::Complex(_) |
@@ -573,17 +570,17 @@ impl TemplateParameters for TypeKind {
             TypeKind::Pointer(_) |
             TypeKind::BlockPointer |
             TypeKind::Reference(_) |
             TypeKind::UnresolvedTypeRef(..) |
             TypeKind::TypeParam |
             TypeKind::Alias(_) |
             TypeKind::ObjCId |
             TypeKind::ObjCSel |
-            TypeKind::ObjCInterface(_) => None,
+            TypeKind::ObjCInterface(_) => vec![],
         }
     }
 }
 
 /// The kind of float this type represents.
 #[derive(Debug, Copy, Clone, PartialEq)]
 pub enum FloatKind {
     /// A `float`.
@@ -591,27 +588,16 @@ pub enum FloatKind {
     /// A `double`.
     Double,
     /// A `long double`.
     LongDouble,
     /// A `__float128`.
     Float128,
 }
 
-impl FloatKind {
-    /// If this type has a known size, return it (in bytes).
-    pub fn known_size(&self) -> usize {
-        match *self {
-            FloatKind::Float => mem::size_of::<f32>(),
-            FloatKind::Double | FloatKind::LongDouble => mem::size_of::<f64>(),
-            FloatKind::Float128 => mem::size_of::<f64>() * 2,
-        }
-    }
-}
-
 /// The different kinds of types that we can parse.
 #[derive(Debug)]
 pub enum TypeKind {
     /// The void type.
     Void,
 
     /// The `nullptr_t` type.
     NullPtr,
@@ -1203,16 +1189,17 @@ impl Type {
                         location
                     );
                     return Err(ParseError::Continue);
                 }
             }
         };
 
         let name = if name.is_empty() { None } else { Some(name) };
+
         let is_const = ty.is_const();
 
         let ty = Type::new(name, layout, kind, is_const);
         // TODO: maybe declaration.canonical()?
         Ok(ParseResult::New(ty, Some(cursor.canonical())))
     }
 }
 
--- a/third_party/rust/bindgen/src/lib.rs
+++ b/third_party/rust/bindgen/src/lib.rs
@@ -1,14 +1,17 @@
 //! Generate Rust bindings for C and C++ libraries.
 //!
 //! Provide a C/C++ header file, receive Rust FFI code to call into C/C++
 //! functions and use types defined in the header.
 //!
 //! See the [`Builder`](./struct.Builder.html) struct for usage.
+//!
+//! See the [Users Guide](https://rust-lang-nursery.github.io/rust-bindgen/) for
+//! additional documentation.
 #![deny(missing_docs)]
 #![deny(warnings)]
 #![deny(unused_extern_crates)]
 // To avoid rather annoying warnings when matching with CXCursor_xxx as a
 // constant.
 #![allow(non_upper_case_globals)]
 // `quote!` nests quite deeply.
 #![recursion_limit="128"]
@@ -18,16 +21,17 @@ extern crate cexpr;
 #[allow(unused_extern_crates)]
 extern crate cfg_if;
 extern crate clang_sys;
 #[macro_use]
 extern crate lazy_static;
 extern crate peeking_take_while;
 #[macro_use]
 extern crate quote;
+extern crate proc_macro2;
 extern crate regex;
 extern crate which;
 
 #[cfg(feature = "logging")]
 #[macro_use]
 extern crate log;
 
 #[cfg(not(feature = "logging"))]
@@ -74,18 +78,20 @@ doc_mod!(parse, parse_docs);
 doc_mod!(regex_set, regex_set_docs);
 
 pub use features::{LATEST_STABLE_RUST, RUST_TARGET_STRINGS, RustTarget};
 use features::RustFeatures;
 use ir::context::{BindgenContext, ItemId};
 use ir::item::Item;
 use parse::{ClangItemParser, ParseError};
 use regex_set::RegexSet;
+pub use codegen::EnumVariation;
 
 use std::borrow::Cow;
+use std::collections::HashMap;
 use std::fs::{File, OpenOptions};
 use std::io::{self, Write};
 use std::iter;
 use std::path::{Path, PathBuf};
 use std::process::{Command, Stdio};
 use std::sync::Arc;
 
 /// A type used to indicate which kind of items do we have to generate.
@@ -150,16 +156,33 @@ impl Default for CodegenConfig {
 /// let bindings = builder().header("path/to/input/header")
 ///     .whitelisted_type("SomeCoolClass")
 ///     .whitelisted_function("do_some_cool_thing")
 ///     .generate()?;
 ///
 /// // Write the generated bindings to an output file.
 /// bindings.write_to_file("path/to/output.rs")?;
 /// ```
+///
+/// # Enums
+///
+/// Bindgen can map C/C++ enums into Rust in different ways. The way bindgen maps enums depends on
+/// the pattern passed to several methods:
+///
+/// 1. [`constified_enum_module()`](#method.constified_enum_module)
+/// 2. [`bitfield_enum()`](#method.bitfield_enum)
+/// 3. [`rustified_enum()`](#method.rustified_enum)
+///
+/// For each C enum, bindgen tries to match the pattern in the following order:
+///
+/// 1. Constified enum module
+/// 2. Bitfield enum
+/// 3. Rustified enum
+///
+/// If none of the above patterns match, then bindgen will generate a set of Rust constants.
 #[derive(Debug, Default)]
 pub struct Builder {
     options: BindgenOptions,
     input_headers: Vec<String>,
     // Tuples of unsaved file contents of the form (name, contents).
     input_header_contents: Vec<(String, String)>,
 }
 
@@ -176,16 +199,26 @@ impl Builder {
         if let Some(header) = self.input_headers.last().cloned() {
             // Positional argument 'header'
             output_vector.push(header);
         }
 
         output_vector.push("--rust-target".into());
         output_vector.push(self.options.rust_target.into());
 
+        if self.options.default_enum_style != Default::default() {
+            output_vector.push("--default-enum-variant=".into());
+            output_vector.push(match self.options.default_enum_style {
+                codegen::EnumVariation::Rust => "rust",
+                codegen::EnumVariation::Bitfield => "bitfield",
+                codegen::EnumVariation::Consts => "consts",
+                codegen::EnumVariation::ModuleConsts => "moduleconsts",
+            }.into())
+        }
+
         self.options
             .bitfield_enums
             .get_items()
             .iter()
             .map(|item| {
                 output_vector.push("--bitfield-enum".into());
                 output_vector.push(
                     item.trim_left_matches("^")
@@ -219,16 +252,30 @@ impl Builder {
                     item.trim_left_matches("^")
                         .trim_right_matches("$")
                         .into(),
                 );
             })
             .count();
 
         self.options
+            .constified_enums
+            .get_items()
+            .iter()
+            .map(|item| {
+                output_vector.push("--constified-enum".into());
+                output_vector.push(
+                    item.trim_left_matches("^")
+                        .trim_right_matches("$")
+                        .into(),
+                );
+            })
+            .count();
+
+        self.options
             .blacklisted_types
             .get_items()
             .iter()
             .map(|item| {
                 output_vector.push("--blacklist-type".into());
                 output_vector.push(
                     item.trim_left_matches("^")
                         .trim_right_matches("$")
@@ -321,29 +368,16 @@ impl Builder {
         }
         if self.options.enable_cxx_namespaces {
             output_vector.push("--enable-cxx-namespaces".into());
         }
         if self.options.disable_name_namespacing {
             output_vector.push("--disable-name-namespacing".into());
         }
 
-        self.options
-            .links
-            .iter()
-            .map(|&(ref item, _)| {
-                output_vector.push("--framework".into());
-                output_vector.push(
-                    item.trim_left_matches("^")
-                        .trim_right_matches("$")
-                        .into(),
-                );
-            })
-            .count();
-
         if !self.options.codegen_config.functions {
             output_vector.push("--ignore-functions".into());
         }
 
         output_vector.push("--generate".into());
 
         //Temporary placeholder for below 4 options
         let mut options: Vec<String> = Vec::new();
@@ -367,29 +401,16 @@ impl Builder {
         }
 
         output_vector.push(options.join(","));
 
         if !self.options.codegen_config.methods {
             output_vector.push("--ignore-methods".into());
         }
 
-        self.options
-            .links
-            .iter()
-            .map(|&(ref item, _)| {
-                output_vector.push("--clang-args".into());
-                output_vector.push(
-                    item.trim_left_matches("^")
-                        .trim_right_matches("$")
-                        .into(),
-                );
-            })
-            .count();
-
         if !self.options.convert_floats {
             output_vector.push("--no-convert-floats".into());
         }
 
         if !self.options.prepend_enum_name {
             output_vector.push("--no-prepend-enum-name".into());
         }
 
@@ -415,29 +436,16 @@ impl Builder {
                 output_vector.push(
                     item.trim_left_matches("^")
                         .trim_right_matches("$")
                         .into(),
                 );
             })
             .count();
 
-        self.options
-            .links
-            .iter()
-            .map(|&(ref item, _)| {
-                output_vector.push("--static".into());
-                output_vector.push(
-                    item.trim_left_matches("^")
-                        .trim_right_matches("$")
-                        .into(),
-                );
-            })
-            .count();
-
         if self.options.use_core {
             output_vector.push("--use-core".into());
         }
 
         if self.options.conservative_inline_namespaces {
             output_vector.push("--conservative-inline-namespaces".into());
         }
 
@@ -595,16 +603,22 @@ impl Builder {
     /// Specify the rust target
     ///
     /// The default is the latest stable Rust version
     pub fn rust_target(mut self, rust_target: RustTarget) -> Self {
         self.options.set_rust_target(rust_target);
         self
     }
 
+    /// Disable support for native Rust unions, if supported.
+    pub fn disable_untagged_union(mut self) -> Self {
+        self.options.rust_features.untagged_union = false;
+        self
+    }
+
     /// Set the output graphviz file.
     pub fn emit_ir_graphviz<T: Into<String>>(mut self, path: T) -> Builder {
         let path = path.into();
         self.options.emit_ir_graphviz = Some(path);
         self
     }
 
     /// Whether the generated bindings should contain documentation comments or
@@ -637,17 +651,17 @@ impl Builder {
     /// function and the `MoonBoots` struct that it transitively references. By
     /// configuring with `whitelist_recursively(false)`, `bindgen` will not emit
     /// bindings for anything except the explicitly whitelisted items, and there
     /// would be no emitted struct definition for `MoonBoots`. However, the
     /// `initiate_dance_party` function would still reference `MoonBoots`!
     ///
     /// **Disabling this feature will almost certainly cause `bindgen` to emit
     /// bindings that will not compile!** If you disable this feature, then it
-    /// is *your* responsiblity to provide definitions for every type that is
+    /// is *your* responsibility to provide definitions for every type that is
     /// referenced from an explicitly whitelisted item. One way to provide the
     /// definitions is by using the [`Builder::raw_line`](#method.raw_line)
     /// method, another would be to define them in Rust and then `include!(...)`
     /// the bindings immediately afterwards.
     pub fn whitelist_recursively(mut self, doit: bool) -> Self {
         self.options.whitelist_recursively = doit;
         self
     }
@@ -735,16 +749,21 @@ impl Builder {
     /// Whitelist the given variable.
     ///
     /// Deprecated: use whitelist_var instead.
     #[deprecated(note = "use whitelist_var instead")]
     pub fn whitelisted_var<T: AsRef<str>>(self, arg: T) -> Builder {
         self.whitelist_var(arg)
     }
 
+    /// Set the default style of code to generate for enums
+    pub fn default_enum_style(mut self, arg: codegen::EnumVariation) -> Builder {
+        self.options.default_enum_style = arg;
+        self
+    }
 
     /// Mark the given enum (or set of enums, if using a pattern) as being
     /// bitfield-like. Regular expressions are supported.
     ///
     /// This makes bindgen generate a type that isn't a rust `enum`. Regular
     /// expressions are supported.
     pub fn bitfield_enum<T: AsRef<str>>(mut self, arg: T) -> Builder {
         self.options.bitfield_enums.insert(arg);
@@ -762,32 +781,68 @@ impl Builder {
     /// Take a look at https://github.com/rust-lang/rust/issues/36927 for
     /// more information.
     pub fn rustified_enum<T: AsRef<str>>(mut self, arg: T) -> Builder {
         self.options.rustified_enums.insert(arg);
         self
     }
 
     /// Mark the given enum (or set of enums, if using a pattern) as a set of
+    /// constants that are not to be put into a module.
+    pub fn constified_enum<T: AsRef<str>>(mut self, arg: T) -> Builder {
+        self.options.constified_enums.insert(arg);
+        self
+    }
+
+    /// Mark the given enum (or set of enums, if using a pattern) as a set of
     /// constants that should be put into a module.
     ///
     /// This makes bindgen generate modules containing constants instead of
     /// just constants. Regular expressions are supported.
     pub fn constified_enum_module<T: AsRef<str>>(mut self, arg: T) -> Builder {
         self.options.constified_enum_modules.insert(arg);
         self
     }
 
     /// Add a string to prepend to the generated bindings. The string is passed
     /// through without any modification.
-    pub fn raw_line<T: Into<String>>(mut self, arg: T) -> Builder {
+    pub fn raw_line<T: Into<String>>(mut self, arg: T) -> Self {
         self.options.raw_lines.push(arg.into());
         self
     }
 
+    /// Add a given line to the beginning of module `mod`.
+    pub fn module_raw_line<T, U>(mut self, mod_: T, line: U) -> Self
+    where
+        T: Into<String>,
+        U: Into<String>,
+    {
+        self.options
+            .module_lines
+            .entry(mod_.into())
+            .or_insert_with(Vec::new)
+            .push(line.into());
+        self
+    }
+
+    /// Add a given set of lines to the beginning of module `mod`.
+    pub fn module_raw_lines<T, I>(mut self, mod_: T, lines: I) -> Self
+    where
+        T: Into<String>,
+        I: IntoIterator,
+        I::Item: Into<String>,
+    {
+        self.options
+            .module_lines
+            .entry(mod_.into())
+            .or_insert_with(Vec::new)
+            .extend(lines.into_iter().map(Into::into));
+        self
+    }
+
     /// Add an argument to be passed straight through to clang.
     pub fn clang_arg<T: Into<String>>(mut self, arg: T) -> Builder {
         self.options.clang_args.push(arg.into());
         self
     }
 
     /// Add arguments to be passed straight through to clang.
     pub fn clang_args<I>(mut self, iter: I) -> Builder
@@ -796,36 +851,16 @@ impl Builder {
         I::Item: AsRef<str>,
     {
         for arg in iter {
             self = self.clang_arg(arg.as_ref())
         }
         self
     }
 
-    /// Make the generated bindings link the given shared library.
-    pub fn link<T: Into<String>>(mut self, library: T) -> Builder {
-        self.options.links.push((library.into(), LinkType::Default));
-        self
-    }
-
-    /// Make the generated bindings link the given static library.
-    pub fn link_static<T: Into<String>>(mut self, library: T) -> Builder {
-        self.options.links.push((library.into(), LinkType::Static));
-        self
-    }
-
-    /// Make the generated bindings link the given framework.
-    pub fn link_framework<T: Into<String>>(mut self, library: T) -> Builder {
-        self.options.links.push(
-            (library.into(), LinkType::Framework),
-        );
-        self
-    }
-
     /// Emit bindings for builtin definitions (for example `__builtin_va_list`)
     /// in the generated Rust.
     pub fn emit_builtins(mut self) -> Builder {
         self.options.builtins = true;
         self
     }
 
     /// Avoid converting floats to `f32`/`f64` by default.
@@ -1237,31 +1272,34 @@ struct BindgenOptions {
     whitelisted_types: RegexSet,
 
     /// Whitelisted functions. See docs for `whitelisted_types` for more.
     whitelisted_functions: RegexSet,
 
     /// Whitelisted variables. See docs for `whitelisted_types` for more.
     whitelisted_vars: RegexSet,
 
+    /// The default style of code to generate for enums
+    default_enum_style: codegen::EnumVariation,
+
     /// The enum patterns to mark an enum as bitfield.
     bitfield_enums: RegexSet,
 
     /// The enum patterns to mark an enum as a Rust enum.
     rustified_enums: RegexSet,
 
     /// The enum patterns to mark an enum as a module of constants.
     constified_enum_modules: RegexSet,
 
+    /// The enum patterns to mark an enum as a set of constants.
+    constified_enums: RegexSet,
+
     /// Whether we should generate builtins or not.
     builtins: bool,
 
-    /// The set of libraries we should link in the generated Rust code.
-    links: Vec<(String, LinkType)>,
-
     /// True if we should dump the Clang AST for debugging purposes.
     emit_ast: bool,
 
     /// True if we should dump our internal IR for debugging purposes.
     emit_ir: bool,
 
     /// Output graphviz dot file.
     emit_ir_graphviz: Option<String>,
@@ -1276,17 +1314,17 @@ struct BindgenOptions {
     /// True if we should generate layout tests for generated structures.
     layout_tests: bool,
 
     /// True if we should implement the Debug trait for C/C++ structures and types
     /// that do not support automatically deriving Debug.
     impl_debug: bool,
 
     /// True if we should implement the PartialEq trait for C/C++ structures and types
-    /// that do not support autoamically deriving PartialEq.
+    /// that do not support automatically deriving PartialEq.
     impl_partialeq: bool,
 
     /// True if we should derive Copy trait implementations for C/C++ structures
     /// and types.
     derive_copy: bool,
 
     /// True if we should derive Debug trait implementations for C/C++ structures
     /// and types.
@@ -1330,19 +1368,25 @@ struct BindgenOptions {
     namespaced_constants: bool,
 
     /// True if we should use MSVC name mangling rules.
     msvc_mangling: bool,
 
     /// Whether we should convert float types to f32/f64 types.
     convert_floats: bool,
 
-    /// The set of raw lines to prepend to the generated Rust code.
+    /// The set of raw lines to prepend to the top-level module of generated
+    /// Rust code.
     raw_lines: Vec<String>,
 
+    /// The set of raw lines to prepend to each of the modules.
+    ///
+    /// This only makes sense if the `enable_cxx_namespaces` option is set.
+    module_lines: HashMap<String, Vec<String>>,
+
     /// The set of arguments to pass straight through to Clang.
     clang_args: Vec<String>,
 
     /// The input header file.
     input_header: Option<String>,
 
     /// Unsaved files for input.
     input_unsaved_files: Vec<clang::UnsavedFile>,
@@ -1355,27 +1399,27 @@ struct BindgenOptions {
     /// of them.
     codegen_config: CodegenConfig,
 
     /// Whether to treat inline namespaces conservatively.
     ///
     /// See the builder method description for more details.
     conservative_inline_namespaces: bool,
 
-    /// Wether to keep documentation comments in the generated output. See the
+    /// Whether to keep documentation comments in the generated output. See the
     /// documentation for more details.
     generate_comments: bool,
 
     /// Whether to generate inline functions. Defaults to false.
     generate_inline_functions: bool,
 
-    /// Wether to whitelist types recursively. Defaults to true.
+    /// Whether to whitelist types recursively. Defaults to true.
     whitelist_recursively: bool,
 
-    /// Intead of emitting 'use objc;' to files generated from objective c files,
+    /// Instead of emitting 'use objc;' to files generated from objective c files,
     /// generate '#[macro_use] extern crate objc;'
     objc_extern_crate: bool,
 
     /// Whether to use the clang-provided name mangling. This is true and
     /// probably needed for C++ features.
     ///
     /// However, some old libclang versions seem to return incorrect results in
     /// some cases for non-mangled functions, see [1], so we allow disabling it.
@@ -1418,16 +1462,17 @@ impl ::std::panic::UnwindSafe for Bindge
 impl BindgenOptions {
     fn build(&mut self) {
         self.whitelisted_vars.build();
         self.whitelisted_types.build();
         self.whitelisted_functions.build();
         self.blacklisted_types.build();
         self.opaque_types.build();
         self.bitfield_enums.build();
+        self.constified_enums.build();
         self.constified_enum_modules.build();
         self.rustified_enums.build();
         self.no_partialeq_types.build();
         self.no_copy_types.build();
         self.no_hash_types.build();
     }
 
     /// Update rust target version
@@ -1452,21 +1497,22 @@ impl Default for BindgenOptions {
             rust_target: rust_target,
             rust_features: rust_target.into(),
             blacklisted_types: Default::default(),
             opaque_types: Default::default(),
             rustfmt_path: Default::default(),
             whitelisted_types: Default::default(),
             whitelisted_functions: Default::default(),
             whitelisted_vars: Default::default(),
+            default_enum_style: Default::default(),
             bitfield_enums: Default::default(),
             rustified_enums: Default::default(),
+            constified_enums: Default::default(),
             constified_enum_modules: Default::default(),
             builtins: false,
-            links: vec![],
             emit_ast: false,
             emit_ir: false,
             emit_ir_graphviz: None,
             layout_tests: true,
             impl_debug: false,
             impl_partialeq: false,
             derive_copy: true,
             derive_debug: true,
@@ -1479,16 +1525,17 @@ impl Default for BindgenOptions {
             enable_cxx_namespaces: false,
             disable_name_namespacing: false,
             use_core: false,
             ctypes_prefix: None,
             namespaced_constants: true,
             msvc_mangling: false,
             convert_floats: true,
             raw_lines: vec![],
+            module_lines: HashMap::default(),
             clang_args: vec![],
             input_header: None,
             input_unsaved_files: vec![],
             parse_callbacks: None,
             codegen_config: CodegenConfig::all(),
             conservative_inline_namespaces: false,
             generate_comments: true,
             generate_inline_functions: false,
@@ -1501,29 +1548,16 @@ impl Default for BindgenOptions {
             rustfmt_configuration_file: None,
             no_partialeq_types: Default::default(),
             no_copy_types: Default::default(),
             no_hash_types: Default::default(),
         }
     }
 }
 
-/// The linking type to use with a given library.
-///
-/// TODO: #104: This is ignored at the moment, but shouldn't be.
-#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
-pub enum LinkType {
-    /// Use shared library linking. This is the default.
-    Default,
-    /// Use static linking.
-    Static,
-    /// The library is an OSX framework.
-    Framework,
-}
-
 fn ensure_libclang_is_loaded() {
     if clang_sys::is_loaded() {
         return;
     }
 
     // XXX (issue #350): Ensure that our dynamically loaded `libclang`
     // doesn't get dropped prematurely, nor is loaded multiple times
     // across different threads.
@@ -1691,25 +1725,25 @@ impl Bindings {
             writer.write(line.as_bytes())?;
             writer.write("\n".as_bytes())?;
         }
 
         if !self.options.raw_lines.is_empty() {
             writer.write("\n".as_bytes())?;
         }
 
-        let bindings = self.module.as_str().to_string();
+        let bindings = self.module.to_string();
 
         match self.rustfmt_generated_string(&bindings) {
             Ok(rustfmt_bindings) => {
                 writer.write(rustfmt_bindings.as_bytes())?;
             },
             Err(err) => {
                 eprintln!("{:?}", err);
-                writer.write(bindings.as_str().as_bytes())?;
+                writer.write(bindings.as_bytes())?;
             },
         }
         Ok(())
     }
 
     /// Checks if rustfmt_bindings is set and runs rustfmt on the string
     fn rustfmt_generated_string<'a>(
         &self,
@@ -1860,23 +1894,23 @@ fn parse(context: &mut BindgenContext) -
         "How did this happen?"
     );
     Ok(())
 }
 
 /// Extracted Clang version data
 #[derive(Debug)]
 pub struct ClangVersion {
-    /// Major and minor semvar, if parsing was successful
+    /// Major and minor semver, if parsing was successful
     pub parsed: Option<(u32, u32)>,
     /// full version string
     pub full: String,
 }
 
-/// Get the major and the minor semvar numbers of Clang's version
+/// Get the major and the minor semver numbers of Clang's version
 pub fn clang_version() -> ClangVersion {
     if !clang_sys::is_loaded() {
         // TODO(emilio): Return meaningful error (breaking).
         clang_sys::load().expect("Unable to find libclang");
     }
 
     let raw_v: String = clang::extract_clang_version();
     let split_v: Option<Vec<&str>> = raw_v.split_whitespace().nth(2).map(|v| {
--- a/third_party/rust/bindgen/src/options.rs
+++ b/third_party/rust/bindgen/src/options.rs
@@ -1,9 +1,9 @@
-use bindgen::{Builder, CodegenConfig, RUST_TARGET_STRINGS, RustTarget, builder};
+use bindgen::{Builder, CodegenConfig, RUST_TARGET_STRINGS, RustTarget, builder, EnumVariation};
 use clap::{App, Arg};
 use std::fs::File;
 use std::io::{self, Error, ErrorKind, Write, stderr};
 use std::path::PathBuf;
 use std::str::FromStr;
 
 /// Construct a new [`Builder`](./struct.Builder.html) from command line flags.
 pub fn builder_from_flags<I>(
@@ -21,36 +21,50 @@ where
     let matches = App::new("bindgen")
         .version(option_env!("CARGO_PKG_VERSION").unwrap_or("unknown"))
         .about("Generates Rust bindings from C/C++ headers.")
         .usage("bindgen [FLAGS] [OPTIONS] <header> -- <clang-args>...")
         .args(&[
             Arg::with_name("header")
                 .help("C or C++ header file")
                 .required(true),
+            Arg::with_name("default-enum-style")
+                .long("default-enum-style")
+                .help("The default style of code used to generate enums.")
+                .value_name("variant")
+                .default_value("consts")
+                .possible_values(&["consts", "moduleconsts", "bitfield", "rust"])
+                .multiple(false),
             Arg::with_name("bitfield-enum")
                 .long("bitfield-enum")
                 .help("Mark any enum whose name matches <regex> as a set of \
-                       bitfield flags instead of an enumeration.")
+                       bitfield flags.")
                 .value_name("regex")
                 .takes_value(true)
                 .multiple(true)
                 .number_of_values(1),
             Arg::with_name("rustified-enum")
                 .long("rustified-enum")
-                .help("Mark any enum whose name matches <regex> as a Rust enum \
-                       instead of a set of constants.")
+                .help("Mark any enum whose name matches <regex> as a Rust enum.")
+                .value_name("regex")
+                .takes_value(true)
+                .multiple(true)
+                .number_of_values(1),
+            Arg::with_name("constified-enum")
+                .long("constified-enum")
+                .help("Mark any enum whose name matches <regex> as a series of \
+                       constants.")
                 .value_name("regex")
                 .takes_value(true)
                 .multiple(true)
                 .number_of_values(1),
             Arg::with_name("constified-enum-module")
                 .long("constified-enum-module")
                 .help("Mark any enum whose name matches <regex> as a module of \
-                       constants instead of just constants.")
+                       constants.")
                 .value_name("regex")
                 .takes_value(true)
                 .multiple(true)
                 .number_of_values(1),
             Arg::with_name("blacklist-type")
                 .long("blacklist-type")
                 .help("Mark <type> as hidden.")
                 .value_name("type")
@@ -144,42 +158,29 @@ where
             Arg::with_name("enable-cxx-namespaces")
                 .long("enable-cxx-namespaces")
                 .help("Enable support for C++ namespaces."),
             Arg::with_name("disable-name-namespacing")
                 .long("disable-name-namespacing")
                 .help("Disable namespacing via mangling, causing bindgen to \
                        generate names like \"Baz\" instead of \"foo_bar_Baz\" \
                        for an input name \"foo::bar::Baz\"."),
-            Arg::with_name("framework")
-                .long("framework-link")
-                .help("Link to framework.")
-                .takes_value(true)
-                .multiple(true)
-                .number_of_values(1),
             Arg::with_name("ignore-functions")
                 .long("ignore-functions")
                 .help("Do not generate bindings for functions or methods. This \
                        is useful when you only care about struct layouts."),
             Arg::with_name("generate")
                 .long("generate")
                 .help("Generate only given items, split by commas. \
                        Valid values are \"functions\",\"types\", \"vars\", \
                        \"methods\", \"constructors\" and \"destructors\".")
                 .takes_value(true),
             Arg::with_name("ignore-methods")
                 .long("ignore-methods")
                 .help("Do not generate bindings for methods."),
-            Arg::with_name("dynamic")
-                .short("l")
-                .long("link")
-                .help("Link to dynamic library.")
-                .takes_value(true)
-                .multiple(true)
-                .number_of_values(1),
             Arg::with_name("no-convert-floats")
                 .long("no-convert-floats")
                 .help("Do not automatically convert floats to f32/f64."),
             Arg::with_name("no-prepend-enum-name")
                 .long("no-prepend-enum-name")
                 .help("Do not prepend the enum name to bitfield or constant variants."),
             Arg::with_name("unstable-rust")
                 .long("unstable-rust")
@@ -202,22 +203,16 @@ where
                 .help("Add a raw line of Rust code at the beginning of output.")
                 .takes_value(true)
                 .multiple(true)
                 .number_of_values(1),
             Arg::with_name("rust-target")
                 .long("rust-target")
                 .help(&rust_target_help)
                 .takes_value(true),
-            Arg::with_name("static")
-                .long("static-link")
-                .help("Link to static library.")
-                .takes_value(true)
-                .multiple(true)
-                .number_of_values(1),
             Arg::with_name("use-core")
                 .long("use-core")
                 .help("Use types from Rust core instead of std."),
             Arg::with_name("conservative-inline-namespaces")
                 .long("conservative-inline-namespaces")
                 .help("Conservatively generate inline namespaces to avoid name \
                        conflicts."),
             Arg::with_name("use-msvc-mangling")
@@ -317,28 +312,38 @@ where
             "warning: the `--unstable-rust` option is deprecated"
         ).expect("Unable to write error message");
     }
 
     if let Some(rust_target) = matches.value_of("rust-target") {
         builder = builder.rust_target(RustTarget::from_str(rust_target)?);
     }
 
+    if let Some(variant) = matches.value_of("default-enum-style") {
+        builder = builder.default_enum_style(EnumVariation::from_str(variant)?)
+    }
+
     if let Some(bitfields) = matches.values_of("bitfield-enum") {
         for regex in bitfields {
             builder = builder.bitfield_enum(regex);
         }
     }
 
     if let Some(rustifieds) = matches.values_of("rustified-enum") {
         for regex in rustifieds {
             builder = builder.rustified_enum(regex);
         }
     }
 
+    if let Some(bitfields) = matches.values_of("constified-enum") {
+        for regex in bitfields {
+            builder = builder.constified_enum(regex);
+        }
+    }
+
     if let Some(constified_mods) = matches.values_of("constified-enum-module") {
         for regex in constified_mods {
             builder = builder.constified_enum_module(regex);
         }
     }
     if let Some(hidden_types) = matches.values_of("blacklist-type") {
         for ty in hidden_types {
             builder = builder.blacklist_type(ty);
@@ -404,22 +409,16 @@ where
     if matches.is_present("time-phases") {
         builder = builder.time_phases(true);
     }
 
     if let Some(prefix) = matches.value_of("ctypes-prefix") {
         builder = builder.ctypes_prefix(prefix);
     }
 
-    if let Some(links) = matches.values_of("dynamic") {
-        for library in links {
-            builder = builder.link(library);
-        }
-    }
-
     if let Some(what_to_generate) = matches.value_of("generate") {
         let mut config = CodegenConfig::nothing();
         for what in what_to_generate.split(",") {
             match what {
                 "functions" => config.functions = true,
                 "types" => config.types = true,
                 "vars" => config.vars = true,
                 "methods" => config.methods = true,
@@ -451,22 +450,16 @@ where
     if matches.is_present("enable-cxx-namespaces") {
         builder = builder.enable_cxx_namespaces();
     }
 
     if matches.is_present("disable-name-namespacing") {
         builder = builder.disable_name_namespacing();
     }
 
-    if let Some(links) = matches.values_of("framework") {
-        for framework in links {
-            builder = builder.link_framework(framework);
-        }
-    }
-
     if matches.is_present("ignore-functions") {
         builder = builder.ignore_functions();
     }
 
     if matches.is_present("ignore-methods") {
         builder = builder.ignore_methods();
     }
 
@@ -493,22 +486,16 @@ where
     }
 
     if let Some(lines) = matches.values_of("raw-line") {
         for line in lines {
             builder = builder.raw_line(line);
         }
     }
 
-    if let Some(links) = matches.values_of("static") {
-        for library in links {
-            builder = builder.link_static(library);
-        }
-    }
-
     if matches.is_present("use-core") {
         builder = builder.use_core();
     }
 
     if matches.is_present("distrust-clang-mangling") {
         builder = builder.trust_clang_mangling(false);
     }
 
--- a/third_party/rust/bindgen/src/time.rs
+++ b/third_party/rust/bindgen/src/time.rs
@@ -17,17 +17,17 @@ impl<'a> Timer<'a> {
     pub fn new(name: &'a str) -> Self {
         Timer {
             output: true,
             name,
             start: Instant::now()
         }
     }
 
-    /// Sets whether or not the Timer will print a mesage
+    /// Sets whether or not the Timer will print a message
     /// when it is dropped.
     pub fn with_output(mut self, output: bool) -> Self {
         self.output = output;
         self
     }
 
     /// Returns the time elapsed since the timer's creation
     pub fn elapsed(&self) -> Duration {
--- a/third_party/rust/clang-sys/.cargo-checksum.json
+++ b/third_party/rust/clang-sys/.cargo-checksum.json
@@ -1,1 +1,1 @@
-{"files":{".travis.yml":"d5c89494c836e00ec8c3c02c9e228bf5dc34aabff203c37662a248e2da4bda05","CHANGELOG.md":"2d6ade5cd80d388392915d24f4712e8fd604579c7b26d48aa99908499e08817d","CONTRIBUTING.md":"4e2a45992604f07a37030bb1fc598c6f54a1785747c4f37a15a37481bbdecce8","Cargo.toml":"c2256b278d66bf80e6b62e58efa62a5fb98665c8c23dec68829b2c9fc2191962","LICENSE.txt":"cfc7749b96f63bd31c3c42b5c471bf756814053e847c10f3eb003417bc523d30","README.md":"dff1b472fe1edbc6059ff5a96e595fa8dab9e9e133d10fd761cf5dfdcc80f4c6","appveyor.yml":"c9ab8ab1ab028b27d2be176e994a0d6a255cf8bcc36e15868472b6b8abf33fac","build.rs":"e6cf2ec64466b21f3e6eb8aaf7327ccdfcc77a2067e0e19ee5e2a6f57117c09b","ci/before_install.sh":"711c9d0539fa0372980c3a288d9482a0e46d3ba0fb8f7c7c110d6488a8ec4de5","ci/install.bat":"fb636c3511ba038ccf805755ef6542237cc595e905edcd61d56abd7163321f76","ci/script.sh":"1bb1cd29bd9635cc126cdcbd6c02f3500620a231a86726bf2165a4b74baaf433","ci/test_script.bat":"73462f51aaa9a1c14ce9f55c41dc3672df64faa9789725384ae4f28d8ba3c90b","clippy.toml":"acef14b9acffa18d1069ae08a4e8fe824a614f91b0bc71a6b1c68e4d885397e6","src/lib.rs":"a0410d2e23f808ba441e7bebe84785e85582c8130613e49c7b3b98e0aaf55b66","src/link.rs":"7323c3ddcd8038b899c21f7087666628f88e9cb430900549855ea78717824e6f","src/support.rs":"ecd0489662caad0a13ea468cbbbec3ca62ba9796a6e24aabb392978a3455ebfd","tests/header.h":"b1cf564b21d76db78529d1934e1481a5f0452fdedc6e32954608293c310498b6","tests/lib.rs":"e5e8a60bcaec3b5d043fde4a993d397adb56454d0b2a6adaa15df0535246f909"},"package":"939a1a34310b120d26eba35c29475933128b0ec58e24b43327f8dbe6036fc538"}
\ No newline at end of file
+{"files":{".travis.yml":"d5c89494c836e00ec8c3c02c9e228bf5dc34aabff203c37662a248e2da4bda05","CHANGELOG.md":"62fd8ba43afbc4da3dba40d448a5af482794aaaa99071d40dc7abf8fc1a2195b","Cargo.toml":"1ada60cd29713d4386050d2b61a9eed430827885520816b0412ed0380fa3fa8f","LICENSE.txt":"cfc7749b96f63bd31c3c42b5c471bf756814053e847c10f3eb003417bc523d30","README.md":"dff1b472fe1edbc6059ff5a96e595fa8dab9e9e133d10fd761cf5dfdcc80f4c6","appveyor.yml":"c9ab8ab1ab028b27d2be176e994a0d6a255cf8bcc36e15868472b6b8abf33fac","build.rs":"50be9c247e528ab0a354a7652fa9516906f79bbb4d128d54db7f5a9ee1ed2a86","ci/before_install.sh":"711c9d0539fa0372980c3a288d9482a0e46d3ba0fb8f7c7c110d6488a8ec4de5","ci/install.bat":"fb636c3511ba038ccf805755ef6542237cc595e905edcd61d56abd7163321f76","ci/script.sh":"1bb1cd29bd9635cc126cdcbd6c02f3500620a231a86726bf2165a4b74baaf433","ci/test_script.bat":"73462f51aaa9a1c14ce9f55c41dc3672df64faa9789725384ae4f28d8ba3c90b","clippy.toml":"acef14b9acffa18d1069ae08a4e8fe824a614f91b0bc71a6b1c68e4d885397e6","src/lib.rs":"d0a11284694f4f77448e72480addca613572d19c07fa92157e0fa717ed504abd","src/link.rs":"a0208e6b8e4840f1162b3b799b5e12dd559cc6f31a330b0eb1ba4ebe2385296d","src/support.rs":"70e77ea4337f740b13c394034c5705e962af6ee7ac4843fc7c9c7fe22ec2d074","tests/header.h":"b1cf564b21d76db78529d1934e1481a5f0452fdedc6e32954608293c310498b6","tests/lib.rs":"e5e8a60bcaec3b5d043fde4a993d397adb56454d0b2a6adaa15df0535246f909"},"package":"d7f7c04e52c35222fffcc3a115b5daf5f7e2bfb71c13c4e2321afe1fc71859c2"}
\ No newline at end of file
--- a/third_party/rust/clang-sys/CHANGELOG.md
+++ b/third_party/rust/clang-sys/CHANGELOG.md
@@ -1,8 +1,13 @@
+## [0.23.0] - 2018-06-16
+
+### Changed
+- Changed `Clang::find` to skip dynamic libraries for an incorrect architecture on Windows
+
 ## [0.22.0] - 2018-03-11
 
 ### Added
 - Added support for `clang` 6.0.x
 - Bumped `libc` version to `0.2.39`
 - Bumped `libloading` version to `0.5.0`
 
 ## [0.21.2] - 2018-02-17
deleted file mode 100644
--- a/third_party/rust/clang-sys/CONTRIBUTING.md
+++ /dev/null
@@ -1,7 +0,0 @@
-# Contributing to clang-sys
-
-## Pull Requests
-
-If you are intending to make a pull request, please make your changes in a branch that originated
-from the `development` branch, not the `master` branch. Then, make your pull request against the
-`development` branch.
--- a/third_party/rust/clang-sys/Cargo.toml
+++ b/third_party/rust/clang-sys/Cargo.toml
@@ -7,42 +7,34 @@
 #
 # If you believe there's an error in this file please file an
 # issue against the rust-lang/cargo repository. If you're
 # editing this file be aware that the upstream Cargo.toml
 # will likely look very different (and much more reasonable)
 
 [package]
 name = "clang-sys"
-version = "0.22.0"
+version = "0.23.0"
 authors = ["Kyle Mayes <kyle@mayeses.com>"]
 build = "build.rs"
 links = "clang"
 description = "Rust bindings for libclang."
 documentation = "https://kylemayes.github.io/clang-sys/3_5/clang_sys"
 readme = "README.md"
 license = "Apache-2.0"
 repository = "https://github.com/KyleMayes/clang-sys"
-[dependencies.clippy]
-version = "0.0.*"
-optional = true
-
 [dependencies.glob]
 version = "0.2.11"
 
 [dependencies.libc]
 version = "0.2.39"
 
 [dependencies.libloading]
 version = "0.5.0"
 optional = true
-[build-dependencies.clippy]
-version = "0.0.*"
-optional = true
-
 [build-dependencies.glob]
 version = "0.2.11"
 
 [features]
 clang_3_5 = []
 clang_3_6 = ["gte_clang_3_6"]
 clang_3_7 = ["gte_clang_3_6", "gte_clang_3_7"]
 clang_3_8 = ["gte_clang_3_6", "gte_clang_3_7", "gte_clang_3_8"]
--- a/third_party/rust/clang-sys/build.rs
+++ b/third_party/rust/clang-sys/build.rs
@@ -20,25 +20,21 @@
 //! static or dynamic libraries.
 //!
 //! * `LLVM_CONFIG_PATH` - provides a path to an `llvm-config` executable
 //! * `LIBCLANG_PATH` - provides a path to a directory containing a `libclang` shared library
 //! * `LIBCLANG_STATIC_PATH` - provides a path to a directory containing LLVM and Clang static libraries
 
 #![allow(unused_attributes)]
 
-#![cfg_attr(feature="clippy", feature(plugin))]
-#![cfg_attr(feature="clippy", plugin(clippy))]
-#![cfg_attr(feature="clippy", warn(clippy))]
-
 extern crate glob;
 
 use std::env;
 use std::fs::{self, File};
-use std::io::{Read};
+use std::io::{Read, Seek, SeekFrom};
 use std::path::{Path, PathBuf};
 use std::process::{Command};
 
 use glob::{MatchOptions};
 
 /// Returns the version in the supplied file if one can be found.
 fn find_version(file: &str) -> Option<&str> {
     if file.starts_with("libclang.so.") {
@@ -123,43 +119,85 @@ const SEARCH_OSX: &[&str] = &[
 
 /// Backup search directory globs for Windows.
 const SEARCH_WINDOWS: &[&str] = &[
     "C:\\LLVM\\lib",
     "C:\\Program Files*\\LLVM\\lib",
     "C:\\MSYS*\\MinGW*\\lib",
 ];
 
+/// Returns the ELF class from the ELF header in the supplied file.
+fn parse_elf_header(file: &PathBuf) -> Result<u8, String> {
+    let mut file = try!(File::open(file).map_err(|e| e.to_string()));
+    let mut elf = [0; 5];
+    try!(file.read_exact(&mut elf).map_err(|e| e.to_string()));
+    if elf[..4] == [127, 69, 76, 70] {
+        Ok(elf[4])
+    } else {
+        Err("invalid ELF header".into())
+    }
+}
+
+/// Returns the magic number from the PE header in the supplied file.
+fn parse_pe_header(file: &PathBuf) -> Result<u16, String> {
+    let mut file = try!(File::open(file).map_err(|e| e.to_string()));
+    let mut pe = [0; 4];
+
+    // Determine the header offset.
+    try!(file.seek(SeekFrom::Start(0x3C)).map_err(|e| e.to_string()));
+    try!(file.read_exact(&mut pe).map_err(|e| e.to_string()));
+    let offset = i32::from(pe[0]) + (i32::from(pe[1]) << 8) + (i32::from(pe[2]) << 16) + (i32::from(pe[3]) << 24);
+
+    // Determine the validity of the header.
+    try!(file.seek(SeekFrom::Start(offset as u64)).map_err(|e| e.to_string()));
+    try!(file.read_exact(&mut pe).map_err(|e| e.to_string()));
+    if pe != [80, 69, 0, 0] {
+        return Err("invalid PE header".into());
+    }
+
+    // Find the magic number.
+    try!(file.seek(SeekFrom::Current(20)).map_err(|e| e.to_string()));
+    try!(file.read_exact(&mut pe).map_err(|e| e.to_string()));
+    Ok(u16::from(pe[0]) + (u16::from(pe[1]) << 8))
+}
+
 /// Indicates the type of library being searched for.
 #[derive(Copy, Clone, Debug, PartialEq, Eq)]
 enum Library {
     Dynamic,
     Static,
 }
 
 impl Library {
     /// Checks whether the supplied file is a valid library for the architecture.
     fn check(&self, file: &PathBuf) -> Result<(), String> {
         if cfg!(any(target_os="freebsd", target_os="linux")) {
             if *self == Library::Static {
                 return Ok(());
             }
-            let mut file = try!(File::open(file).map_err(|e| e.to_string()));
-            let mut elf = [0; 5];
-            try!(file.read_exact(&mut elf).map_err(|e| e.to_string()));
-            if elf[..4] != [127, 69, 76, 70] {
-                return Err("invalid ELF header".into());
-            }
-            if cfg!(target_pointer_width="32") && elf[4] != 1 {
+            let class = try!(parse_elf_header(file));
+            if cfg!(target_pointer_width="32") && class != 1 {
                 return Err("invalid ELF class (64-bit)".into());
             }
-            if cfg!(target_pointer_width="64") && elf[4] != 2 {
+            if cfg!(target_pointer_width="64") && class != 2 {
                 return Err("invalid ELF class (32-bit)".into());
             }
             Ok(())
+        } else if cfg!(target_os="windows") {
+            if *self == Library::Static {
+                return Ok(());
+            }
+            let magic = try!(parse_pe_header(file));
+            if cfg!(target_pointer_width="32") && magic != 267 {
+                return Err("invalid DLL (64-bit)".into());
+            }
+            if cfg!(target_pointer_width="64") && magic != 523 {
+                return Err("invalid DLL (32-bit)".into());
+            }
+            Ok(())
         } else {
             Ok(())
         }
     }
 }
 
 /// Searches for a library, returning the directory it can be found in if the search was successful.
 fn find(library: Library, files: &[String], env: &str) -> Result<PathBuf, String> {
@@ -211,17 +249,17 @@ fn find(library: Library, files: &[Strin
         let lib = directory.join("lib");
         if let Some(file) = contains(&lib, files) {
             try_file!(file);
         }
     }
 
     // Search the `LD_LIBRARY_PATH` directories.
     if let Ok(path) = env::var("LD_LIBRARY_PATH") {
-        for directory in path.split(":").map(Path::new) {
+        for directory in path.split(':').map(Path::new) {
             search_directory!(directory);
         }
     }
 
     // Search the backup directories.
     let search = if cfg!(any(target_os="freebsd", target_os="linux")) {
         SEARCH_LINUX
     } else if cfg!(target_os="macos") {
--- a/third_party/rust/clang-sys/src/lib.rs
+++ b/third_party/rust/clang-sys/src/lib.rs
@@ -22,20 +22,17 @@
 //! * 3.8 - [Documentation](https://kylemayes.github.io/clang-sys/3_8/clang_sys)
 //! * 3.9 - [Documentation](https://kylemayes.github.io/clang-sys/3_9/clang_sys)
 //! * 4.0 - [Documentation](https://kylemayes.github.io/clang-sys/4_0/clang_sys)
 //! * 5.0 - [Documentation](https://kylemayes.github.io/clang-sys/5_0/clang_sys)
 //! * 6.0 - [Documentation](https://kylemayes.github.io/clang-sys/6_0/clang_sys)
 
 #![allow(non_camel_case_types, non_snake_case, non_upper_case_globals)]
 
-#![cfg_attr(feature="clippy", feature(plugin))]
-#![cfg_attr(feature="clippy", plugin(clippy))]
-#![cfg_attr(feature="clippy", warn(clippy))]
-#![cfg_attr(feature="clippy", allow(unreadable_literal))]
+#![cfg_attr(feature="cargo-clippy", allow(unreadable_literal))]
 
 extern crate glob;
 extern crate libc;
 #[cfg(feature="runtime")]
 extern crate libloading;
 
 pub mod support;
 
--- a/third_party/rust/clang-sys/src/link.rs
+++ b/third_party/rust/clang-sys/src/link.rs
@@ -75,17 +75,17 @@ macro_rules! link {
                 match l.borrow().as_ref() {
                     Some(library) => Some(f(&library)),
                     _ => None,
                 }
             })
         }
 
         $(
-            #[cfg_attr(feature="clippy", allow(too_many_arguments))]
+            #[cfg_attr(feature="cargo-clippy", allow(too_many_arguments))]
             $(#[cfg($cfg)])*
             pub unsafe fn $name($($pname: $pty), *) $(-> $ret)* {
                 let f = with_library(|l| {
                     match l.functions.$name {
                         Some(f) => f,
                         _ => panic!(concat!("function not loaded: ", stringify!($name))),
                     }
                 }).expect("a `libclang` shared library is not loaded on this thread");
--- a/third_party/rust/clang-sys/src/support.rs
+++ b/third_party/rust/clang-sys/src/support.rs
@@ -58,22 +58,17 @@ pub struct Clang {
 
 impl Clang {
     //- Constructors -----------------------------
 
     fn new(path: PathBuf, args: &[String]) -> Clang {
         let version = parse_version(&path);
         let c_search_paths = parse_search_paths(&path, "c", args);
         let cpp_search_paths = parse_search_paths(&path, "c++", args);
-        Clang {
-            path: path,
-            version: version,
-            c_search_paths: c_search_paths,
-            cpp_search_paths: cpp_search_paths,
-        }
+        Clang { path, version, c_search_paths, cpp_search_paths }
     }
 
     /// Returns a `clang` executable if one can be found.
     ///
     /// If the `CLANG_PATH` environment variable is set, that is the instance of `clang` used.
     /// Otherwise, a series of directories are searched. First, If a path is supplied, that is the
     /// first directory searched. Then, the directory returned by `llvm-config --bindir` is
     /// searched. On OS X systems, `xcodebuild -find clang` will next be queried. Last, the
new file mode 100644
--- /dev/null
+++ b/third_party/rust/proc-macro2-0.3.5/.cargo-checksum.json
@@ -0,0 +1,1 @@
+{"files":{".travis.yml":"872a0d195dcb1e84f28aa994f301c7139f70360bb42dee3954df5ee965efea15","Cargo.toml":"e71f764696d6998512da00a9ac309f2717d103707aeef81164f906c1588ede63","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"378f5840b258e2779c39418f3f2d7b2ba96f1c7917dd6be0713f88305dbda397","README.md":"ce05336717e1e90724491a2f54487c41c752fa2d32396639439f7c6d0f1e6776","src/lib.rs":"3280d7e0b6043d8472f418aa5c8458c97aa2b5a572f9156a251b5672828468c2","src/stable.rs":"4b5a65bd5dc174dd027b9ee951844c3765450f9d45961a8d6cd7d5f85b4c25c8","src/strnom.rs":"129fe22f0b50e5a64fca82e731c959135381c910e19f3305ef35420e0aadde08","src/unstable.rs":"b43c713ac16d9de0ba0fa1b9bebe390122b4ad60ef2fc75408f721305fdcd46b","tests/test.rs":"b06713fd8bd93ab9f0156bd25152e08f68a71b35e064c53b584f7f7dbb9b60b8"},"package":"77997c53ae6edd6d187fec07ec41b207063b5ee6f33680e9fa86d405cdd313d4"}
\ No newline at end of file
rename from third_party/rust/proc-macro2-0.3.6/.travis.yml
rename to third_party/rust/proc-macro2-0.3.5/.travis.yml
new file mode 100644
--- /dev/null
+++ b/third_party/rust/proc-macro2-0.3.5/Cargo.toml
@@ -0,0 +1,33 @@
+# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO
+#
+# When uploading crates to the registry Cargo will automatically
+# "normalize" Cargo.toml files for maximal compatibility
+# with all versions of Cargo and also rewrite `path` dependencies
+# to registry (e.g. crates.io) dependencies
+#
+# If you believe there's an error in this file please file an
+# issue against the rust-lang/cargo repository. If you're
+# editing this file be aware that the upstream Cargo.toml
+# will likely look very different (and much more reasonable)
+
+[package]
+name = "proc-macro2"
+version = "0.3.5"
+authors = ["Alex Crichton <alex@alexcrichton.com>"]
+description = "A stable implementation of the upcoming new `proc_macro` API. Comes with an\noption, off by default, to also reimplement itself in terms of the upstream\nunstable API.\n"
+homepage = "https://github.com/alexcrichton/proc-macro2"
+documentation = "https://docs.rs/proc-macro2"
+readme = "README.md"
+keywords = ["macros"]
+license = "MIT/Apache-2.0"
+repository = "https://github.com/alexcrichton/proc-macro2"
+
+[lib]
+doctest = false
+[dependencies.unicode-xid]
+version = "0.1"
+
+[features]
+default = ["proc-macro"]
+nightly = ["proc-macro"]
+proc-macro = []
rename from third_party/rust/proc-macro2-0.3.6/LICENSE-APACHE
rename to third_party/rust/proc-macro2-0.3.5/LICENSE-APACHE
rename from third_party/rust/proc-macro2-0.3.6/LICENSE-MIT
rename to third_party/rust/proc-macro2-0.3.5/LICENSE-MIT
rename from third_party/rust/proc-macro2-0.3.6/README.md
rename to third_party/rust/proc-macro2-0.3.5/README.md
new file mode 100644
--- /dev/null
+++ b/third_party/rust/proc-macro2-0.3.5/src/lib.rs
@@ -0,0 +1,590 @@
+//! A "shim crate" intended to multiplex the [`proc_macro`] API on to stable
+//! Rust.
+//!
+//! Procedural macros in Rust operate over the upstream
+//! [`proc_macro::TokenStream`][ts] type. This type currently is quite
+//! conservative and exposed no internal implementation details. Nightly
+//! compilers, however, contain a much richer interface. This richer interface
+//! allows fine-grained inspection of the token stream which avoids
+//! stringification/re-lexing and also preserves span information.
+//!
+//! The upcoming APIs added to [`proc_macro`] upstream are the foundation for
+//! productive procedural macros in the ecosystem. To help prepare the ecosystem
+//! for using them this crate serves to both compile on stable and nightly and
+//! mirrors the API-to-be. The intention is that procedural macros which switch
+//! to use this crate will be trivially able to switch to the upstream
+//! `proc_macro` crate once its API stabilizes.
+//!
+//! In the meantime this crate also has a `nightly` Cargo feature which
+//! enables it to reimplement itself with the unstable API of [`proc_macro`].
+//! This'll allow immediate usage of the beneficial upstream API, particularly
+//! around preserving span information.
+//!
+//! [`proc_macro`]: https://doc.rust-lang.org/proc_macro/
+//! [ts]: https://doc.rust-lang.org/proc_macro/struct.TokenStream.html
+
+// Proc-macro2 types in rustdoc of other crates get linked to here.
+#![doc(html_root_url = "https://docs.rs/proc-macro2/0.3.5")]
+#![cfg_attr(feature = "nightly", feature(proc_macro))]
+
+#[cfg(feature = "proc-macro")]
+extern crate proc_macro;
+
+#[cfg(not(feature = "nightly"))]
+extern crate unicode_xid;
+
+use std::fmt;
+use std::iter::FromIterator;
+use std::marker;
+use std::rc::Rc;
+use std::str::FromStr;
+
+#[macro_use]
+#[cfg(not(feature = "nightly"))]
+mod strnom;
+
+#[path = "stable.rs"]
+#[cfg(not(feature = "nightly"))]
+mod imp;
+#[path = "unstable.rs"]
+#[cfg(feature = "nightly")]
+mod imp;
+
+#[derive(Clone)]
+pub struct TokenStream {
+    inner: imp::TokenStream,
+    _marker: marker::PhantomData<Rc<()>>,
+}
+
+pub struct LexError {
+    inner: imp::LexError,
+    _marker: marker::PhantomData<Rc<()>>,
+}
+
+impl TokenStream {
+    fn _new(inner: imp::TokenStream) -> TokenStream {
+        TokenStream {
+            inner: inner,
+            _marker: marker::PhantomData,
+        }
+    }
+
+    pub fn empty() -> TokenStream {
+        TokenStream::_new(imp::TokenStream::empty())
+    }
+
+    pub fn is_empty(&self) -> bool {
+        self.inner.is_empty()
+    }
+}
+
+impl FromStr for TokenStream {
+    type Err = LexError;
+
+    fn from_str(src: &str) -> Result<TokenStream, LexError> {
+        let e = src.parse().map_err(|e| LexError {
+            inner: e,
+            _marker: marker::PhantomData,
+        })?;
+        Ok(TokenStream::_new(e))
+    }
+}
+
+#[cfg(feature = "proc-macro")]
+impl From<proc_macro::TokenStream> for TokenStream {
+    fn from(inner: proc_macro::TokenStream) -> TokenStream {
+        TokenStream::_new(inner.into())
+    }
+}
+
+#[cfg(feature = "proc-macro")]
+impl From<TokenStream> for proc_macro::TokenStream {
+    fn from(inner: TokenStream) -> proc_macro::TokenStream {
+        inner.inner.into()
+    }
+}
+
+impl FromIterator<TokenTree> for TokenStream {
+    fn from_iter<I: IntoIterator<Item = TokenTree>>(streams: I) -> Self {
+        TokenStream::_new(streams.into_iter().collect())
+    }
+}
+
+impl fmt::Display for TokenStream {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        self.inner.fmt(f)
+    }
+}
+
+impl fmt::Debug for TokenStream {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        self.inner.fmt(f)
+    }
+}
+
+impl fmt::Debug for LexError {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        self.inner.fmt(f)
+    }
+}
+
+// Returned by reference, so we can't easily wrap it.
+#[cfg(procmacro2_semver_exempt)]
+pub use imp::FileName;
+
+#[cfg(procmacro2_semver_exempt)]
+#[derive(Clone, PartialEq, Eq)]
+pub struct SourceFile(imp::SourceFile);
+
+#[cfg(procmacro2_semver_exempt)]
+impl SourceFile {
+    /// Get the path to this source file as a string.
+    pub fn path(&self) -> &FileName {
+        self.0.path()
+    }
+
+    pub fn is_real(&self) -> bool {
+        self.0.is_real()
+    }
+}
+
+#[cfg(procmacro2_semver_exempt)]
+impl AsRef<FileName> for SourceFile {
+    fn as_ref(&self) -> &FileName {
+        self.0.path()
+    }
+}
+
+#[cfg(procmacro2_semver_exempt)]
+impl fmt::Debug for SourceFile {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        self.0.fmt(f)
+    }
+}
+
+#[cfg(procmacro2_semver_exempt)]
+pub struct LineColumn {
+    pub line: usize,
+    pub column: usize,
+}
+
+#[derive(Copy, Clone)]
+pub struct Span {
+    inner: imp::Span,
+    _marker: marker::PhantomData<Rc<()>>,
+}
+
+impl Span {
+    fn _new(inner: imp::Span) -> Span {
+        Span {
+            inner: inner,
+            _marker: marker::PhantomData,
+        }
+    }
+
+    pub fn call_site() -> Span {
+        Span::_new(imp::Span::call_site())
+    }
+
+    #[cfg(procmacro2_semver_exempt)]
+    pub fn def_site() -> Span {
+        Span::_new(imp::Span::def_site())
+    }
+
+    /// Creates a new span with the same line/column information as `self` but
+    /// that resolves symbols as though it were at `other`.
+    #[cfg(procmacro2_semver_exempt)]
+    pub fn resolved_at(&self, other: Span) -> Span {
+        Span::_new(self.inner.resolved_at(other.inner))
+    }
+
+    /// Creates a new span with the same name resolution behavior as `self` but
+    /// with the line/column information of `other`.
+    #[cfg(procmacro2_semver_exempt)]
+    pub fn located_at(&self, other: Span) -> Span {
+        Span::_new(self.inner.located_at(other.inner))
+    }
+
+    /// This method is only available when the `"nightly"` feature is enabled.
+    #[cfg(all(feature = "nightly", feature = "proc-macro"))]
+    pub fn unstable(self) -> proc_macro::Span {
+        self.inner.unstable()
+    }
+
+    #[cfg(procmacro2_semver_exempt)]
+    pub fn source_file(&self) -> SourceFile {
+        SourceFile(self.inner.source_file())
+    }
+
+    #[cfg(procmacro2_semver_exempt)]
+    pub fn start(&self) -> LineColumn {
+        let imp::LineColumn { line, column } = self.inner.start();
+        LineColumn {
+            line: line,
+            column: column,
+        }
+    }
+
+    #[cfg(procmacro2_semver_exempt)]
+    pub fn end(&self) -> LineColumn {
+        let imp::LineColumn { line, column } = self.inner.end();
+        LineColumn {
+            line: line,
+            column: column,
+        }
+    }
+
+    #[cfg(procmacro2_semver_exempt)]
+    pub fn join(&self, other: Span) -> Option<Span> {
+        self.inner.join(other.inner).map(Span::_new)
+    }
+
+    #[cfg(procmacro2_semver_exempt)]
+    pub fn eq(&self, other: &Span) -> bool {
+        self.inner.eq(&other.inner)
+    }
+}
+
+impl fmt::Debug for Span {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        self.inner.fmt(f)
+    }
+}
+
+#[derive(Clone, Debug)]
+pub enum TokenTree {
+    Group(Group),
+    Term(Term),
+    Op(Op),
+    Literal(Literal),
+}
+
+impl TokenTree {
+    pub fn span(&self) -> Span {
+        match *self {
+            TokenTree::Group(ref t) => t.span(),
+            TokenTree::Term(ref t) => t.span(),
+            TokenTree::Op(ref t) => t.span(),
+            TokenTree::Literal(ref t) => t.span(),
+        }
+    }
+
+    pub fn set_span(&mut self, span: Span) {
+        match *self {
+            TokenTree::Group(ref mut t) => t.set_span(span),
+            TokenTree::Term(ref mut t) => t.set_span(span),
+            TokenTree::Op(ref mut t) => t.set_span(span),
+            TokenTree::Literal(ref mut t) => t.set_span(span),
+        }
+    }
+}
+
+impl From<Group> for TokenTree {
+    fn from(g: Group) -> TokenTree {
+        TokenTree::Group(g)
+    }
+}
+
+impl From<Term> for TokenTree {
+    fn from(g: Term) -> TokenTree {
+        TokenTree::Term(g)
+    }
+}
+
+impl From<Op> for TokenTree {
+    fn from(g: Op) -> TokenTree {
+        TokenTree::Op(g)
+    }
+}
+
+impl From<Literal> for TokenTree {
+    fn from(g: Literal) -> TokenTree {
+        TokenTree::Literal(g)
+    }
+}
+
+impl fmt::Display for TokenTree {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        match *self {
+            TokenTree::Group(ref t) => t.fmt(f),
+            TokenTree::Term(ref t) => t.fmt(f),
+            TokenTree::Op(ref t) => t.fmt(f),
+            TokenTree::Literal(ref t) => t.fmt(f),
+        }
+    }
+}
+
+#[derive(Clone, Debug)]
+pub struct Group {
+    delimiter: Delimiter,
+    stream: TokenStream,
+    span: Span,
+}
+
+#[derive(Copy, Clone, Debug, Eq, PartialEq)]
+pub enum Delimiter {
+    Parenthesis,
+    Brace,
+    Bracket,
+    None,
+}
+
+impl Group {
+    pub fn new(delimiter: Delimiter, stream: TokenStream) -> Group {
+        Group {
+            delimiter: delimiter,
+            stream: stream,
+            span: Span::call_site(),
+        }
+    }
+
+    pub fn delimiter(&self) -> Delimiter {
+        self.delimiter
+    }
+
+    pub fn stream(&self) -> TokenStream {
+        self.stream.clone()
+    }
+
+    pub fn span(&self) -> Span {
+        self.span
+    }
+
+    pub fn set_span(&mut self, span: Span) {
+        self.span = span;
+    }
+}
+
+impl fmt::Display for Group {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        self.stream.fmt(f)
+    }
+}
+
+#[derive(Copy, Clone, Debug)]
+pub struct Op {
+    op: char,
+    spacing: Spacing,
+    span: Span,
+}
+
+#[derive(Copy, Clone, Debug, Eq, PartialEq)]
+pub enum Spacing {
+    Alone,
+    Joint,
+}
+
+impl Op {
+    pub fn new(op: char, spacing: Spacing) -> Op {
+        Op {
+            op: op,
+            spacing: spacing,
+            span: Span::call_site(),
+        }
+    }
+
+    pub fn op(&self) -> char {
+        self.op
+    }
+
+    pub fn spacing(&self) -> Spacing {
+        self.spacing
+    }
+
+    pub fn span(&self) -> Span {
+        self.span
+    }
+
+    pub fn set_span(&mut self, span: Span) {
+        self.span = span;
+    }
+}
+
+impl fmt::Display for Op {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        self.op.fmt(f)
+    }
+}
+
+#[derive(Copy, Clone)]
+pub struct Term {
+    inner: imp::Term,
+    _marker: marker::PhantomData<Rc<()>>,
+}
+
+impl Term {
+    fn _new(inner: imp::Term) -> Term {
+        Term {
+            inner: inner,
+            _marker: marker::PhantomData,
+        }
+    }
+
+    pub fn new(string: &str, span: Span) -> Term {
+        Term::_new(imp::Term::new(string, span.inner))
+    }
+
+    pub fn as_str(&self) -> &str {
+        self.inner.as_str()
+    }
+
+    pub fn span(&self) -> Span {
+        Span::_new(self.inner.span())
+    }
+
+    pub fn set_span(&mut self, span: Span) {
+        self.inner.set_span(span.inner);
+    }
+}
+
+impl fmt::Display for Term {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        self.as_str().fmt(f)
+    }
+}
+
+impl fmt::Debug for Term {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        self.inner.fmt(f)
+    }
+}
+
+#[derive(Clone)]
+pub struct Literal {
+    inner: imp::Literal,
+    _marker: marker::PhantomData<Rc<()>>,
+}
+
+macro_rules! int_literals {
+    ($($name:ident => $kind:ident,)*) => ($(
+        pub fn $name(n: $kind) -> Literal {
+            Literal::_new(imp::Literal::$name(n))
+        }
+    )*)
+}
+
+impl Literal {
+    fn _new(inner: imp::Literal) -> Literal {
+        Literal {
+            inner: inner,
+            _marker: marker::PhantomData,
+        }
+    }
+
+    int_literals! {
+        u8_suffixed => u8,
+        u16_suffixed => u16,
+        u32_suffixed => u32,
+        u64_suffixed => u64,
+        usize_suffixed => usize,
+        i8_suffixed => i8,
+        i16_suffixed => i16,
+        i32_suffixed => i32,
+        i64_suffixed => i64,
+        isize_suffixed => isize,
+
+        u8_unsuffixed => u8,
+        u16_unsuffixed => u16,
+        u32_unsuffixed => u32,
+        u64_unsuffixed => u64,
+        usize_unsuffixed => usize,
+        i8_unsuffixed => i8,
+        i16_unsuffixed => i16,
+        i32_unsuffixed => i32,
+        i64_unsuffixed => i64,
+        isize_unsuffixed => isize,
+    }
+
+    pub fn f64_unsuffixed(f: f64) -> Literal {
+        assert!(f.is_finite());
+        Literal::_new(imp::Literal::f64_unsuffixed(f))
+    }
+
+    pub fn f64_suffixed(f: f64) -> Literal {
+        assert!(f.is_finite());
+        Literal::_new(imp::Literal::f64_suffixed(f))
+    }
+
+    pub fn f32_unsuffixed(f: f32) -> Literal {
+        assert!(f.is_finite());
+        Literal::_new(imp::Literal::f32_unsuffixed(f))
+    }
+
+    pub fn f32_suffixed(f: f32) -> Literal {
+        assert!(f.is_finite());
+        Literal::_new(imp::Literal::f32_suffixed(f))
+    }
+
+    pub fn string(string: &str) -> Literal {
+        Literal::_new(imp::Literal::string(string))
+    }
+
+    pub fn character(ch: char) -> Literal {
+        Literal::_new(imp::Literal::character(ch))
+    }
+
+    pub fn byte_string(s: &[u8]) -> Literal {
+        Literal::_new(imp::Literal::byte_string(s))
+    }
+
+    pub fn span(&self) -> Span {
+        Span::_new(self.inner.span())
+    }
+
+    pub fn set_span(&mut self, span: Span) {
+        self.inner.set_span(span.inner);
+    }
+}
+
+impl fmt::Debug for Literal {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        self.inner.fmt(f)
+    }
+}
+
+impl fmt::Display for Literal {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        self.inner.fmt(f)
+    }
+}
+
+pub mod token_stream {
+    use std::fmt;
+    use std::marker;
+    use std::rc::Rc;
+
+    pub use TokenStream;
+    use TokenTree;
+    use imp;
+
+    pub struct IntoIter {
+        inner: imp::TokenTreeIter,
+        _marker: marker::PhantomData<Rc<()>>,
+    }
+
+    impl Iterator for IntoIter {
+        type Item = TokenTree;
+
+        fn next(&mut self) -> Option<TokenTree> {
+            self.inner.next()
+        }
+    }
+
+    impl fmt::Debug for IntoIter {
+        fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+            self.inner.fmt(f)
+        }
+    }
+
+    impl IntoIterator for TokenStream {
+        type Item = TokenTree;
+        type IntoIter = IntoIter;
+
+        fn into_iter(self) -> IntoIter {
+            IntoIter {
+                inner: self.inner.into_iter(),
+                _marker: marker::PhantomData,
+            }
+        }
+    }
+}
new file mode 100644
--- /dev/null
+++ b/third_party/rust/proc-macro2-0.3.5/src/stable.rs
@@ -0,0 +1,1227 @@
+#![cfg_attr(not(procmacro2_semver_exempt), allow(dead_code))]
+
+use std::borrow::Borrow;
+use std::cell::RefCell;
+#[cfg(procmacro2_semver_exempt)]
+use std::cmp;
+use std::collections::HashMap;
+use std::fmt;
+use std::iter;
+use std::rc::Rc;
+use std::str::FromStr;
+use std::vec;
+
+use strnom::{block_comment, skip_whitespace, whitespace, word_break, Cursor, PResult};
+use unicode_xid::UnicodeXID;
+
+use {Delimiter, Group, Op, Spacing, TokenTree};
+
+#[derive(Clone, Debug)]
+pub struct TokenStream {
+    inner: Vec<TokenTree>,
+}
+
+#[derive(Debug)]
+pub struct LexError;
+
+impl TokenStream {
+    pub fn empty() -> TokenStream {
+        TokenStream { inner: Vec::new() }
+    }
+
+    pub fn is_empty(&self) -> bool {
+        self.inner.len() == 0
+    }
+}
+
+#[cfg(procmacro2_semver_exempt)]
+fn get_cursor(src: &str) -> Cursor {
+    // Create a dummy file & add it to the codemap
+    CODEMAP.with(|cm| {
+        let mut cm = cm.borrow_mut();
+        let name = format!("<parsed string {}>", cm.files.len());
+        let span = cm.add_file(&name, src);
+        Cursor {
+            rest: src,
+            off: span.lo,
+        }
+    })
+}
+
+#[cfg(not(procmacro2_semver_exempt))]
+fn get_cursor(src: &str) -> Cursor {
+    Cursor { rest: src }
+}
+
+impl FromStr for TokenStream {
+    type Err = LexError;
+
+    fn from_str(src: &str) -> Result<TokenStream, LexError> {
+        // Create a dummy file & add it to the codemap
+        let cursor = get_cursor(src);
+
+        match token_stream(cursor) {
+            Ok((input, output)) => {
+                if skip_whitespace(input).len() != 0 {
+                    Err(LexError)
+                } else {
+                    Ok(output.inner)
+                }
+            }
+            Err(LexError) => Err(LexError),
+        }
+    }
+}
+
+impl fmt::Display for TokenStream {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        let mut joint = false;
+        for (i, tt) in self.inner.iter().enumerate() {
+            if i != 0 && !joint {
+                write!(f, " ")?;
+            }
+            joint = false;
+            match *tt {
+                TokenTree::Group(ref tt) => {
+                    let (start, end) = match tt.delimiter() {
+                        Delimiter::Parenthesis => ("(", ")"),
+                        Delimiter::Brace => ("{", "}"),
+                        Delimiter::Bracket => ("[", "]"),
+                        Delimiter::None => ("", ""),
+                    };
+                    if tt.stream().inner.inner.len() == 0 {
+                        write!(f, "{} {}", start, end)?
+                    } else {
+                        write!(f, "{} {} {}", start, tt.stream(), end)?
+                    }
+                }
+                TokenTree::Term(ref tt) => write!(f, "{}", tt.as_str())?,
+                TokenTree::Op(ref tt) => {
+                    write!(f, "{}", tt.op())?;
+                    match tt.spacing() {
+                        Spacing::Alone => {}
+                        Spacing::Joint => joint = true,
+                    }
+                }
+                TokenTree::Literal(ref tt) => write!(f, "{}", tt)?,
+            }
+        }
+
+        Ok(())
+    }
+}
+
+#[cfg(feature = "proc-macro")]
+impl From<::proc_macro::TokenStream> for TokenStream {
+    fn from(inner: ::proc_macro::TokenStream) -> TokenStream {
+        inner
+            .to_string()
+            .parse()
+            .expect("compiler token stream parse failed")
+    }
+}
+
+#[cfg(feature = "proc-macro")]
+impl From<TokenStream> for ::proc_macro::TokenStream {
+    fn from(inner: TokenStream) -> ::proc_macro::TokenStream {
+        inner
+            .to_string()
+            .parse()
+            .expect("failed to parse to compiler tokens")
+    }
+}
+
+impl From<TokenTree> for TokenStream {
+    fn from(tree: TokenTree) -> TokenStream {
+        TokenStream { inner: vec![tree] }
+    }
+}
+
+impl iter::FromIterator<TokenTree> for TokenStream {
+    fn from_iter<I: IntoIterator<Item = TokenTree>>(streams: I) -> Self {
+        let mut v = Vec::new();
+
+        for token in streams.into_iter() {
+            v.push(token);
+        }
+
+        TokenStream { inner: v }
+    }
+}
+
+pub type TokenTreeIter = vec::IntoIter<TokenTree>;
+
+impl IntoIterator for TokenStream {
+    type Item = TokenTree;
+    type IntoIter = TokenTreeIter;
+
+    fn into_iter(self) -> TokenTreeIter {
+        self.inner.into_iter()
+    }
+}
+
+#[cfg(procmacro2_semver_exempt)]
+#[derive(Clone, PartialEq, Eq, Debug)]
+pub struct FileName(String);
+
+#[cfg(procmacro2_semver_exempt)]
+impl fmt::Display for FileName {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        self.0.fmt(f)
+    }
+}
+
+#[cfg(procmacro2_semver_exempt)]
+#[derive(Clone, PartialEq, Eq)]
+pub struct SourceFile {
+    name: FileName,
+}
+
+#[cfg(procmacro2_semver_exempt)]
+impl SourceFile {
+    /// Get the path to this source file as a string.
+    pub fn path(&self) -> &FileName {
+        &self.name
+    }
+
+    pub fn is_real(&self) -> bool {
+        // XXX(nika): Support real files in the future?
+        false
+    }
+}
+
+#[cfg(procmacro2_semver_exempt)]
+impl AsRef<FileName> for SourceFile {
+    fn as_ref(&self) -> &FileName {
+        self.path()
+    }
+}
+
+#[cfg(procmacro2_semver_exempt)]
+impl fmt::Debug for SourceFile {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        f.debug_struct("SourceFile")
+            .field("path", &self.path())
+            .field("is_real", &self.is_real())
+            .finish()
+    }
+}
+
+#[cfg(procmacro2_semver_exempt)]
+#[derive(Clone, Copy, Debug, PartialEq, Eq)]
+pub struct LineColumn {
+    pub line: usize,
+    pub column: usize,
+}
+
+#[cfg(procmacro2_semver_exempt)]
+thread_local! {
+    static CODEMAP: RefCell<Codemap> = RefCell::new(Codemap {
+        // NOTE: We start with a single dummy file which all call_site() and
+        // def_site() spans reference.
+        files: vec![FileInfo {
+            name: "<unspecified>".to_owned(),
+            span: Span { lo: 0, hi: 0 },
+            lines: vec![0],
+        }],
+    });
+}
+
+#[cfg(procmacro2_semver_exempt)]
+struct FileInfo {
+    name: String,
+    span: Span,
+    lines: Vec<usize>,
+}
+
+#[cfg(procmacro2_semver_exempt)]
+impl FileInfo {
+    fn offset_line_column(&self, offset: usize) -> LineColumn {
+        assert!(self.span_within(Span {
+            lo: offset as u32,
+            hi: offset as u32
+        }));
+        let offset = offset - self.span.lo as usize;
+        match self.lines.binary_search(&offset) {
+            Ok(found) => LineColumn {
+                line: found + 1,
+                column: 0,
+            },
+            Err(idx) => LineColumn {
+                line: idx,
+                column: offset - self.lines[idx - 1],
+            },
+        }
+    }
+
+    fn span_within(&self, span: Span) -> bool {
+        span.lo >= self.span.lo && span.hi <= self.span.hi
+    }
+}
+
+/// Computesthe offsets of each line in the given source string.
+#[cfg(procmacro2_semver_exempt)]
+fn lines_offsets(s: &str) -> Vec<usize> {
+    let mut lines = vec![0];
+    let mut prev = 0;
+    while let Some(len) = s[prev..].find('\n') {
+        prev += len + 1;
+        lines.push(prev);
+    }
+    lines
+}
+
+#[cfg(procmacro2_semver_exempt)]
+struct Codemap {
+    files: Vec<FileInfo>,
+}
+
+#[cfg(procmacro2_semver_exempt)]
+impl Codemap {
+    fn next_start_pos(&self) -> u32 {
+        // Add 1 so there's always space between files.
+        //
+        // We'll always have at least 1 file, as we initialize our files list
+        // with a dummy file.
+        self.files.last().unwrap().span.hi + 1
+    }
+
+    fn add_file(&mut self, name: &str, src: &str) -> Span {
+        let lines = lines_offsets(src);
+        let lo = self.next_start_pos();
+        // XXX(nika): Shouild we bother doing a checked cast or checked add here?
+        let span = Span {
+            lo: lo,
+            hi: lo + (src.len() as u32),
+        };
+
+        self.files.push(FileInfo {
+            name: name.to_owned(),
+            span: span,
+            lines: lines,
+        });
+
+        span
+    }
+
+    fn fileinfo(&self, span: Span) -> &FileInfo {
+        for file in &self.files {
+            if file.span_within(span) {
+                return file;
+            }
+        }
+        panic!("Invalid span with no related FileInfo!");
+    }
+}
+
+#[derive(Clone, Copy, Debug, PartialEq, Eq)]
+pub struct Span {
+    #[cfg(procmacro2_semver_exempt)]
+    lo: u32,
+    #[cfg(procmacro2_semver_exempt)]
+    hi: u32,
+}
+
+impl Span {
+    #[cfg(not(procmacro2_semver_exempt))]
+    pub fn call_site() -> Span {
+        Span {}
+    }
+
+    #[cfg(procmacro2_semver_exempt)]
+    pub fn call_site() -> Span {
+        Span { lo: 0, hi: 0 }
+    }
+
+    pub fn def_site() -> Span {
+        Span::call_site()
+    }
+
+    pub fn resolved_at(&self, _other: Span) -> Span {
+        // Stable spans consist only of line/column information, so
+        // `resolved_at` and `located_at` only select which span the
+        // caller wants line/column information from.
+        *self
+    }
+
+    pub fn located_at(&self, other: Span) -> Span {
+        other
+    }
+
+    #[cfg(procmacro2_semver_exempt)]
+    pub fn source_file(&self) -> SourceFile {
+        CODEMAP.with(|cm| {
+            let cm = cm.borrow();
+            let fi = cm.fileinfo(*self);
+            SourceFile {
+                name: FileName(fi.name.clone()),
+            }
+        })
+    }
+
+    #[cfg(procmacro2_semver_exempt)]
+    pub fn start(&self) -> LineColumn {
+        CODEMAP.with(|cm| {
+            let cm = cm.borrow();
+            let fi = cm.fileinfo(*self);
+            fi.offset_line_column(self.lo as usize)
+        })
+    }
+
+    #[cfg(procmacro2_semver_exempt)]
+    pub fn end(&self) -> LineColumn {
+        CODEMAP.with(|cm| {
+            let cm = cm.borrow();
+            let fi = cm.fileinfo(*self);
+            fi.offset_line_column(self.hi as usize)
+        })
+    }
+
+    #[cfg(procmacro2_semver_exempt)]
+    pub fn join(&self, other: Span) -> Option<Span> {
+        CODEMAP.with(|cm| {
+            let cm = cm.borrow();
+            // If `other` is not within the same FileInfo as us, return None.
+            if !cm.fileinfo(*self).span_within(other) {
+                return None;
+            }
+            Some(Span {
+                lo: cmp::min(self.lo, other.lo),
+                hi: cmp::max(self.hi, other.hi),
+            })
+        })
+    }
+}
+
+#[derive(Copy, Clone)]
+pub struct Term {
+    intern: usize,
+    span: Span,
+}
+
+thread_local!(static SYMBOLS: RefCell<Interner> = RefCell::new(Interner::new()));
+
+impl Term {
+    pub fn new(string: &str, span: Span) -> Term {
+        Term {
+            intern: SYMBOLS.with(|s| s.borrow_mut().intern(string)),
+            span: span,
+        }
+    }
+
+    pub fn as_str(&self) -> &str {
+        SYMBOLS.with(|interner| {
+            let interner = interner.borrow();
+            let s = interner.get(self.intern);
+            unsafe { &*(s as *const str) }
+        })
+    }
+
+    pub fn span(&self) -> Span {
+        self.span
+    }
+
+    pub fn set_span(&mut self, span: Span) {
+        self.span = span;
+    }
+}
+
+impl fmt::Debug for Term {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        f.debug_tuple("Term").field(&self.as_str()).finish()
+    }
+}
+
+struct Interner {
+    string_to_index: HashMap<MyRc, usize>,
+    index_to_string: Vec<Rc<String>>,
+}
+
+#[derive(Hash, Eq, PartialEq)]
+struct MyRc(Rc<String>);
+
+impl Borrow<str> for MyRc {
+    fn borrow(&self) -> &str {
+        &self.0
+    }
+}
+
+impl Interner {
+    fn new() -> Interner {
+        Interner {
+            string_to_index: HashMap::new(),
+            index_to_string: Vec::new(),
+        }
+    }
+
+    fn intern(&mut self, s: &str) -> usize {
+        if let Some(&idx) = self.string_to_index.get(s) {
+            return idx;
+        }
+        let s = Rc::new(s.to_string());
+        self.index_to_string.push(s.clone());
+        self.string_to_index
+            .insert(MyRc(s), self.index_to_string.len() - 1);
+        self.index_to_string.len() - 1
+    }
+
+    fn get(&self, idx: usize) -> &str {
+        &self.index_to_string[idx]
+    }
+}
+
+#[derive(Clone, Debug)]
+pub struct Literal {
+    text: String,
+    span: Span,
+}
+
+macro_rules! suffixed_numbers {
+    ($($name:ident => $kind:ident,)*) => ($(
+        pub fn $name(n: $kind) -> Literal {
+            Literal::_new(format!(concat!("{}", stringify!($kind)), n))
+        }
+    )*)
+}
+
+macro_rules! unsuffixed_numbers {
+    ($($name:ident => $kind:ident,)*) => ($(
+        pub fn $name(n: $kind) -> Literal {
+            Literal::_new(n.to_string())
+        }
+    )*)
+}
+
+impl Literal {
+    fn _new(text: String) -> Literal {
+        Literal {
+            text: text,
+            span: Span::call_site(),
+        }
+    }
+
+    suffixed_numbers! {
+        u8_suffixed => u8,
+        u16_suffixed => u16,
+        u32_suffixed => u32,
+        u64_suffixed => u64,
+        usize_suffixed => usize,
+        i8_suffixed => i8,
+        i16_suffixed => i16,
+        i32_suffixed => i32,
+        i64_suffixed => i64,
+        isize_suffixed => isize,
+
+        f32_suffixed => f32,
+        f64_suffixed => f64,
+    }
+
+    unsuffixed_numbers! {
+        u8_unsuffixed => u8,
+        u16_unsuffixed => u16,
+        u32_unsuffixed => u32,
+        u64_unsuffixed => u64,
+        usize_unsuffixed => usize,
+        i8_unsuffixed => i8,
+        i16_unsuffixed => i16,
+        i32_unsuffixed => i32,
+        i64_unsuffixed => i64,
+        isize_unsuffixed => isize,
+    }
+
+    pub fn f32_unsuffixed(f: f32) -> Literal {
+        let mut s = f.to_string();
+        if !s.contains(".") {
+            s.push_str(".0");
+        }
+        Literal::_new(s)
+    }
+
+    pub fn f64_unsuffixed(f: f64) -> Literal {
+        let mut s = f.to_string();
+        if !s.contains(".") {
+            s.push_str(".0");
+        }
+        Literal::_new(s)
+    }
+
+    pub fn string(t: &str) -> Literal {
+        let mut s = t.chars()
+            .flat_map(|c| c.escape_default())
+            .collect::<String>();
+        s.push('"');
+        s.insert(0, '"');
+        Literal::_new(s)
+    }
+
+    pub fn character(t: char) -> Literal {
+        Literal::_new(format!("'{}'", t.escape_default().collect::<String>()))
+    }
+
+    pub fn byte_string(bytes: &[u8]) -> Literal {
+        let mut escaped = "b\"".to_string();
+        for b in bytes {
+            match *b {
+                b'\0' => escaped.push_str(r"\0"),
+                b'\t' => escaped.push_str(r"\t"),
+                b'\n' => escaped.push_str(r"\n"),
+                b'\r' => escaped.push_str(r"\r"),
+                b'"' => escaped.push_str("\\\""),
+                b'\\' => escaped.push_str("\\\\"),
+                b'\x20'...b'\x7E' => escaped.push(*b as char),
+                _ => escaped.push_str(&format!("\\x{:02X}", b)),
+            }
+        }
+        escaped.push('"');
+        Literal::_new(escaped)
+    }
+
+    pub fn span(&self) -> Span {
+        self.span
+    }
+
+    pub fn set_span(&mut self, span: Span) {
+        self.span = span;
+    }
+}
+
+impl fmt::Display for Literal {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        self.text.fmt(f)
+    }
+}
+
+fn token_stream(mut input: Cursor) -> PResult<::TokenStream> {
+    let mut trees = Vec::new();
+    loop {
+        let input_no_ws = skip_whitespace(input);
+        if input_no_ws.rest.len() == 0 {
+            break
+        }
+        if let Ok((a, tokens)) = doc_comment(input_no_ws) {
+            input = a;
+            trees.extend(tokens);
+            continue
+        }
+
+        let (a, tt) = match token_tree(input_no_ws) {
+            Ok(p) => p,
+            Err(_) => break,
+        };
+        trees.push(tt);
+        input = a;
+    }
+    Ok((input, ::TokenStream::_new(TokenStream { inner: trees })))
+}
+
+#[cfg(not(procmacro2_semver_exempt))]
+fn spanned<'a, T>(
+    input: Cursor<'a>,
+    f: fn(Cursor<'a>) -> PResult<'a, T>,
+) -> PResult<'a, (T, ::Span)> {
+    let (a, b) = f(skip_whitespace(input))?;
+    Ok((a, ((b, ::Span::_new(Span { })))))
+}
+
+#[cfg(procmacro2_semver_exempt)]
+fn spanned<'a, T>(
+    input: Cursor<'a>,
+    f: fn(Cursor<'a>) -> PResult<'a, T>,
+) -> PResult<'a, (T, ::Span)> {
+    let input = skip_whitespace(input);
+    let lo = input.off;
+    let (a, b) = f(input)?;
+    let hi = a.off;
+    let span = ::Span::_new(Span { lo: lo, hi: hi });
+    Ok((a, (b, span)))
+}
+
+fn token_tree(input: Cursor) -> PResult<TokenTree> {
+    let (rest, (mut tt, span)) = spanned(input, token_kind)?;
+    tt.set_span(span);
+    Ok((rest, tt))
+}
+
+named!(token_kind -> TokenTree, alt!(
+    map!(group, TokenTree::Group)
+    |
+    map!(literal, TokenTree::Literal) // must be before symbol
+    |
+    symbol
+    |
+    map!(op, TokenTree::Op)
+));
+
+named!(group -> Group, alt!(
+    delimited!(
+        punct!("("),
+        token_stream,
+        punct!(")")
+    ) => { |ts| Group::new(Delimiter::Parenthesis, ts) }
+    |
+    delimited!(
+        punct!("["),
+        token_stream,
+        punct!("]")
+    ) => { |ts| Group::new(Delimiter::Bracket, ts) }
+    |
+    delimited!(
+        punct!("{"),
+        token_stream,
+        punct!("}")
+    ) => { |ts| Group::new(Delimiter::Brace, ts) }
+));
+
+fn symbol(mut input: Cursor) -> PResult<TokenTree> {
+    input = skip_whitespace(input);
+
+    let mut chars = input.char_indices();
+
+    let lifetime = input.starts_with("'");
+    if lifetime {
+        chars.next();
+    }
+
+    let raw = !lifetime && input.starts_with("r#");
+    if raw {
+        chars.next();
+        chars.next();
+    }
+
+    match chars.next() {
+        Some((_, ch)) if UnicodeXID::is_xid_start(ch) || ch == '_' => {}
+        _ => return Err(LexError),
+    }
+
+    let mut end = input.len();
+    for (i, ch) in chars {
+        if !UnicodeXID::is_xid_continue(ch) {
+            end = i;
+            break;
+        }
+    }
+
+    let a = &input.rest[..end];
+    if a == "r#_" || lifetime && a != "'static" && KEYWORDS.contains(&&a[1..]) {
+        Err(LexError)
+    } else if a == "_" {
+        Ok((input.advance(end), Op::new('_', Spacing::Alone).into()))
+    } else {
+        Ok((
+            input.advance(end),
+            ::Term::new(a, ::Span::call_site()).into(),
+        ))
+    }
+}
+
+// From https://github.com/rust-lang/rust/blob/master/src/libsyntax_pos/symbol.rs
+static KEYWORDS: &'static [&'static str] = &[
+    "abstract", "alignof", "as", "become", "box", "break", "const", "continue", "crate", "do",
+    "else", "enum", "extern", "false", "final", "fn", "for", "if", "impl", "in", "let", "loop",
+    "macro", "match", "mod", "move", "mut", "offsetof", "override", "priv", "proc", "pub", "pure",
+    "ref", "return", "self", "Self", "sizeof", "static", "struct", "super", "trait", "true",
+    "type", "typeof", "unsafe", "unsized", "use", "virtual", "where", "while", "yield",
+];
+
+fn literal(input: Cursor) -> PResult<::Literal> {
+    let input_no_ws = skip_whitespace(input);
+
+    match literal_nocapture(input_no_ws) {
+        Ok((a, ())) => {
+            let start = input.len() - input_no_ws.len();
+            let len = input_no_ws.len() - a.len();
+            let end = start + len;
+            Ok((
+                a,
+                ::Literal::_new(Literal::_new(input.rest[start..end].to_string())),
+            ))
+        }
+        Err(LexError) => Err(LexError),
+    }
+}
+
+named!(literal_nocapture -> (), alt!(
+    string
+    |
+    byte_string
+    |
+    byte
+    |
+    character
+    |
+    float
+    |
+    int
+));
+
+named!(string -> (), alt!(
+    quoted_string
+    |
+    preceded!(
+        punct!("r"),
+        raw_string
+    ) => { |_| () }
+));
+
+named!(quoted_string -> (), delimited!(
+    punct!("\""),
+    cooked_string,
+    tag!("\"")
+));
+
+fn cooked_string(input: Cursor) -> PResult<()> {
+    let mut chars = input.char_indices().peekable();
+    while let Some((byte_offset, ch)) = chars.next() {
+        match ch {
+            '"' => {
+                return Ok((input.advance(byte_offset), ()));
+            }
+            '\r' => {
+                if let Some((_, '\n')) = chars.next() {
+                    // ...
+                } else {
+                    break;
+                }
+            }
+            '\\' => match chars.next() {
+                Some((_, 'x')) => {
+                    if !backslash_x_char(&mut chars) {
+                        break;
+                    }
+                }
+                Some((_, 'n')) | Some((_, 'r')) | Some((_, 't')) | Some((_, '\\'))
+                | Some((_, '\'')) | Some((_, '"')) | Some((_, '0')) => {}
+                Some((_, 'u')) => {
+                    if !backslash_u(&mut chars) {
+                        break;
+                    }
+                }
+                Some((_, '\n')) | Some((_, '\r')) => {
+                    while let Some(&(_, ch)) = chars.peek() {
+                        if ch.is_whitespace() {
+                            chars.next();
+                        } else {
+                            break;
+                        }
+                    }
+                }
+                _ => break,
+            },
+            _ch => {}
+        }
+    }
+    Err(LexError)
+}
+
+named!(byte_string -> (), alt!(
+    delimited!(
+        punct!("b\""),
+        cooked_byte_string,
+        tag!("\"")
+    ) => { |_| () }
+    |
+    preceded!(
+        punct!("br"),
+        raw_string
+    ) => { |_| () }
+));
+
+fn cooked_byte_string(mut input: Cursor) -> PResult<()> {
+    let mut bytes = input.bytes().enumerate();
+    'outer: while let Some((offset, b)) = bytes.next() {
+        match b {
+            b'"' => {
+                return Ok((input.advance(offset), ()));
+            }
+            b'\r' => {
+                if let Some((_, b'\n')) = bytes.next() {
+                    // ...
+                } else {
+                    break;
+                }
+            }
+            b'\\' => match bytes.next() {
+                Some((_, b'x')) => {
+                    if !backslash_x_byte(&mut bytes) {
+                        break;
+                    }
+                }
+                Some((_, b'n')) | Some((_, b'r')) | Some((_, b't')) | Some((_, b'\\'))
+                | Some((_, b'0')) | Some((_, b'\'')) | Some((_, b'"')) => {}
+                Some((newline, b'\n')) | Some((newline, b'\r')) => {
+                    let rest = input.advance(newline + 1);
+                    for (offset, ch) in rest.char_indices() {
+                        if !ch.is_whitespace() {
+                            input = rest.advance(offset);
+                            bytes = input.bytes().enumerate();
+                            continue 'outer;
+                        }
+                    }
+                    break;
+                }
+                _ => break,
+            },
+            b if b < 0x80 => {}
+            _ => break,
+        }
+    }
+    Err(LexError)
+}
+
+fn raw_string(input: Cursor) -> PResult<()> {
+    let mut chars = input.char_indices();
+    let mut n = 0;
+    while let Some((byte_offset, ch)) = chars.next() {
+        match ch {
+            '"' => {
+                n = byte_offset;
+                break;
+            }
+            '#' => {}
+            _ => return Err(LexError),
+        }
+    }
+    for (byte_offset, ch) in chars {
+        match ch {
+            '"' if input.advance(byte_offset + 1).starts_with(&input.rest[..n]) => {
+                let rest = input.advance(byte_offset + 1 + n);
+                return Ok((rest, ()));
+            }
+            '\r' => {}
+            _ => {}
+        }
+    }
+    Err(LexError)
+}
+
+named!(byte -> (), do_parse!(
+    punct!("b") >>
+    tag!("'") >>
+    cooked_byte >>
+    tag!("'") >>
+    (())
+));
+
+fn cooked_byte(input: Cursor) -> PResult<()> {
+    let mut bytes = input.bytes().enumerate();
+    let ok = match bytes.next().map(|(_, b)| b) {
+        Some(b'\\') => match bytes.next().map(|(_, b)| b) {
+            Some(b'x') => backslash_x_byte(&mut bytes),
+            Some(b'n') | Some(b'r') | Some(b't') | Some(b'\\') | Some(b'0') | Some(b'\'')
+            | Some(b'"') => true,
+            _ => false,
+        },
+        b => b.is_some(),
+    };
+    if ok {
+        match bytes.next() {
+            Some((offset, _)) => {
+                if input.chars().as_str().is_char_boundary(offset) {
+                    Ok((input.advance(offset), ()))
+                } else {
+                    Err(LexError)
+                }
+            }
+            None => Ok((input.advance(input.len()), ())),
+        }
+    } else {
+        Err(LexError)
+    }
+}
+
+named!(character -> (), do_parse!(
+    punct!("'") >>
+    cooked_char >>
+    tag!("'") >>
+    (())
+));
+
+fn cooked_char(input: Cursor) -> PResult<()> {
+    let mut chars = input.char_indices();
+    let ok = match chars.next().map(|(_, ch)| ch) {
+        Some('\\') => match chars.next().map(|(_, ch)| ch) {
+            Some('x') => backslash_x_char(&mut chars),
+            Some('u') => backslash_u(&mut chars),
+            Some('n') | Some('r') | Some('t') | Some('\\') | Some('0') | Some('\'') | Some('"') => {
+                true
+            }
+            _ => false,
+        },
+        ch => ch.is_some(),
+    };
+    if ok {
+        match chars.next() {
+            Some((idx, _)) => Ok((input.advance(idx), ())),
+            None => Ok((input.advance(input.len()), ())),
+        }
+    } else {
+        Err(LexError)
+    }
+}
+
+macro_rules! next_ch {
+    ($chars:ident @ $pat:pat $(| $rest:pat)*) => {
+        match $chars.next() {
+            Some((_, ch)) => match ch {
+                $pat $(| $rest)*  => ch,
+                _ => return false,
+            },
+            None => return false
+        }
+    };
+}
+
+fn backslash_x_char<I>(chars: &mut I) -> bool
+where
+    I: Iterator<Item = (usize, char)>,
+{
+    next_ch!(chars @ '0'...'7');
+    next_ch!(chars @ '0'...'9' | 'a'...'f' | 'A'...'F');
+    true
+}
+
+fn backslash_x_byte<I>(chars: &mut I) -> bool
+where
+    I: Iterator<Item = (usize, u8)>,
+{
+    next_ch!(chars @ b'0'...b'9' | b'a'...b'f' | b'A'...b'F');
+    next_ch!(chars @ b'0'...b'9' | b'a'...b'f' | b'A'...b'F');
+    true
+}
+
+fn backslash_u<I>(chars: &mut I) -> bool
+where
+    I: Iterator<Item = (usize, char)>,
+{
+    next_ch!(chars @ '{');
+    next_ch!(chars @ '0'...'9' | 'a'...'f' | 'A'...'F');
+    loop {
+        let c = next_ch!(chars @ '0'...'9' | 'a'...'f' | 'A'...'F' | '_' | '}');
+        if c == '}' {
+            return true;
+        }
+    }
+}
+
+fn float(input: Cursor) -> PResult<()> {
+    let (rest, ()) = float_digits(input)?;
+    for suffix in &["f32", "f64"] {
+        if rest.starts_with(suffix) {
+            return word_break(rest.advance(suffix.len()));
+        }
+    }
+    word_break(rest)
+}
+
+fn float_digits(input: Cursor) -> PResult<()> {
+    let mut chars = input.chars().peekable();
+    match chars.next() {
+        Some(ch) if ch >= '0' && ch <= '9' => {}
+        _ => return Err(LexError),
+    }
+
+    let mut len = 1;
+    let mut has_dot = false;
+    let mut has_exp = false;
+    while let Some(&ch) = chars.peek() {
+        match ch {
+            '0'...'9' | '_' => {
+                chars.next();
+                len += 1;
+            }
+            '.' => {
+                if has_dot {
+                    break;
+                }
+                chars.next();
+                if chars
+                    .peek()
+                    .map(|&ch| ch == '.' || UnicodeXID::is_xid_start(ch))
+                    .unwrap_or(false)
+                {
+                    return Err(LexError);
+                }
+                len += 1;
+                has_dot = true;
+            }
+            'e' | 'E' => {
+                chars.next();
+                len += 1;
+                has_exp = true;
+                break;
+            }
+            _ => break,
+        }
+    }
+
+    let rest = input.advance(len);
+    if !(has_dot || has_exp || rest.starts_with("f32") || rest.starts_with("f64")) {
+        return Err(LexError);
+    }
+
+    if has_exp {
+        let mut has_exp_value = false;
+        while let Some(&ch) = chars.peek() {
+            match ch {
+                '+' | '-' => {
+                    if has_exp_value {
+                        break;
+                    }
+                    chars.next();
+                    len += 1;
+                }
+                '0'...'9' => {
+                    chars.next();
+                    len += 1;
+                    has_exp_value = true;
+                }
+                '_' => {
+                    chars.next();
+                    len += 1;
+                }
+                _ => break,
+            }
+        }
+        if !has_exp_value {
+            return Err(LexError);
+        }
+    }
+
+    Ok((input.advance(len), ()))
+}
+
+fn int(input: Cursor) -> PResult<()> {
+    let (rest, ()) = digits(input)?;
+    for suffix in &[
+        "isize", "i8", "i16", "i32", "i64", "i128", "usize", "u8", "u16", "u32", "u64", "u128"
+    ] {
+        if rest.starts_with(suffix) {
+            return word_break(rest.advance(suffix.len()));
+        }
+    }
+    word_break(rest)
+}
+
+fn digits(mut input: Cursor) -> PResult<()> {
+    let base = if input.starts_with("0x") {
+        input = input.advance(2);
+        16
+    } else if input.starts_with("0o") {
+        input = input.advance(2);
+        8
+    } else if input.starts_with("0b") {
+        input = input.advance(2);
+        2
+    } else {
+        10
+    };
+
+    let mut len = 0;
+    let mut empty = true;
+    for b in input.bytes() {
+        let digit = match b {
+            b'0'...b'9' => (b - b'0') as u64,
+            b'a'...b'f' => 10 + (b - b'a') as u64,
+            b'A'...b'F' => 10 + (b - b'A') as u64,
+            b'_' => {
+                if empty && base == 10 {
+                    return Err(LexError);
+                }
+                len += 1;
+                continue;
+            }
+            _ => break,
+        };
+        if digit >= base {
+            return Err(LexError);
+        }
+        len += 1;
+        empty = false;
+    }
+    if empty {
+        Err(LexError)
+    } else {
+        Ok((input.advance(len), ()))
+    }
+}
+
+fn op(input: Cursor) -> PResult<Op> {
+    let input = skip_whitespace(input);
+    match op_char(input) {
+        Ok((rest, ch)) => {
+            let kind = match op_char(rest) {
+                Ok(_) => Spacing::Joint,
+                Err(LexError) => Spacing::Alone,
+            };
+            Ok((rest, Op::new(ch, kind)))
+        }
+        Err(LexError) => Err(LexError),
+    }
+}
+
+fn op_char(input: Cursor) -> PResult<char> {
+    let mut chars = input.chars();
+    let first = match chars.next() {
+        Some(ch) => ch,
+        None => {
+            return Err(LexError);
+        }
+    };
+    let recognized = "~!@#$%^&*-=+|;:,<.>/?";
+    if recognized.contains(first) {
+        Ok((input.advance(first.len_utf8()), first))
+    } else {
+        Err(LexError)
+    }
+}
+
+fn doc_comment(input: Cursor) -> PResult<Vec<TokenTree>> {
+    let mut trees = Vec::new();
+    let (rest, ((comment, inner), span)) = spanned(input, doc_comment_contents)?;
+    trees.push(TokenTree::Op(Op::new('#', Spacing::Alone)));
+    if inner {
+        trees.push(Op::new('!', Spacing::Alone).into());
+    }
+    let mut stream = vec![
+        TokenTree::Term(::Term::new("doc", span)),
+        TokenTree::Op(Op::new('=', Spacing::Alone)),
+        TokenTree::Literal(::Literal::string(comment)),
+    ];
+    for tt in stream.iter_mut() {
+        tt.set_span(span);
+    }
+    trees.push(Group::new(Delimiter::Bracket, stream.into_iter().collect()).into());
+    for tt in trees.iter_mut() {
+        tt.set_span(span);
+    }
+    Ok((rest, trees))
+}
+
+named!(doc_comment_contents -> (&str, bool), alt!(
+    do_parse!(
+        punct!("//!") >>
+        s: take_until_newline_or_eof!() >>
+        ((s, true))
+    )
+    |
+    do_parse!(
+        option!(whitespace) >>
+        peek!(tag!("/*!")) >>
+        s: block_comment >>
+        ((s, true))
+    )
+    |
+    do_parse!(
+        punct!("///") >>
+        not!(tag!("/")) >>
+        s: take_until_newline_or_eof!() >>
+        ((s, false))
+    )
+    |
+    do_parse!(
+        option!(whitespace) >>
+        peek!(tuple!(tag!("/**"), not!(tag!("*")))) >>
+        s: block_comment >>
+        ((s, false))
+    )
+));
rename from third_party/rust/proc-macro2-0.3.6/src/strnom.rs
rename to third_party/rust/proc-macro2-0.3.5/src/strnom.rs
rename from third_party/rust/proc-macro2-0.3.6/src/unstable.rs
rename to third_party/rust/proc-macro2-0.3.5/src/unstable.rs
new file mode 100644
--- /dev/null
+++ b/third_party/rust/proc-macro2-0.3.5/tests/test.rs
@@ -0,0 +1,235 @@
+extern crate proc_macro2;
+
+use std::str::{self, FromStr};
+
+use proc_macro2::{Literal, Span, Term, TokenStream, TokenTree};
+
+#[test]
+fn symbols() {
+    assert_eq!(Term::new("foo", Span::call_site()).as_str(), "foo");
+    assert_eq!(Term::new("bar", Span::call_site()).as_str(), "bar");
+}
+
+#[test]
+fn literals() {
+    assert_eq!(Literal::string("foo").to_string(), "\"foo\"");
+    assert_eq!(Literal::string("\"").to_string(), "\"\\\"\"");
+    assert_eq!(Literal::f32_unsuffixed(10.0).to_string(), "10.0");
+}
+
+#[test]
+fn roundtrip() {
+    fn roundtrip(p: &str) {
+        println!("parse: {}", p);
+        let s = p.parse::<TokenStream>().unwrap().to_string();
+        println!("first: {}", s);
+        let s2 = s.to_string().parse::<TokenStream>().unwrap().to_string();
+        assert_eq!(s, s2);
+    }
+    roundtrip("a");
+    roundtrip("<<");
+    roundtrip("<<=");
+    roundtrip(
+        "
+        1
+        1.0
+        1f32
+        2f64
+        1usize
+        4isize
+        4e10
+        1_000
+        1_0i32
+        8u8
+        9
+        0
+        0xffffffffffffffffffffffffffffffff
+    ",
+    );
+    roundtrip("'a");
+    roundtrip("'static");
+    roundtrip("'\\u{10__FFFF}'");
+    roundtrip("\"\\u{10_F0FF__}foo\\u{1_0_0_0__}\"");
+}
+
+#[test]
+fn fail() {
+    fn fail(p: &str) {
+        if p.parse::<TokenStream>().is_ok() {
+            panic!("should have failed to parse: {}", p);
+        }
+    }
+    fail("1x");
+    fail("1u80");
+    fail("1f320");
+    fail("' static");
+    fail("'mut");
+    fail("r#1");
+    fail("r#_");
+}
+
+#[cfg(procmacro2_semver_exempt)]
+#[test]
+fn span_test() {
+    use proc_macro2::TokenTree;
+
+    fn check_spans(p: &str, mut lines: &[(usize, usize, usize, usize)]) {
+        let ts = p.parse::<TokenStream>().unwrap();
+        check_spans_internal(ts, &mut lines);
+    }
+
+    fn check_spans_internal(ts: TokenStream, lines: &mut &[(usize, usize, usize, usize)]) {
+        for i in ts {
+            if let Some((&(sline, scol, eline, ecol), rest)) = lines.split_first() {
+                *lines = rest;
+
+                let start = i.span().start();
+                assert_eq!(start.line, sline, "sline did not match for {}", i);
+                assert_eq!(start.column, scol, "scol did not match for {}", i);
+
+                let end = i.span().end();
+                assert_eq!(end.line, eline, "eline did not match for {}", i);
+                assert_eq!(end.column, ecol, "ecol did not match for {}", i);
+
+                match i {
+                    TokenTree::Group(ref g) => {
+                        check_spans_internal(g.stream().clone(), lines);
+                    }
+                    _ => {}
+                }
+            }
+        }
+    }
+
+    check_spans(
+        "\
+/// This is a document comment
+testing 123
+{
+  testing 234
+}",
+        &[
+            (1, 0, 1, 30),  // #
+            (1, 0, 1, 30),  // [ ... ]
+            (1, 0, 1, 30),  // doc
+            (1, 0, 1, 30),  // =
+            (1, 0, 1, 30),  // "This is..."
+            (2, 0, 2, 7),   // testing
+            (2, 8, 2, 11),  // 123
+            (3, 0, 5, 1),   // { ... }
+            (4, 2, 4, 9),   // testing
+            (4, 10, 4, 13), // 234
+        ],
+    );
+}
+
+#[cfg(procmacro2_semver_exempt)]
+#[cfg(not(feature = "nightly"))]
+#[test]
+fn default_span() {
+    let start = Span::call_site().start();
+    assert_eq!(start.line, 1);
+    assert_eq!(start.column, 0);
+    let end = Span::call_site().end();
+    assert_eq!(end.line, 1);
+    assert_eq!(end.column, 0);
+    let source_file = Span::call_site().source_file();
+    assert_eq!(source_file.path().to_string(), "<unspecified>");
+    assert!(!source_file.is_real());
+}
+
+#[cfg(procmacro2_semver_exempt)]
+#[test]
+fn span_join() {
+    let source1 = "aaa\nbbb"
+        .parse::<TokenStream>()
+        .unwrap()
+        .into_iter()
+        .collect::<Vec<_>>();
+    let source2 = "ccc\nddd"
+        .parse::<TokenStream>()
+        .unwrap()
+        .into_iter()
+        .collect::<Vec<_>>();
+
+    assert!(source1[0].span().source_file() != source2[0].span().source_file());
+    assert_eq!(
+        source1[0].span().source_file(),
+        source1[1].span().source_file()
+    );
+
+    let joined1 = source1[0].span().join(source1[1].span());
+    let joined2 = source1[0].span().join(source2[0].span());
+    assert!(joined1.is_some());
+    assert!(joined2.is_none());
+
+    let start = joined1.unwrap().start();
+    let end = joined1.unwrap().end();
+    assert_eq!(start.line, 1);
+    assert_eq!(start.column, 0);
+    assert_eq!(end.line, 2);
+    assert_eq!(end.column, 3);
+
+    assert_eq!(
+        joined1.unwrap().source_file(),
+        source1[0].span().source_file()
+    );
+}
+
+#[test]
+fn no_panic() {
+    let s = str::from_utf8(b"b\'\xc2\x86  \x00\x00\x00^\"").unwrap();
+    assert!(s.parse::<proc_macro2::TokenStream>().is_err());
+}
+
+#[test]
+fn tricky_doc_comment() {
+    let stream = "/**/".parse::<proc_macro2::TokenStream>().unwrap();
+    let tokens = stream.into_iter().collect::<Vec<_>>();
+    assert!(tokens.is_empty(), "not empty -- {:?}", tokens);
+
+    let stream = "/// doc".parse::<proc_macro2::TokenStream>().unwrap();
+    let tokens = stream.into_iter().collect::<Vec<_>>();
+    assert!(tokens.len() == 2, "not length 2 -- {:?}", tokens);
+    match tokens[0] {
+        proc_macro2::TokenTree::Op(ref tt) => assert_eq!(tt.op(), '#'),
+        _ => panic!("wrong token {:?}", tokens[0]),
+    }
+    let mut tokens = match tokens[1] {
+        proc_macro2::TokenTree::Group(ref tt) => {
+            assert_eq!(tt.delimiter(), proc_macro2::Delimiter::Bracket);
+            tt.stream().into_iter()
+        }
+        _ => panic!("wrong token {:?}", tokens[0]),
+    };
+
+    match tokens.next().unwrap() {
+        proc_macro2::TokenTree::Term(ref tt) => assert_eq!(tt.as_str(), "doc"),
+        t => panic!("wrong token {:?}", t),
+    }
+    match tokens.next().unwrap() {
+        proc_macro2::TokenTree::Op(ref tt) => assert_eq!(tt.op(), '='),
+        t => panic!("wrong token {:?}", t),
+    }
+    match tokens.next().unwrap() {
+        proc_macro2::TokenTree::Literal(ref tt) => {
+            assert_eq!(tt.to_string(), "\" doc\"");
+        }
+        t => panic!("wrong token {:?}", t),
+    }
+    assert!(tokens.next().is_none());
+
+    let stream = "//! doc".parse::<proc_macro2::TokenStream>().unwrap();
+    let tokens = stream.into_iter().collect::<Vec<_>>();
+    assert!(tokens.len() == 3, "not length 3 -- {:?}", tokens);
+}
+
+#[test]
+fn raw_identifier() {
+    let mut tts = TokenStream::from_str("r#dyn").unwrap().into_iter();
+    match tts.next().unwrap() {
+        TokenTree::Term(raw) => assert_eq!("r#dyn", raw.as_str()),
+        wrong => panic!("wrong token {:?}", wrong),
+    }
+    assert!(tts.next().is_none());
+}
deleted file mode 100644
--- a/third_party/rust/proc-macro2-0.3.6/.cargo-checksum.json
+++ /dev/null
@@ -1,1 +0,0 @@
-{"files":{".travis.yml":"872a0d195dcb1e84f28aa994f301c7139f70360bb42dee3954df5ee965efea15","Cargo.toml":"6ed5d7b9bf8805abd76f9e2a9be99b98e2cb70d9b97980b8aa09b6082d26a94d","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"378f5840b258e2779c39418f3f2d7b2ba96f1c7917dd6be0713f88305dbda397","README.md":"ce05336717e1e90724491a2f54487c41c752fa2d32396639439f7c6d0f1e6776","src/lib.rs":"e99fedcb4b410c626fe1a3ab722c8b4f98baed2c64c2dff28c4eb62da354f2e2","src/stable.rs":"fd8d86f7542d211030056a7cdcc58b86131180d54f461910a4a067269eee9d4a","src/strnom.rs":"129fe22f0b50e5a64fca82e731c959135381c910e19f3305ef35420e0aadde08","src/unstable.rs":"b43c713ac16d9de0ba0fa1b9bebe390122b4ad60ef2fc75408f721305fdcd46b","tests/test.rs":"a8229931093cd6b39f759c60ef097e59bc43c98f1b0e5eea06ecc8d5d0879853"},"package":"49b6a521dc81b643e9a51e0d1cf05df46d5a2f3c0280ea72bcb68276ba64a118"}
\ No newline at end of file
deleted file mode 100644
--- a/third_party/rust/proc-macro2-0.3.6/Cargo.toml
+++ /dev/null
@@ -1,33 +0,0 @@
-# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO
-#
-# When uploading crates to the registry Cargo will automatically
-# "normalize" Cargo.toml files for maximal compatibility
-# with all versions of Cargo and also rewrite `path` dependencies
-# to registry (e.g. crates.io) dependencies
-#
-# If you believe there's an error in this file please file an
-# issue against the rust-lang/cargo repository. If you're
-# editing this file be aware that the upstream Cargo.toml
-# will likely look very different (and much more reasonable)
-
-[package]
-name = "proc-macro2"
-version = "0.3.6"
-authors = ["Alex Crichton <alex@alexcrichton.com>"]
-description = "A stable implementation of the upcoming new `proc_macro` API. Comes with an\noption, off by default, to also reimplement itself in terms of the upstream\nunstable API.\n"
-homepage = "https://github.com/alexcrichton/proc-macro2"
-documentation = "https://docs.rs/proc-macro2"
-readme = "README.md"
-keywords = ["macros"]
-license = "MIT/Apache-2.0"
-repository = "https://github.com/alexcrichton/proc-macro2"
-
-[lib]
-doctest = false
-[dependencies.unicode-xid]
-version = "0.1"
-
-[features]
-default = ["proc-macro"]
-nightly = ["proc-macro"]
-proc-macro = []
deleted file mode 100644
--- a/third_party/rust/proc-macro2-0.3.6/src/lib.rs
+++ /dev/null
@@ -1,590 +0,0 @@
-//! A "shim crate" intended to multiplex the [`proc_macro`] API on to stable
-//! Rust.
-//!
-//! Procedural macros in Rust operate over the upstream
-//! [`proc_macro::TokenStream`][ts] type. This type currently is quite
-//! conservative and exposed no internal implementation details. Nightly
-//! compilers, however, contain a much richer interface. This richer interface
-//! allows fine-grained inspection of the token stream which avoids
-//! stringification/re-lexing and also preserves span information.
-//!
-//! The upcoming APIs added to [`proc_macro`] upstream are the foundation for
-//! productive procedural macros in the ecosystem. To help prepare the ecosystem
-//! for using them this crate serves to both compile on stable and nightly and
-//! mirrors the API-to-be. The intention is that procedural macros which switch
-//! to use this crate will be trivially able to switch to the upstream
-//! `proc_macro` crate once its API stabilizes.
-//!
-//! In the meantime this crate also has a `nightly` Cargo feature which
-//! enables it to reimplement itself with the unstable API of [`proc_macro`].
-//! This'll allow immediate usage of the beneficial upstream API, particularly
-//! around preserving span information.
-//!
-//! [`proc_macro`]: https://doc.rust-lang.org/proc_macro/
-//! [ts]: https://doc.rust-lang.org/proc_macro/struct.TokenStream.html
-
-// Proc-macro2 types in rustdoc of other crates get linked to here.
-#![doc(html_root_url = "https://docs.rs/proc-macro2/0.3.6")]
-#![cfg_attr(feature = "nightly", feature(proc_macro))]
-
-#[cfg(feature = "proc-macro")]
-extern crate proc_macro;
-
-#[cfg(not(feature = "nightly"))]
-extern crate unicode_xid;
-
-use std::fmt;
-use std::iter::FromIterator;
-use std::marker;
-use std::rc::Rc;
-use std::str::FromStr;
-
-#[macro_use]
-#[cfg(not(feature = "nightly"))]
-mod strnom;
-
-#[path = "stable.rs"]
-#[cfg(not(feature = "nightly"))]
-mod imp;
-#[path = "unstable.rs"]
-#[cfg(feature = "nightly")]
-mod imp;
-
-#[derive(Clone)]
-pub struct TokenStream {
-    inner: imp::TokenStream,
-    _marker: marker::PhantomData<Rc<()>>,
-}
-
-pub struct LexError {
-    inner: imp::LexError,
-    _marker: marker::PhantomData<Rc<()>>,
-}
-
-impl TokenStream {
-    fn _new(inner: imp::TokenStream) -> TokenStream {
-        TokenStream {
-            inner: inner,
-            _marker: marker::PhantomData,
-        }
-    }
-
-    pub fn empty() -> TokenStream {
-        TokenStream::_new(imp::TokenStream::empty())
-    }
-
-    pub fn is_empty(&self) -> bool {
-        self.inner.is_empty()
-    }
-}
-
-impl FromStr for TokenStream {
-    type Err = LexError;
-
-    fn from_str(src: &str) -> Result<TokenStream, LexError> {
-        let e = src.parse().map_err(|e| LexError {
-            inner: e,
-            _marker: marker::PhantomData,
-        })?;
-        Ok(TokenStream::_new(e))
-    }
-}
-
-#[cfg(feature = "proc-macro")]
-impl From<proc_macro::TokenStream> for TokenStream {
-    fn from(inner: proc_macro::TokenStream) -> TokenStream {
-        TokenStream::_new(inner.into())
-    }
-}
-
-#[cfg(feature = "proc-macro")]
-impl From<TokenStream> for proc_macro::TokenStream {
-    fn from(inner: TokenStream) -> proc_macro::TokenStream {
-        inner.inner.into()
-    }
-}
-
-impl FromIterator<TokenTree> for TokenStream {
-    fn from_iter<I: IntoIterator<Item = TokenTree>>(streams: I) -> Self {
-        TokenStream::_new(streams.into_iter().collect())
-    }
-}
-
-impl fmt::Display for TokenStream {
-    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        self.inner.fmt(f)
-    }
-}
-
-impl fmt::Debug for TokenStream {
-    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        self.inner.fmt(f)
-    }
-}
-
-impl fmt::Debug for LexError {
-    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        self.inner.fmt(f)
-    }
-}
-
-// Returned by reference, so we can't easily wrap it.
-#[cfg(procmacro2_semver_exempt)]
-pub use imp::FileName;
-
-#[cfg(procmacro2_semver_exempt)]
-#[derive(Clone, PartialEq, Eq)]
-pub struct SourceFile(imp::SourceFile);
-
-#[cfg(procmacro2_semver_exempt)]
-impl SourceFile {
-    /// Get the path to this source file as a string.
-    pub fn path(&self) -> &FileName {
-        self.0.path()
-    }
-
-    pub fn is_real(&self) -> bool {
-        self.0.is_real()
-    }
-}
-
-#[cfg(procmacro2_semver_exempt)]
-impl AsRef<FileName> for SourceFile {
-    fn as_ref(&self) -> &FileName {
-        self.0.path()
-    }
-}
-
-#[cfg(procmacro2_semver_exempt)]
-impl fmt::Debug for SourceFile {
-    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        self.0.fmt(f)
-    }
-}
-
-#[cfg(procmacro2_semver_exempt)]
-pub struct LineColumn {
-    pub line: usize,
-    pub column: usize,
-}
-
-#[derive(Copy, Clone)]
-pub struct Span {
-    inner: imp::Span,
-    _marker: marker::PhantomData<Rc<()>>,
-}
-
-impl Span {
-    fn _new(inner: imp::Span) -> Span {
-        Span {
-            inner: inner,
-            _marker: marker::PhantomData,
-        }
-    }
-
-    pub fn call_site() -> Span {
-        Span::_new(imp::Span::call_site())
-    }
-
-    #[cfg(procmacro2_semver_exempt)]
-    pub fn def_site() -> Span {
-        Span::_new(imp::Span::def_site())
-    }
-
-    /// Creates a new span with the same line/column information as `self` but
-    /// that resolves symbols as though it were at `other`.
-    #[cfg(procmacro2_semver_exempt)]
-    pub fn resolved_at(&self, other: Span) -> Span {
-        Span::_new(self.inner.resolved_at(other.inner))
-    }
-
-    /// Creates a new span with the same name resolution behavior as `self` but
-    /// with the line/column information of `other`.
-    #[cfg(procmacro2_semver_exempt)]
-    pub fn located_at(&self, other: Span) -> Span {
-        Span::_new(self.inner.located_at(other.inner))
-    }
-
-    /// This method is only available when the `"nightly"` feature is enabled.
-    #[cfg(all(feature = "nightly", feature = "proc-macro"))]
-    pub fn unstable(self) -> proc_macro::Span {
-        self.inner.unstable()
-    }
-
-    #[cfg(procmacro2_semver_exempt)]
-    pub fn source_file(&self) -> SourceFile {
-        SourceFile(self.inner.source_file())
-    }
-
-    #[cfg(procmacro2_semver_exempt)]
-    pub fn start(&self) -> LineColumn {
-        let imp::LineColumn { line, column } = self.inner.start();
-        LineColumn {
-            line: line,
-            column: column,
-        }
-    }
-
-    #[cfg(procmacro2_semver_exempt)]
-    pub fn end(&self) -> LineColumn {
-        let imp::LineColumn { line, column } = self.inner.end();
-        LineColumn {
-            line: line,
-            column: column,
-        }
-    }
-
-    #[cfg(procmacro2_semver_exempt)]
-    pub fn join(&self, other: Span) -> Option<Span> {
-        self.inner.join(other.inner).map(Span::_new)
-    }
-
-    #[cfg(procmacro2_semver_exempt)]
-    pub fn eq(&self, other: &Span) -> bool {
-        self.inner.eq(&other.inner)
-    }
-}
-
-impl fmt::Debug for Span {
-    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        self.inner.fmt(f)
-    }
-}
-
-#[derive(Clone, Debug)]
-pub enum TokenTree {
-    Group(Group),
-    Term(Term),
-    Op(Op),
-    Literal(Literal),
-}
-
-impl TokenTree {
-    pub fn span(&self) -> Span {
-        match *self {
-            TokenTree::Group(ref t) => t.span(),
-            TokenTree::Term(ref t) => t.span(),
-            TokenTree::Op(ref t) => t.span(),
-            TokenTree::Literal(ref t) => t.span(),
-        }
-    }
-
-    pub fn set_span(&mut self, span: Span) {
-        match *self {
-            TokenTree::Group(ref mut t) => t.set_span(span),
-            TokenTree::Term(ref mut t) => t.set_span(span),
-            TokenTree::Op(ref mut t) => t.set_span(span),
-            TokenTree::Literal(ref mut t) => t.set_span(span),
-        }
-    }
-}
-
-impl From<Group> for TokenTree {
-    fn from(g: Group) -> TokenTree {
-        TokenTree::Group(g)
-    }
-}
-
-impl From<Term> for TokenTree {
-    fn from(g: Term) -> TokenTree {
-        TokenTree::Term(g)
-    }
-}
-
-impl From<Op> for TokenTree {
-    fn from(g: Op) -> TokenTree {
-        TokenTree::Op(g)
-    }
-}
-
-impl From<Literal> for TokenTree {
-    fn from(g: Literal) -> TokenTree {
-        TokenTree::Literal(g)
-    }
-}
-
-impl fmt::Display for TokenTree {
-    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        match *self {
-            TokenTree::Group(ref t) => t.fmt(f),
-            TokenTree::Term(ref t) => t.fmt(f),
-            TokenTree::Op(ref t) => t.fmt(f),
-            TokenTree::Literal(ref t) => t.fmt(f),
-        }
-    }
-}
-
-#[derive(Clone, Debug)]
-pub struct Group {
-    delimiter: Delimiter,
-    stream: TokenStream,
-    span: Span,
-}
-
-#[derive(Copy, Clone, Debug, Eq, PartialEq)]
-pub enum Delimiter {
-    Parenthesis,
-    Brace,
-    Bracket,
-    None,
-}
-
-impl Group {
-    pub fn new(delimiter: Delimiter, stream: TokenStream) -> Group {
-        Group {
-            delimiter: delimiter,
-            stream: stream,
-            span: Span::call_site(),
-        }
-    }
-
-    pub fn delimiter(&self) -> Delimiter {
-        self.delimiter
-    }
-
-    pub fn stream(&self) -> TokenStream {
-        self.stream.clone()
-    }
-
-    pub fn span(&self) -> Span {
-        self.span
-    }
-
-    pub fn set_span(&mut self, span: Span) {
-        self.span = span;
-    }
-}
-
-impl fmt::Display for Group {
-    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        self.stream.fmt(f)
-    }
-}
-
-#[derive(Copy, Clone, Debug)]
-pub struct Op {
-    op: char,
-    spacing: Spacing,
-    span: Span,
-}
-
-#[derive(Copy, Clone, Debug, Eq, PartialEq)]
-pub enum Spacing {
-    Alone,
-    Joint,
-}
-
-impl Op {
-    pub fn new(op: char, spacing: Spacing) -> Op {
-        Op {
-            op: op,
-            spacing: spacing,
-            span: Span::call_site(),
-        }
-    }
-
-    pub fn op(&self) -> char {
-        self.op
-    }
-
-    pub fn spacing(&self) -> Spacing {
-        self.spacing
-    }
-
-    pub fn span(&self) -> Span {
-        self.span
-    }
-
-    pub fn set_span(&mut self, span: Span) {
-        self.span = span;
-    }
-}
-
-impl fmt::Display for Op {
-    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        self.op.fmt(f)
-    }
-}
-
-#[derive(Copy, Clone)]
-pub struct Term {
-    inner: imp::Term,
-    _marker: marker::PhantomData<Rc<()>>,
-}
-
-impl Term {
-    fn _new(inner: imp::Term) -> Term {
-        Term {
-            inner: inner,
-            _marker: marker::PhantomData,
-        }
-    }
-
-    pub fn new(string: &str, span: Span) -> Term {
-        Term::_new(imp::Term::new(string, span.inner))
-    }
-
-    pub fn as_str(&self) -> &str {
-        self.inner.as_str()
-    }
-
-    pub fn span(&self) -> Span {
-        Span::_new(self.inner.span())
-    }
-
-    pub fn set_span(&mut self, span: Span) {
-        self.inner.set_span(span.inner);
-    }
-}
-
-impl fmt::Display for Term {
-    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        self.as_str().fmt(f)
-    }
-}
-
-impl fmt::Debug for Term {
-    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        self.inner.fmt(f)
-    }
-}
-
-#[derive(Clone)]
-pub struct Literal {
-    inner: imp::Literal,
-    _marker: marker::PhantomData<Rc<()>>,
-}
-
-macro_rules! int_literals {
-    ($($name:ident => $kind:ident,)*) => ($(
-        pub fn $name(n: $kind) -> Literal {
-            Literal::_new(imp::Literal::$name(n))
-        }
-    )*)
-}
-
-impl Literal {
-    fn _new(inner: imp::Literal) -> Literal {
-        Literal {
-            inner: inner,
-            _marker: marker::PhantomData,
-        }
-    }
-
-    int_literals! {
-        u8_suffixed => u8,
-        u16_suffixed => u16,
-        u32_suffixed => u32,
-        u64_suffixed => u64,
-        usize_suffixed => usize,
-        i8_suffixed => i8,
-        i16_suffixed => i16,
-        i32_suffixed => i32,
-        i64_suffixed => i64,
-        isize_suffixed => isize,
-
-        u8_unsuffixed => u8,
-        u16_unsuffixed => u16,
-        u32_unsuffixed => u32,
-        u64_unsuffixed => u64,
-        usize_unsuffixed => usize,
-        i8_unsuffixed => i8,
-        i16_unsuffixed => i16,
-        i32_unsuffixed => i32,
-        i64_unsuffixed => i64,
-        isize_unsuffixed => isize,
-    }
-
-    pub fn f64_unsuffixed(f: f64) -> Literal {
-        assert!(f.is_finite());
-        Literal::_new(imp::Literal::f64_unsuffixed(f))
-    }
-
-    pub fn f64_suffixed(f: f64) -> Literal {
-        assert!(f.is_finite());
-        Literal::_new(imp::Literal::f64_suffixed(f))
-    }
-
-    pub fn f32_unsuffixed(f: f32) -> Literal {
-        assert!(f.is_finite());
-        Literal::_new(imp::Literal::f32_unsuffixed(f))
-    }
-
-    pub fn f32_suffixed(f: f32) -> Literal {
-        assert!(f.is_finite());
-        Literal::_new(imp::Literal::f32_suffixed(f))
-    }
-
-    pub fn string(string: &str) -> Literal {
-        Literal::_new(imp::Literal::string(string))
-    }
-
-    pub fn character(ch: char) -> Literal {
-        Literal::_new(imp::Literal::character(ch))
-    }
-
-    pub fn byte_string(s: &[u8]) -> Literal {
-        Literal::_new(imp::Literal::byte_string(s))
-    }
-
-    pub fn span(&self) -> Span {
-        Span::_new(self.inner.span())
-    }
-
-    pub fn set_span(&mut self, span: Span) {
-        self.inner.set_span(span.inner);
-    }
-}
-
-impl fmt::Debug for Literal {
-    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        self.inner.fmt(f)
-    }
-}
-
-impl fmt::Display for Literal {
-    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        self.inner.fmt(f)
-    }
-}
-
-pub mod token_stream {
-    use std::fmt;
-    use std::marker;
-    use std::rc::Rc;
-
-    pub use TokenStream;
-    use TokenTree;
-    use imp;
-
-    pub struct IntoIter {
-        inner: imp::TokenTreeIter,
-        _marker: marker::PhantomData<Rc<()>>,
-    }
-
-    impl Iterator for IntoIter {
-        type Item = TokenTree;
-
-        fn next(&mut self) -> Option<TokenTree> {
-            self.inner.next()
-        }
-    }
-
-    impl fmt::Debug for IntoIter {
-        fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-            self.inner.fmt(f)
-        }
-    }
-
-    impl IntoIterator for TokenStream {
-        type Item = TokenTree;
-        type IntoIter = IntoIter;
-
-        fn into_iter(self) -> IntoIter {
-            IntoIter {
-                inner: self.inner.into_iter(),
-                _marker: marker::PhantomData,
-            }
-        }
-    }
-}
deleted file mode 100644
--- a/third_party/rust/proc-macro2-0.3.6/src/stable.rs
+++ /dev/null
@@ -1,1265 +0,0 @@
-#![cfg_attr(not(procmacro2_semver_exempt), allow(dead_code))]
-
-use std::borrow::Borrow;
-use std::cell::RefCell;
-#[cfg(procmacro2_semver_exempt)]
-use std::cmp;
-use std::collections::HashMap;
-use std::fmt;
-use std::iter;
-use std::rc::Rc;
-use std::str::FromStr;
-use std::vec;
-
-use strnom::{block_comment, skip_whitespace, whitespace, word_break, Cursor, PResult};
-use unicode_xid::UnicodeXID;
-
-use {Delimiter, Group, Op, Spacing, TokenTree};
-
-#[derive(Clone, Debug)]
-pub struct TokenStream {
-    inner: Vec<TokenTree>,
-}
-
-#[derive(Debug)]
-pub struct LexError;
-
-impl TokenStream {
-    pub fn empty() -> TokenStream {
-        TokenStream { inner: Vec::new() }
-    }
-
-    pub fn is_empty(&self) -> bool {
-        self.inner.len() == 0
-    }
-}
-
-#[cfg(procmacro2_semver_exempt)]
-fn get_cursor(src: &str) -> Cursor {
-    // Create a dummy file & add it to the codemap
-    CODEMAP.with(|cm| {
-        let mut cm = cm.borrow_mut();
-        let name = format!("<parsed string {}>", cm.files.len());
-        let span = cm.add_file(&name, src);
-        Cursor {
-            rest: src,
-            off: span.lo,
-        }
-    })
-}
-
-#[cfg(not(procmacro2_semver_exempt))]
-fn get_cursor(src: &str) -> Cursor {
-    Cursor { rest: src }
-}
-
-impl FromStr for TokenStream {
-    type Err = LexError;
-
-    fn from_str(src: &str) -> Result<TokenStream, LexError> {
-        // Create a dummy file & add it to the codemap
-        let cursor = get_cursor(src);
-
-        match token_stream(cursor) {
-            Ok((input, output)) => {
-                if skip_whitespace(input).len() != 0 {
-                    Err(LexError)
-                } else {
-                    Ok(output.inner)
-                }
-            }
-            Err(LexError) => Err(LexError),
-        }
-    }
-}
-
-impl fmt::Display for TokenStream {
-    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        let mut joint = false;
-        for (i, tt) in self.inner.iter().enumerate() {
-            if i != 0 && !joint {
-                write!(f, " ")?;
-            }
-            joint = false;
-            match *tt {
-                TokenTree::Group(ref tt) => {
-                    let (start, end) = match tt.delimiter() {
-                        Delimiter::Parenthesis => ("(", ")"),
-                        Delimiter::Brace => ("{", "}"),
-                        Delimiter::Bracket => ("[", "]"),
-                        Delimiter::None => ("", ""),
-                    };
-                    if tt.stream().inner.inner.len() == 0 {
-                        write!(f, "{} {}", start, end)?
-                    } else {
-                        write!(f, "{} {} {}", start, tt.stream(), end)?
-                    }
-                }
-                TokenTree::Term(ref tt) => write!(f, "{}", tt.as_str())?,
-                TokenTree::Op(ref tt) => {
-                    write!(f, "{}", tt.op())?;
-                    match tt.spacing() {
-                        Spacing::Alone => {}
-                        Spacing::Joint => joint = true,
-                    }
-                }
-                TokenTree::Literal(ref tt) => write!(f, "{}", tt)?,
-            }
-        }
-
-        Ok(())
-    }
-}
-
-#[cfg(feature = "proc-macro")]
-impl From<::proc_macro::TokenStream> for TokenStream {
-    fn from(inner: ::proc_macro::TokenStream) -> TokenStream {
-        inner
-            .to_string()
-            .parse()
-            .expect("compiler token stream parse failed")
-    }
-}
-
-#[cfg(feature = "proc-macro")]
-impl From<TokenStream> for ::proc_macro::TokenStream {
-    fn from(inner: TokenStream) -> ::proc_macro::TokenStream {
-        inner
-            .to_string()
-            .parse()
-            .expect("failed to parse to compiler tokens")
-    }
-}
-
-impl From<TokenTree> for TokenStream {
-    fn from(tree: TokenTree) -> TokenStream {
-        TokenStream { inner: vec![tree] }
-    }
-}
-
-impl iter::FromIterator<TokenTree> for TokenStream {
-    fn from_iter<I: IntoIterator<Item = TokenTree>>(streams: I) -> Self {
-        let mut v = Vec::new();
-
-        for token in streams.into_iter() {
-            v.push(token);
-        }
-
-        TokenStream { inner: v }
-    }
-}
-
-pub type TokenTreeIter = vec::IntoIter<TokenTree>;
-
-impl IntoIterator for TokenStream {
-    type Item = TokenTree;
-    type IntoIter = TokenTreeIter;
-
-    fn into_iter(self) -> TokenTreeIter {
-        self.inner.into_iter()
-    }
-}
-
-#[cfg(procmacro2_semver_exempt)]
-#[derive(Clone, PartialEq, Eq, Debug)]
-pub struct FileName(String);
-
-#[cfg(procmacro2_semver_exempt)]
-impl fmt::Display for FileName {
-    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        self.0.fmt(f)
-    }
-}
-
-#[cfg(procmacro2_semver_exempt)]
-#[derive(Clone, PartialEq, Eq)]
-pub struct SourceFile {
-    name: FileName,
-}
-
-#[cfg(procmacro2_semver_exempt)]
-impl SourceFile {
-    /// Get the path to this source file as a string.
-    pub fn path(&self) -> &FileName {
-        &self.name
-    }
-
-    pub fn is_real(&self) -> bool {
-        // XXX(nika): Support real files in the future?
-        false
-    }
-}
-
-#[cfg(procmacro2_semver_exempt)]
-impl AsRef<FileName> for SourceFile {
-    fn as_ref(&self) -> &FileName {
-        self.path()
-    }
-}
-
-#[cfg(procmacro2_semver_exempt)]
-impl fmt::Debug for SourceFile {
-    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        f.debug_struct("SourceFile")
-            .field("path", &self.path())
-            .field("is_real", &self.is_real())
-            .finish()
-    }
-}
-
-#[cfg(procmacro2_semver_exempt)]
-#[derive(Clone, Copy, Debug, PartialEq, Eq)]
-pub struct LineColumn {
-    pub line: usize,
-    pub column: usize,
-}
-
-#[cfg(procmacro2_semver_exempt)]
-thread_local! {
-    static CODEMAP: RefCell<Codemap> = RefCell::new(Codemap {
-        // NOTE: We start with a single dummy file which all call_site() and
-        // def_site() spans reference.
-        files: vec![FileInfo {
-            name: "<unspecified>".to_owned(),
-            span: Span { lo: 0, hi: 0 },
-            lines: vec![0],
-        }],
-    });
-}
-
-#[cfg(procmacro2_semver_exempt)]
-struct FileInfo {
-    name: String,
-    span: Span,
-    lines: Vec<usize>,
-}
-
-#[cfg(procmacro2_semver_exempt)]
-impl FileInfo {
-    fn offset_line_column(&self, offset: usize) -> LineColumn {
-        assert!(self.span_within(Span {
-            lo: offset as u32,
-            hi: offset as u32
-        }));
-        let offset = offset - self.span.lo as usize;
-        match self.lines.binary_search(&offset) {
-            Ok(found) => LineColumn {
-                line: found + 1,
-                column: 0,
-            },
-            Err(idx) => LineColumn {
-                line: idx,
-                column: offset - self.lines[idx - 1],
-            },
-        }
-    }
-
-    fn span_within(&self, span: Span) -> bool {
-        span.lo >= self.span.lo && span.hi <= self.span.hi
-    }
-}
-
-/// Computesthe offsets of each line in the given source string.
-#[cfg(procmacro2_semver_exempt)]
-fn lines_offsets(s: &str) -> Vec<usize> {
-    let mut lines = vec![0];
-    let mut prev = 0;
-    while let Some(len) = s[prev..].find('\n') {
-        prev += len + 1;
-        lines.push(prev);
-    }
-    lines
-}
-
-#[cfg(procmacro2_semver_exempt)]
-struct Codemap {
-    files: Vec<FileInfo>,
-}
-
-#[cfg(procmacro2_semver_exempt)]
-impl Codemap {
-    fn next_start_pos(&self) -> u32 {
-        // Add 1 so there's always space between files.
-        //
-        // We'll always have at least 1 file, as we initialize our files list
-        // with a dummy file.
-        self.files.last().unwrap().span.hi + 1
-    }
-
-    fn add_file(&mut self, name: &str, src: &str) -> Span {
-        let lines = lines_offsets(src);
-        let lo = self.next_start_pos();
-        // XXX(nika): Shouild we bother doing a checked cast or checked add here?
-        let span = Span {
-            lo: lo,
-            hi: lo + (src.len() as u32),
-        };
-
-        self.files.push(FileInfo {
-            name: name.to_owned(),
-            span: span,
-            lines: lines,
-        });
-
-        span
-    }
-
-    fn fileinfo(&self, span: Span) -> &FileInfo {
-        for file in &self.files {
-            if file.span_within(span) {
-                return file;
-            }
-        }
-        panic!("Invalid span with no related FileInfo!");
-    }
-}
-
-#[derive(Clone, Copy, Debug, PartialEq, Eq)]
-pub struct Span {
-    #[cfg(procmacro2_semver_exempt)]
-    lo: u32,
-    #[cfg(procmacro2_semver_exempt)]
-    hi: u32,
-}
-
-impl Span {
-    #[cfg(not(procmacro2_semver_exempt))]
-    pub fn call_site() -> Span {
-        Span {}
-    }
-
-    #[cfg(procmacro2_semver_exempt)]
-    pub fn call_site() -> Span {
-        Span { lo: 0, hi: 0 }
-    }
-
-    pub fn def_site() -> Span {
-        Span::call_site()
-    }
-
-    pub fn resolved_at(&self, _other: Span) -> Span {
-        // Stable spans consist only of line/column information, so
-        // `resolved_at` and `located_at` only select which span the
-        // caller wants line/column information from.
-        *self
-    }
-
-    pub fn located_at(&self, other: Span) -> Span {
-        other
-    }
-
-    #[cfg(procmacro2_semver_exempt)]
-    pub fn source_file(&self) -> SourceFile {
-        CODEMAP.with(|cm| {
-            let cm = cm.borrow();
-            let fi = cm.fileinfo(*self);
-            SourceFile {
-                name: FileName(fi.name.clone()),
-            }
-        })
-    }
-
-    #[cfg(procmacro2_semver_exempt)]
-    pub fn start(&self) -> LineColumn {
-        CODEMAP.with(|cm| {
-            let cm = cm.borrow();
-            let fi = cm.fileinfo(*self);
-            fi.offset_line_column(self.lo as usize)
-        })
-    }
-
-    #[cfg(procmacro2_semver_exempt)]
-    pub fn end(&self) -> LineColumn {
-        CODEMAP.with(|cm| {
-            let cm = cm.borrow();
-            let fi = cm.fileinfo(*self);
-            fi.offset_line_column(self.hi as usize)
-        })
-    }
-
-    #[cfg(procmacro2_semver_exempt)]
-    pub fn join(&self, other: Span) -> Option<Span> {
-        CODEMAP.with(|cm| {
-            let cm = cm.borrow();
-            // If `other` is not within the same FileInfo as us, return None.
-            if !cm.fileinfo(*self).span_within(other) {
-                return None;
-            }
-            Some(Span {
-                lo: cmp::min(self.lo, other.lo),
-                hi: cmp::max(self.hi, other.hi),
-            })
-        })
-    }
-}
-
-#[derive(Copy, Clone)]
-pub struct Term {
-    intern: usize,
-    span: Span,
-}
-
-thread_local!(static SYMBOLS: RefCell<Interner> = RefCell::new(Interner::new()));
-
-impl Term {
-    pub fn new(string: &str, span: Span) -> Term {
-        validate_term(string);
-
-        Term {
-            intern: SYMBOLS.with(|s| s.borrow_mut().intern(string)),
-            span: span,
-        }
-    }
-
-    pub fn as_str(&self) -> &str {
-        SYMBOLS.with(|interner| {
-            let interner = interner.borrow();
-            let s = interner.get(self.intern);
-            unsafe { &*(s as *const str) }
-        })
-    }
-
-    pub fn span(&self) -> Span {
-        self.span
-    }
-
-    pub fn set_span(&mut self, span: Span) {
-        self.span = span;
-    }
-}
-
-fn validate_term(string: &str) {
-    let validate = if string.starts_with('\'') {
-        &string[1..]
-    } else if string.starts_with("r#") {
-        &string[2..]
-    } else {
-        string
-    };
-
-    if validate.is_empty() {
-        panic!("Term is not allowed to be empty; use Option<Term>");
-    }
-
-    if validate.bytes().all(|digit| digit >= b'0' && digit <= b'9') {
-        panic!("Term cannot be a number; use Literal instead");
-    }
-
-    fn xid_ok(string: &str) -> bool {
-        let mut chars = string.chars();
-        let first = chars.next().unwrap();
-        if !(UnicodeXID::is_xid_start(first) || first == '_') {
-            return false;
-        }
-        for ch in chars {
-            if !UnicodeXID::is_xid_continue(ch) {
-                return false;
-            }
-        }
-        true
-    }
-
-    if !xid_ok(validate) {
-        panic!("{:?} is not a valid Term", string);
-    }
-}
-
-impl fmt::Debug for Term {
-    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        f.debug_tuple("Term").field(&self.as_str()).finish()
-    }
-}
-
-struct Interner {
-    string_to_index: HashMap<MyRc, usize>,
-    index_to_string: Vec<Rc<String>>,
-}
-
-#[derive(Hash, Eq, PartialEq)]
-struct MyRc(Rc<String>);
-
-impl Borrow<str> for MyRc {
-    fn borrow(&self) -> &str {
-        &self.0
-    }
-}
-
-impl Interner {
-    fn new() -> Interner {
-        Interner {
-            string_to_index: HashMap::new(),
-            index_to_string: Vec::new(),
-        }
-    }
-
-    fn intern(&mut self, s: &str) -> usize {
-        if let Some(&idx) = self.string_to_index.get(s) {
-            return idx;
-        }
-        let s = Rc::new(s.to_string());
-        self.index_to_string.push(s.clone());
-        self.string_to_index
-            .insert(MyRc(s), self.index_to_string.len() - 1);
-        self.index_to_string.len() - 1
-    }
-
-    fn get(&self, idx: usize) -> &str {
-        &self.index_to_string[idx]
-    }
-}
-
-#[derive(Clone, Debug)]
-pub struct Literal {
-    text: String,
-    span: Span,
-}
-
-macro_rules! suffixed_numbers {
-    ($($name:ident => $kind:ident,)*) => ($(
-        pub fn $name(n: $kind) -> Literal {
-            Literal::_new(format!(concat!("{}", stringify!($kind)), n))
-        }
-    )*)
-}
-
-macro_rules! unsuffixed_numbers {
-    ($($name:ident => $kind:ident,)*) => ($(
-        pub fn $name(n: $kind) -> Literal {
-            Literal::_new(n.to_string())
-        }
-    )*)
-}
-
-impl Literal {
-    fn _new(text: String) -> Literal {
-        Literal {
-            text: text,
-            span: Span::call_site(),
-        }
-    }
-
-    suffixed_numbers! {
-        u8_suffixed => u8,
-        u16_suffixed => u16,
-        u32_suffixed => u32,
-        u64_suffixed => u64,
-        usize_suffixed => usize,
-        i8_suffixed => i8,
-        i16_suffixed => i16,
-        i32_suffixed => i32,
-        i64_suffixed => i64,
-        isize_suffixed => isize,
-
-        f32_suffixed => f32,
-        f64_suffixed => f64,
-    }
-
-    unsuffixed_numbers! {
-        u8_unsuffixed => u8,
-        u16_unsuffixed => u16,
-        u32_unsuffixed => u32,
-        u64_unsuffixed => u64,
-        usize_unsuffixed => usize,
-        i8_unsuffixed => i8,
-        i16_unsuffixed => i16,
-        i32_unsuffixed => i32,
-        i64_unsuffixed => i64,
-        isize_unsuffixed => isize,
-    }
-
-    pub fn f32_unsuffixed(f: f32) -> Literal {
-        let mut s = f.to_string();
-        if !s.contains(".") {
-            s.push_str(".0");
-        }
-        Literal::_new(s)
-    }
-
-    pub fn f64_unsuffixed(f: f64) -> Literal {
-        let mut s = f.to_string();
-        if !s.contains(".") {
-            s.push_str(".0");
-        }
-        Literal::_new(s)
-    }
-
-    pub fn string(t: &str) -> Literal {
-        let mut s = t.chars()
-            .flat_map(|c| c.escape_default())
-            .collect::<String>();
-        s.push('"');
-        s.insert(0, '"');
-        Literal::_new(s)
-    }
-
-    pub fn character(t: char) -> Literal {
-        Literal::_new(format!("'{}'", t.escape_default().collect::<String>()))
-    }
-
-    pub fn byte_string(bytes: &[u8]) -> Literal {
-        let mut escaped = "b\"".to_string();
-        for b in bytes {
-            match *b {
-                b'\0' => escaped.push_str(r"\0"),
-                b'\t' => escaped.push_str(r"\t"),
-                b'\n' => escaped.push_str(r"\n"),
-                b'\r' => escaped.push_str(r"\r"),
-                b'"' => escaped.push_str("\\\""),
-                b'\\' => escaped.push_str("\\\\"),
-                b'\x20'...b'\x7E' => escaped.push(*b as char),
-                _ => escaped.push_str(&format!("\\x{:02X}", b)),
-            }
-        }
-        escaped.push('"');
-        Literal::_new(escaped)
-    }
-
-    pub fn span(&self) -> Span {
-        self.span
-    }
-
-    pub fn set_span(&mut self, span: Span) {
-        self.span = span;
-    }
-}
-
-impl fmt::Display for Literal {
-    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        self.text.fmt(f)
-    }
-}
-
-fn token_stream(mut input: Cursor) -> PResult<::TokenStream> {
-    let mut trees = Vec::new();
-    loop {
-        let input_no_ws = skip_whitespace(input);
-        if input_no_ws.rest.len() == 0 {
-            break
-        }
-        if let Ok((a, tokens)) = doc_comment(input_no_ws) {
-            input = a;
-            trees.extend(tokens);
-            continue
-        }
-
-        let (a, tt) = match token_tree(input_no_ws) {
-            Ok(p) => p,
-            Err(_) => break,
-        };
-        trees.push(tt);
-        input = a;
-    }
-    Ok((input, ::TokenStream::_new(TokenStream { inner: trees })))
-}
-
-#[cfg(not(procmacro2_semver_exempt))]
-fn spanned<'a, T>(
-    input: Cursor<'a>,
-    f: fn(Cursor<'a>) -> PResult<'a, T>,
-) -> PResult<'a, (T, ::Span)> {
-    let (a, b) = f(skip_whitespace(input))?;
-    Ok((a, ((b, ::Span::_new(Span { })))))
-}
-
-#[cfg(procmacro2_semver_exempt)]
-fn spanned<'a, T>(
-    input: Cursor<'a>,
-    f: fn(Cursor<'a>) -> PResult<'a, T>,
-) -> PResult<'a, (T, ::Span)> {
-    let input = skip_whitespace(input);
-    let lo = input.off;
-    let (a, b) = f(input)?;
-    let hi = a.off;
-    let span = ::Span::_new(Span { lo: lo, hi: hi });
-    Ok((a, (b, span)))
-}
-
-fn token_tree(input: Cursor) -> PResult<TokenTree> {
-    let (rest, (mut tt, span)) = spanned(input, token_kind)?;
-    tt.set_span(span);
-    Ok((rest, tt))
-}
-
-named!(token_kind -> TokenTree, alt!(
-    map!(group, TokenTree::Group)
-    |
-    map!(literal, TokenTree::Literal) // must be before symbol
-    |
-    symbol
-    |
-    map!(op, TokenTree::Op)
-));
-
-named!(group -> Group, alt!(
-    delimited!(
-        punct!("("),
-        token_stream,
-        punct!(")")
-    ) => { |ts| Group::new(Delimiter::Parenthesis, ts) }
-    |
-    delimited!(
-        punct!("["),
-        token_stream,
-        punct!("]")
-    ) => { |ts| Group::new(Delimiter::Bracket, ts) }
-    |
-    delimited!(
-        punct!("{"),
-        token_stream,
-        punct!("}")
-    ) => { |ts| Group::new(Delimiter::Brace, ts) }
-));
-
-fn symbol(mut input: Cursor) -> PResult<TokenTree> {
-    input = skip_whitespace(input);
-
-    let mut chars = input.char_indices();
-
-    let lifetime = input.starts_with("'");
-    if lifetime {
-        chars.next();
-    }
-
-    let raw = !lifetime && input.starts_with("r#");
-    if raw {
-        chars.next();
-        chars.next();
-    }
-
-    match chars.next() {
-        Some((_, ch)) if UnicodeXID::is_xid_start(ch) || ch == '_' => {}
-        _ => return Err(LexError),
-    }
-
-    let mut end = input.len();
-    for (i, ch) in chars {
-        if !UnicodeXID::is_xid_continue(ch) {
-            end = i;
-            break;
-        }
-    }
-
-    let a = &input.rest[..end];
-    if a == "r#_" || lifetime && a != "'static" && KEYWORDS.contains(&&a[1..]) {
-        Err(LexError)
-    } else if a == "_" {
-        Ok((input.advance(end), Op::new('_', Spacing::Alone).into()))
-    } else {
-        Ok((
-            input.advance(end),
-            ::Term::new(a, ::Span::call_site()).into(),
-        ))
-    }
-}
-
-// From https://github.com/rust-lang/rust/blob/master/src/libsyntax_pos/symbol.rs
-static KEYWORDS: &'static [&'static str] = &[
-    "abstract", "alignof", "as", "become", "box", "break", "const", "continue", "crate", "do",
-    "else", "enum", "extern", "false", "final", "fn", "for", "if", "impl", "in", "let", "loop",
-    "macro", "match", "mod", "move", "mut", "offsetof", "override", "priv", "proc", "pub", "pure",
-    "ref", "return", "self", "Self", "sizeof", "static", "struct", "super", "trait", "true",
-    "type", "typeof", "unsafe", "unsized", "use", "virtual", "where", "while", "yield",
-];
-
-fn literal(input: Cursor) -> PResult<::Literal> {
-    let input_no_ws = skip_whitespace(input);
-
-    match literal_nocapture(input_no_ws) {
-        Ok((a, ())) => {
-            let start = input.len() - input_no_ws.len();
-            let len = input_no_ws.len() - a.len();
-            let end = start + len;
-            Ok((
-                a,
-                ::Literal::_new(Literal::_new(input.rest[start..end].to_string())),
-            ))
-        }
-        Err(LexError) => Err(LexError),
-    }
-}
-
-named!(literal_nocapture -> (), alt!(
-    string
-    |
-    byte_string
-    |
-    byte
-    |
-    character
-    |
-    float
-    |
-    int
-));
-
-named!(string -> (), alt!(
-    quoted_string
-    |
-    preceded!(
-        punct!("r"),
-        raw_string
-    ) => { |_| () }
-));
-
-named!(quoted_string -> (), delimited!(
-    punct!("\""),
-    cooked_string,
-    tag!("\"")
-));
-
-fn cooked_string(input: Cursor) -> PResult<()> {
-    let mut chars = input.char_indices().peekable();
-    while let Some((byte_offset, ch)) = chars.next() {
-        match ch {
-            '"' => {
-                return Ok((input.advance(byte_offset), ()));
-            }
-            '\r' => {
-                if let Some((_, '\n')) = chars.next() {
-                    // ...
-                } else {
-                    break;
-                }
-            }
-            '\\' => match chars.next() {
-                Some((_, 'x')) => {
-                    if !backslash_x_char(&mut chars) {
-                        break;
-                    }
-                }
-                Some((_, 'n')) | Some((_, 'r')) | Some((_, 't')) | Some((_, '\\'))
-                | Some((_, '\'')) | Some((_, '"')) | Some((_, '0')) => {}
-                Some((_, 'u')) => {
-                    if !backslash_u(&mut chars) {
-                        break;
-                    }
-                }
-                Some((_, '\n')) | Some((_, '\r')) => {
-                    while let Some(&(_, ch)) = chars.peek() {
-                        if ch.is_whitespace() {
-                            chars.next();
-                        } else {
-                            break;
-                        }
-                    }
-                }
-                _ => break,
-            },
-            _ch => {}
-        }
-    }
-    Err(LexError)
-}
-
-named!(byte_string -> (), alt!(
-    delimited!(
-        punct!("b\""),
-        cooked_byte_string,
-        tag!("\"")
-    ) => { |_| () }
-    |
-    preceded!(
-        punct!("br"),
-        raw_string
-    ) => { |_| () }
-));
-
-fn cooked_byte_string(mut input: Cursor) -> PResult<()> {
-    let mut bytes = input.bytes().enumerate();
-    'outer: while let Some((offset, b)) = bytes.next() {
-        match b {
-            b'"' => {
-                return Ok((input.advance(offset), ()));
-            }
-            b'\r' => {
-                if let Some((_, b'\n')) = bytes.next() {
-                    // ...
-                } else {
-                    break;
-                }
-            }
-            b'\\' => match bytes.next() {
-                Some((_, b'x')) => {
-                    if !backslash_x_byte(&mut bytes) {
-                        break;
-                    }
-                }
-                Some((_, b'n')) | Some((_, b'r')) | Some((_, b't')) | Some((_, b'\\'))
-                | Some((_, b'0')) | Some((_, b'\'')) | Some((_, b'"')) => {}
-                Some((newline, b'\n')) | Some((newline, b'\r')) => {
-                    let rest = input.advance(newline + 1);
-                    for (offset, ch) in rest.char_indices() {
-                        if !ch.is_whitespace() {
-                            input = rest.advance(offset);
-                            bytes = input.bytes().enumerate();
-                            continue 'outer;
-                        }
-                    }
-                    break;
-                }
-                _ => break,
-            },
-            b if b < 0x80 => {}
-            _ => break,
-        }
-    }
-    Err(LexError)
-}
-
-fn raw_string(input: Cursor) -> PResult<()> {
-    let mut chars = input.char_indices();
-    let mut n = 0;
-    while let Some((byte_offset, ch)) = chars.next() {
-        match ch {
-            '"' => {
-                n = byte_offset;
-                break;
-            }
-            '#' => {}
-            _ => return Err(LexError),
-        }
-    }
-    for (byte_offset, ch) in chars {
-        match ch {
-            '"' if input.advance(byte_offset + 1).starts_with(&input.rest[..n]) => {
-                let rest = input.advance(byte_offset + 1 + n);
-                return Ok((rest, ()));
-            }
-            '\r' => {}
-            _ => {}
-        }
-    }
-    Err(LexError)
-}
-
-named!(byte -> (), do_parse!(
-    punct!("b") >>
-    tag!("'") >>
-    cooked_byte >>
-    tag!("'") >>
-    (())
-));
-
-fn cooked_byte(input: Cursor) -> PResult<()> {
-    let mut bytes = input.bytes().enumerate();
-    let ok = match bytes.next().map(|(_, b)| b) {
-        Some(b'\\') => match bytes.next().map(|(_, b)| b) {
-            Some(b'x') => backslash_x_byte(&mut bytes),
-            Some(b'n') | Some(b'r') | Some(b't') | Some(b'\\') | Some(b'0') | Some(b'\'')
-            | Some(b'"') => true,
-            _ => false,
-        },
-        b => b.is_some(),
-    };
-    if ok {
-        match bytes.next() {
-            Some((offset, _)) => {
-                if input.chars().as_str().is_char_boundary(offset) {
-                    Ok((input.advance(offset), ()))
-                } else {
-                    Err(LexError)
-                }
-            }
-            None => Ok((input.advance(input.len()), ())),
-        }
-    } else {
-        Err(LexError)
-    }
-}
-
-named!(character -> (), do_parse!(
-    punct!("'") >>
-    cooked_char >>
-    tag!("'") >>
-    (())
-));
-
-fn cooked_char(input: Cursor) -> PResult<()> {
-    let mut chars = input.char_indices();
-    let ok = match chars.next().map(|(_, ch)| ch) {
-        Some('\\') => match chars.next().map(|(_, ch)| ch) {
-            Some('x') => backslash_x_char(&mut chars),
-            Some('u') => backslash_u(&mut chars),
-            Some('n') | Some('r') | Some('t') | Some('\\') | Some('0') | Some('\'') | Some('"') => {
-                true
-            }
-            _ => false,
-        },
-        ch => ch.is_some(),
-    };
-    if ok {
-        match chars.next() {
-            Some((idx, _)) => Ok((input.advance(idx), ())),
-            None => Ok((input.advance(input.len()), ())),
-        }
-    } else {
-        Err(LexError)
-    }
-}
-
-macro_rules! next_ch {
-    ($chars:ident @ $pat:pat $(| $rest:pat)*) => {
-        match $chars.next() {
-            Some((_, ch)) => match ch {
-                $pat $(| $rest)*  => ch,
-                _ => return false,
-            },
-            None => return false
-        }
-    };
-}
-
-fn backslash_x_char<I>(chars: &mut I) -> bool
-where
-    I: Iterator<Item = (usize, char)>,
-{
-    next_ch!(chars @ '0'...'7');
-    next_ch!(chars @ '0'...'9' | 'a'...'f' | 'A'...'F');
-    true
-}
-
-fn backslash_x_byte<I>(chars: &mut I) -> bool
-where
-    I: Iterator<Item = (usize, u8)>,
-{
-    next_ch!(chars @ b'0'...b'9' | b'a'...b'f' | b'A'...b'F');
-    next_ch!(chars @ b'0'...b'9' | b'a'...b'f' | b'A'...b'F');
-    true
-}
-
-fn backslash_u<I>(chars: &mut I) -> bool
-where
-    I: Iterator<Item = (usize, char)>,
-{
-    next_ch!(chars @ '{');
-    next_ch!(chars @ '0'...'9' | 'a'...'f' | 'A'...'F');
-    loop {
-        let c = next_ch!(chars @ '0'...'9' | 'a'...'f' | 'A'...'F' | '_' | '}');
-        if c == '}' {
-            return true;
-        }
-    }
-}
-
-fn float(input: Cursor) -> PResult<()> {
-    let (rest, ()) = float_digits(input)?;
-    for suffix in &["f32", "f64"] {
-        if rest.starts_with(suffix) {
-            return word_break(rest.advance(suffix.len()));
-        }
-    }
-    word_break(rest)
-}
-
-fn float_digits(input: Cursor) -> PResult<()> {
-    let mut chars = input.chars().peekable();
-    match chars.next() {
-        Some(ch) if ch >= '0' && ch <= '9' => {}
-        _ => return Err(LexError),
-    }
-
-    let mut len = 1;
-    let mut has_dot = false;
-    let mut has_exp = false;
-    while let Some(&ch) = chars.peek() {
-        match ch {
-            '0'...'9' | '_' => {
-                chars.next();
-                len += 1;
-            }
-            '.' => {
-                if has_dot {
-                    break;
-                }
-                chars.next();
-                if chars
-                    .peek()
-                    .map(|&ch| ch == '.' || UnicodeXID::is_xid_start(ch))
-                    .unwrap_or(false)
-                {
-                    return Err(LexError);
-                }
-                len += 1;
-                has_dot = true;
-            }
-            'e' | 'E' => {
-                chars.next();
-                len += 1;
-                has_exp = true;
-                break;
-            }
-            _ => break,
-        }
-    }
-
-    let rest = input.advance(len);
-    if !(has_dot || has_exp || rest.starts_with("f32") || rest.starts_with("f64")) {
-        return Err(LexError);
-    }
-
-    if has_exp {
-        let mut has_exp_value = false;
-        while let Some(&ch) = chars.peek() {
-            match ch {
-                '+' | '-' => {
-                    if has_exp_value {
-                        break;
-                    }
-                    chars.next();
-                    len += 1;
-                }
-                '0'...'9' => {
-                    chars.next();
-                    len += 1;
-                    has_exp_value = true;
-                }
-                '_' => {
-                    chars.next();
-                    len += 1;
-                }
-                _ => break,
-            }
-        }
-        if !has_exp_value {
-            return Err(LexError);
-        }
-    }
-
-    Ok((input.advance(len), ()))
-}
-
-fn int(input: Cursor) -> PResult<()> {
-    let (rest, ()) = digits(input)?;
-    for suffix in &[
-        "isize", "i8", "i16", "i32", "i64", "i128", "usize", "u8", "u16", "u32", "u64", "u128"
-    ] {
-        if rest.starts_with(suffix) {
-            return word_break(rest.advance(suffix.len()));
-        }
-    }
-    word_break(rest)
-}
-
-fn digits(mut input: Cursor) -> PResult<()> {
-    let base = if input.starts_with("0x") {
-        input = input.advance(2);
-        16
-    } else if input.starts_with("0o") {
-        input = input.advance(2);
-        8
-    } else if input.starts_with("0b") {
-        input = input.advance(2);
-        2
-    } else {
-        10
-    };
-
-    let mut len = 0;
-    let mut empty = true;
-    for b in input.bytes() {
-        let digit = match b {
-            b'0'...b'9' => (b - b'0') as u64,
-            b'a'...b'f' => 10 + (b - b'a') as u64,
-            b'A'...b'F' => 10 + (b - b'A') as u64,
-            b'_' => {
-                if empty && base == 10 {
-                    return Err(LexError);
-                }
-                len += 1;
-                continue;
-            }
-            _ => break,
-        };
-        if digit >= base {
-            return Err(LexError);
-        }
-        len += 1;
-        empty = false;
-    }
-    if empty {
-        Err(LexError)
-    } else {
-        Ok((input.advance(len), ()))
-    }
-}
-
-fn op(input: Cursor) -> PResult<Op> {
-    let input = skip_whitespace(input);
-    match op_char(input) {
-        Ok((rest, ch)) => {
-            let kind = match op_char(rest) {
-                Ok(_) => Spacing::Joint,
-                Err(LexError) => Spacing::Alone,
-            };
-            Ok((rest, Op::new(ch, kind)))
-        }
-        Err(LexError) => Err(LexError),
-    }
-}
-
-fn op_char(input: Cursor) -> PResult<char> {
-    let mut chars = input.chars();
-    let first = match chars.next() {
-        Some(ch) => ch,
-        None => {
-            return Err(LexError);
-        }
-    };
-    let recognized = "~!@#$%^&*-=+|;:,<.>/?";
-    if recognized.contains(first) {
-        Ok((input.advance(first.len_utf8()), first))
-    } else {
-        Err(LexError)
-    }
-}
-
-fn doc_comment(input: Cursor) -> PResult<Vec<TokenTree>> {
-    let mut trees = Vec::new();
-    let (rest, ((comment, inner), span)) = spanned(input, doc_comment_contents)?;
-    trees.push(TokenTree::Op(Op::new('#', Spacing::Alone)));
-    if inner {
-        trees.push(Op::new('!', Spacing::Alone).into());
-    }
-    let mut stream = vec![
-        TokenTree::Term(::Term::new("doc", span)),
-        TokenTree::Op(Op::new('=', Spacing::Alone)),
-        TokenTree::Literal(::Literal::string(comment)),
-    ];
-    for tt in stream.iter_mut() {
-        tt.set_span(span);
-    }
-    trees.push(Group::new(Delimiter::Bracket, stream.into_iter().collect()).into());
-    for tt in trees.iter_mut() {
-        tt.set_span(span);
-    }
-    Ok((rest, trees))
-}
-
-named!(doc_comment_contents -> (&str, bool), alt!(
-    do_parse!(
-        punct!("//!") >>
-        s: take_until_newline_or_eof!() >>
-        ((s, true))
-    )
-    |
-    do_parse!(
-        option!(whitespace) >>
-        peek!(tag!("/*!")) >>
-        s: block_comment >>
-        ((s, true))
-    )
-    |
-    do_parse!(
-        punct!("///") >>
-        not!(tag!("/")) >>
-        s: take_until_newline_or_eof!() >>
-        ((s, false))
-    )
-    |
-    do_parse!(
-        option!(whitespace) >>
-        peek!(tuple!(tag!("/**"), not!(tag!("*")))) >>
-        s: block_comment >>
-        ((s, false))
-    )
-));
deleted file mode 100644
--- a/third_party/rust/proc-macro2-0.3.6/tests/test.rs
+++ /dev/null
@@ -1,304 +0,0 @@
-extern crate proc_macro2;
-
-use std::str::{self, FromStr};
-
-use proc_macro2::{Literal, Span, Term, TokenStream, TokenTree};
-
-#[test]
-fn terms() {
-    assert_eq!(Term::new("String", Span::call_site()).as_str(), "String");
-    assert_eq!(Term::new("fn", Span::call_site()).as_str(), "fn");
-    assert_eq!(Term::new("_", Span::call_site()).as_str(), "_");
-}
-
-#[test]
-fn raw_terms() {
-    assert_eq!(Term::new("r#String", Span::call_site()).as_str(), "r#String");
-    assert_eq!(Term::new("r#fn", Span::call_site()).as_str(), "r#fn");
-    assert_eq!(Term::new("r#_", Span::call_site()).as_str(), "r#_");
-}
-
-#[test]
-fn lifetimes() {
-    assert_eq!(Term::new("'a", Span::call_site()).as_str(), "'a");
-    assert_eq!(Term::new("'static", Span::call_site()).as_str(), "'static");
-    assert_eq!(Term::new("'_", Span::call_site()).as_str(), "'_");
-}
-
-#[test]
-#[should_panic(expected = "Term is not allowed to be empty; use Option<Term>")]
-fn term_empty() {
-    Term::new("", Span::call_site());
-}
-
-#[test]
-#[should_panic(expected = "Term cannot be a number; use Literal instead")]
-fn term_number() {
-    Term::new("255", Span::call_site());
-}
-
-#[test]
-#[should_panic(expected = "\"a#\" is not a valid Term")]
-fn term_invalid() {
-    Term::new("a#", Span::call_site());
-}
-
-#[test]
-#[should_panic(expected = "Term is not allowed to be empty; use Option<Term>")]
-fn raw_term_empty() {
-    Term::new("r#", Span::call_site());
-}
-
-#[test]
-#[should_panic(expected = "Term cannot be a number; use Literal instead")]
-fn raw_term_number() {
-    Term::new("r#255", Span::call_site());
-}
-
-#[test]
-#[should_panic(expected = "\"r#a#\" is not a valid Term")]
-fn raw_term_invalid() {
-    Term::new("r#a#", Span::call_site());
-}
-
-#[test]
-#[should_panic(expected = "Term is not allowed to be empty; use Option<Term>")]
-fn lifetime_empty() {
-    Term::new("'", Span::call_site());
-}
-
-#[test]
-#[should_panic(expected = "Term cannot be a number; use Literal instead")]
-fn lifetime_number() {
-    Term::new("'255", Span::call_site());
-}
-
-#[test]
-#[should_panic(expected = r#""\'a#" is not a valid Term"#)]
-fn lifetime_invalid() {
-    Term::new("'a#", Span::call_site());
-}
-
-#[test]
-fn literals() {
-    assert_eq!(Literal::string("foo").to_string(), "\"foo\"");
-    assert_eq!(Literal::string("\"").to_string(), "\"\\\"\"");
-    assert_eq!(Literal::f32_unsuffixed(10.0).to_string(), "10.0");
-}
-
-#[test]
-fn roundtrip() {
-    fn roundtrip(p: &str) {
-        println!("parse: {}", p);
-        let s = p.parse::<TokenStream>().unwrap().to_string();
-        println!("first: {}", s);
-        let s2 = s.to_string().parse::<TokenStream>().unwrap().to_string();
-        assert_eq!(s, s2);
-    }
-    roundtrip("a");
-    roundtrip("<<");
-    roundtrip("<<=");
-    roundtrip(
-        "
-        1
-        1.0
-        1f32
-        2f64
-        1usize
-        4isize
-        4e10
-        1_000
-        1_0i32
-        8u8
-        9
-        0
-        0xffffffffffffffffffffffffffffffff
-    ",
-    );
-    roundtrip("'a");
-    roundtrip("'static");
-    roundtrip("'\\u{10__FFFF}'");
-    roundtrip("\"\\u{10_F0FF__}foo\\u{1_0_0_0__}\"");
-}
-
-#[test]
-fn fail() {
-    fn fail(p: &str) {
-        if p.parse::<TokenStream>().is_ok() {
-            panic!("should have failed to parse: {}", p);
-        }
-    }
-    fail("1x");
-    fail("1u80");
-    fail("1f320");
-    fail("' static");
-    fail("'mut");
-    fail("r#1");
-    fail("r#_");
-}
-
-#[cfg(procmacro2_semver_exempt)]
-#[test]
-fn span_test() {
-    use proc_macro2::TokenTree;
-
-    fn check_spans(p: &str, mut lines: &[(usize, usize, usize, usize)]) {
-        let ts = p.parse::<TokenStream>().unwrap();
-        check_spans_internal(ts, &mut lines);
-    }
-
-    fn check_spans_internal(ts: TokenStream, lines: &mut &[(usize, usize, usize, usize)]) {
-        for i in ts {
-            if let Some((&(sline, scol, eline, ecol), rest)) = lines.split_first() {
-                *lines = rest;
-
-                let start = i.span().start();
-                assert_eq!(start.line, sline, "sline did not match for {}", i);
-                assert_eq!(start.column, scol, "scol did not match for {}", i);
-
-                let end = i.span().end();
-                assert_eq!(end.line, eline, "eline did not match for {}", i);
-                assert_eq!(end.column, ecol, "ecol did not match for {}", i);
-
-                match i {
-                    TokenTree::Group(ref g) => {
-                        check_spans_internal(g.stream().clone(), lines);
-                    }
-                    _ => {}
-                }
-            }
-        }
-    }
-
-    check_spans(
-        "\
-/// This is a document comment
-testing 123
-{
-  testing 234
-}",
-        &[
-            (1, 0, 1, 30),  // #
-            (1, 0, 1, 30),  // [ ... ]
-            (1, 0, 1, 30),  // doc
-            (1, 0, 1, 30),  // =
-            (1, 0, 1, 30),  // "This is..."
-            (2, 0, 2, 7),   // testing
-            (2, 8, 2, 11),  // 123
-            (3, 0, 5, 1),   // { ... }
-            (4, 2, 4, 9),   // testing
-            (4, 10, 4, 13), // 234
-        ],
-    );
-}
-
-#[cfg(procmacro2_semver_exempt)]
-#[cfg(not(feature = "nightly"))]
-#[test]
-fn default_span() {
-    let start = Span::call_site().start();
-    assert_eq!(start.line, 1);
-    assert_eq!(start.column, 0);
-    let end = Span::call_site().end();
-    assert_eq!(end.line, 1);
-    assert_eq!(end.column, 0);
-    let source_file = Span::call_site().source_file();
-    assert_eq!(source_file.path().to_string(), "<unspecified>");
-    assert!(!source_file.is_real());
-}
-
-#[cfg(procmacro2_semver_exempt)]
-#[test]
-fn span_join() {
-    let source1 = "aaa\nbbb"
-        .parse::<TokenStream>()
-        .unwrap()
-        .into_iter()
-        .collect::<Vec<_>>();
-    let source2 = "ccc\nddd"
-        .parse::<TokenStream>()
-        .unwrap()
-        .into_iter()
-        .collect::<Vec<_>>();
-
-    assert!(source1[0].span().source_file() != source2[0].span().source_file());
-    assert_eq!(
-        source1[0].span().source_file(),
-        source1[1].span().source_file()
-    );
-
-    let joined1 = source1[0].span().join(source1[1].span());
-    let joined2 = source1[0].span().join(source2[0].span());
-    assert!(joined1.is_some());
-    assert!(joined2.is_none());
-
-    let start = joined1.unwrap().start();
-    let end = joined1.unwrap().end();
-    assert_eq!(start.line, 1);
-    assert_eq!(start.column, 0);
-    assert_eq!(end.line, 2);
-    assert_eq!(end.column, 3);
-
-    assert_eq!(
-        joined1.unwrap().source_file(),
-        source1[0].span().source_file()
-    );
-}
-
-#[test]
-fn no_panic() {
-    let s = str::from_utf8(b"b\'\xc2\x86  \x00\x00\x00^\"").unwrap();
-    assert!(s.parse::<proc_macro2::TokenStream>().is_err());
-}
-
-#[test]
-fn tricky_doc_comment() {
-    let stream = "/**/".parse::<proc_macro2::TokenStream>().unwrap();
-    let tokens = stream.into_iter().collect::<Vec<_>>();
-    assert!(tokens.is_empty(), "not empty -- {:?}", tokens);
-
-    let stream = "/// doc".parse::<proc_macro2::TokenStream>().unwrap();
-    let tokens = stream.into_iter().collect::<Vec<_>>();
-    assert!(tokens.len() == 2, "not length 2 -- {:?}", tokens);
-    match tokens[0] {
-        proc_macro2::TokenTree::Op(ref tt) => assert_eq!(tt.op(), '#'),
-        _ => panic!("wrong token {:?}", tokens[0]),
-    }
-    let mut tokens = match tokens[1] {
-        proc_macro2::TokenTree::Group(ref tt) => {
-            assert_eq!(tt.delimiter(), proc_macro2::Delimiter::Bracket);
-            tt.stream().into_iter()
-        }
-        _ => panic!("wrong token {:?}", tokens[0]),
-    };
-
-    match tokens.next().unwrap() {
-        proc_macro2::TokenTree::Term(ref tt) => assert_eq!(tt.as_str(), "doc"),
-        t => panic!("wrong token {:?}", t),
-    }
-    match tokens.next().unwrap() {
-        proc_macro2::TokenTree::Op(ref tt) => assert_eq!(tt.op(), '='),
-        t => panic!("wrong token {:?}", t),
-    }
-    match tokens.next().unwrap() {
-        proc_macro2::TokenTree::Literal(ref tt) => {
-            assert_eq!(tt.to_string(), "\" doc\"");
-        }
-        t => panic!("wrong token {:?}", t),
-    }
-    assert!(tokens.next().is_none());
-
-    let stream = "//! doc".parse::<proc_macro2::TokenStream>().unwrap();
-    let tokens = stream.into_iter().collect::<Vec<_>>();
-    assert!(tokens.len() == 3, "not length 3 -- {:?}", tokens);
-}
-
-#[test]
-fn raw_identifier() {
-    let mut tts = TokenStream::from_str("r#dyn").unwrap().into_iter();
-    match tts.next().unwrap() {
-        TokenTree::Term(raw) => assert_eq!("r#dyn", raw.as_str()),
-        wrong => panic!("wrong token {:?}", wrong),
-    }
-    assert!(tts.next().is_none());
-}