deleted file mode 100644
--- a/third_party/rust/bitflags-1.0.0/.cargo-checksum.json
+++ /dev/null
@@ -1,1 +0,0 @@
-{"files":{".travis.yml":"d0da6f63d93a5cfb6536e3be8714239386a79fbfdfe3e6ec92a78c8ddde62010","Cargo.toml":"5a87b6a8e0411a560659a73163f9a222b4b6fa46c6d3ef7bb4dc1e5152807b4a","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"6485b8ed310d3f0340bf1ad1f47645069ce4069dcc6bb46c7d5c6faf41de1fdb","README.md":"aedcbbbefde11d7d8df61645aa93324695e7035d847e934a92e0250920287072","src/example_generated.rs":"8e8f188edaaefb8cc75064bd9e6dfdb8d776132ad838cff377a1acf08216186f","src/lib.rs":"d66cedd360642fcaf89a84408ea6b336f9d89948800e0a8149465cc3a022a621","tests/conflicting_trait_impls.rs":"a2a2e28dee83ead220bbc76653ae203242d9024e05aa47217049c91dd66e3b91","tests/external.rs":"1ec3fb8681056383397f34a9ae87c3d24f031715f88602cab19fa3c820e021b0","tests/external_no_std.rs":"75e0e2d6257b67d4ab9d975a9851f0a874ca7d2cdb0940df6212eafbb0fc2d88","tests/i128_bitflags.rs":"e55fbd7529839bffb8e3a8bf00516b7aca9f4a51cfda5177da17aece8328ad55"},"package":"f5cde24d1b2e2216a726368b2363a273739c91f4e3eb4e0dd12d672d396ad989"}
\ No newline at end of file
deleted file mode 100644
--- a/third_party/rust/bitflags-1.0.0/.travis.yml
+++ /dev/null
@@ -1,31 +0,0 @@
-os:
- - linux
- - osx
-language: rust
-rust:
- # This version is tested to avoid unintentional bumping of the minimum supported Rust version
- - 1.20.0
- - stable
- - beta
- - nightly
-sudo: false
-before_script:
- - pip install -v 'travis-cargo<0.2' --user && export PATH=$HOME/.local/bin:$PATH
- - if [[ -e ~/Library/Python/2.7/bin ]]; then export PATH=~/Library/Python/2.7/bin:$PATH; fi
-script:
- - cargo build --verbose
- - cargo test --verbose
- - travis-cargo --only nightly test
- - cargo doc --no-deps
-after_success:
- - travis-cargo --only nightly doc-upload
-env:
- global:
- - TRAVIS_CARGO_NIGHTLY_FEATURE=unstable_testing
- - secure: "DoZ8g8iPs+X3xEEucke0Ae02JbkQ1qd1SSv/L2aQqxULmREtRcbzRauhiT+ToQO5Ft1Lul8uck14nPfs4gMr/O3jFFBhEBVpSlbkJx7eNL3kwUdp95UNroA8I43xPN/nccJaHDN6TMTD3+uajTQTje2SyzOQP+1gvdKg17kguvE="
-
-
-
-notifications:
- email:
- on_success: never
deleted file mode 100644
--- a/third_party/rust/bitflags-1.0.0/Cargo.toml
+++ /dev/null
@@ -1,31 +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 = "bitflags"
-version = "1.0.0"
-authors = ["The Rust Project Developers"]
-description = "A macro to generate structures which behave like bitflags.\n"
-homepage = "https://github.com/rust-lang-nursery/bitflags"
-documentation = "https://docs.rs/bitflags"
-readme = "README.md"
-keywords = ["bit", "bitmask", "bitflags"]
-categories = ["no-std"]
-license = "MIT/Apache-2.0"
-repository = "https://github.com/rust-lang-nursery/bitflags"
-
-[features]
-unstable_testing = []
-default = ["example_generated"]
-example_generated = []
-[badges.travis-ci]
-repository = "rust-lang-nursery/bitflags"
deleted file mode 100644
--- a/third_party/rust/bitflags-1.0.0/LICENSE-APACHE
+++ /dev/null
@@ -1,201 +0,0 @@
- Apache License
- Version 2.0, January 2004
- http://www.apache.org/licenses/
-
-TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
-1. Definitions.
-
- "License" shall mean the terms and conditions for use, reproduction,
- and distribution as defined by Sections 1 through 9 of this document.
-
- "Licensor" shall mean the copyright owner or entity authorized by
- the copyright owner that is granting the License.
-
- "Legal Entity" shall mean the union of the acting entity and all
- other entities that control, are controlled by, or are under common
- control with that entity. For the purposes of this definition,
- "control" means (i) the power, direct or indirect, to cause the
- direction or management of such entity, whether by contract or
- otherwise, or (ii) ownership of fifty percent (50%) or more of the
- outstanding shares, or (iii) beneficial ownership of such entity.
-
- "You" (or "Your") shall mean an individual or Legal Entity
- exercising permissions granted by this License.
-
- "Source" form shall mean the preferred form for making modifications,
- including but not limited to software source code, documentation
- source, and configuration files.
-
- "Object" form shall mean any form resulting from mechanical
- transformation or translation of a Source form, including but
- not limited to compiled object code, generated documentation,
- and conversions to other media types.
-
- "Work" shall mean the work of authorship, whether in Source or
- Object form, made available under the License, as indicated by a
- copyright notice that is included in or attached to the work
- (an example is provided in the Appendix below).
-
- "Derivative Works" shall mean any work, whether in Source or Object
- form, that is based on (or derived from) the Work and for which the
- editorial revisions, annotations, elaborations, or other modifications
- represent, as a whole, an original work of authorship. For the purposes
- of this License, Derivative Works shall not include works that remain
- separable from, or merely link (or bind by name) to the interfaces of,
- the Work and Derivative Works thereof.
-
- "Contribution" shall mean any work of authorship, including
- the original version of the Work and any modifications or additions
- to that Work or Derivative Works thereof, that is intentionally
- submitted to Licensor for inclusion in the Work by the copyright owner
- or by an individual or Legal Entity authorized to submit on behalf of
- the copyright owner. For the purposes of this definition, "submitted"
- means any form of electronic, verbal, or written communication sent
- to the Licensor or its representatives, including but not limited to
- communication on electronic mailing lists, source code control systems,
- and issue tracking systems that are managed by, or on behalf of, the
- Licensor for the purpose of discussing and improving the Work, but
- excluding communication that is conspicuously marked or otherwise
- designated in writing by the copyright owner as "Not a Contribution."
-
- "Contributor" shall mean Licensor and any individual or Legal Entity
- on behalf of whom a Contribution has been received by Licensor and
- subsequently incorporated within the Work.
-
-2. Grant of Copyright License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- copyright license to reproduce, prepare Derivative Works of,
- publicly display, publicly perform, sublicense, and distribute the
- Work and such Derivative Works in Source or Object form.
-
-3. Grant of Patent License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- (except as stated in this section) patent license to make, have made,
- use, offer to sell, sell, import, and otherwise transfer the Work,
- where such license applies only to those patent claims licensable
- by such Contributor that are necessarily infringed by their
- Contribution(s) alone or by combination of their Contribution(s)
- with the Work to which such Contribution(s) was submitted. If You
- institute patent litigation against any entity (including a
- cross-claim or counterclaim in a lawsuit) alleging that the Work
- or a Contribution incorporated within the Work constitutes direct
- or contributory patent infringement, then any patent licenses
- granted to You under this License for that Work shall terminate
- as of the date such litigation is filed.
-
-4. Redistribution. You may reproduce and distribute copies of the
- Work or Derivative Works thereof in any medium, with or without
- modifications, and in Source or Object form, provided that You
- meet the following conditions:
-
- (a) You must give any other recipients of the Work or
- Derivative Works a copy of this License; and
-
- (b) You must cause any modified files to carry prominent notices
- stating that You changed the files; and
-
- (c) You must retain, in the Source form of any Derivative Works
- that You distribute, all copyright, patent, trademark, and
- attribution notices from the Source form of the Work,
- excluding those notices that do not pertain to any part of
- the Derivative Works; and
-
- (d) If the Work includes a "NOTICE" text file as part of its
- distribution, then any Derivative Works that You distribute must
- include a readable copy of the attribution notices contained
- within such NOTICE file, excluding those notices that do not
- pertain to any part of the Derivative Works, in at least one
- of the following places: within a NOTICE text file distributed
- as part of the Derivative Works; within the Source form or
- documentation, if provided along with the Derivative Works; or,
- within a display generated by the Derivative Works, if and
- wherever such third-party notices normally appear. The contents
- of the NOTICE file are for informational purposes only and
- do not modify the License. You may add Your own attribution
- notices within Derivative Works that You distribute, alongside
- or as an addendum to the NOTICE text from the Work, provided
- that such additional attribution notices cannot be construed
- as modifying the License.
-
- You may add Your own copyright statement to Your modifications and
- may provide additional or different license terms and conditions
- for use, reproduction, or distribution of Your modifications, or
- for any such Derivative Works as a whole, provided Your use,
- reproduction, and distribution of the Work otherwise complies with
- the conditions stated in this License.
-
-5. Submission of Contributions. Unless You explicitly state otherwise,
- any Contribution intentionally submitted for inclusion in the Work
- by You to the Licensor shall be under the terms and conditions of
- this License, without any additional terms or conditions.
- Notwithstanding the above, nothing herein shall supersede or modify
- the terms of any separate license agreement you may have executed
- with Licensor regarding such Contributions.
-
-6. Trademarks. This License does not grant permission to use the trade
- names, trademarks, service marks, or product names of the Licensor,
- except as required for reasonable and customary use in describing the
- origin of the Work and reproducing the content of the NOTICE file.
-
-7. Disclaimer of Warranty. Unless required by applicable law or
- agreed to in writing, Licensor provides the Work (and each
- Contributor provides its Contributions) on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
- implied, including, without limitation, any warranties or conditions
- of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
- PARTICULAR PURPOSE. You are solely responsible for determining the
- appropriateness of using or redistributing the Work and assume any
- risks associated with Your exercise of permissions under this License.
-
-8. Limitation of Liability. In no event and under no legal theory,
- whether in tort (including negligence), contract, or otherwise,
- unless required by applicable law (such as deliberate and grossly
- negligent acts) or agreed to in writing, shall any Contributor be
- liable to You for damages, including any direct, indirect, special,
- incidental, or consequential damages of any character arising as a
- result of this License or out of the use or inability to use the
- Work (including but not limited to damages for loss of goodwill,
- work stoppage, computer failure or malfunction, or any and all
- other commercial damages or losses), even if such Contributor
- has been advised of the possibility of such damages.
-
-9. Accepting Warranty or Additional Liability. While redistributing
- the Work or Derivative Works thereof, You may choose to offer,
- and charge a fee for, acceptance of support, warranty, indemnity,
- or other liability obligations and/or rights consistent with this
- License. However, in accepting such obligations, You may act only
- on Your own behalf and on Your sole responsibility, not on behalf
- of any other Contributor, and only if You agree to indemnify,
- defend, and hold each Contributor harmless for any liability
- incurred by, or claims asserted against, such Contributor by reason
- of your accepting any such warranty or additional liability.
-
-END OF TERMS AND CONDITIONS
-
-APPENDIX: How to apply the Apache License to your work.
-
- To apply the Apache License to your work, attach the following
- boilerplate notice, with the fields enclosed by brackets "[]"
- replaced with your own identifying information. (Don't include
- the brackets!) The text should be enclosed in the appropriate
- comment syntax for the file format. We also recommend that a
- file or class name and description of purpose be included on the
- same "printed page" as the copyright notice for easier
- identification within third-party archives.
-
-Copyright [yyyy] [name of copyright owner]
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
deleted file mode 100644
--- a/third_party/rust/bitflags-1.0.0/LICENSE-MIT
+++ /dev/null
@@ -1,25 +0,0 @@
-Copyright (c) 2014 The Rust Project Developers
-
-Permission is hereby granted, free of charge, to any
-person obtaining a copy of this software and associated
-documentation files (the "Software"), to deal in the
-Software without restriction, including without
-limitation the rights to use, copy, modify, merge,
-publish, distribute, sublicense, and/or sell copies of
-the Software, and to permit persons to whom the Software
-is furnished to do so, subject to the following
-conditions:
-
-The above copyright notice and this permission notice
-shall be included in all copies or substantial portions
-of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
-ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
-TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
-PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
-SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
-CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
-IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
-DEALINGS IN THE SOFTWARE.
deleted file mode 100644
--- a/third_party/rust/bitflags-1.0.0/README.md
+++ /dev/null
@@ -1,31 +0,0 @@
-bitflags
-========
-
-A Rust macro to generate structures which behave like a set of bitflags
-
-[![Build Status](https://travis-ci.org/rust-lang-nursery/bitflags.svg?branch=master)](https://travis-ci.org/rust-lang-nursery/bitflags)
-
-- [Documentation](https://docs.rs/bitflags)
-- [Release notes](https://github.com/rust-lang-nursery/bitflags/releases)
-
-## Usage
-
-Add this to your `Cargo.toml`:
-
-```toml
-[dependencies]
-bitflags = "1.0"
-```
-
-and this to your crate root:
-
-```rust
-#[macro_use]
-extern crate bitflags;
-```
-
-## Rust Version Support
-
-The minimum supported* Rust version is 1.20 due to use of associated constants.
-
-_* As of the current master branch (unreleased)_
deleted file mode 100644
--- a/third_party/rust/bitflags-1.0.0/src/example_generated.rs
+++ /dev/null
@@ -1,16 +0,0 @@
-//! This module shows an example of code generated by the macro. **IT MUST NOT BE USED OUTSIDE THIS
-//! CRATE**.
-
-bitflags! {
- /// This is the same `Flags` struct defined in the [crate level example](../index.html#example).
- /// Note that this struct is just for documentation purposes only, it must not be used outside
- /// this crate.
- pub struct Flags: u32 {
- const FLAG_A = 0b00000001;
- const FLAG_B = 0b00000010;
- const FLAG_C = 0b00000100;
- const FLAG_ABC = Self::FLAG_A.bits
- | Self::FLAG_B.bits
- | Self::FLAG_C.bits;
- }
-}
deleted file mode 100644
--- a/third_party/rust/bitflags-1.0.0/src/lib.rs
+++ /dev/null
@@ -1,1085 +0,0 @@
-// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-//! A typesafe bitmask flag generator useful for sets of C-style bitmask flags.
-//! It can be used for creating typesafe wrappers around C APIs.
-//!
-//! The `bitflags!` macro generates a `struct` that manages a set of flags. The
-//! flags should only be defined for integer types, otherwise unexpected type
-//! errors may occur at compile time.
-//!
-//! # Example
-//!
-//! ```
-//! #[macro_use]
-//! extern crate bitflags;
-//!
-//! bitflags! {
-//! struct Flags: u32 {
-//! const FLAG_A = 0b00000001;
-//! const FLAG_B = 0b00000010;
-//! const FLAG_C = 0b00000100;
-//! const FLAG_ABC = Self::FLAG_A.bits
-//! | Self::FLAG_B.bits
-//! | Self::FLAG_C.bits;
-//! }
-//! }
-//!
-//! fn main() {
-//! let e1 = Flags::FLAG_A | Flags::FLAG_C;
-//! let e2 = Flags::FLAG_B | Flags::FLAG_C;
-//! assert_eq!((e1 | e2), Flags::FLAG_ABC); // union
-//! assert_eq!((e1 & e2), Flags::FLAG_C); // intersection
-//! assert_eq!((e1 - e2), Flags::FLAG_A); // set difference
-//! assert_eq!(!e2, Flags::FLAG_A); // set complement
-//! }
-//! ```
-//!
-//! See [`example_generated::Flags`](./example_generated/struct.Flags.html) for documentation of code
-//! generated by the above `bitflags!` expansion.
-//!
-//! The generated `struct`s can also be extended with type and trait
-//! implementations:
-//!
-//! ```
-//! #[macro_use]
-//! extern crate bitflags;
-//!
-//! use std::fmt;
-//!
-//! bitflags! {
-//! struct Flags: u32 {
-//! const FLAG_A = 0b00000001;
-//! const FLAG_B = 0b00000010;
-//! }
-//! }
-//!
-//! impl Flags {
-//! pub fn clear(&mut self) {
-//! self.bits = 0; // The `bits` field can be accessed from within the
-//! // same module where the `bitflags!` macro was invoked.
-//! }
-//! }
-//!
-//! impl fmt::Display for Flags {
-//! fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-//! write!(f, "hi!")
-//! }
-//! }
-//!
-//! fn main() {
-//! let mut flags = Flags::FLAG_A | Flags::FLAG_B;
-//! flags.clear();
-//! assert!(flags.is_empty());
-//! assert_eq!(format!("{}", flags), "hi!");
-//! assert_eq!(format!("{:?}", Flags::FLAG_A | Flags::FLAG_B), "FLAG_A | FLAG_B");
-//! assert_eq!(format!("{:?}", Flags::FLAG_B), "FLAG_B");
-//! }
-//! ```
-//!
-//! # Visibility
-//!
-//! The generated struct and its associated flag constants are not exported
-//! out of the current module by default. A definition can be exported out of
-//! the current module by adding `pub` before `flags`:
-//!
-//! ```ignore
-//! #[macro_use]
-//! extern crate bitflags;
-//!
-//! mod example {
-//! bitflags! {
-//! pub struct Flags1: u32 {
-//! const FLAG_A = 0b00000001;
-//! }
-//! }
-//! bitflags! {
-//! struct Flags2: u32 {
-//! const FLAG_B = 0b00000010;
-//! }
-//! }
-//! }
-//!
-//! fn main() {
-//! let flag1 = example::Flags1::FLAG_A;
-//! let flag2 = example::Flags2::FLAG_B; // error: const `FLAG_B` is private
-//! }
-//! ```
-//!
-//! # Attributes
-//!
-//! Attributes can be attached to the generated `struct` by placing them
-//! before the `flags` keyword.
-//!
-//! # Trait implementations
-//!
-//! The `Copy`, `Clone`, `PartialEq`, `Eq`, `PartialOrd`, `Ord` and `Hash`
-//! traits automatically derived for the `struct` using the `derive` attribute.
-//! Additional traits can be derived by providing an explicit `derive`
-//! attribute on `flags`.
-//!
-//! The `Extend` and `FromIterator` traits are implemented for the `struct`,
-//! too: `Extend` adds the union of the instances of the `struct` iterated over,
-//! while `FromIterator` calculates the union.
-//!
-//! The `Binary`, `Debug`, `LowerExp`, `Octal` and `UpperExp` trait is also
-//! implemented by displaying the bits value of the internal struct.
-//!
-//! ## Operators
-//!
-//! The following operator traits are implemented for the generated `struct`:
-//!
-//! - `BitOr` and `BitOrAssign`: union
-//! - `BitAnd` and `BitAndAssign`: intersection
-//! - `BitXor` and `BitXorAssign`: toggle
-//! - `Sub` and `SubAssign`: set difference
-//! - `Not`: set complement
-//!
-//! # Methods
-//!
-//! The following methods are defined for the generated `struct`:
-//!
-//! - `empty`: an empty set of flags
-//! - `all`: the set of all flags
-//! - `bits`: the raw value of the flags currently stored
-//! - `from_bits`: convert from underlying bit representation, unless that
-//! representation contains bits that do not correspond to a flag
-//! - `from_bits_truncate`: convert from underlying bit representation, dropping
-//! any bits that do not correspond to flags
-//! - `is_empty`: `true` if no flags are currently stored
-//! - `is_all`: `true` if all flags are currently set
-//! - `intersects`: `true` if there are flags common to both `self` and `other`
-//! - `contains`: `true` all of the flags in `other` are contained within `self`
-//! - `insert`: inserts the specified flags in-place
-//! - `remove`: removes the specified flags in-place
-//! - `toggle`: the specified flags will be inserted if not present, and removed
-//! if they are.
-//! - `set`: inserts or removes the specified flags depending on the passed value
-//!
-//! ## Default
-//!
-//! The `Default` trait is not automatically implemented for the generated struct.
-//!
-//! If your default value is equal to `0` (which is the same value as calling `empty()`
-//! on the generated struct), you can simply derive `Default`:
-//!
-//! ```
-//! #[macro_use]
-//! extern crate bitflags;
-//!
-//! bitflags! {
-//! // Results in default value with bits: 0
-//! #[derive(Default)]
-//! struct Flags: u32 {
-//! const FLAG_A = 0b00000001;
-//! const FLAG_B = 0b00000010;
-//! const FLAG_C = 0b00000100;
-//! }
-//! }
-//!
-//! fn main() {
-//! let derived_default: Flags = Default::default();
-//! assert_eq!(derived_default.bits(), 0);
-//! }
-//! ```
-//!
-//! If your default value is not equal to `0` you need to implement `Default` yourself:
-//!
-//! ```
-//! #[macro_use]
-//! extern crate bitflags;
-//!
-//! bitflags! {
-//! struct Flags: u32 {
-//! const FLAG_A = 0b00000001;
-//! const FLAG_B = 0b00000010;
-//! const FLAG_C = 0b00000100;
-//! }
-//! }
-//!
-//! // explicit `Default` implementation
-//! impl Default for Flags {
-//! fn default() -> Flags {
-//! Flags::FLAG_A | Flags::FLAG_C
-//! }
-//! }
-//!
-//! fn main() {
-//! let implemented_default: Flags = Default::default();
-//! assert_eq!(implemented_default, (Flags::FLAG_A | Flags::FLAG_C));
-//! }
-//! ```
-
-#![no_std]
-
-#![doc(html_root_url = "https://docs.rs/bitflags/1.0.0")]
-// When compiled for the rustc compiler itself we want to make sure that this is
-// an unstable crate.
-#![cfg_attr(rustbuild, feature(staged_api))]
-#![cfg_attr(rustbuild, unstable(feature = "rustc_private", issue = "27812"))]
-
-#[cfg(test)]
-#[macro_use]
-extern crate std;
-
-// Re-export libstd/libcore using an alias so that the macros can work in no_std
-// crates while remaining compatible with normal crates.
-#[doc(hidden)]
-pub extern crate core as _core;
-
-/// The macro used to generate the flag structure.
-///
-/// See the [crate level docs](../bitflags/index.html) for complete documentation.
-///
-/// # Example
-///
-/// ```
-/// #[macro_use]
-/// extern crate bitflags;
-///
-/// bitflags! {
-/// struct Flags: u32 {
-/// const FLAG_A = 0b00000001;
-/// const FLAG_B = 0b00000010;
-/// const FLAG_C = 0b00000100;
-/// const FLAG_ABC = Self::FLAG_A.bits
-/// | Self::FLAG_B.bits
-/// | Self::FLAG_C.bits;
-/// }
-/// }
-///
-/// fn main() {
-/// let e1 = Flags::FLAG_A | Flags::FLAG_C;
-/// let e2 = Flags::FLAG_B | Flags::FLAG_C;
-/// assert_eq!((e1 | e2), Flags::FLAG_ABC); // union
-/// assert_eq!((e1 & e2), Flags::FLAG_C); // intersection
-/// assert_eq!((e1 - e2), Flags::FLAG_A); // set difference
-/// assert_eq!(!e2, Flags::FLAG_A); // set complement
-/// }
-/// ```
-///
-/// The generated `struct`s can also be extended with type and trait
-/// implementations:
-///
-/// ```
-/// #[macro_use]
-/// extern crate bitflags;
-///
-/// use std::fmt;
-///
-/// bitflags! {
-/// struct Flags: u32 {
-/// const FLAG_A = 0b00000001;
-/// const FLAG_B = 0b00000010;
-/// }
-/// }
-///
-/// impl Flags {
-/// pub fn clear(&mut self) {
-/// self.bits = 0; // The `bits` field can be accessed from within the
-/// // same module where the `bitflags!` macro was invoked.
-/// }
-/// }
-///
-/// impl fmt::Display for Flags {
-/// fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-/// write!(f, "hi!")
-/// }
-/// }
-///
-/// fn main() {
-/// let mut flags = Flags::FLAG_A | Flags::FLAG_B;
-/// flags.clear();
-/// assert!(flags.is_empty());
-/// assert_eq!(format!("{}", flags), "hi!");
-/// assert_eq!(format!("{:?}", Flags::FLAG_A | Flags::FLAG_B), "FLAG_A | FLAG_B");
-/// assert_eq!(format!("{:?}", Flags::FLAG_B), "FLAG_B");
-/// }
-/// ```
-#[macro_export]
-macro_rules! bitflags {
- (
- $(#[$outer:meta])*
- pub struct $BitFlags:ident: $T:ty {
- $(
- $(#[$inner:ident $($args:tt)*])*
- const $Flag:ident = $value:expr;
- )+
- }
- ) => {
- #[derive(Copy, PartialEq, Eq, Clone, PartialOrd, Ord, Hash)]
- $(#[$outer])*
- pub struct $BitFlags {
- bits: $T,
- }
-
- __impl_bitflags! {
- struct $BitFlags: $T {
- $(
- $(#[$inner $($args)*])*
- const $Flag = $value;
- )+
- }
- }
- };
- (
- $(#[$outer:meta])*
- struct $BitFlags:ident: $T:ty {
- $(
- $(#[$inner:ident $($args:tt)*])*
- const $Flag:ident = $value:expr;
- )+
- }
- ) => {
- #[derive(Copy, PartialEq, Eq, Clone, PartialOrd, Ord, Hash)]
- $(#[$outer])*
- struct $BitFlags {
- bits: $T,
- }
-
- __impl_bitflags! {
- struct $BitFlags: $T {
- $(
- $(#[$inner $($args)*])*
- const $Flag = $value;
- )+
- }
- }
- };
-}
-
-#[macro_export]
-#[doc(hidden)]
-macro_rules! __impl_bitflags {
- (
- struct $BitFlags:ident: $T:ty {
- $(
- $(#[$attr:ident $($args:tt)*])*
- const $Flag:ident = $value:expr;
- )+
- }
- ) => {
- impl $crate::_core::fmt::Debug for $BitFlags {
- fn fmt(&self, f: &mut $crate::_core::fmt::Formatter) -> $crate::_core::fmt::Result {
- // This convoluted approach is to handle #[cfg]-based flag
- // omission correctly. For example it needs to support:
- //
- // #[cfg(unix)] const A: Flag = /* ... */;
- // #[cfg(windows)] const B: Flag = /* ... */;
-
- // Unconditionally define a check for every flag, even disabled
- // ones.
- #[allow(non_snake_case)]
- trait __BitFlags {
- $(
- fn $Flag(&self) -> bool { false }
- )+
- }
-
- // Conditionally override the check for just those flags that
- // are not #[cfg]ed away.
- impl __BitFlags for $BitFlags {
- $(
- __impl_bitflags! {
- #[allow(deprecated)]
- $(? #[$attr $($args)*])*
- fn $Flag(&self) -> bool {
- self.bits & Self::$Flag.bits == Self::$Flag.bits
- }
- }
- )+
- }
-
- let mut first = true;
- $(
- if <$BitFlags as __BitFlags>::$Flag(self) {
- if !first {
- try!(f.write_str(" | "));
- }
- first = false;
- try!(f.write_str(stringify!($Flag)));
- }
- )+
- if first {
- try!(f.write_str("(empty)"));
- }
- Ok(())
- }
- }
- impl $crate::_core::fmt::Binary for $BitFlags {
- fn fmt(&self, f: &mut $crate::_core::fmt::Formatter) -> $crate::_core::fmt::Result {
- $crate::_core::fmt::Binary::fmt(&self.bits, f)
- }
- }
- impl $crate::_core::fmt::Octal for $BitFlags {
- fn fmt(&self, f: &mut $crate::_core::fmt::Formatter) -> $crate::_core::fmt::Result {
- $crate::_core::fmt::Octal::fmt(&self.bits, f)
- }
- }
- impl $crate::_core::fmt::LowerHex for $BitFlags {
- fn fmt(&self, f: &mut $crate::_core::fmt::Formatter) -> $crate::_core::fmt::Result {
- $crate::_core::fmt::LowerHex::fmt(&self.bits, f)
- }
- }
- impl $crate::_core::fmt::UpperHex for $BitFlags {
- fn fmt(&self, f: &mut $crate::_core::fmt::Formatter) -> $crate::_core::fmt::Result {
- $crate::_core::fmt::UpperHex::fmt(&self.bits, f)
- }
- }
-
- #[allow(dead_code)]
- impl $BitFlags {
- $(
- $(#[$attr $($args)*])*
- pub const $Flag: $BitFlags = $BitFlags { bits: $value };
- )+
-
- /// Returns an empty set of flags.
- #[inline]
- pub fn empty() -> $BitFlags {
- $BitFlags { bits: 0 }
- }
-
- /// Returns the set containing all flags.
- #[inline]
- pub fn all() -> $BitFlags {
- // See `Debug::fmt` for why this approach is taken.
- #[allow(non_snake_case)]
- trait __BitFlags {
- $(
- fn $Flag() -> $T { 0 }
- )+
- }
- impl __BitFlags for $BitFlags {
- $(
- __impl_bitflags! {
- #[allow(deprecated)]
- $(? #[$attr $($args)*])*
- fn $Flag() -> $T { Self::$Flag.bits }
- }
- )+
- }
- $BitFlags { bits: $(<$BitFlags as __BitFlags>::$Flag())|+ }
- }
-
- /// Returns the raw value of the flags currently stored.
- #[inline]
- pub fn bits(&self) -> $T {
- self.bits
- }
-
- /// Convert from underlying bit representation, unless that
- /// representation contains bits that do not correspond to a flag.
- #[inline]
- pub fn from_bits(bits: $T) -> $crate::_core::option::Option<$BitFlags> {
- if (bits & !$BitFlags::all().bits()) == 0 {
- $crate::_core::option::Option::Some($BitFlags { bits: bits })
- } else {
- $crate::_core::option::Option::None
- }
- }
-
- /// Convert from underlying bit representation, dropping any bits
- /// that do not correspond to flags.
- #[inline]
- pub fn from_bits_truncate(bits: $T) -> $BitFlags {
- $BitFlags { bits: bits } & $BitFlags::all()
- }
-
- /// Returns `true` if no flags are currently stored.
- #[inline]
- pub fn is_empty(&self) -> bool {
- *self == $BitFlags::empty()
- }
-
- /// Returns `true` if all flags are currently set.
- #[inline]
- pub fn is_all(&self) -> bool {
- *self == $BitFlags::all()
- }
-
- /// Returns `true` if there are flags common to both `self` and `other`.
- #[inline]
- pub fn intersects(&self, other: $BitFlags) -> bool {
- !(*self & other).is_empty()
- }
-
- /// Returns `true` all of the flags in `other` are contained within `self`.
- #[inline]
- pub fn contains(&self, other: $BitFlags) -> bool {
- (*self & other) == other
- }
-
- /// Inserts the specified flags in-place.
- #[inline]
- pub fn insert(&mut self, other: $BitFlags) {
- self.bits |= other.bits;
- }
-
- /// Removes the specified flags in-place.
- #[inline]
- pub fn remove(&mut self, other: $BitFlags) {
- self.bits &= !other.bits;
- }
-
- /// Toggles the specified flags in-place.
- #[inline]
- pub fn toggle(&mut self, other: $BitFlags) {
- self.bits ^= other.bits;
- }
-
- /// Inserts or removes the specified flags depending on the passed value.
- #[inline]
- pub fn set(&mut self, other: $BitFlags, value: bool) {
- if value {
- self.insert(other);
- } else {
- self.remove(other);
- }
- }
- }
-
- impl $crate::_core::ops::BitOr for $BitFlags {
- type Output = $BitFlags;
-
- /// Returns the union of the two sets of flags.
- #[inline]
- fn bitor(self, other: $BitFlags) -> $BitFlags {
- $BitFlags { bits: self.bits | other.bits }
- }
- }
-
- impl $crate::_core::ops::BitOrAssign for $BitFlags {
-
- /// Adds the set of flags.
- #[inline]
- fn bitor_assign(&mut self, other: $BitFlags) {
- self.bits |= other.bits;
- }
- }
-
- impl $crate::_core::ops::BitXor for $BitFlags {
- type Output = $BitFlags;
-
- /// Returns the left flags, but with all the right flags toggled.
- #[inline]
- fn bitxor(self, other: $BitFlags) -> $BitFlags {
- $BitFlags { bits: self.bits ^ other.bits }
- }
- }
-
- impl $crate::_core::ops::BitXorAssign for $BitFlags {
-
- /// Toggles the set of flags.
- #[inline]
- fn bitxor_assign(&mut self, other: $BitFlags) {
- self.bits ^= other.bits;
- }
- }
-
- impl $crate::_core::ops::BitAnd for $BitFlags {
- type Output = $BitFlags;
-
- /// Returns the intersection between the two sets of flags.
- #[inline]
- fn bitand(self, other: $BitFlags) -> $BitFlags {
- $BitFlags { bits: self.bits & other.bits }
- }
- }
-
- impl $crate::_core::ops::BitAndAssign for $BitFlags {
-
- /// Disables all flags disabled in the set.
- #[inline]
- fn bitand_assign(&mut self, other: $BitFlags) {
- self.bits &= other.bits;
- }
- }
-
- impl $crate::_core::ops::Sub for $BitFlags {
- type Output = $BitFlags;
-
- /// Returns the set difference of the two sets of flags.
- #[inline]
- fn sub(self, other: $BitFlags) -> $BitFlags {
- $BitFlags { bits: self.bits & !other.bits }
- }
- }
-
- impl $crate::_core::ops::SubAssign for $BitFlags {
-
- /// Disables all flags enabled in the set.
- #[inline]
- fn sub_assign(&mut self, other: $BitFlags) {
- self.bits &= !other.bits;
- }
- }
-
- impl $crate::_core::ops::Not for $BitFlags {
- type Output = $BitFlags;
-
- /// Returns the complement of this set of flags.
- #[inline]
- fn not(self) -> $BitFlags {
- $BitFlags { bits: !self.bits } & $BitFlags::all()
- }
- }
-
- impl $crate::_core::iter::Extend<$BitFlags> for $BitFlags {
- fn extend<T: $crate::_core::iter::IntoIterator<Item=$BitFlags>>(&mut self, iterator: T) {
- for item in iterator {
- self.insert(item)
- }
- }
- }
-
- impl $crate::_core::iter::FromIterator<$BitFlags> for $BitFlags {
- fn from_iter<T: $crate::_core::iter::IntoIterator<Item=$BitFlags>>(iterator: T) -> $BitFlags {
- let mut result = Self::empty();
- result.extend(iterator);
- result
- }
- }
- };
-
- // Every attribute that the user writes on a const is applied to the
- // corresponding const that we generate, but within the implementation of
- // Debug and all() we want to ignore everything but #[cfg] attributes. In
- // particular, including a #[deprecated] attribute on those items would fail
- // to compile.
- // https://github.com/rust-lang-nursery/bitflags/issues/109
- //
- // Input:
- //
- // ? #[cfg(feature = "advanced")]
- // ? #[deprecated(note = "Use somthing else.")]
- // ? #[doc = r"High quality documentation."]
- // fn f() -> i32 { /* ... */ }
- //
- // Output:
- //
- // #[cfg(feature = "advanced")]
- // fn f() -> i32 { /* ... */ }
- (
- $(#[$filtered:meta])*
- ? #[cfg $($cfgargs:tt)*]
- $(? #[$rest:ident $($restargs:tt)*])*
- fn $($item:tt)*
- ) => {
- __impl_bitflags! {
- $(#[$filtered])*
- #[cfg $($cfgargs)*]
- $(? #[$rest $($restargs)*])*
- fn $($item)*
- }
- };
- (
- $(#[$filtered:meta])*
- // $next != `cfg`
- ? #[$next:ident $($nextargs:tt)*]
- $(? #[$rest:ident $($restargs:tt)*])*
- fn $($item:tt)*
- ) => {
- __impl_bitflags! {
- $(#[$filtered])*
- // $next filtered out
- $(? #[$rest $($restargs)*])*
- fn $($item)*
- }
- };
- (
- $(#[$filtered:meta])*
- fn $($item:tt)*
- ) => {
- $(#[$filtered])*
- fn $($item)*
- };
-}
-
-#[cfg(feature = "example_generated")]
-pub mod example_generated;
-
-#[cfg(test)]
-mod tests {
- use std::hash::{Hash, Hasher};
- use std::collections::hash_map::DefaultHasher;
-
- bitflags! {
- #[doc = "> The first principle is that you must not fool yourself — and"]
- #[doc = "> you are the easiest person to fool."]
- #[doc = "> "]
- #[doc = "> - Richard Feynman"]
- struct Flags: u32 {
- const FLAG_A = 0b00000001;
- #[doc = "<pcwalton> macros are way better at generating code than trans is"]
- const FLAG_B = 0b00000010;
- const FLAG_C = 0b00000100;
- #[doc = "* cmr bed"]
- #[doc = "* strcat table"]
- #[doc = "<strcat> wait what?"]
- const FLAG_ABC = Self::FLAG_A.bits
- | Self::FLAG_B.bits
- | Self::FLAG_C.bits;
- }
- }
-
- bitflags! {
- struct _CfgFlags: u32 {
- #[cfg(windows)]
- const _CFG_A = 0b01;
- #[cfg(unix)]
- const _CFG_B = 0b01;
- #[cfg(windows)]
- const _CFG_C = _CFG_A.bits | 0b10;
- }
- }
-
- bitflags! {
- struct AnotherSetOfFlags: i8 {
- const ANOTHER_FLAG = -1_i8;
- }
- }
-
- bitflags! {
- struct LongFlags: u32 {
- const LONG_FLAG_A = 0b1111111111111111;
- }
- }
-
- #[test]
- fn test_bits(){
- assert_eq!(Flags::empty().bits(), 0b00000000);
- assert_eq!(Flags::FLAG_A.bits(), 0b00000001);
- assert_eq!(Flags::FLAG_ABC.bits(), 0b00000111);
-
- assert_eq!(AnotherSetOfFlags::empty().bits(), 0b00);
- assert_eq!(AnotherSetOfFlags::ANOTHER_FLAG.bits(), !0_i8);
- }
-
- #[test]
- fn test_from_bits() {
- assert_eq!(Flags::from_bits(0), Some(Flags::empty()));
- assert_eq!(Flags::from_bits(0b1), Some(Flags::FLAG_A));
- assert_eq!(Flags::from_bits(0b10), Some(Flags::FLAG_B));
- assert_eq!(Flags::from_bits(0b11), Some(Flags::FLAG_A | Flags::FLAG_B));
- assert_eq!(Flags::from_bits(0b1000), None);
-
- assert_eq!(AnotherSetOfFlags::from_bits(!0_i8), Some(AnotherSetOfFlags::ANOTHER_FLAG));
- }
-
- #[test]
- fn test_from_bits_truncate() {
- assert_eq!(Flags::from_bits_truncate(0), Flags::empty());
- assert_eq!(Flags::from_bits_truncate(0b1), Flags::FLAG_A);
- assert_eq!(Flags::from_bits_truncate(0b10), Flags::FLAG_B);
- assert_eq!(Flags::from_bits_truncate(0b11), (Flags::FLAG_A | Flags::FLAG_B));
- assert_eq!(Flags::from_bits_truncate(0b1000), Flags::empty());
- assert_eq!(Flags::from_bits_truncate(0b1001), Flags::FLAG_A);
-
- assert_eq!(AnotherSetOfFlags::from_bits_truncate(0_i8), AnotherSetOfFlags::empty());
- }
-
- #[test]
- fn test_is_empty(){
- assert!(Flags::empty().is_empty());
- assert!(!Flags::FLAG_A.is_empty());
- assert!(!Flags::FLAG_ABC.is_empty());
-
- assert!(!AnotherSetOfFlags::ANOTHER_FLAG.is_empty());
- }
-
- #[test]
- fn test_is_all() {
- assert!(Flags::all().is_all());
- assert!(!Flags::FLAG_A.is_all());
- assert!(Flags::FLAG_ABC.is_all());
-
- assert!(AnotherSetOfFlags::ANOTHER_FLAG.is_all());
- }
-
- #[test]
- fn test_two_empties_do_not_intersect() {
- let e1 = Flags::empty();
- let e2 = Flags::empty();
- assert!(!e1.intersects(e2));
-
- assert!(AnotherSetOfFlags::ANOTHER_FLAG.intersects(AnotherSetOfFlags::ANOTHER_FLAG));
- }
-
- #[test]
- fn test_empty_does_not_intersect_with_full() {
- let e1 = Flags::empty();
- let e2 = Flags::FLAG_ABC;
- assert!(!e1.intersects(e2));
- }
-
- #[test]
- fn test_disjoint_intersects() {
- let e1 = Flags::FLAG_A;
- let e2 = Flags::FLAG_B;
- assert!(!e1.intersects(e2));
- }
-
- #[test]
- fn test_overlapping_intersects() {
- let e1 = Flags::FLAG_A;
- let e2 = Flags::FLAG_A | Flags::FLAG_B;
- assert!(e1.intersects(e2));
- }
-
- #[test]
- fn test_contains() {
- let e1 = Flags::FLAG_A;
- let e2 = Flags::FLAG_A | Flags::FLAG_B;
- assert!(!e1.contains(e2));
- assert!(e2.contains(e1));
- assert!(Flags::FLAG_ABC.contains(e2));
-
- assert!(AnotherSetOfFlags::ANOTHER_FLAG.contains(AnotherSetOfFlags::ANOTHER_FLAG));
- }
-
- #[test]
- fn test_insert(){
- let mut e1 = Flags::FLAG_A;
- let e2 = Flags::FLAG_A | Flags::FLAG_B;
- e1.insert(e2);
- assert_eq!(e1, e2);
-
- let mut e3 = AnotherSetOfFlags::empty();
- e3.insert(AnotherSetOfFlags::ANOTHER_FLAG);
- assert_eq!(e3, AnotherSetOfFlags::ANOTHER_FLAG);
- }
-
- #[test]
- fn test_remove(){
- let mut e1 = Flags::FLAG_A | Flags::FLAG_B;
- let e2 = Flags::FLAG_A | Flags::FLAG_C;
- e1.remove(e2);
- assert_eq!(e1, Flags::FLAG_B);
-
- let mut e3 = AnotherSetOfFlags::ANOTHER_FLAG;
- e3.remove(AnotherSetOfFlags::ANOTHER_FLAG);
- assert_eq!(e3, AnotherSetOfFlags::empty());
- }
-
- #[test]
- fn test_operators() {
- let e1 = Flags::FLAG_A | Flags::FLAG_C;
- let e2 = Flags::FLAG_B | Flags::FLAG_C;
- assert_eq!((e1 | e2), Flags::FLAG_ABC); // union
- assert_eq!((e1 & e2), Flags::FLAG_C); // intersection
- assert_eq!((e1 - e2), Flags::FLAG_A); // set difference
- assert_eq!(!e2, Flags::FLAG_A); // set complement
- assert_eq!(e1 ^ e2, Flags::FLAG_A | Flags::FLAG_B); // toggle
- let mut e3 = e1;
- e3.toggle(e2);
- assert_eq!(e3, Flags::FLAG_A | Flags::FLAG_B);
-
- let mut m4 = AnotherSetOfFlags::empty();
- m4.toggle(AnotherSetOfFlags::empty());
- assert_eq!(m4, AnotherSetOfFlags::empty());
- }
-
- #[test]
- fn test_set() {
- let mut e1 = Flags::FLAG_A | Flags::FLAG_C;
- e1.set(Flags::FLAG_B, true);
- e1.set(Flags::FLAG_C, false);
-
- assert_eq!(e1, Flags::FLAG_A | Flags::FLAG_B);
- }
-
- #[test]
- fn test_assignment_operators() {
- let mut m1 = Flags::empty();
- let e1 = Flags::FLAG_A | Flags::FLAG_C;
- // union
- m1 |= Flags::FLAG_A;
- assert_eq!(m1, Flags::FLAG_A);
- // intersection
- m1 &= e1;
- assert_eq!(m1, Flags::FLAG_A);
- // set difference
- m1 -= m1;
- assert_eq!(m1, Flags::empty());
- // toggle
- m1 ^= e1;
- assert_eq!(m1, e1);
- }
-
- #[test]
- fn test_extend() {
- let mut flags;
-
- flags = Flags::empty();
- flags.extend([].iter().cloned());
- assert_eq!(flags, Flags::empty());
-
- flags = Flags::empty();
- flags.extend([Flags::FLAG_A, Flags::FLAG_B].iter().cloned());
- assert_eq!(flags, Flags::FLAG_A | Flags::FLAG_B);
-
- flags = Flags::FLAG_A;
- flags.extend([Flags::FLAG_A, Flags::FLAG_B].iter().cloned());
- assert_eq!(flags, Flags::FLAG_A | Flags::FLAG_B);
-
- flags = Flags::FLAG_B;
- flags.extend([Flags::FLAG_A, Flags::FLAG_ABC].iter().cloned());
- assert_eq!(flags, Flags::FLAG_ABC);
- }
-
- #[test]
- fn test_from_iterator() {
- assert_eq!([].iter().cloned().collect::<Flags>(), Flags::empty());
- assert_eq!([Flags::FLAG_A, Flags::FLAG_B].iter().cloned().collect::<Flags>(),
- Flags::FLAG_A | Flags::FLAG_B);
- assert_eq!([Flags::FLAG_A, Flags::FLAG_ABC].iter().cloned().collect::<Flags>(),
- Flags::FLAG_ABC);
- }
-
- #[test]
- fn test_lt() {
- let mut a = Flags::empty();
- let mut b = Flags::empty();
-
- assert!(!(a < b) && !(b < a));
- b = Flags::FLAG_B;
- assert!(a < b);
- a = Flags::FLAG_C;
- assert!(!(a < b) && b < a);
- b = Flags::FLAG_C | Flags::FLAG_B;
- assert!(a < b);
- }
-
- #[test]
- fn test_ord() {
- let mut a = Flags::empty();
- let mut b = Flags::empty();
-
- assert!(a <= b && a >= b);
- a = Flags::FLAG_A;
- assert!(a > b && a >= b);
- assert!(b < a && b <= a);
- b = Flags::FLAG_B;
- assert!(b > a && b >= a);
- assert!(a < b && a <= b);
- }
-
- fn hash<T: Hash>(t: &T) -> u64 {
- let mut s = DefaultHasher::new();
- t.hash(&mut s);
- s.finish()
- }
-
- #[test]
- fn test_hash() {
- let mut x = Flags::empty();
- let mut y = Flags::empty();
- assert_eq!(hash(&x), hash(&y));
- x = Flags::all();
- y = Flags::FLAG_ABC;
- assert_eq!(hash(&x), hash(&y));
- }
-
- #[test]
- fn test_debug() {
- assert_eq!(format!("{:?}", Flags::FLAG_A | Flags::FLAG_B), "FLAG_A | FLAG_B");
- assert_eq!(format!("{:?}", Flags::empty()), "(empty)");
- assert_eq!(format!("{:?}", Flags::FLAG_ABC), "FLAG_A | FLAG_B | FLAG_C | FLAG_ABC");
- }
-
- #[test]
- fn test_binary() {
- assert_eq!(format!("{:b}", Flags::FLAG_ABC), "111");
- assert_eq!(format!("{:#b}", Flags::FLAG_ABC), "0b111");
- }
-
- #[test]
- fn test_octal() {
- assert_eq!(format!("{:o}", LongFlags::LONG_FLAG_A), "177777");
- assert_eq!(format!("{:#o}", LongFlags::LONG_FLAG_A), "0o177777");
- }
-
- #[test]
- fn test_lowerhex() {
- assert_eq!(format!("{:x}", LongFlags::LONG_FLAG_A), "ffff");
- assert_eq!(format!("{:#x}", LongFlags::LONG_FLAG_A), "0xffff");
- }
-
- #[test]
- fn test_upperhex() {
- assert_eq!(format!("{:X}", LongFlags::LONG_FLAG_A), "FFFF");
- assert_eq!(format!("{:#X}", LongFlags::LONG_FLAG_A), "0xFFFF");
- }
-
- mod submodule {
- bitflags! {
- pub struct PublicFlags: i8 {
- const FLAG_X = 0;
- }
- }
- bitflags! {
- struct PrivateFlags: i8 {
- const FLAG_Y = 0;
- }
- }
-
- #[test]
- fn test_private() {
-
- let _ = PrivateFlags::FLAG_Y;
- }
- }
-
- #[test]
- fn test_public() {
- let _ = submodule::PublicFlags::FLAG_X;
- }
-
- mod t1 {
- mod foo {
- pub type Bar = i32;
- }
-
- bitflags! {
- /// baz
- struct Flags: foo::Bar {
- const A = 0b00000001;
- #[cfg(foo)]
- const B = 0b00000010;
- #[cfg(foo)]
- const C = 0b00000010;
- }
- }
- }
-
- #[test]
- fn test_in_function() {
- bitflags! {
- struct Flags: u8 {
- const A = 1;
- #[cfg(any())] // false
- const B = 2;
- }
- }
- assert_eq!(Flags::all(), Flags::A);
- assert_eq!(format!("{:?}", Flags::A), "A");
- }
-
- #[test]
- fn test_deprecated() {
- bitflags! {
- pub struct TestFlags: u32 {
- #[deprecated(note = "Use something else.")]
- const FLAG_ONE = 1;
- }
- }
- }
-}
deleted file mode 100644
--- a/third_party/rust/bitflags-1.0.0/tests/conflicting_trait_impls.rs
+++ /dev/null
@@ -1,19 +0,0 @@
-#![no_std]
-
-#[macro_use]
-extern crate bitflags;
-
-#[allow(unused_imports)]
-use core::fmt::Display;
-
-bitflags! {
- /// baz
- struct Flags: u32 {
- const A = 0b00000001;
- }
-}
-
-#[test]
-fn main() {
-
-}
deleted file mode 100644
--- a/third_party/rust/bitflags-1.0.0/tests/external.rs
+++ /dev/null
@@ -1,19 +0,0 @@
-#[macro_use]
-extern crate bitflags;
-
-bitflags! {
- /// baz
- struct Flags: u32 {
- const A = 0b00000001;
- #[doc = "bar"]
- const B = 0b00000010;
- const C = 0b00000100;
- #[doc = "foo"]
- const ABC = Flags::A.bits | Flags::B.bits | Flags::C.bits;
- }
-}
-
-#[test]
-fn smoke() {
- assert_eq!(Flags::ABC, Flags::A | Flags::B | Flags::C);
-}
deleted file mode 100644
--- a/third_party/rust/bitflags-1.0.0/tests/external_no_std.rs
+++ /dev/null
@@ -1,21 +0,0 @@
-#![no_std]
-
-#[macro_use]
-extern crate bitflags;
-
-bitflags! {
- /// baz
- struct Flags: u32 {
- const A = 0b00000001;
- #[doc = "bar"]
- const B = 0b00000010;
- const C = 0b00000100;
- #[doc = "foo"]
- const ABC = Flags::A.bits | Flags::B.bits | Flags::C.bits;
- }
-}
-
-#[test]
-fn smoke() {
- assert_eq!(Flags::ABC, Flags::A | Flags::B | Flags::C);
-}
deleted file mode 100644
--- a/third_party/rust/bitflags-1.0.0/tests/i128_bitflags.rs
+++ /dev/null
@@ -1,29 +0,0 @@
-#![cfg(feature = "unstable_testing")]
-
-#![feature(i128_type)]
-
-#[macro_use]
-extern crate bitflags;
-
-bitflags! {
- /// baz
- struct Flags128: u128 {
- const A = 0x0000_0000_0000_0000_0000_0000_0000_0001;
- const B = 0x0000_0000_0000_1000_0000_0000_0000_0000;
- const C = 0x8000_0000_0000_0000_0000_0000_0000_0000;
- const ABC = Self::A.bits | Self::B.bits | Self::C.bits;
- }
-}
-
-#[test]
-fn test_i128_bitflags() {
- assert_eq!(Flags128::ABC, Flags128::A | Flags128::B | Flags128::C);
- assert_eq!(Flags128::A.bits, 0x0000_0000_0000_0000_0000_0000_0000_0001);
- assert_eq!(Flags128::B.bits, 0x0000_0000_0000_1000_0000_0000_0000_0000);
- assert_eq!(Flags128::C.bits, 0x8000_0000_0000_0000_0000_0000_0000_0000);
- assert_eq!(Flags128::ABC.bits, 0x8000_0000_0000_1000_0000_0000_0000_0001);
- assert_eq!(format!("{:?}", Flags128::A), "A");
- assert_eq!(format!("{:?}", Flags128::B), "B");
- assert_eq!(format!("{:?}", Flags128::C), "C");
- assert_eq!(format!("{:?}", Flags128::ABC), "A | B | C | ABC");
-}
deleted file mode 100644
--- a/third_party/rust/cfg-if-0.1.1/.cargo-checksum.json
+++ /dev/null
@@ -1,1 +0,0 @@
-{"files":{".travis.yml":"50f67b20a376d437e0706d9bbb0343c677295529991370b2962f814c0b2efea3","Cargo.toml":"d217067290b088db7f696e02ecc25461a0277e5e5e3bca6c7c0412b604c3526b","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"378f5840b258e2779c39418f3f2d7b2ba96f1c7917dd6be0713f88305dbda397","README.md":"3fa9368c60bc701dea294fbacae0469188c4be1de79f82e972bb9b321776cd52","src/lib.rs":"74b287a91a46dc9d0c179053b439fd40c43ad5389fbd5199fff1cce0094726a6","tests/xcrate.rs":"30dcb70fbb9c96fda2b7825592558279f534776f72e2a8a0a3e26df4dedb3caa"},"package":"d0c47d456a36ebf0536a6705c83c1cbbcb9255fbc1d905a6ded104f479268a29"}
\ No newline at end of file
deleted file mode 100644
--- a/third_party/rust/cfg-if-0.1.1/.travis.yml
+++ /dev/null
@@ -1,23 +0,0 @@
-language: rust
-rust:
- - stable
- - beta
- - nightly
-sudo: false
-before_script:
- - pip install 'travis-cargo<0.2' --user && export PATH=$HOME/.local/bin:$PATH
-script:
- - cargo build --verbose
- - cargo test --verbose
- - rustdoc --test README.md -L target/debug -L target/debug/deps
- - cargo doc --no-deps
-after_success:
- - travis-cargo --only nightly doc-upload
-env:
- global:
- secure: "TyMGH+sbPmKs9lKCziKShxWr3G6im0owEchVrbUChWnQIQv1WydXftFoEoUsVl6qZspjehWK1b1AsnIgCXK0HtEi4DnqLsxs0s36bOjfg5yHBT/pETTr6kcq7KAL4Be4GmI331k6gT1Oi0TPFp7Sg9xpiWsQqKIHA5Szk2wpFQ8="
-
-
-notifications:
- email:
- on_success: never
deleted file mode 100644
--- a/third_party/rust/cfg-if-0.1.1/Cargo.toml
+++ /dev/null
@@ -1,14 +0,0 @@
-[package]
-name = "cfg-if"
-version = "0.1.1"
-authors = ["Alex Crichton <alex@alexcrichton.com>"]
-license = "MIT/Apache-2.0"
-readme = "README.md"
-repository = "https://github.com/alexcrichton/cfg-if"
-homepage = "https://github.com/alexcrichton/cfg-if"
-documentation = "http://alexcrichton.com/cfg-if"
-description = """
-A macro to ergonomically define an item depending on a large number of #[cfg]
-parameters. Structured like an if-else chain, the first matching branch is the
-item that gets emitted.
-"""
deleted file mode 100644
--- a/third_party/rust/cfg-if-0.1.1/LICENSE-APACHE
+++ /dev/null
@@ -1,201 +0,0 @@
- Apache License
- Version 2.0, January 2004
- http://www.apache.org/licenses/
-
-TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
-1. Definitions.
-
- "License" shall mean the terms and conditions for use, reproduction,
- and distribution as defined by Sections 1 through 9 of this document.
-
- "Licensor" shall mean the copyright owner or entity authorized by
- the copyright owner that is granting the License.
-
- "Legal Entity" shall mean the union of the acting entity and all
- other entities that control, are controlled by, or are under common
- control with that entity. For the purposes of this definition,
- "control" means (i) the power, direct or indirect, to cause the
- direction or management of such entity, whether by contract or
- otherwise, or (ii) ownership of fifty percent (50%) or more of the
- outstanding shares, or (iii) beneficial ownership of such entity.
-
- "You" (or "Your") shall mean an individual or Legal Entity
- exercising permissions granted by this License.
-
- "Source" form shall mean the preferred form for making modifications,
- including but not limited to software source code, documentation
- source, and configuration files.
-
- "Object" form shall mean any form resulting from mechanical
- transformation or translation of a Source form, including but
- not limited to compiled object code, generated documentation,
- and conversions to other media types.
-
- "Work" shall mean the work of authorship, whether in Source or
- Object form, made available under the License, as indicated by a
- copyright notice that is included in or attached to the work
- (an example is provided in the Appendix below).
-
- "Derivative Works" shall mean any work, whether in Source or Object
- form, that is based on (or derived from) the Work and for which the
- editorial revisions, annotations, elaborations, or other modifications
- represent, as a whole, an original work of authorship. For the purposes
- of this License, Derivative Works shall not include works that remain
- separable from, or merely link (or bind by name) to the interfaces of,
- the Work and Derivative Works thereof.
-
- "Contribution" shall mean any work of authorship, including
- the original version of the Work and any modifications or additions
- to that Work or Derivative Works thereof, that is intentionally
- submitted to Licensor for inclusion in the Work by the copyright owner
- or by an individual or Legal Entity authorized to submit on behalf of
- the copyright owner. For the purposes of this definition, "submitted"
- means any form of electronic, verbal, or written communication sent
- to the Licensor or its representatives, including but not limited to
- communication on electronic mailing lists, source code control systems,
- and issue tracking systems that are managed by, or on behalf of, the
- Licensor for the purpose of discussing and improving the Work, but
- excluding communication that is conspicuously marked or otherwise
- designated in writing by the copyright owner as "Not a Contribution."
-
- "Contributor" shall mean Licensor and any individual or Legal Entity
- on behalf of whom a Contribution has been received by Licensor and
- subsequently incorporated within the Work.
-
-2. Grant of Copyright License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- copyright license to reproduce, prepare Derivative Works of,
- publicly display, publicly perform, sublicense, and distribute the
- Work and such Derivative Works in Source or Object form.
-
-3. Grant of Patent License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- (except as stated in this section) patent license to make, have made,
- use, offer to sell, sell, import, and otherwise transfer the Work,
- where such license applies only to those patent claims licensable
- by such Contributor that are necessarily infringed by their
- Contribution(s) alone or by combination of their Contribution(s)
- with the Work to which such Contribution(s) was submitted. If You
- institute patent litigation against any entity (including a
- cross-claim or counterclaim in a lawsuit) alleging that the Work
- or a Contribution incorporated within the Work constitutes direct
- or contributory patent infringement, then any patent licenses
- granted to You under this License for that Work shall terminate
- as of the date such litigation is filed.
-
-4. Redistribution. You may reproduce and distribute copies of the
- Work or Derivative Works thereof in any medium, with or without
- modifications, and in Source or Object form, provided that You
- meet the following conditions:
-
- (a) You must give any other recipients of the Work or
- Derivative Works a copy of this License; and
-
- (b) You must cause any modified files to carry prominent notices
- stating that You changed the files; and
-
- (c) You must retain, in the Source form of any Derivative Works
- that You distribute, all copyright, patent, trademark, and
- attribution notices from the Source form of the Work,
- excluding those notices that do not pertain to any part of
- the Derivative Works; and
-
- (d) If the Work includes a "NOTICE" text file as part of its
- distribution, then any Derivative Works that You distribute must
- include a readable copy of the attribution notices contained
- within such NOTICE file, excluding those notices that do not
- pertain to any part of the Derivative Works, in at least one
- of the following places: within a NOTICE text file distributed
- as part of the Derivative Works; within the Source form or
- documentation, if provided along with the Derivative Works; or,
- within a display generated by the Derivative Works, if and
- wherever such third-party notices normally appear. The contents
- of the NOTICE file are for informational purposes only and
- do not modify the License. You may add Your own attribution
- notices within Derivative Works that You distribute, alongside
- or as an addendum to the NOTICE text from the Work, provided
- that such additional attribution notices cannot be construed
- as modifying the License.
-
- You may add Your own copyright statement to Your modifications and
- may provide additional or different license terms and conditions
- for use, reproduction, or distribution of Your modifications, or
- for any such Derivative Works as a whole, provided Your use,
- reproduction, and distribution of the Work otherwise complies with
- the conditions stated in this License.
-
-5. Submission of Contributions. Unless You explicitly state otherwise,
- any Contribution intentionally submitted for inclusion in the Work
- by You to the Licensor shall be under the terms and conditions of
- this License, without any additional terms or conditions.
- Notwithstanding the above, nothing herein shall supersede or modify
- the terms of any separate license agreement you may have executed
- with Licensor regarding such Contributions.
-
-6. Trademarks. This License does not grant permission to use the trade
- names, trademarks, service marks, or product names of the Licensor,
- except as required for reasonable and customary use in describing the
- origin of the Work and reproducing the content of the NOTICE file.
-
-7. Disclaimer of Warranty. Unless required by applicable law or
- agreed to in writing, Licensor provides the Work (and each
- Contributor provides its Contributions) on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
- implied, including, without limitation, any warranties or conditions
- of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
- PARTICULAR PURPOSE. You are solely responsible for determining the
- appropriateness of using or redistributing the Work and assume any
- risks associated with Your exercise of permissions under this License.
-
-8. Limitation of Liability. In no event and under no legal theory,
- whether in tort (including negligence), contract, or otherwise,
- unless required by applicable law (such as deliberate and grossly
- negligent acts) or agreed to in writing, shall any Contributor be
- liable to You for damages, including any direct, indirect, special,
- incidental, or consequential damages of any character arising as a
- result of this License or out of the use or inability to use the
- Work (including but not limited to damages for loss of goodwill,
- work stoppage, computer failure or malfunction, or any and all
- other commercial damages or losses), even if such Contributor
- has been advised of the possibility of such damages.
-
-9. Accepting Warranty or Additional Liability. While redistributing
- the Work or Derivative Works thereof, You may choose to offer,
- and charge a fee for, acceptance of support, warranty, indemnity,
- or other liability obligations and/or rights consistent with this
- License. However, in accepting such obligations, You may act only
- on Your own behalf and on Your sole responsibility, not on behalf
- of any other Contributor, and only if You agree to indemnify,
- defend, and hold each Contributor harmless for any liability
- incurred by, or claims asserted against, such Contributor by reason
- of your accepting any such warranty or additional liability.
-
-END OF TERMS AND CONDITIONS
-
-APPENDIX: How to apply the Apache License to your work.
-
- To apply the Apache License to your work, attach the following
- boilerplate notice, with the fields enclosed by brackets "[]"
- replaced with your own identifying information. (Don't include
- the brackets!) The text should be enclosed in the appropriate
- comment syntax for the file format. We also recommend that a
- file or class name and description of purpose be included on the
- same "printed page" as the copyright notice for easier
- identification within third-party archives.
-
-Copyright [yyyy] [name of copyright owner]
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
deleted file mode 100644
--- a/third_party/rust/cfg-if-0.1.1/LICENSE-MIT
+++ /dev/null
@@ -1,25 +0,0 @@
-Copyright (c) 2014 Alex Crichton
-
-Permission is hereby granted, free of charge, to any
-person obtaining a copy of this software and associated
-documentation files (the "Software"), to deal in the
-Software without restriction, including without
-limitation the rights to use, copy, modify, merge,
-publish, distribute, sublicense, and/or sell copies of
-the Software, and to permit persons to whom the Software
-is furnished to do so, subject to the following
-conditions:
-
-The above copyright notice and this permission notice
-shall be included in all copies or substantial portions
-of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
-ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
-TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
-PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
-SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
-CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
-IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
-DEALINGS IN THE SOFTWARE.
deleted file mode 100644
--- a/third_party/rust/cfg-if-0.1.1/README.md
+++ /dev/null
@@ -1,44 +0,0 @@
-# cfg-if
-
-[![Build Status](https://travis-ci.org/alexcrichton/cfg-if.svg?branch=master)](https://travis-ci.org/alexcrichton/cfg-if)
-
-[Documentation](http://alexcrichton.com/cfg-if)
-
-A macro to ergonomically define an item depending on a large number of #[cfg]
-parameters. Structured like an if-else chain, the first matching branch is the
-item that gets emitted.
-
-```toml
-[dependencies]
-cfg-if = "0.1"
-```
-
-## Example
-
-```rust
-#[macro_use]
-extern crate cfg_if;
-
-cfg_if! {
- if #[cfg(unix)] {
- fn foo() { /* unix specific functionality */ }
- } else if #[cfg(target_pointer_width = "32")] {
- fn foo() { /* non-unix, 32-bit functionality */ }
- } else {
- fn foo() { /* fallback implementation */ }
- }
-}
-
-fn main() {
- foo();
-}
-```
-
-# License
-
-`cfg-if` is primarily distributed under the terms of both the MIT license and
-the Apache License (Version 2.0), with portions covered by various BSD-like
-licenses.
-
-See LICENSE-APACHE, and LICENSE-MIT for details.
-
deleted file mode 100644
--- a/third_party/rust/cfg-if-0.1.1/src/lib.rs
+++ /dev/null
@@ -1,103 +0,0 @@
-//! A macro for defining #[cfg] if-else statements.
-//!
-//! The macro provided by this crate, `cfg_if`, is similar to the `if/elif` C
-//! preprocessor macro by allowing definition of a cascade of `#[cfg]` cases,
-//! emitting the implementation which matches first.
-//!
-//! This allows you to conveniently provide a long list #[cfg]'d blocks of code
-//! without having to rewrite each clause multiple times.
-//!
-//! # Example
-//!
-//! ```
-//! #[macro_use]
-//! extern crate cfg_if;
-//!
-//! cfg_if! {
-//! if #[cfg(unix)] {
-//! fn foo() { /* unix specific functionality */ }
-//! } else if #[cfg(target_pointer_width = "32")] {
-//! fn foo() { /* non-unix, 32-bit functionality */ }
-//! } else {
-//! fn foo() { /* fallback implementation */ }
-//! }
-//! }
-//!
-//! # fn main() {}
-//! ```
-
-#![no_std]
-
-#![doc(html_root_url = "http://alexcrichton.com/cfg-if")]
-#![deny(missing_docs)]
-#![cfg_attr(test, deny(warnings))]
-
-#[macro_export]
-macro_rules! cfg_if {
- ($(
- if #[cfg($($meta:meta),*)] { $($it:item)* }
- ) else * else {
- $($it2:item)*
- }) => {
- __cfg_if_items! {
- () ;
- $( ( ($($meta),*) ($($it)*) ), )*
- ( () ($($it2)*) ),
- }
- }
-}
-
-#[macro_export]
-#[doc(hidden)]
-macro_rules! __cfg_if_items {
- (($($not:meta,)*) ; ) => {};
- (($($not:meta,)*) ; ( ($($m:meta),*) ($($it:item)*) ), $($rest:tt)*) => {
- __cfg_if_apply! { cfg(all($($m,)* not(any($($not),*)))), $($it)* }
- __cfg_if_items! { ($($not,)* $($m,)*) ; $($rest)* }
- }
-}
-
-#[macro_export]
-#[doc(hidden)]
-macro_rules! __cfg_if_apply {
- ($m:meta, $($it:item)*) => {
- $(#[$m] $it)*
- }
-}
-
-#[cfg(test)]
-mod tests {
- cfg_if! {
- if #[cfg(test)] {
- use core::option::Option as Option2;
- fn works1() -> Option2<u32> { Some(1) }
- } else {
- fn works1() -> Option<u32> { None }
- }
- }
-
- cfg_if! {
- if #[cfg(foo)] {
- fn works2() -> bool { false }
- } else if #[cfg(test)] {
- fn works2() -> bool { true }
- } else {
- fn works2() -> bool { false }
- }
- }
-
- cfg_if! {
- if #[cfg(foo)] {
- fn works3() -> bool { false }
- } else {
- fn works3() -> bool { true }
- }
- }
-
- #[test]
- fn it_works() {
- assert!(works1().is_some());
- assert!(works2());
- assert!(works3());
- }
-}
deleted file mode 100644
--- a/third_party/rust/cfg-if-0.1.1/tests/xcrate.rs
+++ /dev/null
@@ -1,17 +0,0 @@
-#[macro_use]
-extern crate cfg_if;
-
-cfg_if! {
- if #[cfg(foo)] {
- fn works() -> bool { false }
- } else if #[cfg(test)] {
- fn works() -> bool { true }
- } else {
- fn works() -> bool { false }
- }
-}
-
-#[test]
-fn smoke() {
- assert!(works());
-}
deleted file mode 100644
--- a/third_party/rust/cmake-0.1.24/.cargo-checksum.json
+++ /dev/null
@@ -1,1 +0,0 @@
-{"files":{".travis.yml":"c5565ac6e1981bf3a88d132c16e381411a239a1c25ec140ee13cf2d50f1f97d0","Cargo.toml":"b00470e46ebb5985066646479d788b7ceb4ec7155c5d0bc99d78230e323c5745","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"378f5840b258e2779c39418f3f2d7b2ba96f1c7917dd6be0713f88305dbda397","README.md":"8ca528d20639506546044c676ff9069e3e850937b02bff4194dcf9e5c3c50d64","src/lib.rs":"414fe90372fa7c7f67853af871f2ca30c117abe406b405719e615b581a9f55ff"},"package":"b8ebbb35d3dc9cd09497168f33de1acb79b265d350ab0ac34133b98f8509af1f"}
\ No newline at end of file
deleted file mode 100644
--- a/third_party/rust/cmake-0.1.24/.travis.yml
+++ /dev/null
@@ -1,20 +0,0 @@
-language: rust
-rust:
- - stable
- - beta
- - nightly
-sudo: false
-before_script:
- - pip install 'travis-cargo<0.2' --user && export PATH=$HOME/.local/bin:$PATH
-script:
- - cargo test --verbose
- - cargo doc --no-deps
-after_success:
- - travis-cargo --only nightly doc-upload
-env:
- global:
- secure: "IA467qqr1j0BpyTqG6hO8Kpt+EUDEjO1pBVhu4+L76/dygkQIwROgqdT7uXZqBPMjU6Rbi0wzGXXHJjbCWVTCjh7U/Q0bK2svtR8DKtM0o1Un/YftSUFt2p/WoiJ9PrkUjKh1rHuoyijpUqAls0JfIz8OdC45egT2SWDufljo+s="
-
-notifications:
- email:
- on_success: never
deleted file mode 100644
--- a/third_party/rust/cmake-0.1.24/Cargo.toml
+++ /dev/null
@@ -1,17 +0,0 @@
-[package]
-
-name = "cmake"
-version = "0.1.24"
-authors = ["Alex Crichton <alex@alexcrichton.com>"]
-license = "MIT/Apache-2.0"
-readme = "README.md"
-keywords = ["build-dependencies"]
-repository = "https://github.com/alexcrichton/cmake-rs"
-homepage = "https://github.com/alexcrichton/cmake-rs"
-documentation = "http://alexcrichton.com/cmake-rs"
-description = """
-A build dependency for running `cmake` to build a native library
-"""
-
-[dependencies]
-gcc = "0.3.48"
deleted file mode 100644
--- a/third_party/rust/cmake-0.1.24/LICENSE-APACHE
+++ /dev/null
@@ -1,201 +0,0 @@
- Apache License
- Version 2.0, January 2004
- http://www.apache.org/licenses/
-
-TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
-1. Definitions.
-
- "License" shall mean the terms and conditions for use, reproduction,
- and distribution as defined by Sections 1 through 9 of this document.
-
- "Licensor" shall mean the copyright owner or entity authorized by
- the copyright owner that is granting the License.
-
- "Legal Entity" shall mean the union of the acting entity and all
- other entities that control, are controlled by, or are under common
- control with that entity. For the purposes of this definition,
- "control" means (i) the power, direct or indirect, to cause the
- direction or management of such entity, whether by contract or
- otherwise, or (ii) ownership of fifty percent (50%) or more of the
- outstanding shares, or (iii) beneficial ownership of such entity.
-
- "You" (or "Your") shall mean an individual or Legal Entity
- exercising permissions granted by this License.
-
- "Source" form shall mean the preferred form for making modifications,
- including but not limited to software source code, documentation
- source, and configuration files.
-
- "Object" form shall mean any form resulting from mechanical
- transformation or translation of a Source form, including but
- not limited to compiled object code, generated documentation,
- and conversions to other media types.
-
- "Work" shall mean the work of authorship, whether in Source or
- Object form, made available under the License, as indicated by a
- copyright notice that is included in or attached to the work
- (an example is provided in the Appendix below).
-
- "Derivative Works" shall mean any work, whether in Source or Object
- form, that is based on (or derived from) the Work and for which the
- editorial revisions, annotations, elaborations, or other modifications
- represent, as a whole, an original work of authorship. For the purposes
- of this License, Derivative Works shall not include works that remain
- separable from, or merely link (or bind by name) to the interfaces of,
- the Work and Derivative Works thereof.
-
- "Contribution" shall mean any work of authorship, including
- the original version of the Work and any modifications or additions
- to that Work or Derivative Works thereof, that is intentionally
- submitted to Licensor for inclusion in the Work by the copyright owner
- or by an individual or Legal Entity authorized to submit on behalf of
- the copyright owner. For the purposes of this definition, "submitted"
- means any form of electronic, verbal, or written communication sent
- to the Licensor or its representatives, including but not limited to
- communication on electronic mailing lists, source code control systems,
- and issue tracking systems that are managed by, or on behalf of, the
- Licensor for the purpose of discussing and improving the Work, but
- excluding communication that is conspicuously marked or otherwise
- designated in writing by the copyright owner as "Not a Contribution."
-
- "Contributor" shall mean Licensor and any individual or Legal Entity
- on behalf of whom a Contribution has been received by Licensor and
- subsequently incorporated within the Work.
-
-2. Grant of Copyright License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- copyright license to reproduce, prepare Derivative Works of,
- publicly display, publicly perform, sublicense, and distribute the
- Work and such Derivative Works in Source or Object form.
-
-3. Grant of Patent License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- (except as stated in this section) patent license to make, have made,
- use, offer to sell, sell, import, and otherwise transfer the Work,
- where such license applies only to those patent claims licensable
- by such Contributor that are necessarily infringed by their
- Contribution(s) alone or by combination of their Contribution(s)
- with the Work to which such Contribution(s) was submitted. If You
- institute patent litigation against any entity (including a
- cross-claim or counterclaim in a lawsuit) alleging that the Work
- or a Contribution incorporated within the Work constitutes direct
- or contributory patent infringement, then any patent licenses
- granted to You under this License for that Work shall terminate
- as of the date such litigation is filed.
-
-4. Redistribution. You may reproduce and distribute copies of the
- Work or Derivative Works thereof in any medium, with or without
- modifications, and in Source or Object form, provided that You
- meet the following conditions:
-
- (a) You must give any other recipients of the Work or
- Derivative Works a copy of this License; and
-
- (b) You must cause any modified files to carry prominent notices
- stating that You changed the files; and
-
- (c) You must retain, in the Source form of any Derivative Works
- that You distribute, all copyright, patent, trademark, and
- attribution notices from the Source form of the Work,
- excluding those notices that do not pertain to any part of
- the Derivative Works; and
-
- (d) If the Work includes a "NOTICE" text file as part of its
- distribution, then any Derivative Works that You distribute must
- include a readable copy of the attribution notices contained
- within such NOTICE file, excluding those notices that do not
- pertain to any part of the Derivative Works, in at least one
- of the following places: within a NOTICE text file distributed
- as part of the Derivative Works; within the Source form or
- documentation, if provided along with the Derivative Works; or,
- within a display generated by the Derivative Works, if and
- wherever such third-party notices normally appear. The contents
- of the NOTICE file are for informational purposes only and
- do not modify the License. You may add Your own attribution
- notices within Derivative Works that You distribute, alongside
- or as an addendum to the NOTICE text from the Work, provided
- that such additional attribution notices cannot be construed
- as modifying the License.
-
- You may add Your own copyright statement to Your modifications and
- may provide additional or different license terms and conditions
- for use, reproduction, or distribution of Your modifications, or
- for any such Derivative Works as a whole, provided Your use,
- reproduction, and distribution of the Work otherwise complies with
- the conditions stated in this License.
-
-5. Submission of Contributions. Unless You explicitly state otherwise,
- any Contribution intentionally submitted for inclusion in the Work
- by You to the Licensor shall be under the terms and conditions of
- this License, without any additional terms or conditions.
- Notwithstanding the above, nothing herein shall supersede or modify
- the terms of any separate license agreement you may have executed
- with Licensor regarding such Contributions.
-
-6. Trademarks. This License does not grant permission to use the trade
- names, trademarks, service marks, or product names of the Licensor,
- except as required for reasonable and customary use in describing the
- origin of the Work and reproducing the content of the NOTICE file.
-
-7. Disclaimer of Warranty. Unless required by applicable law or
- agreed to in writing, Licensor provides the Work (and each
- Contributor provides its Contributions) on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
- implied, including, without limitation, any warranties or conditions
- of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
- PARTICULAR PURPOSE. You are solely responsible for determining the
- appropriateness of using or redistributing the Work and assume any
- risks associated with Your exercise of permissions under this License.
-
-8. Limitation of Liability. In no event and under no legal theory,
- whether in tort (including negligence), contract, or otherwise,
- unless required by applicable law (such as deliberate and grossly
- negligent acts) or agreed to in writing, shall any Contributor be
- liable to You for damages, including any direct, indirect, special,
- incidental, or consequential damages of any character arising as a
- result of this License or out of the use or inability to use the
- Work (including but not limited to damages for loss of goodwill,
- work stoppage, computer failure or malfunction, or any and all
- other commercial damages or losses), even if such Contributor
- has been advised of the possibility of such damages.
-
-9. Accepting Warranty or Additional Liability. While redistributing
- the Work or Derivative Works thereof, You may choose to offer,
- and charge a fee for, acceptance of support, warranty, indemnity,
- or other liability obligations and/or rights consistent with this
- License. However, in accepting such obligations, You may act only
- on Your own behalf and on Your sole responsibility, not on behalf
- of any other Contributor, and only if You agree to indemnify,
- defend, and hold each Contributor harmless for any liability
- incurred by, or claims asserted against, such Contributor by reason
- of your accepting any such warranty or additional liability.
-
-END OF TERMS AND CONDITIONS
-
-APPENDIX: How to apply the Apache License to your work.
-
- To apply the Apache License to your work, attach the following
- boilerplate notice, with the fields enclosed by brackets "[]"
- replaced with your own identifying information. (Don't include
- the brackets!) The text should be enclosed in the appropriate
- comment syntax for the file format. We also recommend that a
- file or class name and description of purpose be included on the
- same "printed page" as the copyright notice for easier
- identification within third-party archives.
-
-Copyright [yyyy] [name of copyright owner]
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
deleted file mode 100644
--- a/third_party/rust/cmake-0.1.24/LICENSE-MIT
+++ /dev/null
@@ -1,25 +0,0 @@
-Copyright (c) 2014 Alex Crichton
-
-Permission is hereby granted, free of charge, to any
-person obtaining a copy of this software and associated
-documentation files (the "Software"), to deal in the
-Software without restriction, including without
-limitation the rights to use, copy, modify, merge,
-publish, distribute, sublicense, and/or sell copies of
-the Software, and to permit persons to whom the Software
-is furnished to do so, subject to the following
-conditions:
-
-The above copyright notice and this permission notice
-shall be included in all copies or substantial portions
-of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
-ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
-TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
-PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
-SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
-CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
-IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
-DEALINGS IN THE SOFTWARE.
deleted file mode 100644
--- a/third_party/rust/cmake-0.1.24/README.md
+++ /dev/null
@@ -1,22 +0,0 @@
-# cmake
-
-[![Build Status](https://travis-ci.org/alexcrichton/cmake-rs.svg?branch=master)](https://travis-ci.org/alexcrichton/cmake-rs)
-
-[Documentation](http://alexcrichton.com/cmake-rs)
-
-A build dependency for running the `cmake` build tool to compile a native
-library.
-
-```toml
-# Cargo.toml
-[build-dependencies]
-cmake = "0.2"
-```
-
-# License
-
-`cmake-rs` is primarily distributed under the terms of both the MIT license and
-the Apache License (Version 2.0), with portions covered by various BSD-like
-licenses.
-
-See LICENSE-APACHE, and LICENSE-MIT for details.
deleted file mode 100644
--- a/third_party/rust/cmake-0.1.24/src/lib.rs
+++ /dev/null
@@ -1,594 +0,0 @@
-//! A build dependency for running `cmake` to build a native library
-//!
-//! This crate provides some necessary boilerplate and shim support for running
-//! the system `cmake` command to build a native library. It will add
-//! appropriate cflags for building code to link into Rust, handle cross
-//! compilation, and use the necessary generator for the platform being
-//! targeted.
-//!
-//! The builder-style configuration allows for various variables and such to be
-//! passed down into the build as well.
-//!
-//! ## Installation
-//!
-//! Add this to your `Cargo.toml`:
-//!
-//! ```toml
-//! [build-dependencies]
-//! cmake = "0.1"
-//! ```
-//!
-//! ## Examples
-//!
-//! ```no_run
-//! use cmake;
-//!
-//! // Builds the project in the directory located in `libfoo`, installing it
-//! // into $OUT_DIR
-//! let dst = cmake::build("libfoo");
-//!
-//! println!("cargo:rustc-link-search=native={}", dst.display());
-//! println!("cargo:rustc-link-lib=static=foo");
-//! ```
-//!
-//! ```no_run
-//! use cmake::Config;
-//!
-//! let dst = Config::new("libfoo")
-//! .define("FOO", "BAR")
-//! .cflag("-foo")
-//! .build();
-//! println!("cargo:rustc-link-search=native={}", dst.display());
-//! println!("cargo:rustc-link-lib=static=foo");
-//! ```
-
-#![deny(missing_docs)]
-
-extern crate gcc;
-
-use std::env;
-use std::ffi::{OsString, OsStr};
-use std::fs::{self, File};
-use std::io::ErrorKind;
-use std::io::prelude::*;
-use std::path::{Path, PathBuf};
-use std::process::Command;
-
-/// Builder style configuration for a pending CMake build.
-pub struct Config {
- path: PathBuf,
- generator: Option<OsString>,
- cflags: OsString,
- cxxflags: OsString,
- defines: Vec<(OsString, OsString)>,
- deps: Vec<String>,
- target: Option<String>,
- host: Option<String>,
- out_dir: Option<PathBuf>,
- profile: Option<String>,
- build_args: Vec<OsString>,
- cmake_target: Option<String>,
- env: Vec<(OsString, OsString)>,
- static_crt: Option<bool>,
-}
-
-/// Builds the native library rooted at `path` with the default cmake options.
-/// This will return the directory in which the library was installed.
-///
-/// # Examples
-///
-/// ```no_run
-/// use cmake;
-///
-/// // Builds the project in the directory located in `libfoo`, installing it
-/// // into $OUT_DIR
-/// let dst = cmake::build("libfoo");
-///
-/// println!("cargo:rustc-link-search=native={}", dst.display());
-/// println!("cargo:rustc-link-lib=static=foo");
-/// ```
-///
-pub fn build<P: AsRef<Path>>(path: P) -> PathBuf {
- Config::new(path.as_ref()).build()
-}
-
-impl Config {
- /// Creates a new blank set of configuration to build the project specified
- /// at the path `path`.
- pub fn new<P: AsRef<Path>>(path: P) -> Config {
- Config {
- path: env::current_dir().unwrap().join(path),
- generator: None,
- cflags: OsString::new(),
- cxxflags: OsString::new(),
- defines: Vec::new(),
- deps: Vec::new(),
- profile: None,
- out_dir: None,
- target: None,
- host: None,
- build_args: Vec::new(),
- cmake_target: None,
- env: Vec::new(),
- static_crt: None,
- }
- }
-
- /// Sets the build-tool generator (`-G`) for this compilation.
- pub fn generator<T: AsRef<OsStr>>(&mut self, generator: T) -> &mut Config {
- self.generator = Some(generator.as_ref().to_owned());
- self
- }
-
- /// Adds a custom flag to pass down to the C compiler, supplementing those
- /// that this library already passes.
- pub fn cflag<P: AsRef<OsStr>>(&mut self, flag: P) -> &mut Config {
- self.cflags.push(" ");
- self.cflags.push(flag.as_ref());
- self
- }
-
- /// Adds a custom flag to pass down to the C++ compiler, supplementing those
- /// that this library already passes.
- pub fn cxxflag<P: AsRef<OsStr>>(&mut self, flag: P) -> &mut Config {
- self.cxxflags.push(" ");
- self.cxxflags.push(flag.as_ref());
- self
- }
-
- /// Adds a new `-D` flag to pass to cmake during the generation step.
- pub fn define<K, V>(&mut self, k: K, v: V) -> &mut Config
- where K: AsRef<OsStr>, V: AsRef<OsStr>
- {
- self.defines.push((k.as_ref().to_owned(), v.as_ref().to_owned()));
- self
- }
-
- /// Registers a dependency for this compilation on the native library built
- /// by Cargo previously.
- ///
- /// This registration will modify the `CMAKE_PREFIX_PATH` environment
- /// variable for the build system generation step.
- pub fn register_dep(&mut self, dep: &str) -> &mut Config {
- self.deps.push(dep.to_string());
- self
- }
-
- /// Sets the target triple for this compilation.
- ///
- /// This is automatically scraped from `$TARGET` which is set for Cargo
- /// build scripts so it's not necessary to call this from a build script.
- pub fn target(&mut self, target: &str) -> &mut Config {
- self.target = Some(target.to_string());
- self
- }
-
- /// Sets the host triple for this compilation.
- ///
- /// This is automatically scraped from `$HOST` which is set for Cargo
- /// build scripts so it's not necessary to call this from a build script.
- pub fn host(&mut self, host: &str) -> &mut Config {
- self.host = Some(host.to_string());
- self
- }
-
- /// Sets the output directory for this compilation.
- ///
- /// This is automatically scraped from `$OUT_DIR` which is set for Cargo
- /// build scripts so it's not necessary to call this from a build script.
- pub fn out_dir<P: AsRef<Path>>(&mut self, out: P) -> &mut Config {
- self.out_dir = Some(out.as_ref().to_path_buf());
- self
- }
-
- /// Sets the profile for this compilation.
- ///
- /// This is automatically scraped from `$PROFILE` which is set for Cargo
- /// build scripts so it's not necessary to call this from a build script.
- pub fn profile(&mut self, profile: &str) -> &mut Config {
- self.profile = Some(profile.to_string());
- self
- }
-
- /// Configures whether the /MT flag or the /MD flag will be passed to msvc build tools.
- ///
- /// This option defaults to `false`, and affect only msvc targets.
- pub fn static_crt(&mut self, static_crt: bool) -> &mut Config {
- self.static_crt = Some(static_crt);
- self
- }
-
- /// Add an argument to the final `cmake` build step
- pub fn build_arg<A: AsRef<OsStr>>(&mut self, arg: A) -> &mut Config {
- self.build_args.push(arg.as_ref().to_owned());
- self
- }
-
- /// Configure an environment variable for the `cmake` processes spawned by
- /// this crate in the `build` step.
- pub fn env<K, V>(&mut self, key: K, value: V) -> &mut Config
- where K: AsRef<OsStr>,
- V: AsRef<OsStr>,
- {
- self.env.push((key.as_ref().to_owned(), value.as_ref().to_owned()));
- self
- }
-
- /// Sets the build target for the final `cmake` build step, this will
- /// default to "install" if not specified.
- pub fn build_target(&mut self, target: &str) -> &mut Config {
- self.cmake_target = Some(target.to_string());
- self
- }
-
- /// Run this configuration, compiling the library with all the configured
- /// options.
- ///
- /// This will run both the build system generator command as well as the
- /// command to build the library.
- pub fn build(&mut self) -> PathBuf {
- let target = self.target.clone().unwrap_or_else(|| {
- getenv_unwrap("TARGET")
- });
- let host = self.host.clone().unwrap_or_else(|| {
- getenv_unwrap("HOST")
- });
- let msvc = target.contains("msvc");
- let mut c_cfg = gcc::Config::new();
- c_cfg.cargo_metadata(false)
- .opt_level(0)
- .debug(false)
- .target(&target)
- .host(&host);
- let mut cxx_cfg = gcc::Config::new();
- cxx_cfg.cargo_metadata(false)
- .cpp(true)
- .opt_level(0)
- .debug(false)
- .target(&target)
- .host(&host);
- if let Some(static_crt) = self.static_crt {
- c_cfg.static_crt(static_crt);
- cxx_cfg.static_crt(static_crt);
- }
- let c_compiler = c_cfg.get_compiler();
- let cxx_compiler = cxx_cfg.get_compiler();
-
- let dst = self.out_dir.clone().unwrap_or_else(|| {
- PathBuf::from(getenv_unwrap("OUT_DIR"))
- });
- let build = dst.join("build");
- self.maybe_clear(&build);
- let _ = fs::create_dir(&build);
-
- // Add all our dependencies to our cmake paths
- let mut cmake_prefix_path = Vec::new();
- for dep in &self.deps {
- if let Some(root) = env::var_os(&format!("DEP_{}_ROOT", dep)) {
- cmake_prefix_path.push(PathBuf::from(root));
- }
- }
- let system_prefix = env::var_os("CMAKE_PREFIX_PATH")
- .unwrap_or(OsString::new());
- cmake_prefix_path.extend(env::split_paths(&system_prefix)
- .map(|s| s.to_owned()));
- let cmake_prefix_path = env::join_paths(&cmake_prefix_path).unwrap();
-
- // Build up the first cmake command to build the build system.
- let mut cmd = Command::new("cmake");
- cmd.arg(&self.path)
- .current_dir(&build);
- if target.contains("windows-gnu") {
- if host.contains("windows") {
- // On MinGW we need to coerce cmake to not generate a visual
- // studio build system but instead use makefiles that MinGW can
- // use to build.
- if self.generator.is_none() {
- cmd.arg("-G").arg("MSYS Makefiles");
- }
- } else {
- // If we're cross compiling onto windows, then set some
- // variables which will hopefully get things to succeed. Some
- // systems may need the `windres` or `dlltool` variables set, so
- // set them if possible.
- if !self.defined("CMAKE_SYSTEM_NAME") {
- cmd.arg("-DCMAKE_SYSTEM_NAME=Windows");
- }
- if !self.defined("CMAKE_RC_COMPILER") {
- let exe = find_exe(c_compiler.path());
- if let Some(name) = exe.file_name().unwrap().to_str() {
- let name = name.replace("gcc", "windres");
- let windres = exe.with_file_name(name);
- if windres.is_file() {
- let mut arg = OsString::from("-DCMAKE_RC_COMPILER=");
- arg.push(&windres);
- cmd.arg(arg);
- }
- }
- }
- }
- } else if msvc {
- // If we're on MSVC we need to be sure to use the right generator or
- // otherwise we won't get 32/64 bit correct automatically.
- // This also guarantees that NMake generator isn't chosen implicitly.
- if self.generator.is_none() {
- cmd.arg("-G").arg(self.visual_studio_generator(&target));
- }
- }
- let mut is_ninja = false;
- if let Some(ref generator) = self.generator {
- cmd.arg("-G").arg(generator);
- is_ninja = generator.to_string_lossy().contains("Ninja");
- }
- let profile = self.profile.clone().unwrap_or_else(|| {
- match &getenv_unwrap("PROFILE")[..] {
- "bench" | "release" => "Release",
- _ => "Debug",
- }.to_string()
- });
- for &(ref k, ref v) in &self.defines {
- let mut os = OsString::from("-D");
- os.push(k);
- os.push("=");
- os.push(v);
- cmd.arg(os);
- }
-
- if !self.defined("CMAKE_INSTALL_PREFIX") {
- let mut dstflag = OsString::from("-DCMAKE_INSTALL_PREFIX=");
- dstflag.push(&dst);
- cmd.arg(dstflag);
- }
-
- let build_type = self.defines.iter().find(|&&(ref a, _)| {
- a == "CMAKE_BUILD_TYPE"
- }).map(|x| x.1.to_str().unwrap()).unwrap_or(&profile);
- let build_type_upcase = build_type.chars()
- .flat_map(|c| c.to_uppercase())
- .collect::<String>();
-
- {
- // let cmake deal with optimization/debuginfo
- let skip_arg = |arg: &OsStr| {
- match arg.to_str() {
- Some(s) => {
- s.starts_with("-O") || s.starts_with("/O") || s == "-g"
- }
- None => false,
- }
- };
- let mut set_compiler = |kind: &str,
- compiler: &gcc::Tool,
- extra: &OsString| {
- let flag_var = format!("CMAKE_{}_FLAGS", kind);
- let tool_var = format!("CMAKE_{}_COMPILER", kind);
- if !self.defined(&flag_var) {
- let mut flagsflag = OsString::from("-D");
- flagsflag.push(&flag_var);
- flagsflag.push("=");
- flagsflag.push(extra);
- for arg in compiler.args() {
- if skip_arg(arg) {
- continue
- }
- flagsflag.push(" ");
- flagsflag.push(arg);
- }
- cmd.arg(flagsflag);
- }
-
- // The visual studio generator apparently doesn't respect
- // `CMAKE_C_FLAGS` but does respect `CMAKE_C_FLAGS_RELEASE` and
- // such. We need to communicate /MD vs /MT, so set those vars
- // here.
- //
- // Note that for other generators, though, this *overrides*
- // things like the optimization flags, which is bad.
- if self.generator.is_none() && msvc {
- let flag_var_alt = format!("CMAKE_{}_FLAGS_{}", kind,
- build_type_upcase);
- if !self.defined(&flag_var_alt) {
- let mut flagsflag = OsString::from("-D");
- flagsflag.push(&flag_var_alt);
- flagsflag.push("=");
- flagsflag.push(extra);
- for arg in compiler.args() {
- if skip_arg(arg) {
- continue
- }
- flagsflag.push(" ");
- flagsflag.push(arg);
- }
- cmd.arg(flagsflag);
- }
- }
-
- // Apparently cmake likes to have an absolute path to the
- // compiler as otherwise it sometimes thinks that this variable
- // changed as it thinks the found compiler, /usr/bin/cc,
- // differs from the specified compiler, cc. Not entirely sure
- // what's up, but at least this means cmake doesn't get
- // confused?
- //
- // Also specify this on Windows only if we use MSVC with Ninja,
- // as it's not needed for MSVC with Visual Studio generators and
- // for MinGW it doesn't really vary.
- if !self.defined("CMAKE_TOOLCHAIN_FILE")
- && !self.defined(&tool_var)
- && (env::consts::FAMILY != "windows" || (msvc && is_ninja)) {
- let mut ccompiler = OsString::from("-D");
- ccompiler.push(&tool_var);
- ccompiler.push("=");
- ccompiler.push(find_exe(compiler.path()));
- #[cfg(windows)] {
- // CMake doesn't like unescaped `\`s in compiler paths
- // so we either have to escape them or replace with `/`s.
- use std::os::windows::ffi::{OsStrExt, OsStringExt};
- let wchars = ccompiler.encode_wide().map(|wchar| {
- if wchar == b'\\' as u16 { '/' as u16 } else { wchar }
- }).collect::<Vec<_>>();
- ccompiler = OsString::from_wide(&wchars);
- }
- cmd.arg(ccompiler);
- }
- };
-
- set_compiler("C", &c_compiler, &self.cflags);
- set_compiler("CXX", &cxx_compiler, &self.cxxflags);
- }
-
- if !self.defined("CMAKE_BUILD_TYPE") {
- cmd.arg(&format!("-DCMAKE_BUILD_TYPE={}", profile));
- }
-
- if !self.defined("CMAKE_TOOLCHAIN_FILE") {
- if let Ok(s) = env::var("CMAKE_TOOLCHAIN_FILE") {
- cmd.arg(&format!("-DCMAKE_TOOLCHAIN_FILE={}", s));
- }
- }
-
- for &(ref k, ref v) in c_compiler.env().iter().chain(&self.env) {
- cmd.env(k, v);
- }
-
- run(cmd.env("CMAKE_PREFIX_PATH", cmake_prefix_path), "cmake");
-
- let mut parallel_args = Vec::new();
- if let Ok(s) = env::var("NUM_JOBS") {
- match self.generator.as_ref().map(|g| g.to_string_lossy()) {
- Some(ref g) if g.contains("Ninja") => {
- parallel_args.push(format!("-j{}", s));
- }
- Some(ref g) if g.contains("Visual Studio") => {
- parallel_args.push(format!("/m:{}", s));
- }
- Some(ref g) if g.contains("NMake") => {
- // NMake creates `Makefile`s, but doesn't understand `-jN`.
- }
- _ => if fs::metadata(&dst.join("build/Makefile")).is_ok() {
- // This looks like `make`, let's hope it understands `-jN`.
- parallel_args.push(format!("-j{}", s));
- }
- }
- }
-
- // And build!
- let target = self.cmake_target.clone().unwrap_or("install".to_string());
- let mut cmd = Command::new("cmake");
- for &(ref k, ref v) in c_compiler.env().iter().chain(&self.env) {
- cmd.env(k, v);
- }
- run(cmd.arg("--build").arg(".")
- .arg("--target").arg(target)
- .arg("--config").arg(&profile)
- .arg("--").args(&self.build_args)
- .args(¶llel_args)
- .current_dir(&build), "cmake");
-
- println!("cargo:root={}", dst.display());
- return dst
- }
-
- fn visual_studio_generator(&self, target: &str) -> String {
- use gcc::windows_registry::{find_vs_version, VsVers};
-
- let base = match find_vs_version() {
- Ok(VsVers::Vs15) => "Visual Studio 15 2017",
- Ok(VsVers::Vs14) => "Visual Studio 14 2015",
- Ok(VsVers::Vs12) => "Visual Studio 12 2013",
- Ok(_) => panic!("Visual studio version detected but this crate \
- doesn't know how to generate cmake files for it, \
- can the `cmake` crate be updated?"),
- Err(msg) => panic!(msg),
- };
- if target.contains("i686") {
- base.to_string()
- } else if target.contains("x86_64") {
- format!("{} Win64", base)
- } else {
- panic!("unsupported msvc target: {}", target);
- }
- }
-
- fn defined(&self, var: &str) -> bool {
- self.defines.iter().any(|&(ref a, _)| a == var)
- }
-
- // If a cmake project has previously been built (e.g. CMakeCache.txt already
- // exists), then cmake will choke if the source directory for the original
- // project being built has changed. Detect this situation through the
- // `CMAKE_HOME_DIRECTORY` variable that cmake emits and if it doesn't match
- // we blow away the build directory and start from scratch (the recommended
- // solution apparently [1]).
- //
- // [1]: https://cmake.org/pipermail/cmake/2012-August/051545.html
- fn maybe_clear(&self, dir: &Path) {
- // CMake will apparently store canonicalized paths which normally
- // isn't relevant to us but we canonicalize it here to ensure
- // we're both checking the same thing.
- let path = fs::canonicalize(&self.path).unwrap_or(self.path.clone());
- let mut f = match File::open(dir.join("CMakeCache.txt")) {
- Ok(f) => f,
- Err(..) => return,
- };
- let mut u8contents = Vec::new();
- match f.read_to_end(&mut u8contents) {
- Ok(f) => f,
- Err(..) => return,
- };
- let contents = String::from_utf8_lossy(&u8contents);
- drop(f);
- for line in contents.lines() {
- if line.starts_with("CMAKE_HOME_DIRECTORY") {
- let needs_cleanup = match line.split('=').next_back() {
- Some(cmake_home) => {
- fs::canonicalize(cmake_home)
- .ok()
- .map(|cmake_home| cmake_home != path)
- .unwrap_or(true)
- },
- None => true
- };
- if needs_cleanup {
- println!("detected home dir change, cleaning out entire build \
- directory");
- fs::remove_dir_all(dir).unwrap();
- }
- break
- }
- }
- }
-}
-
-fn run(cmd: &mut Command, program: &str) {
- println!("running: {:?}", cmd);
- let status = match cmd.status() {
- Ok(status) => status,
- Err(ref e) if e.kind() == ErrorKind::NotFound => {
- fail(&format!("failed to execute command: {}\nis `{}` not installed?",
- e, program));
- }
- Err(e) => fail(&format!("failed to execute command: {}", e)),
- };
- if !status.success() {
- fail(&format!("command did not execute successfully, got: {}", status));
- }
-}
-
-fn find_exe(path: &Path) -> PathBuf {
- env::split_paths(&env::var_os("PATH").unwrap_or(OsString::new()))
- .map(|p| p.join(path))
- .find(|p| fs::metadata(p).is_ok())
- .unwrap_or(path.to_owned())
-}
-
-fn getenv_unwrap(v: &str) -> String {
- match env::var(v) {
- Ok(s) => s,
- Err(..) => fail(&format!("environment variable `{}` not defined", v)),
- }
-}
-
-fn fail(s: &str) -> ! {
- panic!("\n{}\n\nbuild script failed, must exit now", s)
-}
deleted file mode 100644
--- a/third_party/rust/thread_local-0.3.3/.cargo-checksum.json
+++ /dev/null
@@ -1,1 +0,0 @@
-{"files":{".travis.yml":"474743a2a8c8c7bbcc86ed6a4b68165405635651493757d97c06e965c608ee74","Cargo.toml":"0ec34b07cd55626697c62496ab1f826c9b7928697cf3362e7f5a7bcf9e080fda","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"c9a75f18b9ab2927829a208fc6aa2cf4e63b8420887ba29cdb265d6619ae82d5","README.md":"00a29378d5aeb66b7a48b77bee0d463c8b408b8a9cb0abb7674edb10d142aca0","src/lib.rs":"f5d04966ff4da2a79fe4f484687f4b845df5a2fe2b94151d4cad3f595ef6fce2"},"package":"c85048c6260d17cf486ceae3282d9fb6b90be220bf5b28c400f5485ffc29f0c7"}
\ No newline at end of file
deleted file mode 100644
--- a/third_party/rust/thread_local-0.3.3/.travis.yml
+++ /dev/null
@@ -1,28 +0,0 @@
-language: rust
-sudo: false
-
-rust:
-- nightly
-- beta
-- stable
-- 1.9.0
-
-before_script:
-- |
- pip install 'travis-cargo<0.2' --user &&
- export PATH=$HOME/.local/bin:$PATH
-
-script:
-- travis-cargo build
-- travis-cargo test
-- travis-cargo doc -- --no-deps
-
-after_success:
-- travis-cargo --only nightly doc-upload
-
-env:
- global:
- - TRAVIS_CARGO_NIGHTLY_FEATURE=""
-
-notifications:
- email: false
deleted file mode 100644
--- a/third_party/rust/thread_local-0.3.3/Cargo.toml
+++ /dev/null
@@ -1,16 +0,0 @@
-[package]
-name = "thread_local"
-version = "0.3.3"
-authors = ["Amanieu d'Antras <amanieu@gmail.com>"]
-description = "Per-object thread-local storage"
-documentation = "https://amanieu.github.io/thread_local-rs/thread_local/index.html"
-license = "Apache-2.0/MIT"
-repository = "https://github.com/Amanieu/thread_local-rs"
-readme = "README.md"
-keywords = ["thread_local", "concurrent", "thread"]
-
-[dependencies]
-unreachable = "0.1"
-
-[target.'cfg(not(target_os = "emscripten"))'.dependencies]
-thread-id = "3.0"
deleted file mode 100644
--- a/third_party/rust/thread_local-0.3.3/LICENSE-APACHE
+++ /dev/null
@@ -1,201 +0,0 @@
- Apache License
- Version 2.0, January 2004
- http://www.apache.org/licenses/
-
-TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
-1. Definitions.
-
- "License" shall mean the terms and conditions for use, reproduction,
- and distribution as defined by Sections 1 through 9 of this document.
-
- "Licensor" shall mean the copyright owner or entity authorized by
- the copyright owner that is granting the License.
-
- "Legal Entity" shall mean the union of the acting entity and all
- other entities that control, are controlled by, or are under common
- control with that entity. For the purposes of this definition,
- "control" means (i) the power, direct or indirect, to cause the
- direction or management of such entity, whether by contract or
- otherwise, or (ii) ownership of fifty percent (50%) or more of the
- outstanding shares, or (iii) beneficial ownership of such entity.
-
- "You" (or "Your") shall mean an individual or Legal Entity
- exercising permissions granted by this License.
-
- "Source" form shall mean the preferred form for making modifications,
- including but not limited to software source code, documentation
- source, and configuration files.
-
- "Object" form shall mean any form resulting from mechanical
- transformation or translation of a Source form, including but
- not limited to compiled object code, generated documentation,
- and conversions to other media types.
-
- "Work" shall mean the work of authorship, whether in Source or
- Object form, made available under the License, as indicated by a
- copyright notice that is included in or attached to the work
- (an example is provided in the Appendix below).
-
- "Derivative Works" shall mean any work, whether in Source or Object
- form, that is based on (or derived from) the Work and for which the
- editorial revisions, annotations, elaborations, or other modifications
- represent, as a whole, an original work of authorship. For the purposes
- of this License, Derivative Works shall not include works that remain
- separable from, or merely link (or bind by name) to the interfaces of,
- the Work and Derivative Works thereof.
-
- "Contribution" shall mean any work of authorship, including
- the original version of the Work and any modifications or additions
- to that Work or Derivative Works thereof, that is intentionally
- submitted to Licensor for inclusion in the Work by the copyright owner
- or by an individual or Legal Entity authorized to submit on behalf of
- the copyright owner. For the purposes of this definition, "submitted"
- means any form of electronic, verbal, or written communication sent
- to the Licensor or its representatives, including but not limited to
- communication on electronic mailing lists, source code control systems,
- and issue tracking systems that are managed by, or on behalf of, the
- Licensor for the purpose of discussing and improving the Work, but
- excluding communication that is conspicuously marked or otherwise
- designated in writing by the copyright owner as "Not a Contribution."
-
- "Contributor" shall mean Licensor and any individual or Legal Entity
- on behalf of whom a Contribution has been received by Licensor and
- subsequently incorporated within the Work.
-
-2. Grant of Copyright License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- copyright license to reproduce, prepare Derivative Works of,
- publicly display, publicly perform, sublicense, and distribute the
- Work and such Derivative Works in Source or Object form.
-
-3. Grant of Patent License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- (except as stated in this section) patent license to make, have made,
- use, offer to sell, sell, import, and otherwise transfer the Work,
- where such license applies only to those patent claims licensable
- by such Contributor that are necessarily infringed by their
- Contribution(s) alone or by combination of their Contribution(s)
- with the Work to which such Contribution(s) was submitted. If You
- institute patent litigation against any entity (including a
- cross-claim or counterclaim in a lawsuit) alleging that the Work
- or a Contribution incorporated within the Work constitutes direct
- or contributory patent infringement, then any patent licenses
- granted to You under this License for that Work shall terminate
- as of the date such litigation is filed.
-
-4. Redistribution. You may reproduce and distribute copies of the
- Work or Derivative Works thereof in any medium, with or without
- modifications, and in Source or Object form, provided that You
- meet the following conditions:
-
- (a) You must give any other recipients of the Work or
- Derivative Works a copy of this License; and
-
- (b) You must cause any modified files to carry prominent notices
- stating that You changed the files; and
-
- (c) You must retain, in the Source form of any Derivative Works
- that You distribute, all copyright, patent, trademark, and
- attribution notices from the Source form of the Work,
- excluding those notices that do not pertain to any part of
- the Derivative Works; and
-
- (d) If the Work includes a "NOTICE" text file as part of its
- distribution, then any Derivative Works that You distribute must
- include a readable copy of the attribution notices contained
- within such NOTICE file, excluding those notices that do not
- pertain to any part of the Derivative Works, in at least one
- of the following places: within a NOTICE text file distributed
- as part of the Derivative Works; within the Source form or
- documentation, if provided along with the Derivative Works; or,
- within a display generated by the Derivative Works, if and
- wherever such third-party notices normally appear. The contents
- of the NOTICE file are for informational purposes only and
- do not modify the License. You may add Your own attribution
- notices within Derivative Works that You distribute, alongside
- or as an addendum to the NOTICE text from the Work, provided
- that such additional attribution notices cannot be construed
- as modifying the License.
-
- You may add Your own copyright statement to Your modifications and
- may provide additional or different license terms and conditions
- for use, reproduction, or distribution of Your modifications, or
- for any such Derivative Works as a whole, provided Your use,
- reproduction, and distribution of the Work otherwise complies with
- the conditions stated in this License.
-
-5. Submission of Contributions. Unless You explicitly state otherwise,
- any Contribution intentionally submitted for inclusion in the Work
- by You to the Licensor shall be under the terms and conditions of
- this License, without any additional terms or conditions.
- Notwithstanding the above, nothing herein shall supersede or modify
- the terms of any separate license agreement you may have executed
- with Licensor regarding such Contributions.
-
-6. Trademarks. This License does not grant permission to use the trade
- names, trademarks, service marks, or product names of the Licensor,
- except as required for reasonable and customary use in describing the
- origin of the Work and reproducing the content of the NOTICE file.
-
-7. Disclaimer of Warranty. Unless required by applicable law or
- agreed to in writing, Licensor provides the Work (and each
- Contributor provides its Contributions) on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
- implied, including, without limitation, any warranties or conditions
- of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
- PARTICULAR PURPOSE. You are solely responsible for determining the
- appropriateness of using or redistributing the Work and assume any
- risks associated with Your exercise of permissions under this License.
-
-8. Limitation of Liability. In no event and under no legal theory,
- whether in tort (including negligence), contract, or otherwise,
- unless required by applicable law (such as deliberate and grossly
- negligent acts) or agreed to in writing, shall any Contributor be
- liable to You for damages, including any direct, indirect, special,
- incidental, or consequential damages of any character arising as a
- result of this License or out of the use or inability to use the
- Work (including but not limited to damages for loss of goodwill,
- work stoppage, computer failure or malfunction, or any and all
- other commercial damages or losses), even if such Contributor
- has been advised of the possibility of such damages.
-
-9. Accepting Warranty or Additional Liability. While redistributing
- the Work or Derivative Works thereof, You may choose to offer,
- and charge a fee for, acceptance of support, warranty, indemnity,
- or other liability obligations and/or rights consistent with this
- License. However, in accepting such obligations, You may act only
- on Your own behalf and on Your sole responsibility, not on behalf
- of any other Contributor, and only if You agree to indemnify,
- defend, and hold each Contributor harmless for any liability
- incurred by, or claims asserted against, such Contributor by reason
- of your accepting any such warranty or additional liability.
-
-END OF TERMS AND CONDITIONS
-
-APPENDIX: How to apply the Apache License to your work.
-
- To apply the Apache License to your work, attach the following
- boilerplate notice, with the fields enclosed by brackets "[]"
- replaced with your own identifying information. (Don't include
- the brackets!) The text should be enclosed in the appropriate
- comment syntax for the file format. We also recommend that a
- file or class name and description of purpose be included on the
- same "printed page" as the copyright notice for easier
- identification within third-party archives.
-
-Copyright [yyyy] [name of copyright owner]
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
deleted file mode 100644
--- a/third_party/rust/thread_local-0.3.3/LICENSE-MIT
+++ /dev/null
@@ -1,25 +0,0 @@
-Copyright (c) 2016 The Rust Project Developers
-
-Permission is hereby granted, free of charge, to any
-person obtaining a copy of this software and associated
-documentation files (the "Software"), to deal in the
-Software without restriction, including without
-limitation the rights to use, copy, modify, merge,
-publish, distribute, sublicense, and/or sell copies of
-the Software, and to permit persons to whom the Software
-is furnished to do so, subject to the following
-conditions:
-
-The above copyright notice and this permission notice
-shall be included in all copies or substantial portions
-of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
-ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
-TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
-PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
-SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
-CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
-IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
-DEALINGS IN THE SOFTWARE.
deleted file mode 100644
--- a/third_party/rust/thread_local-0.3.3/README.md
+++ /dev/null
@@ -1,41 +0,0 @@
-thread_local
-============
-
-[![Build Status](https://travis-ci.org/Amanieu/thread_local-rs.svg?branch=master)](https://travis-ci.org/Amanieu/thread_local-rs) [![Crates.io](https://img.shields.io/crates/v/thread_local.svg)](https://crates.io/crates/thread_local)
-
-This library provides the `ThreadLocal` and `CachedThreadLocal` types which
-allow a separate copy of an object to be used for each thread. This allows for
-per-object thread-local storage, unlike the standard library's `thread_local!`
-macro which only allows static thread-local storage.
-
-[Documentation](https://amanieu.github.io/thread_local-rs/thread_local/index.html)
-
-## Usage
-
-Add this to your `Cargo.toml`:
-
-```toml
-[dependencies]
-thread_local = "0.3"
-```
-
-and this to your crate root:
-
-```rust
-extern crate thread_local;
-```
-
-## License
-
-Licensed under either of
-
- * Apache License, Version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or http://www.apache.org/licenses/LICENSE-2.0)
- * MIT license ([LICENSE-MIT](LICENSE-MIT) or http://opensource.org/licenses/MIT)
-
-at your option.
-
-### Contribution
-
-Unless you explicitly state otherwise, any contribution intentionally submitted
-for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any
-additional terms or conditions.
deleted file mode 100644
--- a/third_party/rust/thread_local-0.3.3/src/lib.rs
+++ /dev/null
@@ -1,753 +0,0 @@
-// Copyright 2016 Amanieu d'Antras
-//
-// Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or
-// http://apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or
-// http://opensource.org/licenses/MIT>, at your option. This file may not be
-// copied, modified, or distributed except according to those terms.
-
-//! Per-object thread-local storage
-//!
-//! This library provides the `ThreadLocal` type which allows a separate copy of
-//! an object to be used for each thread. This allows for per-object
-//! thread-local storage, unlike the standard library's `thread_local!` macro
-//! which only allows static thread-local storage.
-//!
-//! Per-thread objects are not destroyed when a thread exits. Instead, objects
-//! are only destroyed when the `ThreadLocal` containing them is destroyed.
-//!
-//! You can also iterate over the thread-local values of all thread in a
-//! `ThreadLocal` object using the `iter_mut` and `into_iter` methods. This can
-//! only be done if you have mutable access to the `ThreadLocal` object, which
-//! guarantees that you are the only thread currently accessing it.
-//!
-//! A `CachedThreadLocal` type is also provided which wraps a `ThreadLocal` but
-//! also uses a special fast path for the first thread that writes into it. The
-//! fast path has very low overhead (<1ns per access) while keeping the same
-//! performance as `ThreadLocal` for other threads.
-//!
-//! Note that since thread IDs are recycled when a thread exits, it is possible
-//! for one thread to retrieve the object of another thread. Since this can only
-//! occur after a thread has exited this does not lead to any race conditions.
-//!
-//! # Examples
-//!
-//! Basic usage of `ThreadLocal`:
-//!
-//! ```rust
-//! use thread_local::ThreadLocal;
-//! let tls: ThreadLocal<u32> = ThreadLocal::new();
-//! assert_eq!(tls.get(), None);
-//! assert_eq!(tls.get_or(|| Box::new(5)), &5);
-//! assert_eq!(tls.get(), Some(&5));
-//! ```
-//!
-//! Combining thread-local values into a single result:
-//!
-//! ```rust
-//! use thread_local::ThreadLocal;
-//! use std::sync::Arc;
-//! use std::cell::Cell;
-//! use std::thread;
-//!
-//! let tls = Arc::new(ThreadLocal::new());
-//!
-//! // Create a bunch of threads to do stuff
-//! for _ in 0..5 {
-//! let tls2 = tls.clone();
-//! thread::spawn(move || {
-//! // Increment a counter to count some event...
-//! let cell = tls2.get_or(|| Box::new(Cell::new(0)));
-//! cell.set(cell.get() + 1);
-//! }).join().unwrap();
-//! }
-//!
-//! // Once all threads are done, collect the counter values and return the
-//! // sum of all thread-local counter values.
-//! let tls = Arc::try_unwrap(tls).unwrap();
-//! let total = tls.into_iter().fold(0, |x, y| x + y.get());
-//! assert_eq!(total, 5);
-//! ```
-
-#![warn(missing_docs)]
-
-#[cfg(not(target_os = "emscripten"))]
-extern crate thread_id;
-extern crate unreachable;
-
-use std::sync::atomic::{AtomicPtr, AtomicUsize, Ordering};
-use std::sync::Mutex;
-use std::marker::PhantomData;
-use std::cell::UnsafeCell;
-use std::fmt;
-use std::iter::Chain;
-use std::option::IntoIter as OptionIter;
-use std::panic::UnwindSafe;
-use unreachable::{UncheckedOptionExt, UncheckedResultExt};
-
-/// Thread-local variable wrapper
-///
-/// See the [module-level documentation](index.html) for more.
-pub struct ThreadLocal<T: ?Sized + Send> {
- // Pointer to the current top-level hash table
- table: AtomicPtr<Table<T>>,
-
- // Lock used to guard against concurrent modifications. This is only taken
- // while writing to the table, not when reading from it. This also guards
- // the counter for the total number of values in the hash table.
- lock: Mutex<usize>,
-
- // PhantomData to indicate that we logically own T
- marker: PhantomData<T>,
-}
-
-struct Table<T: ?Sized + Send> {
- // Hash entries for the table
- entries: Box<[TableEntry<T>]>,
-
- // Number of bits used for the hash function
- hash_bits: usize,
-
- // Previous table, half the size of the current one
- prev: Option<Box<Table<T>>>,
-}
-
-struct TableEntry<T: ?Sized + Send> {
- // Current owner of this entry, or 0 if this is an empty entry
- owner: AtomicUsize,
-
- // The object associated with this entry. This is only ever accessed by the
- // owner of the entry.
- data: UnsafeCell<Option<Box<T>>>,
-}
-
-// ThreadLocal is always Sync, even if T isn't
-unsafe impl<T: ?Sized + Send> Sync for ThreadLocal<T> {}
-
-impl<T: ?Sized + Send> Default for ThreadLocal<T> {
- fn default() -> ThreadLocal<T> {
- ThreadLocal::new()
- }
-}
-
-impl<T: ?Sized + Send> Drop for ThreadLocal<T> {
- fn drop(&mut self) {
- unsafe {
- Box::from_raw(self.table.load(Ordering::Relaxed));
- }
- }
-}
-
-// Implementation of Clone for TableEntry, needed to make vec![] work
-impl<T: ?Sized + Send> Clone for TableEntry<T> {
- fn clone(&self) -> TableEntry<T> {
- TableEntry {
- owner: AtomicUsize::new(0),
- data: UnsafeCell::new(None),
- }
- }
-}
-
-// Helper function to get a thread id
-#[cfg(not(target_os = "emscripten"))]
-fn get_thread_id() -> usize {
- thread_id::get()
-}
-#[cfg(target_os = "emscripten")]
-fn get_thread_id() -> usize {
- // pthread_self returns 0 on enscripten, but we use that as a
- // reserved value to indicate an empty slot. We instead fall
- // back to using the address of a thread-local variable, which
- // is slightly slower but guaranteed to produce a non-zero value.
- thread_local!(static KEY: u8 = unsafe { std::mem::uninitialized() });
- KEY.with(|x| x as *const _ as usize)
-}
-
-// Hash function for the thread id
-#[cfg(target_pointer_width = "32")]
-#[inline]
-fn hash(id: usize, bits: usize) -> usize {
- id.wrapping_mul(0x9E3779B9) >> (32 - bits)
-}
-#[cfg(target_pointer_width = "64")]
-#[inline]
-fn hash(id: usize, bits: usize) -> usize {
- id.wrapping_mul(0x9E3779B97F4A7C15) >> (64 - bits)
-}
-
-impl<T: ?Sized + Send> ThreadLocal<T> {
- /// Creates a new empty `ThreadLocal`.
- pub fn new() -> ThreadLocal<T> {
- let entry = TableEntry {
- owner: AtomicUsize::new(0),
- data: UnsafeCell::new(None),
- };
- let table = Table {
- entries: vec![entry; 2].into_boxed_slice(),
- hash_bits: 1,
- prev: None,
- };
- ThreadLocal {
- table: AtomicPtr::new(Box::into_raw(Box::new(table))),
- lock: Mutex::new(0),
- marker: PhantomData,
- }
- }
-
- /// Returns the element for the current thread, if it exists.
- pub fn get(&self) -> Option<&T> {
- let id = get_thread_id();
- self.get_fast(id)
- }
-
- /// Returns the element for the current thread, or creates it if it doesn't
- /// exist.
- pub fn get_or<F>(&self, create: F) -> &T
- where F: FnOnce() -> Box<T>
- {
- unsafe { self.get_or_try(|| Ok::<Box<T>, ()>(create())).unchecked_unwrap_ok() }
- }
-
- /// Returns the element for the current thread, or creates it if it doesn't
- /// exist. If `create` fails, that error is returned and no element is
- /// added.
- pub fn get_or_try<F, E>(&self, create: F) -> Result<&T, E>
- where F: FnOnce() -> Result<Box<T>, E>
- {
- let id = get_thread_id();
- match self.get_fast(id) {
- Some(x) => Ok(x),
- None => Ok(self.insert(id, try!(create()), true)),
- }
- }
-
- // Simple hash table lookup function
- fn lookup(id: usize, table: &Table<T>) -> Option<&UnsafeCell<Option<Box<T>>>> {
- // Because we use a Mutex to prevent concurrent modifications (but not
- // reads) of the hash table, we can avoid any memory barriers here. No
- // elements between our hash bucket and our value can have been modified
- // since we inserted our thread-local value into the table.
- for entry in table.entries.iter().cycle().skip(hash(id, table.hash_bits)) {
- let owner = entry.owner.load(Ordering::Relaxed);
- if owner == id {
- return Some(&entry.data);
- }
- if owner == 0 {
- return None;
- }
- }
- unreachable!();
- }
-
- // Fast path: try to find our thread in the top-level hash table
- fn get_fast(&self, id: usize) -> Option<&T> {
- let table = unsafe { &*self.table.load(Ordering::Relaxed) };
- match Self::lookup(id, table) {
- Some(x) => unsafe { Some((*x.get()).as_ref().unchecked_unwrap()) },
- None => self.get_slow(id, table),
- }
- }
-
- // Slow path: try to find our thread in the other hash tables, and then
- // move it to the top-level hash table.
- #[cold]
- fn get_slow(&self, id: usize, table_top: &Table<T>) -> Option<&T> {
- let mut current = &table_top.prev;
- while let Some(ref table) = *current {
- if let Some(x) = Self::lookup(id, table) {
- let data = unsafe { (*x.get()).take().unchecked_unwrap() };
- return Some(self.insert(id, data, false));
- }
- current = &table.prev;
- }
- None
- }
-
- #[cold]
- fn insert(&self, id: usize, data: Box<T>, new: bool) -> &T {
- // Lock the Mutex to ensure only a single thread is modify the hash
- // table at once.
- let mut count = self.lock.lock().unwrap();
- if new {
- *count += 1;
- }
- let table_raw = self.table.load(Ordering::Relaxed);
- let table = unsafe { &*table_raw };
-
- // If the current top-level hash table is more than 75% full, add a new
- // level with 2x the capacity. Elements will be moved up to the new top
- // level table as they are accessed.
- let table = if *count > table.entries.len() * 3 / 4 {
- let entry = TableEntry {
- owner: AtomicUsize::new(0),
- data: UnsafeCell::new(None),
- };
- let new_table = Box::into_raw(Box::new(Table {
- entries: vec![entry; table.entries.len() * 2].into_boxed_slice(),
- hash_bits: table.hash_bits + 1,
- prev: unsafe { Some(Box::from_raw(table_raw)) },
- }));
- self.table.store(new_table, Ordering::Release);
- unsafe { &*new_table }
- } else {
- table
- };
-
- // Insert the new element into the top-level hash table
- for entry in table.entries.iter().cycle().skip(hash(id, table.hash_bits)) {
- let owner = entry.owner.load(Ordering::Relaxed);
- if owner == 0 {
- unsafe {
- entry.owner.store(id, Ordering::Relaxed);
- *entry.data.get() = Some(data);
- return (*entry.data.get()).as_ref().unchecked_unwrap();
- }
- }
- if owner == id {
- // This can happen if create() inserted a value into this
- // ThreadLocal between our calls to get_fast() and insert(). We
- // just return the existing value and drop the newly-allocated
- // Box.
- unsafe {
- return (*entry.data.get()).as_ref().unchecked_unwrap();
- }
- }
- }
- unreachable!();
- }
-
- /// Returns a mutable iterator over the local values of all threads.
- ///
- /// Since this call borrows the `ThreadLocal` mutably, this operation can
- /// be done safely---the mutable borrow statically guarantees no other
- /// threads are currently accessing their associated values.
- pub fn iter_mut(&mut self) -> IterMut<T> {
- let raw = RawIter {
- remaining: *self.lock.lock().unwrap(),
- index: 0,
- table: self.table.load(Ordering::Relaxed),
- };
- IterMut {
- raw: raw,
- marker: PhantomData,
- }
- }
-
- /// Removes all thread-specific values from the `ThreadLocal`, effectively
- /// reseting it to its original state.
- ///
- /// Since this call borrows the `ThreadLocal` mutably, this operation can
- /// be done safely---the mutable borrow statically guarantees no other
- /// threads are currently accessing their associated values.
- pub fn clear(&mut self) {
- *self = ThreadLocal::new();
- }
-}
-
-impl<T: ?Sized + Send> IntoIterator for ThreadLocal<T> {
- type Item = Box<T>;
- type IntoIter = IntoIter<T>;
-
- fn into_iter(self) -> IntoIter<T> {
- let raw = RawIter {
- remaining: *self.lock.lock().unwrap(),
- index: 0,
- table: self.table.load(Ordering::Relaxed),
- };
- IntoIter {
- raw: raw,
- _thread_local: self,
- }
- }
-}
-
-impl<'a, T: ?Sized + Send + 'a> IntoIterator for &'a mut ThreadLocal<T> {
- type Item = &'a mut Box<T>;
- type IntoIter = IterMut<'a, T>;
-
- fn into_iter(self) -> IterMut<'a, T> {
- self.iter_mut()
- }
-}
-
-impl<T: Send + Default> ThreadLocal<T> {
- /// Returns the element for the current thread, or creates a default one if
- /// it doesn't exist.
- pub fn get_default(&self) -> &T {
- self.get_or(|| Box::new(T::default()))
- }
-}
-
-impl<T: ?Sized + Send + fmt::Debug> fmt::Debug for ThreadLocal<T> {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- write!(f, "ThreadLocal {{ local_data: {:?} }}", self.get())
- }
-}
-
-impl<T: ?Sized + Send + UnwindSafe> UnwindSafe for ThreadLocal<T> {}
-
-struct RawIter<T: ?Sized + Send> {
- remaining: usize,
- index: usize,
- table: *const Table<T>,
-}
-
-impl<T: ?Sized + Send> RawIter<T> {
- fn next(&mut self) -> Option<*mut Option<Box<T>>> {
- if self.remaining == 0 {
- return None;
- }
-
- loop {
- let entries = unsafe { &(*self.table).entries[..] };
- while self.index < entries.len() {
- let val = entries[self.index].data.get();
- self.index += 1;
- if unsafe { (*val).is_some() } {
- self.remaining -= 1;
- return Some(val);
- }
- }
- self.index = 0;
- self.table = unsafe { &**(*self.table).prev.as_ref().unchecked_unwrap() };
- }
- }
-}
-
-/// Mutable iterator over the contents of a `ThreadLocal`.
-pub struct IterMut<'a, T: ?Sized + Send + 'a> {
- raw: RawIter<T>,
- marker: PhantomData<&'a mut ThreadLocal<T>>,
-}
-
-impl<'a, T: ?Sized + Send + 'a> Iterator for IterMut<'a, T> {
- type Item = &'a mut Box<T>;
-
- fn next(&mut self) -> Option<&'a mut Box<T>> {
- self.raw.next().map(|x| unsafe { (*x).as_mut().unchecked_unwrap() })
- }
-
- fn size_hint(&self) -> (usize, Option<usize>) {
- (self.raw.remaining, Some(self.raw.remaining))
- }
-}
-
-impl<'a, T: ?Sized + Send + 'a> ExactSizeIterator for IterMut<'a, T> {}
-
-/// An iterator that moves out of a `ThreadLocal`.
-pub struct IntoIter<T: ?Sized + Send> {
- raw: RawIter<T>,
- _thread_local: ThreadLocal<T>,
-}
-
-impl<T: ?Sized + Send> Iterator for IntoIter<T> {
- type Item = Box<T>;
-
- fn next(&mut self) -> Option<Box<T>> {
- self.raw.next().map(|x| unsafe { (*x).take().unchecked_unwrap() })
- }
-
- fn size_hint(&self) -> (usize, Option<usize>) {
- (self.raw.remaining, Some(self.raw.remaining))
- }
-}
-
-impl<T: ?Sized + Send> ExactSizeIterator for IntoIter<T> {}
-
-/// Wrapper around `ThreadLocal` which adds a fast path for a single thread.
-///
-/// This has the same API as `ThreadLocal`, but will register the first thread
-/// that sets a value as its owner. All accesses by the owner will go through
-/// a special fast path which is much faster than the normal `ThreadLocal` path.
-pub struct CachedThreadLocal<T: ?Sized + Send> {
- owner: AtomicUsize,
- local: UnsafeCell<Option<Box<T>>>,
- global: ThreadLocal<T>,
-}
-
-// CachedThreadLocal is always Sync, even if T isn't
-unsafe impl<T: ?Sized + Send> Sync for CachedThreadLocal<T> {}
-
-impl<T: ?Sized + Send> Default for CachedThreadLocal<T> {
- fn default() -> CachedThreadLocal<T> {
- CachedThreadLocal::new()
- }
-}
-
-impl<T: ?Sized + Send> CachedThreadLocal<T> {
- /// Creates a new empty `CachedThreadLocal`.
- pub fn new() -> CachedThreadLocal<T> {
- CachedThreadLocal {
- owner: AtomicUsize::new(0),
- local: UnsafeCell::new(None),
- global: ThreadLocal::new(),
- }
- }
-
- /// Returns the element for the current thread, if it exists.
- pub fn get(&self) -> Option<&T> {
- let id = get_thread_id();
- let owner = self.owner.load(Ordering::Relaxed);
- if owner == id {
- return unsafe { Some((*self.local.get()).as_ref().unchecked_unwrap()) };
- }
- if owner == 0 {
- return None;
- }
- self.global.get_fast(id)
- }
-
- /// Returns the element for the current thread, or creates it if it doesn't
- /// exist.
- #[inline(always)]
- pub fn get_or<F>(&self, create: F) -> &T
- where F: FnOnce() -> Box<T>
- {
- unsafe { self.get_or_try(|| Ok::<Box<T>, ()>(create())).unchecked_unwrap_ok() }
- }
-
- /// Returns the element for the current thread, or creates it if it doesn't
- /// exist. If `create` fails, that error is returned and no element is
- /// added.
- pub fn get_or_try<F, E>(&self, create: F) -> Result<&T, E>
- where F: FnOnce() -> Result<Box<T>, E>
- {
- let id = get_thread_id();
- let owner = self.owner.load(Ordering::Relaxed);
- if owner == id {
- return Ok(unsafe { (*self.local.get()).as_ref().unchecked_unwrap() });
- }
- self.get_or_try_slow(id, owner, create)
- }
-
- #[cold]
- #[inline(never)]
- fn get_or_try_slow<F, E>(&self, id: usize, owner: usize, create: F) -> Result<&T, E>
- where F: FnOnce() -> Result<Box<T>, E>
- {
- if owner == 0 && self.owner.compare_and_swap(0, id, Ordering::Relaxed) == 0 {
- unsafe {
- (*self.local.get()) = Some(try!(create()));
- return Ok((*self.local.get()).as_ref().unchecked_unwrap());
- }
- }
- match self.global.get_fast(id) {
- Some(x) => Ok(x),
- None => Ok(self.global.insert(id, try!(create()), true)),
- }
- }
-
- /// Returns a mutable iterator over the local values of all threads.
- ///
- /// Since this call borrows the `ThreadLocal` mutably, this operation can
- /// be done safely---the mutable borrow statically guarantees no other
- /// threads are currently accessing their associated values.
- pub fn iter_mut(&mut self) -> CachedIterMut<T> {
- unsafe { (*self.local.get()).as_mut().into_iter().chain(self.global.iter_mut()) }
- }
-
- /// Removes all thread-specific values from the `ThreadLocal`, effectively
- /// reseting it to its original state.
- ///
- /// Since this call borrows the `ThreadLocal` mutably, this operation can
- /// be done safely---the mutable borrow statically guarantees no other
- /// threads are currently accessing their associated values.
- pub fn clear(&mut self) {
- *self = CachedThreadLocal::new();
- }
-}
-
-impl<T: ?Sized + Send> IntoIterator for CachedThreadLocal<T> {
- type Item = Box<T>;
- type IntoIter = CachedIntoIter<T>;
-
- fn into_iter(self) -> CachedIntoIter<T> {
- unsafe { (*self.local.get()).take().into_iter().chain(self.global.into_iter()) }
- }
-}
-
-impl<'a, T: ?Sized + Send + 'a> IntoIterator for &'a mut CachedThreadLocal<T> {
- type Item = &'a mut Box<T>;
- type IntoIter = CachedIterMut<'a, T>;
-
- fn into_iter(self) -> CachedIterMut<'a, T> {
- self.iter_mut()
- }
-}
-
-impl<T: Send + Default> CachedThreadLocal<T> {
- /// Returns the element for the current thread, or creates a default one if
- /// it doesn't exist.
- pub fn get_default(&self) -> &T {
- self.get_or(|| Box::new(T::default()))
- }
-}
-
-impl<T: ?Sized + Send + fmt::Debug> fmt::Debug for CachedThreadLocal<T> {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- write!(f, "ThreadLocal {{ local_data: {:?} }}", self.get())
- }
-}
-
-/// Mutable iterator over the contents of a `CachedThreadLocal`.
-pub type CachedIterMut<'a, T> = Chain<OptionIter<&'a mut Box<T>>, IterMut<'a, T>>;
-
-/// An iterator that moves out of a `CachedThreadLocal`.
-pub type CachedIntoIter<T> = Chain<OptionIter<Box<T>>, IntoIter<T>>;
-
-impl<T: ?Sized + Send + UnwindSafe> UnwindSafe for CachedThreadLocal<T> {}
-
-#[cfg(test)]
-mod tests {
- use std::cell::RefCell;
- use std::sync::Arc;
- use std::sync::atomic::AtomicUsize;
- use std::sync::atomic::Ordering::Relaxed;
- use std::thread;
- use super::{ThreadLocal, CachedThreadLocal};
-
- fn make_create() -> Arc<Fn() -> Box<usize> + Send + Sync> {
- let count = AtomicUsize::new(0);
- Arc::new(move || Box::new(count.fetch_add(1, Relaxed)))
- }
-
- #[test]
- fn same_thread() {
- let create = make_create();
- let mut tls = ThreadLocal::new();
- assert_eq!(None, tls.get());
- assert_eq!("ThreadLocal { local_data: None }", format!("{:?}", &tls));
- assert_eq!(0, *tls.get_or(|| create()));
- assert_eq!(Some(&0), tls.get());
- assert_eq!(0, *tls.get_or(|| create()));
- assert_eq!(Some(&0), tls.get());
- assert_eq!(0, *tls.get_or(|| create()));
- assert_eq!(Some(&0), tls.get());
- assert_eq!("ThreadLocal { local_data: Some(0) }", format!("{:?}", &tls));
- tls.clear();
- assert_eq!(None, tls.get());
- }
-
- #[test]
- fn same_thread_cached() {
- let create = make_create();
- let mut tls = CachedThreadLocal::new();
- assert_eq!(None, tls.get());
- assert_eq!("ThreadLocal { local_data: None }", format!("{:?}", &tls));
- assert_eq!(0, *tls.get_or(|| create()));
- assert_eq!(Some(&0), tls.get());
- assert_eq!(0, *tls.get_or(|| create()));
- assert_eq!(Some(&0), tls.get());
- assert_eq!(0, *tls.get_or(|| create()));
- assert_eq!(Some(&0), tls.get());
- assert_eq!("ThreadLocal { local_data: Some(0) }", format!("{:?}", &tls));
- tls.clear();
- assert_eq!(None, tls.get());
- }
-
- #[test]
- fn different_thread() {
- let create = make_create();
- let tls = Arc::new(ThreadLocal::new());
- assert_eq!(None, tls.get());
- assert_eq!(0, *tls.get_or(|| create()));
- assert_eq!(Some(&0), tls.get());
-
- let tls2 = tls.clone();
- let create2 = create.clone();
- thread::spawn(move || {
- assert_eq!(None, tls2.get());
- assert_eq!(1, *tls2.get_or(|| create2()));
- assert_eq!(Some(&1), tls2.get());
- })
- .join()
- .unwrap();
-
- assert_eq!(Some(&0), tls.get());
- assert_eq!(0, *tls.get_or(|| create()));
- }
-
- #[test]
- fn different_thread_cached() {
- let create = make_create();
- let tls = Arc::new(CachedThreadLocal::new());
- assert_eq!(None, tls.get());
- assert_eq!(0, *tls.get_or(|| create()));
- assert_eq!(Some(&0), tls.get());
-
- let tls2 = tls.clone();
- let create2 = create.clone();
- thread::spawn(move || {
- assert_eq!(None, tls2.get());
- assert_eq!(1, *tls2.get_or(|| create2()));
- assert_eq!(Some(&1), tls2.get());
- })
- .join()
- .unwrap();
-
- assert_eq!(Some(&0), tls.get());
- assert_eq!(0, *tls.get_or(|| create()));
- }
-
- #[test]
- fn iter() {
- let tls = Arc::new(ThreadLocal::new());
- tls.get_or(|| Box::new(1));
-
- let tls2 = tls.clone();
- thread::spawn(move || {
- tls2.get_or(|| Box::new(2));
- let tls3 = tls2.clone();
- thread::spawn(move || {
- tls3.get_or(|| Box::new(3));
- })
- .join()
- .unwrap();
- })
- .join()
- .unwrap();
-
- let mut tls = Arc::try_unwrap(tls).unwrap();
- let mut v = tls.iter_mut().map(|x| **x).collect::<Vec<i32>>();
- v.sort();
- assert_eq!(vec![1, 2, 3], v);
- let mut v = tls.into_iter().map(|x| *x).collect::<Vec<i32>>();
- v.sort();
- assert_eq!(vec![1, 2, 3], v);
- }
-
- #[test]
- fn iter_cached() {
- let tls = Arc::new(CachedThreadLocal::new());
- tls.get_or(|| Box::new(1));
-
- let tls2 = tls.clone();
- thread::spawn(move || {
- tls2.get_or(|| Box::new(2));
- let tls3 = tls2.clone();
- thread::spawn(move || {
- tls3.get_or(|| Box::new(3));
- })
- .join()
- .unwrap();
- })
- .join()
- .unwrap();
-
- let mut tls = Arc::try_unwrap(tls).unwrap();
- let mut v = tls.iter_mut().map(|x| **x).collect::<Vec<i32>>();
- v.sort();
- assert_eq!(vec![1, 2, 3], v);
- let mut v = tls.into_iter().map(|x| *x).collect::<Vec<i32>>();
- v.sort();
- assert_eq!(vec![1, 2, 3], v);
- }
-
- #[test]
- fn is_sync() {
- fn foo<T: Sync>() {}
- foo::<ThreadLocal<String>>();
- foo::<ThreadLocal<RefCell<String>>>();
- foo::<CachedThreadLocal<String>>();
- foo::<CachedThreadLocal<RefCell<String>>>();
- }
-}