diff --git a/.gitignore b/.gitignore index bea1e1f4..3a29a231 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ target/ +vendor/ .gdb_history diff --git a/third-party/vendor/autocfg/.cargo-checksum.json b/third-party/vendor/autocfg/.cargo-checksum.json deleted file mode 100644 index e4cc3fc4..00000000 --- a/third-party/vendor/autocfg/.cargo-checksum.json +++ /dev/null @@ -1 +0,0 @@ -{"files":{"Cargo.lock":"3d91565ed13de572a9ebde408a0c98e33f931d6ab52f212b0830a60b4ab26b77","Cargo.toml":"39f627122dceaad42146634719fde802fca3baa1b3908753af723074ae2a6d69","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"27995d58ad5c1145c1a8cd86244ce844886958a35eb2b78c6b772748669999ac","README.md":"4c8f9b5016f2a0c3dbeca5bc41241f57db5568f803e58c1fa480ae2b3638d0a9","examples/integers.rs":"589ff4271566dfa322becddf3e2c7b592e6e0bc97b02892ce75619b7e452e930","examples/paths.rs":"1b30e466b824ce8df7ad0a55334424131d9d2573d6cf9f7d5d50c09c8901d526","examples/traits.rs":"cbee6a3e1f7db60b02ae25b714926517144a77cb492021f492774cf0e1865a9e","examples/versions.rs":"38535e6d9f5bfae0de474a3db79a40e8f5da8ba9334c5ff4c363de9bc99d4d12","src/error.rs":"12de7dafea4a35d1dc2f0fa79bfa038386bbbea72bf083979f4ddf227999eeda","src/lib.rs":"6fa01458e8f9258d84f83ead24fdb0cdf9aec10838b0262f1dfbdf79c530c537","src/tests.rs":"f0e6dc1ad9223c0336c02e215ea3940acb2af6c3bc8fd791e16cd4e786e6a608","src/version.rs":"175727d5f02f2fe2271ddc9b041db2a5b9c6fe0f95afd17c73a4d982612764a3","tests/rustflags.rs":"5c8169b88216055019db61b5d7baf4abdf675e3b14b54f5037bb1e3acd0a5d3f"},"package":"d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"} \ No newline at end of file diff --git a/third-party/vendor/autocfg/Cargo.lock b/third-party/vendor/autocfg/Cargo.lock deleted file mode 100644 index 2b148536..00000000 --- a/third-party/vendor/autocfg/Cargo.lock +++ /dev/null @@ -1,7 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -version = 3 - -[[package]] -name = "autocfg" -version = "1.1.0" diff --git a/third-party/vendor/autocfg/Cargo.toml b/third-party/vendor/autocfg/Cargo.toml deleted file mode 100644 index f8bd64c0..00000000 --- a/third-party/vendor/autocfg/Cargo.toml +++ /dev/null @@ -1,24 +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 are reading this file be aware that the original Cargo.toml -# will likely look very different (and much more reasonable). -# See Cargo.toml.orig for the original contents. - -[package] -name = "autocfg" -version = "1.1.0" -authors = ["Josh Stone "] -exclude = ["/.github/**", "/bors.toml"] -description = "Automatic cfg for Rust compiler features" -readme = "README.md" -keywords = ["rustc", "build", "autoconf"] -categories = ["development-tools::build-utils"] -license = "Apache-2.0 OR MIT" -repository = "https://github.com/cuviper/autocfg" - -[dependencies] diff --git a/third-party/vendor/autocfg/LICENSE-APACHE b/third-party/vendor/autocfg/LICENSE-APACHE deleted file mode 100644 index 16fe87b0..00000000 --- a/third-party/vendor/autocfg/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. diff --git a/third-party/vendor/autocfg/LICENSE-MIT b/third-party/vendor/autocfg/LICENSE-MIT deleted file mode 100644 index 44fbc4d8..00000000 --- a/third-party/vendor/autocfg/LICENSE-MIT +++ /dev/null @@ -1,25 +0,0 @@ -Copyright (c) 2018 Josh Stone - -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. diff --git a/third-party/vendor/autocfg/README.md b/third-party/vendor/autocfg/README.md deleted file mode 100644 index 8c95696c..00000000 --- a/third-party/vendor/autocfg/README.md +++ /dev/null @@ -1,95 +0,0 @@ -autocfg -======= - -[![autocfg crate](https://img.shields.io/crates/v/autocfg.svg)](https://crates.io/crates/autocfg) -[![autocfg documentation](https://docs.rs/autocfg/badge.svg)](https://docs.rs/autocfg) -![minimum rustc 1.0](https://img.shields.io/badge/rustc-1.0+-red.svg) -![build status](https://github.com/cuviper/autocfg/workflows/master/badge.svg) - -A Rust library for build scripts to automatically configure code based on -compiler support. Code snippets are dynamically tested to see if the `rustc` -will accept them, rather than hard-coding specific version support. - - -## Usage - -Add this to your `Cargo.toml`: - -```toml -[build-dependencies] -autocfg = "1" -``` - -Then use it in your `build.rs` script to detect compiler features. For -example, to test for 128-bit integer support, it might look like: - -```rust -extern crate autocfg; - -fn main() { - let ac = autocfg::new(); - ac.emit_has_type("i128"); - - // (optional) We don't need to rerun for anything external. - autocfg::rerun_path("build.rs"); -} -``` - -If the type test succeeds, this will write a `cargo:rustc-cfg=has_i128` line -for Cargo, which translates to Rust arguments `--cfg has_i128`. Then in the -rest of your Rust code, you can add `#[cfg(has_i128)]` conditions on code that -should only be used when the compiler supports it. - - -## Release Notes - -- 1.1.0 (2022-02-07) - - Use `CARGO_ENCODED_RUSTFLAGS` when it is set. - -- 1.0.1 (2020-08-20) - - Apply `RUSTFLAGS` for more `--target` scenarios, by @adamreichold. - -- 1.0.0 (2020-01-08) - - 🎉 Release 1.0! 🎉 (no breaking changes) - - Add `probe_expression` and `emit_expression_cfg` to test arbitrary expressions. - - Add `probe_constant` and `emit_constant_cfg` to test arbitrary constant expressions. - -- 0.1.7 (2019-10-20) - - Apply `RUSTFLAGS` when probing `$TARGET != $HOST`, mainly for sysroot, by @roblabla. - -- 0.1.6 (2019-08-19) - - Add `probe`/`emit_sysroot_crate`, by @leo60228. - -- 0.1.5 (2019-07-16) - - Mask some warnings from newer rustc. - -- 0.1.4 (2019-05-22) - - Relax `std`/`no_std` probing to a warning instead of an error. - - Improve `rustc` bootstrap compatibility. - -- 0.1.3 (2019-05-21) - - Auto-detects if `#![no_std]` is needed for the `$TARGET`. - -- 0.1.2 (2019-01-16) - - Add `rerun_env(ENV)` to print `cargo:rerun-if-env-changed=ENV`. - - Add `rerun_path(PATH)` to print `cargo:rerun-if-changed=PATH`. - - -## Minimum Rust version policy - -This crate's minimum supported `rustc` version is `1.0.0`. Compatibility is -its entire reason for existence, so this crate will be extremely conservative -about raising this requirement. If this is ever deemed necessary, it will be -treated as a major breaking change for semver purposes. - - -## License - -This project is 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. diff --git a/third-party/vendor/autocfg/examples/integers.rs b/third-party/vendor/autocfg/examples/integers.rs deleted file mode 100644 index 23d4cba6..00000000 --- a/third-party/vendor/autocfg/examples/integers.rs +++ /dev/null @@ -1,9 +0,0 @@ -extern crate autocfg; - -fn main() { - // Normally, cargo will set `OUT_DIR` for build scripts. - let ac = autocfg::AutoCfg::with_dir("target").unwrap(); - for i in 3..8 { - ac.emit_has_type(&format!("i{}", 1 << i)); - } -} diff --git a/third-party/vendor/autocfg/examples/paths.rs b/third-party/vendor/autocfg/examples/paths.rs deleted file mode 100644 index b7a6ca7a..00000000 --- a/third-party/vendor/autocfg/examples/paths.rs +++ /dev/null @@ -1,22 +0,0 @@ -extern crate autocfg; - -fn main() { - // Normally, cargo will set `OUT_DIR` for build scripts. - let ac = autocfg::AutoCfg::with_dir("target").unwrap(); - - // since ancient times... - ac.emit_has_path("std::vec::Vec"); - ac.emit_path_cfg("std::vec::Vec", "has_vec"); - - // rustc 1.10.0 - ac.emit_has_path("std::panic::PanicInfo"); - ac.emit_path_cfg("std::panic::PanicInfo", "has_panic_info"); - - // rustc 1.20.0 - ac.emit_has_path("std::mem::ManuallyDrop"); - ac.emit_path_cfg("std::mem::ManuallyDrop", "has_manually_drop"); - - // rustc 1.25.0 - ac.emit_has_path("std::ptr::NonNull"); - ac.emit_path_cfg("std::ptr::NonNull", "has_non_null"); -} diff --git a/third-party/vendor/autocfg/examples/traits.rs b/third-party/vendor/autocfg/examples/traits.rs deleted file mode 100644 index c1ca0038..00000000 --- a/third-party/vendor/autocfg/examples/traits.rs +++ /dev/null @@ -1,26 +0,0 @@ -extern crate autocfg; - -fn main() { - // Normally, cargo will set `OUT_DIR` for build scripts. - let ac = autocfg::AutoCfg::with_dir("target").unwrap(); - - // since ancient times... - ac.emit_has_trait("std::ops::Add"); - ac.emit_trait_cfg("std::ops::Add", "has_ops"); - - // trait parameters have to be provided - ac.emit_has_trait("std::borrow::Borrow"); - ac.emit_trait_cfg("std::borrow::Borrow", "has_borrow"); - - // rustc 1.8.0 - ac.emit_has_trait("std::ops::AddAssign"); - ac.emit_trait_cfg("std::ops::AddAssign", "has_assign_ops"); - - // rustc 1.12.0 - ac.emit_has_trait("std::iter::Sum"); - ac.emit_trait_cfg("std::iter::Sum", "has_sum"); - - // rustc 1.28.0 - ac.emit_has_trait("std::alloc::GlobalAlloc"); - ac.emit_trait_cfg("std::alloc::GlobalAlloc", "has_global_alloc"); -} diff --git a/third-party/vendor/autocfg/examples/versions.rs b/third-party/vendor/autocfg/examples/versions.rs deleted file mode 100644 index 992919b7..00000000 --- a/third-party/vendor/autocfg/examples/versions.rs +++ /dev/null @@ -1,9 +0,0 @@ -extern crate autocfg; - -fn main() { - // Normally, cargo will set `OUT_DIR` for build scripts. - let ac = autocfg::AutoCfg::with_dir("target").unwrap(); - for i in 0..100 { - ac.emit_rustc_version(1, i); - } -} diff --git a/third-party/vendor/autocfg/src/error.rs b/third-party/vendor/autocfg/src/error.rs deleted file mode 100644 index 46248354..00000000 --- a/third-party/vendor/autocfg/src/error.rs +++ /dev/null @@ -1,69 +0,0 @@ -use std::error; -use std::fmt; -use std::io; -use std::num; -use std::str; - -/// A common error type for the `autocfg` crate. -#[derive(Debug)] -pub struct Error { - kind: ErrorKind, -} - -impl error::Error for Error { - fn description(&self) -> &str { - "AutoCfg error" - } - - fn cause(&self) -> Option<&error::Error> { - match self.kind { - ErrorKind::Io(ref e) => Some(e), - ErrorKind::Num(ref e) => Some(e), - ErrorKind::Utf8(ref e) => Some(e), - ErrorKind::Other(_) => None, - } - } -} - -impl fmt::Display for Error { - fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> { - match self.kind { - ErrorKind::Io(ref e) => e.fmt(f), - ErrorKind::Num(ref e) => e.fmt(f), - ErrorKind::Utf8(ref e) => e.fmt(f), - ErrorKind::Other(s) => s.fmt(f), - } - } -} - -#[derive(Debug)] -enum ErrorKind { - Io(io::Error), - Num(num::ParseIntError), - Utf8(str::Utf8Error), - Other(&'static str), -} - -pub fn from_io(e: io::Error) -> Error { - Error { - kind: ErrorKind::Io(e), - } -} - -pub fn from_num(e: num::ParseIntError) -> Error { - Error { - kind: ErrorKind::Num(e), - } -} - -pub fn from_utf8(e: str::Utf8Error) -> Error { - Error { - kind: ErrorKind::Utf8(e), - } -} - -pub fn from_str(s: &'static str) -> Error { - Error { - kind: ErrorKind::Other(s), - } -} diff --git a/third-party/vendor/autocfg/src/lib.rs b/third-party/vendor/autocfg/src/lib.rs deleted file mode 100644 index cbe393a9..00000000 --- a/third-party/vendor/autocfg/src/lib.rs +++ /dev/null @@ -1,453 +0,0 @@ -//! A Rust library for build scripts to automatically configure code based on -//! compiler support. Code snippets are dynamically tested to see if the `rustc` -//! will accept them, rather than hard-coding specific version support. -//! -//! -//! ## Usage -//! -//! Add this to your `Cargo.toml`: -//! -//! ```toml -//! [build-dependencies] -//! autocfg = "1" -//! ``` -//! -//! Then use it in your `build.rs` script to detect compiler features. For -//! example, to test for 128-bit integer support, it might look like: -//! -//! ```rust -//! extern crate autocfg; -//! -//! fn main() { -//! # // Normally, cargo will set `OUT_DIR` for build scripts. -//! # std::env::set_var("OUT_DIR", "target"); -//! let ac = autocfg::new(); -//! ac.emit_has_type("i128"); -//! -//! // (optional) We don't need to rerun for anything external. -//! autocfg::rerun_path("build.rs"); -//! } -//! ``` -//! -//! If the type test succeeds, this will write a `cargo:rustc-cfg=has_i128` line -//! for Cargo, which translates to Rust arguments `--cfg has_i128`. Then in the -//! rest of your Rust code, you can add `#[cfg(has_i128)]` conditions on code that -//! should only be used when the compiler supports it. -//! -//! ## Caution -//! -//! Many of the probing methods of `AutoCfg` document the particular template they -//! use, **subject to change**. The inputs are not validated to make sure they are -//! semantically correct for their expected use, so it's _possible_ to escape and -//! inject something unintended. However, such abuse is unsupported and will not -//! be considered when making changes to the templates. - -#![deny(missing_debug_implementations)] -#![deny(missing_docs)] -// allow future warnings that can't be fixed while keeping 1.0 compatibility -#![allow(unknown_lints)] -#![allow(bare_trait_objects)] -#![allow(ellipsis_inclusive_range_patterns)] - -/// Local macro to avoid `std::try!`, deprecated in Rust 1.39. -macro_rules! try { - ($result:expr) => { - match $result { - Ok(value) => value, - Err(error) => return Err(error), - } - }; -} - -use std::env; -use std::ffi::OsString; -use std::fs; -use std::io::{stderr, Write}; -use std::path::{Path, PathBuf}; -use std::process::{Command, Stdio}; -#[allow(deprecated)] -use std::sync::atomic::ATOMIC_USIZE_INIT; -use std::sync::atomic::{AtomicUsize, Ordering}; - -mod error; -pub use error::Error; - -mod version; -use version::Version; - -#[cfg(test)] -mod tests; - -/// Helper to detect compiler features for `cfg` output in build scripts. -#[derive(Clone, Debug)] -pub struct AutoCfg { - out_dir: PathBuf, - rustc: PathBuf, - rustc_version: Version, - target: Option, - no_std: bool, - rustflags: Vec, -} - -/// Writes a config flag for rustc on standard out. -/// -/// This looks like: `cargo:rustc-cfg=CFG` -/// -/// Cargo will use this in arguments to rustc, like `--cfg CFG`. -pub fn emit(cfg: &str) { - println!("cargo:rustc-cfg={}", cfg); -} - -/// Writes a line telling Cargo to rerun the build script if `path` changes. -/// -/// This looks like: `cargo:rerun-if-changed=PATH` -/// -/// This requires at least cargo 0.7.0, corresponding to rustc 1.6.0. Earlier -/// versions of cargo will simply ignore the directive. -pub fn rerun_path(path: &str) { - println!("cargo:rerun-if-changed={}", path); -} - -/// Writes a line telling Cargo to rerun the build script if the environment -/// variable `var` changes. -/// -/// This looks like: `cargo:rerun-if-env-changed=VAR` -/// -/// This requires at least cargo 0.21.0, corresponding to rustc 1.20.0. Earlier -/// versions of cargo will simply ignore the directive. -pub fn rerun_env(var: &str) { - println!("cargo:rerun-if-env-changed={}", var); -} - -/// Create a new `AutoCfg` instance. -/// -/// # Panics -/// -/// Panics if `AutoCfg::new()` returns an error. -pub fn new() -> AutoCfg { - AutoCfg::new().unwrap() -} - -impl AutoCfg { - /// Create a new `AutoCfg` instance. - /// - /// # Common errors - /// - /// - `rustc` can't be executed, from `RUSTC` or in the `PATH`. - /// - The version output from `rustc` can't be parsed. - /// - `OUT_DIR` is not set in the environment, or is not a writable directory. - /// - pub fn new() -> Result { - match env::var_os("OUT_DIR") { - Some(d) => Self::with_dir(d), - None => Err(error::from_str("no OUT_DIR specified!")), - } - } - - /// Create a new `AutoCfg` instance with the specified output directory. - /// - /// # Common errors - /// - /// - `rustc` can't be executed, from `RUSTC` or in the `PATH`. - /// - The version output from `rustc` can't be parsed. - /// - `dir` is not a writable directory. - /// - pub fn with_dir>(dir: T) -> Result { - let rustc = env::var_os("RUSTC").unwrap_or_else(|| "rustc".into()); - let rustc: PathBuf = rustc.into(); - let rustc_version = try!(Version::from_rustc(&rustc)); - - let target = env::var_os("TARGET"); - - // Sanity check the output directory - let dir = dir.into(); - let meta = try!(fs::metadata(&dir).map_err(error::from_io)); - if !meta.is_dir() || meta.permissions().readonly() { - return Err(error::from_str("output path is not a writable directory")); - } - - let mut ac = AutoCfg { - rustflags: rustflags(&target, &dir), - out_dir: dir, - rustc: rustc, - rustc_version: rustc_version, - target: target, - no_std: false, - }; - - // Sanity check with and without `std`. - if !ac.probe("").unwrap_or(false) { - ac.no_std = true; - if !ac.probe("").unwrap_or(false) { - // Neither worked, so assume nothing... - ac.no_std = false; - let warning = b"warning: autocfg could not probe for `std`\n"; - stderr().write_all(warning).ok(); - } - } - Ok(ac) - } - - /// Test whether the current `rustc` reports a version greater than - /// or equal to "`major`.`minor`". - pub fn probe_rustc_version(&self, major: usize, minor: usize) -> bool { - self.rustc_version >= Version::new(major, minor, 0) - } - - /// Sets a `cfg` value of the form `rustc_major_minor`, like `rustc_1_29`, - /// if the current `rustc` is at least that version. - pub fn emit_rustc_version(&self, major: usize, minor: usize) { - if self.probe_rustc_version(major, minor) { - emit(&format!("rustc_{}_{}", major, minor)); - } - } - - fn probe>(&self, code: T) -> Result { - #[allow(deprecated)] - static ID: AtomicUsize = ATOMIC_USIZE_INIT; - - let id = ID.fetch_add(1, Ordering::Relaxed); - let mut command = Command::new(&self.rustc); - command - .arg("--crate-name") - .arg(format!("probe{}", id)) - .arg("--crate-type=lib") - .arg("--out-dir") - .arg(&self.out_dir) - .arg("--emit=llvm-ir"); - - if let Some(target) = self.target.as_ref() { - command.arg("--target").arg(target); - } - - command.args(&self.rustflags); - - command.arg("-").stdin(Stdio::piped()); - let mut child = try!(command.spawn().map_err(error::from_io)); - let mut stdin = child.stdin.take().expect("rustc stdin"); - - if self.no_std { - try!(stdin.write_all(b"#![no_std]\n").map_err(error::from_io)); - } - try!(stdin.write_all(code.as_ref()).map_err(error::from_io)); - drop(stdin); - - let status = try!(child.wait().map_err(error::from_io)); - Ok(status.success()) - } - - /// Tests whether the given sysroot crate can be used. - /// - /// The test code is subject to change, but currently looks like: - /// - /// ```ignore - /// extern crate CRATE as probe; - /// ``` - pub fn probe_sysroot_crate(&self, name: &str) -> bool { - self.probe(format!("extern crate {} as probe;", name)) // `as _` wasn't stabilized until Rust 1.33 - .unwrap_or(false) - } - - /// Emits a config value `has_CRATE` if `probe_sysroot_crate` returns true. - pub fn emit_sysroot_crate(&self, name: &str) { - if self.probe_sysroot_crate(name) { - emit(&format!("has_{}", mangle(name))); - } - } - - /// Tests whether the given path can be used. - /// - /// The test code is subject to change, but currently looks like: - /// - /// ```ignore - /// pub use PATH; - /// ``` - pub fn probe_path(&self, path: &str) -> bool { - self.probe(format!("pub use {};", path)).unwrap_or(false) - } - - /// Emits a config value `has_PATH` if `probe_path` returns true. - /// - /// Any non-identifier characters in the `path` will be replaced with - /// `_` in the generated config value. - pub fn emit_has_path(&self, path: &str) { - if self.probe_path(path) { - emit(&format!("has_{}", mangle(path))); - } - } - - /// Emits the given `cfg` value if `probe_path` returns true. - pub fn emit_path_cfg(&self, path: &str, cfg: &str) { - if self.probe_path(path) { - emit(cfg); - } - } - - /// Tests whether the given trait can be used. - /// - /// The test code is subject to change, but currently looks like: - /// - /// ```ignore - /// pub trait Probe: TRAIT + Sized {} - /// ``` - pub fn probe_trait(&self, name: &str) -> bool { - self.probe(format!("pub trait Probe: {} + Sized {{}}", name)) - .unwrap_or(false) - } - - /// Emits a config value `has_TRAIT` if `probe_trait` returns true. - /// - /// Any non-identifier characters in the trait `name` will be replaced with - /// `_` in the generated config value. - pub fn emit_has_trait(&self, name: &str) { - if self.probe_trait(name) { - emit(&format!("has_{}", mangle(name))); - } - } - - /// Emits the given `cfg` value if `probe_trait` returns true. - pub fn emit_trait_cfg(&self, name: &str, cfg: &str) { - if self.probe_trait(name) { - emit(cfg); - } - } - - /// Tests whether the given type can be used. - /// - /// The test code is subject to change, but currently looks like: - /// - /// ```ignore - /// pub type Probe = TYPE; - /// ``` - pub fn probe_type(&self, name: &str) -> bool { - self.probe(format!("pub type Probe = {};", name)) - .unwrap_or(false) - } - - /// Emits a config value `has_TYPE` if `probe_type` returns true. - /// - /// Any non-identifier characters in the type `name` will be replaced with - /// `_` in the generated config value. - pub fn emit_has_type(&self, name: &str) { - if self.probe_type(name) { - emit(&format!("has_{}", mangle(name))); - } - } - - /// Emits the given `cfg` value if `probe_type` returns true. - pub fn emit_type_cfg(&self, name: &str, cfg: &str) { - if self.probe_type(name) { - emit(cfg); - } - } - - /// Tests whether the given expression can be used. - /// - /// The test code is subject to change, but currently looks like: - /// - /// ```ignore - /// pub fn probe() { let _ = EXPR; } - /// ``` - pub fn probe_expression(&self, expr: &str) -> bool { - self.probe(format!("pub fn probe() {{ let _ = {}; }}", expr)) - .unwrap_or(false) - } - - /// Emits the given `cfg` value if `probe_expression` returns true. - pub fn emit_expression_cfg(&self, expr: &str, cfg: &str) { - if self.probe_expression(expr) { - emit(cfg); - } - } - - /// Tests whether the given constant expression can be used. - /// - /// The test code is subject to change, but currently looks like: - /// - /// ```ignore - /// pub const PROBE: () = ((), EXPR).0; - /// ``` - pub fn probe_constant(&self, expr: &str) -> bool { - self.probe(format!("pub const PROBE: () = ((), {}).0;", expr)) - .unwrap_or(false) - } - - /// Emits the given `cfg` value if `probe_constant` returns true. - pub fn emit_constant_cfg(&self, expr: &str, cfg: &str) { - if self.probe_constant(expr) { - emit(cfg); - } - } -} - -fn mangle(s: &str) -> String { - s.chars() - .map(|c| match c { - 'A'...'Z' | 'a'...'z' | '0'...'9' => c, - _ => '_', - }) - .collect() -} - -fn dir_contains_target( - target: &Option, - dir: &Path, - cargo_target_dir: Option, -) -> bool { - target - .as_ref() - .and_then(|target| { - dir.to_str().and_then(|dir| { - let mut cargo_target_dir = cargo_target_dir - .map(PathBuf::from) - .unwrap_or_else(|| PathBuf::from("target")); - cargo_target_dir.push(target); - - cargo_target_dir - .to_str() - .map(|cargo_target_dir| dir.contains(&cargo_target_dir)) - }) - }) - .unwrap_or(false) -} - -fn rustflags(target: &Option, dir: &Path) -> Vec { - // Starting with rust-lang/cargo#9601, shipped in Rust 1.55, Cargo always sets - // CARGO_ENCODED_RUSTFLAGS for any host/target build script invocation. This - // includes any source of flags, whether from the environment, toml config, or - // whatever may come in the future. The value is either an empty string, or a - // list of arguments separated by the ASCII unit separator (US), 0x1f. - if let Ok(a) = env::var("CARGO_ENCODED_RUSTFLAGS") { - return if a.is_empty() { - Vec::new() - } else { - a.split('\x1f').map(str::to_string).collect() - }; - } - - // Otherwise, we have to take a more heuristic approach, and we don't - // support values from toml config at all. - // - // Cargo only applies RUSTFLAGS for building TARGET artifact in - // cross-compilation environment. Sadly, we don't have a way to detect - // when we're building HOST artifact in a cross-compilation environment, - // so for now we only apply RUSTFLAGS when cross-compiling an artifact. - // - // See https://github.com/cuviper/autocfg/pull/10#issuecomment-527575030. - if *target != env::var_os("HOST") - || dir_contains_target(target, dir, env::var_os("CARGO_TARGET_DIR")) - { - if let Ok(rustflags) = env::var("RUSTFLAGS") { - // This is meant to match how cargo handles the RUSTFLAGS environment variable. - // See https://github.com/rust-lang/cargo/blob/69aea5b6f69add7c51cca939a79644080c0b0ba0/src/cargo/core/compiler/build_context/target_info.rs#L434-L441 - return rustflags - .split(' ') - .map(str::trim) - .filter(|s| !s.is_empty()) - .map(str::to_string) - .collect(); - } - } - - Vec::new() -} diff --git a/third-party/vendor/autocfg/src/tests.rs b/third-party/vendor/autocfg/src/tests.rs deleted file mode 100644 index d3b1fbb9..00000000 --- a/third-party/vendor/autocfg/src/tests.rs +++ /dev/null @@ -1,174 +0,0 @@ -use super::AutoCfg; -use std::env; -use std::path::Path; - -impl AutoCfg { - fn core_std(&self, path: &str) -> String { - let krate = if self.no_std { "core" } else { "std" }; - format!("{}::{}", krate, path) - } - - fn assert_std(&self, probe_result: bool) { - assert_eq!(!self.no_std, probe_result); - } - - fn assert_min(&self, major: usize, minor: usize, probe_result: bool) { - assert_eq!(self.probe_rustc_version(major, minor), probe_result); - } - - fn for_test() -> Result { - match env::var_os("TESTS_TARGET_DIR") { - Some(d) => Self::with_dir(d), - None => Self::with_dir("target"), - } - } -} - -#[test] -fn autocfg_version() { - let ac = AutoCfg::for_test().unwrap(); - println!("version: {:?}", ac.rustc_version); - assert!(ac.probe_rustc_version(1, 0)); -} - -#[test] -fn version_cmp() { - use super::version::Version; - let v123 = Version::new(1, 2, 3); - - assert!(Version::new(1, 0, 0) < v123); - assert!(Version::new(1, 2, 2) < v123); - assert!(Version::new(1, 2, 3) == v123); - assert!(Version::new(1, 2, 4) > v123); - assert!(Version::new(1, 10, 0) > v123); - assert!(Version::new(2, 0, 0) > v123); -} - -#[test] -fn probe_add() { - let ac = AutoCfg::for_test().unwrap(); - let add = ac.core_std("ops::Add"); - let add_rhs = add.clone() + ""; - let add_rhs_output = add.clone() + ""; - let dyn_add_rhs_output = "dyn ".to_string() + &*add_rhs_output; - assert!(ac.probe_path(&add)); - assert!(ac.probe_trait(&add)); - assert!(ac.probe_trait(&add_rhs)); - assert!(ac.probe_trait(&add_rhs_output)); - ac.assert_min(1, 27, ac.probe_type(&dyn_add_rhs_output)); -} - -#[test] -fn probe_as_ref() { - let ac = AutoCfg::for_test().unwrap(); - let as_ref = ac.core_std("convert::AsRef"); - let as_ref_str = as_ref.clone() + ""; - let dyn_as_ref_str = "dyn ".to_string() + &*as_ref_str; - assert!(ac.probe_path(&as_ref)); - assert!(ac.probe_trait(&as_ref_str)); - assert!(ac.probe_type(&as_ref_str)); - ac.assert_min(1, 27, ac.probe_type(&dyn_as_ref_str)); -} - -#[test] -fn probe_i128() { - let ac = AutoCfg::for_test().unwrap(); - let i128_path = ac.core_std("i128"); - ac.assert_min(1, 26, ac.probe_path(&i128_path)); - ac.assert_min(1, 26, ac.probe_type("i128")); -} - -#[test] -fn probe_sum() { - let ac = AutoCfg::for_test().unwrap(); - let sum = ac.core_std("iter::Sum"); - let sum_i32 = sum.clone() + ""; - let dyn_sum_i32 = "dyn ".to_string() + &*sum_i32; - ac.assert_min(1, 12, ac.probe_path(&sum)); - ac.assert_min(1, 12, ac.probe_trait(&sum)); - ac.assert_min(1, 12, ac.probe_trait(&sum_i32)); - ac.assert_min(1, 12, ac.probe_type(&sum_i32)); - ac.assert_min(1, 27, ac.probe_type(&dyn_sum_i32)); -} - -#[test] -fn probe_std() { - let ac = AutoCfg::for_test().unwrap(); - ac.assert_std(ac.probe_sysroot_crate("std")); -} - -#[test] -fn probe_alloc() { - let ac = AutoCfg::for_test().unwrap(); - ac.assert_min(1, 36, ac.probe_sysroot_crate("alloc")); -} - -#[test] -fn probe_bad_sysroot_crate() { - let ac = AutoCfg::for_test().unwrap(); - assert!(!ac.probe_sysroot_crate("doesnt_exist")); -} - -#[test] -fn probe_no_std() { - let ac = AutoCfg::for_test().unwrap(); - assert!(ac.probe_type("i32")); - assert!(ac.probe_type("[i32]")); - ac.assert_std(ac.probe_type("Vec")); -} - -#[test] -fn probe_expression() { - let ac = AutoCfg::for_test().unwrap(); - assert!(ac.probe_expression(r#""test".trim_left()"#)); - ac.assert_min(1, 30, ac.probe_expression(r#""test".trim_start()"#)); - ac.assert_std(ac.probe_expression("[1, 2, 3].to_vec()")); -} - -#[test] -fn probe_constant() { - let ac = AutoCfg::for_test().unwrap(); - assert!(ac.probe_constant("1 + 2 + 3")); - ac.assert_min(1, 33, ac.probe_constant("{ let x = 1 + 2 + 3; x * x }")); - ac.assert_min(1, 39, ac.probe_constant(r#""test".len()"#)); -} - -#[test] -fn dir_does_not_contain_target() { - assert!(!super::dir_contains_target( - &Some("x86_64-unknown-linux-gnu".into()), - Path::new("/project/target/debug/build/project-ea75983148559682/out"), - None, - )); -} - -#[test] -fn dir_does_contain_target() { - assert!(super::dir_contains_target( - &Some("x86_64-unknown-linux-gnu".into()), - Path::new( - "/project/target/x86_64-unknown-linux-gnu/debug/build/project-0147aca016480b9d/out" - ), - None, - )); -} - -#[test] -fn dir_does_not_contain_target_with_custom_target_dir() { - assert!(!super::dir_contains_target( - &Some("x86_64-unknown-linux-gnu".into()), - Path::new("/project/custom/debug/build/project-ea75983148559682/out"), - Some("custom".into()), - )); -} - -#[test] -fn dir_does_contain_target_with_custom_target_dir() { - assert!(super::dir_contains_target( - &Some("x86_64-unknown-linux-gnu".into()), - Path::new( - "/project/custom/x86_64-unknown-linux-gnu/debug/build/project-0147aca016480b9d/out" - ), - Some("custom".into()), - )); -} diff --git a/third-party/vendor/autocfg/src/version.rs b/third-party/vendor/autocfg/src/version.rs deleted file mode 100644 index 378c21e6..00000000 --- a/third-party/vendor/autocfg/src/version.rs +++ /dev/null @@ -1,60 +0,0 @@ -use std::path::Path; -use std::process::Command; -use std::str; - -use super::{error, Error}; - -/// A version structure for making relative comparisons. -#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord)] -pub struct Version { - major: usize, - minor: usize, - patch: usize, -} - -impl Version { - /// Creates a `Version` instance for a specific `major.minor.patch` version. - pub fn new(major: usize, minor: usize, patch: usize) -> Self { - Version { - major: major, - minor: minor, - patch: patch, - } - } - - pub fn from_rustc(rustc: &Path) -> Result { - // Get rustc's verbose version - let output = try!(Command::new(rustc) - .args(&["--version", "--verbose"]) - .output() - .map_err(error::from_io)); - if !output.status.success() { - return Err(error::from_str("could not execute rustc")); - } - let output = try!(str::from_utf8(&output.stdout).map_err(error::from_utf8)); - - // Find the release line in the verbose version output. - let release = match output.lines().find(|line| line.starts_with("release: ")) { - Some(line) => &line["release: ".len()..], - None => return Err(error::from_str("could not find rustc release")), - }; - - // Strip off any extra channel info, e.g. "-beta.N", "-nightly" - let version = match release.find('-') { - Some(i) => &release[..i], - None => release, - }; - - // Split the version into semver components. - let mut iter = version.splitn(3, '.'); - let major = try!(iter.next().ok_or(error::from_str("missing major version"))); - let minor = try!(iter.next().ok_or(error::from_str("missing minor version"))); - let patch = try!(iter.next().ok_or(error::from_str("missing patch version"))); - - Ok(Version::new( - try!(major.parse().map_err(error::from_num)), - try!(minor.parse().map_err(error::from_num)), - try!(patch.parse().map_err(error::from_num)), - )) - } -} diff --git a/third-party/vendor/autocfg/tests/rustflags.rs b/third-party/vendor/autocfg/tests/rustflags.rs deleted file mode 100644 index f0545466..00000000 --- a/third-party/vendor/autocfg/tests/rustflags.rs +++ /dev/null @@ -1,33 +0,0 @@ -extern crate autocfg; - -use std::env; - -/// Tests that autocfg uses the RUSTFLAGS or CARGO_ENCODED_RUSTFLAGS -/// environment variables when running rustc. -#[test] -fn test_with_sysroot() { - // Use the same path as this test binary. - let dir = env::current_exe().unwrap().parent().unwrap().to_path_buf(); - env::set_var("OUT_DIR", &format!("{}", dir.display())); - - // If we have encoded rustflags, they take precedence, even if empty. - env::set_var("CARGO_ENCODED_RUSTFLAGS", ""); - env::set_var("RUSTFLAGS", &format!("-L {}", dir.display())); - let ac = autocfg::AutoCfg::new().unwrap(); - assert!(ac.probe_sysroot_crate("std")); - assert!(!ac.probe_sysroot_crate("autocfg")); - - // Now try again with useful encoded args. - env::set_var( - "CARGO_ENCODED_RUSTFLAGS", - &format!("-L\x1f{}", dir.display()), - ); - let ac = autocfg::AutoCfg::new().unwrap(); - assert!(ac.probe_sysroot_crate("autocfg")); - - // Try the old-style RUSTFLAGS, ensuring HOST != TARGET. - env::remove_var("CARGO_ENCODED_RUSTFLAGS"); - env::set_var("HOST", "lol"); - let ac = autocfg::AutoCfg::new().unwrap(); - assert!(ac.probe_sysroot_crate("autocfg")); -} diff --git a/third-party/vendor/buddy_system_allocator/.cargo-checksum.json b/third-party/vendor/buddy_system_allocator/.cargo-checksum.json deleted file mode 100644 index fc252f4f..00000000 --- a/third-party/vendor/buddy_system_allocator/.cargo-checksum.json +++ /dev/null @@ -1 +0,0 @@ -{"files":{"Cargo.toml":"33089d4023be17a6d36fa9f4264594e3e19d0d7bba12523cf702cf71433e72ac","LICENSE":"a9777627704f72c0c959590d0aa090ed6269e1b80e7cb8d126ba6707238da989","README.md":"70730d0d6802f5c961904f193deada8db3890603d5f89c7040aefaf164c3e16d","benches/memory_allocator_benchmark.rs":"6314598ea1d1356897c53f9d3a659a5c0eac453f7d51054d90e9c1de474a21e2","src/frame.rs":"53ac215c697141390c043d5e324224514a07abe71b3266b6e0825818f78b68f4","src/lib.rs":"b88938b059083ae60bce33493f12f3f4a7849aedbfa9b90b4e36b4dbcb52bd49","src/linked_list.rs":"2866b6a224a2863b275eca151fdf30754a4d26736490502792e98a552844615c","src/test.rs":"b5403ce633f8723991b011b2d33e7d2d07a602d2fda3e96578fb9769c4a20c70"},"package":"d44d578cadd17312c75e7d0ef489361f160ace58f7139aa32001fee1a51b89b5"} \ No newline at end of file diff --git a/third-party/vendor/buddy_system_allocator/Cargo.toml b/third-party/vendor/buddy_system_allocator/Cargo.toml deleted file mode 100644 index 5302a5c4..00000000 --- a/third-party/vendor/buddy_system_allocator/Cargo.toml +++ /dev/null @@ -1,56 +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 are reading this file be aware that the original Cargo.toml -# will likely look very different (and much more reasonable). -# See Cargo.toml.orig for the original contents. - -[package] -edition = "2021" -name = "buddy_system_allocator" -version = "0.9.1" -authors = [ - "Jiajie Chen ", - "Vinay Chandra Dommeti ", - "Andrew Walbran ", -] -description = "A bare metal allocator that uses buddy system." -homepage = "https://github.com/rcore-os/buddy_system_allocator" -documentation = "https://docs.rs/buddy_system_allocator" -readme = "README.md" -keywords = [ - "allocator", - "no_std", - "heap", -] -license = "MIT" -repository = "https://github.com/rcore-os/buddy_system_allocator" - -[[bench]] -name = "memory_allocator_benchmark" -harness = false - -[dependencies.spin] -version = "0.9.8" -optional = true - -[dev-dependencies.criterion] -version = "0.5.1" - -[dev-dependencies.ctor] -version = "0.2.6" - -[dev-dependencies.rand] -version = "0.8.5" - -[dev-dependencies.rand_chacha] -version = "0.3.1" - -[features] -const_fn = [] -default = ["use_spin"] -use_spin = ["spin"] diff --git a/third-party/vendor/buddy_system_allocator/LICENSE b/third-party/vendor/buddy_system_allocator/LICENSE deleted file mode 100644 index 978d8f2b..00000000 --- a/third-party/vendor/buddy_system_allocator/LICENSE +++ /dev/null @@ -1,7 +0,0 @@ -Copyright 2019-2020 Jiajie Chen - -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. diff --git a/third-party/vendor/buddy_system_allocator/README.md b/third-party/vendor/buddy_system_allocator/README.md deleted file mode 100644 index 08eb81c9..00000000 --- a/third-party/vendor/buddy_system_allocator/README.md +++ /dev/null @@ -1,47 +0,0 @@ -# buddy_system_allocator - -[![Crates.io version][crate-img]][crate] -[![docs.rs][docs-img]][docs] - -An (almost) drop-in replacement for [phil-opp/linked-list-allocator](https://github.com/phil-opp/linked-list-allocator). But it uses buddy system instead. - -## Usage - -To use buddy_system_allocator for global allocator: - -```rust -use buddy_system_allocator::LockedHeap; - -#[global_allocator] -static HEAP_ALLOCATOR: LockedHeap = LockedHeap::<32>::empty(); -``` - -To init the allocator: - -```rust -unsafe { - HEAP_ALLOCATOR.lock().init(heap_start, heap_size); - // or - HEAP_ALLOCATOR.lock().add_to_heap(heap_start, heap_end); -} -``` - -You can also use `FrameAllocator` and `LockedHeapWithRescue`, see their documentation for usage. - -## Features - -- **`use_spin`** (default): Provide a `LockedHeap` type that implements the [`GlobalAlloc`] trait by using a spinlock. -- **`const_fn`** (nightly only): Provide const fn version of `LockedHeapWithRescue::new`. - -[`GlobalAlloc`]: https://doc.rust-lang.org/nightly/core/alloc/trait.GlobalAlloc.html - -## License - -Some code comes from phil-opp's linked-list-allocator. - -Licensed under MIT License. Thanks phill-opp's linked-list-allocator for inspirations and interface. - -[crate-img]: https://img.shields.io/crates/v/buddy_system_allocator.svg -[crate]: https://crates.io/crates/buddy_system_allocator -[docs-img]: https://docs.rs/buddy_system_allocator/badge.svg -[docs]: https://docs.rs/buddy_system_allocator diff --git a/third-party/vendor/buddy_system_allocator/benches/memory_allocator_benchmark.rs b/third-party/vendor/buddy_system_allocator/benches/memory_allocator_benchmark.rs deleted file mode 100644 index 0055c10c..00000000 --- a/third-party/vendor/buddy_system_allocator/benches/memory_allocator_benchmark.rs +++ /dev/null @@ -1,189 +0,0 @@ -#[macro_use] -extern crate alloc; -#[macro_use] -extern crate ctor; - -use std::sync::Arc; -use std::thread; -use std::thread::sleep; -use std::time::Duration; - -use alloc::alloc::GlobalAlloc; -use alloc::alloc::Layout; -use buddy_system_allocator::LockedHeap; -use criterion::{black_box, criterion_group, criterion_main, Criterion}; -use rand::{Rng, SeedableRng}; - -const SMALL_SIZE: usize = 8; -const LARGE_SIZE: usize = 1024 * 1024; // 1M -const ALIGN: usize = 8; - -/// Alloc small object -#[inline] -pub fn small_alloc(heap: &LockedHeap) { - let layout = unsafe { Layout::from_size_align_unchecked(SMALL_SIZE, ALIGN) }; - unsafe { - let addr = heap.alloc(layout); - heap.dealloc(addr, layout); - } -} - -/// Alloc large object -#[inline] -pub fn large_alloc(heap: &LockedHeap) { - let layout = unsafe { Layout::from_size_align_unchecked(LARGE_SIZE, ALIGN) }; - unsafe { - let addr = heap.alloc(layout); - heap.dealloc(addr, layout); - } -} - -/// Multithreads alloc random sizes of object -#[inline] -pub fn mutil_thread_random_size(heap: &'static LockedHeap) { - const THREAD_SIZE: usize = 10; - - let mut threads = Vec::with_capacity(THREAD_SIZE); - let alloc = Arc::new(heap); - for i in 0..THREAD_SIZE { - let prethread_alloc = alloc.clone(); - let handle = thread::spawn(move || { - // generate a random size of object use seed `i` to ensure the fixed - // result of each turn - let mut rng = rand_chacha::ChaCha8Rng::seed_from_u64(i as u64); - // generate a random object size in range of [SMALL_SIZE ..= LARGE_SIZE] - let layout = unsafe { - Layout::from_size_align_unchecked(rng.gen_range(SMALL_SIZE..=LARGE_SIZE), ALIGN) - }; - let addr = unsafe { prethread_alloc.alloc(layout) }; - - // sleep for a while - sleep(Duration::from_nanos((THREAD_SIZE - i) as u64)); - - unsafe { prethread_alloc.dealloc(addr, layout) } - }); - threads.push(handle); - } - drop(alloc); - - for t in threads { - t.join().unwrap(); - } -} - -/// Multithread benchmark inspired by **Hoard** benchmark -/// -/// Warning: This benchmark generally needs long time to finish -/// -/// ---------------------------------------------------------------------- -/// Hoard: A Fast, Scalable, and Memory-Efficient Allocator -/// for Shared-Memory Multiprocessors -/// Contact author: Emery Berger, http://www.cs.utexas.edu/users/emery -// -/// Copyright (c) 1998-2000, The University of Texas at Austin. -/// -/// This library is free software; you can redistribute it and/or modify -/// it under the terms of the GNU Library General Public License as -/// published by the Free Software Foundation, http://www.fsf.org. -/// -/// This library is distributed in the hope that it will be useful, but -/// WITHOUT ANY WARRANTY; without even the implied warranty of -/// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -/// Library General Public License for more details. -/// ---------------------------------------------------------------------- -/// -#[inline] -pub fn thread_test() { - const N_ITERATIONS: usize = 50; - const N_OBJECTS: usize = 30000; - const N_THREADS: usize = 10; - const OBJECT_SIZE: usize = 1; - - #[derive(Clone)] - struct Foo { - pub a: i32, - pub b: i32, - } - - let mut threads = Vec::with_capacity(N_THREADS); - - for _i in 0..N_THREADS { - let handle = thread::spawn(move || { - // let a = new Foo * [nobjects / nthreads]; - let mut a = Vec::with_capacity(N_OBJECTS / N_THREADS); - for j in 0..N_ITERATIONS { - // inner object: - // a[i] = new Foo[objSize]; - for k in 0..(N_OBJECTS / N_THREADS) { - a.push(vec![ - Foo { - a: k as i32, - b: j as i32 - }; - OBJECT_SIZE - ]); - - // in order to prevent optimization delete allocation directly - // FIXME: don't know whether it works or not - a[k][0].a += a[k][0].b; - } - } - // auto drop here - }); - threads.push(handle); - } - - for t in threads { - t.join().unwrap(); - } -} - -const ORDER: usize = 32; -const MACHINE_ALIGN: usize = core::mem::size_of::(); -/// for now 128M is needed -/// TODO: reduce memory use -const KERNEL_HEAP_SIZE: usize = 128 * 1024 * 1024; -const HEAP_BLOCK: usize = KERNEL_HEAP_SIZE / MACHINE_ALIGN; -static mut HEAP: [usize; HEAP_BLOCK] = [0; HEAP_BLOCK]; - -/// Use `LockedHeap` as global allocator -#[global_allocator] -static HEAP_ALLOCATOR: LockedHeap = LockedHeap::::new(); - -/// Init heap -/// -/// We need `ctor` here because benchmark is running behind the std enviroment, -/// which means std will do some initialization before execute `fn main()`. -/// However, our memory allocator must be init in runtime(use linkedlist, which -/// can not be evaluated in compile time). And in the initialization phase, heap -/// memory is needed. -/// -/// So the solution in this dilemma is to run `fn init_heap()` in initialization phase -/// rather than in `fn main()`. We need `ctor` to do this. -#[ctor] -fn init_heap() { - let heap_start = unsafe { HEAP.as_ptr() as usize }; - unsafe { - HEAP_ALLOCATOR - .lock() - .init(heap_start, HEAP_BLOCK * MACHINE_ALIGN); - } -} - -/// Entry of benchmarks -pub fn criterion_benchmark(c: &mut Criterion) { - // run benchmark - c.bench_function("small alloc", |b| { - b.iter(|| small_alloc(black_box(&HEAP_ALLOCATOR))) - }); - c.bench_function("large alloc", |b| { - b.iter(|| large_alloc(black_box(&HEAP_ALLOCATOR))) - }); - c.bench_function("mutil thread random size", |b| { - b.iter(|| mutil_thread_random_size(black_box(&HEAP_ALLOCATOR))) - }); - c.bench_function("threadtest", |b| b.iter(|| thread_test())); -} - -criterion_group!(benches, criterion_benchmark); -criterion_main!(benches); diff --git a/third-party/vendor/buddy_system_allocator/src/frame.rs b/third-party/vendor/buddy_system_allocator/src/frame.rs deleted file mode 100644 index daf3f0f2..00000000 --- a/third-party/vendor/buddy_system_allocator/src/frame.rs +++ /dev/null @@ -1,206 +0,0 @@ -use super::prev_power_of_two; -use alloc::collections::BTreeSet; -use core::alloc::Layout; -use core::array; -use core::cmp::{max, min}; -use core::ops::Range; - -#[cfg(feature = "use_spin")] -use core::ops::Deref; -#[cfg(feature = "use_spin")] -use spin::Mutex; - -/// A frame allocator that uses buddy system, requiring a global allocator. -/// -/// The max order of the allocator is specified via the const generic parameter `ORDER`. The frame -/// allocator will only be able to allocate ranges of size up to 2ORDER, out of a total -/// range of size at most 2ORDER + 1 - 1. -/// -/// # Usage -/// -/// Create a frame allocator and add some frames to it: -/// ``` -/// use buddy_system_allocator::*; -/// let mut frame = FrameAllocator::<32>::new(); -/// assert!(frame.alloc(1).is_none()); -/// -/// frame.add_frame(0, 3); -/// let num = frame.alloc(1); -/// assert_eq!(num, Some(2)); -/// let num = frame.alloc(2); -/// assert_eq!(num, Some(0)); -/// ``` -pub struct FrameAllocator { - // buddy system with max order of ORDER - free_list: [BTreeSet; ORDER], - - // statistics - allocated: usize, - total: usize, -} - -impl FrameAllocator { - /// Create an empty frame allocator - pub fn new() -> Self { - Self { - free_list: array::from_fn(|_| BTreeSet::default()), - allocated: 0, - total: 0, - } - } - - /// Add a range of frame number [start, end) to the allocator - pub fn add_frame(&mut self, start: usize, end: usize) { - assert!(start <= end); - - let mut total = 0; - let mut current_start = start; - - while current_start < end { - let lowbit = if current_start > 0 { - current_start & (!current_start + 1) - } else { - 32 - }; - let size = min( - min(lowbit, prev_power_of_two(end - current_start)), - 1 << (ORDER - 1), - ); - total += size; - - self.free_list[size.trailing_zeros() as usize].insert(current_start); - current_start += size; - } - - self.total += total; - } - - /// Add a range of frames to the allocator. - pub fn insert(&mut self, range: Range) { - self.add_frame(range.start, range.end); - } - - /// Allocate a range of frames from the allocator, returning the first frame of the allocated - /// range. - pub fn alloc(&mut self, count: usize) -> Option { - let size = count.next_power_of_two(); - self.alloc_power_of_two(size) - } - - /// Allocate a range of frames with the given size and alignment from the allocator, returning - /// the first frame of the allocated range. - /// The allocated size is the maximum of the next power of two of the given size and the - /// alignment. - pub fn alloc_aligned(&mut self, layout: Layout) -> Option { - let size = max(layout.size().next_power_of_two(), layout.align()); - self.alloc_power_of_two(size) - } - - /// Allocate a range of frames of the given size from the allocator. The size must be a power of - /// two. The allocated range will have alignment equal to the size. - fn alloc_power_of_two(&mut self, size: usize) -> Option { - let class = size.trailing_zeros() as usize; - for i in class..self.free_list.len() { - // Find the first non-empty size class - if !self.free_list[i].is_empty() { - // Split buffers - for j in (class + 1..i + 1).rev() { - if let Some(block_ref) = self.free_list[j].iter().next() { - let block = *block_ref; - self.free_list[j - 1].insert(block + (1 << (j - 1))); - self.free_list[j - 1].insert(block); - self.free_list[j].remove(&block); - } else { - return None; - } - } - - let result = self.free_list[class].iter().next(); - if let Some(result_ref) = result { - let result = *result_ref; - self.free_list[class].remove(&result); - self.allocated += size; - return Some(result); - } else { - return None; - } - } - } - None - } - - /// Deallocate a range of frames [frame, frame+count) from the frame allocator. - /// - /// The range should be exactly the same when it was allocated, as in heap allocator - pub fn dealloc(&mut self, start_frame: usize, count: usize) { - let size = count.next_power_of_two(); - self.dealloc_power_of_two(start_frame, size) - } - - /// Deallocate a range of frames which was previously allocated by [`alloc_aligned`]. - /// - /// The layout must be exactly the same as when it was allocated. - pub fn dealloc_aligned(&mut self, start_frame: usize, layout: Layout) { - let size = max(layout.size().next_power_of_two(), layout.align()); - self.dealloc_power_of_two(start_frame, size) - } - - /// Deallocate a range of frames with the given size from the allocator. The size must be a - /// power of two. - fn dealloc_power_of_two(&mut self, start_frame: usize, size: usize) { - let class = size.trailing_zeros() as usize; - - // Merge free buddy lists - let mut current_ptr = start_frame; - let mut current_class = class; - while current_class < self.free_list.len() { - let buddy = current_ptr ^ (1 << current_class); - if self.free_list[current_class].remove(&buddy) { - // Free buddy found - current_ptr = min(current_ptr, buddy); - current_class += 1; - } else { - self.free_list[current_class].insert(current_ptr); - break; - } - } - - self.allocated -= size; - } -} - -/// A locked version of `FrameAllocator` -/// -/// # Usage -/// -/// Create a locked frame allocator and add frames to it: -/// ``` -/// use buddy_system_allocator::*; -/// let mut frame = LockedFrameAllocator::<32>::new(); -/// assert!(frame.lock().alloc(1).is_none()); -/// -/// frame.lock().add_frame(0, 3); -/// let num = frame.lock().alloc(1); -/// assert_eq!(num, Some(2)); -/// let num = frame.lock().alloc(2); -/// assert_eq!(num, Some(0)); -/// ``` -#[cfg(feature = "use_spin")] -pub struct LockedFrameAllocator(Mutex>); - -#[cfg(feature = "use_spin")] -impl LockedFrameAllocator { - /// Creates an empty heap - pub fn new() -> Self { - Self(Mutex::new(FrameAllocator::new())) - } -} - -#[cfg(feature = "use_spin")] -impl Deref for LockedFrameAllocator { - type Target = Mutex>; - - fn deref(&self) -> &Mutex> { - &self.0 - } -} diff --git a/third-party/vendor/buddy_system_allocator/src/lib.rs b/third-party/vendor/buddy_system_allocator/src/lib.rs deleted file mode 100644 index 2fb10eae..00000000 --- a/third-party/vendor/buddy_system_allocator/src/lib.rs +++ /dev/null @@ -1,345 +0,0 @@ -#![cfg_attr(feature = "const_fn", feature(const_mut_refs, const_fn_fn_ptr_basics))] -#![no_std] - -#[cfg(test)] -#[macro_use] -extern crate std; - -#[cfg(feature = "use_spin")] -extern crate spin; - -extern crate alloc; - -#[cfg(feature = "use_spin")] -use core::alloc::GlobalAlloc; -use core::alloc::Layout; -use core::cmp::{max, min}; -use core::fmt; -use core::mem::size_of; -#[cfg(feature = "use_spin")] -use core::ops::Deref; -use core::ptr::NonNull; -#[cfg(feature = "use_spin")] -use spin::Mutex; - -mod frame; -pub mod linked_list; -#[cfg(test)] -mod test; - -pub use frame::*; - -/// A heap that uses buddy system with configurable order. -/// -/// # Usage -/// -/// Create a heap and add a memory region to it: -/// ``` -/// use buddy_system_allocator::*; -/// # use core::mem::size_of; -/// let mut heap = Heap::<32>::empty(); -/// # let space: [usize; 100] = [0; 100]; -/// # let begin: usize = space.as_ptr() as usize; -/// # let end: usize = begin + 100 * size_of::(); -/// # let size: usize = 100 * size_of::(); -/// unsafe { -/// heap.init(begin, size); -/// // or -/// heap.add_to_heap(begin, end); -/// } -/// ``` -pub struct Heap { - // buddy system with max order of `ORDER` - free_list: [linked_list::LinkedList; ORDER], - - // statistics - user: usize, - allocated: usize, - total: usize, -} - -impl Heap { - /// Create an empty heap - pub const fn new() -> Self { - Heap { - free_list: [linked_list::LinkedList::new(); ORDER], - user: 0, - allocated: 0, - total: 0, - } - } - - /// Create an empty heap - pub const fn empty() -> Self { - Self::new() - } - - /// Add a range of memory [start, end) to the heap - pub unsafe fn add_to_heap(&mut self, mut start: usize, mut end: usize) { - // avoid unaligned access on some platforms - start = (start + size_of::() - 1) & (!size_of::() + 1); - end &= !size_of::() + 1; - assert!(start <= end); - - let mut total = 0; - let mut current_start = start; - - while current_start + size_of::() <= end { - let lowbit = current_start & (!current_start + 1); - let size = min(lowbit, prev_power_of_two(end - current_start)); - total += size; - - self.free_list[size.trailing_zeros() as usize].push(current_start as *mut usize); - current_start += size; - } - - self.total += total; - } - - /// Add a range of memory [start, start+size) to the heap - pub unsafe fn init(&mut self, start: usize, size: usize) { - self.add_to_heap(start, start + size); - } - - /// Alloc a range of memory from the heap satifying `layout` requirements - pub fn alloc(&mut self, layout: Layout) -> Result, ()> { - let size = max( - layout.size().next_power_of_two(), - max(layout.align(), size_of::()), - ); - let class = size.trailing_zeros() as usize; - for i in class..self.free_list.len() { - // Find the first non-empty size class - if !self.free_list[i].is_empty() { - // Split buffers - for j in (class + 1..i + 1).rev() { - if let Some(block) = self.free_list[j].pop() { - unsafe { - self.free_list[j - 1] - .push((block as usize + (1 << (j - 1))) as *mut usize); - self.free_list[j - 1].push(block); - } - } else { - return Err(()); - } - } - - let result = NonNull::new( - self.free_list[class] - .pop() - .expect("current block should have free space now") - as *mut u8, - ); - if let Some(result) = result { - self.user += layout.size(); - self.allocated += size; - return Ok(result); - } else { - return Err(()); - } - } - } - Err(()) - } - - /// Dealloc a range of memory from the heap - pub fn dealloc(&mut self, ptr: NonNull, layout: Layout) { - let size = max( - layout.size().next_power_of_two(), - max(layout.align(), size_of::()), - ); - let class = size.trailing_zeros() as usize; - - unsafe { - // Put back into free list - self.free_list[class].push(ptr.as_ptr() as *mut usize); - - // Merge free buddy lists - let mut current_ptr = ptr.as_ptr() as usize; - let mut current_class = class; - - while current_class < self.free_list.len() - 1 { - let buddy = current_ptr ^ (1 << current_class); - let mut flag = false; - for block in self.free_list[current_class].iter_mut() { - if block.value() as usize == buddy { - block.pop(); - flag = true; - break; - } - } - - // Free buddy found - if flag { - self.free_list[current_class].pop(); - current_ptr = min(current_ptr, buddy); - current_class += 1; - self.free_list[current_class].push(current_ptr as *mut usize); - } else { - break; - } - } - } - - self.user -= layout.size(); - self.allocated -= size; - } - - /// Return the number of bytes that user requests - pub fn stats_alloc_user(&self) -> usize { - self.user - } - - /// Return the number of bytes that are actually allocated - pub fn stats_alloc_actual(&self) -> usize { - self.allocated - } - - /// Return the total number of bytes in the heap - pub fn stats_total_bytes(&self) -> usize { - self.total - } -} - -impl fmt::Debug for Heap { - fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { - fmt.debug_struct("Heap") - .field("user", &self.user) - .field("allocated", &self.allocated) - .field("total", &self.total) - .finish() - } -} - -/// A locked version of `Heap` -/// -/// # Usage -/// -/// Create a locked heap and add a memory region to it: -/// ``` -/// use buddy_system_allocator::*; -/// # use core::mem::size_of; -/// let mut heap = LockedHeap::<32>::new(); -/// # let space: [usize; 100] = [0; 100]; -/// # let begin: usize = space.as_ptr() as usize; -/// # let end: usize = begin + 100 * size_of::(); -/// # let size: usize = 100 * size_of::(); -/// unsafe { -/// heap.lock().init(begin, size); -/// // or -/// heap.lock().add_to_heap(begin, end); -/// } -/// ``` -#[cfg(feature = "use_spin")] -pub struct LockedHeap(Mutex>); - -#[cfg(feature = "use_spin")] -impl LockedHeap { - /// Creates an empty heap - pub const fn new() -> Self { - LockedHeap(Mutex::new(Heap::::new())) - } - - /// Creates an empty heap - pub const fn empty() -> Self { - LockedHeap(Mutex::new(Heap::::new())) - } -} - -#[cfg(feature = "use_spin")] -impl Deref for LockedHeap { - type Target = Mutex>; - - fn deref(&self) -> &Self::Target { - &self.0 - } -} - -#[cfg(feature = "use_spin")] -unsafe impl GlobalAlloc for LockedHeap { - unsafe fn alloc(&self, layout: Layout) -> *mut u8 { - self.0 - .lock() - .alloc(layout) - .ok() - .map_or(core::ptr::null_mut(), |allocation| allocation.as_ptr()) - } - - unsafe fn dealloc(&self, ptr: *mut u8, layout: Layout) { - self.0.lock().dealloc(NonNull::new_unchecked(ptr), layout) - } -} - -/// A locked version of `Heap` with rescue before oom -/// -/// # Usage -/// -/// Create a locked heap: -/// ``` -/// use buddy_system_allocator::*; -/// let heap = LockedHeapWithRescue::new(|heap: &mut Heap<32>, layout: &core::alloc::Layout| {}); -/// ``` -/// -/// Before oom, the allocator will try to call rescue function and try for one more time. -#[cfg(feature = "use_spin")] -pub struct LockedHeapWithRescue { - inner: Mutex>, - rescue: fn(&mut Heap, &Layout), -} - -#[cfg(feature = "use_spin")] -impl LockedHeapWithRescue { - /// Creates an empty heap - #[cfg(feature = "const_fn")] - pub const fn new(rescue: fn(&mut Heap, &Layout)) -> Self { - LockedHeapWithRescue { - inner: Mutex::new(Heap::::new()), - rescue, - } - } - - /// Creates an empty heap - #[cfg(not(feature = "const_fn"))] - pub fn new(rescue: fn(&mut Heap, &Layout)) -> Self { - LockedHeapWithRescue { - inner: Mutex::new(Heap::::new()), - rescue, - } - } -} - -#[cfg(feature = "use_spin")] -impl Deref for LockedHeapWithRescue { - type Target = Mutex>; - - fn deref(&self) -> &Self::Target { - &self.inner - } -} - -#[cfg(feature = "use_spin")] -unsafe impl GlobalAlloc for LockedHeapWithRescue { - unsafe fn alloc(&self, layout: Layout) -> *mut u8 { - let mut inner = self.inner.lock(); - match inner.alloc(layout) { - Ok(allocation) => allocation.as_ptr(), - Err(_) => { - (self.rescue)(&mut inner, &layout); - inner - .alloc(layout) - .ok() - .map_or(core::ptr::null_mut(), |allocation| allocation.as_ptr()) - } - } - } - - unsafe fn dealloc(&self, ptr: *mut u8, layout: Layout) { - self.inner - .lock() - .dealloc(NonNull::new_unchecked(ptr), layout) - } -} - -pub(crate) fn prev_power_of_two(num: usize) -> usize { - 1 << (usize::BITS as usize - num.leading_zeros() as usize - 1) -} diff --git a/third-party/vendor/buddy_system_allocator/src/linked_list.rs b/third-party/vendor/buddy_system_allocator/src/linked_list.rs deleted file mode 100644 index 806f9d03..00000000 --- a/third-party/vendor/buddy_system_allocator/src/linked_list.rs +++ /dev/null @@ -1,141 +0,0 @@ -//! Provide the intrusive LinkedList - -use core::marker::PhantomData; -use core::{fmt, ptr}; - -/// An intrusive linked list -/// -/// A clean room implementation of the one used in CS140e 2018 Winter -/// -/// Thanks Sergio Benitez for his excellent work, -/// See [CS140e](https://cs140e.sergio.bz/) for more information -#[derive(Copy, Clone)] -pub struct LinkedList { - head: *mut usize, -} - -unsafe impl Send for LinkedList {} - -impl LinkedList { - /// Create a new LinkedList - pub const fn new() -> LinkedList { - LinkedList { - head: ptr::null_mut(), - } - } - - /// Return `true` if the list is empty - pub fn is_empty(&self) -> bool { - self.head.is_null() - } - - /// Push `item` to the front of the list - pub unsafe fn push(&mut self, item: *mut usize) { - *item = self.head as usize; - self.head = item; - } - - /// Try to remove the first item in the list - pub fn pop(&mut self) -> Option<*mut usize> { - match self.is_empty() { - true => None, - false => { - // Advance head pointer - let item = self.head; - self.head = unsafe { *item as *mut usize }; - Some(item) - } - } - } - - /// Return an iterator over the items in the list - pub fn iter(&self) -> Iter { - Iter { - curr: self.head, - list: PhantomData, - } - } - - /// Return an mutable iterator over the items in the list - pub fn iter_mut(&mut self) -> IterMut { - IterMut { - prev: &mut self.head as *mut *mut usize as *mut usize, - curr: self.head, - list: PhantomData, - } - } -} - -impl fmt::Debug for LinkedList { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - f.debug_list().entries(self.iter()).finish() - } -} - -/// An iterator over the linked list -pub struct Iter<'a> { - curr: *mut usize, - list: PhantomData<&'a LinkedList>, -} - -impl<'a> Iterator for Iter<'a> { - type Item = *mut usize; - - fn next(&mut self) -> Option { - if self.curr.is_null() { - None - } else { - let item = self.curr; - let next = unsafe { *item as *mut usize }; - self.curr = next; - Some(item) - } - } -} - -/// Represent a mutable node in `LinkedList` -pub struct ListNode { - prev: *mut usize, - curr: *mut usize, -} - -impl ListNode { - /// Remove the node from the list - pub fn pop(self) -> *mut usize { - // Skip the current one - unsafe { - *(self.prev) = *(self.curr); - } - self.curr - } - - /// Returns the pointed address - pub fn value(&self) -> *mut usize { - self.curr - } -} - -/// A mutable iterator over the linked list -pub struct IterMut<'a> { - list: PhantomData<&'a mut LinkedList>, - prev: *mut usize, - curr: *mut usize, -} - -impl<'a> Iterator for IterMut<'a> { - type Item = ListNode; - - fn next(&mut self) -> Option { - if self.curr.is_null() { - None - } else { - let res = ListNode { - prev: self.prev, - curr: self.curr, - }; - self.prev = self.curr; - self.curr = unsafe { *self.curr as *mut usize }; - Some(res) - } - } -} diff --git a/third-party/vendor/buddy_system_allocator/src/test.rs b/third-party/vendor/buddy_system_allocator/src/test.rs deleted file mode 100644 index 7f2e0f11..00000000 --- a/third-party/vendor/buddy_system_allocator/src/test.rs +++ /dev/null @@ -1,225 +0,0 @@ -use crate::linked_list; -use crate::FrameAllocator; -use crate::Heap; -use crate::LockedHeapWithRescue; -use core::alloc::GlobalAlloc; -use core::alloc::Layout; -use core::mem::size_of; - -#[test] -fn test_linked_list() { - let mut value1: usize = 0; - let mut value2: usize = 0; - let mut value3: usize = 0; - let mut list = linked_list::LinkedList::new(); - unsafe { - list.push(&mut value1 as *mut usize); - list.push(&mut value2 as *mut usize); - list.push(&mut value3 as *mut usize); - } - - // Test links - assert_eq!(value3, &value2 as *const usize as usize); - assert_eq!(value2, &value1 as *const usize as usize); - assert_eq!(value1, 0); - - // Test iter - let mut iter = list.iter(); - assert_eq!(iter.next(), Some(&mut value3 as *mut usize)); - assert_eq!(iter.next(), Some(&mut value2 as *mut usize)); - assert_eq!(iter.next(), Some(&mut value1 as *mut usize)); - assert_eq!(iter.next(), None); - - // Test iter_mut - - let mut iter_mut = list.iter_mut(); - assert_eq!(iter_mut.next().unwrap().pop(), &mut value3 as *mut usize); - - // Test pop - assert_eq!(list.pop(), Some(&mut value2 as *mut usize)); - assert_eq!(list.pop(), Some(&mut value1 as *mut usize)); - assert_eq!(list.pop(), None); -} - -#[test] -fn test_empty_heap() { - let mut heap = Heap::<32>::new(); - assert!(heap.alloc(Layout::from_size_align(1, 1).unwrap()).is_err()); -} - -#[test] -fn test_heap_add() { - let mut heap = Heap::<32>::new(); - assert!(heap.alloc(Layout::from_size_align(1, 1).unwrap()).is_err()); - - let space: [usize; 100] = [0; 100]; - unsafe { - heap.add_to_heap(space.as_ptr() as usize, space.as_ptr().add(100) as usize); - } - let addr = heap.alloc(Layout::from_size_align(1, 1).unwrap()); - assert!(addr.is_ok()); -} - -#[test] -fn test_heap_oom() { - let mut heap = Heap::<32>::new(); - let space: [usize; 100] = [0; 100]; - unsafe { - heap.add_to_heap(space.as_ptr() as usize, space.as_ptr().add(100) as usize); - } - - assert!(heap - .alloc(Layout::from_size_align(100 * size_of::(), 1).unwrap()) - .is_err()); - assert!(heap.alloc(Layout::from_size_align(1, 1).unwrap()).is_ok()); -} - -#[test] -fn test_heap_oom_rescue() { - static mut SPACE: [usize; 100] = [0; 100]; - let heap = LockedHeapWithRescue::new(|heap: &mut Heap<32>, _layout: &Layout| unsafe { - heap.add_to_heap(SPACE.as_ptr() as usize, SPACE.as_ptr().add(100) as usize); - }); - - unsafe { - assert!(heap.alloc(Layout::from_size_align(1, 1).unwrap()) as usize != 0); - } -} - -#[test] -fn test_heap_alloc_and_free() { - let mut heap = Heap::<32>::new(); - assert!(heap.alloc(Layout::from_size_align(1, 1).unwrap()).is_err()); - - let space: [usize; 100] = [0; 100]; - unsafe { - heap.add_to_heap(space.as_ptr() as usize, space.as_ptr().add(100) as usize); - } - for _ in 0..100 { - let addr = heap.alloc(Layout::from_size_align(1, 1).unwrap()).unwrap(); - heap.dealloc(addr, Layout::from_size_align(1, 1).unwrap()); - } -} - -#[test] -fn test_empty_frame_allocator() { - let mut frame = FrameAllocator::<32>::new(); - assert!(frame.alloc(1).is_none()); -} - -#[test] -fn test_frame_allocator_add() { - let mut frame = FrameAllocator::<32>::new(); - assert!(frame.alloc(1).is_none()); - - frame.insert(0..3); - let num = frame.alloc(1); - assert_eq!(num, Some(2)); - let num = frame.alloc(2); - assert_eq!(num, Some(0)); - assert!(frame.alloc(1).is_none()); - assert!(frame.alloc(2).is_none()); -} - -#[test] -fn test_frame_allocator_allocate_large() { - let mut frame = FrameAllocator::<32>::new(); - assert_eq!(frame.alloc(10_000_000_000), None); -} - -#[test] -fn test_frame_allocator_add_large_size_split() { - let mut frame = FrameAllocator::<32>::new(); - - frame.insert(0..10_000_000_000); - - assert_eq!(frame.alloc(0x8000_0001), None); - assert_eq!(frame.alloc(0x8000_0000), Some(0x8000_0000)); - assert_eq!(frame.alloc(0x8000_0000), Some(0x1_0000_0000)); -} - -#[test] -fn test_frame_allocator_add_large_size() { - let mut frame = FrameAllocator::<33>::new(); - - frame.insert(0..10_000_000_000); - assert_eq!(frame.alloc(0x8000_0001), Some(0x1_0000_0000)); -} - -#[test] -fn test_frame_allocator_alloc_and_free() { - let mut frame = FrameAllocator::<32>::new(); - assert!(frame.alloc(1).is_none()); - - frame.add_frame(0, 1024); - for _ in 0..100 { - let addr = frame.alloc(512).unwrap(); - frame.dealloc(addr, 512); - } -} - -#[test] -fn test_frame_allocator_alloc_and_free_complex() { - let mut frame = FrameAllocator::<32>::new(); - frame.add_frame(100, 1024); - for _ in 0..10 { - let addr = frame.alloc(1).unwrap(); - frame.dealloc(addr, 1); - } - let addr1 = frame.alloc(1).unwrap(); - let addr2 = frame.alloc(1).unwrap(); - assert_ne!(addr1, addr2); -} - -#[test] -fn test_frame_allocator_aligned() { - let mut frame = FrameAllocator::<32>::new(); - frame.add_frame(1, 64); - assert_eq!( - frame.alloc_aligned(Layout::from_size_align(2, 4).unwrap()), - Some(4) - ); - assert_eq!( - frame.alloc_aligned(Layout::from_size_align(2, 2).unwrap()), - Some(2) - ); - assert_eq!( - frame.alloc_aligned(Layout::from_size_align(2, 1).unwrap()), - Some(8) - ); - assert_eq!( - frame.alloc_aligned(Layout::from_size_align(1, 16).unwrap()), - Some(16) - ); -} - -#[test] -fn test_heap_merge_final_order() { - const NUM_ORDERS: usize = 5; - - let backing_size = 1 << NUM_ORDERS; - let backing_layout = Layout::from_size_align(backing_size, backing_size).unwrap(); - - // create a new heap with 5 orders - let mut heap = Heap::::new(); - - // allocate host memory for use by heap - let backing_allocation = unsafe { std::alloc::alloc(backing_layout) }; - - let start = backing_allocation as usize; - let middle = unsafe { backing_allocation.add(backing_size / 2) } as usize; - let end = unsafe { backing_allocation.add(backing_size) } as usize; - - // add two contiguous ranges of memory - unsafe { heap.add_to_heap(start, middle) }; - unsafe { heap.add_to_heap(middle, end) }; - - // NUM_ORDERS - 1 is the maximum order of the heap - let layout = Layout::from_size_align(1 << (NUM_ORDERS - 1), 1).unwrap(); - - // allocation should succeed, using one of the added ranges - let alloc = heap.alloc(layout).unwrap(); - - // deallocation should not attempt to merge the two contiguous ranges as the next order does not exist - heap.dealloc(alloc, layout); -} diff --git a/third-party/vendor/critical-section/.cargo-checksum.json b/third-party/vendor/critical-section/.cargo-checksum.json deleted file mode 100644 index bc6171bc..00000000 --- a/third-party/vendor/critical-section/.cargo-checksum.json +++ /dev/null @@ -1 +0,0 @@ -{"files":{"CHANGELOG.md":"cbd8b81564f893cdb91bea255013af9dada13a0cde91aeaed0002701fb7a020e","CODE_OF_CONDUCT.md":"8e25e95078b1a582086587adf8e1d907d43aacee6a072b8630d54a6289e5e0b9","Cargo.toml":"af0123f9e52fa1482936f1143924dc22891cba334031b5a55c19bc69b804916e","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"fee6bdac4b917351332567b9fd5013c2ef3c847dd113fd6216cf28e96637a157","README.md":"5e6c551ffe891fd5b9a3b6196d8961bbd5e92b1c764999d7e426a83fd23ac623","docs/msrv.md":"690a70e9ed6764198e4a5c0933a4124fc382091754d8bafb82241483ae2d89b9","src/lib.rs":"43a8804ae04c98c323e307c3f018078dd6d6ea5316f7c9bf5b8add24f5eb6000","src/mutex.rs":"4c239da3d73a13689e5c09d248ea2cb5d2c5bff4c87ba73bd405a12c02e85b66","src/std.rs":"4f04dde8d9528d7b6676fc2ea929f9f095e34c613efee23ad1c9d63329eff8ca"},"package":"7059fff8937831a9ae6f0fe4d658ffabf58f2ca96aa9dec1c889f936f705f216"} \ No newline at end of file diff --git a/third-party/vendor/critical-section/CHANGELOG.md b/third-party/vendor/critical-section/CHANGELOG.md deleted file mode 100644 index afd47a33..00000000 --- a/third-party/vendor/critical-section/CHANGELOG.md +++ /dev/null @@ -1,137 +0,0 @@ -# Changelog - -All notable changes to this project will be documented in this file. - -The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), -and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). - -## [Unreleased] - -No unreleased changes yet - -## [v1.1.2] - 2023-08-09 - -- Clarified that `acquire()` must provide ordering guarantees -- Updated atomic-polyfill reference to point to portable-atomic instead -- Improved documentation for `Mutex` example -- Added list of some known implementations - -## [v1.1.1] - 2022-09-13 - -- On the `std` implementation, panicking inside the `critical_section::with()` closure no longer accidentally leaves the critical section locked (#26). - -## [v1.1.0] - 2022-08-17 - -- Added built-in critical section implementation using `std::sync::Mutex`, enabled by the `std` Cargo feature. -- MSRV changed to `1.54` when `std` feature is disabled, `1.63` when enabled. - -## [v1.0.0] - 2022-08-10 - -- Improved docs. - -## [v1.0.0-alpha.2] - 2022-07-28 - -- Change name of the `extern fn`s to avoid clash with critical-section 0.2. - -## [v1.0.0-alpha.1] - 2022-07-28 - -Breaking changes: - -- Removed all builtin impls. These are going to be provided by platform-support crates now. -- Renamed `custom_impl!` to `set_impl!`. -- RestoreState is now an opaque struct for the user, and a transparent `RawRestoreState` type alias for impl writers. -- RestoreState type is now configurable with Cargo features. Default is `()`. (previously it was fixed to `u8`.) -- Added own `CriticalSection` and `Mutex` types, instead of reexporting them from `bare_metal`. - -## [v0.2.8] - 2022-11-29 - -- Implemented critical-section by forwarding to version 1.1.1 - -Breaking changes: - -- `acquire` and `release` are only implemented if the restore-state used by - version 1.1.1 is an u8 or smaller. -- No default critical-section implementation is provided. - -Those breaking changes are necessary because versions <= 0.2.7 were unsound, and that -was impossible to fix without a breaking change. - -This version is meant to minimize that breaking change. However, all -users are encouraged to upgrade to critical-section 1.1. - -If you're seeing a linker error like `undefined symbol: _critical_section_1_0_acquire`, you're affected. To fix it: - -- If your target supports `std`: Add the `critical-section` dependency to `Cargo.toml` enabling the `std` feature. - - ```toml - [dependencies] - critical-section = { version = "1.1", features = ["std"]} - ``` - -- For single-core Cortex-M targets in privileged mode: - ```toml - [dependencies] - cortex-m = { version = "0.7.6", features = ["critical-section-single-core"]} - ``` - -- For single-hart RISC-V targets in privileged mode: - ```toml - [dependencies] - riscv = { version = "0.10", features = ["critical-section-single-hart"]} - ``` - -- For other targets: check if your HAL or architecture-support crate has a `critical-section 1.0` implementation available. Otherwise, [provide your own](https://github.com/rust-embedded/critical-section#providing-an-implementation). - - -## [v0.2.7] - 2022-04-08 - -- Add support for AVR targets. - -## [v0.2.6] - 2022-04-02 - -- Improved docs. - -## [v0.2.5] - 2021-11-02 - -- Fix `std` implementation to allow reentrant (nested) critical sections. This would previously deadlock. - -## [v0.2.4] - 2021-09-24 - -- Add support for 32bit RISC-V targets. - -## [v0.2.3] - 2021-09-13 - -- Use correct `#[vcfg]` for `wasm` targets. - -## [v0.2.2] - 2021-09-13 - -- Added support for `wasm` targets. - -## [v0.2.1] - 2021-05-11 - -- Added critical section implementation for `std`, based on a global Mutex. - -## [v0.2.0] - 2021-05-10 - -- Breaking change: use `CriticalSection<'_>` instead of `&CriticalSection<'_>` - -## v0.1.0 - 2021-05-10 - -- First release - -[Unreleased]: https://github.com/rust-embedded/critical-section/compare/v1.1.2...HEAD -[v1.1.2]: https://github.com/rust-embedded/critical-section/compare/v1.1.1...v1.1.2 -[v1.1.1]: https://github.com/rust-embedded/critical-section/compare/v1.1.0...v1.1.1 -[v1.1.0]: https://github.com/rust-embedded/critical-section/compare/v1.0.0...v1.1.0 -[v1.0.0]: https://github.com/rust-embedded/critical-section/compare/v1.0.0-alpha.2...v1.0.0 -[v1.0.0-alpha.2]: https://github.com/rust-embedded/critical-section/compare/v1.0.0-alpha.1...v1.0.0-alpha.2 -[v1.0.0-alpha.1]: https://github.com/rust-embedded/critical-section/compare/v0.2.7...v1.0.0-alpha.1 -[v0.2.8]: https://github.com/rust-embedded/critical-section/compare/v0.2.7...v0.2.8 -[v0.2.7]: https://github.com/rust-embedded/critical-section/compare/v0.2.6...v0.2.7 -[v0.2.6]: https://github.com/rust-embedded/critical-section/compare/v0.2.5...v0.2.6 -[v0.2.5]: https://github.com/rust-embedded/critical-section/compare/v0.2.4...v0.2.5 -[v0.2.4]: https://github.com/rust-embedded/critical-section/compare/v0.2.3...v0.2.4 -[v0.2.3]: https://github.com/rust-embedded/critical-section/compare/v0.2.2...v0.2.3 -[v0.2.2]: https://github.com/rust-embedded/critical-section/compare/v0.2.1...v0.2.2 -[v0.2.1]: https://github.com/rust-embedded/critical-section/compare/v0.2.0...v0.2.1 -[v0.2.0]: https://github.com/rust-embedded/critical-section/compare/v0.1.0...v0.2.0 diff --git a/third-party/vendor/critical-section/CODE_OF_CONDUCT.md b/third-party/vendor/critical-section/CODE_OF_CONDUCT.md deleted file mode 100644 index bcefc6a2..00000000 --- a/third-party/vendor/critical-section/CODE_OF_CONDUCT.md +++ /dev/null @@ -1,37 +0,0 @@ -# The Rust Code of Conduct - -## Conduct - -**Contact**: [HAL team][team] - -* We are committed to providing a friendly, safe and welcoming environment for all, regardless of level of experience, gender identity and expression, sexual orientation, disability, personal appearance, body size, race, ethnicity, age, religion, nationality, or other similar characteristic. -* On IRC, please avoid using overtly sexual nicknames or other nicknames that might detract from a friendly, safe and welcoming environment for all. -* Please be kind and courteous. There's no need to be mean or rude. -* Respect that people have differences of opinion and that every design or implementation choice carries a trade-off and numerous costs. There is seldom a right answer. -* Please keep unstructured critique to a minimum. If you have solid ideas you want to experiment with, make a fork and see how it works. -* We will exclude you from interaction if you insult, demean or harass anyone. That is not welcome behavior. We interpret the term "harassment" as including the definition in the [Citizen Code of Conduct](http://citizencodeofconduct.org/); if you have any lack of clarity about what might be included in that concept, please read their definition. In particular, we don't tolerate behavior that excludes people in socially marginalized groups. -* Private harassment is also unacceptable. No matter who you are, if you feel you have been or are being harassed or made uncomfortable by a community member, please contact one of the channel ops or any of the [HAL team][team] immediately. Whether you're a regular contributor or a newcomer, we care about making this community a safe place for you and we've got your back. -* Likewise any spamming, trolling, flaming, baiting or other attention-stealing behavior is not welcome. - -## Moderation - -These are the policies for upholding our community's standards of conduct. - -1. Remarks that violate the Rust standards of conduct, including hateful, hurtful, oppressive, or exclusionary remarks, are not allowed. (Cursing is allowed, but never targeting another user, and never in a hateful manner.) -2. Remarks that moderators find inappropriate, whether listed in the code of conduct or not, are also not allowed. -3. Moderators will first respond to such remarks with a warning. -4. If the warning is unheeded, the user will be "kicked," i.e., kicked out of the communication channel to cool off. -5. If the user comes back and continues to make trouble, they will be banned, i.e., indefinitely excluded. -6. Moderators may choose at their discretion to un-ban the user if it was a first offense and they offer the offended party a genuine apology. -7. If a moderator bans someone and you think it was unjustified, please take it up with that moderator, or with a different moderator, **in private**. Complaints about bans in-channel are not allowed. -8. Moderators are held to a higher standard than other community members. If a moderator creates an inappropriate situation, they should expect less leeway than others. - -In the Rust community we strive to go the extra step to look out for each other. Don't just aim to be technically unimpeachable, try to be your best self. In particular, avoid flirting with offensive or sensitive issues, particularly if they're off-topic; this all too often leads to unnecessary fights, hurt feelings, and damaged trust; worse, it can drive people away from the community entirely. - -And if someone takes issue with something you said or did, resist the urge to be defensive. Just stop doing what it was they complained about and apologize. Even if you feel you were misinterpreted or unfairly accused, chances are good there was something you could've communicated better — remember that it's your responsibility to make your fellow Rustaceans comfortable. Everyone wants to get along and we are all here first and foremost because we want to talk about cool technology. You will find that people will be eager to assume good intent and forgive as long as you earn their trust. - -The enforcement policies listed above apply to all official embedded WG venues; including official IRC channels (#rust-embedded); GitHub repositories under rust-embedded; and all forums under rust-embedded.org (forum.rust-embedded.org). - -*Adapted from the [Node.js Policy on Trolling](http://blog.izs.me/post/30036893703/policy-on-trolling) as well as the [Contributor Covenant v1.3.0](https://www.contributor-covenant.org/version/1/3/0/).* - -[team]: https://github.com/rust-embedded/wg#the-hal-team diff --git a/third-party/vendor/critical-section/Cargo.toml b/third-party/vendor/critical-section/Cargo.toml deleted file mode 100644 index 1108b056..00000000 --- a/third-party/vendor/critical-section/Cargo.toml +++ /dev/null @@ -1,33 +0,0 @@ -# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO -# -# When uploading crates to the registry Cargo will automatically -# "normalize" Cargo.toml files for maximal compatibility -# with all versions of Cargo and also rewrite `path` dependencies -# to registry (e.g., crates.io) dependencies. -# -# If you are reading this file be aware that the original Cargo.toml -# will likely look very different (and much more reasonable). -# See Cargo.toml.orig for the original contents. - -[package] -edition = "2018" -name = "critical-section" -version = "1.1.2" -description = "Cross-platform critical section" -readme = "README.md" -categories = [ - "embedded", - "no-std", - "concurrency", -] -license = "MIT OR Apache-2.0" -repository = "https://github.com/rust-embedded/critical-section" - -[features] -restore-state-bool = [] -restore-state-none = [] -restore-state-u16 = [] -restore-state-u32 = [] -restore-state-u64 = [] -restore-state-u8 = [] -std = ["restore-state-bool"] diff --git a/third-party/vendor/critical-section/LICENSE-APACHE b/third-party/vendor/critical-section/LICENSE-APACHE deleted file mode 100644 index 16fe87b0..00000000 --- a/third-party/vendor/critical-section/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. diff --git a/third-party/vendor/critical-section/LICENSE-MIT b/third-party/vendor/critical-section/LICENSE-MIT deleted file mode 100644 index 78bced90..00000000 --- a/third-party/vendor/critical-section/LICENSE-MIT +++ /dev/null @@ -1,25 +0,0 @@ -Copyright (c) 2022 The critical-section authors - -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. diff --git a/third-party/vendor/critical-section/README.md b/third-party/vendor/critical-section/README.md deleted file mode 100644 index 32f1678c..00000000 --- a/third-party/vendor/critical-section/README.md +++ /dev/null @@ -1,250 +0,0 @@ -# critical-section -[![crates.io](https://img.shields.io/crates/d/critical-section.svg)](https://crates.io/crates/critical-section) -[![crates.io](https://img.shields.io/crates/v/critical-section.svg)](https://crates.io/crates/critical-section) -[![Documentation](https://docs.rs/critical-section/badge.svg)](https://docs.rs/critical-section) - -This project is developed and maintained by the [HAL team][team]. - -A critical section that works everywhere! - -When writing software for embedded systems, it's common to use a "critical section" -as a basic primitive to control concurrency. A critical section is essentially a -mutex global to the whole process, that can be acquired by only one thread at a time. -This can be used to protect data behind mutexes, to [emulate atomics](https://crates.io/crates/portable-atomic) in -targets that don't support them, etc. - -There's a wide range of possible implementations depending on the execution environment: -- For bare-metal single core, disabling interrupts in the current (only) core. -- For bare-metal multicore, disabling interrupts in the current core and acquiring a hardware spinlock to prevent other cores from entering a critical section concurrently. -- For bare-metal using a RTOS, using library functions for acquiring a critical section, often named "scheduler lock" or "kernel lock". -- For bare-metal running in non-privileged mode, calling some system call is usually needed. -- For `std` targets, acquiring a global `std::sync::Mutex`. - -Libraries often need to use critical sections, but there's no universal API for this in `core`. This leads -library authors to hard-code them for their target, or at best add some `cfg`s to support a few targets. -This doesn't scale since there are many targets out there, and in the general case it's impossible to know -which critical section implementation is needed from the Rust target alone. For example, the `thumbv7em-none-eabi` target -could be cases 1-4 from the above list. - -This crate solves the problem by providing this missing universal API. - -- It provides functions `acquire`, `release` and `with` that libraries can directly use. -- It provides a way for any crate to supply an implementation. This allows "target support" crates such as architecture crates (`cortex-m`, `riscv`), RTOS bindings, or HALs for multicore chips to supply the correct implementation so that all the crates in the dependency tree automatically use it. - -## Usage in `no-std` binaries. - -First, add a dependency on a crate providing a critical section implementation. Enable the `critical-section-*` Cargo feature if required by the crate. - -Implementations are typically provided by either architecture-support crates, HAL crates, and OS/RTOS bindings, including: - -* The [`cortex-m`] crate provides an implementation for all single-core Cortex-M microcontrollers via its `critical-section-single-core` feature -* The [`riscv`] crate provides an implementation for all single-hart RISC-V microcontrollers via its `critical-section-single-hart` feature -* The [`msp430`] crate provides an implementation for all MSP430 microcontrollers via its `critical-section-single-core` feature -* The [`rp2040-hal`] crate provides a multi-core-safe critical section for the RP2040 microcontroller via its `critical-section-impl` feature -* The [`avr-device`] crate provides an implementation for all AVR microcontrollers via its `critical-section-impl` feature -* The [`esp-hal-common`] crate provides an implementation for ESP32 microcontrollers which is used by the ESP HALs -* The [`embassy-rp`] crate provides a multi-core-safe critical section for the RP2040 microcontroller via its `critical-section-impl` feature -* The [`nrf-softdevice`] crate provides a critical section that's compatible with the nRF soft-device firmware via its `critical-section-impl` feature - -[`cortex-m`]: https://crates.io/crates/cortex-m -[`riscv`]: https://crates.io/crates/riscv -[`msp430`]: https://crates.io/crates/msp430 -[`rp2040-hal`]: https://crates.io/crates/rp2040-hal -[`avr-device`]: https://crates.io/crates/avr-device -[`esp-hal-common`]: https://crates.io/crates/esp-hal-common -[`embassy-rp`]: https://docs.embassy.dev/embassy-rp -[`nrf-softdevice`]: https://docs.embassy.dev/nrf-softdevice - -For example, for single-core Cortex-M targets, you can use: - -```toml -[dependencies] -cortex-m = { version = "0.7.6", features = ["critical-section-single-core"]} -``` - -Then you can use `critical_section::with()`. - -```rust -use core::cell::Cell; -use critical_section::Mutex; - -static MY_VALUE: Mutex> = Mutex::new(Cell::new(0)); - -critical_section::with(|cs| { - // This code runs within a critical section. - - // `cs` is a token that you can use to "prove" that to some API, - // for example to a `Mutex`: - MY_VALUE.borrow(cs).set(42); -}); - -# #[cfg(not(feature = "std"))] // needed for `cargo test --features std` -# mod no_std { -# struct MyCriticalSection; -# critical_section::set_impl!(MyCriticalSection); -# unsafe impl critical_section::Impl for MyCriticalSection { -# unsafe fn acquire() -> () {} -# unsafe fn release(token: ()) {} -# } -# } -``` - -## Usage in `std` binaries. - -Add the `critical-section` dependency to `Cargo.toml` enabling the `std` feature. This makes the `critical-section` crate itself -provide an implementation based on `std::sync::Mutex`, so you don't have to add any other dependency. - -```toml -[dependencies] -critical-section = { version = "1.1", features = ["std"]} -``` - -## Usage in libraries - -If you're writing a library intended to be portable across many targets, simply add a dependency on `critical-section` -and use `critical_section::free` and/or `Mutex` as usual. - -**Do not** add any dependency supplying a critical section implementation. Do not enable any `critical-section-*` Cargo feature. -This has to be done by the end user, enabling the correct implementation for their target. - -**Do not** enable any Cargo feature in `critical-section`. - -## Usage in `std` tests for `no-std` libraries. - -If you want to run `std`-using tests in otherwise `no-std` libraries, enable the `std` feature in `dev-dependencies` only. -This way the main target will use the `no-std` implementation chosen by the end-user's binary, and only the test targets -will use the `std` implementation. - -```toml -[dependencies] -critical-section = "1.1" - -[dev-dependencies] -critical-section = { version = "1.1", features = ["std"]} -``` - -## Providing an implementation - -Crates adding support for a particular architecture, chip or operating system should provide a critical section implementation. -It is **strongly recommended** to gate the implementation behind a feature, so the user can still use another implementation -if needed (having two implementations in the same binary will cause linking to fail). - -Add the dependency, and a `critical-section-*` feature to your `Cargo.toml`: - -```toml -[features] -# Enable critical section implementation that does "foo" -critical-section-foo = ["critical-section/restore-state-bool"] - -[dependencies] -critical-section = { version = "1.0", optional = true } -``` - -Then, provide the critical implementation like this: - -```rust -# #[cfg(not(feature = "std"))] // needed for `cargo test --features std` -# mod no_std { -// This is a type alias for the enabled `restore-state-*` feature. -// For example, it is `bool` if you enable `restore-state-bool`. -use critical_section::RawRestoreState; - -struct MyCriticalSection; -critical_section::set_impl!(MyCriticalSection); - -unsafe impl critical_section::Impl for MyCriticalSection { - unsafe fn acquire() -> RawRestoreState { - // TODO - } - - unsafe fn release(token: RawRestoreState) { - // TODO - } -} -# } -``` - -## Troubleshooting - -### Undefined reference errors - -If you get an error like these: - -```not_rust -undefined reference to `_critical_section_1_0_acquire' -undefined reference to `_critical_section_1_0_release' -``` - -it is because you (or a library) are using `critical_section::with` without providing a critical section implementation. -Make sure you're depending on a crate providing the implementation, and have enabled the `critical-section-*` feature in it if required. See the `Usage` section above. - -The error can also be caused by having the dependency but never `use`ing it. This can be fixed by adding a dummy `use`: - -```rust,ignore -use the_cs_impl_crate as _; -``` - -### Duplicate symbol errors - -If you get errors like these: - -```not_rust -error: symbol `_critical_section_1_0_acquire` is already defined -``` - -it is because you have two crates trying to provide a critical section implementation. You can only -have one implementation in a program. - -You can use `cargo tree --format '{p} {f}'` to view all dependencies and their enabled features. Make sure -that in the whole dependency tree, exactly one implementation is provided. - -Check for multiple versions of the same crate as well. For example, check the `critical-section-single-core` -feature is not enabled for both `cortex-m` 0.7 and 0.8. - -## Why not generics? - -An alternative solution would be to use a `CriticalSection` trait, and make all -code that needs acquiring the critical section generic over it. This has a few problems: - -- It would require passing it as a generic param to a very big amount of code, which -would be quite unergonomic. -- It's common to put `Mutex`es in `static` variables, and `static`s can't -be generic. -- It would allow mixing different critical section implementations in the same program, -which would be unsound. - -## Minimum Supported Rust Version (MSRV) - -This crate is guaranteed to compile on the following Rust versions: - -- If the `std` feature is not enabled: stable Rust 1.54 and up. -- If the `std` feature is enabled: stable Rust 1.63 and up. - -It might compile with older versions but that may change in any new patch release. - -See [here](docs/msrv.md) for details on how the MSRV may be upgraded. - -## License - -This work is licensed under either of - -- Apache License, Version 2.0 ([LICENSE-APACHE](LICENSE-APACHE) or - ) -- MIT license ([LICENSE-MIT](LICENSE-MIT) or ) - -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. - -## Code of Conduct - -Contribution to this crate is organized under the terms of the [Rust Code of -Conduct][CoC], the maintainer of this crate, the [HAL team][team], promises -to intervene to uphold that code of conduct. - -[CoC]: CODE_OF_CONDUCT.md -[team]: https://github.com/rust-embedded/wg#the-hal-team diff --git a/third-party/vendor/critical-section/docs/msrv.md b/third-party/vendor/critical-section/docs/msrv.md deleted file mode 100644 index ec0056a3..00000000 --- a/third-party/vendor/critical-section/docs/msrv.md +++ /dev/null @@ -1,30 +0,0 @@ -# Minimum Supported Rust Version (MSRV) - -This crate is guaranteed to compile on all stable Rust versions going back to -the version stated as MSRV in the README. It *might* compile with even older versions but -that may change in any new patch release. - -## How the MSRV will be upgraded - -For `critical-section`, we do not consider upgrading the MSRV a strictly breaking change as defined by -[SemVer](https://semver.org). - -We follow these rules when upgrading it: - -- We will not update the MSRV on any patch release: \_.\_.*Z*. -- We may upgrade the MSRV on any *major* or *minor* release: *X*.*Y*.\_. -- We may upgrade the MSRV in any preliminary version release (e.g. an `-alpha` release) as - these serve as preparation for the final release. -- MSRV upgrades will be clearly stated in the changelog. - -This applies both to `0._._` releases as well as `>=1._._` releases. - -For example: - -For a given `x.y.z` release, we may upgrade the MSRV on `x` and `y` releases but not on `z` releases. - -If your MSRV upgrade policy differs from this, you are advised to specify the -`critical-section` dependency in your `Cargo.toml` accordingly. - -See the [Rust Embedded Working Group MSRV RFC](https://github.com/rust-embedded/wg/blob/master/rfcs/0523-msrv-2020.md) -for more background information and reasoning. diff --git a/third-party/vendor/critical-section/src/lib.rs b/third-party/vendor/critical-section/src/lib.rs deleted file mode 100644 index 6b26725a..00000000 --- a/third-party/vendor/critical-section/src/lib.rs +++ /dev/null @@ -1,289 +0,0 @@ -#![cfg_attr(not(feature = "std"), no_std)] -#![doc = include_str!("../README.md")] - -mod mutex; -#[cfg(feature = "std")] -mod std; - -use core::marker::PhantomData; - -pub use self::mutex::Mutex; - -/// Critical section token. -/// -/// An instance of this type indicates that the current thread is executing code within a critical -/// section. -#[derive(Clone, Copy, Debug)] -pub struct CriticalSection<'cs> { - _private: PhantomData<&'cs ()>, -} - -impl<'cs> CriticalSection<'cs> { - /// Creates a critical section token. - /// - /// This method is meant to be used to create safe abstractions rather than being directly used - /// in applications. - /// - /// # Safety - /// - /// This must only be called when the current thread is in a critical section. The caller must - /// ensure that the returned instance will not live beyond the end of the critical section. - /// - /// The caller must use adequate fences to prevent the compiler from moving the - /// instructions inside the critical section to the outside of it. Sequentially consistent fences are - /// suggested immediately after entry and immediately before exit from the critical section. - /// - /// Note that the lifetime `'cs` of the returned instance is unconstrained. User code must not - /// be able to influence the lifetime picked for this type, since that might cause it to be - /// inferred to `'static`. - #[inline(always)] - pub unsafe fn new() -> Self { - CriticalSection { - _private: PhantomData, - } - } -} - -#[cfg(any( - all(feature = "restore-state-none", feature = "restore-state-bool"), - all(feature = "restore-state-none", feature = "restore-state-u8"), - all(feature = "restore-state-none", feature = "restore-state-u16"), - all(feature = "restore-state-none", feature = "restore-state-u32"), - all(feature = "restore-state-none", feature = "restore-state-u64"), - all(feature = "restore-state-bool", feature = "restore-state-u8"), - all(feature = "restore-state-bool", feature = "restore-state-u16"), - all(feature = "restore-state-bool", feature = "restore-state-u32"), - all(feature = "restore-state-bool", feature = "restore-state-u64"), - all(feature = "restore-state-u8", feature = "restore-state-u16"), - all(feature = "restore-state-u8", feature = "restore-state-u32"), - all(feature = "restore-state-u8", feature = "restore-state-u64"), - all(feature = "restore-state-u16", feature = "restore-state-u32"), - all(feature = "restore-state-u16", feature = "restore-state-u64"), - all(feature = "restore-state-u32", feature = "restore-state-u64"), -))] -compile_error!("You must set at most one of these Cargo features: restore-state-none, restore-state-bool, restore-state-u8, restore-state-u16, restore-state-u32, restore-state-u64"); - -#[cfg(not(any( - feature = "restore-state-bool", - feature = "restore-state-u8", - feature = "restore-state-u16", - feature = "restore-state-u32", - feature = "restore-state-u64" -)))] -type RawRestoreStateInner = (); - -#[cfg(feature = "restore-state-bool")] -type RawRestoreStateInner = bool; - -#[cfg(feature = "restore-state-u8")] -type RawRestoreStateInner = u8; - -#[cfg(feature = "restore-state-u16")] -type RawRestoreStateInner = u16; - -#[cfg(feature = "restore-state-u32")] -type RawRestoreStateInner = u32; - -#[cfg(feature = "restore-state-u64")] -type RawRestoreStateInner = u64; - -// We have RawRestoreStateInner and RawRestoreState so that we don't have to copypaste the docs 5 times. -// In the docs this shows as `pub type RawRestoreState = u8` or whatever the selected type is, because -// the "inner" type alias is private. - -/// Raw, transparent "restore state". -/// -/// This type changes based on which Cargo feature is selected, out of -/// - `restore-state-none` (default, makes the type be `()`) -/// - `restore-state-bool` -/// - `restore-state-u8` -/// - `restore-state-u16` -/// - `restore-state-u32` -/// - `restore-state-u64` -/// -/// See [`RestoreState`]. -/// -/// User code uses [`RestoreState`] opaquely, critical section implementations -/// use [`RawRestoreState`] so that they can use the inner value. -pub type RawRestoreState = RawRestoreStateInner; - -/// Opaque "restore state". -/// -/// Implementations use this to "carry over" information between acquiring and releasing -/// a critical section. For example, when nesting two critical sections of an -/// implementation that disables interrupts globally, acquiring the inner one won't disable -/// the interrupts since they're already disabled. The impl would use the restore state to "tell" -/// the corresponding release that it does *not* have to reenable interrupts yet, only the -/// outer release should do so. -/// -/// User code uses [`RestoreState`] opaquely, critical section implementations -/// use [`RawRestoreState`] so that they can use the inner value. -#[derive(Clone, Copy, Debug)] -pub struct RestoreState(RawRestoreState); - -impl RestoreState { - /// Create an invalid, dummy `RestoreState`. - /// - /// This can be useful to avoid `Option` when storing a `RestoreState` in a - /// struct field, or a `static`. - /// - /// Note that due to the safety contract of [`acquire`]/[`release`], you must not pass - /// a `RestoreState` obtained from this method to [`release`]. - pub const fn invalid() -> Self { - #[cfg(not(any( - feature = "restore-state-bool", - feature = "restore-state-u8", - feature = "restore-state-u16", - feature = "restore-state-u32", - feature = "restore-state-u64" - )))] - return Self(()); - - #[cfg(feature = "restore-state-bool")] - return Self(false); - - #[cfg(feature = "restore-state-u8")] - return Self(0); - - #[cfg(feature = "restore-state-u16")] - return Self(0); - - #[cfg(feature = "restore-state-u32")] - return Self(0); - - #[cfg(feature = "restore-state-u64")] - return Self(0); - } -} - -/// Acquire a critical section in the current thread. -/// -/// This function is extremely low level. Strongly prefer using [`with`] instead. -/// -/// Nesting critical sections is allowed. The inner critical sections -/// are mostly no-ops since they're already protected by the outer one. -/// -/// # Safety -/// -/// - Each `acquire` call must be paired with exactly one `release` call in the same thread. -/// - `acquire` returns a "restore state" that you must pass to the corresponding `release` call. -/// - `acquire`/`release` pairs must be "properly nested", ie it's not OK to do `a=acquire(); b=acquire(); release(a); release(b);`. -/// - It is UB to call `release` if the critical section is not acquired in the current thread. -/// - It is UB to call `release` with a "restore state" that does not come from the corresponding `acquire` call. -/// - It must provide ordering guarantees at least equivalent to a [`core::sync::atomic::Ordering::Acquire`] -/// on a memory location shared by all critical sections, on which the `release` call will do a -/// [`core::sync::atomic::Ordering::Release`] operation. -#[inline(always)] -pub unsafe fn acquire() -> RestoreState { - extern "Rust" { - fn _critical_section_1_0_acquire() -> RawRestoreState; - } - - #[allow(clippy::unit_arg)] - RestoreState(_critical_section_1_0_acquire()) -} - -/// Release the critical section. -/// -/// This function is extremely low level. Strongly prefer using [`with`] instead. -/// -/// # Safety -/// -/// See [`acquire`] for the safety contract description. -#[inline(always)] -pub unsafe fn release(restore_state: RestoreState) { - extern "Rust" { - fn _critical_section_1_0_release(restore_state: RawRestoreState); - } - - #[allow(clippy::unit_arg)] - _critical_section_1_0_release(restore_state.0) -} - -/// Execute closure `f` in a critical section. -/// -/// Nesting critical sections is allowed. The inner critical sections -/// are mostly no-ops since they're already protected by the outer one. -/// -/// # Panics -/// -/// This function panics if the given closure `f` panics. In this case -/// the critical section is released before unwinding. -#[inline] -pub fn with(f: impl FnOnce(CriticalSection) -> R) -> R { - // Helper for making sure `release` is called even if `f` panics. - struct Guard { - state: RestoreState, - } - - impl Drop for Guard { - #[inline(always)] - fn drop(&mut self) { - unsafe { release(self.state) } - } - } - - let state = unsafe { acquire() }; - let _guard = Guard { state }; - - unsafe { f(CriticalSection::new()) } -} - -/// Methods required for a critical section implementation. -/// -/// This trait is not intended to be used except when implementing a critical section. -/// -/// # Safety -/// -/// Implementations must uphold the contract specified in [`crate::acquire`] and [`crate::release`]. -pub unsafe trait Impl { - /// Acquire the critical section. - /// - /// # Safety - /// - /// Callers must uphold the contract specified in [`crate::acquire`] and [`crate::release`]. - unsafe fn acquire() -> RawRestoreState; - - /// Release the critical section. - /// - /// # Safety - /// - /// Callers must uphold the contract specified in [`crate::acquire`] and [`crate::release`]. - unsafe fn release(restore_state: RawRestoreState); -} - -/// Set the critical section implementation. -/// -/// # Example -/// -/// ``` -/// # #[cfg(not(feature = "std"))] // needed for `cargo test --features std` -/// # mod no_std { -/// use critical_section::RawRestoreState; -/// -/// struct MyCriticalSection; -/// critical_section::set_impl!(MyCriticalSection); -/// -/// unsafe impl critical_section::Impl for MyCriticalSection { -/// unsafe fn acquire() -> RawRestoreState { -/// // ... -/// } -/// -/// unsafe fn release(restore_state: RawRestoreState) { -/// // ... -/// } -/// } -/// # } -#[macro_export] -macro_rules! set_impl { - ($t: ty) => { - #[no_mangle] - unsafe fn _critical_section_1_0_acquire() -> $crate::RawRestoreState { - <$t as $crate::Impl>::acquire() - } - #[no_mangle] - unsafe fn _critical_section_1_0_release(restore_state: $crate::RawRestoreState) { - <$t as $crate::Impl>::release(restore_state) - } - }; -} diff --git a/third-party/vendor/critical-section/src/mutex.rs b/third-party/vendor/critical-section/src/mutex.rs deleted file mode 100644 index c9ea6ff1..00000000 --- a/third-party/vendor/critical-section/src/mutex.rs +++ /dev/null @@ -1,200 +0,0 @@ -use super::CriticalSection; -use core::cell::{Ref, RefCell, RefMut, UnsafeCell}; - -/// A mutex based on critical sections. -/// -/// # Example -/// -/// ```no_run -/// # use critical_section::Mutex; -/// # use std::cell::Cell; -/// -/// static FOO: Mutex> = Mutex::new(Cell::new(42)); -/// -/// fn main() { -/// critical_section::with(|cs| { -/// FOO.borrow(cs).set(43); -/// }); -/// } -/// -/// fn interrupt_handler() { -/// let _x = critical_section::with(|cs| FOO.borrow(cs).get()); -/// } -/// ``` -/// -/// -/// # Design -/// -/// [`std::sync::Mutex`] has two purposes. It converts types that are [`Send`] -/// but not [`Sync`] into types that are both; and it provides -/// [interior mutability]. `critical_section::Mutex`, on the other hand, only adds -/// `Sync`. It does *not* provide interior mutability. -/// -/// This was a conscious design choice. It is possible to create multiple -/// [`CriticalSection`] tokens, either by nesting critical sections or `Copy`ing -/// an existing token. As a result, it would not be sound for [`Mutex::borrow`] -/// to return `&mut T`, because there would be nothing to prevent calling -/// `borrow` multiple times to create aliased `&mut T` references. -/// -/// The solution is to include a runtime check to ensure that each resource is -/// borrowed only once. This is what `std::sync::Mutex` does. However, this is -/// a runtime cost that may not be required in all circumstances. For instance, -/// `Mutex>` never needs to create `&mut T` or equivalent. -/// -/// If `&mut T` is needed, the simplest solution is to use `Mutex>`, -/// which is the closest analogy to `std::sync::Mutex`. [`RefCell`] inserts the -/// exact runtime check necessary to guarantee that the `&mut T` reference is -/// unique. -/// -/// To reduce verbosity when using `Mutex>`, we reimplement some of -/// `RefCell`'s methods on it directly. -/// -/// ```no_run -/// # use critical_section::Mutex; -/// # use std::cell::RefCell; -/// -/// static FOO: Mutex> = Mutex::new(RefCell::new(42)); -/// -/// fn main() { -/// critical_section::with(|cs| { -/// // Instead of calling this -/// let _ = FOO.borrow(cs).take(); -/// // Call this -/// let _ = FOO.take(cs); -/// // `RefCell::borrow` and `RefCell::borrow_mut` are renamed to -/// // `borrow_ref` and `borrow_ref_mut` to avoid name collisions -/// let _: &mut i32 = &mut *FOO.borrow_ref_mut(cs); -/// }) -/// } -/// ``` -/// -/// [`std::sync::Mutex`]: https://doc.rust-lang.org/std/sync/struct.Mutex.html -/// [interior mutability]: https://doc.rust-lang.org/reference/interior-mutability.html -#[derive(Debug)] -pub struct Mutex { - inner: UnsafeCell, -} - -impl Mutex { - /// Creates a new mutex. - #[inline] - pub const fn new(value: T) -> Self { - Mutex { - inner: UnsafeCell::new(value), - } - } - - /// Gets a mutable reference to the contained value when the mutex is already uniquely borrowed. - /// - /// This does not require locking or a critical section since it takes `&mut self`, which - /// guarantees unique ownership already. Care must be taken when using this method to - /// **unsafely** access `static mut` variables, appropriate fences must be used to prevent - /// unwanted optimizations. - #[inline] - pub fn get_mut(&mut self) -> &mut T { - unsafe { &mut *self.inner.get() } - } - - /// Unwraps the contained value, consuming the mutex. - #[inline] - pub fn into_inner(self) -> T { - self.inner.into_inner() - } - - /// Borrows the data for the duration of the critical section. - #[inline] - pub fn borrow<'cs>(&'cs self, _cs: CriticalSection<'cs>) -> &'cs T { - unsafe { &*self.inner.get() } - } -} - -impl Mutex> { - /// Borrow the data and call [`RefCell::replace`] - /// - /// This is equivalent to `self.borrow(cs).replace(t)` - /// - /// # Panics - /// - /// This call could panic. See the documentation for [`RefCell::replace`] - /// for more details. - #[inline] - #[track_caller] - pub fn replace<'cs>(&'cs self, cs: CriticalSection<'cs>, t: T) -> T { - self.borrow(cs).replace(t) - } - - /// Borrow the data and call [`RefCell::replace_with`] - /// - /// This is equivalent to `self.borrow(cs).replace_with(f)` - /// - /// # Panics - /// - /// This call could panic. See the documentation for - /// [`RefCell::replace_with`] for more details. - #[inline] - #[track_caller] - pub fn replace_with<'cs, F>(&'cs self, cs: CriticalSection<'cs>, f: F) -> T - where - F: FnOnce(&mut T) -> T, - { - self.borrow(cs).replace_with(f) - } - - /// Borrow the data and call [`RefCell::borrow`] - /// - /// This is equivalent to `self.borrow(cs).borrow()` - /// - /// # Panics - /// - /// This call could panic. See the documentation for [`RefCell::borrow`] - /// for more details. - #[inline] - #[track_caller] - pub fn borrow_ref<'cs>(&'cs self, cs: CriticalSection<'cs>) -> Ref<'cs, T> { - self.borrow(cs).borrow() - } - - /// Borrow the data and call [`RefCell::borrow_mut`] - /// - /// This is equivalent to `self.borrow(cs).borrow_mut()` - /// - /// # Panics - /// - /// This call could panic. See the documentation for [`RefCell::borrow_mut`] - /// for more details. - #[inline] - #[track_caller] - pub fn borrow_ref_mut<'cs>(&'cs self, cs: CriticalSection<'cs>) -> RefMut<'cs, T> { - self.borrow(cs).borrow_mut() - } -} - -impl Mutex> { - /// Borrow the data and call [`RefCell::take`] - /// - /// This is equivalent to `self.borrow(cs).take()` - /// - /// # Panics - /// - /// This call could panic. See the documentation for [`RefCell::take`] - /// for more details. - #[inline] - #[track_caller] - pub fn take<'cs>(&'cs self, cs: CriticalSection<'cs>) -> T { - self.borrow(cs).take() - } -} - -// NOTE A `Mutex` can be used as a channel so the protected data must be `Send` -// to prevent sending non-Sendable stuff (e.g. access tokens) across different -// threads. -unsafe impl Sync for Mutex where T: Send {} - -/// ``` compile_fail -/// fn bad(cs: critical_section::CriticalSection) -> &u32 { -/// let x = critical_section::Mutex::new(42u32); -/// x.borrow(cs) -/// } -/// ``` -#[cfg(doctest)] -const BorrowMustNotOutliveMutexTest: () = (); diff --git a/third-party/vendor/critical-section/src/std.rs b/third-party/vendor/critical-section/src/std.rs deleted file mode 100644 index 40df4291..00000000 --- a/third-party/vendor/critical-section/src/std.rs +++ /dev/null @@ -1,80 +0,0 @@ -use std::cell::Cell; -use std::mem::MaybeUninit; -use std::sync::{Mutex, MutexGuard}; - -static GLOBAL_MUTEX: Mutex<()> = Mutex::new(()); - -// This is initialized if a thread has acquired the CS, uninitialized otherwise. -static mut GLOBAL_GUARD: MaybeUninit> = MaybeUninit::uninit(); - -std::thread_local!(static IS_LOCKED: Cell = Cell::new(false)); - -struct StdCriticalSection; -crate::set_impl!(StdCriticalSection); - -unsafe impl crate::Impl for StdCriticalSection { - unsafe fn acquire() -> bool { - // Allow reentrancy by checking thread local state - IS_LOCKED.with(|l| { - if l.get() { - // CS already acquired in the current thread. - return true; - } - - // Note: it is fine to set this flag *before* acquiring the mutex because it's thread local. - // No other thread can see its value, there's no potential for races. - // This way, we hold the mutex for slightly less time. - l.set(true); - - // Not acquired in the current thread, acquire it. - let guard = match GLOBAL_MUTEX.lock() { - Ok(guard) => guard, - Err(err) => { - // Ignore poison on the global mutex in case a panic occurred - // while the mutex was held. - err.into_inner() - } - }; - GLOBAL_GUARD.write(guard); - - false - }) - } - - unsafe fn release(nested_cs: bool) { - if !nested_cs { - // SAFETY: As per the acquire/release safety contract, release can only be called - // if the critical section is acquired in the current thread, - // in which case we know the GLOBAL_GUARD is initialized. - GLOBAL_GUARD.assume_init_drop(); - - // Note: it is fine to clear this flag *after* releasing the mutex because it's thread local. - // No other thread can see its value, there's no potential for races. - // This way, we hold the mutex for slightly less time. - IS_LOCKED.with(|l| l.set(false)); - } - } -} - -#[cfg(test)] -mod tests { - use std::thread; - - use crate as critical_section; - - #[cfg(feature = "std")] - #[test] - #[should_panic(expected = "Not a PoisonError!")] - fn reusable_after_panic() { - let _ = thread::spawn(|| { - critical_section::with(|_| { - panic!("Boom!"); - }) - }) - .join(); - - critical_section::with(|_| { - panic!("Not a PoisonError!"); - }) - } -} diff --git a/third-party/vendor/embedded-hal/.cargo-checksum.json b/third-party/vendor/embedded-hal/.cargo-checksum.json deleted file mode 100644 index 154c772b..00000000 --- a/third-party/vendor/embedded-hal/.cargo-checksum.json +++ /dev/null @@ -1 +0,0 @@ -{"files":{"CHANGELOG.md":"d076abc90a94118754e74e065f2b9a8527c9fea300d81bcb1bab1bb5d4cc7b14","Cargo.toml":"2e98e7e78b70c2986e1a2ef2593b7d85cf4cdd198c8d8e872a5b2159f5b1cf16","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"520bc4942f199aad3dfe939c475d67ffbddfea482e41fc4fcad8829b71affc99","README.md":"a8bdcd6b5f60cd0409e638446456b1693d44110f5764e28d149e4ab7d7e58ae0","src/delay.rs":"05960325c846fa20f0fe07a2bba686039ceb05aed6e35e2f7f23c1915b724012","src/digital.rs":"1185f7222cd9a2aec9003c510e2cd810719b6c930d1867c2e4161e747be3c812","src/i2c-shared-bus.svg":"a5fa34e610f9962479f077d57a6117d6a2ae3524012ec5c6275ca81308989c6e","src/i2c.rs":"28d44375daa30acf5488642948bda24a7030738a65f91727b9908cf7dfc3aad0","src/lib.rs":"43ad35769daa4e063d818bc7fb9bee9651548e7583b2fde5e4a104fcef0bfaf9","src/pwm.rs":"8c80846f9afc0b1b162156e4f948124c508dca636212d2db3d2a8fc5a4a66973","src/spi-shared-bus.svg":"8f789f2e90e7800c28e69a9726af0f0f86f11246759f09eb5a1f83321880421b","src/spi.rs":"c04a3f22c679f0f98f6f49e00bbc44dc72d1beba27aa4cc57afd17b2b872a828"},"package":"361a90feb7004eca4019fb28352a9465666b24f840f5c3cddf0ff13920590b89"} \ No newline at end of file diff --git a/third-party/vendor/embedded-hal/CHANGELOG.md b/third-party/vendor/embedded-hal/CHANGELOG.md deleted file mode 100644 index fcbcc41b..00000000 --- a/third-party/vendor/embedded-hal/CHANGELOG.md +++ /dev/null @@ -1,342 +0,0 @@ -# Change Log - -All notable changes to this project will be documented in this file. - -The format is based on [Keep a Changelog](http://keepachangelog.com/) -and this project adheres to [Semantic Versioning](http://semver.org/). - -## [Unreleased] - -No unreleased changes yet. - -## [v1.0.0] - 2023-12-28 - -- gpio: remove `ToggleableOutputPin`, move `toggle()` to `StatefulOutputPin`. - -## [v1.0.0-rc.3] - 2023-12-14 - -- gpio: require `&mut self` in `InputPin` and `StatefulOutputPin`. - -## [v1.0.0-rc.2] - 2023-11-28 - -- Minor document fixes. -- Add #[inline] hints to most of `embedded-hal` functions. -- pwm: rename `get_max_duty_cycle` to `max_duty_cycle`. -- delay: Rename `DelayUs` to `DelayNs` -- delay: Add `DelayNs::delay_ns()` -- delay: Add default impls of `delay_ms` and `delay_us` based on `delay_ns`. -- delay: Make the default impl of `delay_ms` more efficient, it now does less calls to the underlying `delay_ns` (previously `delay_us`). -- spi: Rename `Operation::DelayUs` to `Operation::DelayNs`, with nanosecond precision. - -## [v1.0.0-rc.1] - 2023-08-15 - -- The Minimum Supported Rust Version (MSRV) is now 1.60.0 -- Add optional `defmt` 0.3 support. -- Remove serial traits, the replacement is the `embedded-io` crate. -- Added `+ ?Sized` to all blanket impls. - -## [v1.0.0-alpha.11] - 2023-07-04 - -*** This is (also) an alpha release with breaking changes (sorry) *** - -### Added -- spi: added `Operation::DelayUs(u32)`. - -### Removed -- spi: removed read-only and write-only traits. - -## [v1.0.0-alpha.10] - 2023-04-04 - -*** This is (also) an alpha release with breaking changes (sorry) *** - -### Added -- Added `pwm::SetDutyCycle` trait. - -### Changed -- gpio: add `ErrorKind` enum for consistency with other traits and for future extensibility. No kinds are defined for now. -- delay: make infallible. -- i2c: remove `_iter()` methods. -- i2c: add default implementations for all methods based on `transaction()`. -- i2c: document guidelines for shared bus usage. -- spi: SpiDevice transaction now takes an operation slice instead of a closure - -## [v1.0.0-alpha.9] - 2022-09-28 - -*** This is (also) an alpha release with breaking changes (sorry) *** - -### Changed -- The `embedded-hal` crate now contains blocking traits only. Import paths no longer contain `::blocking`. - -### Added -- Implement `PartialOrd`, `Ord`, `Hash` for `can::StandardId`, `can::ExtendedId` and `can::Id` according to CAN bus arbitration rules -- Implement `Eq` for `i2c::Operation` -- Implement `PartialOrd`, `Ord`, `Hash` for `can::StandardId`, `can::ExtendedId` and `can::Id` according to CAN bus arbitration rules. - -### Fixed -- Fixed documentation for `wait_for_rising_edge`. - -### Removed -- `digital::blocking::IoPin` traits. See: [#340], [#397]. -- `nb` traits are now available in a separate [`embedded-hal-nb`] crate. -- `spi::blocking::ExclusiveDevice` and `spi::blocking::ExclusiveDeviceError`. These have been moved to a separate [`embedded-hal-bus`] crate. -- Moved CAN traits to a separate [`embedded-can`] crate. - -[`embedded-can`]: https://crates.io/crates/embedded-can -[`embedded-hal-nb`]: https://crates.io/crates/embedded-hal-nb -[`embedded-hal-bus`]: https://crates.io/crates/embedded-hal-bus -[#340]: https://github.com/rust-embedded/embedded-hal/issues/340 -[#397]: https://github.com/rust-embedded/embedded-hal/issues/397 - -## [v1.0.0-alpha.8] - 2022-04-15 - -*** This is (also) an alpha release with breaking changes (sorry) *** - -### Changed -- The Minimum Supported Rust Version (MSRV) is now 1.59.0 -- `spi`: unify all traits into `SpiReadBus`, `SpiWriteBus` and `SpiBus` (read-write). -- `spi`: Add `SpiDevice` trait to represent a single device in a (possibly shared) bus, with managed chip-select (CS) pin. -- `spi`: Clarify that implementations are allowed to return before operations are finished, add `flush` to wait until finished. - -### Removed -- ADC traits: `adc::nb::OneShot` and `adc::nb::Channel`. - -## [v1.0.0-alpha.7] - 2022-02-09 - -*** This is (also) an alpha release with breaking changes (sorry) *** - -### Added -- `Error` traits for CAN, SPI, I2C and Serial are implemented for `Infallible`. - -### Fixed -- Fixed blanket impl of `DelayUs` not covering the `delay_ms` method. - -### Changed -- `spi`: traits now enforce all impls on the same struct (e.g. `Transfer` and `Write`) have the same `Error` type. -- `digital`: traits now enforce all impls on the same struct have the same `Error` type. -- `serial`: traits now enforce all impls on the same struct have the same `Error` type. -- `i2c`: traits now enforce all impls on the same struct have the same `Error` type. -- `i2c`: unify all traits into a single `I2c` trait. - -### Removed -- Traits with unconstrained associated types and their modules (See: [#324], [#354]): - - `capture::Capture` - - `pwm::Pwm` - - `pwm::PwmPin` - - `qei::Qei` - - `timer::Cancel` - - `timer::CountDown` - - `timer::Periodic` - - `watchdog::Disable` - - `watchdog::Enable` - - `watchdog::Watchdog` - - -[#324]: https://github.com/rust-embedded/embedded-hal/pull/324/ -[#354]: https://github.com/rust-embedded/embedded-hal/pull/354 - -## [v1.0.0-alpha.6] - 2021-11-19 - -*** This is (also) an alpha release with breaking changes (sorry) *** - -### Changed -- Use `u8` as default SPI as Serial Word type -- The Minimum Supported Rust Version (MSRV) is now 1.46.0 -- Require all SPI and Serial word types to be `Copy`. - -### Added -- Added `Can` Controller Area Network traits. -- `Error` traits for SPI, I2C and Serial traits. The error types used in those must - implement these `Error` traits, which implies providing a conversion to a common - set of error kinds. Generic drivers using these interfaces can then convert the errors - to this common set to act upon them. - -### Removed -- Removed `DelayMs` in favor of `DelayUs` with `u32` as type for clarity. - -## [v1.0.0-alpha.5] - 2021-09-11 - -*** This is (also) an alpha release with breaking changes (sorry) *** - -### Added -- Added `IoPin` trait for pins that can change between being inputs or outputs - dynamically. -- Added `Debug` to all spi mode types. -- Add impls of all traits for references (`&T` or `&mut T` depending on the trait) when `T` implements the trait. -- SPI: Added blocking `Read` trait and `Read` transactional operation -- SPI: Added blocking `Transfer` trait with separate buffers (single-buffer `Transfer` has been renamed `TransferInplace`) - -### Changed -- Swap PWM channel arguments to references -- All trait methods have been renamed to remove the `try_` prefix (i.e. `try_send` -> `send`) for consistency. -- Moved all traits into two submodules for each feature depending on the execution model: `blocking` and `nb` (non-blocking). For example, the spi traits can now be found under `embedded_hal::spi::blocking` or `embedded_hal::spi::nb`. -- Execution-model-independent definitions have been moved into the feature module. For example, SPI `Phase` is now defined in `embedded_hal::spi::Phase`. For convenience, these definitions are reexported in both of its blocking and non-blocking submodules. -- Re-export `nb::{block!, Error, Result}` to avoid version mismatches. These should be used instead of - importing the `nb` crate directly in dependent crates. -- `blocking::Serial`: renamed `bwrite_all` to `write`, `bflush` to `flush. -- Removed `prelude` to avoid method name conflicts between different flavors (blocking, nb) of the same trait. Traits must now be manually imported. -- Removed the various `Default` marker traits. -- Removed `&[W]` returned slice in `spi::blocking::Transfer`. -- Require all associated error types to implement `core::fmt::Debug`. - -### Removed -- Removed random number generation (`rng`) traits in favor of [rand_core](https://crates.io/crates/rand_core). - -## [v1.0.0-alpha.4] - 2020-11-11 - -### Fixed -- Support for I2C addressing modes in `Transactional` I2C traits. - -## [v1.0.0-alpha.3] - 2020-11-04 - -### Added -- `Transactional` SPI interface for executing groups of SPI transactions. -- `Transactional` I2C interface for executing groups of I2C transactions. - - -## [v1.0.0-alpha.2] - 2020-10-16 - -*** This is (also) an alpha release with breaking changes (sorry) *** - -### Added -- 10-bit addressing mode for I2C traits. -- `try_set_state` method for `OutputPin` using an input `PinState` value. - -### Changed - -- I2C addressing modes are now selected via an `AddressMode` type parameter. - The trait features implementations for marker types `SevenBitAddress` and - `TenBitAddress`. `SevenBitAddress` is the default mode so this is not a - breaking change. -- The method `try_write` from the trait `blocking::i2c::WriteIter` trait - has been renamed `try_write_iter` for consistency. -- Updated `nb` dependency to version `1`. -- The watchdog API now uses move semantics. See [PR](https://github.com/rust-embedded/embedded-hal/pull/222). -- The ADC `Channel` trait now uses a stateful method to get the IDs. - -## [v1.0.0-alpha.1] - 2020-06-16 - -*** This is an alpha release with breaking changes (sorry) *** - -### Added -- A nonblocking trait for interfacing with random number generation hardware. - -### Changed -- All traits have been marked as proven (`unproven` feature has been removed). -- All trait methods have been made fallible. -- All trait methods have been renamed `try_*` (i.e. `try_send`) for consistency. -- The `Capture`, `Pwm`, `PwmPin` and `Qei` traits have been moved into their own - `capture`, `pwm` and `qei` modules for consistency. -- Void has been replaced with `core::convert::Infallible` which should be used - in trait implementations where methods cannot fail. -- A new [process](https://github.com/rust-embedded/embedded-hal#how-to-add-a-new-trait) - has been adopted for the addition of traits to the embedded-hal. -- The ADC `Channel` trait now uses a constant to represent the IDs. -- The minimum supported Rust version is 1.35 due to [this issue](https://github.com/rust-lang/rust/issues/54973). - -## [v0.2.3] - 2019-05-09 - -### Added -- A new version of the digital `OutputPin`, `StatefulOutputPin`, `ToggleableOutputPin` - and `InputPin` traits has been added under `digital::v2`. These traits are now - fallible and their methods now return a `Result` type as setting an output pin - and reading an input pin could potentially fail. - See [here](https://github.com/rust-embedded/embedded-hal/issues/95) for more info. -- Compatibility shims between `digital::v1` and `digital::v2` traits allowing v1 traits - to be implicitly promoted to v2, and for v2 traits to be explicitly cast to v1 wrappers. - -### Changed -- The current versions of the `OutputPin`, `StatefulOutputPin`, `ToggleableOutputPin` - and `InputPin` traits have been marked as deprecated. Please use the new versions - included in `digital::v2`. - See [here](https://github.com/rust-embedded/embedded-hal/issues/95) for more info. - - -## [v0.2.2] - 2018-11-03 - -### Added - -- Added the Rust Code of Conduct to this repository -- The first ADC-related trait. This is a simple trait for one-shot conversions. -- Iterator-based blocking write and write+read traits have been added to I2C and SPI. -- New helper constants for SPI modes. -- A new trait for a cancellable countdown. -- New traits for watchdog timer management, including startup, feeding, and stopping. - -### Changed -- Updated docs to clarify I2C address bit widths and expectations. - - -## [v0.2.1] - 2018-05-14 - -### Changed - -- Auto-generated documentation (docs.rs) now includes the unproven traits. - -## [v0.2.0] - 2018-05-12 - -### Added - -- A `ToggeableOutputPin` trait has been added. This trait contains a single method: `toggle` that - can be used to toggle the state of a push-pull pin. - -### Changed - -- [breaking-change] The signature of `CountDown.wait` changed; it now returns `nb::Result<(), - Void>`. Where [`Void`] is the stable alternative to the never type, `!`, provided by the stable - [`void`] crate. Implementations of the `CountDown` trait will have to be updated to use the new - signature. With this change this crate compiles on the stable and beta channels. - -[`Void`]: https://docs.rs/void/1.0.2/void/enum.Void.html -[`void`]: https://crates.io/crates/void - -- [breaking-change] the `OutputPin.is_{low,high}` methods have been moved into its own trait - `StatefulOutputPin` and renamed to `is_set_{low,high}`. - -- It has been clarified in the documentation that `OutputPin` must be implemented for push-pull - output pins (and e.g. not for open drain output pins). - -## [v0.1.3] - 2018-05-14 - -### Changed - -- Re-export most / unchanged traits from embedded-hal v0.2.x to allow interoperation between HAL - implementations and drivers that are using different minor versions. - -## [v0.1.2] - 2018-02-14 - -### Added - -- Unproven `blocking::serial::*` traits - -## [v0.1.1] - 2018-02-06 - -### Added - -- Unproven `digital::InputPin` trait - -## v0.1.0 - 2018-01-16 - -Initial release - -[Unreleased]: https://github.com/rust-embedded/embedded-hal/compare/v1.0.0...HEAD -[v1.0.0]: https://github.com/rust-embedded/embedded-hal/compare/v1.0.0-rc.3...v1.0.0 -[v1.0.0-rc.3]: https://github.com/rust-embedded/embedded-hal/compare/v1.0.0-rc.2...v1.0.0-rc.3 -[v1.0.0-rc.2]: https://github.com/rust-embedded/embedded-hal/compare/v1.0.0-rc.1...v1.0.0-rc.2 -[v1.0.0-rc.1]: https://github.com/rust-embedded/embedded-hal/compare/v1.0.0-alpha.11...v1.0.0-rc.1 -[v1.0.0-alpha.11]: https://github.com/rust-embedded/embedded-hal/compare/v1.0.0-alpha.10...v1.0.0-alpha.11 -[v1.0.0-alpha.10]: https://github.com/rust-embedded/embedded-hal/compare/v1.0.0-alpha.9...v1.0.0-alpha.10 -[v1.0.0-alpha.9]: https://github.com/rust-embedded/embedded-hal/compare/v1.0.0-alpha.8...v1.0.0-alpha.9 -[v1.0.0-alpha.8]: https://github.com/rust-embedded/embedded-hal/compare/v1.0.0-alpha.7...v1.0.0-alpha.8 -[v1.0.0-alpha.7]: https://github.com/rust-embedded/embedded-hal/compare/v1.0.0-alpha.6...v1.0.0-alpha.7 -[v1.0.0-alpha.6]: https://github.com/rust-embedded/embedded-hal/compare/v1.0.0-alpha.5...v1.0.0-alpha.6 -[v1.0.0-alpha.5]: https://github.com/rust-embedded/embedded-hal/compare/v1.0.0-alpha.4...v1.0.0-alpha.5 -[v1.0.0-alpha.4]: https://github.com/rust-embedded/embedded-hal/compare/v1.0.0-alpha.3...v1.0.0-alpha.4 -[v1.0.0-alpha.3]: https://github.com/rust-embedded/embedded-hal/compare/v1.0.0-alpha.2...v1.0.0-alpha.3 -[v1.0.0-alpha.2]: https://github.com/rust-embedded/embedded-hal/compare/v1.0.0-alpha.1...v1.0.0-alpha.2 -[v1.0.0-alpha.1]: https://github.com/rust-embedded/embedded-hal/compare/v0.2.3...v1.0.0-alpha.1 -[v0.2.3]: https://github.com/rust-embedded/embedded-hal/compare/v0.2.2...v0.2.3 -[v0.2.2]: https://github.com/rust-embedded/embedded-hal/compare/v0.2.1...v0.2.2 -[v0.2.1]: https://github.com/rust-embedded/embedded-hal/compare/v0.2.0...v0.2.1 -[v0.2.0]: https://github.com/rust-embedded/embedded-hal/compare/v0.1.2...v0.2.0 -[v0.1.2]: https://github.com/rust-embedded/embedded-hal/compare/v0.1.1...v0.1.2 -[v0.1.1]: https://github.com/rust-embedded/embedded-hal/compare/v0.1.0...v0.1.1 diff --git a/third-party/vendor/embedded-hal/Cargo.toml b/third-party/vendor/embedded-hal/Cargo.toml deleted file mode 100644 index 59423df5..00000000 --- a/third-party/vendor/embedded-hal/Cargo.toml +++ /dev/null @@ -1,44 +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 are reading this file be aware that the original Cargo.toml -# will likely look very different (and much more reasonable). -# See Cargo.toml.orig for the original contents. - -[package] -edition = "2021" -rust-version = "1.60" -name = "embedded-hal" -version = "1.0.0" -authors = [ - "The Embedded HAL Team ", - "Jorge Aparicio ", - "Jonathan 'theJPster' Pallant ", -] -description = " A Hardware Abstraction Layer (HAL) for embedded systems " -documentation = "https://docs.rs/embedded-hal" -readme = "README.md" -keywords = [ - "hal", - "IO", -] -categories = [ - "asynchronous", - "embedded", - "hardware-support", - "no-std", -] -license = "MIT OR Apache-2.0" -repository = "https://github.com/rust-embedded/embedded-hal" - -[dependencies.defmt-03] -version = "0.3" -optional = true -package = "defmt" - -[features] -defmt-03 = ["dep:defmt-03"] diff --git a/third-party/vendor/embedded-hal/LICENSE-APACHE b/third-party/vendor/embedded-hal/LICENSE-APACHE deleted file mode 100644 index 16fe87b0..00000000 --- a/third-party/vendor/embedded-hal/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. diff --git a/third-party/vendor/embedded-hal/LICENSE-MIT b/third-party/vendor/embedded-hal/LICENSE-MIT deleted file mode 100644 index 52cb453f..00000000 --- a/third-party/vendor/embedded-hal/LICENSE-MIT +++ /dev/null @@ -1,25 +0,0 @@ -Copyright (c) 2017-2018 Jorge Aparicio - -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. diff --git a/third-party/vendor/embedded-hal/README.md b/third-party/vendor/embedded-hal/README.md deleted file mode 100644 index 79667661..00000000 --- a/third-party/vendor/embedded-hal/README.md +++ /dev/null @@ -1,106 +0,0 @@ -[![crates.io](https://img.shields.io/crates/d/embedded-hal.svg)](https://crates.io/crates/embedded-hal) -[![crates.io](https://img.shields.io/crates/v/embedded-hal.svg)](https://crates.io/crates/embedded-hal) -[![Documentation](https://docs.rs/embedded-hal/badge.svg)](https://docs.rs/embedded-hal) -![Minimum Supported Rust Version](https://img.shields.io/badge/rustc-1.60+-blue.svg) - -# `embedded-hal` - -> A Hardware Abstraction Layer (HAL) for embedded systems - -This project is developed and maintained by the [HAL team](https://github.com/rust-embedded/wg#the-hal-team). - -## Companion crates - -The main `embedded-hal` crate contains only blocking traits, where the operation is done -synchronously before returning. Check out the following crates, which contain versions -of the traits for other execution models: - -- [`embedded-hal-async`](https://docs.rs/embedded-hal-async): async/await-based. -- [`embedded-hal-nb`](https://docs.rs/embedded-hal-nb): polling-based, using the `nb` crate. - -The [`embedded-hal-bus`](https://docs.rs/embedded-hal-bus) crate provides utilities for sharing -SPI and I2C buses. - -Additionally, more domain-specific traits are available in separate crates: -- [`embedded-can`](https://docs.rs/embedded-can): Controller Area Network (CAN) -- [`embedded-io`](https://docs.rs/embedded-io): I/O byte streams (like `std::io`, but `no-std`-compatible). - -## Serial/UART traits - -There is no serial traits in `embedded-hal`. Instead, use [`embedded-io`](https://crates.io/crates/embedded-io). -A serial port is essentially a byte-oriented stream, and that's what `embedded-io` models. Sharing the traits -with all byte streams has some advantages. For example, it allows generic code providing a command-line interface -or a console to operate either on hardware serial ports or on virtual ones like Telnet or USB CDC-ACM. - -## Design goals - -The HAL - -- Must *erase* device specific details. Neither register, register blocks, nor magic values should -appear in the API. - -- Must be generic *within* a device and *across* devices. The API to use a serial interface must -be the same regardless of whether the implementation uses the USART1 or UART4 peripheral of a -device or the UART0 peripheral of another device. - -- Where possible must *not* be tied to a specific asynchronous model. The API should be usable -in blocking mode, with the `futures` model, with an async/await model or with a callback model. -(cf. the [`nb`](https://docs.rs/nb) crate) - -- Must be minimal, and thus easy to implement and zero cost, yet highly composable. People that -want higher level abstraction should *prefer to use this HAL* rather than *re-implement* -register manipulation code. - -- Serve as a foundation for building an ecosystem of platform-agnostic drivers. Here driver -means a library crate that lets a target platform interface an external device like a digital -sensor or a wireless transceiver. The advantage of this system is that by writing the driver as -a generic library on top of `embedded-hal` driver authors can support any number of target -platforms (e.g. Cortex-M microcontrollers, AVR microcontrollers, embedded Linux, etc.). The -advantage for application developers is that by adopting `embedded-hal` they can unlock all -these drivers for their platform. - -- Trait methods must be fallible so that they can be used in any possible situation. -Nevertheless, HAL implementations can additionally provide infallible versions of the same methods -if they can never fail in their platform. This way, generic code can use the fallible abstractions -provided here but platform-specific code can avoid fallibility-related boilerplate if possible. - -## Out of scope - -- Initialization and configuration stuff like "ensure this serial interface and that SPI -interface are not using the same pins". The HAL will focus on *doing I/O*. - -## Platform agnostic drivers - -You can find platform-agnostic drivers built on top of `embedded-hal` on crates.io by [searching -for the *embedded-hal* keyword](https://crates.io/keywords/embedded-hal). - -If you are writing a platform-agnostic driver yourself you are highly encouraged to [add the -embedded-hal keyword](https://doc.rust-lang.org/cargo/reference/manifest.html#package-metadata) -to your crate before publishing it! - -## Optional Cargo features - -- **`defmt-03`**: Derive `defmt::Format` from `defmt` 0.3 for enums and structs. - -## Minimum Supported Rust Version (MSRV) - -This crate is guaranteed to compile on stable Rust 1.60 and up. It *might* -compile with older versions but that may change in any new patch release. - -See [here](../docs/msrv.md) for details on how the MSRV may be upgraded. - -## License - -Licensed under either of - -- Apache License, Version 2.0 ([LICENSE-APACHE](LICENSE-APACHE) or - ) -- MIT license ([LICENSE-MIT](LICENSE-MIT) or ) - -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. diff --git a/third-party/vendor/embedded-hal/src/delay.rs b/third-party/vendor/embedded-hal/src/delay.rs deleted file mode 100644 index 01e56375..00000000 --- a/third-party/vendor/embedded-hal/src/delay.rs +++ /dev/null @@ -1,62 +0,0 @@ -//! Delays. - -/// Nanoseconds per microsecond -const NANOS_PER_MICRO: u32 = 1_000; -/// Nanoseconds per millisecond -const NANOS_PER_MILLI: u32 = 1_000_000; - -/// Delay with up to nanosecond precision. -pub trait DelayNs { - /// Pauses execution for at minimum `ns` nanoseconds. Pause can be longer - /// if the implementation requires it due to precision/timing issues. - fn delay_ns(&mut self, ns: u32); - - /// Pauses execution for at minimum `us` microseconds. Pause can be longer - /// if the implementation requires it due to precision/timing issues. - fn delay_us(&mut self, mut us: u32) { - const MAX_MICROS: u32 = u32::MAX / NANOS_PER_MICRO; - - // Avoid potential overflow if micro -> nano conversion is too large - while us > MAX_MICROS { - us -= MAX_MICROS; - self.delay_ns(MAX_MICROS * NANOS_PER_MICRO); - } - - self.delay_ns(us * NANOS_PER_MICRO); - } - - /// Pauses execution for at minimum `ms` milliseconds. Pause can be longer - /// if the implementation requires it due to precision/timing issues. - #[inline] - fn delay_ms(&mut self, mut ms: u32) { - const MAX_MILLIS: u32 = u32::MAX / NANOS_PER_MILLI; - - // Avoid potential overflow if milli -> nano conversion is too large - while ms > MAX_MILLIS { - ms -= MAX_MILLIS; - self.delay_ns(MAX_MILLIS * NANOS_PER_MILLI); - } - - self.delay_ns(ms * NANOS_PER_MILLI); - } -} - -impl DelayNs for &mut T -where - T: DelayNs + ?Sized, -{ - #[inline] - fn delay_ns(&mut self, ns: u32) { - T::delay_ns(self, ns); - } - - #[inline] - fn delay_us(&mut self, us: u32) { - T::delay_us(self, us); - } - - #[inline] - fn delay_ms(&mut self, ms: u32) { - T::delay_ms(self, ms); - } -} diff --git a/third-party/vendor/embedded-hal/src/digital.rs b/third-party/vendor/embedded-hal/src/digital.rs deleted file mode 100644 index afcf0396..00000000 --- a/third-party/vendor/embedded-hal/src/digital.rs +++ /dev/null @@ -1,222 +0,0 @@ -//! Digital I/O. - -use core::{convert::From, ops::Not}; - -#[cfg(feature = "defmt-03")] -use crate::defmt; - -/// Error. -pub trait Error: core::fmt::Debug { - /// Convert error to a generic error kind - /// - /// By using this method, errors freely defined by HAL implementations - /// can be converted to a set of generic errors upon which generic - /// code can act. - fn kind(&self) -> ErrorKind; -} - -impl Error for core::convert::Infallible { - fn kind(&self) -> ErrorKind { - match *self {} - } -} - -/// Error kind. -/// -/// This represents a common set of operation errors. HAL implementations are -/// free to define more specific or additional error types. However, by providing -/// a mapping to these common errors, generic code can still react to them. -#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)] -#[cfg_attr(feature = "defmt-03", derive(defmt::Format))] -#[non_exhaustive] -pub enum ErrorKind { - /// A different error occurred. The original error may contain more information. - Other, -} - -impl Error for ErrorKind { - #[inline] - fn kind(&self) -> ErrorKind { - *self - } -} - -impl core::fmt::Display for ErrorKind { - #[inline] - fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { - match self { - Self::Other => write!( - f, - "A different error occurred. The original error may contain more information" - ), - } - } -} - -/// Error type trait. -/// -/// This just defines the error type, to be used by the other traits. -pub trait ErrorType { - /// Error type - type Error: Error; -} - -impl ErrorType for &T { - type Error = T::Error; -} - -impl ErrorType for &mut T { - type Error = T::Error; -} - -/// Digital output pin state. -/// -/// Conversion from `bool` and logical negation are also implemented -/// for this type. -/// ```rust -/// # use embedded_hal::digital::PinState; -/// let state = PinState::from(false); -/// assert_eq!(state, PinState::Low); -/// assert_eq!(!state, PinState::High); -/// ``` -#[derive(Debug, PartialEq, Eq, Clone, Copy)] -#[cfg_attr(feature = "defmt-03", derive(defmt::Format))] -pub enum PinState { - /// Low pin state. - Low, - /// High pin state. - High, -} - -impl From for PinState { - #[inline] - fn from(value: bool) -> Self { - match value { - false => PinState::Low, - true => PinState::High, - } - } -} - -impl Not for PinState { - type Output = PinState; - - #[inline] - fn not(self) -> Self::Output { - match self { - PinState::High => PinState::Low, - PinState::Low => PinState::High, - } - } -} - -impl From for bool { - #[inline] - fn from(value: PinState) -> bool { - match value { - PinState::Low => false, - PinState::High => true, - } - } -} - -/// Single digital push-pull output pin. -pub trait OutputPin: ErrorType { - /// Drives the pin low. - /// - /// *NOTE* the actual electrical state of the pin may not actually be low, e.g. due to external - /// electrical sources. - fn set_low(&mut self) -> Result<(), Self::Error>; - - /// Drives the pin high. - /// - /// *NOTE* the actual electrical state of the pin may not actually be high, e.g. due to external - /// electrical sources. - fn set_high(&mut self) -> Result<(), Self::Error>; - - /// Drives the pin high or low depending on the provided value. - /// - /// *NOTE* the actual electrical state of the pin may not actually be high or low, e.g. due to external - /// electrical sources. - #[inline] - fn set_state(&mut self, state: PinState) -> Result<(), Self::Error> { - match state { - PinState::Low => self.set_low(), - PinState::High => self.set_high(), - } - } -} - -impl OutputPin for &mut T { - #[inline] - fn set_low(&mut self) -> Result<(), Self::Error> { - T::set_low(self) - } - - #[inline] - fn set_high(&mut self) -> Result<(), Self::Error> { - T::set_high(self) - } - - #[inline] - fn set_state(&mut self, state: PinState) -> Result<(), Self::Error> { - T::set_state(self, state) - } -} - -/// Push-pull output pin that can read its output state. -pub trait StatefulOutputPin: OutputPin { - /// Is the pin in drive high mode? - /// - /// *NOTE* this does *not* read the electrical state of the pin. - fn is_set_high(&mut self) -> Result; - - /// Is the pin in drive low mode? - /// - /// *NOTE* this does *not* read the electrical state of the pin. - fn is_set_low(&mut self) -> Result; - - /// Toggle pin output. - fn toggle(&mut self) -> Result<(), Self::Error> { - let was_low: bool = self.is_set_low()?; - self.set_state(PinState::from(was_low)) - } -} - -impl StatefulOutputPin for &mut T { - #[inline] - fn is_set_high(&mut self) -> Result { - T::is_set_high(self) - } - - #[inline] - fn is_set_low(&mut self) -> Result { - T::is_set_low(self) - } - - #[inline] - fn toggle(&mut self) -> Result<(), Self::Error> { - T::toggle(self) - } -} - -/// Single digital input pin. -pub trait InputPin: ErrorType { - /// Is the input pin high? - fn is_high(&mut self) -> Result; - - /// Is the input pin low? - fn is_low(&mut self) -> Result; -} - -impl InputPin for &mut T { - #[inline] - fn is_high(&mut self) -> Result { - T::is_high(self) - } - - #[inline] - fn is_low(&mut self) -> Result { - T::is_low(self) - } -} diff --git a/third-party/vendor/embedded-hal/src/i2c-shared-bus.svg b/third-party/vendor/embedded-hal/src/i2c-shared-bus.svg deleted file mode 100644 index fad8cee6..00000000 --- a/third-party/vendor/embedded-hal/src/i2c-shared-bus.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - -
SDA
SDA
SCL
SCL
MCU
MCU
SDA
SDA
SCL
SCL
I2C DEVICE 1
I2C DEVICE 1
SDA
SDA
SCL
SCL
I2C DEVICE 2
I2C DEVICE 2
Text is not SVG - cannot display
\ No newline at end of file diff --git a/third-party/vendor/embedded-hal/src/i2c.rs b/third-party/vendor/embedded-hal/src/i2c.rs deleted file mode 100644 index 634d5224..00000000 --- a/third-party/vendor/embedded-hal/src/i2c.rs +++ /dev/null @@ -1,432 +0,0 @@ -//! Blocking I2C API. -//! -//! This API supports 7-bit and 10-bit addresses. Traits feature an [`AddressMode`] -//! marker type parameter. Two implementation of the [`AddressMode`] exist: -//! [`SevenBitAddress`] and [`TenBitAddress`]. -//! -//! Through this marker types it is possible to implement each address mode for -//! the traits independently in `embedded-hal` implementations and device drivers -//! can depend only on the mode that they support. -//! -//! Additionally, the I2C 10-bit address mode has been developed to be fully -//! backwards compatible with the 7-bit address mode. This allows for a -//! software-emulated 10-bit addressing implementation if the address mode -//! is not supported by the hardware. -//! -//! Since 7-bit addressing is the mode of the majority of I2C devices, -//! [`SevenBitAddress`] has been set as default mode and thus can be omitted if desired. -//! -//! # Bus sharing -//! -//! I2C allows sharing a single bus between many I2C devices. The SDA and SCL lines are -//! wired in parallel to all devices. When starting a transfer an "address" is sent -//! so that the addressed device can respond and all the others can ignore the transfer. -//! -#![doc = include_str!("i2c-shared-bus.svg")] -//! -//! This bus sharing is common when having multiple I2C devices in the same board, since it uses fewer MCU -//! pins (`2` instead of `2*n`), and fewer MCU I2C peripherals (`1` instead of `n`). -//! -//! This API supports bus sharing natively. Types implementing [`I2c`] are allowed -//! to represent either exclusive or shared access to an I2C bus. HALs typically -//! provide exclusive access implementations. Drivers shouldn't care which -//! kind they receive, they just do transactions on it and let the -//! underlying implementation share or not. -//! -//! The [`embedded-hal-bus`](https://docs.rs/embedded-hal-bus) crate provides several -//! implementations for sharing I2C buses. You can use them to take an exclusive instance -//! you've received from a HAL and "split" it into multiple shared ones, to instantiate -//! several drivers on the same bus. -//! -//! # Flushing -//! -//! Implementations must flush the transfer, ensuring the bus has returned to an idle state before returning. -//! No pipelining is allowed. Users must be able to shut down the I2C peripheral immediately after a transfer -//! returns, without any risk of e.g. cutting short a stop condition. -//! -//! (Implementations must wait until the last ACK bit to report it as an error anyway. Therefore pipelining would only -//! yield very small time savings, not worth the complexity) -//! -//! # For driver authors -//! -//! Drivers can select the adequate address length with `I2c` or `I2c` depending -//! on the target device. If it can use either, the driver can -//! be generic over the address kind as well, though this is rare. -//! -//! Drivers should take the `I2c` instance as an argument to `new()`, and store it in their -//! struct. They **should not** take `&mut I2c`, the trait has a blanket impl for all `&mut T` -//! so taking just `I2c` ensures the user can still pass a `&mut`, but is not forced to. -//! -//! Drivers **should not** try to enable bus sharing by taking `&mut I2c` at every method. -//! This is much less ergonomic than owning the `I2c`, which still allows the user to pass an -//! implementation that does sharing behind the scenes -//! (from [`embedded-hal-bus`](https://docs.rs/embedded-hal-bus), or others). -//! -//! ## Device driver compatible only with 7-bit addresses -//! -//! For demonstration purposes the address mode parameter has been omitted in this example. -//! -//! ``` -//! use embedded_hal::i2c::{I2c, Error}; -//! -//! const ADDR: u8 = 0x15; -//! # const TEMP_REGISTER: u8 = 0x1; -//! pub struct TemperatureSensorDriver { -//! i2c: I2C, -//! } -//! -//! impl TemperatureSensorDriver { -//! pub fn new(i2c: I2C) -> Self { -//! Self { i2c } -//! } -//! -//! pub fn read_temperature(&mut self) -> Result { -//! let mut temp = [0]; -//! self.i2c.write_read(ADDR, &[TEMP_REGISTER], &mut temp)?; -//! Ok(temp[0]) -//! } -//! } -//! ``` -//! -//! ## Device driver compatible only with 10-bit addresses -//! -//! ``` -//! use embedded_hal::i2c::{Error, TenBitAddress, I2c}; -//! -//! const ADDR: u16 = 0x158; -//! # const TEMP_REGISTER: u8 = 0x1; -//! pub struct TemperatureSensorDriver { -//! i2c: I2C, -//! } -//! -//! impl> TemperatureSensorDriver { -//! pub fn new(i2c: I2C) -> Self { -//! Self { i2c } -//! } -//! -//! pub fn read_temperature(&mut self) -> Result { -//! let mut temp = [0]; -//! self.i2c.write_read(ADDR, &[TEMP_REGISTER], &mut temp)?; -//! Ok(temp[0]) -//! } -//! } -//! ``` -//! -//! # For HAL authors -//! -//! HALs **should not** include bus sharing mechanisms. They should expose a single type representing -//! exclusive ownership over the bus, and let the user use [`embedded-hal-bus`](https://docs.rs/embedded-hal-bus) -//! if they want to share it. (One exception is if the underlying platform already -//! supports sharing, such as Linux or some RTOSs.) -//! -//! Here is an example of an embedded-hal implementation of the `I2C` trait -//! for both addressing modes. All trait methods have have default implementations in terms of `transaction`. -//! As such, that is the only method that requires implementation in the HAL. -//! -//! ``` -//! use embedded_hal::i2c::{self, SevenBitAddress, TenBitAddress, I2c, Operation}; -//! -//! /// I2C0 hardware peripheral which supports both 7-bit and 10-bit addressing. -//! pub struct I2c0; -//! -//! #[derive(Debug, Copy, Clone, Eq, PartialEq)] -//! pub enum Error { -//! // ... -//! } -//! -//! impl i2c::Error for Error { -//! fn kind(&self) -> i2c::ErrorKind { -//! match *self { -//! // ... -//! } -//! } -//! } -//! -//! impl i2c::ErrorType for I2c0 { -//! type Error = Error; -//! } -//! -//! impl I2c for I2c0 { -//! fn transaction(&mut self, address: u8, operations: &mut [Operation<'_>]) -> Result<(), Self::Error> { -//! // ... -//! # Ok(()) -//! } -//! } -//! -//! impl I2c for I2c0 { -//! fn transaction(&mut self, address: u16, operations: &mut [Operation<'_>]) -> Result<(), Self::Error> { -//! // ... -//! # Ok(()) -//! } -//! } -//! ``` - -use crate::private; - -#[cfg(feature = "defmt-03")] -use crate::defmt; - -/// I2C error. -pub trait Error: core::fmt::Debug { - /// Convert error to a generic I2C error kind. - /// - /// By using this method, I2C errors freely defined by HAL implementations - /// can be converted to a set of generic I2C errors upon which generic - /// code can act. - fn kind(&self) -> ErrorKind; -} - -impl Error for core::convert::Infallible { - #[inline] - fn kind(&self) -> ErrorKind { - match *self {} - } -} - -/// I2C error kind. -/// -/// This represents a common set of I2C operation errors. HAL implementations are -/// free to define more specific or additional error types. However, by providing -/// a mapping to these common I2C errors, generic code can still react to them. -#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)] -#[cfg_attr(feature = "defmt-03", derive(defmt::Format))] -#[non_exhaustive] -pub enum ErrorKind { - /// Bus error occurred. e.g. A START or a STOP condition is detected and is not - /// located after a multiple of 9 SCL clock pulses. - Bus, - /// The arbitration was lost, e.g. electrical problems with the clock signal. - ArbitrationLoss, - /// A bus operation was not acknowledged, e.g. due to the addressed device not - /// being available on the bus or the device not being ready to process requests - /// at the moment. - NoAcknowledge(NoAcknowledgeSource), - /// The peripheral receive buffer was overrun. - Overrun, - /// A different error occurred. The original error may contain more information. - Other, -} - -/// I2C no acknowledge error source. -/// -/// In cases where it is possible, a device should indicate if a no acknowledge -/// response was received to an address versus a no acknowledge to a data byte. -/// Where it is not possible to differentiate, `Unknown` should be indicated. -#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)] -#[cfg_attr(feature = "defmt-03", derive(defmt::Format))] -pub enum NoAcknowledgeSource { - /// The device did not acknowledge its address. The device may be missing. - Address, - /// The device did not acknowledge the data. It may not be ready to process - /// requests at the moment. - Data, - /// Either the device did not acknowledge its address or the data, but it is - /// unknown which. - Unknown, -} - -impl Error for ErrorKind { - #[inline] - fn kind(&self) -> ErrorKind { - *self - } -} - -impl core::fmt::Display for ErrorKind { - #[inline] - fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { - match self { - Self::Bus => write!(f, "Bus error occurred"), - Self::ArbitrationLoss => write!(f, "The arbitration was lost"), - Self::NoAcknowledge(s) => s.fmt(f), - Self::Overrun => write!(f, "The peripheral receive buffer was overrun"), - Self::Other => write!( - f, - "A different error occurred. The original error may contain more information" - ), - } - } -} - -impl core::fmt::Display for NoAcknowledgeSource { - #[inline] - fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { - match self { - Self::Address => write!(f, "The device did not acknowledge its address"), - Self::Data => write!(f, "The device did not acknowledge the data"), - Self::Unknown => write!(f, "The device did not acknowledge its address or the data"), - } - } -} - -/// I2C error type trait. -/// -/// This just defines the error type, to be used by the other traits. -pub trait ErrorType { - /// Error type - type Error: Error; -} - -impl ErrorType for &mut T { - type Error = T::Error; -} - -/// Address mode (7-bit / 10-bit). -/// -/// Note: This trait is sealed and should not be implemented outside of this crate. -pub trait AddressMode: private::Sealed + 'static {} - -/// 7-bit address mode type. -/// -/// Note that 7-bit addresses defined by drivers should be specified in **right-aligned** form, -/// e.g. in the range `0x00..=0x7F`. -/// -/// For example, a device that has the seven bit address of `0b011_0010`, and therefore is addressed on the wire using: -/// -/// * `0b0110010_0` or `0x64` for *writes* -/// * `0b0110010_1` or `0x65` for *reads* -/// -/// Should be specified as `0b0011_0010` or `0x32`, NOT `0x64` or `0x65`. Care should be taken by both HAL and driver -/// crate writers to use this scheme consistently. -pub type SevenBitAddress = u8; - -/// 10-bit address mode type. -pub type TenBitAddress = u16; - -impl AddressMode for SevenBitAddress {} - -impl AddressMode for TenBitAddress {} - -/// I2C operation. -/// -/// Several operations can be combined as part of a transaction. -#[derive(Debug, PartialEq, Eq)] -#[cfg_attr(feature = "defmt-03", derive(defmt::Format))] -pub enum Operation<'a> { - /// Read data into the provided buffer. - Read(&'a mut [u8]), - /// Write data from the provided buffer. - Write(&'a [u8]), -} - -/// Blocking I2C. -pub trait I2c: ErrorType { - /// Reads enough bytes from slave with `address` to fill `read`. - /// - /// # I2C Events (contract) - /// - /// ``` text - /// Master: ST SAD+R MAK MAK ... NMAK SP - /// Slave: SAK B0 B1 ... BN - /// ``` - /// - /// Where - /// - /// - `ST` = start condition - /// - `SAD+R` = slave address followed by bit 1 to indicate reading - /// - `SAK` = slave acknowledge - /// - `Bi` = ith byte of data - /// - `MAK` = master acknowledge - /// - `NMAK` = master no acknowledge - /// - `SP` = stop condition - #[inline] - fn read(&mut self, address: A, read: &mut [u8]) -> Result<(), Self::Error> { - self.transaction(address, &mut [Operation::Read(read)]) - } - - /// Writes bytes to slave with address `address`. - /// - /// # I2C Events (contract) - /// - /// ``` text - /// Master: ST SAD+W B0 B1 ... BN SP - /// Slave: SAK SAK SAK ... SAK - /// ``` - /// - /// Where - /// - /// - `ST` = start condition - /// - `SAD+W` = slave address followed by bit 0 to indicate writing - /// - `SAK` = slave acknowledge - /// - `Bi` = ith byte of data - /// - `SP` = stop condition - #[inline] - fn write(&mut self, address: A, write: &[u8]) -> Result<(), Self::Error> { - self.transaction(address, &mut [Operation::Write(write)]) - } - - /// Writes bytes to slave with address `address` and then reads enough bytes to fill `read` *in a - /// single transaction*. - /// - /// # I2C Events (contract) - /// - /// ``` text - /// Master: ST SAD+W O0 O1 ... OM SR SAD+R MAK MAK ... NMAK SP - /// Slave: SAK SAK SAK ... SAK SAK I0 I1 ... IN - /// ``` - /// - /// Where - /// - /// - `ST` = start condition - /// - `SAD+W` = slave address followed by bit 0 to indicate writing - /// - `SAK` = slave acknowledge - /// - `Oi` = ith outgoing byte of data - /// - `SR` = repeated start condition - /// - `SAD+R` = slave address followed by bit 1 to indicate reading - /// - `Ii` = ith incoming byte of data - /// - `MAK` = master acknowledge - /// - `NMAK` = master no acknowledge - /// - `SP` = stop condition - #[inline] - fn write_read(&mut self, address: A, write: &[u8], read: &mut [u8]) -> Result<(), Self::Error> { - self.transaction( - address, - &mut [Operation::Write(write), Operation::Read(read)], - ) - } - - /// Execute the provided operations on the I2C bus. - /// - /// Transaction contract: - /// - Before executing the first operation an ST is sent automatically. This is followed by SAD+R/W as appropriate. - /// - Data from adjacent operations of the same type are sent after each other without an SP or SR. - /// - Between adjacent operations of a different type an SR and SAD+R/W is sent. - /// - After executing the last operation an SP is sent automatically. - /// - If the last operation is a `Read` the master does not send an acknowledge for the last byte. - /// - /// - `ST` = start condition - /// - `SAD+R/W` = slave address followed by bit 1 to indicate reading or 0 to indicate writing - /// - `SR` = repeated start condition - /// - `SP` = stop condition - fn transaction( - &mut self, - address: A, - operations: &mut [Operation<'_>], - ) -> Result<(), Self::Error>; -} - -impl + ?Sized> I2c for &mut T { - #[inline] - fn read(&mut self, address: A, read: &mut [u8]) -> Result<(), Self::Error> { - T::read(self, address, read) - } - - #[inline] - fn write(&mut self, address: A, write: &[u8]) -> Result<(), Self::Error> { - T::write(self, address, write) - } - - #[inline] - fn write_read(&mut self, address: A, write: &[u8], read: &mut [u8]) -> Result<(), Self::Error> { - T::write_read(self, address, write, read) - } - - #[inline] - fn transaction( - &mut self, - address: A, - operations: &mut [Operation<'_>], - ) -> Result<(), Self::Error> { - T::transaction(self, address, operations) - } -} diff --git a/third-party/vendor/embedded-hal/src/lib.rs b/third-party/vendor/embedded-hal/src/lib.rs deleted file mode 100644 index f5eb76c3..00000000 --- a/third-party/vendor/embedded-hal/src/lib.rs +++ /dev/null @@ -1,21 +0,0 @@ -#![doc = include_str!("../README.md")] -#![warn(missing_docs)] -#![no_std] - -pub mod delay; -pub mod digital; -pub mod i2c; -pub mod pwm; -pub mod spi; - -mod private { - use crate::i2c::{SevenBitAddress, TenBitAddress}; - pub trait Sealed {} - - impl Sealed for SevenBitAddress {} - impl Sealed for TenBitAddress {} -} - -// needed to prevent defmt macros from breaking, since they emit code that does `defmt::blahblah`. -#[cfg(feature = "defmt-03")] -use defmt_03 as defmt; diff --git a/third-party/vendor/embedded-hal/src/pwm.rs b/third-party/vendor/embedded-hal/src/pwm.rs deleted file mode 100644 index 68a94f54..00000000 --- a/third-party/vendor/embedded-hal/src/pwm.rs +++ /dev/null @@ -1,150 +0,0 @@ -//! Pulse Width Modulation (PWM) traits. - -#[cfg(feature = "defmt-03")] -use crate::defmt; - -/// Error -pub trait Error: core::fmt::Debug { - /// Convert error to a generic error kind. - /// - /// By using this method, errors freely defined by HAL implementations - /// can be converted to a set of generic errors upon which generic - /// code can act. - fn kind(&self) -> ErrorKind; -} - -impl Error for core::convert::Infallible { - #[inline] - fn kind(&self) -> ErrorKind { - match *self {} - } -} - -/// Error kind. -/// -/// This represents a common set of operation errors. HAL implementations are -/// free to define more specific or additional error types. However, by providing -/// a mapping to these common errors, generic code can still react to them. -#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)] -#[cfg_attr(feature = "defmt-03", derive(defmt::Format))] -#[non_exhaustive] -pub enum ErrorKind { - /// A different error occurred. The original error may contain more information. - Other, -} - -impl Error for ErrorKind { - #[inline] - fn kind(&self) -> ErrorKind { - *self - } -} - -impl core::fmt::Display for ErrorKind { - #[inline] - fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { - match self { - Self::Other => write!( - f, - "A different error occurred. The original error may contain more information" - ), - } - } -} - -/// Error type trait. -/// -/// This just defines the error type, to be used by the other traits. -pub trait ErrorType { - /// Error type - type Error: Error; -} - -impl ErrorType for &mut T { - type Error = T::Error; -} - -/// Single PWM channel / pin. -pub trait SetDutyCycle: ErrorType { - /// Get the maximum duty cycle value. - /// - /// This value corresponds to a 100% duty cycle. - fn max_duty_cycle(&self) -> u16; - - /// Set the duty cycle to `duty / max_duty`. - /// - /// The caller is responsible for ensuring that the duty cycle value is less than or equal to the maximum duty cycle value, - /// as reported by [`max_duty_cycle`]. - /// - /// [`max_duty_cycle`]: SetDutyCycle::max_duty_cycle - fn set_duty_cycle(&mut self, duty: u16) -> Result<(), Self::Error>; - - /// Set the duty cycle to 0%, or always inactive. - #[inline] - fn set_duty_cycle_fully_off(&mut self) -> Result<(), Self::Error> { - self.set_duty_cycle(0) - } - - /// Set the duty cycle to 100%, or always active. - #[inline] - fn set_duty_cycle_fully_on(&mut self) -> Result<(), Self::Error> { - self.set_duty_cycle(self.max_duty_cycle()) - } - - /// Set the duty cycle to `num / denom`. - /// - /// The caller is responsible for ensuring that `num` is less than or equal to `denom`, - /// and that `denom` is not zero. - #[inline] - fn set_duty_cycle_fraction(&mut self, num: u16, denom: u16) -> Result<(), Self::Error> { - debug_assert!(denom != 0); - debug_assert!(num <= denom); - let duty = u32::from(num) * u32::from(self.max_duty_cycle()) / u32::from(denom); - - // This is safe because we know that `num <= denom`, so `duty <= self.max_duty_cycle()` (u16) - #[allow(clippy::cast_possible_truncation)] - { - self.set_duty_cycle(duty as u16) - } - } - - /// Set the duty cycle to `percent / 100` - /// - /// The caller is responsible for ensuring that `percent` is less than or equal to 100. - #[inline] - fn set_duty_cycle_percent(&mut self, percent: u8) -> Result<(), Self::Error> { - self.set_duty_cycle_fraction(u16::from(percent), 100) - } -} - -impl SetDutyCycle for &mut T { - #[inline] - fn max_duty_cycle(&self) -> u16 { - T::max_duty_cycle(self) - } - - #[inline] - fn set_duty_cycle(&mut self, duty: u16) -> Result<(), Self::Error> { - T::set_duty_cycle(self, duty) - } - - #[inline] - fn set_duty_cycle_fully_off(&mut self) -> Result<(), Self::Error> { - T::set_duty_cycle_fully_off(self) - } - - #[inline] - fn set_duty_cycle_fully_on(&mut self) -> Result<(), Self::Error> { - T::set_duty_cycle_fully_on(self) - } - - #[inline] - fn set_duty_cycle_fraction(&mut self, num: u16, denom: u16) -> Result<(), Self::Error> { - T::set_duty_cycle_fraction(self, num, denom) - } - - #[inline] - fn set_duty_cycle_percent(&mut self, percent: u8) -> Result<(), Self::Error> { - T::set_duty_cycle_percent(self, percent) - } -} diff --git a/third-party/vendor/embedded-hal/src/spi-shared-bus.svg b/third-party/vendor/embedded-hal/src/spi-shared-bus.svg deleted file mode 100644 index 950be629..00000000 --- a/third-party/vendor/embedded-hal/src/spi-shared-bus.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - -
SCK
SCK
MISO
MISO
MOSI
MOSI
CS_1
CS_1
CS_2
CS_2
MCU
MCU
SCK
SCK
MISO
MISO
MOSI
MOSI
CS
CS
SPI DEVICE 1
SPI DEVICE 1
SCK
SCK
MISO
MISO
MOSI
MOSI
CS
CS
SPI DEVICE 2
SPI DEVICE 2
Text is not SVG - cannot display
\ No newline at end of file diff --git a/third-party/vendor/embedded-hal/src/spi.rs b/third-party/vendor/embedded-hal/src/spi.rs deleted file mode 100644 index 508a4a9b..00000000 --- a/third-party/vendor/embedded-hal/src/spi.rs +++ /dev/null @@ -1,506 +0,0 @@ -//! Blocking SPI master mode traits. -//! -//! # Bus vs Device -//! -//! SPI allows sharing a single bus between many SPI devices. The SCK, MOSI and MISO lines are -//! wired in parallel to all the devices, and each device gets a dedicated chip-select (CS) line from the MCU, like this: -//! -#![doc= include_str!("spi-shared-bus.svg")] -//! -//! CS is usually active-low. When CS is high (not asserted), SPI devices ignore all incoming data, and -//! don't drive MISO. When CS is low (asserted), the device is active: reacts to incoming data on MOSI and -//! drives MISO with the response data. By asserting one CS or another, the MCU can choose to which -//! SPI device it "talks" to on the (possibly shared) bus. -//! -//! This bus sharing is common when having multiple SPI devices in the same board, since it uses fewer MCU -//! pins (`n+3` instead of `4*n`), and fewer MCU SPI peripherals (`1` instead of `n`). -//! -//! However, it poses a challenge when building portable drivers for SPI devices. The driver needs to -//! be able to talk to its device on the bus, while not interfering with other drivers talking to other -//! devices. -//! -//! To solve this, `embedded-hal` has two kinds of SPI traits: **SPI bus** and **SPI device**. -//! -//! ## Bus -//! -//! The [`SpiBus`] trait represents **exclusive ownership** over the whole SPI bus. This is usually the entire -//! SPI MCU peripheral, plus the SCK, MOSI and MISO pins. -//! -//! Owning an instance of an SPI bus guarantees exclusive access, this is, we have the guarantee no other -//! piece of code will try to use the bus while we own it. -//! -//! ## Device -//! -//! The [`SpiDevice`] trait represents **ownership over a single SPI device selected by a CS pin** in a (possibly shared) bus. This is typically: -//! -//! - Exclusive ownership of the **CS pin**. -//! - Access to the **underlying SPI bus**. If shared, it'll be behind some kind of lock/mutex. -//! -//! An [`SpiDevice`] allows initiating [transactions](SpiDevice::transaction) against the target device on the bus. A transaction -//! consists of asserting CS, then doing one or more transfers, then deasserting CS. For the entire duration of the transaction, the [`SpiDevice`] -//! implementation will ensure no other transaction can be opened on the same bus. This is the key that allows correct sharing of the bus. -//! -//! # For driver authors -//! -//! When implementing a driver, it's crucial to pick the right trait, to ensure correct operation -//! with maximum interoperability. Here are some guidelines depending on the device you're implementing a driver for: -//! -//! If your device **has a CS pin**, use [`SpiDevice`]. Do not manually -//! manage the CS pin, the [`SpiDevice`] implementation will do it for you. -//! By using [`SpiDevice`], your driver will cooperate nicely with other drivers for other devices in the same shared SPI bus. -//! -//! ``` -//! # use embedded_hal::spi::{SpiBus, SpiDevice, Operation}; -//! pub struct MyDriver { -//! spi: SPI, -//! } -//! -//! impl MyDriver -//! where -//! SPI: SpiDevice, -//! { -//! pub fn new(spi: SPI) -> Self { -//! Self { spi } -//! } -//! -//! pub fn read_foo(&mut self) -> Result<[u8; 2], MyError> { -//! let mut buf = [0; 2]; -//! -//! // `transaction` asserts and deasserts CS for us. No need to do it manually! -//! self.spi.transaction(&mut [ -//! Operation::Write(&[0x90]), -//! Operation::Read(&mut buf), -//! ]).map_err(MyError::Spi)?; -//! -//! Ok(buf) -//! } -//! } -//! -//! #[derive(Copy, Clone, Debug)] -//! enum MyError { -//! Spi(SPI), -//! // Add other errors for your driver here. -//! } -//! ``` -//! -//! If your device **does not have a CS pin**, use [`SpiBus`]. This will ensure -//! your driver has exclusive access to the bus, so no other drivers can interfere. It's not possible to safely share -//! a bus without CS pins. By requiring [`SpiBus`] you disallow sharing, ensuring correct operation. -//! -//! ``` -//! # use embedded_hal::spi::SpiBus; -//! pub struct MyDriver { -//! spi: SPI, -//! } -//! -//! impl MyDriver -//! where -//! SPI: SpiBus, -//! { -//! pub fn new(spi: SPI) -> Self { -//! Self { spi } -//! } -//! -//! pub fn read_foo(&mut self) -> Result<[u8; 2], MyError> { -//! let mut buf = [0; 2]; -//! self.spi.write(&[0x90]).map_err(MyError::Spi)?; -//! self.spi.read(&mut buf).map_err(MyError::Spi)?; -//! Ok(buf) -//! } -//! } -//! -//! #[derive(Copy, Clone, Debug)] -//! enum MyError { -//! Spi(SPI), -//! // Add other errors for your driver here. -//! } -//! ``` -//! -//! If you're (ab)using SPI to **implement other protocols** by bitbanging (WS2812B, onewire, generating arbitrary waveforms...), use [`SpiBus`]. -//! SPI bus sharing doesn't make sense at all in this case. By requiring [`SpiBus`] you disallow sharing, ensuring correct operation. -//! -//! # For HAL authors -//! -//! HALs **must** implement [`SpiBus`]. Users can combine the bus together with the CS pin (which should -//! implement [`OutputPin`](crate::digital::OutputPin)) using HAL-independent [`SpiDevice`] implementations such as the ones in [`embedded-hal-bus`](https://crates.io/crates/embedded-hal-bus). -//! -//! HALs may additionally implement [`SpiDevice`] to **take advantage of hardware CS management**, which may provide some performance -//! benefits. (There's no point in a HAL implementing [`SpiDevice`] if the CS management is software-only, this task is better left to -//! the HAL-independent implementations). -//! -//! HALs **must not** add infrastructure for sharing at the [`SpiBus`] level. User code owning a [`SpiBus`] must have the guarantee -//! of exclusive access. -//! -//! # Flushing -//! -//! To improve performance, [`SpiBus`] implementations are allowed to return before the operation is finished, i.e. when the bus is still not -//! idle. This allows pipelining SPI transfers with CPU work. -//! -//! When calling another method when a previous operation is still in progress, implementations can either wait for the previous operation -//! to finish, or enqueue the new one, but they must not return a "busy" error. Users must be able to do multiple method calls in a row -//! and have them executed "as if" they were done sequentially, without having to check for "busy" errors. -//! -//! When using a [`SpiBus`], call [`flush`](SpiBus::flush) to wait for operations to actually finish. Examples of situations -//! where this is needed are: -//! - To synchronize SPI activity and GPIO activity, for example before deasserting a CS pin. -//! - Before deinitializing the hardware SPI peripheral. -//! -//! When using a [`SpiDevice`], you can still call [`flush`](SpiBus::flush) on the bus within a transaction. -//! It's very rarely needed, because [`transaction`](SpiDevice::transaction) already flushes for you -//! before deasserting CS. For example, you may need it to synchronize with GPIOs other than CS, such as DCX pins -//! sometimes found in SPI displays. -//! -//! For example, for [`write`](SpiBus::write) operations, it is common for hardware SPI peripherals to have a small -//! FIFO buffer, usually 1-4 bytes. Software writes data to the FIFO, and the peripheral sends it on MOSI at its own pace, -//! at the specified SPI frequency. It is allowed for an implementation of [`write`](SpiBus::write) to return as soon -//! as all the data has been written to the FIFO, before it is actually sent. Calling [`flush`](SpiBus::flush) would -//! wait until all the bits have actually been sent, the FIFO is empty, and the bus is idle. -//! -//! This still applies to other operations such as [`read`](SpiBus::read) or [`transfer`](SpiBus::transfer). It is less obvious -//! why, because these methods can't return before receiving all the read data. However it's still technically possible -//! for them to return before the bus is idle. For example, assuming SPI mode 0, the last bit is sampled on the first (rising) edge -//! of SCK, at which point a method could return, but the second (falling) SCK edge still has to happen before the bus is idle. -//! -//! # CS-to-clock delays -//! -//! Many chips require a minimum delay between asserting CS and the first SCK edge, and the last SCK edge and deasserting CS. -//! Drivers should *NOT* use [`Operation::DelayNs`] for this, they should instead document that the user should configure the -//! delays when creating the `SpiDevice` instance, same as they have to configure the SPI frequency and mode. This has a few advantages: -//! -//! - Allows implementations that use hardware-managed CS to program the delay in hardware -//! - Allows the end user more flexibility. For example, they can choose to not configure any delay if their MCU is slow -//! enough to "naturally" do the delay (very common if the delay is in the order of nanoseconds). - -use core::fmt::Debug; - -#[cfg(feature = "defmt-03")] -use crate::defmt; - -/// Clock polarity. -#[derive(Clone, Copy, Debug, PartialEq, Eq)] -#[cfg_attr(feature = "defmt-03", derive(defmt::Format))] -pub enum Polarity { - /// Clock signal low when idle. - IdleLow, - /// Clock signal high when idle. - IdleHigh, -} - -/// Clock phase. -#[derive(Clone, Copy, Debug, PartialEq, Eq)] -#[cfg_attr(feature = "defmt-03", derive(defmt::Format))] -pub enum Phase { - /// Data in "captured" on the first clock transition. - CaptureOnFirstTransition, - /// Data in "captured" on the second clock transition. - CaptureOnSecondTransition, -} - -/// SPI mode. -#[derive(Clone, Copy, Debug, PartialEq, Eq)] -#[cfg_attr(feature = "defmt-03", derive(defmt::Format))] -pub struct Mode { - /// Clock polarity. - pub polarity: Polarity, - /// Clock phase. - pub phase: Phase, -} - -/// Helper for CPOL = 0, CPHA = 0. -pub const MODE_0: Mode = Mode { - polarity: Polarity::IdleLow, - phase: Phase::CaptureOnFirstTransition, -}; - -/// Helper for CPOL = 0, CPHA = 1. -pub const MODE_1: Mode = Mode { - polarity: Polarity::IdleLow, - phase: Phase::CaptureOnSecondTransition, -}; - -/// Helper for CPOL = 1, CPHA = 0. -pub const MODE_2: Mode = Mode { - polarity: Polarity::IdleHigh, - phase: Phase::CaptureOnFirstTransition, -}; - -/// Helper for CPOL = 1, CPHA = 1. -pub const MODE_3: Mode = Mode { - polarity: Polarity::IdleHigh, - phase: Phase::CaptureOnSecondTransition, -}; - -/// SPI error. -pub trait Error: Debug { - /// Convert error to a generic SPI error kind. - /// - /// By using this method, SPI errors freely defined by HAL implementations - /// can be converted to a set of generic SPI errors upon which generic - /// code can act. - fn kind(&self) -> ErrorKind; -} - -impl Error for core::convert::Infallible { - #[inline] - fn kind(&self) -> ErrorKind { - match *self {} - } -} - -/// SPI error kind. -/// -/// This represents a common set of SPI operation errors. HAL implementations are -/// free to define more specific or additional error types. However, by providing -/// a mapping to these common SPI errors, generic code can still react to them. -#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)] -#[cfg_attr(feature = "defmt-03", derive(defmt::Format))] -#[non_exhaustive] -pub enum ErrorKind { - /// The peripheral receive buffer was overrun. - Overrun, - /// Multiple devices on the SPI bus are trying to drive the slave select pin, e.g. in a multi-master setup. - ModeFault, - /// Received data does not conform to the peripheral configuration. - FrameFormat, - /// An error occurred while asserting or deasserting the Chip Select pin. - ChipSelectFault, - /// A different error occurred. The original error may contain more information. - Other, -} - -impl Error for ErrorKind { - #[inline] - fn kind(&self) -> ErrorKind { - *self - } -} - -impl core::fmt::Display for ErrorKind { - #[inline] - fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { - match self { - Self::Overrun => write!(f, "The peripheral receive buffer was overrun"), - Self::ModeFault => write!( - f, - "Multiple devices on the SPI bus are trying to drive the slave select pin" - ), - Self::FrameFormat => write!( - f, - "Received data does not conform to the peripheral configuration" - ), - Self::ChipSelectFault => write!( - f, - "An error occurred while asserting or deasserting the Chip Select pin" - ), - Self::Other => write!( - f, - "A different error occurred. The original error may contain more information" - ), - } - } -} - -/// SPI error type trait. -/// -/// This just defines the error type, to be used by the other SPI traits. -pub trait ErrorType { - /// Error type. - type Error: Error; -} - -impl ErrorType for &mut T { - type Error = T::Error; -} - -/// SPI transaction operation. -/// -/// This allows composition of SPI operations into a single bus transaction. -#[derive(Debug, PartialEq, Eq)] -#[cfg_attr(feature = "defmt-03", derive(defmt::Format))] -pub enum Operation<'a, Word: 'static> { - /// Read data into the provided buffer. - /// - /// Equivalent to [`SpiBus::read`]. - Read(&'a mut [Word]), - /// Write data from the provided buffer, discarding read data. - /// - /// Equivalent to [`SpiBus::write`]. - Write(&'a [Word]), - /// Read data into the first buffer, while writing data from the second buffer. - /// - /// Equivalent to [`SpiBus::transfer`]. - Transfer(&'a mut [Word], &'a [Word]), - /// Write data out while reading data into the provided buffer. - /// - /// Equivalent to [`SpiBus::transfer_in_place`]. - TransferInPlace(&'a mut [Word]), - /// Delay for at least the specified number of nanoseconds. - DelayNs(u32), -} - -/// SPI device trait. -/// -/// `SpiDevice` represents ownership over a single SPI device on a (possibly shared) bus, selected -/// with a CS (Chip Select) pin. -/// -/// See the [module-level documentation](self) for important usage information. -pub trait SpiDevice: ErrorType { - /// Perform a transaction against the device. - /// - /// - Locks the bus - /// - Asserts the CS (Chip Select) pin. - /// - Performs all the operations. - /// - [Flushes](SpiBus::flush) the bus. - /// - Deasserts the CS pin. - /// - Unlocks the bus. - /// - /// The locking mechanism is implementation-defined. The only requirement is it must prevent two - /// transactions from executing concurrently against the same bus. Examples of implementations are: - /// critical sections, blocking mutexes, returning an error or panicking if the bus is already busy. - /// - /// On bus errors the implementation should try to deassert CS. - /// If an error occurs while deasserting CS the bus error should take priority as the return value. - fn transaction(&mut self, operations: &mut [Operation<'_, Word>]) -> Result<(), Self::Error>; - - /// Do a read within a transaction. - /// - /// This is a convenience method equivalent to `device.transaction(&mut [Operation::Read(buf)])`. - /// - /// See also: [`SpiDevice::transaction`], [`SpiBus::read`] - #[inline] - fn read(&mut self, buf: &mut [Word]) -> Result<(), Self::Error> { - self.transaction(&mut [Operation::Read(buf)]) - } - - /// Do a write within a transaction. - /// - /// This is a convenience method equivalent to `device.transaction(&mut [Operation::Write(buf)])`. - /// - /// See also: [`SpiDevice::transaction`], [`SpiBus::write`] - #[inline] - fn write(&mut self, buf: &[Word]) -> Result<(), Self::Error> { - self.transaction(&mut [Operation::Write(buf)]) - } - - /// Do a transfer within a transaction. - /// - /// This is a convenience method equivalent to `device.transaction(&mut [Operation::Transfer(read, write)]`. - /// - /// See also: [`SpiDevice::transaction`], [`SpiBus::transfer`] - #[inline] - fn transfer(&mut self, read: &mut [Word], write: &[Word]) -> Result<(), Self::Error> { - self.transaction(&mut [Operation::Transfer(read, write)]) - } - - /// Do an in-place transfer within a transaction. - /// - /// This is a convenience method equivalent to `device.transaction(&mut [Operation::TransferInPlace(buf)]`. - /// - /// See also: [`SpiDevice::transaction`], [`SpiBus::transfer_in_place`] - #[inline] - fn transfer_in_place(&mut self, buf: &mut [Word]) -> Result<(), Self::Error> { - self.transaction(&mut [Operation::TransferInPlace(buf)]) - } -} - -impl + ?Sized> SpiDevice for &mut T { - #[inline] - fn transaction(&mut self, operations: &mut [Operation<'_, Word>]) -> Result<(), Self::Error> { - T::transaction(self, operations) - } - - #[inline] - fn read(&mut self, buf: &mut [Word]) -> Result<(), Self::Error> { - T::read(self, buf) - } - - #[inline] - fn write(&mut self, buf: &[Word]) -> Result<(), Self::Error> { - T::write(self, buf) - } - - #[inline] - fn transfer(&mut self, read: &mut [Word], write: &[Word]) -> Result<(), Self::Error> { - T::transfer(self, read, write) - } - - #[inline] - fn transfer_in_place(&mut self, buf: &mut [Word]) -> Result<(), Self::Error> { - T::transfer_in_place(self, buf) - } -} - -/// SPI bus. -/// -/// `SpiBus` represents **exclusive ownership** over the whole SPI bus, with SCK, MOSI and MISO pins. -/// -/// See the [module-level documentation](self) for important information on SPI Bus vs Device traits. -pub trait SpiBus: ErrorType { - /// Read `words` from the slave. - /// - /// The word value sent on MOSI during reading is implementation-defined, - /// typically `0x00`, `0xFF`, or configurable. - /// - /// Implementations are allowed to return before the operation is - /// complete. See the [module-level documentation](self) for details. - fn read(&mut self, words: &mut [Word]) -> Result<(), Self::Error>; - - /// Write `words` to the slave, ignoring all the incoming words. - /// - /// Implementations are allowed to return before the operation is - /// complete. See the [module-level documentation](self) for details. - fn write(&mut self, words: &[Word]) -> Result<(), Self::Error>; - - /// Write and read simultaneously. `write` is written to the slave on MOSI and - /// words received on MISO are stored in `read`. - /// - /// It is allowed for `read` and `write` to have different lengths, even zero length. - /// The transfer runs for `max(read.len(), write.len())` words. If `read` is shorter, - /// incoming words after `read` has been filled will be discarded. If `write` is shorter, - /// the value of words sent in MOSI after all `write` has been sent is implementation-defined, - /// typically `0x00`, `0xFF`, or configurable. - /// - /// Implementations are allowed to return before the operation is - /// complete. See the [module-level documentation](self) for details. - fn transfer(&mut self, read: &mut [Word], write: &[Word]) -> Result<(), Self::Error>; - - /// Write and read simultaneously. The contents of `words` are - /// written to the slave, and the received words are stored into the same - /// `words` buffer, overwriting it. - /// - /// Implementations are allowed to return before the operation is - /// complete. See the [module-level documentation](self) for details. - fn transfer_in_place(&mut self, words: &mut [Word]) -> Result<(), Self::Error>; - - /// Wait until all operations have completed and the bus is idle. - /// - /// See the [module-level documentation](self) for important usage information. - fn flush(&mut self) -> Result<(), Self::Error>; -} - -impl + ?Sized, Word: Copy + 'static> SpiBus for &mut T { - #[inline] - fn read(&mut self, words: &mut [Word]) -> Result<(), Self::Error> { - T::read(self, words) - } - - #[inline] - fn write(&mut self, words: &[Word]) -> Result<(), Self::Error> { - T::write(self, words) - } - - #[inline] - fn transfer(&mut self, read: &mut [Word], write: &[Word]) -> Result<(), Self::Error> { - T::transfer(self, read, write) - } - - #[inline] - fn transfer_in_place(&mut self, words: &mut [Word]) -> Result<(), Self::Error> { - T::transfer_in_place(self, words) - } - - #[inline] - fn flush(&mut self) -> Result<(), Self::Error> { - T::flush(self) - } -} diff --git a/third-party/vendor/lock_api/.cargo-checksum.json b/third-party/vendor/lock_api/.cargo-checksum.json deleted file mode 100644 index f525b6dd..00000000 --- a/third-party/vendor/lock_api/.cargo-checksum.json +++ /dev/null @@ -1 +0,0 @@ -{"files":{"Cargo.toml":"33d5077741ae3052ec99816d7390a65220b898b87fb100589d5783352d4052f5","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"c9a75f18b9ab2927829a208fc6aa2cf4e63b8420887ba29cdb265d6619ae82d5","build.rs":"af84139c71d151adead0b4398c394a7dd16087bb2db44b14a0ed970ce868a6c6","src/lib.rs":"4d2f97a740d3bda0cf2ba0ccbaa44a294952a701fc5a8219a755b4187bab29d4","src/mutex.rs":"d24c765e7b371542992465027dba520e66a09e67a78324ab8396449aadad0d77","src/remutex.rs":"036fb60892d4b727257dbdf68a921738f048a94ed5ca0a1bb78ee0f68381cf9e","src/rwlock.rs":"4b85d7b42474ebe0ba91f6fd953232510164989ce5ef1511790de486d8960301"},"package":"3c168f8615b12bc01f9c17e2eb0cc07dcae1940121185446edc3744920e8ef45"} \ No newline at end of file diff --git a/third-party/vendor/lock_api/Cargo.toml b/third-party/vendor/lock_api/Cargo.toml deleted file mode 100644 index 501db6e3..00000000 --- a/third-party/vendor/lock_api/Cargo.toml +++ /dev/null @@ -1,60 +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 are reading this file be aware that the original Cargo.toml -# will likely look very different (and much more reasonable). -# See Cargo.toml.orig for the original contents. - -[package] -edition = "2018" -rust-version = "1.49.0" -name = "lock_api" -version = "0.4.11" -authors = ["Amanieu d'Antras "] -description = "Wrappers to create fully-featured Mutex and RwLock types. Compatible with no_std." -keywords = [ - "mutex", - "rwlock", - "lock", - "no_std", -] -categories = [ - "concurrency", - "no-std", -] -license = "MIT OR Apache-2.0" -repository = "https://github.com/Amanieu/parking_lot" - -[package.metadata.docs.rs] -all-features = true -rustdoc-args = [ - "--cfg", - "docsrs", - "--generate-link-to-definition", -] - -[dependencies.owning_ref] -version = "0.4.1" -optional = true - -[dependencies.scopeguard] -version = "1.1.0" -default-features = false - -[dependencies.serde] -version = "1.0.126" -optional = true -default-features = false - -[build-dependencies.autocfg] -version = "1.1.0" - -[features] -arc_lock = [] -atomic_usize = [] -default = ["atomic_usize"] -nightly = [] diff --git a/third-party/vendor/lock_api/LICENSE-APACHE b/third-party/vendor/lock_api/LICENSE-APACHE deleted file mode 100644 index 16fe87b0..00000000 --- a/third-party/vendor/lock_api/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. diff --git a/third-party/vendor/lock_api/LICENSE-MIT b/third-party/vendor/lock_api/LICENSE-MIT deleted file mode 100644 index 40b8817a..00000000 --- a/third-party/vendor/lock_api/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. diff --git a/third-party/vendor/lock_api/build.rs b/third-party/vendor/lock_api/build.rs deleted file mode 100644 index 886a3454..00000000 --- a/third-party/vendor/lock_api/build.rs +++ /dev/null @@ -1,7 +0,0 @@ -fn main() { - let cfg = autocfg::new(); - - if cfg.probe_rustc_version(1, 61) { - println!("cargo:rustc-cfg=has_const_fn_trait_bound"); - } -} diff --git a/third-party/vendor/lock_api/src/lib.rs b/third-party/vendor/lock_api/src/lib.rs deleted file mode 100644 index 3ea417a4..00000000 --- a/third-party/vendor/lock_api/src/lib.rs +++ /dev/null @@ -1,116 +0,0 @@ -// Copyright 2018 Amanieu d'Antras -// -// Licensed under the Apache License, Version 2.0, or the MIT license , at your option. This file may not be -// copied, modified, or distributed except according to those terms. - -//! This library provides type-safe and fully-featured `Mutex` and `RwLock` -//! types which wrap a simple raw mutex or rwlock type. This has several -//! benefits: not only does it eliminate a large portion of the work in -//! implementing custom lock types, it also allows users to write code which is -//! generic with regards to different lock implementations. -//! -//! Basic usage of this crate is very straightforward: -//! -//! 1. Create a raw lock type. This should only contain the lock state, not any -//! data protected by the lock. -//! 2. Implement the `RawMutex` trait for your custom lock type. -//! 3. Export your mutex as a type alias for `lock_api::Mutex`, and -//! your mutex guard as a type alias for `lock_api::MutexGuard`. -//! See the [example](#example) below for details. -//! -//! This process is similar for RwLocks, except that two guards need to be -//! exported instead of one. (Or 3 guards if your type supports upgradable read -//! locks, see [extension traits](#extension-traits) below for details) -//! -//! # Example -//! -//! ``` -//! use lock_api::{RawMutex, Mutex, GuardSend}; -//! use std::sync::atomic::{AtomicBool, Ordering}; -//! -//! // 1. Define our raw lock type -//! pub struct RawSpinlock(AtomicBool); -//! -//! // 2. Implement RawMutex for this type -//! unsafe impl RawMutex for RawSpinlock { -//! const INIT: RawSpinlock = RawSpinlock(AtomicBool::new(false)); -//! -//! // A spinlock guard can be sent to another thread and unlocked there -//! type GuardMarker = GuardSend; -//! -//! fn lock(&self) { -//! // Note: This isn't the best way of implementing a spinlock, but it -//! // suffices for the sake of this example. -//! while !self.try_lock() {} -//! } -//! -//! fn try_lock(&self) -> bool { -//! self.0 -//! .compare_exchange(false, true, Ordering::Acquire, Ordering::Relaxed) -//! .is_ok() -//! } -//! -//! unsafe fn unlock(&self) { -//! self.0.store(false, Ordering::Release); -//! } -//! } -//! -//! // 3. Export the wrappers. This are the types that your users will actually use. -//! pub type Spinlock = lock_api::Mutex; -//! pub type SpinlockGuard<'a, T> = lock_api::MutexGuard<'a, RawSpinlock, T>; -//! ``` -//! -//! # Extension traits -//! -//! In addition to basic locking & unlocking functionality, you have the option -//! of exposing additional functionality in your lock types by implementing -//! additional traits for it. Examples of extension features include: -//! -//! - Fair unlocking (`RawMutexFair`, `RawRwLockFair`) -//! - Lock timeouts (`RawMutexTimed`, `RawRwLockTimed`) -//! - Downgradable write locks (`RawRwLockDowngradable`) -//! - Recursive read locks (`RawRwLockRecursive`) -//! - Upgradable read locks (`RawRwLockUpgrade`) -//! -//! The `Mutex` and `RwLock` wrappers will automatically expose this additional -//! functionality if the raw lock type implements these extension traits. -//! -//! # Cargo features -//! -//! This crate supports three cargo features: -//! -//! - `owning_ref`: Allows your lock types to be used with the `owning_ref` crate. -//! - `arc_lock`: Enables locking from an `Arc`. This enables types such as `ArcMutexGuard`. Note that this -//! requires the `alloc` crate to be present. - -#![no_std] -#![cfg_attr(docsrs, feature(doc_auto_cfg))] -#![warn(missing_docs)] -#![warn(rust_2018_idioms)] - -#[macro_use] -extern crate scopeguard; - -#[cfg(feature = "arc_lock")] -extern crate alloc; - -/// Marker type which indicates that the Guard type for a lock is `Send`. -pub struct GuardSend(()); - -/// Marker type which indicates that the Guard type for a lock is not `Send`. -pub struct GuardNoSend(*mut ()); - -unsafe impl Sync for GuardNoSend {} - -mod mutex; -pub use crate::mutex::*; - -#[cfg(feature = "atomic_usize")] -mod remutex; -#[cfg(feature = "atomic_usize")] -pub use crate::remutex::*; - -mod rwlock; -pub use crate::rwlock::*; diff --git a/third-party/vendor/lock_api/src/mutex.rs b/third-party/vendor/lock_api/src/mutex.rs deleted file mode 100644 index 80eadfa9..00000000 --- a/third-party/vendor/lock_api/src/mutex.rs +++ /dev/null @@ -1,960 +0,0 @@ -// Copyright 2018 Amanieu d'Antras -// -// Licensed under the Apache License, Version 2.0, or the MIT license , at your option. This file may not be -// copied, modified, or distributed except according to those terms. - -use core::cell::UnsafeCell; -use core::fmt; -use core::marker::PhantomData; -use core::mem; -use core::ops::{Deref, DerefMut}; - -#[cfg(feature = "arc_lock")] -use alloc::sync::Arc; -#[cfg(feature = "arc_lock")] -use core::mem::ManuallyDrop; -#[cfg(feature = "arc_lock")] -use core::ptr; - -#[cfg(feature = "owning_ref")] -use owning_ref::StableAddress; - -#[cfg(feature = "serde")] -use serde::{Deserialize, Deserializer, Serialize, Serializer}; - -/// Basic operations for a mutex. -/// -/// Types implementing this trait can be used by `Mutex` to form a safe and -/// fully-functioning mutex type. -/// -/// # Safety -/// -/// Implementations of this trait must ensure that the mutex is actually -/// exclusive: a lock can't be acquired while the mutex is already locked. -pub unsafe trait RawMutex { - /// Initial value for an unlocked mutex. - // A “non-constant” const item is a legacy way to supply an initialized value to downstream - // static items. Can hopefully be replaced with `const fn new() -> Self` at some point. - #[allow(clippy::declare_interior_mutable_const)] - const INIT: Self; - - /// Marker type which determines whether a lock guard should be `Send`. Use - /// one of the `GuardSend` or `GuardNoSend` helper types here. - type GuardMarker; - - /// Acquires this mutex, blocking the current thread until it is able to do so. - fn lock(&self); - - /// Attempts to acquire this mutex without blocking. Returns `true` - /// if the lock was successfully acquired and `false` otherwise. - fn try_lock(&self) -> bool; - - /// Unlocks this mutex. - /// - /// # Safety - /// - /// This method may only be called if the mutex is held in the current context, i.e. it must - /// be paired with a successful call to [`lock`], [`try_lock`], [`try_lock_for`] or [`try_lock_until`]. - /// - /// [`lock`]: #tymethod.lock - /// [`try_lock`]: #tymethod.try_lock - /// [`try_lock_for`]: trait.RawMutexTimed.html#tymethod.try_lock_for - /// [`try_lock_until`]: trait.RawMutexTimed.html#tymethod.try_lock_until - unsafe fn unlock(&self); - - /// Checks whether the mutex is currently locked. - #[inline] - fn is_locked(&self) -> bool { - let acquired_lock = self.try_lock(); - if acquired_lock { - // Safety: The lock has been successfully acquired above. - unsafe { - self.unlock(); - } - } - !acquired_lock - } -} - -/// Additional methods for mutexes which support fair unlocking. -/// -/// Fair unlocking means that a lock is handed directly over to the next waiting -/// thread if there is one, without giving other threads the opportunity to -/// "steal" the lock in the meantime. This is typically slower than unfair -/// unlocking, but may be necessary in certain circumstances. -pub unsafe trait RawMutexFair: RawMutex { - /// Unlocks this mutex using a fair unlock protocol. - /// - /// # Safety - /// - /// This method may only be called if the mutex is held in the current context, see - /// the documentation of [`unlock`]. - /// - /// [`unlock`]: trait.RawMutex.html#tymethod.unlock - unsafe fn unlock_fair(&self); - - /// Temporarily yields the mutex to a waiting thread if there is one. - /// - /// This method is functionally equivalent to calling `unlock_fair` followed - /// by `lock`, however it can be much more efficient in the case where there - /// are no waiting threads. - /// - /// # Safety - /// - /// This method may only be called if the mutex is held in the current context, see - /// the documentation of [`unlock`]. - /// - /// [`unlock`]: trait.RawMutex.html#tymethod.unlock - unsafe fn bump(&self) { - self.unlock_fair(); - self.lock(); - } -} - -/// Additional methods for mutexes which support locking with timeouts. -/// -/// The `Duration` and `Instant` types are specified as associated types so that -/// this trait is usable even in `no_std` environments. -pub unsafe trait RawMutexTimed: RawMutex { - /// Duration type used for `try_lock_for`. - type Duration; - - /// Instant type used for `try_lock_until`. - type Instant; - - /// Attempts to acquire this lock until a timeout is reached. - fn try_lock_for(&self, timeout: Self::Duration) -> bool; - - /// Attempts to acquire this lock until a timeout is reached. - fn try_lock_until(&self, timeout: Self::Instant) -> bool; -} - -/// A mutual exclusion primitive useful for protecting shared data -/// -/// This mutex will block threads waiting for the lock to become available. The -/// mutex can also be statically initialized or created via a `new` -/// constructor. Each mutex has a type parameter which represents the data that -/// it is protecting. The data can only be accessed through the RAII guards -/// returned from `lock` and `try_lock`, which guarantees that the data is only -/// ever accessed when the mutex is locked. -pub struct Mutex { - raw: R, - data: UnsafeCell, -} - -unsafe impl Send for Mutex {} -unsafe impl Sync for Mutex {} - -impl Mutex { - /// Creates a new mutex in an unlocked state ready for use. - #[cfg(has_const_fn_trait_bound)] - #[inline] - pub const fn new(val: T) -> Mutex { - Mutex { - raw: R::INIT, - data: UnsafeCell::new(val), - } - } - - /// Creates a new mutex in an unlocked state ready for use. - #[cfg(not(has_const_fn_trait_bound))] - #[inline] - pub fn new(val: T) -> Mutex { - Mutex { - raw: R::INIT, - data: UnsafeCell::new(val), - } - } - - /// Consumes this mutex, returning the underlying data. - #[inline] - pub fn into_inner(self) -> T { - self.data.into_inner() - } -} - -impl Mutex { - /// Creates a new mutex based on a pre-existing raw mutex. - /// - /// This allows creating a mutex in a constant context on stable Rust. - #[inline] - pub const fn const_new(raw_mutex: R, val: T) -> Mutex { - Mutex { - raw: raw_mutex, - data: UnsafeCell::new(val), - } - } -} - -impl Mutex { - /// Creates a new `MutexGuard` without checking if the mutex is locked. - /// - /// # Safety - /// - /// This method must only be called if the thread logically holds the lock. - /// - /// Calling this function when a guard has already been produced is undefined behaviour unless - /// the guard was forgotten with `mem::forget`. - #[inline] - pub unsafe fn make_guard_unchecked(&self) -> MutexGuard<'_, R, T> { - MutexGuard { - mutex: self, - marker: PhantomData, - } - } - - /// Acquires a mutex, blocking the current thread until it is able to do so. - /// - /// This function will block the local thread until it is available to acquire - /// the mutex. Upon returning, the thread is the only thread with the mutex - /// held. An RAII guard is returned to allow scoped unlock of the lock. When - /// the guard goes out of scope, the mutex will be unlocked. - /// - /// Attempts to lock a mutex in the thread which already holds the lock will - /// result in a deadlock. - #[inline] - pub fn lock(&self) -> MutexGuard<'_, R, T> { - self.raw.lock(); - // SAFETY: The lock is held, as required. - unsafe { self.make_guard_unchecked() } - } - - /// Attempts to acquire this lock. - /// - /// If the lock could not be acquired at this time, then `None` is returned. - /// Otherwise, an RAII guard is returned. The lock will be unlocked when the - /// guard is dropped. - /// - /// This function does not block. - #[inline] - pub fn try_lock(&self) -> Option> { - if self.raw.try_lock() { - // SAFETY: The lock is held, as required. - Some(unsafe { self.make_guard_unchecked() }) - } else { - None - } - } - - /// Returns a mutable reference to the underlying data. - /// - /// Since this call borrows the `Mutex` mutably, no actual locking needs to - /// take place---the mutable borrow statically guarantees no locks exist. - #[inline] - pub fn get_mut(&mut self) -> &mut T { - unsafe { &mut *self.data.get() } - } - - /// Checks whether the mutex is currently locked. - #[inline] - pub fn is_locked(&self) -> bool { - self.raw.is_locked() - } - - /// Forcibly unlocks the mutex. - /// - /// This is useful when combined with `mem::forget` to hold a lock without - /// the need to maintain a `MutexGuard` object alive, for example when - /// dealing with FFI. - /// - /// # Safety - /// - /// This method must only be called if the current thread logically owns a - /// `MutexGuard` but that guard has been discarded using `mem::forget`. - /// Behavior is undefined if a mutex is unlocked when not locked. - #[inline] - pub unsafe fn force_unlock(&self) { - self.raw.unlock(); - } - - /// Returns the underlying raw mutex object. - /// - /// Note that you will most likely need to import the `RawMutex` trait from - /// `lock_api` to be able to call functions on the raw mutex. - /// - /// # Safety - /// - /// This method is unsafe because it allows unlocking a mutex while - /// still holding a reference to a `MutexGuard`. - #[inline] - pub unsafe fn raw(&self) -> &R { - &self.raw - } - - /// Returns a raw pointer to the underlying data. - /// - /// This is useful when combined with `mem::forget` to hold a lock without - /// the need to maintain a `MutexGuard` object alive, for example when - /// dealing with FFI. - /// - /// # Safety - /// - /// You must ensure that there are no data races when dereferencing the - /// returned pointer, for example if the current thread logically owns - /// a `MutexGuard` but that guard has been discarded using `mem::forget`. - #[inline] - pub fn data_ptr(&self) -> *mut T { - self.data.get() - } - - /// Creates a new `ArcMutexGuard` without checking if the mutex is locked. - /// - /// # Safety - /// - /// This method must only be called if the thread logically holds the lock. - /// - /// Calling this function when a guard has already been produced is undefined behaviour unless - /// the guard was forgotten with `mem::forget`. - #[cfg(feature = "arc_lock")] - #[inline] - unsafe fn make_arc_guard_unchecked(self: &Arc) -> ArcMutexGuard { - ArcMutexGuard { - mutex: self.clone(), - marker: PhantomData, - } - } - - /// Acquires a lock through an `Arc`. - /// - /// This method is similar to the `lock` method; however, it requires the `Mutex` to be inside of an `Arc` - /// and the resulting mutex guard has no lifetime requirements. - #[cfg(feature = "arc_lock")] - #[inline] - pub fn lock_arc(self: &Arc) -> ArcMutexGuard { - self.raw.lock(); - // SAFETY: the locking guarantee is upheld - unsafe { self.make_arc_guard_unchecked() } - } - - /// Attempts to acquire a lock through an `Arc`. - /// - /// This method is similar to the `try_lock` method; however, it requires the `Mutex` to be inside of an - /// `Arc` and the resulting mutex guard has no lifetime requirements. - #[cfg(feature = "arc_lock")] - #[inline] - pub fn try_lock_arc(self: &Arc) -> Option> { - if self.raw.try_lock() { - // SAFETY: locking guarantee is upheld - Some(unsafe { self.make_arc_guard_unchecked() }) - } else { - None - } - } -} - -impl Mutex { - /// Forcibly unlocks the mutex using a fair unlock procotol. - /// - /// This is useful when combined with `mem::forget` to hold a lock without - /// the need to maintain a `MutexGuard` object alive, for example when - /// dealing with FFI. - /// - /// # Safety - /// - /// This method must only be called if the current thread logically owns a - /// `MutexGuard` but that guard has been discarded using `mem::forget`. - /// Behavior is undefined if a mutex is unlocked when not locked. - #[inline] - pub unsafe fn force_unlock_fair(&self) { - self.raw.unlock_fair(); - } -} - -impl Mutex { - /// Attempts to acquire this lock until a timeout is reached. - /// - /// If the lock could not be acquired before the timeout expired, then - /// `None` is returned. Otherwise, an RAII guard is returned. The lock will - /// be unlocked when the guard is dropped. - #[inline] - pub fn try_lock_for(&self, timeout: R::Duration) -> Option> { - if self.raw.try_lock_for(timeout) { - // SAFETY: The lock is held, as required. - Some(unsafe { self.make_guard_unchecked() }) - } else { - None - } - } - - /// Attempts to acquire this lock until a timeout is reached. - /// - /// If the lock could not be acquired before the timeout expired, then - /// `None` is returned. Otherwise, an RAII guard is returned. The lock will - /// be unlocked when the guard is dropped. - #[inline] - pub fn try_lock_until(&self, timeout: R::Instant) -> Option> { - if self.raw.try_lock_until(timeout) { - // SAFETY: The lock is held, as required. - Some(unsafe { self.make_guard_unchecked() }) - } else { - None - } - } - - /// Attempts to acquire this lock through an `Arc` until a timeout is reached. - /// - /// This method is similar to the `try_lock_for` method; however, it requires the `Mutex` to be inside of an - /// `Arc` and the resulting mutex guard has no lifetime requirements. - #[cfg(feature = "arc_lock")] - #[inline] - pub fn try_lock_arc_for(self: &Arc, timeout: R::Duration) -> Option> { - if self.raw.try_lock_for(timeout) { - // SAFETY: locking guarantee is upheld - Some(unsafe { self.make_arc_guard_unchecked() }) - } else { - None - } - } - - /// Attempts to acquire this lock through an `Arc` until a timeout is reached. - /// - /// This method is similar to the `try_lock_until` method; however, it requires the `Mutex` to be inside of - /// an `Arc` and the resulting mutex guard has no lifetime requirements. - #[cfg(feature = "arc_lock")] - #[inline] - pub fn try_lock_arc_until( - self: &Arc, - timeout: R::Instant, - ) -> Option> { - if self.raw.try_lock_until(timeout) { - // SAFETY: locking guarantee is upheld - Some(unsafe { self.make_arc_guard_unchecked() }) - } else { - None - } - } -} - -impl Default for Mutex { - #[inline] - fn default() -> Mutex { - Mutex::new(Default::default()) - } -} - -impl From for Mutex { - #[inline] - fn from(t: T) -> Mutex { - Mutex::new(t) - } -} - -impl fmt::Debug for Mutex { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - match self.try_lock() { - Some(guard) => f.debug_struct("Mutex").field("data", &&*guard).finish(), - None => { - struct LockedPlaceholder; - impl fmt::Debug for LockedPlaceholder { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.write_str("") - } - } - - f.debug_struct("Mutex") - .field("data", &LockedPlaceholder) - .finish() - } - } - } -} - -// Copied and modified from serde -#[cfg(feature = "serde")] -impl Serialize for Mutex -where - R: RawMutex, - T: Serialize + ?Sized, -{ - fn serialize(&self, serializer: S) -> Result - where - S: Serializer, - { - self.lock().serialize(serializer) - } -} - -#[cfg(feature = "serde")] -impl<'de, R, T> Deserialize<'de> for Mutex -where - R: RawMutex, - T: Deserialize<'de> + ?Sized, -{ - fn deserialize(deserializer: D) -> Result - where - D: Deserializer<'de>, - { - Deserialize::deserialize(deserializer).map(Mutex::new) - } -} - -/// An RAII implementation of a "scoped lock" of a mutex. When this structure is -/// dropped (falls out of scope), the lock will be unlocked. -/// -/// The data protected by the mutex can be accessed through this guard via its -/// `Deref` and `DerefMut` implementations. -#[clippy::has_significant_drop] -#[must_use = "if unused the Mutex will immediately unlock"] -pub struct MutexGuard<'a, R: RawMutex, T: ?Sized> { - mutex: &'a Mutex, - marker: PhantomData<(&'a mut T, R::GuardMarker)>, -} - -unsafe impl<'a, R: RawMutex + Sync + 'a, T: ?Sized + Sync + 'a> Sync for MutexGuard<'a, R, T> {} - -impl<'a, R: RawMutex + 'a, T: ?Sized + 'a> MutexGuard<'a, R, T> { - /// Returns a reference to the original `Mutex` object. - pub fn mutex(s: &Self) -> &'a Mutex { - s.mutex - } - - /// Makes a new `MappedMutexGuard` for a component of the locked data. - /// - /// This operation cannot fail as the `MutexGuard` passed - /// in already locked the mutex. - /// - /// This is an associated function that needs to be - /// used as `MutexGuard::map(...)`. A method would interfere with methods of - /// the same name on the contents of the locked data. - #[inline] - pub fn map(s: Self, f: F) -> MappedMutexGuard<'a, R, U> - where - F: FnOnce(&mut T) -> &mut U, - { - let raw = &s.mutex.raw; - let data = f(unsafe { &mut *s.mutex.data.get() }); - mem::forget(s); - MappedMutexGuard { - raw, - data, - marker: PhantomData, - } - } - - /// Attempts to make a new `MappedMutexGuard` for a component of the - /// locked data. The original guard is returned if the closure returns `None`. - /// - /// This operation cannot fail as the `MutexGuard` passed - /// in already locked the mutex. - /// - /// This is an associated function that needs to be - /// used as `MutexGuard::try_map(...)`. A method would interfere with methods of - /// the same name on the contents of the locked data. - #[inline] - pub fn try_map(s: Self, f: F) -> Result, Self> - where - F: FnOnce(&mut T) -> Option<&mut U>, - { - let raw = &s.mutex.raw; - let data = match f(unsafe { &mut *s.mutex.data.get() }) { - Some(data) => data, - None => return Err(s), - }; - mem::forget(s); - Ok(MappedMutexGuard { - raw, - data, - marker: PhantomData, - }) - } - - /// Temporarily unlocks the mutex to execute the given function. - /// - /// This is safe because `&mut` guarantees that there exist no other - /// references to the data protected by the mutex. - #[inline] - pub fn unlocked(s: &mut Self, f: F) -> U - where - F: FnOnce() -> U, - { - // Safety: A MutexGuard always holds the lock. - unsafe { - s.mutex.raw.unlock(); - } - defer!(s.mutex.raw.lock()); - f() - } - - /// Leaks the mutex guard and returns a mutable reference to the data - /// protected by the mutex. - /// - /// This will leave the `Mutex` in a locked state. - #[inline] - pub fn leak(s: Self) -> &'a mut T { - let r = unsafe { &mut *s.mutex.data.get() }; - mem::forget(s); - r - } -} - -impl<'a, R: RawMutexFair + 'a, T: ?Sized + 'a> MutexGuard<'a, R, T> { - /// Unlocks the mutex using a fair unlock protocol. - /// - /// By default, mutexes are unfair and allow the current thread to re-lock - /// the mutex before another has the chance to acquire the lock, even if - /// that thread has been blocked on the mutex for a long time. This is the - /// default because it allows much higher throughput as it avoids forcing a - /// context switch on every mutex unlock. This can result in one thread - /// acquiring a mutex many more times than other threads. - /// - /// However in some cases it can be beneficial to ensure fairness by forcing - /// the lock to pass on to a waiting thread if there is one. This is done by - /// using this method instead of dropping the `MutexGuard` normally. - #[inline] - pub fn unlock_fair(s: Self) { - // Safety: A MutexGuard always holds the lock. - unsafe { - s.mutex.raw.unlock_fair(); - } - mem::forget(s); - } - - /// Temporarily unlocks the mutex to execute the given function. - /// - /// The mutex is unlocked using a fair unlock protocol. - /// - /// This is safe because `&mut` guarantees that there exist no other - /// references to the data protected by the mutex. - #[inline] - pub fn unlocked_fair(s: &mut Self, f: F) -> U - where - F: FnOnce() -> U, - { - // Safety: A MutexGuard always holds the lock. - unsafe { - s.mutex.raw.unlock_fair(); - } - defer!(s.mutex.raw.lock()); - f() - } - - /// Temporarily yields the mutex to a waiting thread if there is one. - /// - /// This method is functionally equivalent to calling `unlock_fair` followed - /// by `lock`, however it can be much more efficient in the case where there - /// are no waiting threads. - #[inline] - pub fn bump(s: &mut Self) { - // Safety: A MutexGuard always holds the lock. - unsafe { - s.mutex.raw.bump(); - } - } -} - -impl<'a, R: RawMutex + 'a, T: ?Sized + 'a> Deref for MutexGuard<'a, R, T> { - type Target = T; - #[inline] - fn deref(&self) -> &T { - unsafe { &*self.mutex.data.get() } - } -} - -impl<'a, R: RawMutex + 'a, T: ?Sized + 'a> DerefMut for MutexGuard<'a, R, T> { - #[inline] - fn deref_mut(&mut self) -> &mut T { - unsafe { &mut *self.mutex.data.get() } - } -} - -impl<'a, R: RawMutex + 'a, T: ?Sized + 'a> Drop for MutexGuard<'a, R, T> { - #[inline] - fn drop(&mut self) { - // Safety: A MutexGuard always holds the lock. - unsafe { - self.mutex.raw.unlock(); - } - } -} - -impl<'a, R: RawMutex + 'a, T: fmt::Debug + ?Sized + 'a> fmt::Debug for MutexGuard<'a, R, T> { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - fmt::Debug::fmt(&**self, f) - } -} - -impl<'a, R: RawMutex + 'a, T: fmt::Display + ?Sized + 'a> fmt::Display for MutexGuard<'a, R, T> { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - (**self).fmt(f) - } -} - -#[cfg(feature = "owning_ref")] -unsafe impl<'a, R: RawMutex + 'a, T: ?Sized + 'a> StableAddress for MutexGuard<'a, R, T> {} - -/// An RAII mutex guard returned by the `Arc` locking operations on `Mutex`. -/// -/// This is similar to the `MutexGuard` struct, except instead of using a reference to unlock the `Mutex` it -/// uses an `Arc`. This has several advantages, most notably that it has an `'static` lifetime. -#[cfg(feature = "arc_lock")] -#[clippy::has_significant_drop] -#[must_use = "if unused the Mutex will immediately unlock"] -pub struct ArcMutexGuard { - mutex: Arc>, - marker: PhantomData<*const ()>, -} - -#[cfg(feature = "arc_lock")] -unsafe impl Send for ArcMutexGuard where - R::GuardMarker: Send -{ -} -#[cfg(feature = "arc_lock")] -unsafe impl Sync for ArcMutexGuard where - R::GuardMarker: Sync -{ -} - -#[cfg(feature = "arc_lock")] -impl ArcMutexGuard { - /// Returns a reference to the `Mutex` this is guarding, contained in its `Arc`. - #[inline] - pub fn mutex(s: &Self) -> &Arc> { - &s.mutex - } - - /// Unlocks the mutex and returns the `Arc` that was held by the [`ArcMutexGuard`]. - #[inline] - pub fn into_arc(s: Self) -> Arc> { - // Safety: Skip our Drop impl and manually unlock the mutex. - let arc = unsafe { ptr::read(&s.mutex) }; - mem::forget(s); - unsafe { - arc.raw.unlock(); - } - arc - } - - /// Temporarily unlocks the mutex to execute the given function. - /// - /// This is safe because `&mut` guarantees that there exist no other - /// references to the data protected by the mutex. - #[inline] - pub fn unlocked(s: &mut Self, f: F) -> U - where - F: FnOnce() -> U, - { - // Safety: A MutexGuard always holds the lock. - unsafe { - s.mutex.raw.unlock(); - } - defer!(s.mutex.raw.lock()); - f() - } -} - -#[cfg(feature = "arc_lock")] -impl ArcMutexGuard { - /// Unlocks the mutex using a fair unlock protocol. - /// - /// This is functionally identical to the `unlock_fair` method on [`MutexGuard`]. - #[inline] - pub fn unlock_fair(s: Self) { - // Safety: A MutexGuard always holds the lock. - unsafe { - s.mutex.raw.unlock_fair(); - } - - // SAFETY: make sure the Arc gets it reference decremented - let mut s = ManuallyDrop::new(s); - unsafe { ptr::drop_in_place(&mut s.mutex) }; - } - - /// Temporarily unlocks the mutex to execute the given function. - /// - /// This is functionally identical to the `unlocked_fair` method on [`MutexGuard`]. - #[inline] - pub fn unlocked_fair(s: &mut Self, f: F) -> U - where - F: FnOnce() -> U, - { - // Safety: A MutexGuard always holds the lock. - unsafe { - s.mutex.raw.unlock_fair(); - } - defer!(s.mutex.raw.lock()); - f() - } - - /// Temporarily yields the mutex to a waiting thread if there is one. - /// - /// This is functionally identical to the `bump` method on [`MutexGuard`]. - #[inline] - pub fn bump(s: &mut Self) { - // Safety: A MutexGuard always holds the lock. - unsafe { - s.mutex.raw.bump(); - } - } -} - -#[cfg(feature = "arc_lock")] -impl Deref for ArcMutexGuard { - type Target = T; - #[inline] - fn deref(&self) -> &T { - unsafe { &*self.mutex.data.get() } - } -} - -#[cfg(feature = "arc_lock")] -impl DerefMut for ArcMutexGuard { - #[inline] - fn deref_mut(&mut self) -> &mut T { - unsafe { &mut *self.mutex.data.get() } - } -} - -#[cfg(feature = "arc_lock")] -impl Drop for ArcMutexGuard { - #[inline] - fn drop(&mut self) { - // Safety: A MutexGuard always holds the lock. - unsafe { - self.mutex.raw.unlock(); - } - } -} - -/// An RAII mutex guard returned by `MutexGuard::map`, which can point to a -/// subfield of the protected data. -/// -/// The main difference between `MappedMutexGuard` and `MutexGuard` is that the -/// former doesn't support temporarily unlocking and re-locking, since that -/// could introduce soundness issues if the locked object is modified by another -/// thread. -#[clippy::has_significant_drop] -#[must_use = "if unused the Mutex will immediately unlock"] -pub struct MappedMutexGuard<'a, R: RawMutex, T: ?Sized> { - raw: &'a R, - data: *mut T, - marker: PhantomData<&'a mut T>, -} - -unsafe impl<'a, R: RawMutex + Sync + 'a, T: ?Sized + Sync + 'a> Sync - for MappedMutexGuard<'a, R, T> -{ -} -unsafe impl<'a, R: RawMutex + 'a, T: ?Sized + Send + 'a> Send for MappedMutexGuard<'a, R, T> where - R::GuardMarker: Send -{ -} - -impl<'a, R: RawMutex + 'a, T: ?Sized + 'a> MappedMutexGuard<'a, R, T> { - /// Makes a new `MappedMutexGuard` for a component of the locked data. - /// - /// This operation cannot fail as the `MappedMutexGuard` passed - /// in already locked the mutex. - /// - /// This is an associated function that needs to be - /// used as `MappedMutexGuard::map(...)`. A method would interfere with methods of - /// the same name on the contents of the locked data. - #[inline] - pub fn map(s: Self, f: F) -> MappedMutexGuard<'a, R, U> - where - F: FnOnce(&mut T) -> &mut U, - { - let raw = s.raw; - let data = f(unsafe { &mut *s.data }); - mem::forget(s); - MappedMutexGuard { - raw, - data, - marker: PhantomData, - } - } - - /// Attempts to make a new `MappedMutexGuard` for a component of the - /// locked data. The original guard is returned if the closure returns `None`. - /// - /// This operation cannot fail as the `MappedMutexGuard` passed - /// in already locked the mutex. - /// - /// This is an associated function that needs to be - /// used as `MappedMutexGuard::try_map(...)`. A method would interfere with methods of - /// the same name on the contents of the locked data. - #[inline] - pub fn try_map(s: Self, f: F) -> Result, Self> - where - F: FnOnce(&mut T) -> Option<&mut U>, - { - let raw = s.raw; - let data = match f(unsafe { &mut *s.data }) { - Some(data) => data, - None => return Err(s), - }; - mem::forget(s); - Ok(MappedMutexGuard { - raw, - data, - marker: PhantomData, - }) - } -} - -impl<'a, R: RawMutexFair + 'a, T: ?Sized + 'a> MappedMutexGuard<'a, R, T> { - /// Unlocks the mutex using a fair unlock protocol. - /// - /// By default, mutexes are unfair and allow the current thread to re-lock - /// the mutex before another has the chance to acquire the lock, even if - /// that thread has been blocked on the mutex for a long time. This is the - /// default because it allows much higher throughput as it avoids forcing a - /// context switch on every mutex unlock. This can result in one thread - /// acquiring a mutex many more times than other threads. - /// - /// However in some cases it can be beneficial to ensure fairness by forcing - /// the lock to pass on to a waiting thread if there is one. This is done by - /// using this method instead of dropping the `MutexGuard` normally. - #[inline] - pub fn unlock_fair(s: Self) { - // Safety: A MutexGuard always holds the lock. - unsafe { - s.raw.unlock_fair(); - } - mem::forget(s); - } -} - -impl<'a, R: RawMutex + 'a, T: ?Sized + 'a> Deref for MappedMutexGuard<'a, R, T> { - type Target = T; - #[inline] - fn deref(&self) -> &T { - unsafe { &*self.data } - } -} - -impl<'a, R: RawMutex + 'a, T: ?Sized + 'a> DerefMut for MappedMutexGuard<'a, R, T> { - #[inline] - fn deref_mut(&mut self) -> &mut T { - unsafe { &mut *self.data } - } -} - -impl<'a, R: RawMutex + 'a, T: ?Sized + 'a> Drop for MappedMutexGuard<'a, R, T> { - #[inline] - fn drop(&mut self) { - // Safety: A MappedMutexGuard always holds the lock. - unsafe { - self.raw.unlock(); - } - } -} - -impl<'a, R: RawMutex + 'a, T: fmt::Debug + ?Sized + 'a> fmt::Debug for MappedMutexGuard<'a, R, T> { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - fmt::Debug::fmt(&**self, f) - } -} - -impl<'a, R: RawMutex + 'a, T: fmt::Display + ?Sized + 'a> fmt::Display - for MappedMutexGuard<'a, R, T> -{ - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - (**self).fmt(f) - } -} - -#[cfg(feature = "owning_ref")] -unsafe impl<'a, R: RawMutex + 'a, T: ?Sized + 'a> StableAddress for MappedMutexGuard<'a, R, T> {} diff --git a/third-party/vendor/lock_api/src/remutex.rs b/third-party/vendor/lock_api/src/remutex.rs deleted file mode 100644 index 74f2da34..00000000 --- a/third-party/vendor/lock_api/src/remutex.rs +++ /dev/null @@ -1,1051 +0,0 @@ -// Copyright 2018 Amanieu d'Antras -// -// Licensed under the Apache License, Version 2.0, or the MIT license , at your option. This file may not be -// copied, modified, or distributed except according to those terms. - -use crate::{ - mutex::{RawMutex, RawMutexFair, RawMutexTimed}, - GuardNoSend, -}; -use core::{ - cell::{Cell, UnsafeCell}, - fmt, - marker::PhantomData, - mem, - num::NonZeroUsize, - ops::Deref, - sync::atomic::{AtomicUsize, Ordering}, -}; - -#[cfg(feature = "arc_lock")] -use alloc::sync::Arc; -#[cfg(feature = "arc_lock")] -use core::mem::ManuallyDrop; -#[cfg(feature = "arc_lock")] -use core::ptr; - -#[cfg(feature = "owning_ref")] -use owning_ref::StableAddress; - -#[cfg(feature = "serde")] -use serde::{Deserialize, Deserializer, Serialize, Serializer}; - -/// Helper trait which returns a non-zero thread ID. -/// -/// The simplest way to implement this trait is to return the address of a -/// thread-local variable. -/// -/// # Safety -/// -/// Implementations of this trait must ensure that no two active threads share -/// the same thread ID. However the ID of a thread that has exited can be -/// re-used since that thread is no longer active. -pub unsafe trait GetThreadId { - /// Initial value. - // A “non-constant” const item is a legacy way to supply an initialized value to downstream - // static items. Can hopefully be replaced with `const fn new() -> Self` at some point. - #[allow(clippy::declare_interior_mutable_const)] - const INIT: Self; - - /// Returns a non-zero thread ID which identifies the current thread of - /// execution. - fn nonzero_thread_id(&self) -> NonZeroUsize; -} - -/// A raw mutex type that wraps another raw mutex to provide reentrancy. -/// -/// Although this has the same methods as the [`RawMutex`] trait, it does -/// not implement it, and should not be used in the same way, since this -/// mutex can successfully acquire a lock multiple times in the same thread. -/// Only use this when you know you want a raw mutex that can be locked -/// reentrantly; you probably want [`ReentrantMutex`] instead. -/// -/// [`RawMutex`]: trait.RawMutex.html -/// [`ReentrantMutex`]: struct.ReentrantMutex.html -pub struct RawReentrantMutex { - owner: AtomicUsize, - lock_count: Cell, - mutex: R, - get_thread_id: G, -} - -unsafe impl Send for RawReentrantMutex {} -unsafe impl Sync for RawReentrantMutex {} - -impl RawReentrantMutex { - /// Initial value for an unlocked mutex. - #[allow(clippy::declare_interior_mutable_const)] - pub const INIT: Self = RawReentrantMutex { - owner: AtomicUsize::new(0), - lock_count: Cell::new(0), - mutex: R::INIT, - get_thread_id: G::INIT, - }; - - #[inline] - fn lock_internal bool>(&self, try_lock: F) -> bool { - let id = self.get_thread_id.nonzero_thread_id().get(); - if self.owner.load(Ordering::Relaxed) == id { - self.lock_count.set( - self.lock_count - .get() - .checked_add(1) - .expect("ReentrantMutex lock count overflow"), - ); - } else { - if !try_lock() { - return false; - } - self.owner.store(id, Ordering::Relaxed); - debug_assert_eq!(self.lock_count.get(), 0); - self.lock_count.set(1); - } - true - } - - /// Acquires this mutex, blocking if it's held by another thread. - #[inline] - pub fn lock(&self) { - self.lock_internal(|| { - self.mutex.lock(); - true - }); - } - - /// Attempts to acquire this mutex without blocking. Returns `true` - /// if the lock was successfully acquired and `false` otherwise. - #[inline] - pub fn try_lock(&self) -> bool { - self.lock_internal(|| self.mutex.try_lock()) - } - - /// Unlocks this mutex. The inner mutex may not be unlocked if - /// this mutex was acquired previously in the current thread. - /// - /// # Safety - /// - /// This method may only be called if the mutex is held by the current thread. - #[inline] - pub unsafe fn unlock(&self) { - let lock_count = self.lock_count.get() - 1; - self.lock_count.set(lock_count); - if lock_count == 0 { - self.owner.store(0, Ordering::Relaxed); - self.mutex.unlock(); - } - } - - /// Checks whether the mutex is currently locked. - #[inline] - pub fn is_locked(&self) -> bool { - self.mutex.is_locked() - } - - /// Checks whether the mutex is currently held by the current thread. - #[inline] - pub fn is_owned_by_current_thread(&self) -> bool { - let id = self.get_thread_id.nonzero_thread_id().get(); - self.owner.load(Ordering::Relaxed) == id - } -} - -impl RawReentrantMutex { - /// Unlocks this mutex using a fair unlock protocol. The inner mutex - /// may not be unlocked if this mutex was acquired previously in the - /// current thread. - /// - /// # Safety - /// - /// This method may only be called if the mutex is held by the current thread. - #[inline] - pub unsafe fn unlock_fair(&self) { - let lock_count = self.lock_count.get() - 1; - self.lock_count.set(lock_count); - if lock_count == 0 { - self.owner.store(0, Ordering::Relaxed); - self.mutex.unlock_fair(); - } - } - - /// Temporarily yields the mutex to a waiting thread if there is one. - /// - /// This method is functionally equivalent to calling `unlock_fair` followed - /// by `lock`, however it can be much more efficient in the case where there - /// are no waiting threads. - /// - /// # Safety - /// - /// This method may only be called if the mutex is held by the current thread. - #[inline] - pub unsafe fn bump(&self) { - if self.lock_count.get() == 1 { - let id = self.owner.load(Ordering::Relaxed); - self.owner.store(0, Ordering::Relaxed); - self.lock_count.set(0); - self.mutex.bump(); - self.owner.store(id, Ordering::Relaxed); - self.lock_count.set(1); - } - } -} - -impl RawReentrantMutex { - /// Attempts to acquire this lock until a timeout is reached. - #[inline] - pub fn try_lock_until(&self, timeout: R::Instant) -> bool { - self.lock_internal(|| self.mutex.try_lock_until(timeout)) - } - - /// Attempts to acquire this lock until a timeout is reached. - #[inline] - pub fn try_lock_for(&self, timeout: R::Duration) -> bool { - self.lock_internal(|| self.mutex.try_lock_for(timeout)) - } -} - -/// A mutex which can be recursively locked by a single thread. -/// -/// This type is identical to `Mutex` except for the following points: -/// -/// - Locking multiple times from the same thread will work correctly instead of -/// deadlocking. -/// - `ReentrantMutexGuard` does not give mutable references to the locked data. -/// Use a `RefCell` if you need this. -/// -/// See [`Mutex`](struct.Mutex.html) for more details about the underlying mutex -/// primitive. -pub struct ReentrantMutex { - raw: RawReentrantMutex, - data: UnsafeCell, -} - -unsafe impl Send - for ReentrantMutex -{ -} -unsafe impl Sync - for ReentrantMutex -{ -} - -impl ReentrantMutex { - /// Creates a new reentrant mutex in an unlocked state ready for use. - #[cfg(has_const_fn_trait_bound)] - #[inline] - pub const fn new(val: T) -> ReentrantMutex { - ReentrantMutex { - data: UnsafeCell::new(val), - raw: RawReentrantMutex { - owner: AtomicUsize::new(0), - lock_count: Cell::new(0), - mutex: R::INIT, - get_thread_id: G::INIT, - }, - } - } - - /// Creates a new reentrant mutex in an unlocked state ready for use. - #[cfg(not(has_const_fn_trait_bound))] - #[inline] - pub fn new(val: T) -> ReentrantMutex { - ReentrantMutex { - data: UnsafeCell::new(val), - raw: RawReentrantMutex { - owner: AtomicUsize::new(0), - lock_count: Cell::new(0), - mutex: R::INIT, - get_thread_id: G::INIT, - }, - } - } - - /// Consumes this mutex, returning the underlying data. - #[inline] - pub fn into_inner(self) -> T { - self.data.into_inner() - } -} - -impl ReentrantMutex { - /// Creates a new reentrant mutex based on a pre-existing raw mutex and a - /// helper to get the thread ID. - /// - /// This allows creating a reentrant mutex in a constant context on stable - /// Rust. - #[inline] - pub const fn const_new(raw_mutex: R, get_thread_id: G, val: T) -> ReentrantMutex { - ReentrantMutex { - data: UnsafeCell::new(val), - raw: RawReentrantMutex { - owner: AtomicUsize::new(0), - lock_count: Cell::new(0), - mutex: raw_mutex, - get_thread_id, - }, - } - } -} - -impl ReentrantMutex { - /// Creates a new `ReentrantMutexGuard` without checking if the lock is held. - /// - /// # Safety - /// - /// This method must only be called if the thread logically holds the lock. - /// - /// Calling this function when a guard has already been produced is undefined behaviour unless - /// the guard was forgotten with `mem::forget`. - #[inline] - pub unsafe fn make_guard_unchecked(&self) -> ReentrantMutexGuard<'_, R, G, T> { - ReentrantMutexGuard { - remutex: &self, - marker: PhantomData, - } - } - - /// Acquires a reentrant mutex, blocking the current thread until it is able - /// to do so. - /// - /// If the mutex is held by another thread then this function will block the - /// local thread until it is available to acquire the mutex. If the mutex is - /// already held by the current thread then this function will increment the - /// lock reference count and return immediately. Upon returning, - /// the thread is the only thread with the mutex held. An RAII guard is - /// returned to allow scoped unlock of the lock. When the guard goes out of - /// scope, the mutex will be unlocked. - #[inline] - pub fn lock(&self) -> ReentrantMutexGuard<'_, R, G, T> { - self.raw.lock(); - // SAFETY: The lock is held, as required. - unsafe { self.make_guard_unchecked() } - } - - /// Attempts to acquire this lock. - /// - /// If the lock could not be acquired at this time, then `None` is returned. - /// Otherwise, an RAII guard is returned. The lock will be unlocked when the - /// guard is dropped. - /// - /// This function does not block. - #[inline] - pub fn try_lock(&self) -> Option> { - if self.raw.try_lock() { - // SAFETY: The lock is held, as required. - Some(unsafe { self.make_guard_unchecked() }) - } else { - None - } - } - - /// Returns a mutable reference to the underlying data. - /// - /// Since this call borrows the `ReentrantMutex` mutably, no actual locking needs to - /// take place---the mutable borrow statically guarantees no locks exist. - #[inline] - pub fn get_mut(&mut self) -> &mut T { - unsafe { &mut *self.data.get() } - } - - /// Checks whether the mutex is currently locked. - #[inline] - pub fn is_locked(&self) -> bool { - self.raw.is_locked() - } - - /// Checks whether the mutex is currently held by the current thread. - #[inline] - pub fn is_owned_by_current_thread(&self) -> bool { - self.raw.is_owned_by_current_thread() - } - - /// Forcibly unlocks the mutex. - /// - /// This is useful when combined with `mem::forget` to hold a lock without - /// the need to maintain a `ReentrantMutexGuard` object alive, for example when - /// dealing with FFI. - /// - /// # Safety - /// - /// This method must only be called if the current thread logically owns a - /// `ReentrantMutexGuard` but that guard has be discarded using `mem::forget`. - /// Behavior is undefined if a mutex is unlocked when not locked. - #[inline] - pub unsafe fn force_unlock(&self) { - self.raw.unlock(); - } - - /// Returns the underlying raw mutex object. - /// - /// Note that you will most likely need to import the `RawMutex` trait from - /// `lock_api` to be able to call functions on the raw mutex. - /// - /// # Safety - /// - /// This method is unsafe because it allows unlocking a mutex while - /// still holding a reference to a `ReentrantMutexGuard`. - #[inline] - pub unsafe fn raw(&self) -> &R { - &self.raw.mutex - } - - /// Returns a raw pointer to the underlying data. - /// - /// This is useful when combined with `mem::forget` to hold a lock without - /// the need to maintain a `ReentrantMutexGuard` object alive, for example - /// when dealing with FFI. - /// - /// # Safety - /// - /// You must ensure that there are no data races when dereferencing the - /// returned pointer, for example if the current thread logically owns a - /// `ReentrantMutexGuard` but that guard has been discarded using - /// `mem::forget`. - #[inline] - pub fn data_ptr(&self) -> *mut T { - self.data.get() - } - - /// Creates a new `ArcReentrantMutexGuard` without checking if the lock is held. - /// - /// # Safety - /// - /// This method must only be called if the thread logically holds the lock. - /// - /// Calling this function when a guard has already been produced is undefined behaviour unless - /// the guard was forgotten with `mem::forget`. - #[cfg(feature = "arc_lock")] - #[inline] - pub unsafe fn make_arc_guard_unchecked(self: &Arc) -> ArcReentrantMutexGuard { - ArcReentrantMutexGuard { - remutex: self.clone(), - marker: PhantomData, - } - } - - /// Acquires a reentrant mutex through an `Arc`. - /// - /// This method is similar to the `lock` method; however, it requires the `ReentrantMutex` to be inside of an - /// `Arc` and the resulting mutex guard has no lifetime requirements. - #[cfg(feature = "arc_lock")] - #[inline] - pub fn lock_arc(self: &Arc) -> ArcReentrantMutexGuard { - self.raw.lock(); - // SAFETY: locking guarantee is upheld - unsafe { self.make_arc_guard_unchecked() } - } - - /// Attempts to acquire a reentrant mutex through an `Arc`. - /// - /// This method is similar to the `try_lock` method; however, it requires the `ReentrantMutex` to be inside - /// of an `Arc` and the resulting mutex guard has no lifetime requirements. - #[cfg(feature = "arc_lock")] - #[inline] - pub fn try_lock_arc(self: &Arc) -> Option> { - if self.raw.try_lock() { - // SAFETY: locking guarantee is upheld - Some(unsafe { self.make_arc_guard_unchecked() }) - } else { - None - } - } -} - -impl ReentrantMutex { - /// Forcibly unlocks the mutex using a fair unlock protocol. - /// - /// This is useful when combined with `mem::forget` to hold a lock without - /// the need to maintain a `ReentrantMutexGuard` object alive, for example when - /// dealing with FFI. - /// - /// # Safety - /// - /// This method must only be called if the current thread logically owns a - /// `ReentrantMutexGuard` but that guard has be discarded using `mem::forget`. - /// Behavior is undefined if a mutex is unlocked when not locked. - #[inline] - pub unsafe fn force_unlock_fair(&self) { - self.raw.unlock_fair(); - } -} - -impl ReentrantMutex { - /// Attempts to acquire this lock until a timeout is reached. - /// - /// If the lock could not be acquired before the timeout expired, then - /// `None` is returned. Otherwise, an RAII guard is returned. The lock will - /// be unlocked when the guard is dropped. - #[inline] - pub fn try_lock_for(&self, timeout: R::Duration) -> Option> { - if self.raw.try_lock_for(timeout) { - // SAFETY: The lock is held, as required. - Some(unsafe { self.make_guard_unchecked() }) - } else { - None - } - } - - /// Attempts to acquire this lock until a timeout is reached. - /// - /// If the lock could not be acquired before the timeout expired, then - /// `None` is returned. Otherwise, an RAII guard is returned. The lock will - /// be unlocked when the guard is dropped. - #[inline] - pub fn try_lock_until(&self, timeout: R::Instant) -> Option> { - if self.raw.try_lock_until(timeout) { - // SAFETY: The lock is held, as required. - Some(unsafe { self.make_guard_unchecked() }) - } else { - None - } - } - - /// Attempts to acquire this lock until a timeout is reached, through an `Arc`. - /// - /// This method is similar to the `try_lock_for` method; however, it requires the `ReentrantMutex` to be - /// inside of an `Arc` and the resulting mutex guard has no lifetime requirements. - #[cfg(feature = "arc_lock")] - #[inline] - pub fn try_lock_arc_for( - self: &Arc, - timeout: R::Duration, - ) -> Option> { - if self.raw.try_lock_for(timeout) { - // SAFETY: locking guarantee is upheld - Some(unsafe { self.make_arc_guard_unchecked() }) - } else { - None - } - } - - /// Attempts to acquire this lock until a timeout is reached, through an `Arc`. - /// - /// This method is similar to the `try_lock_until` method; however, it requires the `ReentrantMutex` to be - /// inside of an `Arc` and the resulting mutex guard has no lifetime requirements. - #[cfg(feature = "arc_lock")] - #[inline] - pub fn try_lock_arc_until( - self: &Arc, - timeout: R::Instant, - ) -> Option> { - if self.raw.try_lock_until(timeout) { - // SAFETY: locking guarantee is upheld - Some(unsafe { self.make_arc_guard_unchecked() }) - } else { - None - } - } -} - -impl Default for ReentrantMutex { - #[inline] - fn default() -> ReentrantMutex { - ReentrantMutex::new(Default::default()) - } -} - -impl From for ReentrantMutex { - #[inline] - fn from(t: T) -> ReentrantMutex { - ReentrantMutex::new(t) - } -} - -impl fmt::Debug for ReentrantMutex { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - match self.try_lock() { - Some(guard) => f - .debug_struct("ReentrantMutex") - .field("data", &&*guard) - .finish(), - None => { - struct LockedPlaceholder; - impl fmt::Debug for LockedPlaceholder { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.write_str("") - } - } - - f.debug_struct("ReentrantMutex") - .field("data", &LockedPlaceholder) - .finish() - } - } - } -} - -// Copied and modified from serde -#[cfg(feature = "serde")] -impl Serialize for ReentrantMutex -where - R: RawMutex, - G: GetThreadId, - T: Serialize + ?Sized, -{ - fn serialize(&self, serializer: S) -> Result - where - S: Serializer, - { - self.lock().serialize(serializer) - } -} - -#[cfg(feature = "serde")] -impl<'de, R, G, T> Deserialize<'de> for ReentrantMutex -where - R: RawMutex, - G: GetThreadId, - T: Deserialize<'de> + ?Sized, -{ - fn deserialize(deserializer: D) -> Result - where - D: Deserializer<'de>, - { - Deserialize::deserialize(deserializer).map(ReentrantMutex::new) - } -} - -/// An RAII implementation of a "scoped lock" of a reentrant mutex. When this structure -/// is dropped (falls out of scope), the lock will be unlocked. -/// -/// The data protected by the mutex can be accessed through this guard via its -/// `Deref` implementation. -#[clippy::has_significant_drop] -#[must_use = "if unused the ReentrantMutex will immediately unlock"] -pub struct ReentrantMutexGuard<'a, R: RawMutex, G: GetThreadId, T: ?Sized> { - remutex: &'a ReentrantMutex, - marker: PhantomData<(&'a T, GuardNoSend)>, -} - -unsafe impl<'a, R: RawMutex + Sync + 'a, G: GetThreadId + Sync + 'a, T: ?Sized + Sync + 'a> Sync - for ReentrantMutexGuard<'a, R, G, T> -{ -} - -impl<'a, R: RawMutex + 'a, G: GetThreadId + 'a, T: ?Sized + 'a> ReentrantMutexGuard<'a, R, G, T> { - /// Returns a reference to the original `ReentrantMutex` object. - pub fn remutex(s: &Self) -> &'a ReentrantMutex { - s.remutex - } - - /// Makes a new `MappedReentrantMutexGuard` for a component of the locked data. - /// - /// This operation cannot fail as the `ReentrantMutexGuard` passed - /// in already locked the mutex. - /// - /// This is an associated function that needs to be - /// used as `ReentrantMutexGuard::map(...)`. A method would interfere with methods of - /// the same name on the contents of the locked data. - #[inline] - pub fn map(s: Self, f: F) -> MappedReentrantMutexGuard<'a, R, G, U> - where - F: FnOnce(&T) -> &U, - { - let raw = &s.remutex.raw; - let data = f(unsafe { &*s.remutex.data.get() }); - mem::forget(s); - MappedReentrantMutexGuard { - raw, - data, - marker: PhantomData, - } - } - - /// Attempts to make a new `MappedReentrantMutexGuard` for a component of the - /// locked data. The original guard is return if the closure returns `None`. - /// - /// This operation cannot fail as the `ReentrantMutexGuard` passed - /// in already locked the mutex. - /// - /// This is an associated function that needs to be - /// used as `ReentrantMutexGuard::try_map(...)`. A method would interfere with methods of - /// the same name on the contents of the locked data. - #[inline] - pub fn try_map( - s: Self, - f: F, - ) -> Result, Self> - where - F: FnOnce(&T) -> Option<&U>, - { - let raw = &s.remutex.raw; - let data = match f(unsafe { &*s.remutex.data.get() }) { - Some(data) => data, - None => return Err(s), - }; - mem::forget(s); - Ok(MappedReentrantMutexGuard { - raw, - data, - marker: PhantomData, - }) - } - - /// Temporarily unlocks the mutex to execute the given function. - /// - /// This is safe because `&mut` guarantees that there exist no other - /// references to the data protected by the mutex. - #[inline] - pub fn unlocked(s: &mut Self, f: F) -> U - where - F: FnOnce() -> U, - { - // Safety: A ReentrantMutexGuard always holds the lock. - unsafe { - s.remutex.raw.unlock(); - } - defer!(s.remutex.raw.lock()); - f() - } -} - -impl<'a, R: RawMutexFair + 'a, G: GetThreadId + 'a, T: ?Sized + 'a> - ReentrantMutexGuard<'a, R, G, T> -{ - /// Unlocks the mutex using a fair unlock protocol. - /// - /// By default, mutexes are unfair and allow the current thread to re-lock - /// the mutex before another has the chance to acquire the lock, even if - /// that thread has been blocked on the mutex for a long time. This is the - /// default because it allows much higher throughput as it avoids forcing a - /// context switch on every mutex unlock. This can result in one thread - /// acquiring a mutex many more times than other threads. - /// - /// However in some cases it can be beneficial to ensure fairness by forcing - /// the lock to pass on to a waiting thread if there is one. This is done by - /// using this method instead of dropping the `ReentrantMutexGuard` normally. - #[inline] - pub fn unlock_fair(s: Self) { - // Safety: A ReentrantMutexGuard always holds the lock - unsafe { - s.remutex.raw.unlock_fair(); - } - mem::forget(s); - } - - /// Temporarily unlocks the mutex to execute the given function. - /// - /// The mutex is unlocked a fair unlock protocol. - /// - /// This is safe because `&mut` guarantees that there exist no other - /// references to the data protected by the mutex. - #[inline] - pub fn unlocked_fair(s: &mut Self, f: F) -> U - where - F: FnOnce() -> U, - { - // Safety: A ReentrantMutexGuard always holds the lock - unsafe { - s.remutex.raw.unlock_fair(); - } - defer!(s.remutex.raw.lock()); - f() - } - - /// Temporarily yields the mutex to a waiting thread if there is one. - /// - /// This method is functionally equivalent to calling `unlock_fair` followed - /// by `lock`, however it can be much more efficient in the case where there - /// are no waiting threads. - #[inline] - pub fn bump(s: &mut Self) { - // Safety: A ReentrantMutexGuard always holds the lock - unsafe { - s.remutex.raw.bump(); - } - } -} - -impl<'a, R: RawMutex + 'a, G: GetThreadId + 'a, T: ?Sized + 'a> Deref - for ReentrantMutexGuard<'a, R, G, T> -{ - type Target = T; - #[inline] - fn deref(&self) -> &T { - unsafe { &*self.remutex.data.get() } - } -} - -impl<'a, R: RawMutex + 'a, G: GetThreadId + 'a, T: ?Sized + 'a> Drop - for ReentrantMutexGuard<'a, R, G, T> -{ - #[inline] - fn drop(&mut self) { - // Safety: A ReentrantMutexGuard always holds the lock. - unsafe { - self.remutex.raw.unlock(); - } - } -} - -impl<'a, R: RawMutex + 'a, G: GetThreadId + 'a, T: fmt::Debug + ?Sized + 'a> fmt::Debug - for ReentrantMutexGuard<'a, R, G, T> -{ - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - fmt::Debug::fmt(&**self, f) - } -} - -impl<'a, R: RawMutex + 'a, G: GetThreadId + 'a, T: fmt::Display + ?Sized + 'a> fmt::Display - for ReentrantMutexGuard<'a, R, G, T> -{ - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - (**self).fmt(f) - } -} - -#[cfg(feature = "owning_ref")] -unsafe impl<'a, R: RawMutex + 'a, G: GetThreadId + 'a, T: ?Sized + 'a> StableAddress - for ReentrantMutexGuard<'a, R, G, T> -{ -} - -/// An RAII mutex guard returned by the `Arc` locking operations on `ReentrantMutex`. -/// -/// This is similar to the `ReentrantMutexGuard` struct, except instead of using a reference to unlock the -/// `Mutex` it uses an `Arc`. This has several advantages, most notably that it has an `'static` -/// lifetime. -#[cfg(feature = "arc_lock")] -#[clippy::has_significant_drop] -#[must_use = "if unused the ReentrantMutex will immediately unlock"] -pub struct ArcReentrantMutexGuard { - remutex: Arc>, - marker: PhantomData, -} - -#[cfg(feature = "arc_lock")] -impl ArcReentrantMutexGuard { - /// Returns a reference to the `ReentrantMutex` this object is guarding, contained in its `Arc`. - pub fn remutex(s: &Self) -> &Arc> { - &s.remutex - } - - /// Temporarily unlocks the mutex to execute the given function. - /// - /// This is safe because `&mut` guarantees that there exist no other - /// references to the data protected by the mutex. - #[inline] - pub fn unlocked(s: &mut Self, f: F) -> U - where - F: FnOnce() -> U, - { - // Safety: A ReentrantMutexGuard always holds the lock. - unsafe { - s.remutex.raw.unlock(); - } - defer!(s.remutex.raw.lock()); - f() - } -} - -#[cfg(feature = "arc_lock")] -impl ArcReentrantMutexGuard { - /// Unlocks the mutex using a fair unlock protocol. - /// - /// This is functionally identical to the `unlock_fair` method on [`ReentrantMutexGuard`]. - #[inline] - pub fn unlock_fair(s: Self) { - // Safety: A ReentrantMutexGuard always holds the lock - unsafe { - s.remutex.raw.unlock_fair(); - } - - // SAFETY: ensure that the Arc's refcount is decremented - let mut s = ManuallyDrop::new(s); - unsafe { ptr::drop_in_place(&mut s.remutex) }; - } - - /// Temporarily unlocks the mutex to execute the given function. - /// - /// This is functionally identical to the `unlocked_fair` method on [`ReentrantMutexGuard`]. - #[inline] - pub fn unlocked_fair(s: &mut Self, f: F) -> U - where - F: FnOnce() -> U, - { - // Safety: A ReentrantMutexGuard always holds the lock - unsafe { - s.remutex.raw.unlock_fair(); - } - defer!(s.remutex.raw.lock()); - f() - } - - /// Temporarily yields the mutex to a waiting thread if there is one. - /// - /// This is functionally equivalent to the `bump` method on [`ReentrantMutexGuard`]. - #[inline] - pub fn bump(s: &mut Self) { - // Safety: A ReentrantMutexGuard always holds the lock - unsafe { - s.remutex.raw.bump(); - } - } -} - -#[cfg(feature = "arc_lock")] -impl Deref for ArcReentrantMutexGuard { - type Target = T; - #[inline] - fn deref(&self) -> &T { - unsafe { &*self.remutex.data.get() } - } -} - -#[cfg(feature = "arc_lock")] -impl Drop for ArcReentrantMutexGuard { - #[inline] - fn drop(&mut self) { - // Safety: A ReentrantMutexGuard always holds the lock. - unsafe { - self.remutex.raw.unlock(); - } - } -} - -/// An RAII mutex guard returned by `ReentrantMutexGuard::map`, which can point to a -/// subfield of the protected data. -/// -/// The main difference between `MappedReentrantMutexGuard` and `ReentrantMutexGuard` is that the -/// former doesn't support temporarily unlocking and re-locking, since that -/// could introduce soundness issues if the locked object is modified by another -/// thread. -#[clippy::has_significant_drop] -#[must_use = "if unused the ReentrantMutex will immediately unlock"] -pub struct MappedReentrantMutexGuard<'a, R: RawMutex, G: GetThreadId, T: ?Sized> { - raw: &'a RawReentrantMutex, - data: *const T, - marker: PhantomData<&'a T>, -} - -unsafe impl<'a, R: RawMutex + Sync + 'a, G: GetThreadId + Sync + 'a, T: ?Sized + Sync + 'a> Sync - for MappedReentrantMutexGuard<'a, R, G, T> -{ -} - -impl<'a, R: RawMutex + 'a, G: GetThreadId + 'a, T: ?Sized + 'a> - MappedReentrantMutexGuard<'a, R, G, T> -{ - /// Makes a new `MappedReentrantMutexGuard` for a component of the locked data. - /// - /// This operation cannot fail as the `MappedReentrantMutexGuard` passed - /// in already locked the mutex. - /// - /// This is an associated function that needs to be - /// used as `MappedReentrantMutexGuard::map(...)`. A method would interfere with methods of - /// the same name on the contents of the locked data. - #[inline] - pub fn map(s: Self, f: F) -> MappedReentrantMutexGuard<'a, R, G, U> - where - F: FnOnce(&T) -> &U, - { - let raw = s.raw; - let data = f(unsafe { &*s.data }); - mem::forget(s); - MappedReentrantMutexGuard { - raw, - data, - marker: PhantomData, - } - } - - /// Attempts to make a new `MappedReentrantMutexGuard` for a component of the - /// locked data. The original guard is return if the closure returns `None`. - /// - /// This operation cannot fail as the `MappedReentrantMutexGuard` passed - /// in already locked the mutex. - /// - /// This is an associated function that needs to be - /// used as `MappedReentrantMutexGuard::try_map(...)`. A method would interfere with methods of - /// the same name on the contents of the locked data. - #[inline] - pub fn try_map( - s: Self, - f: F, - ) -> Result, Self> - where - F: FnOnce(&T) -> Option<&U>, - { - let raw = s.raw; - let data = match f(unsafe { &*s.data }) { - Some(data) => data, - None => return Err(s), - }; - mem::forget(s); - Ok(MappedReentrantMutexGuard { - raw, - data, - marker: PhantomData, - }) - } -} - -impl<'a, R: RawMutexFair + 'a, G: GetThreadId + 'a, T: ?Sized + 'a> - MappedReentrantMutexGuard<'a, R, G, T> -{ - /// Unlocks the mutex using a fair unlock protocol. - /// - /// By default, mutexes are unfair and allow the current thread to re-lock - /// the mutex before another has the chance to acquire the lock, even if - /// that thread has been blocked on the mutex for a long time. This is the - /// default because it allows much higher throughput as it avoids forcing a - /// context switch on every mutex unlock. This can result in one thread - /// acquiring a mutex many more times than other threads. - /// - /// However in some cases it can be beneficial to ensure fairness by forcing - /// the lock to pass on to a waiting thread if there is one. This is done by - /// using this method instead of dropping the `ReentrantMutexGuard` normally. - #[inline] - pub fn unlock_fair(s: Self) { - // Safety: A MappedReentrantMutexGuard always holds the lock - unsafe { - s.raw.unlock_fair(); - } - mem::forget(s); - } -} - -impl<'a, R: RawMutex + 'a, G: GetThreadId + 'a, T: ?Sized + 'a> Deref - for MappedReentrantMutexGuard<'a, R, G, T> -{ - type Target = T; - #[inline] - fn deref(&self) -> &T { - unsafe { &*self.data } - } -} - -impl<'a, R: RawMutex + 'a, G: GetThreadId + 'a, T: ?Sized + 'a> Drop - for MappedReentrantMutexGuard<'a, R, G, T> -{ - #[inline] - fn drop(&mut self) { - // Safety: A MappedReentrantMutexGuard always holds the lock. - unsafe { - self.raw.unlock(); - } - } -} - -impl<'a, R: RawMutex + 'a, G: GetThreadId + 'a, T: fmt::Debug + ?Sized + 'a> fmt::Debug - for MappedReentrantMutexGuard<'a, R, G, T> -{ - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - fmt::Debug::fmt(&**self, f) - } -} - -impl<'a, R: RawMutex + 'a, G: GetThreadId + 'a, T: fmt::Display + ?Sized + 'a> fmt::Display - for MappedReentrantMutexGuard<'a, R, G, T> -{ - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - (**self).fmt(f) - } -} - -#[cfg(feature = "owning_ref")] -unsafe impl<'a, R: RawMutex + 'a, G: GetThreadId + 'a, T: ?Sized + 'a> StableAddress - for MappedReentrantMutexGuard<'a, R, G, T> -{ -} diff --git a/third-party/vendor/lock_api/src/rwlock.rs b/third-party/vendor/lock_api/src/rwlock.rs deleted file mode 100644 index cf9e8aa0..00000000 --- a/third-party/vendor/lock_api/src/rwlock.rs +++ /dev/null @@ -1,2883 +0,0 @@ -// Copyright 2016 Amanieu d'Antras -// -// Licensed under the Apache License, Version 2.0, or the MIT license , at your option. This file may not be -// copied, modified, or distributed except according to those terms. - -use core::cell::UnsafeCell; -use core::fmt; -use core::marker::PhantomData; -use core::mem; -use core::ops::{Deref, DerefMut}; - -#[cfg(feature = "arc_lock")] -use alloc::sync::Arc; -#[cfg(feature = "arc_lock")] -use core::mem::ManuallyDrop; -#[cfg(feature = "arc_lock")] -use core::ptr; - -#[cfg(feature = "owning_ref")] -use owning_ref::StableAddress; - -#[cfg(feature = "serde")] -use serde::{Deserialize, Deserializer, Serialize, Serializer}; - -/// Basic operations for a reader-writer lock. -/// -/// Types implementing this trait can be used by `RwLock` to form a safe and -/// fully-functioning `RwLock` type. -/// -/// # Safety -/// -/// Implementations of this trait must ensure that the `RwLock` is actually -/// exclusive: an exclusive lock can't be acquired while an exclusive or shared -/// lock exists, and a shared lock can't be acquire while an exclusive lock -/// exists. -pub unsafe trait RawRwLock { - /// Initial value for an unlocked `RwLock`. - // A “non-constant” const item is a legacy way to supply an initialized value to downstream - // static items. Can hopefully be replaced with `const fn new() -> Self` at some point. - #[allow(clippy::declare_interior_mutable_const)] - const INIT: Self; - - /// Marker type which determines whether a lock guard should be `Send`. Use - /// one of the `GuardSend` or `GuardNoSend` helper types here. - type GuardMarker; - - /// Acquires a shared lock, blocking the current thread until it is able to do so. - fn lock_shared(&self); - - /// Attempts to acquire a shared lock without blocking. - fn try_lock_shared(&self) -> bool; - - /// Releases a shared lock. - /// - /// # Safety - /// - /// This method may only be called if a shared lock is held in the current context. - unsafe fn unlock_shared(&self); - - /// Acquires an exclusive lock, blocking the current thread until it is able to do so. - fn lock_exclusive(&self); - - /// Attempts to acquire an exclusive lock without blocking. - fn try_lock_exclusive(&self) -> bool; - - /// Releases an exclusive lock. - /// - /// # Safety - /// - /// This method may only be called if an exclusive lock is held in the current context. - unsafe fn unlock_exclusive(&self); - - /// Checks if this `RwLock` is currently locked in any way. - #[inline] - fn is_locked(&self) -> bool { - let acquired_lock = self.try_lock_exclusive(); - if acquired_lock { - // Safety: A lock was successfully acquired above. - unsafe { - self.unlock_exclusive(); - } - } - !acquired_lock - } - - /// Check if this `RwLock` is currently exclusively locked. - fn is_locked_exclusive(&self) -> bool { - let acquired_lock = self.try_lock_shared(); - if acquired_lock { - // Safety: A shared lock was successfully acquired above. - unsafe { - self.unlock_shared(); - } - } - !acquired_lock - } -} - -/// Additional methods for RwLocks which support fair unlocking. -/// -/// Fair unlocking means that a lock is handed directly over to the next waiting -/// thread if there is one, without giving other threads the opportunity to -/// "steal" the lock in the meantime. This is typically slower than unfair -/// unlocking, but may be necessary in certain circumstances. -pub unsafe trait RawRwLockFair: RawRwLock { - /// Releases a shared lock using a fair unlock protocol. - /// - /// # Safety - /// - /// This method may only be called if a shared lock is held in the current context. - unsafe fn unlock_shared_fair(&self); - - /// Releases an exclusive lock using a fair unlock protocol. - /// - /// # Safety - /// - /// This method may only be called if an exclusive lock is held in the current context. - unsafe fn unlock_exclusive_fair(&self); - - /// Temporarily yields a shared lock to a waiting thread if there is one. - /// - /// This method is functionally equivalent to calling `unlock_shared_fair` followed - /// by `lock_shared`, however it can be much more efficient in the case where there - /// are no waiting threads. - /// - /// # Safety - /// - /// This method may only be called if a shared lock is held in the current context. - unsafe fn bump_shared(&self) { - self.unlock_shared_fair(); - self.lock_shared(); - } - - /// Temporarily yields an exclusive lock to a waiting thread if there is one. - /// - /// This method is functionally equivalent to calling `unlock_exclusive_fair` followed - /// by `lock_exclusive`, however it can be much more efficient in the case where there - /// are no waiting threads. - /// - /// # Safety - /// - /// This method may only be called if an exclusive lock is held in the current context. - unsafe fn bump_exclusive(&self) { - self.unlock_exclusive_fair(); - self.lock_exclusive(); - } -} - -/// Additional methods for RwLocks which support atomically downgrading an -/// exclusive lock to a shared lock. -pub unsafe trait RawRwLockDowngrade: RawRwLock { - /// Atomically downgrades an exclusive lock into a shared lock without - /// allowing any thread to take an exclusive lock in the meantime. - /// - /// # Safety - /// - /// This method may only be called if an exclusive lock is held in the current context. - unsafe fn downgrade(&self); -} - -/// Additional methods for RwLocks which support locking with timeouts. -/// -/// The `Duration` and `Instant` types are specified as associated types so that -/// this trait is usable even in `no_std` environments. -pub unsafe trait RawRwLockTimed: RawRwLock { - /// Duration type used for `try_lock_for`. - type Duration; - - /// Instant type used for `try_lock_until`. - type Instant; - - /// Attempts to acquire a shared lock until a timeout is reached. - fn try_lock_shared_for(&self, timeout: Self::Duration) -> bool; - - /// Attempts to acquire a shared lock until a timeout is reached. - fn try_lock_shared_until(&self, timeout: Self::Instant) -> bool; - - /// Attempts to acquire an exclusive lock until a timeout is reached. - fn try_lock_exclusive_for(&self, timeout: Self::Duration) -> bool; - - /// Attempts to acquire an exclusive lock until a timeout is reached. - fn try_lock_exclusive_until(&self, timeout: Self::Instant) -> bool; -} - -/// Additional methods for RwLocks which support recursive read locks. -/// -/// These are guaranteed to succeed without blocking if -/// another read lock is held at the time of the call. This allows a thread -/// to recursively lock a `RwLock`. However using this method can cause -/// writers to starve since readers no longer block if a writer is waiting -/// for the lock. -pub unsafe trait RawRwLockRecursive: RawRwLock { - /// Acquires a shared lock without deadlocking in case of a recursive lock. - fn lock_shared_recursive(&self); - - /// Attempts to acquire a shared lock without deadlocking in case of a recursive lock. - fn try_lock_shared_recursive(&self) -> bool; -} - -/// Additional methods for RwLocks which support recursive read locks and timeouts. -pub unsafe trait RawRwLockRecursiveTimed: RawRwLockRecursive + RawRwLockTimed { - /// Attempts to acquire a shared lock until a timeout is reached, without - /// deadlocking in case of a recursive lock. - fn try_lock_shared_recursive_for(&self, timeout: Self::Duration) -> bool; - - /// Attempts to acquire a shared lock until a timeout is reached, without - /// deadlocking in case of a recursive lock. - fn try_lock_shared_recursive_until(&self, timeout: Self::Instant) -> bool; -} - -/// Additional methods for RwLocks which support atomically upgrading a shared -/// lock to an exclusive lock. -/// -/// This requires acquiring a special "upgradable read lock" instead of a -/// normal shared lock. There may only be one upgradable lock at any time, -/// otherwise deadlocks could occur when upgrading. -pub unsafe trait RawRwLockUpgrade: RawRwLock { - /// Acquires an upgradable lock, blocking the current thread until it is able to do so. - fn lock_upgradable(&self); - - /// Attempts to acquire an upgradable lock without blocking. - fn try_lock_upgradable(&self) -> bool; - - /// Releases an upgradable lock. - /// - /// # Safety - /// - /// This method may only be called if an upgradable lock is held in the current context. - unsafe fn unlock_upgradable(&self); - - /// Upgrades an upgradable lock to an exclusive lock. - /// - /// # Safety - /// - /// This method may only be called if an upgradable lock is held in the current context. - unsafe fn upgrade(&self); - - /// Attempts to upgrade an upgradable lock to an exclusive lock without - /// blocking. - /// - /// # Safety - /// - /// This method may only be called if an upgradable lock is held in the current context. - unsafe fn try_upgrade(&self) -> bool; -} - -/// Additional methods for RwLocks which support upgradable locks and fair -/// unlocking. -pub unsafe trait RawRwLockUpgradeFair: RawRwLockUpgrade + RawRwLockFair { - /// Releases an upgradable lock using a fair unlock protocol. - /// - /// # Safety - /// - /// This method may only be called if an upgradable lock is held in the current context. - unsafe fn unlock_upgradable_fair(&self); - - /// Temporarily yields an upgradable lock to a waiting thread if there is one. - /// - /// This method is functionally equivalent to calling `unlock_upgradable_fair` followed - /// by `lock_upgradable`, however it can be much more efficient in the case where there - /// are no waiting threads. - /// - /// # Safety - /// - /// This method may only be called if an upgradable lock is held in the current context. - unsafe fn bump_upgradable(&self) { - self.unlock_upgradable_fair(); - self.lock_upgradable(); - } -} - -/// Additional methods for RwLocks which support upgradable locks and lock -/// downgrading. -pub unsafe trait RawRwLockUpgradeDowngrade: RawRwLockUpgrade + RawRwLockDowngrade { - /// Downgrades an upgradable lock to a shared lock. - /// - /// # Safety - /// - /// This method may only be called if an upgradable lock is held in the current context. - unsafe fn downgrade_upgradable(&self); - - /// Downgrades an exclusive lock to an upgradable lock. - /// - /// # Safety - /// - /// This method may only be called if an exclusive lock is held in the current context. - unsafe fn downgrade_to_upgradable(&self); -} - -/// Additional methods for RwLocks which support upgradable locks and locking -/// with timeouts. -pub unsafe trait RawRwLockUpgradeTimed: RawRwLockUpgrade + RawRwLockTimed { - /// Attempts to acquire an upgradable lock until a timeout is reached. - fn try_lock_upgradable_for(&self, timeout: Self::Duration) -> bool; - - /// Attempts to acquire an upgradable lock until a timeout is reached. - fn try_lock_upgradable_until(&self, timeout: Self::Instant) -> bool; - - /// Attempts to upgrade an upgradable lock to an exclusive lock until a - /// timeout is reached. - /// - /// # Safety - /// - /// This method may only be called if an upgradable lock is held in the current context. - unsafe fn try_upgrade_for(&self, timeout: Self::Duration) -> bool; - - /// Attempts to upgrade an upgradable lock to an exclusive lock until a - /// timeout is reached. - /// - /// # Safety - /// - /// This method may only be called if an upgradable lock is held in the current context. - unsafe fn try_upgrade_until(&self, timeout: Self::Instant) -> bool; -} - -/// A reader-writer lock -/// -/// This type of lock allows a number of readers or at most one writer at any -/// point in time. The write portion of this lock typically allows modification -/// of the underlying data (exclusive access) and the read portion of this lock -/// typically allows for read-only access (shared access). -/// -/// The type parameter `T` represents the data that this lock protects. It is -/// required that `T` satisfies `Send` to be shared across threads and `Sync` to -/// allow concurrent access through readers. The RAII guards returned from the -/// locking methods implement `Deref` (and `DerefMut` for the `write` methods) -/// to allow access to the contained of the lock. -pub struct RwLock { - raw: R, - data: UnsafeCell, -} - -// Copied and modified from serde -#[cfg(feature = "serde")] -impl Serialize for RwLock -where - R: RawRwLock, - T: Serialize + ?Sized, -{ - fn serialize(&self, serializer: S) -> Result - where - S: Serializer, - { - self.read().serialize(serializer) - } -} - -#[cfg(feature = "serde")] -impl<'de, R, T> Deserialize<'de> for RwLock -where - R: RawRwLock, - T: Deserialize<'de> + ?Sized, -{ - fn deserialize(deserializer: D) -> Result - where - D: Deserializer<'de>, - { - Deserialize::deserialize(deserializer).map(RwLock::new) - } -} - -unsafe impl Send for RwLock {} -unsafe impl Sync for RwLock {} - -impl RwLock { - /// Creates a new instance of an `RwLock` which is unlocked. - #[cfg(has_const_fn_trait_bound)] - #[inline] - pub const fn new(val: T) -> RwLock { - RwLock { - data: UnsafeCell::new(val), - raw: R::INIT, - } - } - - /// Creates a new instance of an `RwLock` which is unlocked. - #[cfg(not(has_const_fn_trait_bound))] - #[inline] - pub fn new(val: T) -> RwLock { - RwLock { - data: UnsafeCell::new(val), - raw: R::INIT, - } - } - - /// Consumes this `RwLock`, returning the underlying data. - #[inline] - #[allow(unused_unsafe)] - pub fn into_inner(self) -> T { - unsafe { self.data.into_inner() } - } -} - -impl RwLock { - /// Creates a new new instance of an `RwLock` based on a pre-existing - /// `RawRwLock`. - /// - /// This allows creating a `RwLock` in a constant context on stable - /// Rust. - #[inline] - pub const fn const_new(raw_rwlock: R, val: T) -> RwLock { - RwLock { - data: UnsafeCell::new(val), - raw: raw_rwlock, - } - } -} - -impl RwLock { - /// Creates a new `RwLockReadGuard` without checking if the lock is held. - /// - /// # Safety - /// - /// This method must only be called if the thread logically holds a read lock. - /// - /// This function does not increment the read count of the lock. Calling this function when a - /// guard has already been produced is undefined behaviour unless the guard was forgotten - /// with `mem::forget`.` - #[inline] - pub unsafe fn make_read_guard_unchecked(&self) -> RwLockReadGuard<'_, R, T> { - RwLockReadGuard { - rwlock: self, - marker: PhantomData, - } - } - - /// Creates a new `RwLockReadGuard` without checking if the lock is held. - /// - /// # Safety - /// - /// This method must only be called if the thread logically holds a write lock. - /// - /// Calling this function when a guard has already been produced is undefined behaviour unless - /// the guard was forgotten with `mem::forget`. - #[inline] - pub unsafe fn make_write_guard_unchecked(&self) -> RwLockWriteGuard<'_, R, T> { - RwLockWriteGuard { - rwlock: self, - marker: PhantomData, - } - } - - /// Locks this `RwLock` with shared read access, blocking the current thread - /// until it can be acquired. - /// - /// The calling thread will be blocked until there are no more writers which - /// hold the lock. There may be other readers currently inside the lock when - /// this method returns. - /// - /// Note that attempts to recursively acquire a read lock on a `RwLock` when - /// the current thread already holds one may result in a deadlock. - /// - /// Returns an RAII guard which will release this thread's shared access - /// once it is dropped. - #[inline] - pub fn read(&self) -> RwLockReadGuard<'_, R, T> { - self.raw.lock_shared(); - // SAFETY: The lock is held, as required. - unsafe { self.make_read_guard_unchecked() } - } - - /// Attempts to acquire this `RwLock` with shared read access. - /// - /// If the access could not be granted at this time, then `None` is returned. - /// Otherwise, an RAII guard is returned which will release the shared access - /// when it is dropped. - /// - /// This function does not block. - #[inline] - pub fn try_read(&self) -> Option> { - if self.raw.try_lock_shared() { - // SAFETY: The lock is held, as required. - Some(unsafe { self.make_read_guard_unchecked() }) - } else { - None - } - } - - /// Locks this `RwLock` with exclusive write access, blocking the current - /// thread until it can be acquired. - /// - /// This function will not return while other writers or other readers - /// currently have access to the lock. - /// - /// Returns an RAII guard which will drop the write access of this `RwLock` - /// when dropped. - #[inline] - pub fn write(&self) -> RwLockWriteGuard<'_, R, T> { - self.raw.lock_exclusive(); - // SAFETY: The lock is held, as required. - unsafe { self.make_write_guard_unchecked() } - } - - /// Attempts to lock this `RwLock` with exclusive write access. - /// - /// If the lock could not be acquired at this time, then `None` is returned. - /// Otherwise, an RAII guard is returned which will release the lock when - /// it is dropped. - /// - /// This function does not block. - #[inline] - pub fn try_write(&self) -> Option> { - if self.raw.try_lock_exclusive() { - // SAFETY: The lock is held, as required. - Some(unsafe { self.make_write_guard_unchecked() }) - } else { - None - } - } - - /// Returns a mutable reference to the underlying data. - /// - /// Since this call borrows the `RwLock` mutably, no actual locking needs to - /// take place---the mutable borrow statically guarantees no locks exist. - #[inline] - pub fn get_mut(&mut self) -> &mut T { - unsafe { &mut *self.data.get() } - } - - /// Checks whether this `RwLock` is currently locked in any way. - #[inline] - pub fn is_locked(&self) -> bool { - self.raw.is_locked() - } - - /// Check if this `RwLock` is currently exclusively locked. - #[inline] - pub fn is_locked_exclusive(&self) -> bool { - self.raw.is_locked_exclusive() - } - - /// Forcibly unlocks a read lock. - /// - /// This is useful when combined with `mem::forget` to hold a lock without - /// the need to maintain a `RwLockReadGuard` object alive, for example when - /// dealing with FFI. - /// - /// # Safety - /// - /// This method must only be called if the current thread logically owns a - /// `RwLockReadGuard` but that guard has be discarded using `mem::forget`. - /// Behavior is undefined if a rwlock is read-unlocked when not read-locked. - #[inline] - pub unsafe fn force_unlock_read(&self) { - self.raw.unlock_shared(); - } - - /// Forcibly unlocks a write lock. - /// - /// This is useful when combined with `mem::forget` to hold a lock without - /// the need to maintain a `RwLockWriteGuard` object alive, for example when - /// dealing with FFI. - /// - /// # Safety - /// - /// This method must only be called if the current thread logically owns a - /// `RwLockWriteGuard` but that guard has be discarded using `mem::forget`. - /// Behavior is undefined if a rwlock is write-unlocked when not write-locked. - #[inline] - pub unsafe fn force_unlock_write(&self) { - self.raw.unlock_exclusive(); - } - - /// Returns the underlying raw reader-writer lock object. - /// - /// Note that you will most likely need to import the `RawRwLock` trait from - /// `lock_api` to be able to call functions on the raw - /// reader-writer lock. - /// - /// # Safety - /// - /// This method is unsafe because it allows unlocking a mutex while - /// still holding a reference to a lock guard. - pub unsafe fn raw(&self) -> &R { - &self.raw - } - - /// Returns a raw pointer to the underlying data. - /// - /// This is useful when combined with `mem::forget` to hold a lock without - /// the need to maintain a `RwLockReadGuard` or `RwLockWriteGuard` object - /// alive, for example when dealing with FFI. - /// - /// # Safety - /// - /// You must ensure that there are no data races when dereferencing the - /// returned pointer, for example if the current thread logically owns a - /// `RwLockReadGuard` or `RwLockWriteGuard` but that guard has been discarded - /// using `mem::forget`. - #[inline] - pub fn data_ptr(&self) -> *mut T { - self.data.get() - } - - /// Creates a new `RwLockReadGuard` without checking if the lock is held. - /// - /// # Safety - /// - /// This method must only be called if the thread logically holds a read lock. - /// - /// This function does not increment the read count of the lock. Calling this function when a - /// guard has already been produced is undefined behaviour unless the guard was forgotten - /// with `mem::forget`.` - #[cfg(feature = "arc_lock")] - #[inline] - pub unsafe fn make_arc_read_guard_unchecked(self: &Arc) -> ArcRwLockReadGuard { - ArcRwLockReadGuard { - rwlock: self.clone(), - marker: PhantomData, - } - } - - /// Creates a new `RwLockWriteGuard` without checking if the lock is held. - /// - /// # Safety - /// - /// This method must only be called if the thread logically holds a write lock. - /// - /// Calling this function when a guard has already been produced is undefined behaviour unless - /// the guard was forgotten with `mem::forget`. - #[cfg(feature = "arc_lock")] - #[inline] - pub unsafe fn make_arc_write_guard_unchecked(self: &Arc) -> ArcRwLockWriteGuard { - ArcRwLockWriteGuard { - rwlock: self.clone(), - marker: PhantomData, - } - } - - /// Locks this `RwLock` with read access, through an `Arc`. - /// - /// This method is similar to the `read` method; however, it requires the `RwLock` to be inside of an `Arc` - /// and the resulting read guard has no lifetime requirements. - #[cfg(feature = "arc_lock")] - #[inline] - pub fn read_arc(self: &Arc) -> ArcRwLockReadGuard { - self.raw.lock_shared(); - // SAFETY: locking guarantee is upheld - unsafe { self.make_arc_read_guard_unchecked() } - } - - /// Attempts to lock this `RwLock` with read access, through an `Arc`. - /// - /// This method is similar to the `try_read` method; however, it requires the `RwLock` to be inside of an - /// `Arc` and the resulting read guard has no lifetime requirements. - #[cfg(feature = "arc_lock")] - #[inline] - pub fn try_read_arc(self: &Arc) -> Option> { - if self.raw.try_lock_shared() { - // SAFETY: locking guarantee is upheld - Some(unsafe { self.make_arc_read_guard_unchecked() }) - } else { - None - } - } - - /// Locks this `RwLock` with write access, through an `Arc`. - /// - /// This method is similar to the `write` method; however, it requires the `RwLock` to be inside of an `Arc` - /// and the resulting write guard has no lifetime requirements. - #[cfg(feature = "arc_lock")] - #[inline] - pub fn write_arc(self: &Arc) -> ArcRwLockWriteGuard { - self.raw.lock_exclusive(); - // SAFETY: locking guarantee is upheld - unsafe { self.make_arc_write_guard_unchecked() } - } - - /// Attempts to lock this `RwLock` with writ access, through an `Arc`. - /// - /// This method is similar to the `try_write` method; however, it requires the `RwLock` to be inside of an - /// `Arc` and the resulting write guard has no lifetime requirements. - #[cfg(feature = "arc_lock")] - #[inline] - pub fn try_write_arc(self: &Arc) -> Option> { - if self.raw.try_lock_exclusive() { - // SAFETY: locking guarantee is upheld - Some(unsafe { self.make_arc_write_guard_unchecked() }) - } else { - None - } - } -} - -impl RwLock { - /// Forcibly unlocks a read lock using a fair unlock procotol. - /// - /// This is useful when combined with `mem::forget` to hold a lock without - /// the need to maintain a `RwLockReadGuard` object alive, for example when - /// dealing with FFI. - /// - /// # Safety - /// - /// This method must only be called if the current thread logically owns a - /// `RwLockReadGuard` but that guard has be discarded using `mem::forget`. - /// Behavior is undefined if a rwlock is read-unlocked when not read-locked. - #[inline] - pub unsafe fn force_unlock_read_fair(&self) { - self.raw.unlock_shared_fair(); - } - - /// Forcibly unlocks a write lock using a fair unlock procotol. - /// - /// This is useful when combined with `mem::forget` to hold a lock without - /// the need to maintain a `RwLockWriteGuard` object alive, for example when - /// dealing with FFI. - /// - /// # Safety - /// - /// This method must only be called if the current thread logically owns a - /// `RwLockWriteGuard` but that guard has be discarded using `mem::forget`. - /// Behavior is undefined if a rwlock is write-unlocked when not write-locked. - #[inline] - pub unsafe fn force_unlock_write_fair(&self) { - self.raw.unlock_exclusive_fair(); - } -} - -impl RwLock { - /// Attempts to acquire this `RwLock` with shared read access until a timeout - /// is reached. - /// - /// If the access could not be granted before the timeout expires, then - /// `None` is returned. Otherwise, an RAII guard is returned which will - /// release the shared access when it is dropped. - #[inline] - pub fn try_read_for(&self, timeout: R::Duration) -> Option> { - if self.raw.try_lock_shared_for(timeout) { - // SAFETY: The lock is held, as required. - Some(unsafe { self.make_read_guard_unchecked() }) - } else { - None - } - } - - /// Attempts to acquire this `RwLock` with shared read access until a timeout - /// is reached. - /// - /// If the access could not be granted before the timeout expires, then - /// `None` is returned. Otherwise, an RAII guard is returned which will - /// release the shared access when it is dropped. - #[inline] - pub fn try_read_until(&self, timeout: R::Instant) -> Option> { - if self.raw.try_lock_shared_until(timeout) { - // SAFETY: The lock is held, as required. - Some(unsafe { self.make_read_guard_unchecked() }) - } else { - None - } - } - - /// Attempts to acquire this `RwLock` with exclusive write access until a - /// timeout is reached. - /// - /// If the access could not be granted before the timeout expires, then - /// `None` is returned. Otherwise, an RAII guard is returned which will - /// release the exclusive access when it is dropped. - #[inline] - pub fn try_write_for(&self, timeout: R::Duration) -> Option> { - if self.raw.try_lock_exclusive_for(timeout) { - // SAFETY: The lock is held, as required. - Some(unsafe { self.make_write_guard_unchecked() }) - } else { - None - } - } - - /// Attempts to acquire this `RwLock` with exclusive write access until a - /// timeout is reached. - /// - /// If the access could not be granted before the timeout expires, then - /// `None` is returned. Otherwise, an RAII guard is returned which will - /// release the exclusive access when it is dropped. - #[inline] - pub fn try_write_until(&self, timeout: R::Instant) -> Option> { - if self.raw.try_lock_exclusive_until(timeout) { - // SAFETY: The lock is held, as required. - Some(unsafe { self.make_write_guard_unchecked() }) - } else { - None - } - } - - /// Attempts to acquire this `RwLock` with read access until a timeout is reached, through an `Arc`. - /// - /// This method is similar to the `try_read_for` method; however, it requires the `RwLock` to be inside of an - /// `Arc` and the resulting read guard has no lifetime requirements. - #[cfg(feature = "arc_lock")] - #[inline] - pub fn try_read_arc_for( - self: &Arc, - timeout: R::Duration, - ) -> Option> { - if self.raw.try_lock_shared_for(timeout) { - // SAFETY: locking guarantee is upheld - Some(unsafe { self.make_arc_read_guard_unchecked() }) - } else { - None - } - } - - /// Attempts to acquire this `RwLock` with read access until a timeout is reached, through an `Arc`. - /// - /// This method is similar to the `try_read_until` method; however, it requires the `RwLock` to be inside of - /// an `Arc` and the resulting read guard has no lifetime requirements. - #[cfg(feature = "arc_lock")] - #[inline] - pub fn try_read_arc_until( - self: &Arc, - timeout: R::Instant, - ) -> Option> { - if self.raw.try_lock_shared_until(timeout) { - // SAFETY: locking guarantee is upheld - Some(unsafe { self.make_arc_read_guard_unchecked() }) - } else { - None - } - } - - /// Attempts to acquire this `RwLock` with write access until a timeout is reached, through an `Arc`. - /// - /// This method is similar to the `try_write_for` method; however, it requires the `RwLock` to be inside of - /// an `Arc` and the resulting write guard has no lifetime requirements. - #[cfg(feature = "arc_lock")] - #[inline] - pub fn try_write_arc_for( - self: &Arc, - timeout: R::Duration, - ) -> Option> { - if self.raw.try_lock_exclusive_for(timeout) { - // SAFETY: locking guarantee is upheld - Some(unsafe { self.make_arc_write_guard_unchecked() }) - } else { - None - } - } - - /// Attempts to acquire this `RwLock` with read access until a timeout is reached, through an `Arc`. - /// - /// This method is similar to the `try_write_until` method; however, it requires the `RwLock` to be inside of - /// an `Arc` and the resulting read guard has no lifetime requirements. - #[cfg(feature = "arc_lock")] - #[inline] - pub fn try_write_arc_until( - self: &Arc, - timeout: R::Instant, - ) -> Option> { - if self.raw.try_lock_exclusive_until(timeout) { - // SAFETY: locking guarantee is upheld - Some(unsafe { self.make_arc_write_guard_unchecked() }) - } else { - None - } - } -} - -impl RwLock { - /// Locks this `RwLock` with shared read access, blocking the current thread - /// until it can be acquired. - /// - /// The calling thread will be blocked until there are no more writers which - /// hold the lock. There may be other readers currently inside the lock when - /// this method returns. - /// - /// Unlike `read`, this method is guaranteed to succeed without blocking if - /// another read lock is held at the time of the call. This allows a thread - /// to recursively lock a `RwLock`. However using this method can cause - /// writers to starve since readers no longer block if a writer is waiting - /// for the lock. - /// - /// Returns an RAII guard which will release this thread's shared access - /// once it is dropped. - #[inline] - pub fn read_recursive(&self) -> RwLockReadGuard<'_, R, T> { - self.raw.lock_shared_recursive(); - // SAFETY: The lock is held, as required. - unsafe { self.make_read_guard_unchecked() } - } - - /// Attempts to acquire this `RwLock` with shared read access. - /// - /// If the access could not be granted at this time, then `None` is returned. - /// Otherwise, an RAII guard is returned which will release the shared access - /// when it is dropped. - /// - /// This method is guaranteed to succeed if another read lock is held at the - /// time of the call. See the documentation for `read_recursive` for details. - /// - /// This function does not block. - #[inline] - pub fn try_read_recursive(&self) -> Option> { - if self.raw.try_lock_shared_recursive() { - // SAFETY: The lock is held, as required. - Some(unsafe { self.make_read_guard_unchecked() }) - } else { - None - } - } - - /// Locks this `RwLock` with shared read access, through an `Arc`. - /// - /// This method is similar to the `read_recursive` method; however, it requires the `RwLock` to be inside of - /// an `Arc` and the resulting read guard has no lifetime requirements. - #[cfg(feature = "arc_lock")] - #[inline] - pub fn read_arc_recursive(self: &Arc) -> ArcRwLockReadGuard { - self.raw.lock_shared_recursive(); - // SAFETY: locking guarantee is upheld - unsafe { self.make_arc_read_guard_unchecked() } - } - - /// Attempts to lock this `RwLock` with shared read access, through an `Arc`. - /// - /// This method is similar to the `try_read_recursive` method; however, it requires the `RwLock` to be inside - /// of an `Arc` and the resulting read guard has no lifetime requirements. - #[cfg(feature = "arc_lock")] - #[inline] - pub fn try_read_recursive_arc(self: &Arc) -> Option> { - if self.raw.try_lock_shared_recursive() { - // SAFETY: locking guarantee is upheld - Some(unsafe { self.make_arc_read_guard_unchecked() }) - } else { - None - } - } -} - -impl RwLock { - /// Attempts to acquire this `RwLock` with shared read access until a timeout - /// is reached. - /// - /// If the access could not be granted before the timeout expires, then - /// `None` is returned. Otherwise, an RAII guard is returned which will - /// release the shared access when it is dropped. - /// - /// This method is guaranteed to succeed without blocking if another read - /// lock is held at the time of the call. See the documentation for - /// `read_recursive` for details. - #[inline] - pub fn try_read_recursive_for( - &self, - timeout: R::Duration, - ) -> Option> { - if self.raw.try_lock_shared_recursive_for(timeout) { - // SAFETY: The lock is held, as required. - Some(unsafe { self.make_read_guard_unchecked() }) - } else { - None - } - } - - /// Attempts to acquire this `RwLock` with shared read access until a timeout - /// is reached. - /// - /// If the access could not be granted before the timeout expires, then - /// `None` is returned. Otherwise, an RAII guard is returned which will - /// release the shared access when it is dropped. - #[inline] - pub fn try_read_recursive_until( - &self, - timeout: R::Instant, - ) -> Option> { - if self.raw.try_lock_shared_recursive_until(timeout) { - // SAFETY: The lock is held, as required. - Some(unsafe { self.make_read_guard_unchecked() }) - } else { - None - } - } - - /// Attempts to lock this `RwLock` with read access until a timeout is reached, through an `Arc`. - /// - /// This method is similar to the `try_read_recursive_for` method; however, it requires the `RwLock` to be - /// inside of an `Arc` and the resulting read guard has no lifetime requirements. - #[cfg(feature = "arc_lock")] - #[inline] - pub fn try_read_arc_recursive_for( - self: &Arc, - timeout: R::Duration, - ) -> Option> { - if self.raw.try_lock_shared_recursive_for(timeout) { - // SAFETY: locking guarantee is upheld - Some(unsafe { self.make_arc_read_guard_unchecked() }) - } else { - None - } - } - - /// Attempts to lock this `RwLock` with read access until a timeout is reached, through an `Arc`. - /// - /// This method is similar to the `try_read_recursive_until` method; however, it requires the `RwLock` to be - /// inside of an `Arc` and the resulting read guard has no lifetime requirements. - #[cfg(feature = "arc_lock")] - #[inline] - pub fn try_read_arc_recursive_until( - self: &Arc, - timeout: R::Instant, - ) -> Option> { - if self.raw.try_lock_shared_recursive_until(timeout) { - // SAFETY: locking guarantee is upheld - Some(unsafe { self.make_arc_read_guard_unchecked() }) - } else { - None - } - } -} - -impl RwLock { - /// Creates a new `RwLockUpgradableReadGuard` without checking if the lock is held. - /// - /// # Safety - /// - /// This method must only be called if the thread logically holds an upgradable read lock. - /// - /// This function does not increment the read count of the lock. Calling this function when a - /// guard has already been produced is undefined behaviour unless the guard was forgotten - /// with `mem::forget`.` - #[inline] - pub unsafe fn make_upgradable_guard_unchecked(&self) -> RwLockUpgradableReadGuard<'_, R, T> { - RwLockUpgradableReadGuard { - rwlock: self, - marker: PhantomData, - } - } - - /// Locks this `RwLock` with upgradable read access, blocking the current thread - /// until it can be acquired. - /// - /// The calling thread will be blocked until there are no more writers or other - /// upgradable reads which hold the lock. There may be other readers currently - /// inside the lock when this method returns. - /// - /// Returns an RAII guard which will release this thread's shared access - /// once it is dropped. - #[inline] - pub fn upgradable_read(&self) -> RwLockUpgradableReadGuard<'_, R, T> { - self.raw.lock_upgradable(); - // SAFETY: The lock is held, as required. - unsafe { self.make_upgradable_guard_unchecked() } - } - - /// Attempts to acquire this `RwLock` with upgradable read access. - /// - /// If the access could not be granted at this time, then `None` is returned. - /// Otherwise, an RAII guard is returned which will release the shared access - /// when it is dropped. - /// - /// This function does not block. - #[inline] - pub fn try_upgradable_read(&self) -> Option> { - if self.raw.try_lock_upgradable() { - // SAFETY: The lock is held, as required. - Some(unsafe { self.make_upgradable_guard_unchecked() }) - } else { - None - } - } - - /// Creates a new `ArcRwLockUpgradableReadGuard` without checking if the lock is held. - /// - /// # Safety - /// - /// This method must only be called if the thread logically holds an upgradable read lock. - /// - /// This function does not increment the read count of the lock. Calling this function when a - /// guard has already been produced is undefined behaviour unless the guard was forgotten - /// with `mem::forget`.` - #[cfg(feature = "arc_lock")] - #[inline] - pub unsafe fn make_upgradable_arc_guard_unchecked( - self: &Arc, - ) -> ArcRwLockUpgradableReadGuard { - ArcRwLockUpgradableReadGuard { - rwlock: self.clone(), - marker: PhantomData, - } - } - - /// Locks this `RwLock` with upgradable read access, through an `Arc`. - /// - /// This method is similar to the `upgradable_read` method; however, it requires the `RwLock` to be - /// inside of an `Arc` and the resulting read guard has no lifetime requirements. - #[cfg(feature = "arc_lock")] - #[inline] - pub fn upgradable_read_arc(self: &Arc) -> ArcRwLockUpgradableReadGuard { - self.raw.lock_upgradable(); - // SAFETY: locking guarantee is upheld - unsafe { self.make_upgradable_arc_guard_unchecked() } - } - - /// Attempts to lock this `RwLock` with upgradable read access, through an `Arc`. - /// - /// This method is similar to the `try_upgradable_read` method; however, it requires the `RwLock` to be - /// inside of an `Arc` and the resulting read guard has no lifetime requirements. - #[cfg(feature = "arc_lock")] - #[inline] - pub fn try_upgradable_read_arc(self: &Arc) -> Option> { - if self.raw.try_lock_upgradable() { - // SAFETY: locking guarantee is upheld - Some(unsafe { self.make_upgradable_arc_guard_unchecked() }) - } else { - None - } - } -} - -impl RwLock { - /// Attempts to acquire this `RwLock` with upgradable read access until a timeout - /// is reached. - /// - /// If the access could not be granted before the timeout expires, then - /// `None` is returned. Otherwise, an RAII guard is returned which will - /// release the shared access when it is dropped. - #[inline] - pub fn try_upgradable_read_for( - &self, - timeout: R::Duration, - ) -> Option> { - if self.raw.try_lock_upgradable_for(timeout) { - // SAFETY: The lock is held, as required. - Some(unsafe { self.make_upgradable_guard_unchecked() }) - } else { - None - } - } - - /// Attempts to acquire this `RwLock` with upgradable read access until a timeout - /// is reached. - /// - /// If the access could not be granted before the timeout expires, then - /// `None` is returned. Otherwise, an RAII guard is returned which will - /// release the shared access when it is dropped. - #[inline] - pub fn try_upgradable_read_until( - &self, - timeout: R::Instant, - ) -> Option> { - if self.raw.try_lock_upgradable_until(timeout) { - // SAFETY: The lock is held, as required. - Some(unsafe { self.make_upgradable_guard_unchecked() }) - } else { - None - } - } - - /// Attempts to lock this `RwLock` with upgradable access until a timeout is reached, through an `Arc`. - /// - /// This method is similar to the `try_upgradable_read_for` method; however, it requires the `RwLock` to be - /// inside of an `Arc` and the resulting read guard has no lifetime requirements. - #[cfg(feature = "arc_lock")] - #[inline] - pub fn try_upgradable_read_arc_for( - self: &Arc, - timeout: R::Duration, - ) -> Option> { - if self.raw.try_lock_upgradable_for(timeout) { - // SAFETY: locking guarantee is upheld - Some(unsafe { self.make_upgradable_arc_guard_unchecked() }) - } else { - None - } - } - - /// Attempts to lock this `RwLock` with upgradable access until a timeout is reached, through an `Arc`. - /// - /// This method is similar to the `try_upgradable_read_until` method; however, it requires the `RwLock` to be - /// inside of an `Arc` and the resulting read guard has no lifetime requirements. - #[cfg(feature = "arc_lock")] - #[inline] - pub fn try_upgradable_read_arc_until( - self: &Arc, - timeout: R::Instant, - ) -> Option> { - if self.raw.try_lock_upgradable_until(timeout) { - // SAFETY: locking guarantee is upheld - Some(unsafe { self.make_upgradable_arc_guard_unchecked() }) - } else { - None - } - } -} - -impl Default for RwLock { - #[inline] - fn default() -> RwLock { - RwLock::new(Default::default()) - } -} - -impl From for RwLock { - #[inline] - fn from(t: T) -> RwLock { - RwLock::new(t) - } -} - -impl fmt::Debug for RwLock { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - match self.try_read() { - Some(guard) => f.debug_struct("RwLock").field("data", &&*guard).finish(), - None => { - struct LockedPlaceholder; - impl fmt::Debug for LockedPlaceholder { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.write_str("") - } - } - - f.debug_struct("RwLock") - .field("data", &LockedPlaceholder) - .finish() - } - } - } -} - -/// RAII structure used to release the shared read access of a lock when -/// dropped. -#[clippy::has_significant_drop] -#[must_use = "if unused the RwLock will immediately unlock"] -pub struct RwLockReadGuard<'a, R: RawRwLock, T: ?Sized> { - rwlock: &'a RwLock, - marker: PhantomData<(&'a T, R::GuardMarker)>, -} - -unsafe impl Sync for RwLockReadGuard<'_, R, T> {} - -impl<'a, R: RawRwLock + 'a, T: ?Sized + 'a> RwLockReadGuard<'a, R, T> { - /// Returns a reference to the original reader-writer lock object. - pub fn rwlock(s: &Self) -> &'a RwLock { - s.rwlock - } - - /// Make a new `MappedRwLockReadGuard` for a component of the locked data. - /// - /// This operation cannot fail as the `RwLockReadGuard` passed - /// in already locked the data. - /// - /// This is an associated function that needs to be - /// used as `RwLockReadGuard::map(...)`. A method would interfere with methods of - /// the same name on the contents of the locked data. - #[inline] - pub fn map(s: Self, f: F) -> MappedRwLockReadGuard<'a, R, U> - where - F: FnOnce(&T) -> &U, - { - let raw = &s.rwlock.raw; - let data = f(unsafe { &*s.rwlock.data.get() }); - mem::forget(s); - MappedRwLockReadGuard { - raw, - data, - marker: PhantomData, - } - } - - /// Attempts to make a new `MappedRwLockReadGuard` for a component of the - /// locked data. Returns the original guard if the closure returns `None`. - /// - /// This operation cannot fail as the `RwLockReadGuard` passed - /// in already locked the data. - /// - /// This is an associated function that needs to be - /// used as `RwLockReadGuard::try_map(...)`. A method would interfere with methods of - /// the same name on the contents of the locked data. - #[inline] - pub fn try_map(s: Self, f: F) -> Result, Self> - where - F: FnOnce(&T) -> Option<&U>, - { - let raw = &s.rwlock.raw; - let data = match f(unsafe { &*s.rwlock.data.get() }) { - Some(data) => data, - None => return Err(s), - }; - mem::forget(s); - Ok(MappedRwLockReadGuard { - raw, - data, - marker: PhantomData, - }) - } - - /// Temporarily unlocks the `RwLock` to execute the given function. - /// - /// This is safe because `&mut` guarantees that there exist no other - /// references to the data protected by the `RwLock`. - #[inline] - pub fn unlocked(s: &mut Self, f: F) -> U - where - F: FnOnce() -> U, - { - // Safety: An RwLockReadGuard always holds a shared lock. - unsafe { - s.rwlock.raw.unlock_shared(); - } - defer!(s.rwlock.raw.lock_shared()); - f() - } -} - -impl<'a, R: RawRwLockFair + 'a, T: ?Sized + 'a> RwLockReadGuard<'a, R, T> { - /// Unlocks the `RwLock` using a fair unlock protocol. - /// - /// By default, `RwLock` is unfair and allow the current thread to re-lock - /// the `RwLock` before another has the chance to acquire the lock, even if - /// that thread has been blocked on the `RwLock` for a long time. This is - /// the default because it allows much higher throughput as it avoids - /// forcing a context switch on every `RwLock` unlock. This can result in one - /// thread acquiring a `RwLock` many more times than other threads. - /// - /// However in some cases it can be beneficial to ensure fairness by forcing - /// the lock to pass on to a waiting thread if there is one. This is done by - /// using this method instead of dropping the `RwLockReadGuard` normally. - #[inline] - pub fn unlock_fair(s: Self) { - // Safety: An RwLockReadGuard always holds a shared lock. - unsafe { - s.rwlock.raw.unlock_shared_fair(); - } - mem::forget(s); - } - - /// Temporarily unlocks the `RwLock` to execute the given function. - /// - /// The `RwLock` is unlocked a fair unlock protocol. - /// - /// This is safe because `&mut` guarantees that there exist no other - /// references to the data protected by the `RwLock`. - #[inline] - pub fn unlocked_fair(s: &mut Self, f: F) -> U - where - F: FnOnce() -> U, - { - // Safety: An RwLockReadGuard always holds a shared lock. - unsafe { - s.rwlock.raw.unlock_shared_fair(); - } - defer!(s.rwlock.raw.lock_shared()); - f() - } - - /// Temporarily yields the `RwLock` to a waiting thread if there is one. - /// - /// This method is functionally equivalent to calling `unlock_fair` followed - /// by `read`, however it can be much more efficient in the case where there - /// are no waiting threads. - #[inline] - pub fn bump(s: &mut Self) { - // Safety: An RwLockReadGuard always holds a shared lock. - unsafe { - s.rwlock.raw.bump_shared(); - } - } -} - -impl<'a, R: RawRwLock + 'a, T: ?Sized + 'a> Deref for RwLockReadGuard<'a, R, T> { - type Target = T; - #[inline] - fn deref(&self) -> &T { - unsafe { &*self.rwlock.data.get() } - } -} - -impl<'a, R: RawRwLock + 'a, T: ?Sized + 'a> Drop for RwLockReadGuard<'a, R, T> { - #[inline] - fn drop(&mut self) { - // Safety: An RwLockReadGuard always holds a shared lock. - unsafe { - self.rwlock.raw.unlock_shared(); - } - } -} - -impl<'a, R: RawRwLock + 'a, T: fmt::Debug + ?Sized + 'a> fmt::Debug for RwLockReadGuard<'a, R, T> { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - fmt::Debug::fmt(&**self, f) - } -} - -impl<'a, R: RawRwLock + 'a, T: fmt::Display + ?Sized + 'a> fmt::Display - for RwLockReadGuard<'a, R, T> -{ - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - (**self).fmt(f) - } -} - -#[cfg(feature = "owning_ref")] -unsafe impl<'a, R: RawRwLock + 'a, T: ?Sized + 'a> StableAddress for RwLockReadGuard<'a, R, T> {} - -/// An RAII rwlock guard returned by the `Arc` locking operations on `RwLock`. -/// -/// This is similar to the `RwLockReadGuard` struct, except instead of using a reference to unlock the `RwLock` -/// it uses an `Arc`. This has several advantages, most notably that it has an `'static` lifetime. -#[cfg(feature = "arc_lock")] -#[clippy::has_significant_drop] -#[must_use = "if unused the RwLock will immediately unlock"] -pub struct ArcRwLockReadGuard { - rwlock: Arc>, - marker: PhantomData, -} - -#[cfg(feature = "arc_lock")] -impl ArcRwLockReadGuard { - /// Returns a reference to the rwlock, contained in its `Arc`. - pub fn rwlock(s: &Self) -> &Arc> { - &s.rwlock - } - - /// Temporarily unlocks the `RwLock` to execute the given function. - /// - /// This is functionally identical to the `unlocked` method on [`RwLockReadGuard`]. - #[inline] - pub fn unlocked(s: &mut Self, f: F) -> U - where - F: FnOnce() -> U, - { - // Safety: An RwLockReadGuard always holds a shared lock. - unsafe { - s.rwlock.raw.unlock_shared(); - } - defer!(s.rwlock.raw.lock_shared()); - f() - } -} - -#[cfg(feature = "arc_lock")] -impl ArcRwLockReadGuard { - /// Unlocks the `RwLock` using a fair unlock protocol. - /// - /// This is functionally identical to the `unlock_fair` method on [`RwLockReadGuard`]. - #[inline] - pub fn unlock_fair(s: Self) { - // Safety: An RwLockReadGuard always holds a shared lock. - unsafe { - s.rwlock.raw.unlock_shared_fair(); - } - - // SAFETY: ensure the Arc has its refcount decremented - let mut s = ManuallyDrop::new(s); - unsafe { ptr::drop_in_place(&mut s.rwlock) }; - } - - /// Temporarily unlocks the `RwLock` to execute the given function. - /// - /// This is functionally identical to the `unlocked_fair` method on [`RwLockReadGuard`]. - #[inline] - pub fn unlocked_fair(s: &mut Self, f: F) -> U - where - F: FnOnce() -> U, - { - // Safety: An RwLockReadGuard always holds a shared lock. - unsafe { - s.rwlock.raw.unlock_shared_fair(); - } - defer!(s.rwlock.raw.lock_shared()); - f() - } - - /// Temporarily yields the `RwLock` to a waiting thread if there is one. - /// - /// This is functionally identical to the `bump` method on [`RwLockReadGuard`]. - #[inline] - pub fn bump(s: &mut Self) { - // Safety: An RwLockReadGuard always holds a shared lock. - unsafe { - s.rwlock.raw.bump_shared(); - } - } -} - -#[cfg(feature = "arc_lock")] -impl Deref for ArcRwLockReadGuard { - type Target = T; - #[inline] - fn deref(&self) -> &T { - unsafe { &*self.rwlock.data.get() } - } -} - -#[cfg(feature = "arc_lock")] -impl Drop for ArcRwLockReadGuard { - #[inline] - fn drop(&mut self) { - // Safety: An RwLockReadGuard always holds a shared lock. - unsafe { - self.rwlock.raw.unlock_shared(); - } - } -} - -#[cfg(feature = "arc_lock")] -impl fmt::Debug for ArcRwLockReadGuard { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - fmt::Debug::fmt(&**self, f) - } -} - -#[cfg(feature = "arc_lock")] -impl fmt::Display for ArcRwLockReadGuard { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - (**self).fmt(f) - } -} - -/// RAII structure used to release the exclusive write access of a lock when -/// dropped. -#[clippy::has_significant_drop] -#[must_use = "if unused the RwLock will immediately unlock"] -pub struct RwLockWriteGuard<'a, R: RawRwLock, T: ?Sized> { - rwlock: &'a RwLock, - marker: PhantomData<(&'a mut T, R::GuardMarker)>, -} - -unsafe impl Sync for RwLockWriteGuard<'_, R, T> {} - -impl<'a, R: RawRwLock + 'a, T: ?Sized + 'a> RwLockWriteGuard<'a, R, T> { - /// Returns a reference to the original reader-writer lock object. - pub fn rwlock(s: &Self) -> &'a RwLock { - s.rwlock - } - - /// Make a new `MappedRwLockWriteGuard` for a component of the locked data. - /// - /// This operation cannot fail as the `RwLockWriteGuard` passed - /// in already locked the data. - /// - /// This is an associated function that needs to be - /// used as `RwLockWriteGuard::map(...)`. A method would interfere with methods of - /// the same name on the contents of the locked data. - #[inline] - pub fn map(s: Self, f: F) -> MappedRwLockWriteGuard<'a, R, U> - where - F: FnOnce(&mut T) -> &mut U, - { - let raw = &s.rwlock.raw; - let data = f(unsafe { &mut *s.rwlock.data.get() }); - mem::forget(s); - MappedRwLockWriteGuard { - raw, - data, - marker: PhantomData, - } - } - - /// Attempts to make a new `MappedRwLockWriteGuard` for a component of the - /// locked data. The original guard is return if the closure returns `None`. - /// - /// This operation cannot fail as the `RwLockWriteGuard` passed - /// in already locked the data. - /// - /// This is an associated function that needs to be - /// used as `RwLockWriteGuard::try_map(...)`. A method would interfere with methods of - /// the same name on the contents of the locked data. - #[inline] - pub fn try_map(s: Self, f: F) -> Result, Self> - where - F: FnOnce(&mut T) -> Option<&mut U>, - { - let raw = &s.rwlock.raw; - let data = match f(unsafe { &mut *s.rwlock.data.get() }) { - Some(data) => data, - None => return Err(s), - }; - mem::forget(s); - Ok(MappedRwLockWriteGuard { - raw, - data, - marker: PhantomData, - }) - } - - /// Temporarily unlocks the `RwLock` to execute the given function. - /// - /// This is safe because `&mut` guarantees that there exist no other - /// references to the data protected by the `RwLock`. - #[inline] - pub fn unlocked(s: &mut Self, f: F) -> U - where - F: FnOnce() -> U, - { - // Safety: An RwLockReadGuard always holds a shared lock. - unsafe { - s.rwlock.raw.unlock_exclusive(); - } - defer!(s.rwlock.raw.lock_exclusive()); - f() - } -} - -impl<'a, R: RawRwLockDowngrade + 'a, T: ?Sized + 'a> RwLockWriteGuard<'a, R, T> { - /// Atomically downgrades a write lock into a read lock without allowing any - /// writers to take exclusive access of the lock in the meantime. - /// - /// Note that if there are any writers currently waiting to take the lock - /// then other readers may not be able to acquire the lock even if it was - /// downgraded. - pub fn downgrade(s: Self) -> RwLockReadGuard<'a, R, T> { - // Safety: An RwLockWriteGuard always holds an exclusive lock. - unsafe { - s.rwlock.raw.downgrade(); - } - let rwlock = s.rwlock; - mem::forget(s); - RwLockReadGuard { - rwlock, - marker: PhantomData, - } - } -} - -impl<'a, R: RawRwLockUpgradeDowngrade + 'a, T: ?Sized + 'a> RwLockWriteGuard<'a, R, T> { - /// Atomically downgrades a write lock into an upgradable read lock without allowing any - /// writers to take exclusive access of the lock in the meantime. - /// - /// Note that if there are any writers currently waiting to take the lock - /// then other readers may not be able to acquire the lock even if it was - /// downgraded. - pub fn downgrade_to_upgradable(s: Self) -> RwLockUpgradableReadGuard<'a, R, T> { - // Safety: An RwLockWriteGuard always holds an exclusive lock. - unsafe { - s.rwlock.raw.downgrade_to_upgradable(); - } - let rwlock = s.rwlock; - mem::forget(s); - RwLockUpgradableReadGuard { - rwlock, - marker: PhantomData, - } - } -} - -impl<'a, R: RawRwLockFair + 'a, T: ?Sized + 'a> RwLockWriteGuard<'a, R, T> { - /// Unlocks the `RwLock` using a fair unlock protocol. - /// - /// By default, `RwLock` is unfair and allow the current thread to re-lock - /// the `RwLock` before another has the chance to acquire the lock, even if - /// that thread has been blocked on the `RwLock` for a long time. This is - /// the default because it allows much higher throughput as it avoids - /// forcing a context switch on every `RwLock` unlock. This can result in one - /// thread acquiring a `RwLock` many more times than other threads. - /// - /// However in some cases it can be beneficial to ensure fairness by forcing - /// the lock to pass on to a waiting thread if there is one. This is done by - /// using this method instead of dropping the `RwLockWriteGuard` normally. - #[inline] - pub fn unlock_fair(s: Self) { - // Safety: An RwLockWriteGuard always holds an exclusive lock. - unsafe { - s.rwlock.raw.unlock_exclusive_fair(); - } - mem::forget(s); - } - - /// Temporarily unlocks the `RwLock` to execute the given function. - /// - /// The `RwLock` is unlocked a fair unlock protocol. - /// - /// This is safe because `&mut` guarantees that there exist no other - /// references to the data protected by the `RwLock`. - #[inline] - pub fn unlocked_fair(s: &mut Self, f: F) -> U - where - F: FnOnce() -> U, - { - // Safety: An RwLockWriteGuard always holds an exclusive lock. - unsafe { - s.rwlock.raw.unlock_exclusive_fair(); - } - defer!(s.rwlock.raw.lock_exclusive()); - f() - } - - /// Temporarily yields the `RwLock` to a waiting thread if there is one. - /// - /// This method is functionally equivalent to calling `unlock_fair` followed - /// by `write`, however it can be much more efficient in the case where there - /// are no waiting threads. - #[inline] - pub fn bump(s: &mut Self) { - // Safety: An RwLockWriteGuard always holds an exclusive lock. - unsafe { - s.rwlock.raw.bump_exclusive(); - } - } -} - -impl<'a, R: RawRwLock + 'a, T: ?Sized + 'a> Deref for RwLockWriteGuard<'a, R, T> { - type Target = T; - #[inline] - fn deref(&self) -> &T { - unsafe { &*self.rwlock.data.get() } - } -} - -impl<'a, R: RawRwLock + 'a, T: ?Sized + 'a> DerefMut for RwLockWriteGuard<'a, R, T> { - #[inline] - fn deref_mut(&mut self) -> &mut T { - unsafe { &mut *self.rwlock.data.get() } - } -} - -impl<'a, R: RawRwLock + 'a, T: ?Sized + 'a> Drop for RwLockWriteGuard<'a, R, T> { - #[inline] - fn drop(&mut self) { - // Safety: An RwLockWriteGuard always holds an exclusive lock. - unsafe { - self.rwlock.raw.unlock_exclusive(); - } - } -} - -impl<'a, R: RawRwLock + 'a, T: fmt::Debug + ?Sized + 'a> fmt::Debug for RwLockWriteGuard<'a, R, T> { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - fmt::Debug::fmt(&**self, f) - } -} - -impl<'a, R: RawRwLock + 'a, T: fmt::Display + ?Sized + 'a> fmt::Display - for RwLockWriteGuard<'a, R, T> -{ - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - (**self).fmt(f) - } -} - -#[cfg(feature = "owning_ref")] -unsafe impl<'a, R: RawRwLock + 'a, T: ?Sized + 'a> StableAddress for RwLockWriteGuard<'a, R, T> {} - -/// An RAII rwlock guard returned by the `Arc` locking operations on `RwLock`. -/// This is similar to the `RwLockWriteGuard` struct, except instead of using a reference to unlock the `RwLock` -/// it uses an `Arc`. This has several advantages, most notably that it has an `'static` lifetime. -#[cfg(feature = "arc_lock")] -#[clippy::has_significant_drop] -#[must_use = "if unused the RwLock will immediately unlock"] -pub struct ArcRwLockWriteGuard { - rwlock: Arc>, - marker: PhantomData, -} - -#[cfg(feature = "arc_lock")] -impl ArcRwLockWriteGuard { - /// Returns a reference to the rwlock, contained in its `Arc`. - pub fn rwlock(s: &Self) -> &Arc> { - &s.rwlock - } - - /// Temporarily unlocks the `RwLock` to execute the given function. - /// - /// This is functionally equivalent to the `unlocked` method on [`RwLockWriteGuard`]. - #[inline] - pub fn unlocked(s: &mut Self, f: F) -> U - where - F: FnOnce() -> U, - { - // Safety: An RwLockWriteGuard always holds a shared lock. - unsafe { - s.rwlock.raw.unlock_exclusive(); - } - defer!(s.rwlock.raw.lock_exclusive()); - f() - } -} - -#[cfg(feature = "arc_lock")] -impl ArcRwLockWriteGuard { - /// Atomically downgrades a write lock into a read lock without allowing any - /// writers to take exclusive access of the lock in the meantime. - /// - /// This is functionally equivalent to the `downgrade` method on [`RwLockWriteGuard`]. - pub fn downgrade(s: Self) -> ArcRwLockReadGuard { - // Safety: An RwLockWriteGuard always holds an exclusive lock. - unsafe { - s.rwlock.raw.downgrade(); - } - - // SAFETY: prevent the arc's refcount from changing using ManuallyDrop and ptr::read - let s = ManuallyDrop::new(s); - let rwlock = unsafe { ptr::read(&s.rwlock) }; - - ArcRwLockReadGuard { - rwlock, - marker: PhantomData, - } - } -} - -#[cfg(feature = "arc_lock")] -impl ArcRwLockWriteGuard { - /// Atomically downgrades a write lock into an upgradable read lock without allowing any - /// writers to take exclusive access of the lock in the meantime. - /// - /// This is functionally identical to the `downgrade_to_upgradable` method on [`RwLockWriteGuard`]. - pub fn downgrade_to_upgradable(s: Self) -> ArcRwLockUpgradableReadGuard { - // Safety: An RwLockWriteGuard always holds an exclusive lock. - unsafe { - s.rwlock.raw.downgrade_to_upgradable(); - } - - // SAFETY: same as above - let s = ManuallyDrop::new(s); - let rwlock = unsafe { ptr::read(&s.rwlock) }; - - ArcRwLockUpgradableReadGuard { - rwlock, - marker: PhantomData, - } - } -} - -#[cfg(feature = "arc_lock")] -impl ArcRwLockWriteGuard { - /// Unlocks the `RwLock` using a fair unlock protocol. - /// - /// This is functionally equivalent to the `unlock_fair` method on [`RwLockWriteGuard`]. - #[inline] - pub fn unlock_fair(s: Self) { - // Safety: An RwLockWriteGuard always holds an exclusive lock. - unsafe { - s.rwlock.raw.unlock_exclusive_fair(); - } - - // SAFETY: prevent the Arc from leaking memory - let mut s = ManuallyDrop::new(s); - unsafe { ptr::drop_in_place(&mut s.rwlock) }; - } - - /// Temporarily unlocks the `RwLock` to execute the given function. - /// - /// This is functionally equivalent to the `unlocked_fair` method on [`RwLockWriteGuard`]. - #[inline] - pub fn unlocked_fair(s: &mut Self, f: F) -> U - where - F: FnOnce() -> U, - { - // Safety: An RwLockWriteGuard always holds an exclusive lock. - unsafe { - s.rwlock.raw.unlock_exclusive_fair(); - } - defer!(s.rwlock.raw.lock_exclusive()); - f() - } - - /// Temporarily yields the `RwLock` to a waiting thread if there is one. - /// - /// This method is functionally equivalent to the `bump` method on [`RwLockWriteGuard`]. - #[inline] - pub fn bump(s: &mut Self) { - // Safety: An RwLockWriteGuard always holds an exclusive lock. - unsafe { - s.rwlock.raw.bump_exclusive(); - } - } -} - -#[cfg(feature = "arc_lock")] -impl Deref for ArcRwLockWriteGuard { - type Target = T; - #[inline] - fn deref(&self) -> &T { - unsafe { &*self.rwlock.data.get() } - } -} - -#[cfg(feature = "arc_lock")] -impl DerefMut for ArcRwLockWriteGuard { - #[inline] - fn deref_mut(&mut self) -> &mut T { - unsafe { &mut *self.rwlock.data.get() } - } -} - -#[cfg(feature = "arc_lock")] -impl Drop for ArcRwLockWriteGuard { - #[inline] - fn drop(&mut self) { - // Safety: An RwLockWriteGuard always holds an exclusive lock. - unsafe { - self.rwlock.raw.unlock_exclusive(); - } - } -} - -#[cfg(feature = "arc_lock")] -impl fmt::Debug for ArcRwLockWriteGuard { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - fmt::Debug::fmt(&**self, f) - } -} - -#[cfg(feature = "arc_lock")] -impl fmt::Display for ArcRwLockWriteGuard { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - (**self).fmt(f) - } -} - -/// RAII structure used to release the upgradable read access of a lock when -/// dropped. -#[clippy::has_significant_drop] -#[must_use = "if unused the RwLock will immediately unlock"] -pub struct RwLockUpgradableReadGuard<'a, R: RawRwLockUpgrade, T: ?Sized> { - rwlock: &'a RwLock, - marker: PhantomData<(&'a T, R::GuardMarker)>, -} - -unsafe impl<'a, R: RawRwLockUpgrade + 'a, T: ?Sized + Sync + 'a> Sync - for RwLockUpgradableReadGuard<'a, R, T> -{ -} - -impl<'a, R: RawRwLockUpgrade + 'a, T: ?Sized + 'a> RwLockUpgradableReadGuard<'a, R, T> { - /// Returns a reference to the original reader-writer lock object. - pub fn rwlock(s: &Self) -> &'a RwLock { - s.rwlock - } - - /// Temporarily unlocks the `RwLock` to execute the given function. - /// - /// This is safe because `&mut` guarantees that there exist no other - /// references to the data protected by the `RwLock`. - #[inline] - pub fn unlocked(s: &mut Self, f: F) -> U - where - F: FnOnce() -> U, - { - // Safety: An RwLockUpgradableReadGuard always holds an upgradable lock. - unsafe { - s.rwlock.raw.unlock_upgradable(); - } - defer!(s.rwlock.raw.lock_upgradable()); - f() - } - - /// Atomically upgrades an upgradable read lock lock into an exclusive write lock, - /// blocking the current thread until it can be acquired. - pub fn upgrade(s: Self) -> RwLockWriteGuard<'a, R, T> { - // Safety: An RwLockUpgradableReadGuard always holds an upgradable lock. - unsafe { - s.rwlock.raw.upgrade(); - } - let rwlock = s.rwlock; - mem::forget(s); - RwLockWriteGuard { - rwlock, - marker: PhantomData, - } - } - - /// Tries to atomically upgrade an upgradable read lock into an exclusive write lock. - /// - /// If the access could not be granted at this time, then the current guard is returned. - pub fn try_upgrade(s: Self) -> Result, Self> { - // Safety: An RwLockUpgradableReadGuard always holds an upgradable lock. - if unsafe { s.rwlock.raw.try_upgrade() } { - let rwlock = s.rwlock; - mem::forget(s); - Ok(RwLockWriteGuard { - rwlock, - marker: PhantomData, - }) - } else { - Err(s) - } - } -} - -impl<'a, R: RawRwLockUpgradeFair + 'a, T: ?Sized + 'a> RwLockUpgradableReadGuard<'a, R, T> { - /// Unlocks the `RwLock` using a fair unlock protocol. - /// - /// By default, `RwLock` is unfair and allow the current thread to re-lock - /// the `RwLock` before another has the chance to acquire the lock, even if - /// that thread has been blocked on the `RwLock` for a long time. This is - /// the default because it allows much higher throughput as it avoids - /// forcing a context switch on every `RwLock` unlock. This can result in one - /// thread acquiring a `RwLock` many more times than other threads. - /// - /// However in some cases it can be beneficial to ensure fairness by forcing - /// the lock to pass on to a waiting thread if there is one. This is done by - /// using this method instead of dropping the `RwLockUpgradableReadGuard` normally. - #[inline] - pub fn unlock_fair(s: Self) { - // Safety: An RwLockUpgradableReadGuard always holds an upgradable lock. - unsafe { - s.rwlock.raw.unlock_upgradable_fair(); - } - mem::forget(s); - } - - /// Temporarily unlocks the `RwLock` to execute the given function. - /// - /// The `RwLock` is unlocked a fair unlock protocol. - /// - /// This is safe because `&mut` guarantees that there exist no other - /// references to the data protected by the `RwLock`. - #[inline] - pub fn unlocked_fair(s: &mut Self, f: F) -> U - where - F: FnOnce() -> U, - { - // Safety: An RwLockUpgradableReadGuard always holds an upgradable lock. - unsafe { - s.rwlock.raw.unlock_upgradable_fair(); - } - defer!(s.rwlock.raw.lock_upgradable()); - f() - } - - /// Temporarily yields the `RwLock` to a waiting thread if there is one. - /// - /// This method is functionally equivalent to calling `unlock_fair` followed - /// by `upgradable_read`, however it can be much more efficient in the case where there - /// are no waiting threads. - #[inline] - pub fn bump(s: &mut Self) { - // Safety: An RwLockUpgradableReadGuard always holds an upgradable lock. - unsafe { - s.rwlock.raw.bump_upgradable(); - } - } -} - -impl<'a, R: RawRwLockUpgradeDowngrade + 'a, T: ?Sized + 'a> RwLockUpgradableReadGuard<'a, R, T> { - /// Atomically downgrades an upgradable read lock lock into a shared read lock - /// without allowing any writers to take exclusive access of the lock in the - /// meantime. - /// - /// Note that if there are any writers currently waiting to take the lock - /// then other readers may not be able to acquire the lock even if it was - /// downgraded. - pub fn downgrade(s: Self) -> RwLockReadGuard<'a, R, T> { - // Safety: An RwLockUpgradableReadGuard always holds an upgradable lock. - unsafe { - s.rwlock.raw.downgrade_upgradable(); - } - let rwlock = s.rwlock; - mem::forget(s); - RwLockReadGuard { - rwlock, - marker: PhantomData, - } - } - - /// First, atomically upgrades an upgradable read lock lock into an exclusive write lock, - /// blocking the current thread until it can be acquired. - /// - /// Then, calls the provided closure with an exclusive reference to the lock's data. - /// - /// Finally, atomically downgrades the lock back to an upgradable read lock. - /// The closure's return value is wrapped in `Some` and returned. - /// - /// This function only requires a mutable reference to the guard, unlike - /// `upgrade` which takes the guard by value. - pub fn with_upgraded Ret>(&mut self, f: F) -> Ret { - unsafe { - self.rwlock.raw.upgrade(); - } - - // Safety: We just upgraded the lock, so we have mutable access to the data. - // This will restore the state the lock was in at the start of the function. - defer!(unsafe { self.rwlock.raw.downgrade_to_upgradable() }); - - // Safety: We upgraded the lock, so we have mutable access to the data. - // When this function returns, whether by drop or panic, - // the drop guard will downgrade it back to an upgradeable lock. - f(unsafe { &mut *self.rwlock.data.get() }) - } - - /// First, tries to atomically upgrade an upgradable read lock into an exclusive write lock. - /// - /// If the access could not be granted at this time, then `None` is returned. - /// - /// Otherwise, calls the provided closure with an exclusive reference to the lock's data, - /// and finally downgrades the lock back to an upgradable read lock. - /// The closure's return value is wrapped in `Some` and returned. - /// - /// This function only requires a mutable reference to the guard, unlike - /// `try_upgrade` which takes the guard by value. - pub fn try_with_upgraded Ret>(&mut self, f: F) -> Option { - if unsafe { self.rwlock.raw.try_upgrade() } { - // Safety: We just upgraded the lock, so we have mutable access to the data. - // This will restore the state the lock was in at the start of the function. - defer!(unsafe { self.rwlock.raw.downgrade_to_upgradable() }); - - // Safety: We upgraded the lock, so we have mutable access to the data. - // When this function returns, whether by drop or panic, - // the drop guard will downgrade it back to an upgradeable lock. - Some(f(unsafe { &mut *self.rwlock.data.get() })) - } else { - None - } - } -} - -impl<'a, R: RawRwLockUpgradeTimed + 'a, T: ?Sized + 'a> RwLockUpgradableReadGuard<'a, R, T> { - /// Tries to atomically upgrade an upgradable read lock into an exclusive - /// write lock, until a timeout is reached. - /// - /// If the access could not be granted before the timeout expires, then - /// the current guard is returned. - pub fn try_upgrade_for( - s: Self, - timeout: R::Duration, - ) -> Result, Self> { - // Safety: An RwLockUpgradableReadGuard always holds an upgradable lock. - if unsafe { s.rwlock.raw.try_upgrade_for(timeout) } { - let rwlock = s.rwlock; - mem::forget(s); - Ok(RwLockWriteGuard { - rwlock, - marker: PhantomData, - }) - } else { - Err(s) - } - } - - /// Tries to atomically upgrade an upgradable read lock into an exclusive - /// write lock, until a timeout is reached. - /// - /// If the access could not be granted before the timeout expires, then - /// the current guard is returned. - #[inline] - pub fn try_upgrade_until( - s: Self, - timeout: R::Instant, - ) -> Result, Self> { - // Safety: An RwLockUpgradableReadGuard always holds an upgradable lock. - if unsafe { s.rwlock.raw.try_upgrade_until(timeout) } { - let rwlock = s.rwlock; - mem::forget(s); - Ok(RwLockWriteGuard { - rwlock, - marker: PhantomData, - }) - } else { - Err(s) - } - } -} - -impl<'a, R: RawRwLockUpgradeTimed + RawRwLockUpgradeDowngrade + 'a, T: ?Sized + 'a> - RwLockUpgradableReadGuard<'a, R, T> -{ - /// Tries to atomically upgrade an upgradable read lock into an exclusive - /// write lock, until a timeout is reached. - /// - /// If the access could not be granted before the timeout expires, then - /// `None` is returned. - /// - /// Otherwise, calls the provided closure with an exclusive reference to the lock's data, - /// and finally downgrades the lock back to an upgradable read lock. - /// The closure's return value is wrapped in `Some` and returned. - /// - /// This function only requires a mutable reference to the guard, unlike - /// `try_upgrade_for` which takes the guard by value. - pub fn try_with_upgraded_for Ret>( - &mut self, - timeout: R::Duration, - f: F, - ) -> Option { - if unsafe { self.rwlock.raw.try_upgrade_for(timeout) } { - // Safety: We just upgraded the lock, so we have mutable access to the data. - // This will restore the state the lock was in at the start of the function. - defer!(unsafe { self.rwlock.raw.downgrade_upgradable() }); - - // Safety: We upgraded the lock, so we have mutable access to the data. - // When this function returns, whether by drop or panic, - // the drop guard will downgrade it back to an upgradeable lock. - Some(f(unsafe { &mut *self.rwlock.data.get() })) - } else { - None - } - } - - /// Tries to atomically upgrade an upgradable read lock into an exclusive - /// write lock, until a timeout is reached. - /// - /// If the access could not be granted before the timeout expires, then - /// `None` is returned. - /// - /// Otherwise, calls the provided closure with an exclusive reference to the lock's data, - /// and finally downgrades the lock back to an upgradable read lock. - /// The closure's return value is wrapped in `Some` and returned. - /// - /// This function only requires a mutable reference to the guard, unlike - /// `try_upgrade_until` which takes the guard by value. - pub fn try_with_upgraded_until Ret>( - &mut self, - timeout: R::Instant, - f: F, - ) -> Option { - if unsafe { self.rwlock.raw.try_upgrade_until(timeout) } { - // Safety: We just upgraded the lock, so we have mutable access to the data. - // This will restore the state the lock was in at the start of the function. - defer!(unsafe { self.rwlock.raw.downgrade_upgradable() }); - - // Safety: We upgraded the lock, so we have mutable access to the data. - // When this function returns, whether by drop or panic, - // the drop guard will downgrade it back to an upgradeable lock. - Some(f(unsafe { &mut *self.rwlock.data.get() })) - } else { - None - } - } -} - -impl<'a, R: RawRwLockUpgrade + 'a, T: ?Sized + 'a> Deref for RwLockUpgradableReadGuard<'a, R, T> { - type Target = T; - #[inline] - fn deref(&self) -> &T { - unsafe { &*self.rwlock.data.get() } - } -} - -impl<'a, R: RawRwLockUpgrade + 'a, T: ?Sized + 'a> Drop for RwLockUpgradableReadGuard<'a, R, T> { - #[inline] - fn drop(&mut self) { - // Safety: An RwLockUpgradableReadGuard always holds an upgradable lock. - unsafe { - self.rwlock.raw.unlock_upgradable(); - } - } -} - -impl<'a, R: RawRwLockUpgrade + 'a, T: fmt::Debug + ?Sized + 'a> fmt::Debug - for RwLockUpgradableReadGuard<'a, R, T> -{ - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - fmt::Debug::fmt(&**self, f) - } -} - -impl<'a, R: RawRwLockUpgrade + 'a, T: fmt::Display + ?Sized + 'a> fmt::Display - for RwLockUpgradableReadGuard<'a, R, T> -{ - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - (**self).fmt(f) - } -} - -#[cfg(feature = "owning_ref")] -unsafe impl<'a, R: RawRwLockUpgrade + 'a, T: ?Sized + 'a> StableAddress - for RwLockUpgradableReadGuard<'a, R, T> -{ -} - -/// An RAII rwlock guard returned by the `Arc` locking operations on `RwLock`. -/// This is similar to the `RwLockUpgradableReadGuard` struct, except instead of using a reference to unlock the -/// `RwLock` it uses an `Arc`. This has several advantages, most notably that it has an `'static` -/// lifetime. -#[cfg(feature = "arc_lock")] -#[clippy::has_significant_drop] -#[must_use = "if unused the RwLock will immediately unlock"] -pub struct ArcRwLockUpgradableReadGuard { - rwlock: Arc>, - marker: PhantomData, -} - -#[cfg(feature = "arc_lock")] -impl ArcRwLockUpgradableReadGuard { - /// Returns a reference to the rwlock, contained in its original `Arc`. - pub fn rwlock(s: &Self) -> &Arc> { - &s.rwlock - } - - /// Temporarily unlocks the `RwLock` to execute the given function. - /// - /// This is functionally identical to the `unlocked` method on [`RwLockUpgradableReadGuard`]. - #[inline] - pub fn unlocked(s: &mut Self, f: F) -> U - where - F: FnOnce() -> U, - { - // Safety: An RwLockUpgradableReadGuard always holds an upgradable lock. - unsafe { - s.rwlock.raw.unlock_upgradable(); - } - defer!(s.rwlock.raw.lock_upgradable()); - f() - } - - /// Atomically upgrades an upgradable read lock lock into an exclusive write lock, - /// blocking the current thread until it can be acquired. - pub fn upgrade(s: Self) -> ArcRwLockWriteGuard { - // Safety: An RwLockUpgradableReadGuard always holds an upgradable lock. - unsafe { - s.rwlock.raw.upgrade(); - } - - // SAFETY: avoid incrementing or decrementing the refcount using ManuallyDrop and reading the Arc out - // of the struct - let s = ManuallyDrop::new(s); - let rwlock = unsafe { ptr::read(&s.rwlock) }; - - ArcRwLockWriteGuard { - rwlock, - marker: PhantomData, - } - } - - /// Tries to atomically upgrade an upgradable read lock into an exclusive write lock. - /// - /// If the access could not be granted at this time, then the current guard is returned. - pub fn try_upgrade(s: Self) -> Result, Self> { - // Safety: An RwLockUpgradableReadGuard always holds an upgradable lock. - if unsafe { s.rwlock.raw.try_upgrade() } { - // SAFETY: same as above - let s = ManuallyDrop::new(s); - let rwlock = unsafe { ptr::read(&s.rwlock) }; - - Ok(ArcRwLockWriteGuard { - rwlock, - marker: PhantomData, - }) - } else { - Err(s) - } - } -} - -#[cfg(feature = "arc_lock")] -impl ArcRwLockUpgradableReadGuard { - /// Unlocks the `RwLock` using a fair unlock protocol. - /// - /// This is functionally identical to the `unlock_fair` method on [`RwLockUpgradableReadGuard`]. - #[inline] - pub fn unlock_fair(s: Self) { - // Safety: An RwLockUpgradableReadGuard always holds an upgradable lock. - unsafe { - s.rwlock.raw.unlock_upgradable_fair(); - } - - // SAFETY: make sure we decrement the refcount properly - let mut s = ManuallyDrop::new(s); - unsafe { ptr::drop_in_place(&mut s.rwlock) }; - } - - /// Temporarily unlocks the `RwLock` to execute the given function. - /// - /// This is functionally equivalent to the `unlocked_fair` method on [`RwLockUpgradableReadGuard`]. - #[inline] - pub fn unlocked_fair(s: &mut Self, f: F) -> U - where - F: FnOnce() -> U, - { - // Safety: An RwLockUpgradableReadGuard always holds an upgradable lock. - unsafe { - s.rwlock.raw.unlock_upgradable_fair(); - } - defer!(s.rwlock.raw.lock_upgradable()); - f() - } - - /// Temporarily yields the `RwLock` to a waiting thread if there is one. - /// - /// This method is functionally equivalent to calling `bump` on [`RwLockUpgradableReadGuard`]. - #[inline] - pub fn bump(s: &mut Self) { - // Safety: An RwLockUpgradableReadGuard always holds an upgradable lock. - unsafe { - s.rwlock.raw.bump_upgradable(); - } - } -} - -#[cfg(feature = "arc_lock")] -impl ArcRwLockUpgradableReadGuard { - /// Atomically downgrades an upgradable read lock lock into a shared read lock - /// without allowing any writers to take exclusive access of the lock in the - /// meantime. - /// - /// Note that if there are any writers currently waiting to take the lock - /// then other readers may not be able to acquire the lock even if it was - /// downgraded. - pub fn downgrade(s: Self) -> ArcRwLockReadGuard { - // Safety: An RwLockUpgradableReadGuard always holds an upgradable lock. - unsafe { - s.rwlock.raw.downgrade_upgradable(); - } - - // SAFETY: use ManuallyDrop and ptr::read to ensure the refcount is not changed - let s = ManuallyDrop::new(s); - let rwlock = unsafe { ptr::read(&s.rwlock) }; - - ArcRwLockReadGuard { - rwlock, - marker: PhantomData, - } - } - - /// First, atomically upgrades an upgradable read lock lock into an exclusive write lock, - /// blocking the current thread until it can be acquired. - /// - /// Then, calls the provided closure with an exclusive reference to the lock's data. - /// - /// Finally, atomically downgrades the lock back to an upgradable read lock. - /// The closure's return value is returned. - /// - /// This function only requires a mutable reference to the guard, unlike - /// `upgrade` which takes the guard by value. - pub fn with_upgraded Ret>(&mut self, f: F) -> Ret { - unsafe { - self.rwlock.raw.upgrade(); - } - - // Safety: We just upgraded the lock, so we have mutable access to the data. - // This will restore the state the lock was in at the start of the function. - defer!(unsafe { self.rwlock.raw.downgrade_upgradable() }); - - // Safety: We upgraded the lock, so we have mutable access to the data. - // When this function returns, whether by drop or panic, - // the drop guard will downgrade it back to an upgradeable lock. - f(unsafe { &mut *self.rwlock.data.get() }) - } - - /// First, tries to atomically upgrade an upgradable read lock into an exclusive write lock. - /// - /// If the access could not be granted at this time, then `None` is returned. - /// - /// Otherwise, calls the provided closure with an exclusive reference to the lock's data, - /// and finally downgrades the lock back to an upgradable read lock. - /// The closure's return value is wrapped in `Some` and returned. - /// - /// This function only requires a mutable reference to the guard, unlike - /// `try_upgrade` which takes the guard by value. - pub fn try_with_upgraded Ret>(&mut self, f: F) -> Option { - if unsafe { self.rwlock.raw.try_upgrade() } { - // Safety: We just upgraded the lock, so we have mutable access to the data. - // This will restore the state the lock was in at the start of the function. - defer!(unsafe { self.rwlock.raw.downgrade_upgradable() }); - - // Safety: We upgraded the lock, so we have mutable access to the data. - // When this function returns, whether by drop or panic, - // the drop guard will downgrade it back to an upgradeable lock. - Some(f(unsafe { &mut *self.rwlock.data.get() })) - } else { - None - } - } -} - -#[cfg(feature = "arc_lock")] -impl ArcRwLockUpgradableReadGuard { - /// Tries to atomically upgrade an upgradable read lock into an exclusive - /// write lock, until a timeout is reached. - /// - /// If the access could not be granted before the timeout expires, then - /// the current guard is returned. - pub fn try_upgrade_for( - s: Self, - timeout: R::Duration, - ) -> Result, Self> { - // Safety: An RwLockUpgradableReadGuard always holds an upgradable lock. - if unsafe { s.rwlock.raw.try_upgrade_for(timeout) } { - // SAFETY: same as above - let s = ManuallyDrop::new(s); - let rwlock = unsafe { ptr::read(&s.rwlock) }; - - Ok(ArcRwLockWriteGuard { - rwlock, - marker: PhantomData, - }) - } else { - Err(s) - } - } - - /// Tries to atomically upgrade an upgradable read lock into an exclusive - /// write lock, until a timeout is reached. - /// - /// If the access could not be granted before the timeout expires, then - /// the current guard is returned. - #[inline] - pub fn try_upgrade_until( - s: Self, - timeout: R::Instant, - ) -> Result, Self> { - // Safety: An RwLockUpgradableReadGuard always holds an upgradable lock. - if unsafe { s.rwlock.raw.try_upgrade_until(timeout) } { - // SAFETY: same as above - let s = ManuallyDrop::new(s); - let rwlock = unsafe { ptr::read(&s.rwlock) }; - - Ok(ArcRwLockWriteGuard { - rwlock, - marker: PhantomData, - }) - } else { - Err(s) - } - } -} - -#[cfg(feature = "arc_lock")] -impl - ArcRwLockUpgradableReadGuard -{ - /// Tries to atomically upgrade an upgradable read lock into an exclusive - /// write lock, until a timeout is reached. - /// - /// If the access could not be granted before the timeout expires, then - /// `None` is returned. - /// - /// Otherwise, calls the provided closure with an exclusive reference to the lock's data, - /// and finally downgrades the lock back to an upgradable read lock. - /// The closure's return value is wrapped in `Some` and returned. - /// - /// This function only requires a mutable reference to the guard, unlike - /// `try_upgrade_for` which takes the guard by value. - pub fn try_with_upgraded_for Ret>( - &mut self, - timeout: R::Duration, - f: F, - ) -> Option { - if unsafe { self.rwlock.raw.try_upgrade_for(timeout) } { - // Safety: We just upgraded the lock, so we have mutable access to the data. - // This will restore the state the lock was in at the start of the function. - defer!(unsafe { self.rwlock.raw.downgrade_upgradable() }); - - // Safety: We upgraded the lock, so we have mutable access to the data. - // When this function returns, whether by drop or panic, - // the drop guard will downgrade it back to an upgradeable lock. - Some(f(unsafe { &mut *self.rwlock.data.get() })) - } else { - None - } - } - - /// Tries to atomically upgrade an upgradable read lock into an exclusive - /// write lock, until a timeout is reached. - /// - /// If the access could not be granted before the timeout expires, then - /// `None` is returned. - /// - /// Otherwise, calls the provided closure with an exclusive reference to the lock's data, - /// and finally downgrades the lock back to an upgradable read lock. - /// The closure's return value is wrapped in `Some` and returned. - /// - /// This function only requires a mutable reference to the guard, unlike - /// `try_upgrade_until` which takes the guard by value. - pub fn try_with_upgraded_until Ret>( - &mut self, - timeout: R::Instant, - f: F, - ) -> Option { - if unsafe { self.rwlock.raw.try_upgrade_until(timeout) } { - // Safety: We just upgraded the lock, so we have mutable access to the data. - // This will restore the state the lock was in at the start of the function. - defer!(unsafe { self.rwlock.raw.downgrade_upgradable() }); - - // Safety: We upgraded the lock, so we have mutable access to the data. - // When this function returns, whether by drop or panic, - // the drop guard will downgrade it back to an upgradeable lock. - Some(f(unsafe { &mut *self.rwlock.data.get() })) - } else { - None - } - } -} - -#[cfg(feature = "arc_lock")] -impl Deref for ArcRwLockUpgradableReadGuard { - type Target = T; - #[inline] - fn deref(&self) -> &T { - unsafe { &*self.rwlock.data.get() } - } -} - -#[cfg(feature = "arc_lock")] -impl Drop for ArcRwLockUpgradableReadGuard { - #[inline] - fn drop(&mut self) { - // Safety: An RwLockUpgradableReadGuard always holds an upgradable lock. - unsafe { - self.rwlock.raw.unlock_upgradable(); - } - } -} - -#[cfg(feature = "arc_lock")] -impl fmt::Debug - for ArcRwLockUpgradableReadGuard -{ - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - fmt::Debug::fmt(&**self, f) - } -} - -#[cfg(feature = "arc_lock")] -impl fmt::Display - for ArcRwLockUpgradableReadGuard -{ - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - (**self).fmt(f) - } -} - -/// An RAII read lock guard returned by `RwLockReadGuard::map`, which can point to a -/// subfield of the protected data. -/// -/// The main difference between `MappedRwLockReadGuard` and `RwLockReadGuard` is that the -/// former doesn't support temporarily unlocking and re-locking, since that -/// could introduce soundness issues if the locked object is modified by another -/// thread. -#[clippy::has_significant_drop] -#[must_use = "if unused the RwLock will immediately unlock"] -pub struct MappedRwLockReadGuard<'a, R: RawRwLock, T: ?Sized> { - raw: &'a R, - data: *const T, - marker: PhantomData<&'a T>, -} - -unsafe impl<'a, R: RawRwLock + 'a, T: ?Sized + Sync + 'a> Sync for MappedRwLockReadGuard<'a, R, T> {} -unsafe impl<'a, R: RawRwLock + 'a, T: ?Sized + Sync + 'a> Send for MappedRwLockReadGuard<'a, R, T> where - R::GuardMarker: Send -{ -} - -impl<'a, R: RawRwLock + 'a, T: ?Sized + 'a> MappedRwLockReadGuard<'a, R, T> { - /// Make a new `MappedRwLockReadGuard` for a component of the locked data. - /// - /// This operation cannot fail as the `MappedRwLockReadGuard` passed - /// in already locked the data. - /// - /// This is an associated function that needs to be - /// used as `MappedRwLockReadGuard::map(...)`. A method would interfere with methods of - /// the same name on the contents of the locked data. - #[inline] - pub fn map(s: Self, f: F) -> MappedRwLockReadGuard<'a, R, U> - where - F: FnOnce(&T) -> &U, - { - let raw = s.raw; - let data = f(unsafe { &*s.data }); - mem::forget(s); - MappedRwLockReadGuard { - raw, - data, - marker: PhantomData, - } - } - - /// Attempts to make a new `MappedRwLockReadGuard` for a component of the - /// locked data. The original guard is return if the closure returns `None`. - /// - /// This operation cannot fail as the `MappedRwLockReadGuard` passed - /// in already locked the data. - /// - /// This is an associated function that needs to be - /// used as `MappedRwLockReadGuard::try_map(...)`. A method would interfere with methods of - /// the same name on the contents of the locked data. - #[inline] - pub fn try_map(s: Self, f: F) -> Result, Self> - where - F: FnOnce(&T) -> Option<&U>, - { - let raw = s.raw; - let data = match f(unsafe { &*s.data }) { - Some(data) => data, - None => return Err(s), - }; - mem::forget(s); - Ok(MappedRwLockReadGuard { - raw, - data, - marker: PhantomData, - }) - } -} - -impl<'a, R: RawRwLockFair + 'a, T: ?Sized + 'a> MappedRwLockReadGuard<'a, R, T> { - /// Unlocks the `RwLock` using a fair unlock protocol. - /// - /// By default, `RwLock` is unfair and allow the current thread to re-lock - /// the `RwLock` before another has the chance to acquire the lock, even if - /// that thread has been blocked on the `RwLock` for a long time. This is - /// the default because it allows much higher throughput as it avoids - /// forcing a context switch on every `RwLock` unlock. This can result in one - /// thread acquiring a `RwLock` many more times than other threads. - /// - /// However in some cases it can be beneficial to ensure fairness by forcing - /// the lock to pass on to a waiting thread if there is one. This is done by - /// using this method instead of dropping the `MappedRwLockReadGuard` normally. - #[inline] - pub fn unlock_fair(s: Self) { - // Safety: A MappedRwLockReadGuard always holds a shared lock. - unsafe { - s.raw.unlock_shared_fair(); - } - mem::forget(s); - } -} - -impl<'a, R: RawRwLock + 'a, T: ?Sized + 'a> Deref for MappedRwLockReadGuard<'a, R, T> { - type Target = T; - #[inline] - fn deref(&self) -> &T { - unsafe { &*self.data } - } -} - -impl<'a, R: RawRwLock + 'a, T: ?Sized + 'a> Drop for MappedRwLockReadGuard<'a, R, T> { - #[inline] - fn drop(&mut self) { - // Safety: A MappedRwLockReadGuard always holds a shared lock. - unsafe { - self.raw.unlock_shared(); - } - } -} - -impl<'a, R: RawRwLock + 'a, T: fmt::Debug + ?Sized + 'a> fmt::Debug - for MappedRwLockReadGuard<'a, R, T> -{ - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - fmt::Debug::fmt(&**self, f) - } -} - -impl<'a, R: RawRwLock + 'a, T: fmt::Display + ?Sized + 'a> fmt::Display - for MappedRwLockReadGuard<'a, R, T> -{ - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - (**self).fmt(f) - } -} - -#[cfg(feature = "owning_ref")] -unsafe impl<'a, R: RawRwLock + 'a, T: ?Sized + 'a> StableAddress - for MappedRwLockReadGuard<'a, R, T> -{ -} - -/// An RAII write lock guard returned by `RwLockWriteGuard::map`, which can point to a -/// subfield of the protected data. -/// -/// The main difference between `MappedRwLockWriteGuard` and `RwLockWriteGuard` is that the -/// former doesn't support temporarily unlocking and re-locking, since that -/// could introduce soundness issues if the locked object is modified by another -/// thread. -#[clippy::has_significant_drop] -#[must_use = "if unused the RwLock will immediately unlock"] -pub struct MappedRwLockWriteGuard<'a, R: RawRwLock, T: ?Sized> { - raw: &'a R, - data: *mut T, - marker: PhantomData<&'a mut T>, -} - -unsafe impl<'a, R: RawRwLock + 'a, T: ?Sized + Sync + 'a> Sync - for MappedRwLockWriteGuard<'a, R, T> -{ -} -unsafe impl<'a, R: RawRwLock + 'a, T: ?Sized + Send + 'a> Send for MappedRwLockWriteGuard<'a, R, T> where - R::GuardMarker: Send -{ -} - -impl<'a, R: RawRwLock + 'a, T: ?Sized + 'a> MappedRwLockWriteGuard<'a, R, T> { - /// Make a new `MappedRwLockWriteGuard` for a component of the locked data. - /// - /// This operation cannot fail as the `MappedRwLockWriteGuard` passed - /// in already locked the data. - /// - /// This is an associated function that needs to be - /// used as `MappedRwLockWriteGuard::map(...)`. A method would interfere with methods of - /// the same name on the contents of the locked data. - #[inline] - pub fn map(s: Self, f: F) -> MappedRwLockWriteGuard<'a, R, U> - where - F: FnOnce(&mut T) -> &mut U, - { - let raw = s.raw; - let data = f(unsafe { &mut *s.data }); - mem::forget(s); - MappedRwLockWriteGuard { - raw, - data, - marker: PhantomData, - } - } - - /// Attempts to make a new `MappedRwLockWriteGuard` for a component of the - /// locked data. The original guard is return if the closure returns `None`. - /// - /// This operation cannot fail as the `MappedRwLockWriteGuard` passed - /// in already locked the data. - /// - /// This is an associated function that needs to be - /// used as `MappedRwLockWriteGuard::try_map(...)`. A method would interfere with methods of - /// the same name on the contents of the locked data. - #[inline] - pub fn try_map(s: Self, f: F) -> Result, Self> - where - F: FnOnce(&mut T) -> Option<&mut U>, - { - let raw = s.raw; - let data = match f(unsafe { &mut *s.data }) { - Some(data) => data, - None => return Err(s), - }; - mem::forget(s); - Ok(MappedRwLockWriteGuard { - raw, - data, - marker: PhantomData, - }) - } -} - -impl<'a, R: RawRwLockFair + 'a, T: ?Sized + 'a> MappedRwLockWriteGuard<'a, R, T> { - /// Unlocks the `RwLock` using a fair unlock protocol. - /// - /// By default, `RwLock` is unfair and allow the current thread to re-lock - /// the `RwLock` before another has the chance to acquire the lock, even if - /// that thread has been blocked on the `RwLock` for a long time. This is - /// the default because it allows much higher throughput as it avoids - /// forcing a context switch on every `RwLock` unlock. This can result in one - /// thread acquiring a `RwLock` many more times than other threads. - /// - /// However in some cases it can be beneficial to ensure fairness by forcing - /// the lock to pass on to a waiting thread if there is one. This is done by - /// using this method instead of dropping the `MappedRwLockWriteGuard` normally. - #[inline] - pub fn unlock_fair(s: Self) { - // Safety: A MappedRwLockWriteGuard always holds an exclusive lock. - unsafe { - s.raw.unlock_exclusive_fair(); - } - mem::forget(s); - } -} - -impl<'a, R: RawRwLock + 'a, T: ?Sized + 'a> Deref for MappedRwLockWriteGuard<'a, R, T> { - type Target = T; - #[inline] - fn deref(&self) -> &T { - unsafe { &*self.data } - } -} - -impl<'a, R: RawRwLock + 'a, T: ?Sized + 'a> DerefMut for MappedRwLockWriteGuard<'a, R, T> { - #[inline] - fn deref_mut(&mut self) -> &mut T { - unsafe { &mut *self.data } - } -} - -impl<'a, R: RawRwLock + 'a, T: ?Sized + 'a> Drop for MappedRwLockWriteGuard<'a, R, T> { - #[inline] - fn drop(&mut self) { - // Safety: A MappedRwLockWriteGuard always holds an exclusive lock. - unsafe { - self.raw.unlock_exclusive(); - } - } -} - -impl<'a, R: RawRwLock + 'a, T: fmt::Debug + ?Sized + 'a> fmt::Debug - for MappedRwLockWriteGuard<'a, R, T> -{ - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - fmt::Debug::fmt(&**self, f) - } -} - -impl<'a, R: RawRwLock + 'a, T: fmt::Display + ?Sized + 'a> fmt::Display - for MappedRwLockWriteGuard<'a, R, T> -{ - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - (**self).fmt(f) - } -} - -#[cfg(feature = "owning_ref")] -unsafe impl<'a, R: RawRwLock + 'a, T: ?Sized + 'a> StableAddress - for MappedRwLockWriteGuard<'a, R, T> -{ -} diff --git a/third-party/vendor/log/.cargo-checksum.json b/third-party/vendor/log/.cargo-checksum.json deleted file mode 100644 index 357ec02f..00000000 --- a/third-party/vendor/log/.cargo-checksum.json +++ /dev/null @@ -1 +0,0 @@ -{"files":{"CHANGELOG.md":"4cf5d5c08ecf2cca9bfc6c0393fb06375675e1a712cd0da17426d54dd6b26281","Cargo.toml":"400053190237140d908218465ab8942fe65196c43925be6faef37e284b5817ff","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"6485b8ed310d3f0340bf1ad1f47645069ce4069dcc6bb46c7d5c6faf41de1fdb","README.md":"788bda1deb337541be7ddaf8a7483d1c315f008aeab72374973135ad490e06c4","benches/value.rs":"6ce7689c8c714c93fa58afa984aefe54f0fc279fdd69e1582d013c97d1688eba","src/__private_api.rs":"de6799f0772181878a2fbfb93146641243a86f1115f2e8234a255d70105e2e65","src/kv/error.rs":"5dea46a9eb2128442a60f7f8a0e0b9e5f155bc0e9ecc5134f91e466cb04c8a31","src/kv/key.rs":"941979c92db5f9b999b9eba4f96a8d43da034da80849fbfa65277f122b5fc39f","src/kv/mod.rs":"3592b750c206d5a36545d0c5f2e5db79c499c3f96dced13c5aeeacc7409b4ff6","src/kv/source.rs":"4fd7f0083caef44094984c02bd3d15d7e5fd6b95e809b2d6abab31aa8d01f5c3","src/kv/value.rs":"7f0ee0327dcfbb3df3ed4f0c8caed4bebd4b76bb7407f32f100d660f2a10eabd","src/lib.rs":"1332fb825d498244bf068ce929d744c7316888c7f99e4711149af69ed028730c","src/macros.rs":"f0604416b1a839ba84509c17bff3741766cfa401cb09c0b00e33c36ae1c710ad","src/serde.rs":"1f8614b42ffb1b34bdf58ce3ab6584b760a8a9e9aa6e00b27dc229cbc46f0a2b","triagebot.toml":"a135e10c777cd13459559bdf74fb704c1379af7c9b0f70bc49fa6f5a837daa81"},"package":"b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f"} \ No newline at end of file diff --git a/third-party/vendor/log/CHANGELOG.md b/third-party/vendor/log/CHANGELOG.md deleted file mode 100644 index 60870804..00000000 --- a/third-party/vendor/log/CHANGELOG.md +++ /dev/null @@ -1,273 +0,0 @@ -# Change Log - -## [Unreleased] - -## [0.4.20] - 2023-07-11 - -* Remove rustversion dev-dependency by @Thomasdezeeuw in https://github.com/rust-lang/log/pull/568 -* Remove `local_inner_macros` usage by @EFanZh in https://github.com/rust-lang/log/pull/570 - -## [0.4.19] - 2023-06-10 - -* Use target_has_atomic instead of the old atomic_cas cfg by @GuillaumeGomez in https://github.com/rust-lang/log/pull/555 -* Put MSRV into Cargo.toml by @est31 in https://github.com/rust-lang/log/pull/557 - -## [0.4.18] - 2023-05-28 - -* fix markdown links (again) by @hellow554 in https://github.com/rust-lang/log/pull/513 -* add cargo doc to workflow by @hellow554 in https://github.com/rust-lang/log/pull/515 -* Apply Clippy lints by @hellow554 in https://github.com/rust-lang/log/pull/516 -* Replace ad-hoc eq_ignore_ascii_case with slice::eq_ignore_ascii_case by @glandium in https://github.com/rust-lang/log/pull/519 -* fix up windows targets by @KodrAus in https://github.com/rust-lang/log/pull/528 -* typo fix by @jiangying000 in https://github.com/rust-lang/log/pull/529 -* Remove dependency on cfg_if by @EriKWDev in https://github.com/rust-lang/log/pull/536 -* GitHub Workflows security hardening by @sashashura in https://github.com/rust-lang/log/pull/538 -* Fix build status badge by @atouchet in https://github.com/rust-lang/log/pull/539 -* Add call_logger to the documentation by @a1ecbr0wn in https://github.com/rust-lang/log/pull/547 -* Use stable internals for key-value API by @KodrAus in https://github.com/rust-lang/log/pull/550 -* Change wording of list of implementations by @Thomasdezeeuw in https://github.com/rust-lang/log/pull/553 -* Add std-logger to list of implementations by @Thomasdezeeuw in https://github.com/rust-lang/log/pull/554 -* Add `set_max_level_racy` and gate `set_max_level` by @djkoloski in https://github.com/rust-lang/log/pull/544 -* [doc] src/lib.rs : prefix an unused variable with an underscore by @OccupyMars2025 in https://github.com/rust-lang/log/pull/561 -* [doc] src/macros.rs : correct grammar errors of an example in lib documentation by @OccupyMars2025 in https://github.com/rust-lang/log/pull/562 - -## [0.4.17] - 2022-04-29 - -* Update `kv_unstable` internal dependencies. - -## [0.4.16] - 2022-03-22 - -* Fix a conflict with unqualified `Option` use in macros. - -## [0.4.15] - 2022-02-23 - -* Silence a warning about the deprecated `spin_loop_hint`. -* Relax ordering in the atomic `set_max_level` call. -* Add thumbv4t-none-eabi to targets that don't support atomics -* Allow levels to be iterated over. -* Implement `Log` on some common wrapper types. -* Improvements to test coverage. -* Improvements to documentation. -* Add key-value support to the `log!` macros. -* Tighten `kv_unstable` internal dependencies so they don't bump past their current alpha. -* Add a simple visit API to `kv_unstable`. -* Support `NonZero*` integers as values in structured logging -* Support static strings as keys in structured logging - -## [0.4.14] - 2021-01-27 - -* Remove the `__private_api_log_lit` special case. -* Fixed incorrect combination of `kv_unstable` and `std` features causing compile failures. -* Remove unstable `Value::to_*` conversions that were incorrectly using `as`. -* Rename unstable `Value::to_error` to `Value::to_borrowed_error`. - -## [0.4.13] - 2021-01-11 - -* This is the same as `0.4.11`, except with a `kv_unstable_std` feature added to aid migrating current dependents to `0.4.14` (which was originally going to be `0.4.13` until it was decided to create a patch from `0.4.11` to minimize disruption). - -## [0.4.12] - 2020-12-24 - -### New - -* Support platforms without atomics by racing instead of failing to compile -* Implement `Log` for `Box` -* Update `cfg-if` to `1.0` -* Internal reworks of the structured logging API. Removed the `Fill` API -and added `source::as_map` and `source::as_list` to easily serialize a `Source` -as either a map of `{key: value, ..}` or as a list of `[(key, value), ..]`. - -### Fixed - -* Fixed deserialization of `LevelFilter` to use their `u64` index variants - -## [0.4.11] - 2020-07-09 - -### New - -* Support coercing structured values into concrete types. -* Reference the `win_dbg_logger` in the readme. - -### Fixed - -* Updates a few deprecated items used internally. -* Fixed issues in docs and expands sections. -* Show the correct build badge in the readme. -* Fix up a possible inference breakage with structured value errors. -* Respect formatting flags in structured value formatting. - -## [0.4.10] - 2019-12-16 (yanked) - -### Fixed - -* Fixed the `log!` macros so they work in expression context (this regressed in `0.4.9`, which has been yanked). - -## [0.4.9] - 2019-12-12 (yanked) - -### Minimum Supported Rust Version - -This release bumps the minimum compiler version to `1.31.0`. This was mainly needed for `cfg-if`, -but between `1.16.0` and `1.31.0` there are a lot of language and library improvements we now -take advantage of. - -### New - -* Unstable support for capturing key-value pairs in a record using the `log!` macros - -### Improved - -* Better documentation for max level filters. -* Internal updates to line up with bumped MSRV - -## [0.4.8] - 2019-07-28 - -### New - -* Support attempting to get `Record` fields as static strings. - -## [0.4.7] - 2019-07-06 - -### New - -* Support for embedded environments with thread-unsafe initialization. -* Initial unstable support for capturing structured data under the `kv_unstable` -feature gate. This new API doesn't affect existing users and may change in future -patches (so those changes may not appear in the changelog until it stabilizes). - -### Improved - -* Docs for using `log` with the 2018 edition. -* Error messages for macros missing arguments. - -## [0.4.6] - 2018-10-27 - -### Improved - -* Support 2018-style macro import for the `log_enabled!` macro. - -## [0.4.5] - 2018-09-03 - -### Improved - -* Make `log`'s internal helper macros less likely to conflict with user-defined - macros. - -## [0.4.4] - 2018-08-17 - -### Improved - -* Support 2018-style imports of the log macros. - -## [0.4.3] - 2018-06-29 - -### Improved - -* More code generation improvements. - -## [0.4.2] - 2018-06-05 - -### Improved - -* Log invocations now generate less code. - -### Fixed - -* Example Logger implementations now properly set the max log level. - -## [0.4.1] - 2017-12-30 - -### Fixed - -* Some doc links were fixed. - -## [0.4.0] - 2017-12-24 - -The changes in this release include cleanup of some obscure functionality and a more robust public -API designed to support bridges to other logging systems, and provide more flexibility to new -features in the future. - -### Compatibility - -Vast portions of the Rust ecosystem use the 0.3.x release series of log, and we don't want to force -the community to go through the pain of upgrading every crate to 0.4.x at the exact same time. Along -with 0.4.0, we've published a new 0.3.9 release which acts as a "shim" over 0.4.0. This will allow -crates using either version to coexist without losing messages from one side or the other. - -There is one caveat - a log message generated by a crate using 0.4.x but consumed by a logging -implementation using 0.3.x will not have a file name or module path. Applications affected by this -can upgrade their logging implementations to one using 0.4.x to avoid losing this information. The -other direction does not lose any information, fortunately! - -**TL;DR** Libraries should feel comfortable upgrading to 0.4.0 without treating that as a breaking -change. Applications may need to update their logging implementation (e.g. env-logger) to a newer -version using log 0.4.x to avoid losing module and file information. - -### New - -* The crate is now `no_std` by default. -* `Level` and `LevelFilter` now implement `Serialize` and `Deserialize` when the `serde` feature is - enabled. -* The `Record` and `Metadata` types can now be constructed by third-party code via a builder API. -* The `logger` free function returns a reference to the logger implementation. This, along with the - ability to construct `Record`s, makes it possible to bridge from another logging framework to - this one without digging into the private internals of the crate. The standard `error!` `warn!`, - etc, macros now exclusively use the public API of the crate rather than "secret" internal APIs. -* `Log::flush` has been added to allow crates to tell the logging implementation to ensure that all - "in flight" log events have been persisted. This can be used, for example, just before an - application exits to ensure that asynchronous log sinks finish their work. - -### Removed - -* The `shutdown` and `shutdown_raw` functions have been removed. Supporting shutdown significantly - complicated the implementation and imposed a performance cost on each logging operation. -* The `log_panics` function and its associated `nightly` Cargo feature have been removed. Use the - [log-panics](https://crates.io/crates/log-panics) instead. - -### Changed - -* The `Log` prefix has been removed from type names. For example, `LogLevelFilter` is now - `LevelFilter`, and `LogRecord` is now `Record`. -* The `MaxLogLevelFilter` object has been removed in favor of a `set_max_level` free function. -* The `set_logger` free functions have been restructured. The logger is now directly passed to the - functions rather than a closure which returns the logger. `set_logger` now takes a `&'static - Log` and is usable in `no_std` contexts in place of the old `set_logger_raw`. `set_boxed_logger` - is a convenience function which takes a `Box` but otherwise acts like `set_logger`. It - requires the `std` feature. -* The `file` and `module_path` values in `Record` no longer have the `'static` lifetime to support - integration with other logging frameworks that don't provide a `'static` lifetime for the - equivalent values. -* The `file`, `line`, and `module_path` values in `Record` are now `Option`s to support integration - with other logging frameworks that don't provide those values. - -### In the Future - -* We're looking to add support for *structured* logging - the inclusion of extra key-value pairs of - information in a log event in addition to the normal string message. This should be able to be - added in a backwards compatible manner to the 0.4.x series when the design is worked out. - -## Older - -Look at the [release tags] for information about older releases. - -[Unreleased]: https://github.com/rust-lang-nursery/log/compare/0.4.18...HEAD -[0.4.20]: https://github.com/rust-lang-nursery/log/compare/0.4.19...0.4.20 -[0.4.19]: https://github.com/rust-lang-nursery/log/compare/0.4.18...0.4.19 -[0.4.18]: https://github.com/rust-lang-nursery/log/compare/0.4.17...0.4.18 -[0.4.17]: https://github.com/rust-lang-nursery/log/compare/0.4.16...0.4.17 -[0.4.16]: https://github.com/rust-lang-nursery/log/compare/0.4.15...0.4.16 -[0.4.15]: https://github.com/rust-lang-nursery/log/compare/0.4.13...0.4.15 -[0.4.14]: https://github.com/rust-lang-nursery/log/compare/0.4.13...0.4.14 -[0.4.13]: https://github.com/rust-lang-nursery/log/compare/0.4.11...0.4.13 -[0.4.12]: https://github.com/rust-lang-nursery/log/compare/0.4.11...0.4.12 -[0.4.11]: https://github.com/rust-lang-nursery/log/compare/0.4.10...0.4.11 -[0.4.10]: https://github.com/rust-lang-nursery/log/compare/0.4.9...0.4.10 -[0.4.9]: https://github.com/rust-lang-nursery/log/compare/0.4.8...0.4.9 -[0.4.8]: https://github.com/rust-lang-nursery/log/compare/0.4.7...0.4.8 -[0.4.7]: https://github.com/rust-lang-nursery/log/compare/0.4.6...0.4.7 -[0.4.6]: https://github.com/rust-lang-nursery/log/compare/0.4.5...0.4.6 -[0.4.5]: https://github.com/rust-lang-nursery/log/compare/0.4.4...0.4.5 -[0.4.4]: https://github.com/rust-lang-nursery/log/compare/0.4.3...0.4.4 -[0.4.3]: https://github.com/rust-lang-nursery/log/compare/0.4.2...0.4.3 -[0.4.2]: https://github.com/rust-lang-nursery/log/compare/0.4.1...0.4.2 -[0.4.1]: https://github.com/rust-lang-nursery/log/compare/0.4.0...0.4.1 -[0.4.0]: https://github.com/rust-lang-nursery/log/compare/0.3.8...0.4.0 -[release tags]: https://github.com/rust-lang-nursery/log/releases diff --git a/third-party/vendor/log/Cargo.toml b/third-party/vendor/log/Cargo.toml deleted file mode 100644 index b72d9c31..00000000 --- a/third-party/vendor/log/Cargo.toml +++ /dev/null @@ -1,118 +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 are reading this file be aware that the original Cargo.toml -# will likely look very different (and much more reasonable). -# See Cargo.toml.orig for the original contents. - -[package] -rust-version = "1.60.0" -name = "log" -version = "0.4.20" -authors = ["The Rust Project Developers"] -exclude = ["rfcs/**/*"] -description = """ -A lightweight logging facade for Rust -""" -documentation = "https://docs.rs/log" -readme = "README.md" -keywords = ["logging"] -categories = ["development-tools::debugging"] -license = "MIT OR Apache-2.0" -repository = "https://github.com/rust-lang/log" - -[package.metadata.docs.rs] -features = [ - "std", - "serde", - "kv_unstable_std", - "kv_unstable_sval", - "kv_unstable_serde", -] - -[[test]] -name = "filters" -path = "tests/filters.rs" -harness = false - -[[test]] -name = "macros" -path = "tests/macros.rs" -harness = true - -[dependencies.serde] -version = "1.0" -optional = true -default-features = false - -[dependencies.sval] -version = "2.1" -optional = true -default-features = false - -[dependencies.sval_ref] -version = "2.1" -optional = true -default-features = false - -[dependencies.value-bag] -version = "1.4" -optional = true -default-features = false - -[dev-dependencies.proc-macro2] -version = "1.0.63" -default-features = false - -[dev-dependencies.serde] -version = "1.0" -features = ["derive"] - -[dev-dependencies.serde_test] -version = "1.0" - -[dev-dependencies.sval] -version = "2.1" - -[dev-dependencies.sval_derive] -version = "2.1" - -[dev-dependencies.value-bag] -version = "1.4" -features = ["test"] - -[features] -kv_unstable = ["value-bag"] -kv_unstable_serde = [ - "kv_unstable_std", - "value-bag/serde", - "serde", -] -kv_unstable_std = [ - "std", - "kv_unstable", - "value-bag/error", -] -kv_unstable_sval = [ - "kv_unstable", - "value-bag/sval", - "sval", - "sval_ref", -] -max_level_debug = [] -max_level_error = [] -max_level_info = [] -max_level_off = [] -max_level_trace = [] -max_level_warn = [] -release_max_level_debug = [] -release_max_level_error = [] -release_max_level_info = [] -release_max_level_off = [] -release_max_level_trace = [] -release_max_level_warn = [] -std = [] diff --git a/third-party/vendor/log/LICENSE-APACHE b/third-party/vendor/log/LICENSE-APACHE deleted file mode 100644 index 16fe87b0..00000000 --- a/third-party/vendor/log/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. diff --git a/third-party/vendor/log/LICENSE-MIT b/third-party/vendor/log/LICENSE-MIT deleted file mode 100644 index 39d4bdb5..00000000 --- a/third-party/vendor/log/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. diff --git a/third-party/vendor/log/README.md b/third-party/vendor/log/README.md deleted file mode 100644 index 3dd64579..00000000 --- a/third-party/vendor/log/README.md +++ /dev/null @@ -1,121 +0,0 @@ -log -=== - -A Rust library providing a lightweight logging *facade*. - -[![Build status](https://img.shields.io/github/actions/workflow/status/rust-lang/log/main.yml?branch=master)](https://github.com/rust-lang/log/actions) -[![Latest version](https://img.shields.io/crates/v/log.svg)](https://crates.io/crates/log) -[![Documentation](https://docs.rs/log/badge.svg)](https://docs.rs/log) -![License](https://img.shields.io/crates/l/log.svg) - -* [`log` documentation](https://docs.rs/log) - -A logging facade provides a single logging API that abstracts over the actual -logging implementation. Libraries can use the logging API provided by this -crate, and the consumer of those libraries can choose the logging -implementation that is most suitable for its use case. - - -## Minimum supported `rustc` - -`1.60.0+` - -This version is explicitly tested in CI and may be bumped in any release as needed. Maintaining compatibility with older compilers is a priority though, so the bar for bumping the minimum supported version is set very high. Any changes to the supported minimum version will be called out in the release notes. - -## Usage - -### In libraries - -Libraries should link only to the `log` crate, and use the provided macros to -log whatever information will be useful to downstream consumers: - -```toml -[dependencies] -log = "0.4" -``` - -```rust -use log::{info, trace, warn}; - -pub fn shave_the_yak(yak: &mut Yak) { - trace!("Commencing yak shaving"); - - loop { - match find_a_razor() { - Ok(razor) => { - info!("Razor located: {}", razor); - yak.shave(razor); - break; - } - Err(err) => { - warn!("Unable to locate a razor: {}, retrying", err); - } - } - } -} -``` - -### In executables - -In order to produce log output, executables have to use a logger implementation compatible with the facade. -There are many available implementations to choose from, here are some options: - -* Simple minimal loggers: - * [`env_logger`](https://docs.rs/env_logger/*/env_logger/) - * [`simple_logger`](https://docs.rs/simple_logger/*/simple_logger/) - * [`simplelog`](https://docs.rs/simplelog/*/simplelog/) - * [`pretty_env_logger`](https://docs.rs/pretty_env_logger/*/pretty_env_logger/) - * [`stderrlog`](https://docs.rs/stderrlog/*/stderrlog/) - * [`flexi_logger`](https://docs.rs/flexi_logger/*/flexi_logger/) - * [`call_logger`](https://docs.rs/call_logger/*/call_logger/) - * [`std-logger`](https://docs.rs/std-logger/*/std_logger/) - * [`structured-logger`](https://docs.rs/structured-logger/latest/structured_logger/) -* Complex configurable frameworks: - * [`log4rs`](https://docs.rs/log4rs/*/log4rs/) - * [`fern`](https://docs.rs/fern/*/fern/) -* Adaptors for other facilities: - * [`syslog`](https://docs.rs/syslog/*/syslog/) - * [`systemd-journal-logger`](https://docs.rs/systemd-journal-logger/*/systemd_journal_logger/) - * [`slog-stdlog`](https://docs.rs/slog-stdlog/*/slog_stdlog/) - * [`android_log`](https://docs.rs/android_log/*/android_log/) - * [`win_dbg_logger`](https://docs.rs/win_dbg_logger/*/win_dbg_logger/) - * [`db_logger`](https://docs.rs/db_logger/*/db_logger/) - * [`log-to-defmt`](https://docs.rs/log-to-defmt/*/log_to_defmt/) -* For WebAssembly binaries: - * [`console_log`](https://docs.rs/console_log/*/console_log/) -* For dynamic libraries: - * You may need to construct [an FFI-safe wrapper over `log`](https://github.com/rust-lang/log/issues/421) to initialize in your libraries. -* Utilities: - * [`log_err`](https://docs.rs/log_err/*/log_err/) - -Executables should choose a logger implementation and initialize it early in the -runtime of the program. Logger implementations will typically include a -function to do this. Any log messages generated before the logger is -initialized will be ignored. - -The executable itself may use the `log` crate to log as well. - -## Structured logging - -If you enable the `kv_unstable` feature, you can associate structured data with your log records: - -```rust -use log::{info, trace, warn, as_serde, as_error}; - -pub fn shave_the_yak(yak: &mut Yak) { - trace!(target = "yak_events", yak = as_serde!(yak); "Commencing yak shaving"); - - loop { - match find_a_razor() { - Ok(razor) => { - info!(razor = razor; "Razor located"); - yak.shave(razor); - break; - } - Err(err) => { - warn!(err = as_error!(err); "Unable to locate a razor, retrying"); - } - } - } -} -``` diff --git a/third-party/vendor/log/benches/value.rs b/third-party/vendor/log/benches/value.rs deleted file mode 100644 index 4e6960e8..00000000 --- a/third-party/vendor/log/benches/value.rs +++ /dev/null @@ -1,30 +0,0 @@ -#![cfg(feature = "kv_unstable")] -#![feature(test)] - -extern crate log; -extern crate test; - -use log::kv::Value; - -#[bench] -fn u8_to_value(b: &mut test::Bencher) { - b.iter(|| Value::from(1u8)) -} - -#[bench] -fn u8_to_value_debug(b: &mut test::Bencher) { - b.iter(|| Value::from_debug(&1u8)) -} - -#[bench] -fn str_to_value_debug(b: &mut test::Bencher) { - b.iter(|| Value::from_debug(&"a string")) -} - -#[bench] -fn custom_to_value_debug(b: &mut test::Bencher) { - #[derive(Debug)] - struct A; - - b.iter(|| Value::from_debug(&A)) -} diff --git a/third-party/vendor/log/src/__private_api.rs b/third-party/vendor/log/src/__private_api.rs deleted file mode 100644 index 7304deb8..00000000 --- a/third-party/vendor/log/src/__private_api.rs +++ /dev/null @@ -1,57 +0,0 @@ -//! WARNING: this is not part of the crate's public API and is subject to change at any time - -use crate::{Level, Metadata, Record}; -use std::fmt::Arguments; -pub use std::option::Option; -pub use std::{file, format_args, line, module_path, stringify}; - -#[cfg(not(feature = "kv_unstable"))] -pub fn log( - args: Arguments, - level: Level, - &(target, module_path, file): &(&str, &'static str, &'static str), - line: u32, - kvs: Option<&[(&str, &str)]>, -) { - if kvs.is_some() { - panic!( - "key-value support is experimental and must be enabled using the `kv_unstable` feature" - ) - } - - crate::logger().log( - &Record::builder() - .args(args) - .level(level) - .target(target) - .module_path_static(Some(module_path)) - .file_static(Some(file)) - .line(Some(line)) - .build(), - ); -} - -#[cfg(feature = "kv_unstable")] -pub fn log( - args: Arguments, - level: Level, - &(target, module_path, file): &(&str, &'static str, &'static str), - line: u32, - kvs: Option<&[(&str, &dyn crate::kv::ToValue)]>, -) { - crate::logger().log( - &Record::builder() - .args(args) - .level(level) - .target(target) - .module_path_static(Some(module_path)) - .file_static(Some(file)) - .line(Some(line)) - .key_values(&kvs) - .build(), - ); -} - -pub fn enabled(level: Level, target: &str) -> bool { - crate::logger().enabled(&Metadata::builder().level(level).target(target).build()) -} diff --git a/third-party/vendor/log/src/kv/error.rs b/third-party/vendor/log/src/kv/error.rs deleted file mode 100644 index c72d3239..00000000 --- a/third-party/vendor/log/src/kv/error.rs +++ /dev/null @@ -1,90 +0,0 @@ -use std::fmt; - -/// An error encountered while working with structured data. -#[derive(Debug)] -pub struct Error { - inner: Inner, -} - -#[derive(Debug)] -enum Inner { - #[cfg(feature = "std")] - Boxed(std_support::BoxedError), - Msg(&'static str), - Value(value_bag::Error), - Fmt, -} - -impl Error { - /// Create an error from a message. - pub fn msg(msg: &'static str) -> Self { - Error { - inner: Inner::Msg(msg), - } - } - - // Not public so we don't leak the `value_bag` API - pub(super) fn from_value(err: value_bag::Error) -> Self { - Error { - inner: Inner::Value(err), - } - } - - // Not public so we don't leak the `value_bag` API - pub(super) fn into_value(self) -> value_bag::Error { - match self.inner { - Inner::Value(err) => err, - #[cfg(feature = "kv_unstable_std")] - _ => value_bag::Error::boxed(self), - #[cfg(not(feature = "kv_unstable_std"))] - _ => value_bag::Error::msg("error inspecting a value"), - } - } -} - -impl fmt::Display for Error { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - use self::Inner::*; - match &self.inner { - #[cfg(feature = "std")] - &Boxed(ref err) => err.fmt(f), - &Value(ref err) => err.fmt(f), - &Msg(ref msg) => msg.fmt(f), - &Fmt => fmt::Error.fmt(f), - } - } -} - -impl From for Error { - fn from(_: fmt::Error) -> Self { - Error { inner: Inner::Fmt } - } -} - -#[cfg(feature = "std")] -mod std_support { - use super::*; - use std::{error, io}; - - pub(super) type BoxedError = Box; - - impl Error { - /// Create an error from a standard error type. - pub fn boxed(err: E) -> Self - where - E: Into, - { - Error { - inner: Inner::Boxed(err.into()), - } - } - } - - impl error::Error for Error {} - - impl From for Error { - fn from(err: io::Error) -> Self { - Error::boxed(err) - } - } -} diff --git a/third-party/vendor/log/src/kv/key.rs b/third-party/vendor/log/src/kv/key.rs deleted file mode 100644 index 4f9a506e..00000000 --- a/third-party/vendor/log/src/kv/key.rs +++ /dev/null @@ -1,157 +0,0 @@ -//! Structured keys. - -use std::borrow::Borrow; -use std::fmt; - -/// A type that can be converted into a [`Key`](struct.Key.html). -pub trait ToKey { - /// Perform the conversion. - fn to_key(&self) -> Key; -} - -impl<'a, T> ToKey for &'a T -where - T: ToKey + ?Sized, -{ - fn to_key(&self) -> Key { - (**self).to_key() - } -} - -impl<'k> ToKey for Key<'k> { - fn to_key(&self) -> Key { - Key { key: self.key } - } -} - -impl ToKey for str { - fn to_key(&self) -> Key { - Key::from_str(self) - } -} - -/// A key in a structured key-value pair. -// These impls must only be based on the as_str() representation of the key -// If a new field (such as an optional index) is added to the key they must not affect comparison -#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] -pub struct Key<'k> { - key: &'k str, -} - -impl<'k> Key<'k> { - /// Get a key from a borrowed string. - pub fn from_str(key: &'k str) -> Self { - Key { key } - } - - /// Get a borrowed string from this key. - pub fn as_str(&self) -> &str { - self.key - } - - /// Try get a string borrowed for the `'k` lifetime from this key. - pub fn to_borrowed_str(&self) -> Option<&'k str> { - // NOTE: This API leaves room for keys to be owned - Some(self.key) - } -} - -impl<'k> fmt::Display for Key<'k> { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - self.key.fmt(f) - } -} - -impl<'k> AsRef for Key<'k> { - fn as_ref(&self) -> &str { - self.as_str() - } -} - -impl<'k> Borrow for Key<'k> { - fn borrow(&self) -> &str { - self.as_str() - } -} - -impl<'k> From<&'k str> for Key<'k> { - fn from(s: &'k str) -> Self { - Key::from_str(s) - } -} - -#[cfg(feature = "std")] -mod std_support { - use super::*; - - use std::borrow::Cow; - - impl ToKey for String { - fn to_key(&self) -> Key { - Key::from_str(self) - } - } - - impl<'a> ToKey for Cow<'a, str> { - fn to_key(&self) -> Key { - Key::from_str(self) - } - } -} - -#[cfg(feature = "kv_unstable_sval")] -mod sval_support { - use super::*; - - extern crate sval; - extern crate sval_ref; - - use self::sval::Value; - use self::sval_ref::ValueRef; - - impl<'a> Value for Key<'a> { - fn stream<'sval, S: sval::Stream<'sval> + ?Sized>( - &'sval self, - stream: &mut S, - ) -> sval::Result { - self.key.stream(stream) - } - } - - impl<'a> ValueRef<'a> for Key<'a> { - fn stream_ref + ?Sized>( - &self, - stream: &mut S, - ) -> self::sval::Result { - self.key.stream(stream) - } - } -} - -#[cfg(feature = "kv_unstable_serde")] -mod serde_support { - use super::*; - - extern crate serde; - - use self::serde::{Serialize, Serializer}; - - impl<'a> Serialize for Key<'a> { - fn serialize(&self, serializer: S) -> Result - where - S: Serializer, - { - self.key.serialize(serializer) - } - } -} - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn key_from_string() { - assert_eq!("a key", Key::from_str("a key").as_str()); - } -} diff --git a/third-party/vendor/log/src/kv/mod.rs b/third-party/vendor/log/src/kv/mod.rs deleted file mode 100644 index 5dc69337..00000000 --- a/third-party/vendor/log/src/kv/mod.rs +++ /dev/null @@ -1,26 +0,0 @@ -//! **UNSTABLE:** Structured key-value pairs. -//! -//! This module is unstable and breaking changes may be made -//! at any time. See [the tracking issue](https://github.com/rust-lang-nursery/log/issues/328) -//! for more details. -//! -//! Add the `kv_unstable` feature to your `Cargo.toml` to enable -//! this module: -//! -//! ```toml -//! [dependencies.log] -//! features = ["kv_unstable"] -//! ``` - -mod error; -mod key; -pub mod source; - -pub mod value; - -pub use self::error::Error; -pub use self::key::{Key, ToKey}; -pub use self::source::{Source, Visitor}; - -#[doc(inline)] -pub use self::value::{ToValue, Value}; diff --git a/third-party/vendor/log/src/kv/source.rs b/third-party/vendor/log/src/kv/source.rs deleted file mode 100644 index 45fc6dce..00000000 --- a/third-party/vendor/log/src/kv/source.rs +++ /dev/null @@ -1,776 +0,0 @@ -//! Sources for key-value pairs. - -#[cfg(feature = "kv_unstable_sval")] -extern crate sval; -#[cfg(feature = "kv_unstable_sval")] -extern crate sval_ref; - -#[cfg(feature = "kv_unstable_serde")] -extern crate serde; - -use kv::{Error, Key, ToKey, ToValue, Value}; -use std::fmt; - -/// A source of key-value pairs. -/// -/// The source may be a single pair, a set of pairs, or a filter over a set of pairs. -/// Use the [`Visitor`](trait.Visitor.html) trait to inspect the structured data -/// in a source. -pub trait Source { - /// Visit key-value pairs. - /// - /// A source doesn't have to guarantee any ordering or uniqueness of key-value pairs. - /// If the given visitor returns an error then the source may early-return with it, - /// even if there are more key-value pairs. - /// - /// # Implementation notes - /// - /// A source should yield the same key-value pairs to a subsequent visitor unless - /// that visitor itself fails. - fn visit<'kvs>(&'kvs self, visitor: &mut dyn Visitor<'kvs>) -> Result<(), Error>; - - /// Get the value for a given key. - /// - /// If the key appears multiple times in the source then which key is returned - /// is implementation specific. - /// - /// # Implementation notes - /// - /// A source that can provide a more efficient implementation of this method - /// should override it. - #[cfg(not(test))] - fn get<'v>(&'v self, key: Key) -> Option> { - get_default(self, key) - } - - #[cfg(test)] - fn get<'v>(&'v self, key: Key) -> Option>; - - /// Count the number of key-value pairs that can be visited. - /// - /// # Implementation notes - /// - /// A source that knows the number of key-value pairs upfront may provide a more - /// efficient implementation. - /// - /// A subsequent call to `visit` should yield the same number of key-value pairs - /// to the visitor, unless that visitor fails part way through. - #[cfg(not(test))] - fn count(&self) -> usize { - count_default(self) - } - - #[cfg(test)] - fn count(&self) -> usize; -} - -/// The default implemention of `Source::get` -pub(crate) fn get_default<'v>(source: &'v (impl Source + ?Sized), key: Key) -> Option> { - struct Get<'k, 'v> { - key: Key<'k>, - found: Option>, - } - - impl<'k, 'kvs> Visitor<'kvs> for Get<'k, 'kvs> { - fn visit_pair(&mut self, key: Key<'kvs>, value: Value<'kvs>) -> Result<(), Error> { - if self.key == key { - self.found = Some(value); - } - - Ok(()) - } - } - - let mut get = Get { key, found: None }; - - let _ = source.visit(&mut get); - get.found -} - -/// The default implementation of `Source::count`. -pub(crate) fn count_default(source: impl Source) -> usize { - struct Count(usize); - - impl<'kvs> Visitor<'kvs> for Count { - fn visit_pair(&mut self, _: Key<'kvs>, _: Value<'kvs>) -> Result<(), Error> { - self.0 += 1; - - Ok(()) - } - } - - let mut count = Count(0); - let _ = source.visit(&mut count); - count.0 -} - -impl<'a, T> Source for &'a T -where - T: Source + ?Sized, -{ - fn visit<'kvs>(&'kvs self, visitor: &mut dyn Visitor<'kvs>) -> Result<(), Error> { - Source::visit(&**self, visitor) - } - - fn get<'v>(&'v self, key: Key) -> Option> { - Source::get(&**self, key) - } - - fn count(&self) -> usize { - Source::count(&**self) - } -} - -impl Source for (K, V) -where - K: ToKey, - V: ToValue, -{ - fn visit<'kvs>(&'kvs self, visitor: &mut dyn Visitor<'kvs>) -> Result<(), Error> { - visitor.visit_pair(self.0.to_key(), self.1.to_value()) - } - - fn get<'v>(&'v self, key: Key) -> Option> { - if self.0.to_key() == key { - Some(self.1.to_value()) - } else { - None - } - } - - fn count(&self) -> usize { - 1 - } -} - -impl Source for [S] -where - S: Source, -{ - fn visit<'kvs>(&'kvs self, visitor: &mut dyn Visitor<'kvs>) -> Result<(), Error> { - for source in self { - source.visit(visitor)?; - } - - Ok(()) - } - - fn get<'v>(&'v self, key: Key) -> Option> { - for source in self { - if let Some(found) = source.get(key.clone()) { - return Some(found); - } - } - - None - } - - fn count(&self) -> usize { - self.len() - } -} - -impl Source for Option -where - S: Source, -{ - fn visit<'kvs>(&'kvs self, visitor: &mut dyn Visitor<'kvs>) -> Result<(), Error> { - if let Some(ref source) = *self { - source.visit(visitor)?; - } - - Ok(()) - } - - fn get<'v>(&'v self, key: Key) -> Option> { - self.as_ref().and_then(|s| s.get(key)) - } - - fn count(&self) -> usize { - self.as_ref().map(Source::count).unwrap_or(0) - } -} - -/// A visitor for the key-value pairs in a [`Source`](trait.Source.html). -pub trait Visitor<'kvs> { - /// Visit a key-value pair. - fn visit_pair(&mut self, key: Key<'kvs>, value: Value<'kvs>) -> Result<(), Error>; -} - -impl<'a, 'kvs, T> Visitor<'kvs> for &'a mut T -where - T: Visitor<'kvs> + ?Sized, -{ - fn visit_pair(&mut self, key: Key<'kvs>, value: Value<'kvs>) -> Result<(), Error> { - (**self).visit_pair(key, value) - } -} - -impl<'a, 'b: 'a, 'kvs> Visitor<'kvs> for fmt::DebugMap<'a, 'b> { - fn visit_pair(&mut self, key: Key<'kvs>, value: Value<'kvs>) -> Result<(), Error> { - self.entry(&key, &value); - Ok(()) - } -} - -impl<'a, 'b: 'a, 'kvs> Visitor<'kvs> for fmt::DebugList<'a, 'b> { - fn visit_pair(&mut self, key: Key<'kvs>, value: Value<'kvs>) -> Result<(), Error> { - self.entry(&(key, value)); - Ok(()) - } -} - -impl<'a, 'b: 'a, 'kvs> Visitor<'kvs> for fmt::DebugSet<'a, 'b> { - fn visit_pair(&mut self, key: Key<'kvs>, value: Value<'kvs>) -> Result<(), Error> { - self.entry(&(key, value)); - Ok(()) - } -} - -impl<'a, 'b: 'a, 'kvs> Visitor<'kvs> for fmt::DebugTuple<'a, 'b> { - fn visit_pair(&mut self, key: Key<'kvs>, value: Value<'kvs>) -> Result<(), Error> { - self.field(&key); - self.field(&value); - Ok(()) - } -} - -#[cfg(feature = "std")] -mod std_support { - use super::*; - use std::borrow::Borrow; - use std::collections::{BTreeMap, HashMap}; - use std::hash::{BuildHasher, Hash}; - - impl Source for Box - where - S: Source + ?Sized, - { - fn visit<'kvs>(&'kvs self, visitor: &mut dyn Visitor<'kvs>) -> Result<(), Error> { - Source::visit(&**self, visitor) - } - - fn get<'v>(&'v self, key: Key) -> Option> { - Source::get(&**self, key) - } - - fn count(&self) -> usize { - Source::count(&**self) - } - } - - impl Source for Vec - where - S: Source, - { - fn visit<'kvs>(&'kvs self, visitor: &mut dyn Visitor<'kvs>) -> Result<(), Error> { - Source::visit(&**self, visitor) - } - - fn get<'v>(&'v self, key: Key) -> Option> { - Source::get(&**self, key) - } - - fn count(&self) -> usize { - Source::count(&**self) - } - } - - impl<'kvs, V> Visitor<'kvs> for Box - where - V: Visitor<'kvs> + ?Sized, - { - fn visit_pair(&mut self, key: Key<'kvs>, value: Value<'kvs>) -> Result<(), Error> { - (**self).visit_pair(key, value) - } - } - - impl Source for HashMap - where - K: ToKey + Borrow + Eq + Hash, - V: ToValue, - S: BuildHasher, - { - fn visit<'kvs>(&'kvs self, visitor: &mut dyn Visitor<'kvs>) -> Result<(), Error> { - for (key, value) in self { - visitor.visit_pair(key.to_key(), value.to_value())?; - } - Ok(()) - } - - fn get<'v>(&'v self, key: Key) -> Option> { - HashMap::get(self, key.as_str()).map(|v| v.to_value()) - } - - fn count(&self) -> usize { - self.len() - } - } - - impl Source for BTreeMap - where - K: ToKey + Borrow + Ord, - V: ToValue, - { - fn visit<'kvs>(&'kvs self, visitor: &mut dyn Visitor<'kvs>) -> Result<(), Error> { - for (key, value) in self { - visitor.visit_pair(key.to_key(), value.to_value())?; - } - Ok(()) - } - - fn get<'v>(&'v self, key: Key) -> Option> { - BTreeMap::get(self, key.as_str()).map(|v| v.to_value()) - } - - fn count(&self) -> usize { - self.len() - } - } - - #[cfg(test)] - mod tests { - use super::*; - use kv::value::tests::Token; - use std::collections::{BTreeMap, HashMap}; - - #[test] - fn count() { - assert_eq!(1, Source::count(&Box::new(("a", 1)))); - assert_eq!(2, Source::count(&vec![("a", 1), ("b", 2)])); - } - - #[test] - fn get() { - let source = vec![("a", 1), ("b", 2), ("a", 1)]; - assert_eq!( - Token::I64(1), - Source::get(&source, Key::from_str("a")).unwrap().to_token() - ); - - let source = Box::new(Option::None::<(&str, i32)>); - assert!(Source::get(&source, Key::from_str("a")).is_none()); - } - - #[test] - fn hash_map() { - let mut map = HashMap::new(); - map.insert("a", 1); - map.insert("b", 2); - - assert_eq!(2, Source::count(&map)); - assert_eq!( - Token::I64(1), - Source::get(&map, Key::from_str("a")).unwrap().to_token() - ); - } - - #[test] - fn btree_map() { - let mut map = BTreeMap::new(); - map.insert("a", 1); - map.insert("b", 2); - - assert_eq!(2, Source::count(&map)); - assert_eq!( - Token::I64(1), - Source::get(&map, Key::from_str("a")).unwrap().to_token() - ); - } - } -} - -/// The result of calling `Source::as_map`. -pub struct AsMap(S); - -/// Visit this source as a map. -pub fn as_map(source: S) -> AsMap -where - S: Source, -{ - AsMap(source) -} - -impl Source for AsMap -where - S: Source, -{ - fn visit<'kvs>(&'kvs self, visitor: &mut dyn Visitor<'kvs>) -> Result<(), Error> { - self.0.visit(visitor) - } - - fn get<'v>(&'v self, key: Key) -> Option> { - self.0.get(key) - } - - fn count(&self) -> usize { - self.0.count() - } -} - -impl fmt::Debug for AsMap -where - S: Source, -{ - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - let mut f = f.debug_map(); - self.0.visit(&mut f).map_err(|_| fmt::Error)?; - f.finish() - } -} - -/// The result of calling `Source::as_list` -pub struct AsList(S); - -/// Visit this source as a list. -pub fn as_list(source: S) -> AsList -where - S: Source, -{ - AsList(source) -} - -impl Source for AsList -where - S: Source, -{ - fn visit<'kvs>(&'kvs self, visitor: &mut dyn Visitor<'kvs>) -> Result<(), Error> { - self.0.visit(visitor) - } - - fn get<'v>(&'v self, key: Key) -> Option> { - self.0.get(key) - } - - fn count(&self) -> usize { - self.0.count() - } -} - -impl fmt::Debug for AsList -where - S: Source, -{ - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - let mut f = f.debug_list(); - self.0.visit(&mut f).map_err(|_| fmt::Error)?; - f.finish() - } -} - -#[cfg(feature = "kv_unstable_sval")] -mod sval_support { - use super::*; - - impl self::sval::Value for AsMap - where - S: Source, - { - fn stream<'sval, SV: self::sval::Stream<'sval> + ?Sized>( - &'sval self, - stream: &mut SV, - ) -> self::sval::Result { - struct StreamVisitor<'a, V: ?Sized>(&'a mut V); - - impl<'a, 'kvs, V: self::sval::Stream<'kvs> + ?Sized> Visitor<'kvs> for StreamVisitor<'a, V> { - fn visit_pair(&mut self, key: Key<'kvs>, value: Value<'kvs>) -> Result<(), Error> { - self.0 - .map_key_begin() - .map_err(|_| Error::msg("failed to stream map key"))?; - sval_ref::stream_ref(self.0, key) - .map_err(|_| Error::msg("failed to stream map key"))?; - self.0 - .map_key_end() - .map_err(|_| Error::msg("failed to stream map key"))?; - - self.0 - .map_value_begin() - .map_err(|_| Error::msg("failed to stream map value"))?; - sval_ref::stream_ref(self.0, value) - .map_err(|_| Error::msg("failed to stream map value"))?; - self.0 - .map_value_end() - .map_err(|_| Error::msg("failed to stream map value"))?; - - Ok(()) - } - } - - stream - .map_begin(Some(self.count())) - .map_err(|_| self::sval::Error::new())?; - - self.visit(&mut StreamVisitor(stream)) - .map_err(|_| self::sval::Error::new())?; - - stream.map_end().map_err(|_| self::sval::Error::new()) - } - } - - impl self::sval::Value for AsList - where - S: Source, - { - fn stream<'sval, SV: self::sval::Stream<'sval> + ?Sized>( - &'sval self, - stream: &mut SV, - ) -> self::sval::Result { - struct StreamVisitor<'a, V: ?Sized>(&'a mut V); - - impl<'a, 'kvs, V: self::sval::Stream<'kvs> + ?Sized> Visitor<'kvs> for StreamVisitor<'a, V> { - fn visit_pair(&mut self, key: Key<'kvs>, value: Value<'kvs>) -> Result<(), Error> { - self.0 - .seq_value_begin() - .map_err(|_| Error::msg("failed to stream seq value"))?; - self::sval_ref::stream_ref(self.0, (key, value)) - .map_err(|_| Error::msg("failed to stream seq value"))?; - self.0 - .seq_value_end() - .map_err(|_| Error::msg("failed to stream seq value"))?; - - Ok(()) - } - } - - stream - .seq_begin(Some(self.count())) - .map_err(|_| self::sval::Error::new())?; - - self.visit(&mut StreamVisitor(stream)) - .map_err(|_| self::sval::Error::new())?; - - stream.seq_end().map_err(|_| self::sval::Error::new()) - } - } - - #[cfg(test)] - mod tests { - extern crate sval_derive; - - use super::*; - - use self::sval_derive::Value; - - use crate::kv::source; - - #[test] - fn derive_stream() { - #[derive(Value)] - pub struct MyRecordAsMap<'a> { - msg: &'a str, - kvs: source::AsMap<&'a dyn Source>, - } - - #[derive(Value)] - pub struct MyRecordAsList<'a> { - msg: &'a str, - kvs: source::AsList<&'a dyn Source>, - } - } - } -} - -#[cfg(feature = "kv_unstable_serde")] -pub mod as_map { - //! `serde` adapters for serializing a `Source` as a map. - - use super::*; - - use self::serde::{Serialize, Serializer}; - - /// Serialize a `Source` as a map. - pub fn serialize(source: &T, serializer: S) -> Result - where - T: Source, - S: Serializer, - { - as_map(source).serialize(serializer) - } -} - -#[cfg(feature = "kv_unstable_serde")] -pub mod as_list { - //! `serde` adapters for serializing a `Source` as a list. - - use super::*; - - use self::serde::{Serialize, Serializer}; - - /// Serialize a `Source` as a list. - pub fn serialize(source: &T, serializer: S) -> Result - where - T: Source, - S: Serializer, - { - as_list(source).serialize(serializer) - } -} - -#[cfg(feature = "kv_unstable_serde")] -mod serde_support { - use super::*; - - use self::serde::ser::{Error as SerError, Serialize, SerializeMap, SerializeSeq, Serializer}; - - impl Serialize for AsMap - where - T: Source, - { - fn serialize(&self, serializer: S) -> Result - where - S: Serializer, - { - struct SerializerVisitor<'a, S>(&'a mut S); - - impl<'a, 'kvs, S> Visitor<'kvs> for SerializerVisitor<'a, S> - where - S: SerializeMap, - { - fn visit_pair(&mut self, key: Key<'kvs>, value: Value<'kvs>) -> Result<(), Error> { - self.0 - .serialize_entry(&key, &value) - .map_err(|_| Error::msg("failed to serialize map entry"))?; - Ok(()) - } - } - - let mut map = serializer.serialize_map(Some(self.count()))?; - - self.visit(&mut SerializerVisitor(&mut map)) - .map_err(|_| S::Error::custom("failed to visit key-values"))?; - - map.end() - } - } - - impl Serialize for AsList - where - T: Source, - { - fn serialize(&self, serializer: S) -> Result - where - S: Serializer, - { - struct SerializerVisitor<'a, S>(&'a mut S); - - impl<'a, 'kvs, S> Visitor<'kvs> for SerializerVisitor<'a, S> - where - S: SerializeSeq, - { - fn visit_pair(&mut self, key: Key<'kvs>, value: Value<'kvs>) -> Result<(), Error> { - self.0 - .serialize_element(&(key, value)) - .map_err(|_| Error::msg("failed to serialize seq entry"))?; - Ok(()) - } - } - - let mut seq = serializer.serialize_seq(Some(self.count()))?; - - self.visit(&mut SerializerVisitor(&mut seq)) - .map_err(|_| S::Error::custom("failed to visit seq"))?; - - seq.end() - } - } - - #[cfg(test)] - mod tests { - use super::*; - - use self::serde::Serialize; - - use crate::kv::source; - - #[test] - fn derive_serialize() { - #[derive(Serialize)] - pub struct MyRecordAsMap<'a> { - msg: &'a str, - #[serde(flatten)] - #[serde(with = "source::as_map")] - kvs: &'a dyn Source, - } - - #[derive(Serialize)] - pub struct MyRecordAsList<'a> { - msg: &'a str, - #[serde(flatten)] - #[serde(with = "source::as_list")] - kvs: &'a dyn Source, - } - } - } -} - -#[cfg(test)] -mod tests { - use super::*; - use kv::value::tests::Token; - - #[test] - fn source_is_object_safe() { - fn _check(_: &dyn Source) {} - } - - #[test] - fn visitor_is_object_safe() { - fn _check(_: &dyn Visitor) {} - } - - #[test] - fn count() { - struct OnePair { - key: &'static str, - value: i32, - } - - impl Source for OnePair { - fn visit<'kvs>(&'kvs self, visitor: &mut dyn Visitor<'kvs>) -> Result<(), Error> { - visitor.visit_pair(self.key.to_key(), self.value.to_value()) - } - - fn get<'v>(&'v self, key: Key) -> Option> { - get_default(self, key) - } - - fn count(&self) -> usize { - count_default(self) - } - } - - assert_eq!(1, Source::count(&("a", 1))); - assert_eq!(2, Source::count(&[("a", 1), ("b", 2)] as &[_])); - assert_eq!(0, Source::count(&Option::None::<(&str, i32)>)); - assert_eq!(1, Source::count(&OnePair { key: "a", value: 1 })); - } - - #[test] - fn get() { - let source = &[("a", 1), ("b", 2), ("a", 1)] as &[_]; - assert_eq!( - Token::I64(1), - Source::get(source, Key::from_str("a")).unwrap().to_token() - ); - assert_eq!( - Token::I64(2), - Source::get(source, Key::from_str("b")).unwrap().to_token() - ); - assert!(Source::get(&source, Key::from_str("c")).is_none()); - - let source = Option::None::<(&str, i32)>; - assert!(Source::get(&source, Key::from_str("a")).is_none()); - } - - #[test] - fn as_map() { - let _ = crate::kv::source::as_map(("a", 1)); - let _ = crate::kv::source::as_map(&("a", 1) as &dyn Source); - } - - #[test] - fn as_list() { - let _ = crate::kv::source::as_list(("a", 1)); - let _ = crate::kv::source::as_list(&("a", 1) as &dyn Source); - } -} diff --git a/third-party/vendor/log/src/kv/value.rs b/third-party/vendor/log/src/kv/value.rs deleted file mode 100644 index 9485d485..00000000 --- a/third-party/vendor/log/src/kv/value.rs +++ /dev/null @@ -1,1031 +0,0 @@ -//! Structured values. - -use std::fmt; - -extern crate value_bag; - -#[cfg(feature = "kv_unstable_sval")] -extern crate sval; -#[cfg(feature = "kv_unstable_sval")] -extern crate sval_ref; - -#[cfg(feature = "kv_unstable_serde")] -extern crate serde; - -use self::value_bag::ValueBag; - -pub use kv::Error; - -/// A type that can be converted into a [`Value`](struct.Value.html). -pub trait ToValue { - /// Perform the conversion. - fn to_value(&self) -> Value; -} - -impl<'a, T> ToValue for &'a T -where - T: ToValue + ?Sized, -{ - fn to_value(&self) -> Value { - (**self).to_value() - } -} - -impl<'v> ToValue for Value<'v> { - fn to_value(&self) -> Value { - Value { - inner: self.inner.clone(), - } - } -} - -/// Get a value from a type implementing `std::fmt::Debug`. -#[macro_export] -macro_rules! as_debug { - ($capture:expr) => { - $crate::kv::Value::from_debug(&$capture) - }; -} - -/// Get a value from a type implementing `std::fmt::Display`. -#[macro_export] -macro_rules! as_display { - ($capture:expr) => { - $crate::kv::Value::from_display(&$capture) - }; -} - -/// Get a value from an error. -#[cfg(feature = "kv_unstable_std")] -#[macro_export] -macro_rules! as_error { - ($capture:expr) => { - $crate::kv::Value::from_dyn_error(&$capture) - }; -} - -#[cfg(feature = "kv_unstable_serde")] -/// Get a value from a type implementing `serde::Serialize`. -#[macro_export] -macro_rules! as_serde { - ($capture:expr) => { - $crate::kv::Value::from_serde(&$capture) - }; -} - -/// Get a value from a type implementing `sval::Value`. -#[cfg(feature = "kv_unstable_sval")] -#[macro_export] -macro_rules! as_sval { - ($capture:expr) => { - $crate::kv::Value::from_sval(&$capture) - }; -} - -/// A value in a structured key-value pair. -/// -/// # Capturing values -/// -/// There are a few ways to capture a value: -/// -/// - Using the `Value::capture_*` methods. -/// - Using the `Value::from_*` methods. -/// - Using the `ToValue` trait. -/// - Using the standard `From` trait. -/// -/// ## Using the `Value::capture_*` methods -/// -/// `Value` offers a few constructor methods that capture values of different kinds. -/// These methods require a `T: 'static` to support downcasting. -/// -/// ``` -/// use log::kv::Value; -/// -/// let value = Value::capture_debug(&42i32); -/// -/// assert_eq!(Some(42), value.to_i64()); -/// ``` -/// -/// ## Using the `Value::from_*` methods -/// -/// `Value` offers a few constructor methods that capture values of different kinds. -/// These methods don't require `T: 'static`, but can't support downcasting. -/// -/// ``` -/// use log::kv::Value; -/// -/// let value = Value::from_debug(&42i32); -/// -/// assert_eq!(None, value.to_i64()); -/// ``` -/// -/// ## Using the `ToValue` trait -/// -/// The `ToValue` trait can be used to capture values generically. -/// It's the bound used by `Source`. -/// -/// ``` -/// # use log::kv::ToValue; -/// let value = 42i32.to_value(); -/// -/// assert_eq!(Some(42), value.to_i64()); -/// ``` -/// -/// ``` -/// # use std::fmt::Debug; -/// use log::kv::ToValue; -/// -/// let value = (&42i32 as &dyn Debug).to_value(); -/// -/// assert_eq!(None, value.to_i64()); -/// ``` -/// -/// ## Using the standard `From` trait -/// -/// Standard types that implement `ToValue` also implement `From`. -/// -/// ``` -/// use log::kv::Value; -/// -/// let value = Value::from(42i32); -/// -/// assert_eq!(Some(42), value.to_i64()); -/// ``` -pub struct Value<'v> { - inner: ValueBag<'v>, -} - -impl<'v> Value<'v> { - /// Get a value from a type implementing `ToValue`. - pub fn from_any(value: &'v T) -> Self - where - T: ToValue, - { - value.to_value() - } - - /// Get a value from a type implementing `std::fmt::Debug`. - pub fn capture_debug(value: &'v T) -> Self - where - T: fmt::Debug + 'static, - { - Value { - inner: ValueBag::capture_debug(value), - } - } - - /// Get a value from a type implementing `std::fmt::Display`. - pub fn capture_display(value: &'v T) -> Self - where - T: fmt::Display + 'static, - { - Value { - inner: ValueBag::capture_display(value), - } - } - - /// Get a value from an error. - #[cfg(feature = "kv_unstable_std")] - pub fn capture_error(err: &'v T) -> Self - where - T: std::error::Error + 'static, - { - Value { - inner: ValueBag::capture_error(err), - } - } - - #[cfg(feature = "kv_unstable_serde")] - /// Get a value from a type implementing `serde::Serialize`. - pub fn capture_serde(value: &'v T) -> Self - where - T: self::serde::Serialize + 'static, - { - Value { - inner: ValueBag::capture_serde1(value), - } - } - - /// Get a value from a type implementing `sval::Value`. - #[cfg(feature = "kv_unstable_sval")] - pub fn capture_sval(value: &'v T) -> Self - where - T: self::sval::Value + 'static, - { - Value { - inner: ValueBag::capture_sval2(value), - } - } - - /// Get a value from a type implementing `std::fmt::Debug`. - pub fn from_debug(value: &'v T) -> Self - where - T: fmt::Debug, - { - Value { - inner: ValueBag::from_debug(value), - } - } - - /// Get a value from a type implementing `std::fmt::Display`. - pub fn from_display(value: &'v T) -> Self - where - T: fmt::Display, - { - Value { - inner: ValueBag::from_display(value), - } - } - - /// Get a value from a type implementing `serde::Serialize`. - #[cfg(feature = "kv_unstable_serde")] - pub fn from_serde(value: &'v T) -> Self - where - T: self::serde::Serialize, - { - Value { - inner: ValueBag::from_serde1(value), - } - } - - /// Get a value from a type implementing `sval::Value`. - #[cfg(feature = "kv_unstable_sval")] - pub fn from_sval(value: &'v T) -> Self - where - T: self::sval::Value, - { - Value { - inner: ValueBag::from_sval2(value), - } - } - - /// Get a value from a dynamic `std::fmt::Debug`. - pub fn from_dyn_debug(value: &'v dyn fmt::Debug) -> Self { - Value { - inner: ValueBag::from_dyn_debug(value), - } - } - - /// Get a value from a dynamic `std::fmt::Display`. - pub fn from_dyn_display(value: &'v dyn fmt::Display) -> Self { - Value { - inner: ValueBag::from_dyn_display(value), - } - } - - /// Get a value from a dynamic error. - #[cfg(feature = "kv_unstable_std")] - pub fn from_dyn_error(err: &'v (dyn std::error::Error + 'static)) -> Self { - Value { - inner: ValueBag::from_dyn_error(err), - } - } - - /// Get a value from an internal primitive. - fn from_value_bag(value: T) -> Self - where - T: Into>, - { - Value { - inner: value.into(), - } - } - - /// Check whether this value can be downcast to `T`. - pub fn is(&self) -> bool { - self.inner.is::() - } - - /// Try downcast this value to `T`. - pub fn downcast_ref(&self) -> Option<&T> { - self.inner.downcast_ref::() - } - - /// Inspect this value using a simple visitor. - pub fn visit(&self, visitor: impl Visit<'v>) -> Result<(), Error> { - struct Visitor(V); - - impl<'v, V> value_bag::visit::Visit<'v> for Visitor - where - V: Visit<'v>, - { - fn visit_any(&mut self, value: ValueBag) -> Result<(), value_bag::Error> { - self.0 - .visit_any(Value { inner: value }) - .map_err(Error::into_value) - } - - fn visit_u64(&mut self, value: u64) -> Result<(), value_bag::Error> { - self.0.visit_u64(value).map_err(Error::into_value) - } - - fn visit_i64(&mut self, value: i64) -> Result<(), value_bag::Error> { - self.0.visit_i64(value).map_err(Error::into_value) - } - - fn visit_u128(&mut self, value: u128) -> Result<(), value_bag::Error> { - self.0.visit_u128(value).map_err(Error::into_value) - } - - fn visit_i128(&mut self, value: i128) -> Result<(), value_bag::Error> { - self.0.visit_i128(value).map_err(Error::into_value) - } - - fn visit_f64(&mut self, value: f64) -> Result<(), value_bag::Error> { - self.0.visit_f64(value).map_err(Error::into_value) - } - - fn visit_bool(&mut self, value: bool) -> Result<(), value_bag::Error> { - self.0.visit_bool(value).map_err(Error::into_value) - } - - fn visit_str(&mut self, value: &str) -> Result<(), value_bag::Error> { - self.0.visit_str(value).map_err(Error::into_value) - } - - fn visit_borrowed_str(&mut self, value: &'v str) -> Result<(), value_bag::Error> { - self.0.visit_borrowed_str(value).map_err(Error::into_value) - } - - fn visit_char(&mut self, value: char) -> Result<(), value_bag::Error> { - self.0.visit_char(value).map_err(Error::into_value) - } - - #[cfg(feature = "kv_unstable_std")] - fn visit_error( - &mut self, - err: &(dyn std::error::Error + 'static), - ) -> Result<(), value_bag::Error> { - self.0.visit_error(err).map_err(Error::into_value) - } - - #[cfg(feature = "kv_unstable_std")] - fn visit_borrowed_error( - &mut self, - err: &'v (dyn std::error::Error + 'static), - ) -> Result<(), value_bag::Error> { - self.0.visit_borrowed_error(err).map_err(Error::into_value) - } - } - - self.inner - .visit(&mut Visitor(visitor)) - .map_err(Error::from_value) - } -} - -impl<'v> fmt::Debug for Value<'v> { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - fmt::Debug::fmt(&self.inner, f) - } -} - -impl<'v> fmt::Display for Value<'v> { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - fmt::Display::fmt(&self.inner, f) - } -} - -impl ToValue for dyn fmt::Debug { - fn to_value(&self) -> Value { - Value::from_dyn_debug(self) - } -} - -impl ToValue for dyn fmt::Display { - fn to_value(&self) -> Value { - Value::from_dyn_display(self) - } -} - -#[cfg(feature = "kv_unstable_std")] -impl ToValue for dyn std::error::Error + 'static { - fn to_value(&self) -> Value { - Value::from_dyn_error(self) - } -} - -#[cfg(feature = "kv_unstable_serde")] -impl<'v> self::serde::Serialize for Value<'v> { - fn serialize(&self, s: S) -> Result - where - S: self::serde::Serializer, - { - self.inner.serialize(s) - } -} - -#[cfg(feature = "kv_unstable_sval")] -impl<'v> self::sval::Value for Value<'v> { - fn stream<'sval, S: self::sval::Stream<'sval> + ?Sized>( - &'sval self, - stream: &mut S, - ) -> self::sval::Result { - self::sval::Value::stream(&self.inner, stream) - } -} - -#[cfg(feature = "kv_unstable_sval")] -impl<'v> self::sval_ref::ValueRef<'v> for Value<'v> { - fn stream_ref + ?Sized>(&self, stream: &mut S) -> self::sval::Result { - self::sval_ref::ValueRef::stream_ref(&self.inner, stream) - } -} - -impl ToValue for str { - fn to_value(&self) -> Value { - Value::from(self) - } -} - -impl ToValue for u128 { - fn to_value(&self) -> Value { - Value::from(self) - } -} - -impl ToValue for i128 { - fn to_value(&self) -> Value { - Value::from(self) - } -} - -impl ToValue for std::num::NonZeroU128 { - fn to_value(&self) -> Value { - Value::from(self) - } -} - -impl ToValue for std::num::NonZeroI128 { - fn to_value(&self) -> Value { - Value::from(self) - } -} - -impl<'v> From<&'v str> for Value<'v> { - fn from(value: &'v str) -> Self { - Value::from_value_bag(value) - } -} - -impl<'v> From<&'v u128> for Value<'v> { - fn from(value: &'v u128) -> Self { - Value::from_value_bag(value) - } -} - -impl<'v> From<&'v i128> for Value<'v> { - fn from(value: &'v i128) -> Self { - Value::from_value_bag(value) - } -} - -impl<'v> From<&'v std::num::NonZeroU128> for Value<'v> { - fn from(v: &'v std::num::NonZeroU128) -> Value<'v> { - // SAFETY: `NonZeroU128` and `u128` have the same ABI - Value::from_value_bag(unsafe { std::mem::transmute::<&std::num::NonZeroU128, &u128>(v) }) - } -} - -impl<'v> From<&'v std::num::NonZeroI128> for Value<'v> { - fn from(v: &'v std::num::NonZeroI128) -> Value<'v> { - // SAFETY: `NonZeroI128` and `i128` have the same ABI - Value::from_value_bag(unsafe { std::mem::transmute::<&std::num::NonZeroI128, &i128>(v) }) - } -} - -impl ToValue for () { - fn to_value(&self) -> Value { - Value::from_value_bag(()) - } -} - -impl ToValue for Option -where - T: ToValue, -{ - fn to_value(&self) -> Value { - match *self { - Some(ref value) => value.to_value(), - None => Value::from_value_bag(()), - } - } -} - -macro_rules! impl_to_value_primitive { - ($($into_ty:ty,)*) => { - $( - impl ToValue for $into_ty { - fn to_value(&self) -> Value { - Value::from(*self) - } - } - - impl<'v> From<$into_ty> for Value<'v> { - fn from(value: $into_ty) -> Self { - Value::from_value_bag(value) - } - } - )* - }; -} - -macro_rules! impl_to_value_nonzero_primitive { - ($($into_ty:ident,)*) => { - $( - impl ToValue for std::num::$into_ty { - fn to_value(&self) -> Value { - Value::from(self.get()) - } - } - - impl<'v> From for Value<'v> { - fn from(value: std::num::$into_ty) -> Self { - Value::from(value.get()) - } - } - )* - }; -} - -macro_rules! impl_value_to_primitive { - ($(#[doc = $doc:tt] $into_name:ident -> $into_ty:ty,)*) => { - impl<'v> Value<'v> { - $( - #[doc = $doc] - pub fn $into_name(&self) -> Option<$into_ty> { - self.inner.$into_name() - } - )* - } - } -} - -impl_to_value_primitive![usize, u8, u16, u32, u64, isize, i8, i16, i32, i64, f32, f64, char, bool,]; - -#[rustfmt::skip] -impl_to_value_nonzero_primitive![ - NonZeroUsize, NonZeroU8, NonZeroU16, NonZeroU32, NonZeroU64, - NonZeroIsize, NonZeroI8, NonZeroI16, NonZeroI32, NonZeroI64, -]; - -impl_value_to_primitive![ - #[doc = "Try convert this value into a `u64`."] - to_u64 -> u64, - #[doc = "Try convert this value into a `i64`."] - to_i64 -> i64, - #[doc = "Try convert this value into a `u128`."] - to_u128 -> u128, - #[doc = "Try convert this value into a `i128`."] - to_i128 -> i128, - #[doc = "Try convert this value into a `f64`."] - to_f64 -> f64, - #[doc = "Try convert this value into a `char`."] - to_char -> char, - #[doc = "Try convert this value into a `bool`."] - to_bool -> bool, -]; - -impl<'v> Value<'v> { - /// Try convert this value into an error. - #[cfg(feature = "kv_unstable_std")] - pub fn to_borrowed_error(&self) -> Option<&(dyn std::error::Error + 'static)> { - self.inner.to_borrowed_error() - } - - /// Try convert this value into a borrowed string. - pub fn to_borrowed_str(&self) -> Option<&str> { - self.inner.to_borrowed_str() - } -} - -#[cfg(feature = "kv_unstable_std")] -mod std_support { - use super::*; - - use std::borrow::Cow; - - impl ToValue for Box - where - T: ToValue + ?Sized, - { - fn to_value(&self) -> Value { - (**self).to_value() - } - } - - impl ToValue for String { - fn to_value(&self) -> Value { - Value::from(&**self) - } - } - - impl<'v> ToValue for Cow<'v, str> { - fn to_value(&self) -> Value { - Value::from(&**self) - } - } - - impl<'v> Value<'v> { - /// Try convert this value into a string. - pub fn to_str(&self) -> Option> { - self.inner.to_str() - } - } - - impl<'v> From<&'v String> for Value<'v> { - fn from(v: &'v String) -> Self { - Value::from(&**v) - } - } -} - -/// A visitor for a `Value`. -pub trait Visit<'v> { - /// Visit a `Value`. - /// - /// This is the only required method on `Visit` and acts as a fallback for any - /// more specific methods that aren't overridden. - /// The `Value` may be formatted using its `fmt::Debug` or `fmt::Display` implementation, - /// or serialized using its `sval::Value` or `serde::Serialize` implementation. - fn visit_any(&mut self, value: Value) -> Result<(), Error>; - - /// Visit an unsigned integer. - fn visit_u64(&mut self, value: u64) -> Result<(), Error> { - self.visit_any(value.into()) - } - - /// Visit a signed integer. - fn visit_i64(&mut self, value: i64) -> Result<(), Error> { - self.visit_any(value.into()) - } - - /// Visit a big unsigned integer. - fn visit_u128(&mut self, value: u128) -> Result<(), Error> { - self.visit_any((&value).into()) - } - - /// Visit a big signed integer. - fn visit_i128(&mut self, value: i128) -> Result<(), Error> { - self.visit_any((&value).into()) - } - - /// Visit a floating point. - fn visit_f64(&mut self, value: f64) -> Result<(), Error> { - self.visit_any(value.into()) - } - - /// Visit a boolean. - fn visit_bool(&mut self, value: bool) -> Result<(), Error> { - self.visit_any(value.into()) - } - - /// Visit a string. - fn visit_str(&mut self, value: &str) -> Result<(), Error> { - self.visit_any(value.into()) - } - - /// Visit a string. - fn visit_borrowed_str(&mut self, value: &'v str) -> Result<(), Error> { - self.visit_str(value) - } - - /// Visit a Unicode character. - fn visit_char(&mut self, value: char) -> Result<(), Error> { - let mut b = [0; 4]; - self.visit_str(&*value.encode_utf8(&mut b)) - } - - /// Visit an error. - #[cfg(feature = "kv_unstable_std")] - fn visit_error(&mut self, err: &(dyn std::error::Error + 'static)) -> Result<(), Error> { - self.visit_any(Value::from_dyn_error(err)) - } - - /// Visit an error. - #[cfg(feature = "kv_unstable_std")] - fn visit_borrowed_error( - &mut self, - err: &'v (dyn std::error::Error + 'static), - ) -> Result<(), Error> { - self.visit_any(Value::from_dyn_error(err)) - } -} - -impl<'a, 'v, T: ?Sized> Visit<'v> for &'a mut T -where - T: Visit<'v>, -{ - fn visit_any(&mut self, value: Value) -> Result<(), Error> { - (**self).visit_any(value) - } - - fn visit_u64(&mut self, value: u64) -> Result<(), Error> { - (**self).visit_u64(value) - } - - fn visit_i64(&mut self, value: i64) -> Result<(), Error> { - (**self).visit_i64(value) - } - - fn visit_u128(&mut self, value: u128) -> Result<(), Error> { - (**self).visit_u128(value) - } - - fn visit_i128(&mut self, value: i128) -> Result<(), Error> { - (**self).visit_i128(value) - } - - fn visit_f64(&mut self, value: f64) -> Result<(), Error> { - (**self).visit_f64(value) - } - - fn visit_bool(&mut self, value: bool) -> Result<(), Error> { - (**self).visit_bool(value) - } - - fn visit_str(&mut self, value: &str) -> Result<(), Error> { - (**self).visit_str(value) - } - - fn visit_borrowed_str(&mut self, value: &'v str) -> Result<(), Error> { - (**self).visit_borrowed_str(value) - } - - fn visit_char(&mut self, value: char) -> Result<(), Error> { - (**self).visit_char(value) - } - - #[cfg(feature = "kv_unstable_std")] - fn visit_error(&mut self, err: &(dyn std::error::Error + 'static)) -> Result<(), Error> { - (**self).visit_error(err) - } - - #[cfg(feature = "kv_unstable_std")] - fn visit_borrowed_error( - &mut self, - err: &'v (dyn std::error::Error + 'static), - ) -> Result<(), Error> { - (**self).visit_borrowed_error(err) - } -} - -#[cfg(test)] -pub(crate) mod tests { - use super::*; - - pub(crate) use super::value_bag::test::TestToken as Token; - - impl<'v> Value<'v> { - pub(crate) fn to_token(&self) -> Token { - self.inner.to_test_token() - } - } - - fn unsigned() -> impl Iterator> { - vec![ - Value::from(8u8), - Value::from(16u16), - Value::from(32u32), - Value::from(64u64), - Value::from(1usize), - Value::from(std::num::NonZeroU8::new(8).unwrap()), - Value::from(std::num::NonZeroU16::new(16).unwrap()), - Value::from(std::num::NonZeroU32::new(32).unwrap()), - Value::from(std::num::NonZeroU64::new(64).unwrap()), - Value::from(std::num::NonZeroUsize::new(1).unwrap()), - ] - .into_iter() - } - - fn signed() -> impl Iterator> { - vec![ - Value::from(-8i8), - Value::from(-16i16), - Value::from(-32i32), - Value::from(-64i64), - Value::from(-1isize), - Value::from(std::num::NonZeroI8::new(-8).unwrap()), - Value::from(std::num::NonZeroI16::new(-16).unwrap()), - Value::from(std::num::NonZeroI32::new(-32).unwrap()), - Value::from(std::num::NonZeroI64::new(-64).unwrap()), - Value::from(std::num::NonZeroIsize::new(-1).unwrap()), - ] - .into_iter() - } - - fn float() -> impl Iterator> { - vec![Value::from(32.32f32), Value::from(64.64f64)].into_iter() - } - - fn bool() -> impl Iterator> { - vec![Value::from(true), Value::from(false)].into_iter() - } - - fn str() -> impl Iterator> { - vec![Value::from("a string"), Value::from("a loong string")].into_iter() - } - - fn char() -> impl Iterator> { - vec![Value::from('a'), Value::from('⛰')].into_iter() - } - - #[test] - fn test_capture_fmt() { - assert_eq!(Some(42u64), Value::capture_display(&42).to_u64()); - assert_eq!(Some(42u64), Value::capture_debug(&42).to_u64()); - - assert!(Value::from_display(&42).to_u64().is_none()); - assert!(Value::from_debug(&42).to_u64().is_none()); - } - - #[cfg(feature = "kv_unstable_std")] - #[test] - fn test_capture_error() { - let err = std::io::Error::from(std::io::ErrorKind::Other); - - assert!(Value::capture_error(&err).to_borrowed_error().is_some()); - assert!(Value::from_dyn_error(&err).to_borrowed_error().is_some()); - } - - #[cfg(feature = "kv_unstable_serde")] - #[test] - fn test_capture_serde() { - assert_eq!(Some(42u64), Value::capture_serde(&42).to_u64()); - - assert_eq!(Some(42u64), Value::from_serde(&42).to_u64()); - } - - #[cfg(feature = "kv_unstable_sval")] - #[test] - fn test_capture_sval() { - assert_eq!(Some(42u64), Value::capture_sval(&42).to_u64()); - - assert_eq!(Some(42u64), Value::from_sval(&42).to_u64()); - } - - #[test] - fn test_to_value_display() { - assert_eq!(42u64.to_value().to_string(), "42"); - assert_eq!(42i64.to_value().to_string(), "42"); - assert_eq!(42.01f64.to_value().to_string(), "42.01"); - assert_eq!(true.to_value().to_string(), "true"); - assert_eq!('a'.to_value().to_string(), "a"); - assert_eq!("a loong string".to_value().to_string(), "a loong string"); - assert_eq!(Some(true).to_value().to_string(), "true"); - assert_eq!(().to_value().to_string(), "None"); - assert_eq!(Option::None::.to_value().to_string(), "None"); - } - - #[test] - fn test_to_value_structured() { - assert_eq!(42u64.to_value().to_token(), Token::U64(42)); - assert_eq!(42i64.to_value().to_token(), Token::I64(42)); - assert_eq!(42.01f64.to_value().to_token(), Token::F64(42.01)); - assert_eq!(true.to_value().to_token(), Token::Bool(true)); - assert_eq!('a'.to_value().to_token(), Token::Char('a')); - assert_eq!( - "a loong string".to_value().to_token(), - Token::Str("a loong string".into()) - ); - assert_eq!(Some(true).to_value().to_token(), Token::Bool(true)); - assert_eq!(().to_value().to_token(), Token::None); - assert_eq!(Option::None::.to_value().to_token(), Token::None); - } - - #[test] - fn test_to_number() { - for v in unsigned() { - assert!(v.to_u64().is_some()); - assert!(v.to_i64().is_some()); - } - - for v in signed() { - assert!(v.to_i64().is_some()); - } - - for v in unsigned().chain(signed()).chain(float()) { - assert!(v.to_f64().is_some()); - } - - for v in bool().chain(str()).chain(char()) { - assert!(v.to_u64().is_none()); - assert!(v.to_i64().is_none()); - assert!(v.to_f64().is_none()); - } - } - - #[test] - fn test_to_str() { - for v in str() { - assert!(v.to_borrowed_str().is_some()); - - #[cfg(feature = "kv_unstable_std")] - assert!(v.to_str().is_some()); - } - - let short_lived = String::from("short lived"); - let v = Value::from(&*short_lived); - - assert!(v.to_borrowed_str().is_some()); - - #[cfg(feature = "kv_unstable_std")] - assert!(v.to_str().is_some()); - - for v in unsigned().chain(signed()).chain(float()).chain(bool()) { - assert!(v.to_borrowed_str().is_none()); - - #[cfg(feature = "kv_unstable_std")] - assert!(v.to_str().is_none()); - } - } - - #[test] - fn test_to_bool() { - for v in bool() { - assert!(v.to_bool().is_some()); - } - - for v in unsigned() - .chain(signed()) - .chain(float()) - .chain(str()) - .chain(char()) - { - assert!(v.to_bool().is_none()); - } - } - - #[test] - fn test_to_char() { - for v in char() { - assert!(v.to_char().is_some()); - } - - for v in unsigned() - .chain(signed()) - .chain(float()) - .chain(str()) - .chain(bool()) - { - assert!(v.to_char().is_none()); - } - } - - #[test] - fn test_downcast_ref() { - #[derive(Debug)] - struct Foo(u64); - - let v = Value::capture_debug(&Foo(42)); - - assert!(v.is::()); - assert_eq!(42u64, v.downcast_ref::().expect("invalid downcast").0); - } - - #[test] - fn test_visit_integer() { - struct Extract(Option); - - impl<'v> Visit<'v> for Extract { - fn visit_any(&mut self, value: Value) -> Result<(), Error> { - unimplemented!("unexpected value: {:?}", value) - } - - fn visit_u64(&mut self, value: u64) -> Result<(), Error> { - self.0 = Some(value); - - Ok(()) - } - } - - let mut extract = Extract(None); - Value::from(42u64).visit(&mut extract).unwrap(); - - assert_eq!(Some(42), extract.0); - } - - #[test] - fn test_visit_borrowed_str() { - struct Extract<'v>(Option<&'v str>); - - impl<'v> Visit<'v> for Extract<'v> { - fn visit_any(&mut self, value: Value) -> Result<(), Error> { - unimplemented!("unexpected value: {:?}", value) - } - - fn visit_borrowed_str(&mut self, value: &'v str) -> Result<(), Error> { - self.0 = Some(value); - - Ok(()) - } - } - - let mut extract = Extract(None); - - let short_lived = String::from("A short-lived string"); - Value::from(&*short_lived).visit(&mut extract).unwrap(); - - assert_eq!(Some("A short-lived string"), extract.0); - } -} diff --git a/third-party/vendor/log/src/lib.rs b/third-party/vendor/log/src/lib.rs deleted file mode 100644 index ab5cdfa4..00000000 --- a/third-party/vendor/log/src/lib.rs +++ /dev/null @@ -1,1827 +0,0 @@ -// Copyright 2015 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 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -//! A lightweight logging facade. -//! -//! The `log` crate provides a single logging API that abstracts over the -//! actual logging implementation. Libraries can use the logging API provided -//! by this crate, and the consumer of those libraries can choose the logging -//! implementation that is most suitable for its use case. -//! -//! If no logging implementation is selected, the facade falls back to a "noop" -//! implementation that ignores all log messages. The overhead in this case -//! is very small - just an integer load, comparison and jump. -//! -//! A log request consists of a _target_, a _level_, and a _body_. A target is a -//! string which defaults to the module path of the location of the log request, -//! though that default may be overridden. Logger implementations typically use -//! the target to filter requests based on some user configuration. -//! -//! # Usage -//! -//! The basic use of the log crate is through the five logging macros: [`error!`], -//! [`warn!`], [`info!`], [`debug!`] and [`trace!`] -//! where `error!` represents the highest-priority log messages -//! and `trace!` the lowest. The log messages are filtered by configuring -//! the log level to exclude messages with a lower priority. -//! Each of these macros accept format strings similarly to [`println!`]. -//! -//! -//! [`error!`]: ./macro.error.html -//! [`warn!`]: ./macro.warn.html -//! [`info!`]: ./macro.info.html -//! [`debug!`]: ./macro.debug.html -//! [`trace!`]: ./macro.trace.html -//! [`println!`]: https://doc.rust-lang.org/stable/std/macro.println.html -//! -//! ## In libraries -//! -//! Libraries should link only to the `log` crate, and use the provided -//! macros to log whatever information will be useful to downstream consumers. -//! -//! ### Examples -//! -//! ```edition2018 -//! # #[derive(Debug)] pub struct Yak(String); -//! # impl Yak { fn shave(&mut self, _: u32) {} } -//! # fn find_a_razor() -> Result { Ok(1) } -//! use log::{info, warn}; -//! -//! pub fn shave_the_yak(yak: &mut Yak) { -//! info!(target: "yak_events", "Commencing yak shaving for {:?}", yak); -//! -//! loop { -//! match find_a_razor() { -//! Ok(razor) => { -//! info!("Razor located: {}", razor); -//! yak.shave(razor); -//! break; -//! } -//! Err(err) => { -//! warn!("Unable to locate a razor: {}, retrying", err); -//! } -//! } -//! } -//! } -//! # fn main() {} -//! ``` -//! -//! ## In executables -//! -//! Executables should choose a logging implementation and initialize it early in the -//! runtime of the program. Logging implementations will typically include a -//! function to do this. Any log messages generated before -//! the implementation is initialized will be ignored. -//! -//! The executable itself may use the `log` crate to log as well. -//! -//! ### Warning -//! -//! The logging system may only be initialized once. -//! -//! ## Structured logging -//! -//! If you enable the `kv_unstable` feature you can associate structured values -//! with your log records. If we take the example from before, we can include -//! some additional context besides what's in the formatted message: -//! -//! ```edition2018 -//! # #[macro_use] extern crate serde; -//! # #[derive(Debug, Serialize)] pub struct Yak(String); -//! # impl Yak { fn shave(&mut self, _: u32) {} } -//! # fn find_a_razor() -> Result { Ok(1) } -//! # #[cfg(feature = "kv_unstable_serde")] -//! # fn main() { -//! use log::{info, warn, as_serde, as_error}; -//! -//! pub fn shave_the_yak(yak: &mut Yak) { -//! info!(target: "yak_events", yak = as_serde!(yak); "Commencing yak shaving"); -//! -//! loop { -//! match find_a_razor() { -//! Ok(razor) => { -//! info!(razor = razor; "Razor located"); -//! yak.shave(razor); -//! break; -//! } -//! Err(err) => { -//! warn!(err = as_error!(err); "Unable to locate a razor, retrying"); -//! } -//! } -//! } -//! } -//! # } -//! # #[cfg(not(feature = "kv_unstable_serde"))] -//! # fn main() {} -//! ``` -//! -//! # Available logging implementations -//! -//! In order to produce log output executables have to use -//! a logger implementation compatible with the facade. -//! There are many available implementations to choose from, -//! here are some of the most popular ones: -//! -//! * Simple minimal loggers: -//! * [env_logger] -//! * [simple_logger] -//! * [simplelog] -//! * [pretty_env_logger] -//! * [stderrlog] -//! * [flexi_logger] -//! * [call_logger] -//! * [structured-logger] -//! * Complex configurable frameworks: -//! * [log4rs] -//! * [fern] -//! * Adaptors for other facilities: -//! * [syslog] -//! * [slog-stdlog] -//! * [systemd-journal-logger] -//! * [android_log] -//! * [win_dbg_logger] -//! * [db_logger] -//! * [log-to-defmt] -//! * For WebAssembly binaries: -//! * [console_log] -//! * For dynamic libraries: -//! * You may need to construct an FFI-safe wrapper over `log` to initialize in your libraries -//! -//! # Implementing a Logger -//! -//! Loggers implement the [`Log`] trait. Here's a very basic example that simply -//! logs all messages at the [`Error`][level_link], [`Warn`][level_link] or -//! [`Info`][level_link] levels to stdout: -//! -//! ```edition2018 -//! use log::{Record, Level, Metadata}; -//! -//! struct SimpleLogger; -//! -//! impl log::Log for SimpleLogger { -//! fn enabled(&self, metadata: &Metadata) -> bool { -//! metadata.level() <= Level::Info -//! } -//! -//! fn log(&self, record: &Record) { -//! if self.enabled(record.metadata()) { -//! println!("{} - {}", record.level(), record.args()); -//! } -//! } -//! -//! fn flush(&self) {} -//! } -//! -//! # fn main() {} -//! ``` -//! -//! Loggers are installed by calling the [`set_logger`] function. The maximum -//! log level also needs to be adjusted via the [`set_max_level`] function. The -//! logging facade uses this as an optimization to improve performance of log -//! messages at levels that are disabled. It's important to set it, as it -//! defaults to [`Off`][filter_link], so no log messages will ever be captured! -//! In the case of our example logger, we'll want to set the maximum log level -//! to [`Info`][filter_link], since we ignore any [`Debug`][level_link] or -//! [`Trace`][level_link] level log messages. A logging implementation should -//! provide a function that wraps a call to [`set_logger`] and -//! [`set_max_level`], handling initialization of the logger: -//! -//! ```edition2018 -//! # use log::{Level, Metadata}; -//! # struct SimpleLogger; -//! # impl log::Log for SimpleLogger { -//! # fn enabled(&self, _: &Metadata) -> bool { false } -//! # fn log(&self, _: &log::Record) {} -//! # fn flush(&self) {} -//! # } -//! # fn main() {} -//! use log::{SetLoggerError, LevelFilter}; -//! -//! static LOGGER: SimpleLogger = SimpleLogger; -//! -//! pub fn init() -> Result<(), SetLoggerError> { -//! log::set_logger(&LOGGER) -//! .map(|()| log::set_max_level(LevelFilter::Info)) -//! } -//! ``` -//! -//! Implementations that adjust their configurations at runtime should take care -//! to adjust the maximum log level as well. -//! -//! # Use with `std` -//! -//! `set_logger` requires you to provide a `&'static Log`, which can be hard to -//! obtain if your logger depends on some runtime configuration. The -//! `set_boxed_logger` function is available with the `std` Cargo feature. It is -//! identical to `set_logger` except that it takes a `Box` rather than a -//! `&'static Log`: -//! -//! ```edition2018 -//! # use log::{Level, LevelFilter, Log, SetLoggerError, Metadata}; -//! # struct SimpleLogger; -//! # impl log::Log for SimpleLogger { -//! # fn enabled(&self, _: &Metadata) -> bool { false } -//! # fn log(&self, _: &log::Record) {} -//! # fn flush(&self) {} -//! # } -//! # fn main() {} -//! # #[cfg(feature = "std")] -//! pub fn init() -> Result<(), SetLoggerError> { -//! log::set_boxed_logger(Box::new(SimpleLogger)) -//! .map(|()| log::set_max_level(LevelFilter::Info)) -//! } -//! ``` -//! -//! # Compile time filters -//! -//! Log levels can be statically disabled at compile time via Cargo features. Log invocations at -//! disabled levels will be skipped and will not even be present in the resulting binary. -//! This level is configured separately for release and debug builds. The features are: -//! -//! * `max_level_off` -//! * `max_level_error` -//! * `max_level_warn` -//! * `max_level_info` -//! * `max_level_debug` -//! * `max_level_trace` -//! * `release_max_level_off` -//! * `release_max_level_error` -//! * `release_max_level_warn` -//! * `release_max_level_info` -//! * `release_max_level_debug` -//! * `release_max_level_trace` -//! -//! These features control the value of the `STATIC_MAX_LEVEL` constant. The logging macros check -//! this value before logging a message. By default, no levels are disabled. -//! -//! Libraries should avoid using the max level features because they're global and can't be changed -//! once they're set. -//! -//! For example, a crate can disable trace level logs in debug builds and trace, debug, and info -//! level logs in release builds with the following configuration: -//! -//! ```toml -//! [dependencies] -//! log = { version = "0.4", features = ["max_level_debug", "release_max_level_warn"] } -//! ``` -//! # Crate Feature Flags -//! -//! The following crate feature flags are available in addition to the filters. They are -//! configured in your `Cargo.toml`. -//! -//! * `std` allows use of `std` crate instead of the default `core`. Enables using `std::error` and -//! `set_boxed_logger` functionality. -//! * `serde` enables support for serialization and deserialization of `Level` and `LevelFilter`. -//! -//! ```toml -//! [dependencies] -//! log = { version = "0.4", features = ["std", "serde"] } -//! ``` -//! -//! # Version compatibility -//! -//! The 0.3 and 0.4 versions of the `log` crate are almost entirely compatible. Log messages -//! made using `log` 0.3 will forward transparently to a logger implementation using `log` 0.4. Log -//! messages made using `log` 0.4 will forward to a logger implementation using `log` 0.3, but the -//! module path and file name information associated with the message will unfortunately be lost. -//! -//! [`Log`]: trait.Log.html -//! [level_link]: enum.Level.html -//! [filter_link]: enum.LevelFilter.html -//! [`set_logger`]: fn.set_logger.html -//! [`set_max_level`]: fn.set_max_level.html -//! [`try_set_logger_raw`]: fn.try_set_logger_raw.html -//! [`shutdown_logger_raw`]: fn.shutdown_logger_raw.html -//! [env_logger]: https://docs.rs/env_logger/*/env_logger/ -//! [simple_logger]: https://github.com/borntyping/rust-simple_logger -//! [simplelog]: https://github.com/drakulix/simplelog.rs -//! [pretty_env_logger]: https://docs.rs/pretty_env_logger/*/pretty_env_logger/ -//! [stderrlog]: https://docs.rs/stderrlog/*/stderrlog/ -//! [flexi_logger]: https://docs.rs/flexi_logger/*/flexi_logger/ -//! [call_logger]: https://docs.rs/call_logger/*/call_logger/ -//! [syslog]: https://docs.rs/syslog/*/syslog/ -//! [slog-stdlog]: https://docs.rs/slog-stdlog/*/slog_stdlog/ -//! [log4rs]: https://docs.rs/log4rs/*/log4rs/ -//! [fern]: https://docs.rs/fern/*/fern/ -//! [systemd-journal-logger]: https://docs.rs/systemd-journal-logger/*/systemd_journal_logger/ -//! [android_log]: https://docs.rs/android_log/*/android_log/ -//! [win_dbg_logger]: https://docs.rs/win_dbg_logger/*/win_dbg_logger/ -//! [db_logger]: https://docs.rs/db_logger/*/db_logger/ -//! [log-to-defmt]: https://docs.rs/log-to-defmt/*/log_to_defmt/ -//! [console_log]: https://docs.rs/console_log/*/console_log/ -//! [structured-logger]: https://docs.rs/structured-logger/latest/structured_logger/ - -#![doc( - html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png", - html_favicon_url = "https://www.rust-lang.org/favicon.ico", - html_root_url = "https://docs.rs/log/0.4.20" -)] -#![warn(missing_docs)] -#![deny(missing_debug_implementations, unconditional_recursion)] -#![cfg_attr(all(not(feature = "std"), not(test)), no_std)] -// When compiled for the rustc compiler itself we want to make sure that this is -// an unstable crate -#![cfg_attr(rustbuild, feature(staged_api, rustc_private))] -#![cfg_attr(rustbuild, unstable(feature = "rustc_private", issue = "27812"))] - -#[cfg(all(not(feature = "std"), not(test)))] -extern crate core as std; - -use std::cmp; -#[cfg(feature = "std")] -use std::error; -use std::fmt; -use std::mem; -use std::str::FromStr; - -#[macro_use] -mod macros; -mod serde; - -#[cfg(feature = "kv_unstable")] -pub mod kv; - -#[cfg(target_has_atomic = "ptr")] -use std::sync::atomic::{AtomicUsize, Ordering}; - -#[cfg(not(target_has_atomic = "ptr"))] -use std::cell::Cell; -#[cfg(not(target_has_atomic = "ptr"))] -use std::sync::atomic::Ordering; - -#[cfg(not(target_has_atomic = "ptr"))] -struct AtomicUsize { - v: Cell, -} - -#[cfg(not(target_has_atomic = "ptr"))] -impl AtomicUsize { - const fn new(v: usize) -> AtomicUsize { - AtomicUsize { v: Cell::new(v) } - } - - fn load(&self, _order: Ordering) -> usize { - self.v.get() - } - - fn store(&self, val: usize, _order: Ordering) { - self.v.set(val) - } - - #[cfg(target_has_atomic = "ptr")] - fn compare_exchange( - &self, - current: usize, - new: usize, - _success: Ordering, - _failure: Ordering, - ) -> Result { - let prev = self.v.get(); - if current == prev { - self.v.set(new); - } - Ok(prev) - } -} - -// Any platform without atomics is unlikely to have multiple cores, so -// writing via Cell will not be a race condition. -#[cfg(not(target_has_atomic = "ptr"))] -unsafe impl Sync for AtomicUsize {} - -// The LOGGER static holds a pointer to the global logger. It is protected by -// the STATE static which determines whether LOGGER has been initialized yet. -static mut LOGGER: &dyn Log = &NopLogger; - -static STATE: AtomicUsize = AtomicUsize::new(0); - -// There are three different states that we care about: the logger's -// uninitialized, the logger's initializing (set_logger's been called but -// LOGGER hasn't actually been set yet), or the logger's active. -const UNINITIALIZED: usize = 0; -const INITIALIZING: usize = 1; -const INITIALIZED: usize = 2; - -static MAX_LOG_LEVEL_FILTER: AtomicUsize = AtomicUsize::new(0); - -static LOG_LEVEL_NAMES: [&str; 6] = ["OFF", "ERROR", "WARN", "INFO", "DEBUG", "TRACE"]; - -static SET_LOGGER_ERROR: &str = "attempted to set a logger after the logging system \ - was already initialized"; -static LEVEL_PARSE_ERROR: &str = - "attempted to convert a string that doesn't match an existing log level"; - -/// An enum representing the available verbosity levels of the logger. -/// -/// Typical usage includes: checking if a certain `Level` is enabled with -/// [`log_enabled!`](macro.log_enabled.html), specifying the `Level` of -/// [`log!`](macro.log.html), and comparing a `Level` directly to a -/// [`LevelFilter`](enum.LevelFilter.html). -#[repr(usize)] -#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Debug, Hash)] -pub enum Level { - /// The "error" level. - /// - /// Designates very serious errors. - // This way these line up with the discriminants for LevelFilter below - // This works because Rust treats field-less enums the same way as C does: - // https://doc.rust-lang.org/reference/items/enumerations.html#custom-discriminant-values-for-field-less-enumerations - Error = 1, - /// The "warn" level. - /// - /// Designates hazardous situations. - Warn, - /// The "info" level. - /// - /// Designates useful information. - Info, - /// The "debug" level. - /// - /// Designates lower priority information. - Debug, - /// The "trace" level. - /// - /// Designates very low priority, often extremely verbose, information. - Trace, -} - -impl PartialEq for Level { - #[inline] - fn eq(&self, other: &LevelFilter) -> bool { - *self as usize == *other as usize - } -} - -impl PartialOrd for Level { - #[inline] - fn partial_cmp(&self, other: &LevelFilter) -> Option { - Some((*self as usize).cmp(&(*other as usize))) - } -} - -fn ok_or(t: Option, e: E) -> Result { - match t { - Some(t) => Ok(t), - None => Err(e), - } -} - -impl FromStr for Level { - type Err = ParseLevelError; - fn from_str(level: &str) -> Result { - ok_or( - LOG_LEVEL_NAMES - .iter() - .position(|&name| name.eq_ignore_ascii_case(level)) - .into_iter() - .filter(|&idx| idx != 0) - .map(|idx| Level::from_usize(idx).unwrap()) - .next(), - ParseLevelError(()), - ) - } -} - -impl fmt::Display for Level { - fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { - fmt.pad(self.as_str()) - } -} - -impl Level { - fn from_usize(u: usize) -> Option { - match u { - 1 => Some(Level::Error), - 2 => Some(Level::Warn), - 3 => Some(Level::Info), - 4 => Some(Level::Debug), - 5 => Some(Level::Trace), - _ => None, - } - } - - /// Returns the most verbose logging level. - #[inline] - pub fn max() -> Level { - Level::Trace - } - - /// Converts the `Level` to the equivalent `LevelFilter`. - #[inline] - pub fn to_level_filter(&self) -> LevelFilter { - LevelFilter::from_usize(*self as usize).unwrap() - } - - /// Returns the string representation of the `Level`. - /// - /// This returns the same string as the `fmt::Display` implementation. - pub fn as_str(&self) -> &'static str { - LOG_LEVEL_NAMES[*self as usize] - } - - /// Iterate through all supported logging levels. - /// - /// The order of iteration is from more severe to less severe log messages. - /// - /// # Examples - /// - /// ``` - /// use log::Level; - /// - /// let mut levels = Level::iter(); - /// - /// assert_eq!(Some(Level::Error), levels.next()); - /// assert_eq!(Some(Level::Trace), levels.last()); - /// ``` - pub fn iter() -> impl Iterator { - (1..6).map(|i| Self::from_usize(i).unwrap()) - } -} - -/// An enum representing the available verbosity level filters of the logger. -/// -/// A `LevelFilter` may be compared directly to a [`Level`]. Use this type -/// to get and set the maximum log level with [`max_level()`] and [`set_max_level`]. -/// -/// [`Level`]: enum.Level.html -/// [`max_level()`]: fn.max_level.html -/// [`set_max_level`]: fn.set_max_level.html -#[repr(usize)] -#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Debug, Hash)] -pub enum LevelFilter { - /// A level lower than all log levels. - Off, - /// Corresponds to the `Error` log level. - Error, - /// Corresponds to the `Warn` log level. - Warn, - /// Corresponds to the `Info` log level. - Info, - /// Corresponds to the `Debug` log level. - Debug, - /// Corresponds to the `Trace` log level. - Trace, -} - -impl PartialEq for LevelFilter { - #[inline] - fn eq(&self, other: &Level) -> bool { - other.eq(self) - } -} - -impl PartialOrd for LevelFilter { - #[inline] - fn partial_cmp(&self, other: &Level) -> Option { - Some((*self as usize).cmp(&(*other as usize))) - } -} - -impl FromStr for LevelFilter { - type Err = ParseLevelError; - fn from_str(level: &str) -> Result { - ok_or( - LOG_LEVEL_NAMES - .iter() - .position(|&name| name.eq_ignore_ascii_case(level)) - .map(|p| LevelFilter::from_usize(p).unwrap()), - ParseLevelError(()), - ) - } -} - -impl fmt::Display for LevelFilter { - fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { - fmt.pad(self.as_str()) - } -} - -impl LevelFilter { - fn from_usize(u: usize) -> Option { - match u { - 0 => Some(LevelFilter::Off), - 1 => Some(LevelFilter::Error), - 2 => Some(LevelFilter::Warn), - 3 => Some(LevelFilter::Info), - 4 => Some(LevelFilter::Debug), - 5 => Some(LevelFilter::Trace), - _ => None, - } - } - - /// Returns the most verbose logging level filter. - #[inline] - pub fn max() -> LevelFilter { - LevelFilter::Trace - } - - /// Converts `self` to the equivalent `Level`. - /// - /// Returns `None` if `self` is `LevelFilter::Off`. - #[inline] - pub fn to_level(&self) -> Option { - Level::from_usize(*self as usize) - } - - /// Returns the string representation of the `LevelFilter`. - /// - /// This returns the same string as the `fmt::Display` implementation. - pub fn as_str(&self) -> &'static str { - LOG_LEVEL_NAMES[*self as usize] - } - - /// Iterate through all supported filtering levels. - /// - /// The order of iteration is from less to more verbose filtering. - /// - /// # Examples - /// - /// ``` - /// use log::LevelFilter; - /// - /// let mut levels = LevelFilter::iter(); - /// - /// assert_eq!(Some(LevelFilter::Off), levels.next()); - /// assert_eq!(Some(LevelFilter::Trace), levels.last()); - /// ``` - pub fn iter() -> impl Iterator { - (0..6).map(|i| Self::from_usize(i).unwrap()) - } -} - -#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug)] -enum MaybeStaticStr<'a> { - Static(&'static str), - Borrowed(&'a str), -} - -impl<'a> MaybeStaticStr<'a> { - #[inline] - fn get(&self) -> &'a str { - match *self { - MaybeStaticStr::Static(s) => s, - MaybeStaticStr::Borrowed(s) => s, - } - } -} - -/// The "payload" of a log message. -/// -/// # Use -/// -/// `Record` structures are passed as parameters to the [`log`][method.log] -/// method of the [`Log`] trait. Logger implementors manipulate these -/// structures in order to display log messages. `Record`s are automatically -/// created by the [`log!`] macro and so are not seen by log users. -/// -/// Note that the [`level()`] and [`target()`] accessors are equivalent to -/// `self.metadata().level()` and `self.metadata().target()` respectively. -/// These methods are provided as a convenience for users of this structure. -/// -/// # Example -/// -/// The following example shows a simple logger that displays the level, -/// module path, and message of any `Record` that is passed to it. -/// -/// ```edition2018 -/// struct SimpleLogger; -/// -/// impl log::Log for SimpleLogger { -/// fn enabled(&self, _metadata: &log::Metadata) -> bool { -/// true -/// } -/// -/// fn log(&self, record: &log::Record) { -/// if !self.enabled(record.metadata()) { -/// return; -/// } -/// -/// println!("{}:{} -- {}", -/// record.level(), -/// record.target(), -/// record.args()); -/// } -/// fn flush(&self) {} -/// } -/// ``` -/// -/// [method.log]: trait.Log.html#tymethod.log -/// [`Log`]: trait.Log.html -/// [`log!`]: macro.log.html -/// [`level()`]: struct.Record.html#method.level -/// [`target()`]: struct.Record.html#method.target -#[derive(Clone, Debug)] -pub struct Record<'a> { - metadata: Metadata<'a>, - args: fmt::Arguments<'a>, - module_path: Option>, - file: Option>, - line: Option, - #[cfg(feature = "kv_unstable")] - key_values: KeyValues<'a>, -} - -// This wrapper type is only needed so we can -// `#[derive(Debug)]` on `Record`. It also -// provides a useful `Debug` implementation for -// the underlying `Source`. -#[cfg(feature = "kv_unstable")] -#[derive(Clone)] -struct KeyValues<'a>(&'a dyn kv::Source); - -#[cfg(feature = "kv_unstable")] -impl<'a> fmt::Debug for KeyValues<'a> { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - let mut visitor = f.debug_map(); - self.0.visit(&mut visitor).map_err(|_| fmt::Error)?; - visitor.finish() - } -} - -impl<'a> Record<'a> { - /// Returns a new builder. - #[inline] - pub fn builder() -> RecordBuilder<'a> { - RecordBuilder::new() - } - - /// The message body. - #[inline] - pub fn args(&self) -> &fmt::Arguments<'a> { - &self.args - } - - /// Metadata about the log directive. - #[inline] - pub fn metadata(&self) -> &Metadata<'a> { - &self.metadata - } - - /// The verbosity level of the message. - #[inline] - pub fn level(&self) -> Level { - self.metadata.level() - } - - /// The name of the target of the directive. - #[inline] - pub fn target(&self) -> &'a str { - self.metadata.target() - } - - /// The module path of the message. - #[inline] - pub fn module_path(&self) -> Option<&'a str> { - self.module_path.map(|s| s.get()) - } - - /// The module path of the message, if it is a `'static` string. - #[inline] - pub fn module_path_static(&self) -> Option<&'static str> { - match self.module_path { - Some(MaybeStaticStr::Static(s)) => Some(s), - _ => None, - } - } - - /// The source file containing the message. - #[inline] - pub fn file(&self) -> Option<&'a str> { - self.file.map(|s| s.get()) - } - - /// The module path of the message, if it is a `'static` string. - #[inline] - pub fn file_static(&self) -> Option<&'static str> { - match self.file { - Some(MaybeStaticStr::Static(s)) => Some(s), - _ => None, - } - } - - /// The line containing the message. - #[inline] - pub fn line(&self) -> Option { - self.line - } - - /// The structured key-value pairs associated with the message. - #[cfg(feature = "kv_unstable")] - #[inline] - pub fn key_values(&self) -> &dyn kv::Source { - self.key_values.0 - } - - /// Create a new [`RecordBuilder`](struct.RecordBuilder.html) based on this record. - #[cfg(feature = "kv_unstable")] - #[inline] - pub fn to_builder(&self) -> RecordBuilder { - RecordBuilder { - record: Record { - metadata: Metadata { - level: self.metadata.level, - target: self.metadata.target, - }, - args: self.args, - module_path: self.module_path, - file: self.file, - line: self.line, - key_values: self.key_values.clone(), - }, - } - } -} - -/// Builder for [`Record`](struct.Record.html). -/// -/// Typically should only be used by log library creators or for testing and "shim loggers". -/// The `RecordBuilder` can set the different parameters of `Record` object, and returns -/// the created object when `build` is called. -/// -/// # Examples -/// -/// ```edition2018 -/// use log::{Level, Record}; -/// -/// let record = Record::builder() -/// .args(format_args!("Error!")) -/// .level(Level::Error) -/// .target("myApp") -/// .file(Some("server.rs")) -/// .line(Some(144)) -/// .module_path(Some("server")) -/// .build(); -/// ``` -/// -/// Alternatively, use [`MetadataBuilder`](struct.MetadataBuilder.html): -/// -/// ```edition2018 -/// use log::{Record, Level, MetadataBuilder}; -/// -/// let error_metadata = MetadataBuilder::new() -/// .target("myApp") -/// .level(Level::Error) -/// .build(); -/// -/// let record = Record::builder() -/// .metadata(error_metadata) -/// .args(format_args!("Error!")) -/// .line(Some(433)) -/// .file(Some("app.rs")) -/// .module_path(Some("server")) -/// .build(); -/// ``` -#[derive(Debug)] -pub struct RecordBuilder<'a> { - record: Record<'a>, -} - -impl<'a> RecordBuilder<'a> { - /// Construct new `RecordBuilder`. - /// - /// The default options are: - /// - /// - `args`: [`format_args!("")`] - /// - `metadata`: [`Metadata::builder().build()`] - /// - `module_path`: `None` - /// - `file`: `None` - /// - `line`: `None` - /// - /// [`format_args!("")`]: https://doc.rust-lang.org/std/macro.format_args.html - /// [`Metadata::builder().build()`]: struct.MetadataBuilder.html#method.build - #[inline] - pub fn new() -> RecordBuilder<'a> { - RecordBuilder { - record: Record { - args: format_args!(""), - metadata: Metadata::builder().build(), - module_path: None, - file: None, - line: None, - #[cfg(feature = "kv_unstable")] - key_values: KeyValues(&Option::None::<(kv::Key, kv::Value)>), - }, - } - } - - /// Set [`args`](struct.Record.html#method.args). - #[inline] - pub fn args(&mut self, args: fmt::Arguments<'a>) -> &mut RecordBuilder<'a> { - self.record.args = args; - self - } - - /// Set [`metadata`](struct.Record.html#method.metadata). Construct a `Metadata` object with [`MetadataBuilder`](struct.MetadataBuilder.html). - #[inline] - pub fn metadata(&mut self, metadata: Metadata<'a>) -> &mut RecordBuilder<'a> { - self.record.metadata = metadata; - self - } - - /// Set [`Metadata::level`](struct.Metadata.html#method.level). - #[inline] - pub fn level(&mut self, level: Level) -> &mut RecordBuilder<'a> { - self.record.metadata.level = level; - self - } - - /// Set [`Metadata::target`](struct.Metadata.html#method.target) - #[inline] - pub fn target(&mut self, target: &'a str) -> &mut RecordBuilder<'a> { - self.record.metadata.target = target; - self - } - - /// Set [`module_path`](struct.Record.html#method.module_path) - #[inline] - pub fn module_path(&mut self, path: Option<&'a str>) -> &mut RecordBuilder<'a> { - self.record.module_path = path.map(MaybeStaticStr::Borrowed); - self - } - - /// Set [`module_path`](struct.Record.html#method.module_path) to a `'static` string - #[inline] - pub fn module_path_static(&mut self, path: Option<&'static str>) -> &mut RecordBuilder<'a> { - self.record.module_path = path.map(MaybeStaticStr::Static); - self - } - - /// Set [`file`](struct.Record.html#method.file) - #[inline] - pub fn file(&mut self, file: Option<&'a str>) -> &mut RecordBuilder<'a> { - self.record.file = file.map(MaybeStaticStr::Borrowed); - self - } - - /// Set [`file`](struct.Record.html#method.file) to a `'static` string. - #[inline] - pub fn file_static(&mut self, file: Option<&'static str>) -> &mut RecordBuilder<'a> { - self.record.file = file.map(MaybeStaticStr::Static); - self - } - - /// Set [`line`](struct.Record.html#method.line) - #[inline] - pub fn line(&mut self, line: Option) -> &mut RecordBuilder<'a> { - self.record.line = line; - self - } - - /// Set [`key_values`](struct.Record.html#method.key_values) - #[cfg(feature = "kv_unstable")] - #[inline] - pub fn key_values(&mut self, kvs: &'a dyn kv::Source) -> &mut RecordBuilder<'a> { - self.record.key_values = KeyValues(kvs); - self - } - - /// Invoke the builder and return a `Record` - #[inline] - pub fn build(&self) -> Record<'a> { - self.record.clone() - } -} - -impl<'a> Default for RecordBuilder<'a> { - fn default() -> Self { - Self::new() - } -} - -/// Metadata about a log message. -/// -/// # Use -/// -/// `Metadata` structs are created when users of the library use -/// logging macros. -/// -/// They are consumed by implementations of the `Log` trait in the -/// `enabled` method. -/// -/// `Record`s use `Metadata` to determine the log message's severity -/// and target. -/// -/// Users should use the `log_enabled!` macro in their code to avoid -/// constructing expensive log messages. -/// -/// # Examples -/// -/// ```edition2018 -/// use log::{Record, Level, Metadata}; -/// -/// struct MyLogger; -/// -/// impl log::Log for MyLogger { -/// fn enabled(&self, metadata: &Metadata) -> bool { -/// metadata.level() <= Level::Info -/// } -/// -/// fn log(&self, record: &Record) { -/// if self.enabled(record.metadata()) { -/// println!("{} - {}", record.level(), record.args()); -/// } -/// } -/// fn flush(&self) {} -/// } -/// -/// # fn main(){} -/// ``` -#[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug)] -pub struct Metadata<'a> { - level: Level, - target: &'a str, -} - -impl<'a> Metadata<'a> { - /// Returns a new builder. - #[inline] - pub fn builder() -> MetadataBuilder<'a> { - MetadataBuilder::new() - } - - /// The verbosity level of the message. - #[inline] - pub fn level(&self) -> Level { - self.level - } - - /// The name of the target of the directive. - #[inline] - pub fn target(&self) -> &'a str { - self.target - } -} - -/// Builder for [`Metadata`](struct.Metadata.html). -/// -/// Typically should only be used by log library creators or for testing and "shim loggers". -/// The `MetadataBuilder` can set the different parameters of a `Metadata` object, and returns -/// the created object when `build` is called. -/// -/// # Example -/// -/// ```edition2018 -/// let target = "myApp"; -/// use log::{Level, MetadataBuilder}; -/// let metadata = MetadataBuilder::new() -/// .level(Level::Debug) -/// .target(target) -/// .build(); -/// ``` -#[derive(Eq, PartialEq, Ord, PartialOrd, Hash, Debug)] -pub struct MetadataBuilder<'a> { - metadata: Metadata<'a>, -} - -impl<'a> MetadataBuilder<'a> { - /// Construct a new `MetadataBuilder`. - /// - /// The default options are: - /// - /// - `level`: `Level::Info` - /// - `target`: `""` - #[inline] - pub fn new() -> MetadataBuilder<'a> { - MetadataBuilder { - metadata: Metadata { - level: Level::Info, - target: "", - }, - } - } - - /// Setter for [`level`](struct.Metadata.html#method.level). - #[inline] - pub fn level(&mut self, arg: Level) -> &mut MetadataBuilder<'a> { - self.metadata.level = arg; - self - } - - /// Setter for [`target`](struct.Metadata.html#method.target). - #[inline] - pub fn target(&mut self, target: &'a str) -> &mut MetadataBuilder<'a> { - self.metadata.target = target; - self - } - - /// Returns a `Metadata` object. - #[inline] - pub fn build(&self) -> Metadata<'a> { - self.metadata.clone() - } -} - -impl<'a> Default for MetadataBuilder<'a> { - fn default() -> Self { - Self::new() - } -} - -/// A trait encapsulating the operations required of a logger. -pub trait Log: Sync + Send { - /// Determines if a log message with the specified metadata would be - /// logged. - /// - /// This is used by the `log_enabled!` macro to allow callers to avoid - /// expensive computation of log message arguments if the message would be - /// discarded anyway. - /// - /// # For implementors - /// - /// This method isn't called automatically by the `log!` macros. - /// It's up to an implementation of the `Log` trait to call `enabled` in its own - /// `log` method implementation to guarantee that filtering is applied. - fn enabled(&self, metadata: &Metadata) -> bool; - - /// Logs the `Record`. - /// - /// # For implementors - /// - /// Note that `enabled` is *not* necessarily called before this method. - /// Implementations of `log` should perform all necessary filtering - /// internally. - fn log(&self, record: &Record); - - /// Flushes any buffered records. - fn flush(&self); -} - -// Just used as a dummy initial value for LOGGER -struct NopLogger; - -impl Log for NopLogger { - fn enabled(&self, _: &Metadata) -> bool { - false - } - - fn log(&self, _: &Record) {} - fn flush(&self) {} -} - -impl Log for &'_ T -where - T: ?Sized + Log, -{ - fn enabled(&self, metadata: &Metadata) -> bool { - (**self).enabled(metadata) - } - - fn log(&self, record: &Record) { - (**self).log(record); - } - fn flush(&self) { - (**self).flush(); - } -} - -#[cfg(feature = "std")] -impl Log for std::boxed::Box -where - T: ?Sized + Log, -{ - fn enabled(&self, metadata: &Metadata) -> bool { - self.as_ref().enabled(metadata) - } - - fn log(&self, record: &Record) { - self.as_ref().log(record) - } - fn flush(&self) { - self.as_ref().flush() - } -} - -#[cfg(feature = "std")] -impl Log for std::sync::Arc -where - T: ?Sized + Log, -{ - fn enabled(&self, metadata: &Metadata) -> bool { - self.as_ref().enabled(metadata) - } - - fn log(&self, record: &Record) { - self.as_ref().log(record) - } - fn flush(&self) { - self.as_ref().flush() - } -} - -/// Sets the global maximum log level. -/// -/// Generally, this should only be called by the active logging implementation. -/// -/// Note that `Trace` is the maximum level, because it provides the maximum amount of detail in the emitted logs. -#[inline] -#[cfg(target_has_atomic = "ptr")] -pub fn set_max_level(level: LevelFilter) { - MAX_LOG_LEVEL_FILTER.store(level as usize, Ordering::Relaxed); -} - -/// A thread-unsafe version of [`set_max_level`]. -/// -/// This function is available on all platforms, even those that do not have -/// support for atomics that is needed by [`set_max_level`]. -/// -/// In almost all cases, [`set_max_level`] should be preferred. -/// -/// # Safety -/// -/// This function is only safe to call when no other level setting function is -/// called while this function still executes. -/// -/// This can be upheld by (for example) making sure that **there are no other -/// threads**, and (on embedded) that **interrupts are disabled**. -/// -/// Is is safe to use all other logging functions while this function runs -/// (including all logging macros). -/// -/// [`set_max_level`]: fn.set_max_level.html -#[inline] -pub unsafe fn set_max_level_racy(level: LevelFilter) { - // `MAX_LOG_LEVEL_FILTER` uses a `Cell` as the underlying primitive when a - // platform doesn't support `target_has_atomic = "ptr"`, so even though this looks the same - // as `set_max_level` it may have different safety properties. - MAX_LOG_LEVEL_FILTER.store(level as usize, Ordering::Relaxed); -} - -/// Returns the current maximum log level. -/// -/// The [`log!`], [`error!`], [`warn!`], [`info!`], [`debug!`], and [`trace!`] macros check -/// this value and discard any message logged at a higher level. The maximum -/// log level is set by the [`set_max_level`] function. -/// -/// [`log!`]: macro.log.html -/// [`error!`]: macro.error.html -/// [`warn!`]: macro.warn.html -/// [`info!`]: macro.info.html -/// [`debug!`]: macro.debug.html -/// [`trace!`]: macro.trace.html -/// [`set_max_level`]: fn.set_max_level.html -#[inline(always)] -pub fn max_level() -> LevelFilter { - // Since `LevelFilter` is `repr(usize)`, - // this transmute is sound if and only if `MAX_LOG_LEVEL_FILTER` - // is set to a usize that is a valid discriminant for `LevelFilter`. - // Since `MAX_LOG_LEVEL_FILTER` is private, the only time it's set - // is by `set_max_level` above, i.e. by casting a `LevelFilter` to `usize`. - // So any usize stored in `MAX_LOG_LEVEL_FILTER` is a valid discriminant. - unsafe { mem::transmute(MAX_LOG_LEVEL_FILTER.load(Ordering::Relaxed)) } -} - -/// Sets the global logger to a `Box`. -/// -/// This is a simple convenience wrapper over `set_logger`, which takes a -/// `Box` rather than a `&'static Log`. See the documentation for -/// [`set_logger`] for more details. -/// -/// Requires the `std` feature. -/// -/// # Errors -/// -/// An error is returned if a logger has already been set. -/// -/// [`set_logger`]: fn.set_logger.html -#[cfg(all(feature = "std", target_has_atomic = "ptr"))] -pub fn set_boxed_logger(logger: Box) -> Result<(), SetLoggerError> { - set_logger_inner(|| Box::leak(logger)) -} - -/// Sets the global logger to a `&'static Log`. -/// -/// This function may only be called once in the lifetime of a program. Any log -/// events that occur before the call to `set_logger` completes will be ignored. -/// -/// This function does not typically need to be called manually. Logger -/// implementations should provide an initialization method that installs the -/// logger internally. -/// -/// # Availability -/// -/// This method is available even when the `std` feature is disabled. However, -/// it is currently unavailable on `thumbv6` targets, which lack support for -/// some atomic operations which are used by this function. Even on those -/// targets, [`set_logger_racy`] will be available. -/// -/// # Errors -/// -/// An error is returned if a logger has already been set. -/// -/// # Examples -/// -/// ```edition2018 -/// use log::{error, info, warn, Record, Level, Metadata, LevelFilter}; -/// -/// static MY_LOGGER: MyLogger = MyLogger; -/// -/// struct MyLogger; -/// -/// impl log::Log for MyLogger { -/// fn enabled(&self, metadata: &Metadata) -> bool { -/// metadata.level() <= Level::Info -/// } -/// -/// fn log(&self, record: &Record) { -/// if self.enabled(record.metadata()) { -/// println!("{} - {}", record.level(), record.args()); -/// } -/// } -/// fn flush(&self) {} -/// } -/// -/// # fn main(){ -/// log::set_logger(&MY_LOGGER).unwrap(); -/// log::set_max_level(LevelFilter::Info); -/// -/// info!("hello log"); -/// warn!("warning"); -/// error!("oops"); -/// # } -/// ``` -/// -/// [`set_logger_racy`]: fn.set_logger_racy.html -#[cfg(target_has_atomic = "ptr")] -pub fn set_logger(logger: &'static dyn Log) -> Result<(), SetLoggerError> { - set_logger_inner(|| logger) -} - -#[cfg(target_has_atomic = "ptr")] -fn set_logger_inner(make_logger: F) -> Result<(), SetLoggerError> -where - F: FnOnce() -> &'static dyn Log, -{ - let old_state = match STATE.compare_exchange( - UNINITIALIZED, - INITIALIZING, - Ordering::SeqCst, - Ordering::SeqCst, - ) { - Ok(s) | Err(s) => s, - }; - match old_state { - UNINITIALIZED => { - unsafe { - LOGGER = make_logger(); - } - STATE.store(INITIALIZED, Ordering::SeqCst); - Ok(()) - } - INITIALIZING => { - while STATE.load(Ordering::SeqCst) == INITIALIZING { - // TODO: replace with `hint::spin_loop` once MSRV is 1.49.0. - #[allow(deprecated)] - std::sync::atomic::spin_loop_hint(); - } - Err(SetLoggerError(())) - } - _ => Err(SetLoggerError(())), - } -} - -/// A thread-unsafe version of [`set_logger`]. -/// -/// This function is available on all platforms, even those that do not have -/// support for atomics that is needed by [`set_logger`]. -/// -/// In almost all cases, [`set_logger`] should be preferred. -/// -/// # Safety -/// -/// This function is only safe to call when no other logger initialization -/// function is called while this function still executes. -/// -/// This can be upheld by (for example) making sure that **there are no other -/// threads**, and (on embedded) that **interrupts are disabled**. -/// -/// It is safe to use other logging functions while this function runs -/// (including all logging macros). -/// -/// [`set_logger`]: fn.set_logger.html -pub unsafe fn set_logger_racy(logger: &'static dyn Log) -> Result<(), SetLoggerError> { - match STATE.load(Ordering::SeqCst) { - UNINITIALIZED => { - LOGGER = logger; - STATE.store(INITIALIZED, Ordering::SeqCst); - Ok(()) - } - INITIALIZING => { - // This is just plain UB, since we were racing another initialization function - unreachable!("set_logger_racy must not be used with other initialization functions") - } - _ => Err(SetLoggerError(())), - } -} - -/// The type returned by [`set_logger`] if [`set_logger`] has already been called. -/// -/// [`set_logger`]: fn.set_logger.html -#[allow(missing_copy_implementations)] -#[derive(Debug)] -pub struct SetLoggerError(()); - -impl fmt::Display for SetLoggerError { - fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { - fmt.write_str(SET_LOGGER_ERROR) - } -} - -// The Error trait is not available in libcore -#[cfg(feature = "std")] -impl error::Error for SetLoggerError {} - -/// The type returned by [`from_str`] when the string doesn't match any of the log levels. -/// -/// [`from_str`]: https://doc.rust-lang.org/std/str/trait.FromStr.html#tymethod.from_str -#[allow(missing_copy_implementations)] -#[derive(Debug, PartialEq, Eq)] -pub struct ParseLevelError(()); - -impl fmt::Display for ParseLevelError { - fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { - fmt.write_str(LEVEL_PARSE_ERROR) - } -} - -// The Error trait is not available in libcore -#[cfg(feature = "std")] -impl error::Error for ParseLevelError {} - -/// Returns a reference to the logger. -/// -/// If a logger has not been set, a no-op implementation is returned. -pub fn logger() -> &'static dyn Log { - if STATE.load(Ordering::SeqCst) != INITIALIZED { - static NOP: NopLogger = NopLogger; - &NOP - } else { - unsafe { LOGGER } - } -} - -// WARNING: this is not part of the crate's public API and is subject to change at any time -#[doc(hidden)] -pub mod __private_api; - -/// The statically resolved maximum log level. -/// -/// See the crate level documentation for information on how to configure this. -/// -/// This value is checked by the log macros, but not by the `Log`ger returned by -/// the [`logger`] function. Code that manually calls functions on that value -/// should compare the level against this value. -/// -/// [`logger`]: fn.logger.html -pub const STATIC_MAX_LEVEL: LevelFilter = MAX_LEVEL_INNER; - -const MAX_LEVEL_INNER: LevelFilter = get_max_level_inner(); - -const fn get_max_level_inner() -> LevelFilter { - #[allow(unreachable_code)] - { - #[cfg(all(not(debug_assertions), feature = "release_max_level_off"))] - { - return LevelFilter::Off; - } - #[cfg(all(not(debug_assertions), feature = "release_max_level_error"))] - { - return LevelFilter::Error; - } - #[cfg(all(not(debug_assertions), feature = "release_max_level_warn"))] - { - return LevelFilter::Warn; - } - #[cfg(all(not(debug_assertions), feature = "release_max_level_info"))] - { - return LevelFilter::Info; - } - #[cfg(all(not(debug_assertions), feature = "release_max_level_debug"))] - { - return LevelFilter::Debug; - } - #[cfg(all(not(debug_assertions), feature = "release_max_level_trace"))] - { - return LevelFilter::Trace; - } - #[cfg(feature = "max_level_off")] - { - return LevelFilter::Off; - } - #[cfg(feature = "max_level_error")] - { - return LevelFilter::Error; - } - #[cfg(feature = "max_level_warn")] - { - return LevelFilter::Warn; - } - #[cfg(feature = "max_level_info")] - { - return LevelFilter::Info; - } - #[cfg(feature = "max_level_debug")] - { - return LevelFilter::Debug; - } - - LevelFilter::Trace - } -} - -#[cfg(test)] -mod tests { - extern crate std; - use super::{Level, LevelFilter, ParseLevelError}; - use tests::std::string::ToString; - - #[test] - fn test_levelfilter_from_str() { - let tests = [ - ("off", Ok(LevelFilter::Off)), - ("error", Ok(LevelFilter::Error)), - ("warn", Ok(LevelFilter::Warn)), - ("info", Ok(LevelFilter::Info)), - ("debug", Ok(LevelFilter::Debug)), - ("trace", Ok(LevelFilter::Trace)), - ("OFF", Ok(LevelFilter::Off)), - ("ERROR", Ok(LevelFilter::Error)), - ("WARN", Ok(LevelFilter::Warn)), - ("INFO", Ok(LevelFilter::Info)), - ("DEBUG", Ok(LevelFilter::Debug)), - ("TRACE", Ok(LevelFilter::Trace)), - ("asdf", Err(ParseLevelError(()))), - ]; - for &(s, ref expected) in &tests { - assert_eq!(expected, &s.parse()); - } - } - - #[test] - fn test_level_from_str() { - let tests = [ - ("OFF", Err(ParseLevelError(()))), - ("error", Ok(Level::Error)), - ("warn", Ok(Level::Warn)), - ("info", Ok(Level::Info)), - ("debug", Ok(Level::Debug)), - ("trace", Ok(Level::Trace)), - ("ERROR", Ok(Level::Error)), - ("WARN", Ok(Level::Warn)), - ("INFO", Ok(Level::Info)), - ("DEBUG", Ok(Level::Debug)), - ("TRACE", Ok(Level::Trace)), - ("asdf", Err(ParseLevelError(()))), - ]; - for &(s, ref expected) in &tests { - assert_eq!(expected, &s.parse()); - } - } - - #[test] - fn test_level_as_str() { - let tests = &[ - (Level::Error, "ERROR"), - (Level::Warn, "WARN"), - (Level::Info, "INFO"), - (Level::Debug, "DEBUG"), - (Level::Trace, "TRACE"), - ]; - for (input, expected) in tests { - assert_eq!(*expected, input.as_str()); - } - } - - #[test] - fn test_level_show() { - assert_eq!("INFO", Level::Info.to_string()); - assert_eq!("ERROR", Level::Error.to_string()); - } - - #[test] - fn test_levelfilter_show() { - assert_eq!("OFF", LevelFilter::Off.to_string()); - assert_eq!("ERROR", LevelFilter::Error.to_string()); - } - - #[test] - fn test_cross_cmp() { - assert!(Level::Debug > LevelFilter::Error); - assert!(LevelFilter::Warn < Level::Trace); - assert!(LevelFilter::Off < Level::Error); - } - - #[test] - fn test_cross_eq() { - assert!(Level::Error == LevelFilter::Error); - assert!(LevelFilter::Off != Level::Error); - assert!(Level::Trace == LevelFilter::Trace); - } - - #[test] - fn test_to_level() { - assert_eq!(Some(Level::Error), LevelFilter::Error.to_level()); - assert_eq!(None, LevelFilter::Off.to_level()); - assert_eq!(Some(Level::Debug), LevelFilter::Debug.to_level()); - } - - #[test] - fn test_to_level_filter() { - assert_eq!(LevelFilter::Error, Level::Error.to_level_filter()); - assert_eq!(LevelFilter::Trace, Level::Trace.to_level_filter()); - } - - #[test] - fn test_level_filter_as_str() { - let tests = &[ - (LevelFilter::Off, "OFF"), - (LevelFilter::Error, "ERROR"), - (LevelFilter::Warn, "WARN"), - (LevelFilter::Info, "INFO"), - (LevelFilter::Debug, "DEBUG"), - (LevelFilter::Trace, "TRACE"), - ]; - for (input, expected) in tests { - assert_eq!(*expected, input.as_str()); - } - } - - #[test] - #[cfg(feature = "std")] - fn test_error_trait() { - use super::SetLoggerError; - let e = SetLoggerError(()); - assert_eq!( - &e.to_string(), - "attempted to set a logger after the logging system \ - was already initialized" - ); - } - - #[test] - fn test_metadata_builder() { - use super::MetadataBuilder; - let target = "myApp"; - let metadata_test = MetadataBuilder::new() - .level(Level::Debug) - .target(target) - .build(); - assert_eq!(metadata_test.level(), Level::Debug); - assert_eq!(metadata_test.target(), "myApp"); - } - - #[test] - fn test_metadata_convenience_builder() { - use super::Metadata; - let target = "myApp"; - let metadata_test = Metadata::builder() - .level(Level::Debug) - .target(target) - .build(); - assert_eq!(metadata_test.level(), Level::Debug); - assert_eq!(metadata_test.target(), "myApp"); - } - - #[test] - fn test_record_builder() { - use super::{MetadataBuilder, RecordBuilder}; - let target = "myApp"; - let metadata = MetadataBuilder::new().target(target).build(); - let fmt_args = format_args!("hello"); - let record_test = RecordBuilder::new() - .args(fmt_args) - .metadata(metadata) - .module_path(Some("foo")) - .file(Some("bar")) - .line(Some(30)) - .build(); - assert_eq!(record_test.metadata().target(), "myApp"); - assert_eq!(record_test.module_path(), Some("foo")); - assert_eq!(record_test.file(), Some("bar")); - assert_eq!(record_test.line(), Some(30)); - } - - #[test] - fn test_record_convenience_builder() { - use super::{Metadata, Record}; - let target = "myApp"; - let metadata = Metadata::builder().target(target).build(); - let fmt_args = format_args!("hello"); - let record_test = Record::builder() - .args(fmt_args) - .metadata(metadata) - .module_path(Some("foo")) - .file(Some("bar")) - .line(Some(30)) - .build(); - assert_eq!(record_test.target(), "myApp"); - assert_eq!(record_test.module_path(), Some("foo")); - assert_eq!(record_test.file(), Some("bar")); - assert_eq!(record_test.line(), Some(30)); - } - - #[test] - fn test_record_complete_builder() { - use super::{Level, Record}; - let target = "myApp"; - let record_test = Record::builder() - .module_path(Some("foo")) - .file(Some("bar")) - .line(Some(30)) - .target(target) - .level(Level::Error) - .build(); - assert_eq!(record_test.target(), "myApp"); - assert_eq!(record_test.level(), Level::Error); - assert_eq!(record_test.module_path(), Some("foo")); - assert_eq!(record_test.file(), Some("bar")); - assert_eq!(record_test.line(), Some(30)); - } - - #[test] - #[cfg(feature = "kv_unstable")] - fn test_record_key_values_builder() { - use super::Record; - use kv::{self, Visitor}; - - struct TestVisitor { - seen_pairs: usize, - } - - impl<'kvs> Visitor<'kvs> for TestVisitor { - fn visit_pair( - &mut self, - _: kv::Key<'kvs>, - _: kv::Value<'kvs>, - ) -> Result<(), kv::Error> { - self.seen_pairs += 1; - Ok(()) - } - } - - let kvs: &[(&str, i32)] = &[("a", 1), ("b", 2)]; - let record_test = Record::builder().key_values(&kvs).build(); - - let mut visitor = TestVisitor { seen_pairs: 0 }; - - record_test.key_values().visit(&mut visitor).unwrap(); - - assert_eq!(2, visitor.seen_pairs); - } - - #[test] - #[cfg(feature = "kv_unstable")] - fn test_record_key_values_get_coerce() { - use super::Record; - - let kvs: &[(&str, &str)] = &[("a", "1"), ("b", "2")]; - let record = Record::builder().key_values(&kvs).build(); - - assert_eq!( - "2", - record - .key_values() - .get("b".into()) - .expect("missing key") - .to_borrowed_str() - .expect("invalid value") - ); - } - - // Test that the `impl Log for Foo` blocks work - // This test mostly operates on a type level, so failures will be compile errors - #[test] - fn test_foreign_impl() { - use super::Log; - #[cfg(feature = "std")] - use std::sync::Arc; - - fn assert_is_log() {} - - assert_is_log::<&dyn Log>(); - - #[cfg(feature = "std")] - assert_is_log::>(); - - #[cfg(feature = "std")] - assert_is_log::>(); - - // Assert these statements for all T: Log + ?Sized - #[allow(unused)] - fn forall() { - #[cfg(feature = "std")] - assert_is_log::>(); - - assert_is_log::<&T>(); - - #[cfg(feature = "std")] - assert_is_log::>(); - } - } -} diff --git a/third-party/vendor/log/src/macros.rs b/third-party/vendor/log/src/macros.rs deleted file mode 100644 index 281ff257..00000000 --- a/third-party/vendor/log/src/macros.rs +++ /dev/null @@ -1,240 +0,0 @@ -// Copyright 2014-2015 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 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -/// The standard logging macro. -/// -/// This macro will generically log with the specified `Level` and `format!` -/// based argument list. -/// -/// # Examples -/// -/// ```edition2018 -/// use log::{log, Level}; -/// -/// # fn main() { -/// let data = (42, "Forty-two"); -/// let private_data = "private"; -/// -/// log!(Level::Error, "Received errors: {}, {}", data.0, data.1); -/// log!(target: "app_events", Level::Warn, "App warning: {}, {}, {}", -/// data.0, data.1, private_data); -/// # } -/// ``` -#[macro_export] -macro_rules! log { - // log!(target: "my_target", Level::Info, key1 = 42, key2 = true; "a {} event", "log"); - (target: $target:expr, $lvl:expr, $($key:tt = $value:expr),+; $($arg:tt)+) => ({ - let lvl = $lvl; - if lvl <= $crate::STATIC_MAX_LEVEL && lvl <= $crate::max_level() { - $crate::__private_api::log( - $crate::__private_api::format_args!($($arg)+), - lvl, - &($target, $crate::__private_api::module_path!(), $crate::__private_api::file!()), - $crate::__private_api::line!(), - $crate::__private_api::Option::Some(&[$(($crate::__log_key!($key), &$value)),+]) - ); - } - }); - - // log!(target: "my_target", Level::Info, "a {} event", "log"); - (target: $target:expr, $lvl:expr, $($arg:tt)+) => ({ - let lvl = $lvl; - if lvl <= $crate::STATIC_MAX_LEVEL && lvl <= $crate::max_level() { - $crate::__private_api::log( - $crate::__private_api::format_args!($($arg)+), - lvl, - &($target, $crate::__private_api::module_path!(), $crate::__private_api::file!()), - $crate::__private_api::line!(), - $crate::__private_api::Option::None, - ); - } - }); - - // log!(Level::Info, "a log event") - ($lvl:expr, $($arg:tt)+) => ($crate::log!(target: $crate::__private_api::module_path!(), $lvl, $($arg)+)); -} - -/// Logs a message at the error level. -/// -/// # Examples -/// -/// ```edition2018 -/// use log::error; -/// -/// # fn main() { -/// let (err_info, port) = ("No connection", 22); -/// -/// error!("Error: {} on port {}", err_info, port); -/// error!(target: "app_events", "App Error: {}, Port: {}", err_info, 22); -/// # } -/// ``` -#[macro_export] -macro_rules! error { - // error!(target: "my_target", key1 = 42, key2 = true; "a {} event", "log") - // error!(target: "my_target", "a {} event", "log") - (target: $target:expr, $($arg:tt)+) => ($crate::log!(target: $target, $crate::Level::Error, $($arg)+)); - - // error!("a {} event", "log") - ($($arg:tt)+) => ($crate::log!($crate::Level::Error, $($arg)+)) -} - -/// Logs a message at the warn level. -/// -/// # Examples -/// -/// ```edition2018 -/// use log::warn; -/// -/// # fn main() { -/// let warn_description = "Invalid Input"; -/// -/// warn!("Warning! {}!", warn_description); -/// warn!(target: "input_events", "App received warning: {}", warn_description); -/// # } -/// ``` -#[macro_export] -macro_rules! warn { - // warn!(target: "my_target", key1 = 42, key2 = true; "a {} event", "log") - // warn!(target: "my_target", "a {} event", "log") - (target: $target:expr, $($arg:tt)+) => ($crate::log!(target: $target, $crate::Level::Warn, $($arg)+)); - - // warn!("a {} event", "log") - ($($arg:tt)+) => ($crate::log!($crate::Level::Warn, $($arg)+)) -} - -/// Logs a message at the info level. -/// -/// # Examples -/// -/// ```edition2018 -/// use log::info; -/// -/// # fn main() { -/// # struct Connection { port: u32, speed: f32 } -/// let conn_info = Connection { port: 40, speed: 3.20 }; -/// -/// info!("Connected to port {} at {} Mb/s", conn_info.port, conn_info.speed); -/// info!(target: "connection_events", "Successful connection, port: {}, speed: {}", -/// conn_info.port, conn_info.speed); -/// # } -/// ``` -#[macro_export] -macro_rules! info { - // info!(target: "my_target", key1 = 42, key2 = true; "a {} event", "log") - // info!(target: "my_target", "a {} event", "log") - (target: $target:expr, $($arg:tt)+) => ($crate::log!(target: $target, $crate::Level::Info, $($arg)+)); - - // info!("a {} event", "log") - ($($arg:tt)+) => ($crate::log!($crate::Level::Info, $($arg)+)) -} - -/// Logs a message at the debug level. -/// -/// # Examples -/// -/// ```edition2018 -/// use log::debug; -/// -/// # fn main() { -/// # struct Position { x: f32, y: f32 } -/// let pos = Position { x: 3.234, y: -1.223 }; -/// -/// debug!("New position: x: {}, y: {}", pos.x, pos.y); -/// debug!(target: "app_events", "New position: x: {}, y: {}", pos.x, pos.y); -/// # } -/// ``` -#[macro_export] -macro_rules! debug { - // debug!(target: "my_target", key1 = 42, key2 = true; "a {} event", "log") - // debug!(target: "my_target", "a {} event", "log") - (target: $target:expr, $($arg:tt)+) => ($crate::log!(target: $target, $crate::Level::Debug, $($arg)+)); - - // debug!("a {} event", "log") - ($($arg:tt)+) => ($crate::log!($crate::Level::Debug, $($arg)+)) -} - -/// Logs a message at the trace level. -/// -/// # Examples -/// -/// ```edition2018 -/// use log::trace; -/// -/// # fn main() { -/// # struct Position { x: f32, y: f32 } -/// let pos = Position { x: 3.234, y: -1.223 }; -/// -/// trace!("Position is: x: {}, y: {}", pos.x, pos.y); -/// trace!(target: "app_events", "x is {} and y is {}", -/// if pos.x >= 0.0 { "positive" } else { "negative" }, -/// if pos.y >= 0.0 { "positive" } else { "negative" }); -/// # } -/// ``` -#[macro_export] -macro_rules! trace { - // trace!(target: "my_target", key1 = 42, key2 = true; "a {} event", "log") - // trace!(target: "my_target", "a {} event", "log") - (target: $target:expr, $($arg:tt)+) => ($crate::log!(target: $target, $crate::Level::Trace, $($arg)+)); - - // trace!("a {} event", "log") - ($($arg:tt)+) => ($crate::log!($crate::Level::Trace, $($arg)+)) -} - -/// Determines if a message logged at the specified level in that module will -/// be logged. -/// -/// This can be used to avoid expensive computation of log message arguments if -/// the message would be ignored anyway. -/// -/// # Examples -/// -/// ```edition2018 -/// use log::Level::Debug; -/// use log::{debug, log_enabled}; -/// -/// # fn foo() { -/// if log_enabled!(Debug) { -/// let data = expensive_call(); -/// debug!("expensive debug data: {} {}", data.x, data.y); -/// } -/// if log_enabled!(target: "Global", Debug) { -/// let data = expensive_call(); -/// debug!(target: "Global", "expensive debug data: {} {}", data.x, data.y); -/// } -/// # } -/// # struct Data { x: u32, y: u32 } -/// # fn expensive_call() -> Data { Data { x: 0, y: 0 } } -/// # fn main() {} -/// ``` -#[macro_export] -macro_rules! log_enabled { - (target: $target:expr, $lvl:expr) => {{ - let lvl = $lvl; - lvl <= $crate::STATIC_MAX_LEVEL - && lvl <= $crate::max_level() - && $crate::__private_api::enabled(lvl, $target) - }}; - ($lvl:expr) => { - $crate::log_enabled!(target: $crate::__private_api::module_path!(), $lvl) - }; -} - -#[doc(hidden)] -#[macro_export] -macro_rules! __log_key { - // key1 = 42 - ($($args:ident)*) => { - $crate::__private_api::stringify!($($args)*) - }; - // "key1" = 42 - ($($args:expr)*) => { - $($args)* - }; -} diff --git a/third-party/vendor/log/src/serde.rs b/third-party/vendor/log/src/serde.rs deleted file mode 100644 index 50128330..00000000 --- a/third-party/vendor/log/src/serde.rs +++ /dev/null @@ -1,400 +0,0 @@ -#![cfg(feature = "serde")] - -extern crate serde; -use self::serde::de::{ - Deserialize, DeserializeSeed, Deserializer, EnumAccess, Error, Unexpected, VariantAccess, - Visitor, -}; -use self::serde::ser::{Serialize, Serializer}; - -use {Level, LevelFilter, LOG_LEVEL_NAMES}; - -use std::fmt; -use std::str::{self, FromStr}; - -// The Deserialize impls are handwritten to be case insensitive using FromStr. - -impl Serialize for Level { - fn serialize(&self, serializer: S) -> Result - where - S: Serializer, - { - match *self { - Level::Error => serializer.serialize_unit_variant("Level", 0, "ERROR"), - Level::Warn => serializer.serialize_unit_variant("Level", 1, "WARN"), - Level::Info => serializer.serialize_unit_variant("Level", 2, "INFO"), - Level::Debug => serializer.serialize_unit_variant("Level", 3, "DEBUG"), - Level::Trace => serializer.serialize_unit_variant("Level", 4, "TRACE"), - } - } -} - -impl<'de> Deserialize<'de> for Level { - fn deserialize(deserializer: D) -> Result - where - D: Deserializer<'de>, - { - struct LevelIdentifier; - - impl<'de> Visitor<'de> for LevelIdentifier { - type Value = Level; - - fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { - formatter.write_str("log level") - } - - fn visit_str(self, s: &str) -> Result - where - E: Error, - { - // Case insensitive. - FromStr::from_str(s).map_err(|_| Error::unknown_variant(s, &LOG_LEVEL_NAMES[1..])) - } - - fn visit_bytes(self, value: &[u8]) -> Result - where - E: Error, - { - let variant = str::from_utf8(value) - .map_err(|_| Error::invalid_value(Unexpected::Bytes(value), &self))?; - - self.visit_str(variant) - } - - fn visit_u64(self, v: u64) -> Result - where - E: Error, - { - let variant = LOG_LEVEL_NAMES[1..] - .get(v as usize) - .ok_or_else(|| Error::invalid_value(Unexpected::Unsigned(v), &self))?; - - self.visit_str(variant) - } - } - - impl<'de> DeserializeSeed<'de> for LevelIdentifier { - type Value = Level; - - fn deserialize(self, deserializer: D) -> Result - where - D: Deserializer<'de>, - { - deserializer.deserialize_identifier(LevelIdentifier) - } - } - - struct LevelEnum; - - impl<'de> Visitor<'de> for LevelEnum { - type Value = Level; - - fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { - formatter.write_str("log level") - } - - fn visit_enum
(self, value: A) -> Result - where - A: EnumAccess<'de>, - { - let (level, variant) = value.variant_seed(LevelIdentifier)?; - // Every variant is a unit variant. - variant.unit_variant()?; - Ok(level) - } - } - - deserializer.deserialize_enum("Level", &LOG_LEVEL_NAMES[1..], LevelEnum) - } -} - -impl Serialize for LevelFilter { - fn serialize(&self, serializer: S) -> Result - where - S: Serializer, - { - match *self { - LevelFilter::Off => serializer.serialize_unit_variant("LevelFilter", 0, "OFF"), - LevelFilter::Error => serializer.serialize_unit_variant("LevelFilter", 1, "ERROR"), - LevelFilter::Warn => serializer.serialize_unit_variant("LevelFilter", 2, "WARN"), - LevelFilter::Info => serializer.serialize_unit_variant("LevelFilter", 3, "INFO"), - LevelFilter::Debug => serializer.serialize_unit_variant("LevelFilter", 4, "DEBUG"), - LevelFilter::Trace => serializer.serialize_unit_variant("LevelFilter", 5, "TRACE"), - } - } -} - -impl<'de> Deserialize<'de> for LevelFilter { - fn deserialize(deserializer: D) -> Result - where - D: Deserializer<'de>, - { - struct LevelFilterIdentifier; - - impl<'de> Visitor<'de> for LevelFilterIdentifier { - type Value = LevelFilter; - - fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { - formatter.write_str("log level filter") - } - - fn visit_str(self, s: &str) -> Result - where - E: Error, - { - // Case insensitive. - FromStr::from_str(s).map_err(|_| Error::unknown_variant(s, &LOG_LEVEL_NAMES)) - } - - fn visit_bytes(self, value: &[u8]) -> Result - where - E: Error, - { - let variant = str::from_utf8(value) - .map_err(|_| Error::invalid_value(Unexpected::Bytes(value), &self))?; - - self.visit_str(variant) - } - - fn visit_u64(self, v: u64) -> Result - where - E: Error, - { - let variant = LOG_LEVEL_NAMES - .get(v as usize) - .ok_or_else(|| Error::invalid_value(Unexpected::Unsigned(v), &self))?; - - self.visit_str(variant) - } - } - - impl<'de> DeserializeSeed<'de> for LevelFilterIdentifier { - type Value = LevelFilter; - - fn deserialize(self, deserializer: D) -> Result - where - D: Deserializer<'de>, - { - deserializer.deserialize_identifier(LevelFilterIdentifier) - } - } - - struct LevelFilterEnum; - - impl<'de> Visitor<'de> for LevelFilterEnum { - type Value = LevelFilter; - - fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { - formatter.write_str("log level filter") - } - - fn visit_enum(self, value: A) -> Result - where - A: EnumAccess<'de>, - { - let (level_filter, variant) = value.variant_seed(LevelFilterIdentifier)?; - // Every variant is a unit variant. - variant.unit_variant()?; - Ok(level_filter) - } - } - - deserializer.deserialize_enum("LevelFilter", &LOG_LEVEL_NAMES, LevelFilterEnum) - } -} - -#[cfg(test)] -mod tests { - extern crate serde_test; - use self::serde_test::{assert_de_tokens, assert_de_tokens_error, assert_tokens, Token}; - - use {Level, LevelFilter}; - - fn level_token(variant: &'static str) -> Token { - Token::UnitVariant { - name: "Level", - variant: variant, - } - } - - fn level_bytes_tokens(variant: &'static [u8]) -> [Token; 3] { - [ - Token::Enum { name: "Level" }, - Token::Bytes(variant), - Token::Unit, - ] - } - - fn level_variant_tokens(variant: u32) -> [Token; 3] { - [ - Token::Enum { name: "Level" }, - Token::U32(variant), - Token::Unit, - ] - } - - fn level_filter_token(variant: &'static str) -> Token { - Token::UnitVariant { - name: "LevelFilter", - variant: variant, - } - } - - fn level_filter_bytes_tokens(variant: &'static [u8]) -> [Token; 3] { - [ - Token::Enum { - name: "LevelFilter", - }, - Token::Bytes(variant), - Token::Unit, - ] - } - - fn level_filter_variant_tokens(variant: u32) -> [Token; 3] { - [ - Token::Enum { - name: "LevelFilter", - }, - Token::U32(variant), - Token::Unit, - ] - } - - #[test] - fn test_level_ser_de() { - let cases = [ - (Level::Error, [level_token("ERROR")]), - (Level::Warn, [level_token("WARN")]), - (Level::Info, [level_token("INFO")]), - (Level::Debug, [level_token("DEBUG")]), - (Level::Trace, [level_token("TRACE")]), - ]; - - for &(s, expected) in &cases { - assert_tokens(&s, &expected); - } - } - - #[test] - fn test_level_case_insensitive() { - let cases = [ - (Level::Error, [level_token("error")]), - (Level::Warn, [level_token("warn")]), - (Level::Info, [level_token("info")]), - (Level::Debug, [level_token("debug")]), - (Level::Trace, [level_token("trace")]), - ]; - - for &(s, expected) in &cases { - assert_de_tokens(&s, &expected); - } - } - - #[test] - fn test_level_de_bytes() { - let cases = [ - (Level::Error, level_bytes_tokens(b"ERROR")), - (Level::Warn, level_bytes_tokens(b"WARN")), - (Level::Info, level_bytes_tokens(b"INFO")), - (Level::Debug, level_bytes_tokens(b"DEBUG")), - (Level::Trace, level_bytes_tokens(b"TRACE")), - ]; - - for &(value, tokens) in &cases { - assert_de_tokens(&value, &tokens); - } - } - - #[test] - fn test_level_de_variant_index() { - let cases = [ - (Level::Error, level_variant_tokens(0)), - (Level::Warn, level_variant_tokens(1)), - (Level::Info, level_variant_tokens(2)), - (Level::Debug, level_variant_tokens(3)), - (Level::Trace, level_variant_tokens(4)), - ]; - - for &(value, tokens) in &cases { - assert_de_tokens(&value, &tokens); - } - } - - #[test] - fn test_level_de_error() { - let msg = "unknown variant `errorx`, expected one of \ - `ERROR`, `WARN`, `INFO`, `DEBUG`, `TRACE`"; - assert_de_tokens_error::(&[level_token("errorx")], msg); - } - - #[test] - fn test_level_filter_ser_de() { - let cases = [ - (LevelFilter::Off, [level_filter_token("OFF")]), - (LevelFilter::Error, [level_filter_token("ERROR")]), - (LevelFilter::Warn, [level_filter_token("WARN")]), - (LevelFilter::Info, [level_filter_token("INFO")]), - (LevelFilter::Debug, [level_filter_token("DEBUG")]), - (LevelFilter::Trace, [level_filter_token("TRACE")]), - ]; - - for &(s, expected) in &cases { - assert_tokens(&s, &expected); - } - } - - #[test] - fn test_level_filter_case_insensitive() { - let cases = [ - (LevelFilter::Off, [level_filter_token("off")]), - (LevelFilter::Error, [level_filter_token("error")]), - (LevelFilter::Warn, [level_filter_token("warn")]), - (LevelFilter::Info, [level_filter_token("info")]), - (LevelFilter::Debug, [level_filter_token("debug")]), - (LevelFilter::Trace, [level_filter_token("trace")]), - ]; - - for &(s, expected) in &cases { - assert_de_tokens(&s, &expected); - } - } - - #[test] - fn test_level_filter_de_bytes() { - let cases = [ - (LevelFilter::Off, level_filter_bytes_tokens(b"OFF")), - (LevelFilter::Error, level_filter_bytes_tokens(b"ERROR")), - (LevelFilter::Warn, level_filter_bytes_tokens(b"WARN")), - (LevelFilter::Info, level_filter_bytes_tokens(b"INFO")), - (LevelFilter::Debug, level_filter_bytes_tokens(b"DEBUG")), - (LevelFilter::Trace, level_filter_bytes_tokens(b"TRACE")), - ]; - - for &(value, tokens) in &cases { - assert_de_tokens(&value, &tokens); - } - } - - #[test] - fn test_level_filter_de_variant_index() { - let cases = [ - (LevelFilter::Off, level_filter_variant_tokens(0)), - (LevelFilter::Error, level_filter_variant_tokens(1)), - (LevelFilter::Warn, level_filter_variant_tokens(2)), - (LevelFilter::Info, level_filter_variant_tokens(3)), - (LevelFilter::Debug, level_filter_variant_tokens(4)), - (LevelFilter::Trace, level_filter_variant_tokens(5)), - ]; - - for &(value, tokens) in &cases { - assert_de_tokens(&value, &tokens); - } - } - - #[test] - fn test_level_filter_de_error() { - let msg = "unknown variant `errorx`, expected one of \ - `OFF`, `ERROR`, `WARN`, `INFO`, `DEBUG`, `TRACE`"; - assert_de_tokens_error::(&[level_filter_token("errorx")], msg); - } -} diff --git a/third-party/vendor/log/triagebot.toml b/third-party/vendor/log/triagebot.toml deleted file mode 100644 index fa0824ac..00000000 --- a/third-party/vendor/log/triagebot.toml +++ /dev/null @@ -1 +0,0 @@ -[assign] diff --git a/third-party/vendor/proc-macro2/.cargo-checksum.json b/third-party/vendor/proc-macro2/.cargo-checksum.json deleted file mode 100644 index 9368d276..00000000 --- a/third-party/vendor/proc-macro2/.cargo-checksum.json +++ /dev/null @@ -1 +0,0 @@ -{"files":{"Cargo.toml":"cf58b9b5cd9abb5dca91d4d61809edcf425156bd8e9bb69e0398e00e74aa7af1","LICENSE-APACHE":"62c7a1e35f56406896d7aa7ca52d0cc0d272ac022b5d2796e7d6905db8a3636a","LICENSE-MIT":"23f18e03dc49df91622fe2a76176497404e46ced8a715d9d2b67a7446571cca3","README.md":"c609b6865476d6c35879784e9155367a97a0da496aa5c3c61488440a20f59883","build.rs":"8b4facae0d125ca3b437b4f5ebcd6ea3da3fcc65fcfc2cf357ae544423aa4568","build/probe.rs":"971fd2178dc506ccdc5c2065c37b77696a4aee8e00330ca52625db4a857f68d3","rust-toolchain.toml":"6bbb61302978c736b2da03e4fb40e3beab908f85d533ab46fd541e637b5f3e0f","src/detection.rs":"ed9a5f9a979ab01247d7a68eeb1afa3c13209334c5bfff0f9289cb07e5bb4e8b","src/extra.rs":"7c3864497cb5298fd5d0e9f5ae5797860338a9a4263220a8e8eabecda1583797","src/fallback.rs":"2e668a1ed90243e6f627a0c85c73c61f5c4107d82e149de5960d806d5eae99f9","src/lib.rs":"ea7a33758942e0911d5545e57b6a726c5bca7960fe3eed58a46b692244ac575a","src/location.rs":"f55d2e61f1bb1af65e14ed04c9e91eb1ddbf8430e8c05f2048d1cd538d27368e","src/marker.rs":"c11c5a1be8bdf18be3fcd224393f350a9aae7ce282e19ce583c84910c6903a8f","src/parse.rs":"4b77cddbc2752bc4d38a65acd8b96b6786c5220d19b1e1b37810257b5d24132d","src/rcvec.rs":"1c3c48c4f819927cc445ae15ca3bb06775feff2fd1cb21901ae4c40c7e6b4e82","src/wrapper.rs":"029fc07e8adbea2dd2a0aab49b07c3fb9cd8bc0539ea85bf9166c46922933742","tests/comments.rs":"31115b3a56c83d93eef2fb4c9566bf4543e302560732986161b98aef504785ed","tests/features.rs":"a86deb8644992a4eb64d9fd493eff16f9cf9c5cb6ade3a634ce0c990cf87d559","tests/marker.rs":"3190ee07dae510251f360db701ce257030f94a479b6689c3a9ef804bd5d8d099","tests/test.rs":"de9163d0b7d53a56de4c3d00acb415785e55c161becfe37b2a0c5d8d1931f14f","tests/test_fmt.rs":"b7743b612af65f2c88cbe109d50a093db7aa7e87f9e37bf45b7bbaeb240aa020","tests/test_size.rs":"acf05963c1e62052d769d237b50844a2c59b4182b491231b099a4f74e5456ab0"},"package":"e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae"} \ No newline at end of file diff --git a/third-party/vendor/proc-macro2/Cargo.toml b/third-party/vendor/proc-macro2/Cargo.toml deleted file mode 100644 index 65506c21..00000000 --- a/third-party/vendor/proc-macro2/Cargo.toml +++ /dev/null @@ -1,76 +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 are reading this file be aware that the original Cargo.toml -# will likely look very different (and much more reasonable). -# See Cargo.toml.orig for the original contents. - -[package] -edition = "2021" -rust-version = "1.56" -name = "proc-macro2" -version = "1.0.78" -authors = [ - "David Tolnay ", - "Alex Crichton ", -] -autobenches = false -description = "A substitute implementation of the compiler's `proc_macro` API to decouple token-based libraries from the procedural macro use case." -documentation = "https://docs.rs/proc-macro2" -readme = "README.md" -keywords = [ - "macros", - "syn", -] -categories = ["development-tools::procedural-macro-helpers"] -license = "MIT OR Apache-2.0" -repository = "https://github.com/dtolnay/proc-macro2" - -[package.metadata.docs.rs] -rustc-args = [ - "--cfg", - "procmacro2_semver_exempt", -] -rustdoc-args = [ - "--cfg", - "procmacro2_semver_exempt", - "--cfg", - "doc_cfg", - "--generate-link-to-definition", -] -targets = ["x86_64-unknown-linux-gnu"] - -[package.metadata.playground] -features = ["span-locations"] - -[lib] -doc-scrape-examples = false - -[dependencies.unicode-ident] -version = "1.0" - -[dev-dependencies.flate2] -version = "1.0" - -[dev-dependencies.quote] -version = "1.0" -default_features = false - -[dev-dependencies.rayon] -version = "1.0" - -[dev-dependencies.rustversion] -version = "1" - -[dev-dependencies.tar] -version = "0.4" - -[features] -default = ["proc-macro"] -nightly = [] -proc-macro = [] -span-locations = [] diff --git a/third-party/vendor/proc-macro2/LICENSE-APACHE b/third-party/vendor/proc-macro2/LICENSE-APACHE deleted file mode 100644 index 1b5ec8b7..00000000 --- a/third-party/vendor/proc-macro2/LICENSE-APACHE +++ /dev/null @@ -1,176 +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 diff --git a/third-party/vendor/proc-macro2/LICENSE-MIT b/third-party/vendor/proc-macro2/LICENSE-MIT deleted file mode 100644 index 31aa7938..00000000 --- a/third-party/vendor/proc-macro2/LICENSE-MIT +++ /dev/null @@ -1,23 +0,0 @@ -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. diff --git a/third-party/vendor/proc-macro2/README.md b/third-party/vendor/proc-macro2/README.md deleted file mode 100644 index 3a29ce8b..00000000 --- a/third-party/vendor/proc-macro2/README.md +++ /dev/null @@ -1,94 +0,0 @@ -# proc-macro2 - -[github](https://github.com/dtolnay/proc-macro2) -[crates.io](https://crates.io/crates/proc-macro2) -[docs.rs](https://docs.rs/proc-macro2) -[build status](https://github.com/dtolnay/proc-macro2/actions?query=branch%3Amaster) - -A wrapper around the procedural macro API of the compiler's `proc_macro` crate. -This library serves two purposes: - -- **Bring proc-macro-like functionality to other contexts like build.rs and - main.rs.** Types from `proc_macro` are entirely specific to procedural macros - and cannot ever exist in code outside of a procedural macro. Meanwhile - `proc_macro2` types may exist anywhere including non-macro code. By developing - foundational libraries like [syn] and [quote] against `proc_macro2` rather - than `proc_macro`, the procedural macro ecosystem becomes easily applicable to - many other use cases and we avoid reimplementing non-macro equivalents of - those libraries. - -- **Make procedural macros unit testable.** As a consequence of being specific - to procedural macros, nothing that uses `proc_macro` can be executed from a - unit test. In order for helper libraries or components of a macro to be - testable in isolation, they must be implemented using `proc_macro2`. - -[syn]: https://github.com/dtolnay/syn -[quote]: https://github.com/dtolnay/quote - -## Usage - -```toml -[dependencies] -proc-macro2 = "1.0" -``` - -The skeleton of a typical procedural macro typically looks like this: - -```rust -extern crate proc_macro; - -#[proc_macro_derive(MyDerive)] -pub fn my_derive(input: proc_macro::TokenStream) -> proc_macro::TokenStream { - let input = proc_macro2::TokenStream::from(input); - - let output: proc_macro2::TokenStream = { - /* transform input */ - }; - - proc_macro::TokenStream::from(output) -} -``` - -If parsing with [Syn], you'll use [`parse_macro_input!`] instead to propagate -parse errors correctly back to the compiler when parsing fails. - -[`parse_macro_input!`]: https://docs.rs/syn/2.0/syn/macro.parse_macro_input.html - -## Unstable features - -The default feature set of proc-macro2 tracks the most recent stable compiler -API. Functionality in `proc_macro` that is not yet stable is not exposed by -proc-macro2 by default. - -To opt into the additional APIs available in the most recent nightly compiler, -the `procmacro2_semver_exempt` config flag must be passed to rustc. We will -polyfill those nightly-only APIs back to Rust 1.56.0. As these are unstable APIs -that track the nightly compiler, minor versions of proc-macro2 may make breaking -changes to them at any time. - -``` -RUSTFLAGS='--cfg procmacro2_semver_exempt' cargo build -``` - -Note that this must not only be done for your crate, but for any crate that -depends on your crate. This infectious nature is intentional, as it serves as a -reminder that you are outside of the normal semver guarantees. - -Semver exempt methods are marked as such in the proc-macro2 documentation. - -
- -#### License - - -Licensed under either of
Apache License, Version -2.0 or MIT license at your option. - - -
- - -Unless you explicitly state otherwise, any contribution intentionally submitted -for inclusion in this crate by you, as defined in the Apache-2.0 license, shall -be dual licensed as above, without any additional terms or conditions. - diff --git a/third-party/vendor/proc-macro2/build.rs b/third-party/vendor/proc-macro2/build.rs deleted file mode 100644 index 3347f878..00000000 --- a/third-party/vendor/proc-macro2/build.rs +++ /dev/null @@ -1,202 +0,0 @@ -// rustc-cfg emitted by the build script: -// -// "wrap_proc_macro" -// Wrap types from libproc_macro rather than polyfilling the whole API. -// Enabled on rustc 1.29+ as long as procmacro2_semver_exempt is not set, -// because we can't emulate the unstable API without emulating everything -// else. Also enabled unconditionally on nightly, in which case the -// procmacro2_semver_exempt surface area is implemented by using the -// nightly-only proc_macro API. -// -// "hygiene" -// Enable Span::mixed_site() and non-dummy behavior of Span::resolved_at -// and Span::located_at. Enabled on Rust 1.45+. -// -// "proc_macro_span" -// Enable non-dummy behavior of Span::start and Span::end methods which -// requires an unstable compiler feature. Enabled when building with -// nightly, unless `-Z allow-feature` in RUSTFLAGS disallows unstable -// features. -// -// "super_unstable" -// Implement the semver exempt API in terms of the nightly-only proc_macro -// API. Enabled when using procmacro2_semver_exempt on a nightly compiler. -// -// "span_locations" -// Provide methods Span::start and Span::end which give the line/column -// location of a token. Enabled by procmacro2_semver_exempt or the -// "span-locations" Cargo cfg. This is behind a cfg because tracking -// location inside spans is a performance hit. -// -// "is_available" -// Use proc_macro::is_available() to detect if the proc macro API is -// available or needs to be polyfilled instead of trying to use the proc -// macro API and catching a panic if it isn't available. Enabled on Rust -// 1.57+. - -use std::env; -use std::ffi::OsString; -use std::path::Path; -use std::process::{self, Command, Stdio}; -use std::str; -use std::u32; - -fn main() { - let rustc = rustc_minor_version().unwrap_or(u32::MAX); - - let docs_rs = env::var_os("DOCS_RS").is_some(); - let semver_exempt = cfg!(procmacro2_semver_exempt) || docs_rs; - if semver_exempt { - // https://github.com/dtolnay/proc-macro2/issues/147 - println!("cargo:rustc-cfg=procmacro2_semver_exempt"); - } - - if semver_exempt || cfg!(feature = "span-locations") { - println!("cargo:rustc-cfg=span_locations"); - } - - if rustc < 57 { - println!("cargo:rustc-cfg=no_is_available"); - } - - if rustc < 66 { - println!("cargo:rustc-cfg=no_source_text"); - } - - if !cfg!(feature = "proc-macro") { - println!("cargo:rerun-if-changed=build.rs"); - return; - } - - println!("cargo:rerun-if-changed=build/probe.rs"); - - let proc_macro_span; - let consider_rustc_bootstrap; - if compile_probe(false) { - // This is a nightly or dev compiler, so it supports unstable features - // regardless of RUSTC_BOOTSTRAP. No need to rerun build script if - // RUSTC_BOOTSTRAP is changed. - proc_macro_span = true; - consider_rustc_bootstrap = false; - } else if let Some(rustc_bootstrap) = env::var_os("RUSTC_BOOTSTRAP") { - if compile_probe(true) { - // This is a stable or beta compiler for which the user has set - // RUSTC_BOOTSTRAP to turn on unstable features. Rerun build script - // if they change it. - proc_macro_span = true; - consider_rustc_bootstrap = true; - } else if rustc_bootstrap == "1" { - // This compiler does not support the proc macro Span API in the - // form that proc-macro2 expects. No need to pay attention to - // RUSTC_BOOTSTRAP. - proc_macro_span = false; - consider_rustc_bootstrap = false; - } else { - // This is a stable or beta compiler for which RUSTC_BOOTSTRAP is - // set to restrict the use of unstable features by this crate. - proc_macro_span = false; - consider_rustc_bootstrap = true; - } - } else { - // Without RUSTC_BOOTSTRAP, this compiler does not support the proc - // macro Span API in the form that proc-macro2 expects, but try again if - // the user turns on unstable features. - proc_macro_span = false; - consider_rustc_bootstrap = true; - } - - if proc_macro_span || !semver_exempt { - println!("cargo:rustc-cfg=wrap_proc_macro"); - } - - if proc_macro_span { - println!("cargo:rustc-cfg=proc_macro_span"); - } - - if semver_exempt && proc_macro_span { - println!("cargo:rustc-cfg=super_unstable"); - } - - if consider_rustc_bootstrap { - println!("cargo:rerun-if-env-changed=RUSTC_BOOTSTRAP"); - } -} - -fn compile_probe(rustc_bootstrap: bool) -> bool { - if env::var_os("RUSTC_STAGE").is_some() { - // We are running inside rustc bootstrap. This is a highly non-standard - // environment with issues such as: - // - // https://github.com/rust-lang/cargo/issues/11138 - // https://github.com/rust-lang/rust/issues/114839 - // - // Let's just not use nightly features here. - return false; - } - - let rustc = cargo_env_var("RUSTC"); - let out_dir = cargo_env_var("OUT_DIR"); - let probefile = Path::new("build").join("probe.rs"); - - // Make sure to pick up Cargo rustc configuration. - let mut cmd = if let Some(wrapper) = env::var_os("RUSTC_WRAPPER") { - let mut cmd = Command::new(wrapper); - // The wrapper's first argument is supposed to be the path to rustc. - cmd.arg(rustc); - cmd - } else { - Command::new(rustc) - }; - - if !rustc_bootstrap { - cmd.env_remove("RUSTC_BOOTSTRAP"); - } - - cmd.stderr(Stdio::null()) - .arg("--edition=2021") - .arg("--crate-name=proc_macro2") - .arg("--crate-type=lib") - .arg("--emit=dep-info,metadata") - .arg("--out-dir") - .arg(out_dir) - .arg(probefile); - - if let Some(target) = env::var_os("TARGET") { - cmd.arg("--target").arg(target); - } - - // If Cargo wants to set RUSTFLAGS, use that. - if let Ok(rustflags) = env::var("CARGO_ENCODED_RUSTFLAGS") { - if !rustflags.is_empty() { - for arg in rustflags.split('\x1f') { - cmd.arg(arg); - } - } - } - - match cmd.status() { - Ok(status) => status.success(), - Err(_) => false, - } -} - -fn rustc_minor_version() -> Option { - let rustc = cargo_env_var("RUSTC"); - let output = Command::new(rustc).arg("--version").output().ok()?; - let version = str::from_utf8(&output.stdout).ok()?; - let mut pieces = version.split('.'); - if pieces.next() != Some("rustc 1") { - return None; - } - pieces.next()?.parse().ok() -} - -fn cargo_env_var(key: &str) -> OsString { - env::var_os(key).unwrap_or_else(|| { - eprintln!( - "Environment variable ${} is not set during execution of build script", - key, - ); - process::exit(1); - }) -} diff --git a/third-party/vendor/proc-macro2/build/probe.rs b/third-party/vendor/proc-macro2/build/probe.rs deleted file mode 100644 index 2c4947a0..00000000 --- a/third-party/vendor/proc-macro2/build/probe.rs +++ /dev/null @@ -1,25 +0,0 @@ -// This code exercises the surface area that we expect of Span's unstable API. -// If the current toolchain is able to compile it, then proc-macro2 is able to -// offer these APIs too. - -#![feature(proc_macro_span)] - -extern crate proc_macro; - -use core::ops::{Range, RangeBounds}; -use proc_macro::{Literal, Span}; - -pub fn byte_range(this: &Span) -> Range { - this.byte_range() -} - -pub fn join(this: &Span, other: Span) -> Option { - this.join(other) -} - -pub fn subspan>(this: &Literal, range: R) -> Option { - this.subspan(range) -} - -// Include in sccache cache key. -const _: Option<&str> = option_env!("RUSTC_BOOTSTRAP"); diff --git a/third-party/vendor/proc-macro2/rust-toolchain.toml b/third-party/vendor/proc-macro2/rust-toolchain.toml deleted file mode 100644 index 20fe888c..00000000 --- a/third-party/vendor/proc-macro2/rust-toolchain.toml +++ /dev/null @@ -1,2 +0,0 @@ -[toolchain] -components = ["rust-src"] diff --git a/third-party/vendor/proc-macro2/src/detection.rs b/third-party/vendor/proc-macro2/src/detection.rs deleted file mode 100644 index beba7b23..00000000 --- a/third-party/vendor/proc-macro2/src/detection.rs +++ /dev/null @@ -1,75 +0,0 @@ -use core::sync::atomic::{AtomicUsize, Ordering}; -use std::sync::Once; - -static WORKS: AtomicUsize = AtomicUsize::new(0); -static INIT: Once = Once::new(); - -pub(crate) fn inside_proc_macro() -> bool { - match WORKS.load(Ordering::Relaxed) { - 1 => return false, - 2 => return true, - _ => {} - } - - INIT.call_once(initialize); - inside_proc_macro() -} - -pub(crate) fn force_fallback() { - WORKS.store(1, Ordering::Relaxed); -} - -pub(crate) fn unforce_fallback() { - initialize(); -} - -#[cfg(not(no_is_available))] -fn initialize() { - let available = proc_macro::is_available(); - WORKS.store(available as usize + 1, Ordering::Relaxed); -} - -// Swap in a null panic hook to avoid printing "thread panicked" to stderr, -// then use catch_unwind to determine whether the compiler's proc_macro is -// working. When proc-macro2 is used from outside of a procedural macro all -// of the proc_macro crate's APIs currently panic. -// -// The Once is to prevent the possibility of this ordering: -// -// thread 1 calls take_hook, gets the user's original hook -// thread 1 calls set_hook with the null hook -// thread 2 calls take_hook, thinks null hook is the original hook -// thread 2 calls set_hook with the null hook -// thread 1 calls set_hook with the actual original hook -// thread 2 calls set_hook with what it thinks is the original hook -// -// in which the user's hook has been lost. -// -// There is still a race condition where a panic in a different thread can -// happen during the interval that the user's original panic hook is -// unregistered such that their hook is incorrectly not called. This is -// sufficiently unlikely and less bad than printing panic messages to stderr -// on correct use of this crate. Maybe there is a libstd feature request -// here. For now, if a user needs to guarantee that this failure mode does -// not occur, they need to call e.g. `proc_macro2::Span::call_site()` from -// the main thread before launching any other threads. -#[cfg(no_is_available)] -fn initialize() { - use std::panic::{self, PanicInfo}; - - type PanicHook = dyn Fn(&PanicInfo) + Sync + Send + 'static; - - let null_hook: Box = Box::new(|_panic_info| { /* ignore */ }); - let sanity_check = &*null_hook as *const PanicHook; - let original_hook = panic::take_hook(); - panic::set_hook(null_hook); - - let works = panic::catch_unwind(proc_macro::Span::call_site).is_ok(); - WORKS.store(works as usize + 1, Ordering::Relaxed); - - let hopefully_null_hook = panic::take_hook(); - panic::set_hook(original_hook); - if sanity_check != &*hopefully_null_hook { - panic!("observed race condition in proc_macro2::inside_proc_macro"); - } -} diff --git a/third-party/vendor/proc-macro2/src/extra.rs b/third-party/vendor/proc-macro2/src/extra.rs deleted file mode 100644 index 543ec1d9..00000000 --- a/third-party/vendor/proc-macro2/src/extra.rs +++ /dev/null @@ -1,151 +0,0 @@ -//! Items which do not have a correspondence to any API in the proc_macro crate, -//! but are necessary to include in proc-macro2. - -use crate::fallback; -use crate::imp; -use crate::marker::{ProcMacroAutoTraits, MARKER}; -use crate::Span; -use core::fmt::{self, Debug}; - -/// Invalidate any `proc_macro2::Span` that exist on the current thread. -/// -/// The implementation of `Span` uses thread-local data structures and this -/// function clears them. Calling any method on a `Span` on the current thread -/// created prior to the invalidation will return incorrect values or crash. -/// -/// This function is useful for programs that process more than 232 -/// bytes of Rust source code on the same thread. Just like rustc, proc-macro2 -/// uses 32-bit source locations, and these wrap around when the total source -/// code processed by the same thread exceeds 232 bytes (4 -/// gigabytes). After a wraparound, `Span` methods such as `source_text()` can -/// return wrong data. -/// -/// # Example -/// -/// As of late 2023, there is 200 GB of Rust code published on crates.io. -/// Looking at just the newest version of every crate, it is 16 GB of code. So a -/// workload that involves parsing it all would overflow a 32-bit source -/// location unless spans are being invalidated. -/// -/// ``` -/// use flate2::read::GzDecoder; -/// use std::ffi::OsStr; -/// use std::io::{BufReader, Read}; -/// use std::str::FromStr; -/// use tar::Archive; -/// -/// rayon::scope(|s| { -/// for krate in every_version_of_every_crate() { -/// s.spawn(move |_| { -/// proc_macro2::extra::invalidate_current_thread_spans(); -/// -/// let reader = BufReader::new(krate); -/// let tar = GzDecoder::new(reader); -/// let mut archive = Archive::new(tar); -/// for entry in archive.entries().unwrap() { -/// let mut entry = entry.unwrap(); -/// let path = entry.path().unwrap(); -/// if path.extension() != Some(OsStr::new("rs")) { -/// continue; -/// } -/// let mut content = String::new(); -/// entry.read_to_string(&mut content).unwrap(); -/// match proc_macro2::TokenStream::from_str(&content) { -/// Ok(tokens) => {/* ... */}, -/// Err(_) => continue, -/// } -/// } -/// }); -/// } -/// }); -/// # -/// # fn every_version_of_every_crate() -> Vec { -/// # Vec::new() -/// # } -/// ``` -/// -/// # Panics -/// -/// This function is not applicable to and will panic if called from a -/// procedural macro. -#[cfg(span_locations)] -#[cfg_attr(doc_cfg, doc(cfg(feature = "span-locations")))] -pub fn invalidate_current_thread_spans() { - crate::imp::invalidate_current_thread_spans(); -} - -/// An object that holds a [`Group`]'s `span_open()` and `span_close()` together -/// in a more compact representation than holding those 2 spans individually. -/// -/// [`Group`]: crate::Group -#[derive(Copy, Clone)] -pub struct DelimSpan { - inner: DelimSpanEnum, - _marker: ProcMacroAutoTraits, -} - -#[derive(Copy, Clone)] -enum DelimSpanEnum { - #[cfg(wrap_proc_macro)] - Compiler { - join: proc_macro::Span, - open: proc_macro::Span, - close: proc_macro::Span, - }, - Fallback(fallback::Span), -} - -impl DelimSpan { - pub(crate) fn new(group: &imp::Group) -> Self { - #[cfg(wrap_proc_macro)] - let inner = match group { - imp::Group::Compiler(group) => DelimSpanEnum::Compiler { - join: group.span(), - open: group.span_open(), - close: group.span_close(), - }, - imp::Group::Fallback(group) => DelimSpanEnum::Fallback(group.span()), - }; - - #[cfg(not(wrap_proc_macro))] - let inner = DelimSpanEnum::Fallback(group.span()); - - DelimSpan { - inner, - _marker: MARKER, - } - } - - /// Returns a span covering the entire delimited group. - pub fn join(&self) -> Span { - match &self.inner { - #[cfg(wrap_proc_macro)] - DelimSpanEnum::Compiler { join, .. } => Span::_new(imp::Span::Compiler(*join)), - DelimSpanEnum::Fallback(span) => Span::_new_fallback(*span), - } - } - - /// Returns a span for the opening punctuation of the group only. - pub fn open(&self) -> Span { - match &self.inner { - #[cfg(wrap_proc_macro)] - DelimSpanEnum::Compiler { open, .. } => Span::_new(imp::Span::Compiler(*open)), - DelimSpanEnum::Fallback(span) => Span::_new_fallback(span.first_byte()), - } - } - - /// Returns a span for the closing punctuation of the group only. - pub fn close(&self) -> Span { - match &self.inner { - #[cfg(wrap_proc_macro)] - DelimSpanEnum::Compiler { close, .. } => Span::_new(imp::Span::Compiler(*close)), - DelimSpanEnum::Fallback(span) => Span::_new_fallback(span.last_byte()), - } - } -} - -impl Debug for DelimSpan { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - Debug::fmt(&self.join(), f) - } -} diff --git a/third-party/vendor/proc-macro2/src/fallback.rs b/third-party/vendor/proc-macro2/src/fallback.rs deleted file mode 100644 index 16bf645c..00000000 --- a/third-party/vendor/proc-macro2/src/fallback.rs +++ /dev/null @@ -1,1170 +0,0 @@ -#[cfg(span_locations)] -use crate::location::LineColumn; -use crate::parse::{self, Cursor}; -use crate::rcvec::{RcVec, RcVecBuilder, RcVecIntoIter, RcVecMut}; -use crate::{Delimiter, Spacing, TokenTree}; -#[cfg(all(span_locations, not(fuzzing)))] -use alloc::collections::BTreeMap; -#[cfg(all(span_locations, not(fuzzing)))] -use core::cell::RefCell; -#[cfg(span_locations)] -use core::cmp; -use core::fmt::{self, Debug, Display, Write}; -use core::mem::ManuallyDrop; -#[cfg(span_locations)] -use core::ops::Range; -use core::ops::RangeBounds; -use core::ptr; -use core::str::FromStr; -use std::path::PathBuf; - -/// Force use of proc-macro2's fallback implementation of the API for now, even -/// if the compiler's implementation is available. -pub fn force() { - #[cfg(wrap_proc_macro)] - crate::detection::force_fallback(); -} - -/// Resume using the compiler's implementation of the proc macro API if it is -/// available. -pub fn unforce() { - #[cfg(wrap_proc_macro)] - crate::detection::unforce_fallback(); -} - -#[derive(Clone)] -pub(crate) struct TokenStream { - inner: RcVec, -} - -#[derive(Debug)] -pub(crate) struct LexError { - pub(crate) span: Span, -} - -impl LexError { - pub(crate) fn span(&self) -> Span { - self.span - } - - pub(crate) fn call_site() -> Self { - LexError { - span: Span::call_site(), - } - } -} - -impl TokenStream { - pub fn new() -> Self { - TokenStream { - inner: RcVecBuilder::new().build(), - } - } - - pub fn is_empty(&self) -> bool { - self.inner.len() == 0 - } - - fn take_inner(self) -> RcVecBuilder { - let nodrop = ManuallyDrop::new(self); - unsafe { ptr::read(&nodrop.inner) }.make_owned() - } -} - -fn push_token_from_proc_macro(mut vec: RcVecMut, token: TokenTree) { - // https://github.com/dtolnay/proc-macro2/issues/235 - match token { - TokenTree::Literal(crate::Literal { - #[cfg(wrap_proc_macro)] - inner: crate::imp::Literal::Fallback(literal), - #[cfg(not(wrap_proc_macro))] - inner: literal, - .. - }) if literal.repr.starts_with('-') => { - push_negative_literal(vec, literal); - } - _ => vec.push(token), - } - - #[cold] - fn push_negative_literal(mut vec: RcVecMut, mut literal: Literal) { - literal.repr.remove(0); - let mut punct = crate::Punct::new('-', Spacing::Alone); - punct.set_span(crate::Span::_new_fallback(literal.span)); - vec.push(TokenTree::Punct(punct)); - vec.push(TokenTree::Literal(crate::Literal::_new_fallback(literal))); - } -} - -// Nonrecursive to prevent stack overflow. -impl Drop for TokenStream { - fn drop(&mut self) { - let mut inner = match self.inner.get_mut() { - Some(inner) => inner, - None => return, - }; - while let Some(token) = inner.pop() { - let group = match token { - TokenTree::Group(group) => group.inner, - _ => continue, - }; - #[cfg(wrap_proc_macro)] - let group = match group { - crate::imp::Group::Fallback(group) => group, - crate::imp::Group::Compiler(_) => continue, - }; - inner.extend(group.stream.take_inner()); - } - } -} - -pub(crate) struct TokenStreamBuilder { - inner: RcVecBuilder, -} - -impl TokenStreamBuilder { - pub fn new() -> Self { - TokenStreamBuilder { - inner: RcVecBuilder::new(), - } - } - - pub fn with_capacity(cap: usize) -> Self { - TokenStreamBuilder { - inner: RcVecBuilder::with_capacity(cap), - } - } - - pub fn push_token_from_parser(&mut self, tt: TokenTree) { - self.inner.push(tt); - } - - pub fn build(self) -> TokenStream { - TokenStream { - inner: self.inner.build(), - } - } -} - -#[cfg(span_locations)] -fn get_cursor(src: &str) -> Cursor { - #[cfg(fuzzing)] - return Cursor { rest: src, off: 1 }; - - // Create a dummy file & add it to the source map - #[cfg(not(fuzzing))] - SOURCE_MAP.with(|sm| { - let mut sm = sm.borrow_mut(); - let span = sm.add_file(src); - Cursor { - rest: src, - off: span.lo, - } - }) -} - -#[cfg(not(span_locations))] -fn get_cursor(src: &str) -> Cursor { - Cursor { rest: src } -} - -impl FromStr for TokenStream { - type Err = LexError; - - fn from_str(src: &str) -> Result { - // Create a dummy file & add it to the source map - let mut cursor = get_cursor(src); - - // Strip a byte order mark if present - const BYTE_ORDER_MARK: &str = "\u{feff}"; - if cursor.starts_with(BYTE_ORDER_MARK) { - cursor = cursor.advance(BYTE_ORDER_MARK.len()); - } - - parse::token_stream(cursor) - } -} - -impl Display for LexError { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - f.write_str("cannot parse string into token stream") - } -} - -impl Display for TokenStream { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - let mut joint = false; - for (i, tt) in self.inner.iter().enumerate() { - if i != 0 && !joint { - write!(f, " ")?; - } - joint = false; - match tt { - TokenTree::Group(tt) => Display::fmt(tt, f), - TokenTree::Ident(tt) => Display::fmt(tt, f), - TokenTree::Punct(tt) => { - joint = tt.spacing() == Spacing::Joint; - Display::fmt(tt, f) - } - TokenTree::Literal(tt) => Display::fmt(tt, f), - }?; - } - - Ok(()) - } -} - -impl Debug for TokenStream { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - f.write_str("TokenStream ")?; - f.debug_list().entries(self.clone()).finish() - } -} - -#[cfg(feature = "proc-macro")] -impl From for TokenStream { - fn from(inner: proc_macro::TokenStream) -> Self { - inner - .to_string() - .parse() - .expect("compiler token stream parse failed") - } -} - -#[cfg(feature = "proc-macro")] -impl From for proc_macro::TokenStream { - fn from(inner: TokenStream) -> Self { - inner - .to_string() - .parse() - .expect("failed to parse to compiler tokens") - } -} - -impl From for TokenStream { - fn from(tree: TokenTree) -> Self { - let mut stream = RcVecBuilder::new(); - push_token_from_proc_macro(stream.as_mut(), tree); - TokenStream { - inner: stream.build(), - } - } -} - -impl FromIterator for TokenStream { - fn from_iter>(tokens: I) -> Self { - let mut stream = TokenStream::new(); - stream.extend(tokens); - stream - } -} - -impl FromIterator for TokenStream { - fn from_iter>(streams: I) -> Self { - let mut v = RcVecBuilder::new(); - - for stream in streams { - v.extend(stream.take_inner()); - } - - TokenStream { inner: v.build() } - } -} - -impl Extend for TokenStream { - fn extend>(&mut self, tokens: I) { - let mut vec = self.inner.make_mut(); - tokens - .into_iter() - .for_each(|token| push_token_from_proc_macro(vec.as_mut(), token)); - } -} - -impl Extend for TokenStream { - fn extend>(&mut self, streams: I) { - self.inner.make_mut().extend(streams.into_iter().flatten()); - } -} - -pub(crate) type TokenTreeIter = RcVecIntoIter; - -impl IntoIterator for TokenStream { - type Item = TokenTree; - type IntoIter = TokenTreeIter; - - fn into_iter(self) -> TokenTreeIter { - self.take_inner().into_iter() - } -} - -#[derive(Clone, PartialEq, Eq)] -pub(crate) struct SourceFile { - path: PathBuf, -} - -impl SourceFile { - /// Get the path to this source file as a string. - pub fn path(&self) -> PathBuf { - self.path.clone() - } - - pub fn is_real(&self) -> bool { - false - } -} - -impl Debug for SourceFile { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - f.debug_struct("SourceFile") - .field("path", &self.path()) - .field("is_real", &self.is_real()) - .finish() - } -} - -#[cfg(all(span_locations, not(fuzzing)))] -thread_local! { - static SOURCE_MAP: RefCell = RefCell::new(SourceMap { - // Start with a single dummy file which all call_site() and def_site() - // spans reference. - files: vec![FileInfo { - source_text: String::new(), - span: Span { lo: 0, hi: 0 }, - lines: vec![0], - char_index_to_byte_offset: BTreeMap::new(), - }], - }); -} - -#[cfg(span_locations)] -pub(crate) fn invalidate_current_thread_spans() { - #[cfg(not(fuzzing))] - SOURCE_MAP.with(|sm| sm.borrow_mut().files.truncate(1)); -} - -#[cfg(all(span_locations, not(fuzzing)))] -struct FileInfo { - source_text: String, - span: Span, - lines: Vec, - char_index_to_byte_offset: BTreeMap, -} - -#[cfg(all(span_locations, not(fuzzing)))] -impl FileInfo { - fn offset_line_column(&self, offset: usize) -> LineColumn { - assert!(self.span_within(Span { - lo: offset as u32, - hi: offset as u32, - })); - let offset = offset - self.span.lo as usize; - match self.lines.binary_search(&offset) { - Ok(found) => LineColumn { - line: found + 1, - column: 0, - }, - Err(idx) => LineColumn { - line: idx, - column: offset - self.lines[idx - 1], - }, - } - } - - fn span_within(&self, span: Span) -> bool { - span.lo >= self.span.lo && span.hi <= self.span.hi - } - - fn byte_range(&mut self, span: Span) -> Range { - let lo_char = (span.lo - self.span.lo) as usize; - - // Look up offset of the largest already-computed char index that is - // less than or equal to the current requested one. We resume counting - // chars from that point. - let (&last_char_index, &last_byte_offset) = self - .char_index_to_byte_offset - .range(..=lo_char) - .next_back() - .unwrap_or((&0, &0)); - - let lo_byte = if last_char_index == lo_char { - last_byte_offset - } else { - let total_byte_offset = match self.source_text[last_byte_offset..] - .char_indices() - .nth(lo_char - last_char_index) - { - Some((additional_offset, _ch)) => last_byte_offset + additional_offset, - None => self.source_text.len(), - }; - self.char_index_to_byte_offset - .insert(lo_char, total_byte_offset); - total_byte_offset - }; - - let trunc_lo = &self.source_text[lo_byte..]; - let char_len = (span.hi - span.lo) as usize; - lo_byte..match trunc_lo.char_indices().nth(char_len) { - Some((offset, _ch)) => lo_byte + offset, - None => self.source_text.len(), - } - } - - fn source_text(&mut self, span: Span) -> String { - let byte_range = self.byte_range(span); - self.source_text[byte_range].to_owned() - } -} - -/// Computes the offsets of each line in the given source string -/// and the total number of characters -#[cfg(all(span_locations, not(fuzzing)))] -fn lines_offsets(s: &str) -> (usize, Vec) { - let mut lines = vec![0]; - let mut total = 0; - - for ch in s.chars() { - total += 1; - if ch == '\n' { - lines.push(total); - } - } - - (total, lines) -} - -#[cfg(all(span_locations, not(fuzzing)))] -struct SourceMap { - files: Vec, -} - -#[cfg(all(span_locations, not(fuzzing)))] -impl SourceMap { - fn next_start_pos(&self) -> u32 { - // Add 1 so there's always space between files. - // - // We'll always have at least 1 file, as we initialize our files list - // with a dummy file. - self.files.last().unwrap().span.hi + 1 - } - - fn add_file(&mut self, src: &str) -> Span { - let (len, lines) = lines_offsets(src); - let lo = self.next_start_pos(); - let span = Span { - lo, - hi: lo + (len as u32), - }; - - self.files.push(FileInfo { - source_text: src.to_owned(), - span, - lines, - // Populated lazily by source_text(). - char_index_to_byte_offset: BTreeMap::new(), - }); - - span - } - - #[cfg(procmacro2_semver_exempt)] - fn filepath(&self, span: Span) -> PathBuf { - for (i, file) in self.files.iter().enumerate() { - if file.span_within(span) { - return PathBuf::from(if i == 0 { - "".to_owned() - } else { - format!("", i) - }); - } - } - unreachable!("Invalid span with no related FileInfo!"); - } - - fn fileinfo(&self, span: Span) -> &FileInfo { - for file in &self.files { - if file.span_within(span) { - return file; - } - } - unreachable!("Invalid span with no related FileInfo!"); - } - - fn fileinfo_mut(&mut self, span: Span) -> &mut FileInfo { - for file in &mut self.files { - if file.span_within(span) { - return file; - } - } - unreachable!("Invalid span with no related FileInfo!"); - } -} - -#[derive(Clone, Copy, PartialEq, Eq)] -pub(crate) struct Span { - #[cfg(span_locations)] - pub(crate) lo: u32, - #[cfg(span_locations)] - pub(crate) hi: u32, -} - -impl Span { - #[cfg(not(span_locations))] - pub fn call_site() -> Self { - Span {} - } - - #[cfg(span_locations)] - pub fn call_site() -> Self { - Span { lo: 0, hi: 0 } - } - - pub fn mixed_site() -> Self { - Span::call_site() - } - - #[cfg(procmacro2_semver_exempt)] - pub fn def_site() -> Self { - Span::call_site() - } - - pub fn resolved_at(&self, _other: Span) -> Span { - // Stable spans consist only of line/column information, so - // `resolved_at` and `located_at` only select which span the - // caller wants line/column information from. - *self - } - - pub fn located_at(&self, other: Span) -> Span { - other - } - - #[cfg(procmacro2_semver_exempt)] - pub fn source_file(&self) -> SourceFile { - #[cfg(fuzzing)] - return SourceFile { - path: PathBuf::from(""), - }; - - #[cfg(not(fuzzing))] - SOURCE_MAP.with(|sm| { - let sm = sm.borrow(); - let path = sm.filepath(*self); - SourceFile { path } - }) - } - - #[cfg(span_locations)] - pub fn byte_range(&self) -> Range { - #[cfg(fuzzing)] - return 0..0; - - #[cfg(not(fuzzing))] - { - if self.is_call_site() { - 0..0 - } else { - SOURCE_MAP.with(|sm| sm.borrow_mut().fileinfo_mut(*self).byte_range(*self)) - } - } - } - - #[cfg(span_locations)] - pub fn start(&self) -> LineColumn { - #[cfg(fuzzing)] - return LineColumn { line: 0, column: 0 }; - - #[cfg(not(fuzzing))] - SOURCE_MAP.with(|sm| { - let sm = sm.borrow(); - let fi = sm.fileinfo(*self); - fi.offset_line_column(self.lo as usize) - }) - } - - #[cfg(span_locations)] - pub fn end(&self) -> LineColumn { - #[cfg(fuzzing)] - return LineColumn { line: 0, column: 0 }; - - #[cfg(not(fuzzing))] - SOURCE_MAP.with(|sm| { - let sm = sm.borrow(); - let fi = sm.fileinfo(*self); - fi.offset_line_column(self.hi as usize) - }) - } - - #[cfg(not(span_locations))] - pub fn join(&self, _other: Span) -> Option { - Some(Span {}) - } - - #[cfg(span_locations)] - pub fn join(&self, other: Span) -> Option { - #[cfg(fuzzing)] - return { - let _ = other; - None - }; - - #[cfg(not(fuzzing))] - SOURCE_MAP.with(|sm| { - let sm = sm.borrow(); - // If `other` is not within the same FileInfo as us, return None. - if !sm.fileinfo(*self).span_within(other) { - return None; - } - Some(Span { - lo: cmp::min(self.lo, other.lo), - hi: cmp::max(self.hi, other.hi), - }) - }) - } - - #[cfg(not(span_locations))] - pub fn source_text(&self) -> Option { - None - } - - #[cfg(span_locations)] - pub fn source_text(&self) -> Option { - #[cfg(fuzzing)] - return None; - - #[cfg(not(fuzzing))] - { - if self.is_call_site() { - None - } else { - Some(SOURCE_MAP.with(|sm| sm.borrow_mut().fileinfo_mut(*self).source_text(*self))) - } - } - } - - #[cfg(not(span_locations))] - pub(crate) fn first_byte(self) -> Self { - self - } - - #[cfg(span_locations)] - pub(crate) fn first_byte(self) -> Self { - Span { - lo: self.lo, - hi: cmp::min(self.lo.saturating_add(1), self.hi), - } - } - - #[cfg(not(span_locations))] - pub(crate) fn last_byte(self) -> Self { - self - } - - #[cfg(span_locations)] - pub(crate) fn last_byte(self) -> Self { - Span { - lo: cmp::max(self.hi.saturating_sub(1), self.lo), - hi: self.hi, - } - } - - #[cfg(span_locations)] - fn is_call_site(&self) -> bool { - self.lo == 0 && self.hi == 0 - } -} - -impl Debug for Span { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - #[cfg(span_locations)] - return write!(f, "bytes({}..{})", self.lo, self.hi); - - #[cfg(not(span_locations))] - write!(f, "Span") - } -} - -pub(crate) fn debug_span_field_if_nontrivial(debug: &mut fmt::DebugStruct, span: Span) { - #[cfg(span_locations)] - { - if span.is_call_site() { - return; - } - } - - if cfg!(span_locations) { - debug.field("span", &span); - } -} - -#[derive(Clone)] -pub(crate) struct Group { - delimiter: Delimiter, - stream: TokenStream, - span: Span, -} - -impl Group { - pub fn new(delimiter: Delimiter, stream: TokenStream) -> Self { - Group { - delimiter, - stream, - span: Span::call_site(), - } - } - - pub fn delimiter(&self) -> Delimiter { - self.delimiter - } - - pub fn stream(&self) -> TokenStream { - self.stream.clone() - } - - pub fn span(&self) -> Span { - self.span - } - - pub fn span_open(&self) -> Span { - self.span.first_byte() - } - - pub fn span_close(&self) -> Span { - self.span.last_byte() - } - - pub fn set_span(&mut self, span: Span) { - self.span = span; - } -} - -impl Display for Group { - // We attempt to match libproc_macro's formatting. - // Empty parens: () - // Nonempty parens: (...) - // Empty brackets: [] - // Nonempty brackets: [...] - // Empty braces: { } - // Nonempty braces: { ... } - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - let (open, close) = match self.delimiter { - Delimiter::Parenthesis => ("(", ")"), - Delimiter::Brace => ("{ ", "}"), - Delimiter::Bracket => ("[", "]"), - Delimiter::None => ("", ""), - }; - - f.write_str(open)?; - Display::fmt(&self.stream, f)?; - if self.delimiter == Delimiter::Brace && !self.stream.inner.is_empty() { - f.write_str(" ")?; - } - f.write_str(close)?; - - Ok(()) - } -} - -impl Debug for Group { - fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { - let mut debug = fmt.debug_struct("Group"); - debug.field("delimiter", &self.delimiter); - debug.field("stream", &self.stream); - debug_span_field_if_nontrivial(&mut debug, self.span); - debug.finish() - } -} - -#[derive(Clone)] -pub(crate) struct Ident { - sym: String, - span: Span, - raw: bool, -} - -impl Ident { - #[track_caller] - pub fn new_checked(string: &str, span: Span) -> Self { - validate_ident(string); - Ident::new_unchecked(string, span) - } - - pub fn new_unchecked(string: &str, span: Span) -> Self { - Ident { - sym: string.to_owned(), - span, - raw: false, - } - } - - #[track_caller] - pub fn new_raw_checked(string: &str, span: Span) -> Self { - validate_ident_raw(string); - Ident::new_raw_unchecked(string, span) - } - - pub fn new_raw_unchecked(string: &str, span: Span) -> Self { - Ident { - sym: string.to_owned(), - span, - raw: true, - } - } - - pub fn span(&self) -> Span { - self.span - } - - pub fn set_span(&mut self, span: Span) { - self.span = span; - } -} - -pub(crate) fn is_ident_start(c: char) -> bool { - c == '_' || unicode_ident::is_xid_start(c) -} - -pub(crate) fn is_ident_continue(c: char) -> bool { - unicode_ident::is_xid_continue(c) -} - -#[track_caller] -fn validate_ident(string: &str) { - if string.is_empty() { - panic!("Ident is not allowed to be empty; use Option"); - } - - if string.bytes().all(|digit| b'0' <= digit && digit <= b'9') { - panic!("Ident cannot be a number; use Literal instead"); - } - - fn ident_ok(string: &str) -> bool { - let mut chars = string.chars(); - let first = chars.next().unwrap(); - if !is_ident_start(first) { - return false; - } - for ch in chars { - if !is_ident_continue(ch) { - return false; - } - } - true - } - - if !ident_ok(string) { - panic!("{:?} is not a valid Ident", string); - } -} - -#[track_caller] -fn validate_ident_raw(string: &str) { - validate_ident(string); - - match string { - "_" | "super" | "self" | "Self" | "crate" => { - panic!("`r#{}` cannot be a raw identifier", string); - } - _ => {} - } -} - -impl PartialEq for Ident { - fn eq(&self, other: &Ident) -> bool { - self.sym == other.sym && self.raw == other.raw - } -} - -impl PartialEq for Ident -where - T: ?Sized + AsRef, -{ - fn eq(&self, other: &T) -> bool { - let other = other.as_ref(); - if self.raw { - other.starts_with("r#") && self.sym == other[2..] - } else { - self.sym == other - } - } -} - -impl Display for Ident { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - if self.raw { - f.write_str("r#")?; - } - Display::fmt(&self.sym, f) - } -} - -#[allow(clippy::missing_fields_in_debug)] -impl Debug for Ident { - // Ident(proc_macro), Ident(r#union) - #[cfg(not(span_locations))] - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - let mut debug = f.debug_tuple("Ident"); - debug.field(&format_args!("{}", self)); - debug.finish() - } - - // Ident { - // sym: proc_macro, - // span: bytes(128..138) - // } - #[cfg(span_locations)] - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - let mut debug = f.debug_struct("Ident"); - debug.field("sym", &format_args!("{}", self)); - debug_span_field_if_nontrivial(&mut debug, self.span); - debug.finish() - } -} - -#[derive(Clone)] -pub(crate) struct Literal { - repr: String, - span: Span, -} - -macro_rules! suffixed_numbers { - ($($name:ident => $kind:ident,)*) => ($( - pub fn $name(n: $kind) -> Literal { - Literal::_new(format!(concat!("{}", stringify!($kind)), n)) - } - )*) -} - -macro_rules! unsuffixed_numbers { - ($($name:ident => $kind:ident,)*) => ($( - pub fn $name(n: $kind) -> Literal { - Literal::_new(n.to_string()) - } - )*) -} - -impl Literal { - pub(crate) fn _new(repr: String) -> Self { - Literal { - repr, - span: Span::call_site(), - } - } - - pub(crate) unsafe fn from_str_unchecked(repr: &str) -> Self { - Literal::_new(repr.to_owned()) - } - - suffixed_numbers! { - u8_suffixed => u8, - u16_suffixed => u16, - u32_suffixed => u32, - u64_suffixed => u64, - u128_suffixed => u128, - usize_suffixed => usize, - i8_suffixed => i8, - i16_suffixed => i16, - i32_suffixed => i32, - i64_suffixed => i64, - i128_suffixed => i128, - isize_suffixed => isize, - - f32_suffixed => f32, - f64_suffixed => f64, - } - - unsuffixed_numbers! { - u8_unsuffixed => u8, - u16_unsuffixed => u16, - u32_unsuffixed => u32, - u64_unsuffixed => u64, - u128_unsuffixed => u128, - usize_unsuffixed => usize, - i8_unsuffixed => i8, - i16_unsuffixed => i16, - i32_unsuffixed => i32, - i64_unsuffixed => i64, - i128_unsuffixed => i128, - isize_unsuffixed => isize, - } - - pub fn f32_unsuffixed(f: f32) -> Literal { - let mut s = f.to_string(); - if !s.contains('.') { - s.push_str(".0"); - } - Literal::_new(s) - } - - pub fn f64_unsuffixed(f: f64) -> Literal { - let mut s = f.to_string(); - if !s.contains('.') { - s.push_str(".0"); - } - Literal::_new(s) - } - - pub fn string(t: &str) -> Literal { - let mut repr = String::with_capacity(t.len() + 2); - repr.push('"'); - let mut chars = t.chars(); - while let Some(ch) = chars.next() { - if ch == '\0' { - repr.push_str( - if chars - .as_str() - .starts_with(|next| '0' <= next && next <= '7') - { - // circumvent clippy::octal_escapes lint - "\\x00" - } else { - "\\0" - }, - ); - } else if ch == '\'' { - // escape_debug turns this into "\'" which is unnecessary. - repr.push(ch); - } else { - repr.extend(ch.escape_debug()); - } - } - repr.push('"'); - Literal::_new(repr) - } - - pub fn character(t: char) -> Literal { - let mut repr = String::new(); - repr.push('\''); - if t == '"' { - // escape_debug turns this into '\"' which is unnecessary. - repr.push(t); - } else { - repr.extend(t.escape_debug()); - } - repr.push('\''); - Literal::_new(repr) - } - - pub fn byte_string(bytes: &[u8]) -> Literal { - let mut escaped = "b\"".to_string(); - let mut bytes = bytes.iter(); - while let Some(&b) = bytes.next() { - #[allow(clippy::match_overlapping_arm)] - match b { - b'\0' => escaped.push_str(match bytes.as_slice().first() { - // circumvent clippy::octal_escapes lint - Some(b'0'..=b'7') => r"\x00", - _ => r"\0", - }), - b'\t' => escaped.push_str(r"\t"), - b'\n' => escaped.push_str(r"\n"), - b'\r' => escaped.push_str(r"\r"), - b'"' => escaped.push_str("\\\""), - b'\\' => escaped.push_str("\\\\"), - b'\x20'..=b'\x7E' => escaped.push(b as char), - _ => { - let _ = write!(escaped, "\\x{:02X}", b); - } - } - } - escaped.push('"'); - Literal::_new(escaped) - } - - pub fn span(&self) -> Span { - self.span - } - - pub fn set_span(&mut self, span: Span) { - self.span = span; - } - - pub fn subspan>(&self, range: R) -> Option { - #[cfg(not(span_locations))] - { - let _ = range; - None - } - - #[cfg(span_locations)] - { - use core::ops::Bound; - - let lo = match range.start_bound() { - Bound::Included(start) => { - let start = u32::try_from(*start).ok()?; - self.span.lo.checked_add(start)? - } - Bound::Excluded(start) => { - let start = u32::try_from(*start).ok()?; - self.span.lo.checked_add(start)?.checked_add(1)? - } - Bound::Unbounded => self.span.lo, - }; - let hi = match range.end_bound() { - Bound::Included(end) => { - let end = u32::try_from(*end).ok()?; - self.span.lo.checked_add(end)?.checked_add(1)? - } - Bound::Excluded(end) => { - let end = u32::try_from(*end).ok()?; - self.span.lo.checked_add(end)? - } - Bound::Unbounded => self.span.hi, - }; - if lo <= hi && hi <= self.span.hi { - Some(Span { lo, hi }) - } else { - None - } - } - } -} - -impl FromStr for Literal { - type Err = LexError; - - fn from_str(repr: &str) -> Result { - let mut cursor = get_cursor(repr); - #[cfg(span_locations)] - let lo = cursor.off; - - let negative = cursor.starts_with_char('-'); - if negative { - cursor = cursor.advance(1); - if !cursor.starts_with_fn(|ch| ch.is_ascii_digit()) { - return Err(LexError::call_site()); - } - } - - if let Ok((rest, mut literal)) = parse::literal(cursor) { - if rest.is_empty() { - if negative { - literal.repr.insert(0, '-'); - } - literal.span = Span { - #[cfg(span_locations)] - lo, - #[cfg(span_locations)] - hi: rest.off, - }; - return Ok(literal); - } - } - Err(LexError::call_site()) - } -} - -impl Display for Literal { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - Display::fmt(&self.repr, f) - } -} - -impl Debug for Literal { - fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { - let mut debug = fmt.debug_struct("Literal"); - debug.field("lit", &format_args!("{}", self.repr)); - debug_span_field_if_nontrivial(&mut debug, self.span); - debug.finish() - } -} diff --git a/third-party/vendor/proc-macro2/src/lib.rs b/third-party/vendor/proc-macro2/src/lib.rs deleted file mode 100644 index 01f2049c..00000000 --- a/third-party/vendor/proc-macro2/src/lib.rs +++ /dev/null @@ -1,1345 +0,0 @@ -//! [![github]](https://github.com/dtolnay/proc-macro2) [![crates-io]](https://crates.io/crates/proc-macro2) [![docs-rs]](crate) -//! -//! [github]: https://img.shields.io/badge/github-8da0cb?style=for-the-badge&labelColor=555555&logo=github -//! [crates-io]: https://img.shields.io/badge/crates.io-fc8d62?style=for-the-badge&labelColor=555555&logo=rust -//! [docs-rs]: https://img.shields.io/badge/docs.rs-66c2a5?style=for-the-badge&labelColor=555555&logo=docs.rs -//! -//!
-//! -//! A wrapper around the procedural macro API of the compiler's [`proc_macro`] -//! crate. This library serves two purposes: -//! -//! [`proc_macro`]: https://doc.rust-lang.org/proc_macro/ -//! -//! - **Bring proc-macro-like functionality to other contexts like build.rs and -//! main.rs.** Types from `proc_macro` are entirely specific to procedural -//! macros and cannot ever exist in code outside of a procedural macro. -//! Meanwhile `proc_macro2` types may exist anywhere including non-macro code. -//! By developing foundational libraries like [syn] and [quote] against -//! `proc_macro2` rather than `proc_macro`, the procedural macro ecosystem -//! becomes easily applicable to many other use cases and we avoid -//! reimplementing non-macro equivalents of those libraries. -//! -//! - **Make procedural macros unit testable.** As a consequence of being -//! specific to procedural macros, nothing that uses `proc_macro` can be -//! executed from a unit test. In order for helper libraries or components of -//! a macro to be testable in isolation, they must be implemented using -//! `proc_macro2`. -//! -//! [syn]: https://github.com/dtolnay/syn -//! [quote]: https://github.com/dtolnay/quote -//! -//! # Usage -//! -//! The skeleton of a typical procedural macro typically looks like this: -//! -//! ``` -//! extern crate proc_macro; -//! -//! # const IGNORE: &str = stringify! { -//! #[proc_macro_derive(MyDerive)] -//! # }; -//! # #[cfg(wrap_proc_macro)] -//! pub fn my_derive(input: proc_macro::TokenStream) -> proc_macro::TokenStream { -//! let input = proc_macro2::TokenStream::from(input); -//! -//! let output: proc_macro2::TokenStream = { -//! /* transform input */ -//! # input -//! }; -//! -//! proc_macro::TokenStream::from(output) -//! } -//! ``` -//! -//! If parsing with [Syn], you'll use [`parse_macro_input!`] instead to -//! propagate parse errors correctly back to the compiler when parsing fails. -//! -//! [`parse_macro_input!`]: https://docs.rs/syn/2.0/syn/macro.parse_macro_input.html -//! -//! # Unstable features -//! -//! The default feature set of proc-macro2 tracks the most recent stable -//! compiler API. Functionality in `proc_macro` that is not yet stable is not -//! exposed by proc-macro2 by default. -//! -//! To opt into the additional APIs available in the most recent nightly -//! compiler, the `procmacro2_semver_exempt` config flag must be passed to -//! rustc. We will polyfill those nightly-only APIs back to Rust 1.56.0. As -//! these are unstable APIs that track the nightly compiler, minor versions of -//! proc-macro2 may make breaking changes to them at any time. -//! -//! ```sh -//! RUSTFLAGS='--cfg procmacro2_semver_exempt' cargo build -//! ``` -//! -//! Note that this must not only be done for your crate, but for any crate that -//! depends on your crate. This infectious nature is intentional, as it serves -//! as a reminder that you are outside of the normal semver guarantees. -//! -//! Semver exempt methods are marked as such in the proc-macro2 documentation. -//! -//! # Thread-Safety -//! -//! Most types in this crate are `!Sync` because the underlying compiler -//! types make use of thread-local memory, meaning they cannot be accessed from -//! a different thread. - -// Proc-macro2 types in rustdoc of other crates get linked to here. -#![doc(html_root_url = "https://docs.rs/proc-macro2/1.0.78")] -#![cfg_attr(any(proc_macro_span, super_unstable), feature(proc_macro_span))] -#![cfg_attr(super_unstable, feature(proc_macro_def_site))] -#![cfg_attr(doc_cfg, feature(doc_cfg))] -#![deny(unsafe_op_in_unsafe_fn)] -#![allow( - clippy::cast_lossless, - clippy::cast_possible_truncation, - clippy::checked_conversions, - clippy::doc_markdown, - clippy::items_after_statements, - clippy::iter_without_into_iter, - clippy::let_underscore_untyped, - clippy::manual_assert, - clippy::manual_range_contains, - clippy::missing_safety_doc, - clippy::must_use_candidate, - clippy::needless_doctest_main, - clippy::new_without_default, - clippy::return_self_not_must_use, - clippy::shadow_unrelated, - clippy::trivially_copy_pass_by_ref, - clippy::unnecessary_wraps, - clippy::unused_self, - clippy::used_underscore_binding, - clippy::vec_init_then_push -)] - -#[cfg(all(procmacro2_semver_exempt, wrap_proc_macro, not(super_unstable)))] -compile_error! {"\ - Something is not right. If you've tried to turn on \ - procmacro2_semver_exempt, you need to ensure that it \ - is turned on for the compilation of the proc-macro2 \ - build script as well. -"} - -#[cfg(all( - procmacro2_nightly_testing, - feature = "proc-macro", - not(proc_macro_span) -))] -compile_error! {"\ - Build script probe failed to compile. -"} - -extern crate alloc; - -#[cfg(feature = "proc-macro")] -extern crate proc_macro; - -mod marker; -mod parse; -mod rcvec; - -#[cfg(wrap_proc_macro)] -mod detection; - -// Public for proc_macro2::fallback::force() and unforce(), but those are quite -// a niche use case so we omit it from rustdoc. -#[doc(hidden)] -pub mod fallback; - -pub mod extra; - -#[cfg(not(wrap_proc_macro))] -use crate::fallback as imp; -#[path = "wrapper.rs"] -#[cfg(wrap_proc_macro)] -mod imp; - -#[cfg(span_locations)] -mod location; - -use crate::extra::DelimSpan; -use crate::marker::{ProcMacroAutoTraits, MARKER}; -use core::cmp::Ordering; -use core::fmt::{self, Debug, Display}; -use core::hash::{Hash, Hasher}; -#[cfg(span_locations)] -use core::ops::Range; -use core::ops::RangeBounds; -use core::str::FromStr; -use std::error::Error; -#[cfg(procmacro2_semver_exempt)] -use std::path::PathBuf; - -#[cfg(span_locations)] -#[cfg_attr(doc_cfg, doc(cfg(feature = "span-locations")))] -pub use crate::location::LineColumn; - -/// An abstract stream of tokens, or more concretely a sequence of token trees. -/// -/// This type provides interfaces for iterating over token trees and for -/// collecting token trees into one stream. -/// -/// Token stream is both the input and output of `#[proc_macro]`, -/// `#[proc_macro_attribute]` and `#[proc_macro_derive]` definitions. -#[derive(Clone)] -pub struct TokenStream { - inner: imp::TokenStream, - _marker: ProcMacroAutoTraits, -} - -/// Error returned from `TokenStream::from_str`. -pub struct LexError { - inner: imp::LexError, - _marker: ProcMacroAutoTraits, -} - -impl TokenStream { - fn _new(inner: imp::TokenStream) -> Self { - TokenStream { - inner, - _marker: MARKER, - } - } - - fn _new_fallback(inner: fallback::TokenStream) -> Self { - TokenStream { - inner: inner.into(), - _marker: MARKER, - } - } - - /// Returns an empty `TokenStream` containing no token trees. - pub fn new() -> Self { - TokenStream::_new(imp::TokenStream::new()) - } - - /// Checks if this `TokenStream` is empty. - pub fn is_empty(&self) -> bool { - self.inner.is_empty() - } -} - -/// `TokenStream::default()` returns an empty stream, -/// i.e. this is equivalent with `TokenStream::new()`. -impl Default for TokenStream { - fn default() -> Self { - TokenStream::new() - } -} - -/// Attempts to break the string into tokens and parse those tokens into a token -/// stream. -/// -/// May fail for a number of reasons, for example, if the string contains -/// unbalanced delimiters or characters not existing in the language. -/// -/// NOTE: Some errors may cause panics instead of returning `LexError`. We -/// reserve the right to change these errors into `LexError`s later. -impl FromStr for TokenStream { - type Err = LexError; - - fn from_str(src: &str) -> Result { - let e = src.parse().map_err(|e| LexError { - inner: e, - _marker: MARKER, - })?; - Ok(TokenStream::_new(e)) - } -} - -#[cfg(feature = "proc-macro")] -#[cfg_attr(doc_cfg, doc(cfg(feature = "proc-macro")))] -impl From for TokenStream { - fn from(inner: proc_macro::TokenStream) -> Self { - TokenStream::_new(inner.into()) - } -} - -#[cfg(feature = "proc-macro")] -#[cfg_attr(doc_cfg, doc(cfg(feature = "proc-macro")))] -impl From for proc_macro::TokenStream { - fn from(inner: TokenStream) -> Self { - inner.inner.into() - } -} - -impl From for TokenStream { - fn from(token: TokenTree) -> Self { - TokenStream::_new(imp::TokenStream::from(token)) - } -} - -impl Extend for TokenStream { - fn extend>(&mut self, streams: I) { - self.inner.extend(streams); - } -} - -impl Extend for TokenStream { - fn extend>(&mut self, streams: I) { - self.inner - .extend(streams.into_iter().map(|stream| stream.inner)); - } -} - -/// Collects a number of token trees into a single stream. -impl FromIterator for TokenStream { - fn from_iter>(streams: I) -> Self { - TokenStream::_new(streams.into_iter().collect()) - } -} -impl FromIterator for TokenStream { - fn from_iter>(streams: I) -> Self { - TokenStream::_new(streams.into_iter().map(|i| i.inner).collect()) - } -} - -/// Prints the token stream as a string that is supposed to be losslessly -/// convertible back into the same token stream (modulo spans), except for -/// possibly `TokenTree::Group`s with `Delimiter::None` delimiters and negative -/// numeric literals. -impl Display for TokenStream { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - Display::fmt(&self.inner, f) - } -} - -/// Prints token in a form convenient for debugging. -impl Debug for TokenStream { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - Debug::fmt(&self.inner, f) - } -} - -impl LexError { - pub fn span(&self) -> Span { - Span::_new(self.inner.span()) - } -} - -impl Debug for LexError { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - Debug::fmt(&self.inner, f) - } -} - -impl Display for LexError { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - Display::fmt(&self.inner, f) - } -} - -impl Error for LexError {} - -/// The source file of a given `Span`. -/// -/// This type is semver exempt and not exposed by default. -#[cfg(all(procmacro2_semver_exempt, any(not(wrap_proc_macro), super_unstable)))] -#[cfg_attr(doc_cfg, doc(cfg(procmacro2_semver_exempt)))] -#[derive(Clone, PartialEq, Eq)] -pub struct SourceFile { - inner: imp::SourceFile, - _marker: ProcMacroAutoTraits, -} - -#[cfg(all(procmacro2_semver_exempt, any(not(wrap_proc_macro), super_unstable)))] -impl SourceFile { - fn _new(inner: imp::SourceFile) -> Self { - SourceFile { - inner, - _marker: MARKER, - } - } - - /// Get the path to this source file. - /// - /// ### Note - /// - /// If the code span associated with this `SourceFile` was generated by an - /// external macro, this may not be an actual path on the filesystem. Use - /// [`is_real`] to check. - /// - /// Also note that even if `is_real` returns `true`, if - /// `--remap-path-prefix` was passed on the command line, the path as given - /// may not actually be valid. - /// - /// [`is_real`]: #method.is_real - pub fn path(&self) -> PathBuf { - self.inner.path() - } - - /// Returns `true` if this source file is a real source file, and not - /// generated by an external macro's expansion. - pub fn is_real(&self) -> bool { - self.inner.is_real() - } -} - -#[cfg(all(procmacro2_semver_exempt, any(not(wrap_proc_macro), super_unstable)))] -impl Debug for SourceFile { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - Debug::fmt(&self.inner, f) - } -} - -/// A region of source code, along with macro expansion information. -#[derive(Copy, Clone)] -pub struct Span { - inner: imp::Span, - _marker: ProcMacroAutoTraits, -} - -impl Span { - fn _new(inner: imp::Span) -> Self { - Span { - inner, - _marker: MARKER, - } - } - - fn _new_fallback(inner: fallback::Span) -> Self { - Span { - inner: inner.into(), - _marker: MARKER, - } - } - - /// The span of the invocation of the current procedural macro. - /// - /// Identifiers created with this span will be resolved as if they were - /// written directly at the macro call location (call-site hygiene) and - /// other code at the macro call site will be able to refer to them as well. - pub fn call_site() -> Self { - Span::_new(imp::Span::call_site()) - } - - /// The span located at the invocation of the procedural macro, but with - /// local variables, labels, and `$crate` resolved at the definition site - /// of the macro. This is the same hygiene behavior as `macro_rules`. - pub fn mixed_site() -> Self { - Span::_new(imp::Span::mixed_site()) - } - - /// A span that resolves at the macro definition site. - /// - /// This method is semver exempt and not exposed by default. - #[cfg(procmacro2_semver_exempt)] - #[cfg_attr(doc_cfg, doc(cfg(procmacro2_semver_exempt)))] - pub fn def_site() -> Self { - Span::_new(imp::Span::def_site()) - } - - /// Creates a new span with the same line/column information as `self` but - /// that resolves symbols as though it were at `other`. - pub fn resolved_at(&self, other: Span) -> Span { - Span::_new(self.inner.resolved_at(other.inner)) - } - - /// Creates a new span with the same name resolution behavior as `self` but - /// with the line/column information of `other`. - pub fn located_at(&self, other: Span) -> Span { - Span::_new(self.inner.located_at(other.inner)) - } - - /// Convert `proc_macro2::Span` to `proc_macro::Span`. - /// - /// This method is available when building with a nightly compiler, or when - /// building with rustc 1.29+ *without* semver exempt features. - /// - /// # Panics - /// - /// Panics if called from outside of a procedural macro. Unlike - /// `proc_macro2::Span`, the `proc_macro::Span` type can only exist within - /// the context of a procedural macro invocation. - #[cfg(wrap_proc_macro)] - pub fn unwrap(self) -> proc_macro::Span { - self.inner.unwrap() - } - - // Soft deprecated. Please use Span::unwrap. - #[cfg(wrap_proc_macro)] - #[doc(hidden)] - pub fn unstable(self) -> proc_macro::Span { - self.unwrap() - } - - /// The original source file into which this span points. - /// - /// This method is semver exempt and not exposed by default. - #[cfg(all(procmacro2_semver_exempt, any(not(wrap_proc_macro), super_unstable)))] - #[cfg_attr(doc_cfg, doc(cfg(procmacro2_semver_exempt)))] - pub fn source_file(&self) -> SourceFile { - SourceFile::_new(self.inner.source_file()) - } - - /// Returns the span's byte position range in the source file. - /// - /// This method requires the `"span-locations"` feature to be enabled. - /// - /// When executing in a procedural macro context, the returned range is only - /// accurate if compiled with a nightly toolchain. The stable toolchain does - /// not have this information available. When executing outside of a - /// procedural macro, such as main.rs or build.rs, the byte range is always - /// accurate regardless of toolchain. - #[cfg(span_locations)] - #[cfg_attr(doc_cfg, doc(cfg(feature = "span-locations")))] - pub fn byte_range(&self) -> Range { - self.inner.byte_range() - } - - /// Get the starting line/column in the source file for this span. - /// - /// This method requires the `"span-locations"` feature to be enabled. - /// - /// When executing in a procedural macro context, the returned line/column - /// are only meaningful if compiled with a nightly toolchain. The stable - /// toolchain does not have this information available. When executing - /// outside of a procedural macro, such as main.rs or build.rs, the - /// line/column are always meaningful regardless of toolchain. - #[cfg(span_locations)] - #[cfg_attr(doc_cfg, doc(cfg(feature = "span-locations")))] - pub fn start(&self) -> LineColumn { - self.inner.start() - } - - /// Get the ending line/column in the source file for this span. - /// - /// This method requires the `"span-locations"` feature to be enabled. - /// - /// When executing in a procedural macro context, the returned line/column - /// are only meaningful if compiled with a nightly toolchain. The stable - /// toolchain does not have this information available. When executing - /// outside of a procedural macro, such as main.rs or build.rs, the - /// line/column are always meaningful regardless of toolchain. - #[cfg(span_locations)] - #[cfg_attr(doc_cfg, doc(cfg(feature = "span-locations")))] - pub fn end(&self) -> LineColumn { - self.inner.end() - } - - /// Create a new span encompassing `self` and `other`. - /// - /// Returns `None` if `self` and `other` are from different files. - /// - /// Warning: the underlying [`proc_macro::Span::join`] method is - /// nightly-only. When called from within a procedural macro not using a - /// nightly compiler, this method will always return `None`. - /// - /// [`proc_macro::Span::join`]: https://doc.rust-lang.org/proc_macro/struct.Span.html#method.join - pub fn join(&self, other: Span) -> Option { - self.inner.join(other.inner).map(Span::_new) - } - - /// Compares two spans to see if they're equal. - /// - /// This method is semver exempt and not exposed by default. - #[cfg(procmacro2_semver_exempt)] - #[cfg_attr(doc_cfg, doc(cfg(procmacro2_semver_exempt)))] - pub fn eq(&self, other: &Span) -> bool { - self.inner.eq(&other.inner) - } - - /// Returns the source text behind a span. This preserves the original - /// source code, including spaces and comments. It only returns a result if - /// the span corresponds to real source code. - /// - /// Note: The observable result of a macro should only rely on the tokens - /// and not on this source text. The result of this function is a best - /// effort to be used for diagnostics only. - pub fn source_text(&self) -> Option { - self.inner.source_text() - } -} - -/// Prints a span in a form convenient for debugging. -impl Debug for Span { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - Debug::fmt(&self.inner, f) - } -} - -/// A single token or a delimited sequence of token trees (e.g. `[1, (), ..]`). -#[derive(Clone)] -pub enum TokenTree { - /// A token stream surrounded by bracket delimiters. - Group(Group), - /// An identifier. - Ident(Ident), - /// A single punctuation character (`+`, `,`, `$`, etc.). - Punct(Punct), - /// A literal character (`'a'`), string (`"hello"`), number (`2.3`), etc. - Literal(Literal), -} - -impl TokenTree { - /// Returns the span of this tree, delegating to the `span` method of - /// the contained token or a delimited stream. - pub fn span(&self) -> Span { - match self { - TokenTree::Group(t) => t.span(), - TokenTree::Ident(t) => t.span(), - TokenTree::Punct(t) => t.span(), - TokenTree::Literal(t) => t.span(), - } - } - - /// Configures the span for *only this token*. - /// - /// Note that if this token is a `Group` then this method will not configure - /// the span of each of the internal tokens, this will simply delegate to - /// the `set_span` method of each variant. - pub fn set_span(&mut self, span: Span) { - match self { - TokenTree::Group(t) => t.set_span(span), - TokenTree::Ident(t) => t.set_span(span), - TokenTree::Punct(t) => t.set_span(span), - TokenTree::Literal(t) => t.set_span(span), - } - } -} - -impl From for TokenTree { - fn from(g: Group) -> Self { - TokenTree::Group(g) - } -} - -impl From for TokenTree { - fn from(g: Ident) -> Self { - TokenTree::Ident(g) - } -} - -impl From for TokenTree { - fn from(g: Punct) -> Self { - TokenTree::Punct(g) - } -} - -impl From for TokenTree { - fn from(g: Literal) -> Self { - TokenTree::Literal(g) - } -} - -/// Prints the token tree as a string that is supposed to be losslessly -/// convertible back into the same token tree (modulo spans), except for -/// possibly `TokenTree::Group`s with `Delimiter::None` delimiters and negative -/// numeric literals. -impl Display for TokenTree { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - match self { - TokenTree::Group(t) => Display::fmt(t, f), - TokenTree::Ident(t) => Display::fmt(t, f), - TokenTree::Punct(t) => Display::fmt(t, f), - TokenTree::Literal(t) => Display::fmt(t, f), - } - } -} - -/// Prints token tree in a form convenient for debugging. -impl Debug for TokenTree { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - // Each of these has the name in the struct type in the derived debug, - // so don't bother with an extra layer of indirection - match self { - TokenTree::Group(t) => Debug::fmt(t, f), - TokenTree::Ident(t) => { - let mut debug = f.debug_struct("Ident"); - debug.field("sym", &format_args!("{}", t)); - imp::debug_span_field_if_nontrivial(&mut debug, t.span().inner); - debug.finish() - } - TokenTree::Punct(t) => Debug::fmt(t, f), - TokenTree::Literal(t) => Debug::fmt(t, f), - } - } -} - -/// A delimited token stream. -/// -/// A `Group` internally contains a `TokenStream` which is surrounded by -/// `Delimiter`s. -#[derive(Clone)] -pub struct Group { - inner: imp::Group, -} - -/// Describes how a sequence of token trees is delimited. -#[derive(Copy, Clone, Debug, Eq, PartialEq)] -pub enum Delimiter { - /// `( ... )` - Parenthesis, - /// `{ ... }` - Brace, - /// `[ ... ]` - Bracket, - /// `Ø ... Ø` - /// - /// An implicit delimiter, that may, for example, appear around tokens - /// coming from a "macro variable" `$var`. It is important to preserve - /// operator priorities in cases like `$var * 3` where `$var` is `1 + 2`. - /// Implicit delimiters may not survive roundtrip of a token stream through - /// a string. - None, -} - -impl Group { - fn _new(inner: imp::Group) -> Self { - Group { inner } - } - - fn _new_fallback(inner: fallback::Group) -> Self { - Group { - inner: inner.into(), - } - } - - /// Creates a new `Group` with the given delimiter and token stream. - /// - /// This constructor will set the span for this group to - /// `Span::call_site()`. To change the span you can use the `set_span` - /// method below. - pub fn new(delimiter: Delimiter, stream: TokenStream) -> Self { - Group { - inner: imp::Group::new(delimiter, stream.inner), - } - } - - /// Returns the punctuation used as the delimiter for this group: a set of - /// parentheses, square brackets, or curly braces. - pub fn delimiter(&self) -> Delimiter { - self.inner.delimiter() - } - - /// Returns the `TokenStream` of tokens that are delimited in this `Group`. - /// - /// Note that the returned token stream does not include the delimiter - /// returned above. - pub fn stream(&self) -> TokenStream { - TokenStream::_new(self.inner.stream()) - } - - /// Returns the span for the delimiters of this token stream, spanning the - /// entire `Group`. - /// - /// ```text - /// pub fn span(&self) -> Span { - /// ^^^^^^^ - /// ``` - pub fn span(&self) -> Span { - Span::_new(self.inner.span()) - } - - /// Returns the span pointing to the opening delimiter of this group. - /// - /// ```text - /// pub fn span_open(&self) -> Span { - /// ^ - /// ``` - pub fn span_open(&self) -> Span { - Span::_new(self.inner.span_open()) - } - - /// Returns the span pointing to the closing delimiter of this group. - /// - /// ```text - /// pub fn span_close(&self) -> Span { - /// ^ - /// ``` - pub fn span_close(&self) -> Span { - Span::_new(self.inner.span_close()) - } - - /// Returns an object that holds this group's `span_open()` and - /// `span_close()` together (in a more compact representation than holding - /// those 2 spans individually). - pub fn delim_span(&self) -> DelimSpan { - DelimSpan::new(&self.inner) - } - - /// Configures the span for this `Group`'s delimiters, but not its internal - /// tokens. - /// - /// This method will **not** set the span of all the internal tokens spanned - /// by this group, but rather it will only set the span of the delimiter - /// tokens at the level of the `Group`. - pub fn set_span(&mut self, span: Span) { - self.inner.set_span(span.inner); - } -} - -/// Prints the group as a string that should be losslessly convertible back -/// into the same group (modulo spans), except for possibly `TokenTree::Group`s -/// with `Delimiter::None` delimiters. -impl Display for Group { - fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { - Display::fmt(&self.inner, formatter) - } -} - -impl Debug for Group { - fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { - Debug::fmt(&self.inner, formatter) - } -} - -/// A `Punct` is a single punctuation character like `+`, `-` or `#`. -/// -/// Multicharacter operators like `+=` are represented as two instances of -/// `Punct` with different forms of `Spacing` returned. -#[derive(Clone)] -pub struct Punct { - ch: char, - spacing: Spacing, - span: Span, -} - -/// Whether a `Punct` is followed immediately by another `Punct` or followed by -/// another token or whitespace. -#[derive(Copy, Clone, Debug, Eq, PartialEq)] -pub enum Spacing { - /// E.g. `+` is `Alone` in `+ =`, `+ident` or `+()`. - Alone, - /// E.g. `+` is `Joint` in `+=` or `'` is `Joint` in `'#`. - /// - /// Additionally, single quote `'` can join with identifiers to form - /// lifetimes `'ident`. - Joint, -} - -impl Punct { - /// Creates a new `Punct` from the given character and spacing. - /// - /// The `ch` argument must be a valid punctuation character permitted by the - /// language, otherwise the function will panic. - /// - /// The returned `Punct` will have the default span of `Span::call_site()` - /// which can be further configured with the `set_span` method below. - pub fn new(ch: char, spacing: Spacing) -> Self { - Punct { - ch, - spacing, - span: Span::call_site(), - } - } - - /// Returns the value of this punctuation character as `char`. - pub fn as_char(&self) -> char { - self.ch - } - - /// Returns the spacing of this punctuation character, indicating whether - /// it's immediately followed by another `Punct` in the token stream, so - /// they can potentially be combined into a multicharacter operator - /// (`Joint`), or it's followed by some other token or whitespace (`Alone`) - /// so the operator has certainly ended. - pub fn spacing(&self) -> Spacing { - self.spacing - } - - /// Returns the span for this punctuation character. - pub fn span(&self) -> Span { - self.span - } - - /// Configure the span for this punctuation character. - pub fn set_span(&mut self, span: Span) { - self.span = span; - } -} - -/// Prints the punctuation character as a string that should be losslessly -/// convertible back into the same character. -impl Display for Punct { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - Display::fmt(&self.ch, f) - } -} - -impl Debug for Punct { - fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { - let mut debug = fmt.debug_struct("Punct"); - debug.field("char", &self.ch); - debug.field("spacing", &self.spacing); - imp::debug_span_field_if_nontrivial(&mut debug, self.span.inner); - debug.finish() - } -} - -/// A word of Rust code, which may be a keyword or legal variable name. -/// -/// An identifier consists of at least one Unicode code point, the first of -/// which has the XID_Start property and the rest of which have the XID_Continue -/// property. -/// -/// - The empty string is not an identifier. Use `Option`. -/// - A lifetime is not an identifier. Use `syn::Lifetime` instead. -/// -/// An identifier constructed with `Ident::new` is permitted to be a Rust -/// keyword, though parsing one through its [`Parse`] implementation rejects -/// Rust keywords. Use `input.call(Ident::parse_any)` when parsing to match the -/// behaviour of `Ident::new`. -/// -/// [`Parse`]: https://docs.rs/syn/2.0/syn/parse/trait.Parse.html -/// -/// # Examples -/// -/// A new ident can be created from a string using the `Ident::new` function. -/// A span must be provided explicitly which governs the name resolution -/// behavior of the resulting identifier. -/// -/// ``` -/// use proc_macro2::{Ident, Span}; -/// -/// fn main() { -/// let call_ident = Ident::new("calligraphy", Span::call_site()); -/// -/// println!("{}", call_ident); -/// } -/// ``` -/// -/// An ident can be interpolated into a token stream using the `quote!` macro. -/// -/// ``` -/// use proc_macro2::{Ident, Span}; -/// use quote::quote; -/// -/// fn main() { -/// let ident = Ident::new("demo", Span::call_site()); -/// -/// // Create a variable binding whose name is this ident. -/// let expanded = quote! { let #ident = 10; }; -/// -/// // Create a variable binding with a slightly different name. -/// let temp_ident = Ident::new(&format!("new_{}", ident), Span::call_site()); -/// let expanded = quote! { let #temp_ident = 10; }; -/// } -/// ``` -/// -/// A string representation of the ident is available through the `to_string()` -/// method. -/// -/// ``` -/// # use proc_macro2::{Ident, Span}; -/// # -/// # let ident = Ident::new("another_identifier", Span::call_site()); -/// # -/// // Examine the ident as a string. -/// let ident_string = ident.to_string(); -/// if ident_string.len() > 60 { -/// println!("Very long identifier: {}", ident_string) -/// } -/// ``` -#[derive(Clone)] -pub struct Ident { - inner: imp::Ident, - _marker: ProcMacroAutoTraits, -} - -impl Ident { - fn _new(inner: imp::Ident) -> Self { - Ident { - inner, - _marker: MARKER, - } - } - - /// Creates a new `Ident` with the given `string` as well as the specified - /// `span`. - /// - /// The `string` argument must be a valid identifier permitted by the - /// language, otherwise the function will panic. - /// - /// Note that `span`, currently in rustc, configures the hygiene information - /// for this identifier. - /// - /// As of this time `Span::call_site()` explicitly opts-in to "call-site" - /// hygiene meaning that identifiers created with this span will be resolved - /// as if they were written directly at the location of the macro call, and - /// other code at the macro call site will be able to refer to them as well. - /// - /// Later spans like `Span::def_site()` will allow to opt-in to - /// "definition-site" hygiene meaning that identifiers created with this - /// span will be resolved at the location of the macro definition and other - /// code at the macro call site will not be able to refer to them. - /// - /// Due to the current importance of hygiene this constructor, unlike other - /// tokens, requires a `Span` to be specified at construction. - /// - /// # Panics - /// - /// Panics if the input string is neither a keyword nor a legal variable - /// name. If you are not sure whether the string contains an identifier and - /// need to handle an error case, use - /// syn::parse_str::<Ident> - /// rather than `Ident::new`. - #[track_caller] - pub fn new(string: &str, span: Span) -> Self { - Ident::_new(imp::Ident::new_checked(string, span.inner)) - } - - /// Same as `Ident::new`, but creates a raw identifier (`r#ident`). The - /// `string` argument must be a valid identifier permitted by the language - /// (including keywords, e.g. `fn`). Keywords which are usable in path - /// segments (e.g. `self`, `super`) are not supported, and will cause a - /// panic. - #[track_caller] - pub fn new_raw(string: &str, span: Span) -> Self { - Ident::_new(imp::Ident::new_raw_checked(string, span.inner)) - } - - /// Returns the span of this `Ident`. - pub fn span(&self) -> Span { - Span::_new(self.inner.span()) - } - - /// Configures the span of this `Ident`, possibly changing its hygiene - /// context. - pub fn set_span(&mut self, span: Span) { - self.inner.set_span(span.inner); - } -} - -impl PartialEq for Ident { - fn eq(&self, other: &Ident) -> bool { - self.inner == other.inner - } -} - -impl PartialEq for Ident -where - T: ?Sized + AsRef, -{ - fn eq(&self, other: &T) -> bool { - self.inner == other - } -} - -impl Eq for Ident {} - -impl PartialOrd for Ident { - fn partial_cmp(&self, other: &Ident) -> Option { - Some(self.cmp(other)) - } -} - -impl Ord for Ident { - fn cmp(&self, other: &Ident) -> Ordering { - self.to_string().cmp(&other.to_string()) - } -} - -impl Hash for Ident { - fn hash(&self, hasher: &mut H) { - self.to_string().hash(hasher); - } -} - -/// Prints the identifier as a string that should be losslessly convertible back -/// into the same identifier. -impl Display for Ident { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - Display::fmt(&self.inner, f) - } -} - -impl Debug for Ident { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - Debug::fmt(&self.inner, f) - } -} - -/// A literal string (`"hello"`), byte string (`b"hello"`), character (`'a'`), -/// byte character (`b'a'`), an integer or floating point number with or without -/// a suffix (`1`, `1u8`, `2.3`, `2.3f32`). -/// -/// Boolean literals like `true` and `false` do not belong here, they are -/// `Ident`s. -#[derive(Clone)] -pub struct Literal { - inner: imp::Literal, - _marker: ProcMacroAutoTraits, -} - -macro_rules! suffixed_int_literals { - ($($name:ident => $kind:ident,)*) => ($( - /// Creates a new suffixed integer literal with the specified value. - /// - /// This function will create an integer like `1u32` where the integer - /// value specified is the first part of the token and the integral is - /// also suffixed at the end. Literals created from negative numbers may - /// not survive roundtrips through `TokenStream` or strings and may be - /// broken into two tokens (`-` and positive literal). - /// - /// Literals created through this method have the `Span::call_site()` - /// span by default, which can be configured with the `set_span` method - /// below. - pub fn $name(n: $kind) -> Literal { - Literal::_new(imp::Literal::$name(n)) - } - )*) -} - -macro_rules! unsuffixed_int_literals { - ($($name:ident => $kind:ident,)*) => ($( - /// Creates a new unsuffixed integer literal with the specified value. - /// - /// This function will create an integer like `1` where the integer - /// value specified is the first part of the token. No suffix is - /// specified on this token, meaning that invocations like - /// `Literal::i8_unsuffixed(1)` are equivalent to - /// `Literal::u32_unsuffixed(1)`. Literals created from negative numbers - /// may not survive roundtrips through `TokenStream` or strings and may - /// be broken into two tokens (`-` and positive literal). - /// - /// Literals created through this method have the `Span::call_site()` - /// span by default, which can be configured with the `set_span` method - /// below. - pub fn $name(n: $kind) -> Literal { - Literal::_new(imp::Literal::$name(n)) - } - )*) -} - -impl Literal { - fn _new(inner: imp::Literal) -> Self { - Literal { - inner, - _marker: MARKER, - } - } - - fn _new_fallback(inner: fallback::Literal) -> Self { - Literal { - inner: inner.into(), - _marker: MARKER, - } - } - - suffixed_int_literals! { - u8_suffixed => u8, - u16_suffixed => u16, - u32_suffixed => u32, - u64_suffixed => u64, - u128_suffixed => u128, - usize_suffixed => usize, - i8_suffixed => i8, - i16_suffixed => i16, - i32_suffixed => i32, - i64_suffixed => i64, - i128_suffixed => i128, - isize_suffixed => isize, - } - - unsuffixed_int_literals! { - u8_unsuffixed => u8, - u16_unsuffixed => u16, - u32_unsuffixed => u32, - u64_unsuffixed => u64, - u128_unsuffixed => u128, - usize_unsuffixed => usize, - i8_unsuffixed => i8, - i16_unsuffixed => i16, - i32_unsuffixed => i32, - i64_unsuffixed => i64, - i128_unsuffixed => i128, - isize_unsuffixed => isize, - } - - /// Creates a new unsuffixed floating-point literal. - /// - /// This constructor is similar to those like `Literal::i8_unsuffixed` where - /// the float's value is emitted directly into the token but no suffix is - /// used, so it may be inferred to be a `f64` later in the compiler. - /// Literals created from negative numbers may not survive round-trips - /// through `TokenStream` or strings and may be broken into two tokens (`-` - /// and positive literal). - /// - /// # Panics - /// - /// This function requires that the specified float is finite, for example - /// if it is infinity or NaN this function will panic. - pub fn f64_unsuffixed(f: f64) -> Literal { - assert!(f.is_finite()); - Literal::_new(imp::Literal::f64_unsuffixed(f)) - } - - /// Creates a new suffixed floating-point literal. - /// - /// This constructor will create a literal like `1.0f64` where the value - /// specified is the preceding part of the token and `f64` is the suffix of - /// the token. This token will always be inferred to be an `f64` in the - /// compiler. Literals created from negative numbers may not survive - /// round-trips through `TokenStream` or strings and may be broken into two - /// tokens (`-` and positive literal). - /// - /// # Panics - /// - /// This function requires that the specified float is finite, for example - /// if it is infinity or NaN this function will panic. - pub fn f64_suffixed(f: f64) -> Literal { - assert!(f.is_finite()); - Literal::_new(imp::Literal::f64_suffixed(f)) - } - - /// Creates a new unsuffixed floating-point literal. - /// - /// This constructor is similar to those like `Literal::i8_unsuffixed` where - /// the float's value is emitted directly into the token but no suffix is - /// used, so it may be inferred to be a `f64` later in the compiler. - /// Literals created from negative numbers may not survive round-trips - /// through `TokenStream` or strings and may be broken into two tokens (`-` - /// and positive literal). - /// - /// # Panics - /// - /// This function requires that the specified float is finite, for example - /// if it is infinity or NaN this function will panic. - pub fn f32_unsuffixed(f: f32) -> Literal { - assert!(f.is_finite()); - Literal::_new(imp::Literal::f32_unsuffixed(f)) - } - - /// Creates a new suffixed floating-point literal. - /// - /// This constructor will create a literal like `1.0f32` where the value - /// specified is the preceding part of the token and `f32` is the suffix of - /// the token. This token will always be inferred to be an `f32` in the - /// compiler. Literals created from negative numbers may not survive - /// round-trips through `TokenStream` or strings and may be broken into two - /// tokens (`-` and positive literal). - /// - /// # Panics - /// - /// This function requires that the specified float is finite, for example - /// if it is infinity or NaN this function will panic. - pub fn f32_suffixed(f: f32) -> Literal { - assert!(f.is_finite()); - Literal::_new(imp::Literal::f32_suffixed(f)) - } - - /// String literal. - pub fn string(string: &str) -> Literal { - Literal::_new(imp::Literal::string(string)) - } - - /// Character literal. - pub fn character(ch: char) -> Literal { - Literal::_new(imp::Literal::character(ch)) - } - - /// Byte string literal. - pub fn byte_string(s: &[u8]) -> Literal { - Literal::_new(imp::Literal::byte_string(s)) - } - - /// Returns the span encompassing this literal. - pub fn span(&self) -> Span { - Span::_new(self.inner.span()) - } - - /// Configures the span associated for this literal. - pub fn set_span(&mut self, span: Span) { - self.inner.set_span(span.inner); - } - - /// Returns a `Span` that is a subset of `self.span()` containing only - /// the source bytes in range `range`. Returns `None` if the would-be - /// trimmed span is outside the bounds of `self`. - /// - /// Warning: the underlying [`proc_macro::Literal::subspan`] method is - /// nightly-only. When called from within a procedural macro not using a - /// nightly compiler, this method will always return `None`. - /// - /// [`proc_macro::Literal::subspan`]: https://doc.rust-lang.org/proc_macro/struct.Literal.html#method.subspan - pub fn subspan>(&self, range: R) -> Option { - self.inner.subspan(range).map(Span::_new) - } - - // Intended for the `quote!` macro to use when constructing a proc-macro2 - // token out of a macro_rules $:literal token, which is already known to be - // a valid literal. This avoids reparsing/validating the literal's string - // representation. This is not public API other than for quote. - #[doc(hidden)] - pub unsafe fn from_str_unchecked(repr: &str) -> Self { - Literal::_new(unsafe { imp::Literal::from_str_unchecked(repr) }) - } -} - -impl FromStr for Literal { - type Err = LexError; - - fn from_str(repr: &str) -> Result { - repr.parse().map(Literal::_new).map_err(|inner| LexError { - inner, - _marker: MARKER, - }) - } -} - -impl Debug for Literal { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - Debug::fmt(&self.inner, f) - } -} - -impl Display for Literal { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - Display::fmt(&self.inner, f) - } -} - -/// Public implementation details for the `TokenStream` type, such as iterators. -pub mod token_stream { - use crate::marker::{ProcMacroAutoTraits, MARKER}; - use crate::{imp, TokenTree}; - use core::fmt::{self, Debug}; - - pub use crate::TokenStream; - - /// An iterator over `TokenStream`'s `TokenTree`s. - /// - /// The iteration is "shallow", e.g. the iterator doesn't recurse into - /// delimited groups, and returns whole groups as token trees. - #[derive(Clone)] - pub struct IntoIter { - inner: imp::TokenTreeIter, - _marker: ProcMacroAutoTraits, - } - - impl Iterator for IntoIter { - type Item = TokenTree; - - fn next(&mut self) -> Option { - self.inner.next() - } - - fn size_hint(&self) -> (usize, Option) { - self.inner.size_hint() - } - } - - impl Debug for IntoIter { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - f.write_str("TokenStream ")?; - f.debug_list().entries(self.clone()).finish() - } - } - - impl IntoIterator for TokenStream { - type Item = TokenTree; - type IntoIter = IntoIter; - - fn into_iter(self) -> IntoIter { - IntoIter { - inner: self.inner.into_iter(), - _marker: MARKER, - } - } - } -} diff --git a/third-party/vendor/proc-macro2/src/location.rs b/third-party/vendor/proc-macro2/src/location.rs deleted file mode 100644 index 463026c2..00000000 --- a/third-party/vendor/proc-macro2/src/location.rs +++ /dev/null @@ -1,29 +0,0 @@ -use core::cmp::Ordering; - -/// A line-column pair representing the start or end of a `Span`. -/// -/// This type is semver exempt and not exposed by default. -#[cfg_attr(doc_cfg, doc(cfg(feature = "span-locations")))] -#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)] -pub struct LineColumn { - /// The 1-indexed line in the source file on which the span starts or ends - /// (inclusive). - pub line: usize, - /// The 0-indexed column (in UTF-8 characters) in the source file on which - /// the span starts or ends (inclusive). - pub column: usize, -} - -impl Ord for LineColumn { - fn cmp(&self, other: &Self) -> Ordering { - self.line - .cmp(&other.line) - .then(self.column.cmp(&other.column)) - } -} - -impl PartialOrd for LineColumn { - fn partial_cmp(&self, other: &Self) -> Option { - Some(self.cmp(other)) - } -} diff --git a/third-party/vendor/proc-macro2/src/marker.rs b/third-party/vendor/proc-macro2/src/marker.rs deleted file mode 100644 index 23b94ce6..00000000 --- a/third-party/vendor/proc-macro2/src/marker.rs +++ /dev/null @@ -1,17 +0,0 @@ -use alloc::rc::Rc; -use core::marker::PhantomData; -use core::panic::{RefUnwindSafe, UnwindSafe}; - -// Zero sized marker with the correct set of autotrait impls we want all proc -// macro types to have. -#[derive(Copy, Clone)] -#[cfg_attr( - all(procmacro2_semver_exempt, any(not(wrap_proc_macro), super_unstable)), - derive(PartialEq, Eq) -)] -pub(crate) struct ProcMacroAutoTraits(PhantomData>); - -pub(crate) const MARKER: ProcMacroAutoTraits = ProcMacroAutoTraits(PhantomData); - -impl UnwindSafe for ProcMacroAutoTraits {} -impl RefUnwindSafe for ProcMacroAutoTraits {} diff --git a/third-party/vendor/proc-macro2/src/parse.rs b/third-party/vendor/proc-macro2/src/parse.rs deleted file mode 100644 index 07239bc3..00000000 --- a/third-party/vendor/proc-macro2/src/parse.rs +++ /dev/null @@ -1,996 +0,0 @@ -use crate::fallback::{ - self, is_ident_continue, is_ident_start, Group, LexError, Literal, Span, TokenStream, - TokenStreamBuilder, -}; -use crate::{Delimiter, Punct, Spacing, TokenTree}; -use core::char; -use core::str::{Bytes, CharIndices, Chars}; - -#[derive(Copy, Clone, Eq, PartialEq)] -pub(crate) struct Cursor<'a> { - pub rest: &'a str, - #[cfg(span_locations)] - pub off: u32, -} - -impl<'a> Cursor<'a> { - pub fn advance(&self, bytes: usize) -> Cursor<'a> { - let (_front, rest) = self.rest.split_at(bytes); - Cursor { - rest, - #[cfg(span_locations)] - off: self.off + _front.chars().count() as u32, - } - } - - pub fn starts_with(&self, s: &str) -> bool { - self.rest.starts_with(s) - } - - pub fn starts_with_char(&self, ch: char) -> bool { - self.rest.starts_with(ch) - } - - pub fn starts_with_fn(&self, f: Pattern) -> bool - where - Pattern: FnMut(char) -> bool, - { - self.rest.starts_with(f) - } - - pub fn is_empty(&self) -> bool { - self.rest.is_empty() - } - - fn len(&self) -> usize { - self.rest.len() - } - - fn as_bytes(&self) -> &'a [u8] { - self.rest.as_bytes() - } - - fn bytes(&self) -> Bytes<'a> { - self.rest.bytes() - } - - fn chars(&self) -> Chars<'a> { - self.rest.chars() - } - - fn char_indices(&self) -> CharIndices<'a> { - self.rest.char_indices() - } - - fn parse(&self, tag: &str) -> Result, Reject> { - if self.starts_with(tag) { - Ok(self.advance(tag.len())) - } else { - Err(Reject) - } - } -} - -pub(crate) struct Reject; -type PResult<'a, O> = Result<(Cursor<'a>, O), Reject>; - -fn skip_whitespace(input: Cursor) -> Cursor { - let mut s = input; - - while !s.is_empty() { - let byte = s.as_bytes()[0]; - if byte == b'/' { - if s.starts_with("//") - && (!s.starts_with("///") || s.starts_with("////")) - && !s.starts_with("//!") - { - let (cursor, _) = take_until_newline_or_eof(s); - s = cursor; - continue; - } else if s.starts_with("/**/") { - s = s.advance(4); - continue; - } else if s.starts_with("/*") - && (!s.starts_with("/**") || s.starts_with("/***")) - && !s.starts_with("/*!") - { - match block_comment(s) { - Ok((rest, _)) => { - s = rest; - continue; - } - Err(Reject) => return s, - } - } - } - match byte { - b' ' | 0x09..=0x0d => { - s = s.advance(1); - continue; - } - b if b.is_ascii() => {} - _ => { - let ch = s.chars().next().unwrap(); - if is_whitespace(ch) { - s = s.advance(ch.len_utf8()); - continue; - } - } - } - return s; - } - s -} - -fn block_comment(input: Cursor) -> PResult<&str> { - if !input.starts_with("/*") { - return Err(Reject); - } - - let mut depth = 0usize; - let bytes = input.as_bytes(); - let mut i = 0usize; - let upper = bytes.len() - 1; - - while i < upper { - if bytes[i] == b'/' && bytes[i + 1] == b'*' { - depth += 1; - i += 1; // eat '*' - } else if bytes[i] == b'*' && bytes[i + 1] == b'/' { - depth -= 1; - if depth == 0 { - return Ok((input.advance(i + 2), &input.rest[..i + 2])); - } - i += 1; // eat '/' - } - i += 1; - } - - Err(Reject) -} - -fn is_whitespace(ch: char) -> bool { - // Rust treats left-to-right mark and right-to-left mark as whitespace - ch.is_whitespace() || ch == '\u{200e}' || ch == '\u{200f}' -} - -fn word_break(input: Cursor) -> Result { - match input.chars().next() { - Some(ch) if is_ident_continue(ch) => Err(Reject), - Some(_) | None => Ok(input), - } -} - -// Rustc's representation of a macro expansion error in expression position or -// type position. -const ERROR: &str = "(/*ERROR*/)"; - -pub(crate) fn token_stream(mut input: Cursor) -> Result { - let mut trees = TokenStreamBuilder::new(); - let mut stack = Vec::new(); - - loop { - input = skip_whitespace(input); - - if let Ok((rest, ())) = doc_comment(input, &mut trees) { - input = rest; - continue; - } - - #[cfg(span_locations)] - let lo = input.off; - - let first = match input.bytes().next() { - Some(first) => first, - None => match stack.last() { - None => return Ok(trees.build()), - #[cfg(span_locations)] - Some((lo, _frame)) => { - return Err(LexError { - span: Span { lo: *lo, hi: *lo }, - }) - } - #[cfg(not(span_locations))] - Some(_frame) => return Err(LexError { span: Span {} }), - }, - }; - - if let Some(open_delimiter) = match first { - b'(' if !input.starts_with(ERROR) => Some(Delimiter::Parenthesis), - b'[' => Some(Delimiter::Bracket), - b'{' => Some(Delimiter::Brace), - _ => None, - } { - input = input.advance(1); - let frame = (open_delimiter, trees); - #[cfg(span_locations)] - let frame = (lo, frame); - stack.push(frame); - trees = TokenStreamBuilder::new(); - } else if let Some(close_delimiter) = match first { - b')' => Some(Delimiter::Parenthesis), - b']' => Some(Delimiter::Bracket), - b'}' => Some(Delimiter::Brace), - _ => None, - } { - let frame = match stack.pop() { - Some(frame) => frame, - None => return Err(lex_error(input)), - }; - #[cfg(span_locations)] - let (lo, frame) = frame; - let (open_delimiter, outer) = frame; - if open_delimiter != close_delimiter { - return Err(lex_error(input)); - } - input = input.advance(1); - let mut g = Group::new(open_delimiter, trees.build()); - g.set_span(Span { - #[cfg(span_locations)] - lo, - #[cfg(span_locations)] - hi: input.off, - }); - trees = outer; - trees.push_token_from_parser(TokenTree::Group(crate::Group::_new_fallback(g))); - } else { - let (rest, mut tt) = match leaf_token(input) { - Ok((rest, tt)) => (rest, tt), - Err(Reject) => return Err(lex_error(input)), - }; - tt.set_span(crate::Span::_new_fallback(Span { - #[cfg(span_locations)] - lo, - #[cfg(span_locations)] - hi: rest.off, - })); - trees.push_token_from_parser(tt); - input = rest; - } - } -} - -fn lex_error(cursor: Cursor) -> LexError { - #[cfg(not(span_locations))] - let _ = cursor; - LexError { - span: Span { - #[cfg(span_locations)] - lo: cursor.off, - #[cfg(span_locations)] - hi: cursor.off, - }, - } -} - -fn leaf_token(input: Cursor) -> PResult { - if let Ok((input, l)) = literal(input) { - // must be parsed before ident - Ok((input, TokenTree::Literal(crate::Literal::_new_fallback(l)))) - } else if let Ok((input, p)) = punct(input) { - Ok((input, TokenTree::Punct(p))) - } else if let Ok((input, i)) = ident(input) { - Ok((input, TokenTree::Ident(i))) - } else if input.starts_with(ERROR) { - let rest = input.advance(ERROR.len()); - let repr = crate::Literal::_new_fallback(Literal::_new(ERROR.to_owned())); - Ok((rest, TokenTree::Literal(repr))) - } else { - Err(Reject) - } -} - -fn ident(input: Cursor) -> PResult { - if [ - "r\"", "r#\"", "r##", "b\"", "b\'", "br\"", "br#", "c\"", "cr\"", "cr#", - ] - .iter() - .any(|prefix| input.starts_with(prefix)) - { - Err(Reject) - } else { - ident_any(input) - } -} - -fn ident_any(input: Cursor) -> PResult { - let raw = input.starts_with("r#"); - let rest = input.advance((raw as usize) << 1); - - let (rest, sym) = ident_not_raw(rest)?; - - if !raw { - let ident = crate::Ident::_new(crate::imp::Ident::new_unchecked( - sym, - fallback::Span::call_site(), - )); - return Ok((rest, ident)); - } - - match sym { - "_" | "super" | "self" | "Self" | "crate" => return Err(Reject), - _ => {} - } - - let ident = crate::Ident::_new(crate::imp::Ident::new_raw_unchecked( - sym, - fallback::Span::call_site(), - )); - Ok((rest, ident)) -} - -fn ident_not_raw(input: Cursor) -> PResult<&str> { - let mut chars = input.char_indices(); - - match chars.next() { - Some((_, ch)) if is_ident_start(ch) => {} - _ => return Err(Reject), - } - - let mut end = input.len(); - for (i, ch) in chars { - if !is_ident_continue(ch) { - end = i; - break; - } - } - - Ok((input.advance(end), &input.rest[..end])) -} - -pub(crate) fn literal(input: Cursor) -> PResult { - let rest = literal_nocapture(input)?; - let end = input.len() - rest.len(); - Ok((rest, Literal::_new(input.rest[..end].to_string()))) -} - -fn literal_nocapture(input: Cursor) -> Result { - if let Ok(ok) = string(input) { - Ok(ok) - } else if let Ok(ok) = byte_string(input) { - Ok(ok) - } else if let Ok(ok) = c_string(input) { - Ok(ok) - } else if let Ok(ok) = byte(input) { - Ok(ok) - } else if let Ok(ok) = character(input) { - Ok(ok) - } else if let Ok(ok) = float(input) { - Ok(ok) - } else if let Ok(ok) = int(input) { - Ok(ok) - } else { - Err(Reject) - } -} - -fn literal_suffix(input: Cursor) -> Cursor { - match ident_not_raw(input) { - Ok((input, _)) => input, - Err(Reject) => input, - } -} - -fn string(input: Cursor) -> Result { - if let Ok(input) = input.parse("\"") { - cooked_string(input) - } else if let Ok(input) = input.parse("r") { - raw_string(input) - } else { - Err(Reject) - } -} - -fn cooked_string(mut input: Cursor) -> Result { - let mut chars = input.char_indices(); - - while let Some((i, ch)) = chars.next() { - match ch { - '"' => { - let input = input.advance(i + 1); - return Ok(literal_suffix(input)); - } - '\r' => match chars.next() { - Some((_, '\n')) => {} - _ => break, - }, - '\\' => match chars.next() { - Some((_, 'x')) => { - backslash_x_char(&mut chars)?; - } - Some((_, 'n' | 'r' | 't' | '\\' | '\'' | '"' | '0')) => {} - Some((_, 'u')) => { - backslash_u(&mut chars)?; - } - Some((newline, ch @ ('\n' | '\r'))) => { - input = input.advance(newline + 1); - trailing_backslash(&mut input, ch as u8)?; - chars = input.char_indices(); - } - _ => break, - }, - _ch => {} - } - } - Err(Reject) -} - -fn raw_string(input: Cursor) -> Result { - let (input, delimiter) = delimiter_of_raw_string(input)?; - let mut bytes = input.bytes().enumerate(); - while let Some((i, byte)) = bytes.next() { - match byte { - b'"' if input.rest[i + 1..].starts_with(delimiter) => { - let rest = input.advance(i + 1 + delimiter.len()); - return Ok(literal_suffix(rest)); - } - b'\r' => match bytes.next() { - Some((_, b'\n')) => {} - _ => break, - }, - _ => {} - } - } - Err(Reject) -} - -fn byte_string(input: Cursor) -> Result { - if let Ok(input) = input.parse("b\"") { - cooked_byte_string(input) - } else if let Ok(input) = input.parse("br") { - raw_byte_string(input) - } else { - Err(Reject) - } -} - -fn cooked_byte_string(mut input: Cursor) -> Result { - let mut bytes = input.bytes().enumerate(); - while let Some((offset, b)) = bytes.next() { - match b { - b'"' => { - let input = input.advance(offset + 1); - return Ok(literal_suffix(input)); - } - b'\r' => match bytes.next() { - Some((_, b'\n')) => {} - _ => break, - }, - b'\\' => match bytes.next() { - Some((_, b'x')) => { - backslash_x_byte(&mut bytes)?; - } - Some((_, b'n' | b'r' | b't' | b'\\' | b'0' | b'\'' | b'"')) => {} - Some((newline, b @ (b'\n' | b'\r'))) => { - input = input.advance(newline + 1); - trailing_backslash(&mut input, b)?; - bytes = input.bytes().enumerate(); - } - _ => break, - }, - b if b.is_ascii() => {} - _ => break, - } - } - Err(Reject) -} - -fn delimiter_of_raw_string(input: Cursor) -> PResult<&str> { - for (i, byte) in input.bytes().enumerate() { - match byte { - b'"' => { - if i > 255 { - // https://github.com/rust-lang/rust/pull/95251 - return Err(Reject); - } - return Ok((input.advance(i + 1), &input.rest[..i])); - } - b'#' => {} - _ => break, - } - } - Err(Reject) -} - -fn raw_byte_string(input: Cursor) -> Result { - let (input, delimiter) = delimiter_of_raw_string(input)?; - let mut bytes = input.bytes().enumerate(); - while let Some((i, byte)) = bytes.next() { - match byte { - b'"' if input.rest[i + 1..].starts_with(delimiter) => { - let rest = input.advance(i + 1 + delimiter.len()); - return Ok(literal_suffix(rest)); - } - b'\r' => match bytes.next() { - Some((_, b'\n')) => {} - _ => break, - }, - other => { - if !other.is_ascii() { - break; - } - } - } - } - Err(Reject) -} - -fn c_string(input: Cursor) -> Result { - if let Ok(input) = input.parse("c\"") { - cooked_c_string(input) - } else if let Ok(input) = input.parse("cr") { - raw_c_string(input) - } else { - Err(Reject) - } -} - -fn raw_c_string(input: Cursor) -> Result { - let (input, delimiter) = delimiter_of_raw_string(input)?; - let mut bytes = input.bytes().enumerate(); - while let Some((i, byte)) = bytes.next() { - match byte { - b'"' if input.rest[i + 1..].starts_with(delimiter) => { - let rest = input.advance(i + 1 + delimiter.len()); - return Ok(literal_suffix(rest)); - } - b'\r' => match bytes.next() { - Some((_, b'\n')) => {} - _ => break, - }, - b'\0' => break, - _ => {} - } - } - Err(Reject) -} - -fn cooked_c_string(mut input: Cursor) -> Result { - let mut chars = input.char_indices(); - - while let Some((i, ch)) = chars.next() { - match ch { - '"' => { - let input = input.advance(i + 1); - return Ok(literal_suffix(input)); - } - '\r' => match chars.next() { - Some((_, '\n')) => {} - _ => break, - }, - '\\' => match chars.next() { - Some((_, 'x')) => { - backslash_x_nonzero(&mut chars)?; - } - Some((_, 'n' | 'r' | 't' | '\\' | '\'' | '"')) => {} - Some((_, 'u')) => { - if backslash_u(&mut chars)? == '\0' { - break; - } - } - Some((newline, ch @ ('\n' | '\r'))) => { - input = input.advance(newline + 1); - trailing_backslash(&mut input, ch as u8)?; - chars = input.char_indices(); - } - _ => break, - }, - '\0' => break, - _ch => {} - } - } - Err(Reject) -} - -fn byte(input: Cursor) -> Result { - let input = input.parse("b'")?; - let mut bytes = input.bytes().enumerate(); - let ok = match bytes.next().map(|(_, b)| b) { - Some(b'\\') => match bytes.next().map(|(_, b)| b) { - Some(b'x') => backslash_x_byte(&mut bytes).is_ok(), - Some(b'n' | b'r' | b't' | b'\\' | b'0' | b'\'' | b'"') => true, - _ => false, - }, - b => b.is_some(), - }; - if !ok { - return Err(Reject); - } - let (offset, _) = bytes.next().ok_or(Reject)?; - if !input.chars().as_str().is_char_boundary(offset) { - return Err(Reject); - } - let input = input.advance(offset).parse("'")?; - Ok(literal_suffix(input)) -} - -fn character(input: Cursor) -> Result { - let input = input.parse("'")?; - let mut chars = input.char_indices(); - let ok = match chars.next().map(|(_, ch)| ch) { - Some('\\') => match chars.next().map(|(_, ch)| ch) { - Some('x') => backslash_x_char(&mut chars).is_ok(), - Some('u') => backslash_u(&mut chars).is_ok(), - Some('n' | 'r' | 't' | '\\' | '0' | '\'' | '"') => true, - _ => false, - }, - ch => ch.is_some(), - }; - if !ok { - return Err(Reject); - } - let (idx, _) = chars.next().ok_or(Reject)?; - let input = input.advance(idx).parse("'")?; - Ok(literal_suffix(input)) -} - -macro_rules! next_ch { - ($chars:ident @ $pat:pat) => { - match $chars.next() { - Some((_, ch)) => match ch { - $pat => ch, - _ => return Err(Reject), - }, - None => return Err(Reject), - } - }; -} - -fn backslash_x_char(chars: &mut I) -> Result<(), Reject> -where - I: Iterator, -{ - next_ch!(chars @ '0'..='7'); - next_ch!(chars @ '0'..='9' | 'a'..='f' | 'A'..='F'); - Ok(()) -} - -fn backslash_x_byte(chars: &mut I) -> Result<(), Reject> -where - I: Iterator, -{ - next_ch!(chars @ b'0'..=b'9' | b'a'..=b'f' | b'A'..=b'F'); - next_ch!(chars @ b'0'..=b'9' | b'a'..=b'f' | b'A'..=b'F'); - Ok(()) -} - -fn backslash_x_nonzero(chars: &mut I) -> Result<(), Reject> -where - I: Iterator, -{ - let first = next_ch!(chars @ '0'..='9' | 'a'..='f' | 'A'..='F'); - let second = next_ch!(chars @ '0'..='9' | 'a'..='f' | 'A'..='F'); - if first == '0' && second == '0' { - Err(Reject) - } else { - Ok(()) - } -} - -fn backslash_u(chars: &mut I) -> Result -where - I: Iterator, -{ - next_ch!(chars @ '{'); - let mut value = 0; - let mut len = 0; - for (_, ch) in chars { - let digit = match ch { - '0'..='9' => ch as u8 - b'0', - 'a'..='f' => 10 + ch as u8 - b'a', - 'A'..='F' => 10 + ch as u8 - b'A', - '_' if len > 0 => continue, - '}' if len > 0 => return char::from_u32(value).ok_or(Reject), - _ => break, - }; - if len == 6 { - break; - } - value *= 0x10; - value += u32::from(digit); - len += 1; - } - Err(Reject) -} - -fn trailing_backslash(input: &mut Cursor, mut last: u8) -> Result<(), Reject> { - let mut whitespace = input.bytes().enumerate(); - loop { - if last == b'\r' && whitespace.next().map_or(true, |(_, b)| b != b'\n') { - return Err(Reject); - } - match whitespace.next() { - Some((_, b @ (b' ' | b'\t' | b'\n' | b'\r'))) => { - last = b; - } - Some((offset, _)) => { - *input = input.advance(offset); - return Ok(()); - } - None => return Err(Reject), - } - } -} - -fn float(input: Cursor) -> Result { - let mut rest = float_digits(input)?; - if let Some(ch) = rest.chars().next() { - if is_ident_start(ch) { - rest = ident_not_raw(rest)?.0; - } - } - word_break(rest) -} - -fn float_digits(input: Cursor) -> Result { - let mut chars = input.chars().peekable(); - match chars.next() { - Some(ch) if '0' <= ch && ch <= '9' => {} - _ => return Err(Reject), - } - - let mut len = 1; - let mut has_dot = false; - let mut has_exp = false; - while let Some(&ch) = chars.peek() { - match ch { - '0'..='9' | '_' => { - chars.next(); - len += 1; - } - '.' => { - if has_dot { - break; - } - chars.next(); - if chars - .peek() - .map_or(false, |&ch| ch == '.' || is_ident_start(ch)) - { - return Err(Reject); - } - len += 1; - has_dot = true; - } - 'e' | 'E' => { - chars.next(); - len += 1; - has_exp = true; - break; - } - _ => break, - } - } - - if !(has_dot || has_exp) { - return Err(Reject); - } - - if has_exp { - let token_before_exp = if has_dot { - Ok(input.advance(len - 1)) - } else { - Err(Reject) - }; - let mut has_sign = false; - let mut has_exp_value = false; - while let Some(&ch) = chars.peek() { - match ch { - '+' | '-' => { - if has_exp_value { - break; - } - if has_sign { - return token_before_exp; - } - chars.next(); - len += 1; - has_sign = true; - } - '0'..='9' => { - chars.next(); - len += 1; - has_exp_value = true; - } - '_' => { - chars.next(); - len += 1; - } - _ => break, - } - } - if !has_exp_value { - return token_before_exp; - } - } - - Ok(input.advance(len)) -} - -fn int(input: Cursor) -> Result { - let mut rest = digits(input)?; - if let Some(ch) = rest.chars().next() { - if is_ident_start(ch) { - rest = ident_not_raw(rest)?.0; - } - } - word_break(rest) -} - -fn digits(mut input: Cursor) -> Result { - let base = if input.starts_with("0x") { - input = input.advance(2); - 16 - } else if input.starts_with("0o") { - input = input.advance(2); - 8 - } else if input.starts_with("0b") { - input = input.advance(2); - 2 - } else { - 10 - }; - - let mut len = 0; - let mut empty = true; - for b in input.bytes() { - match b { - b'0'..=b'9' => { - let digit = (b - b'0') as u64; - if digit >= base { - return Err(Reject); - } - } - b'a'..=b'f' => { - let digit = 10 + (b - b'a') as u64; - if digit >= base { - break; - } - } - b'A'..=b'F' => { - let digit = 10 + (b - b'A') as u64; - if digit >= base { - break; - } - } - b'_' => { - if empty && base == 10 { - return Err(Reject); - } - len += 1; - continue; - } - _ => break, - }; - len += 1; - empty = false; - } - if empty { - Err(Reject) - } else { - Ok(input.advance(len)) - } -} - -fn punct(input: Cursor) -> PResult { - let (rest, ch) = punct_char(input)?; - if ch == '\'' { - if ident_any(rest)?.0.starts_with_char('\'') { - Err(Reject) - } else { - Ok((rest, Punct::new('\'', Spacing::Joint))) - } - } else { - let kind = match punct_char(rest) { - Ok(_) => Spacing::Joint, - Err(Reject) => Spacing::Alone, - }; - Ok((rest, Punct::new(ch, kind))) - } -} - -fn punct_char(input: Cursor) -> PResult { - if input.starts_with("//") || input.starts_with("/*") { - // Do not accept `/` of a comment as a punct. - return Err(Reject); - } - - let mut chars = input.chars(); - let first = match chars.next() { - Some(ch) => ch, - None => { - return Err(Reject); - } - }; - let recognized = "~!@#$%^&*-=+|;:,<.>/?'"; - if recognized.contains(first) { - Ok((input.advance(first.len_utf8()), first)) - } else { - Err(Reject) - } -} - -fn doc_comment<'a>(input: Cursor<'a>, trees: &mut TokenStreamBuilder) -> PResult<'a, ()> { - #[cfg(span_locations)] - let lo = input.off; - let (rest, (comment, inner)) = doc_comment_contents(input)?; - let fallback_span = Span { - #[cfg(span_locations)] - lo, - #[cfg(span_locations)] - hi: rest.off, - }; - let span = crate::Span::_new_fallback(fallback_span); - - let mut scan_for_bare_cr = comment; - while let Some(cr) = scan_for_bare_cr.find('\r') { - let rest = &scan_for_bare_cr[cr + 1..]; - if !rest.starts_with('\n') { - return Err(Reject); - } - scan_for_bare_cr = rest; - } - - let mut pound = Punct::new('#', Spacing::Alone); - pound.set_span(span); - trees.push_token_from_parser(TokenTree::Punct(pound)); - - if inner { - let mut bang = Punct::new('!', Spacing::Alone); - bang.set_span(span); - trees.push_token_from_parser(TokenTree::Punct(bang)); - } - - let doc_ident = crate::Ident::_new(crate::imp::Ident::new_unchecked("doc", fallback_span)); - let mut equal = Punct::new('=', Spacing::Alone); - equal.set_span(span); - let mut literal = crate::Literal::string(comment); - literal.set_span(span); - let mut bracketed = TokenStreamBuilder::with_capacity(3); - bracketed.push_token_from_parser(TokenTree::Ident(doc_ident)); - bracketed.push_token_from_parser(TokenTree::Punct(equal)); - bracketed.push_token_from_parser(TokenTree::Literal(literal)); - let group = Group::new(Delimiter::Bracket, bracketed.build()); - let mut group = crate::Group::_new_fallback(group); - group.set_span(span); - trees.push_token_from_parser(TokenTree::Group(group)); - - Ok((rest, ())) -} - -fn doc_comment_contents(input: Cursor) -> PResult<(&str, bool)> { - if input.starts_with("//!") { - let input = input.advance(3); - let (input, s) = take_until_newline_or_eof(input); - Ok((input, (s, true))) - } else if input.starts_with("/*!") { - let (input, s) = block_comment(input)?; - Ok((input, (&s[3..s.len() - 2], true))) - } else if input.starts_with("///") { - let input = input.advance(3); - if input.starts_with_char('/') { - return Err(Reject); - } - let (input, s) = take_until_newline_or_eof(input); - Ok((input, (s, false))) - } else if input.starts_with("/**") && !input.rest[3..].starts_with('*') { - let (input, s) = block_comment(input)?; - Ok((input, (&s[3..s.len() - 2], false))) - } else { - Err(Reject) - } -} - -fn take_until_newline_or_eof(input: Cursor) -> (Cursor, &str) { - let chars = input.char_indices(); - - for (i, ch) in chars { - if ch == '\n' { - return (input.advance(i), &input.rest[..i]); - } else if ch == '\r' && input.rest[i + 1..].starts_with('\n') { - return (input.advance(i + 1), &input.rest[..i]); - } - } - - (input.advance(input.len()), input.rest) -} diff --git a/third-party/vendor/proc-macro2/src/rcvec.rs b/third-party/vendor/proc-macro2/src/rcvec.rs deleted file mode 100644 index 37955afb..00000000 --- a/third-party/vendor/proc-macro2/src/rcvec.rs +++ /dev/null @@ -1,145 +0,0 @@ -use alloc::rc::Rc; -use alloc::vec; -use core::mem; -use core::panic::RefUnwindSafe; -use core::slice; - -pub(crate) struct RcVec { - inner: Rc>, -} - -pub(crate) struct RcVecBuilder { - inner: Vec, -} - -pub(crate) struct RcVecMut<'a, T> { - inner: &'a mut Vec, -} - -#[derive(Clone)] -pub(crate) struct RcVecIntoIter { - inner: vec::IntoIter, -} - -impl RcVec { - pub fn is_empty(&self) -> bool { - self.inner.is_empty() - } - - pub fn len(&self) -> usize { - self.inner.len() - } - - pub fn iter(&self) -> slice::Iter { - self.inner.iter() - } - - pub fn make_mut(&mut self) -> RcVecMut - where - T: Clone, - { - RcVecMut { - inner: Rc::make_mut(&mut self.inner), - } - } - - pub fn get_mut(&mut self) -> Option> { - let inner = Rc::get_mut(&mut self.inner)?; - Some(RcVecMut { inner }) - } - - pub fn make_owned(mut self) -> RcVecBuilder - where - T: Clone, - { - let vec = if let Some(owned) = Rc::get_mut(&mut self.inner) { - mem::take(owned) - } else { - Vec::clone(&self.inner) - }; - RcVecBuilder { inner: vec } - } -} - -impl RcVecBuilder { - pub fn new() -> Self { - RcVecBuilder { inner: Vec::new() } - } - - pub fn with_capacity(cap: usize) -> Self { - RcVecBuilder { - inner: Vec::with_capacity(cap), - } - } - - pub fn push(&mut self, element: T) { - self.inner.push(element); - } - - pub fn extend(&mut self, iter: impl IntoIterator) { - self.inner.extend(iter); - } - - pub fn as_mut(&mut self) -> RcVecMut { - RcVecMut { - inner: &mut self.inner, - } - } - - pub fn build(self) -> RcVec { - RcVec { - inner: Rc::new(self.inner), - } - } -} - -impl<'a, T> RcVecMut<'a, T> { - pub fn push(&mut self, element: T) { - self.inner.push(element); - } - - pub fn extend(&mut self, iter: impl IntoIterator) { - self.inner.extend(iter); - } - - pub fn pop(&mut self) -> Option { - self.inner.pop() - } - - pub fn as_mut(&mut self) -> RcVecMut { - RcVecMut { inner: self.inner } - } -} - -impl Clone for RcVec { - fn clone(&self) -> Self { - RcVec { - inner: Rc::clone(&self.inner), - } - } -} - -impl IntoIterator for RcVecBuilder { - type Item = T; - type IntoIter = RcVecIntoIter; - - fn into_iter(self) -> Self::IntoIter { - RcVecIntoIter { - inner: self.inner.into_iter(), - } - } -} - -impl Iterator for RcVecIntoIter { - type Item = T; - - fn next(&mut self) -> Option { - self.inner.next() - } - - fn size_hint(&self) -> (usize, Option) { - self.inner.size_hint() - } -} - -impl RefUnwindSafe for RcVec where T: RefUnwindSafe {} diff --git a/third-party/vendor/proc-macro2/src/wrapper.rs b/third-party/vendor/proc-macro2/src/wrapper.rs deleted file mode 100644 index a71043ab..00000000 --- a/third-party/vendor/proc-macro2/src/wrapper.rs +++ /dev/null @@ -1,954 +0,0 @@ -use crate::detection::inside_proc_macro; -#[cfg(span_locations)] -use crate::location::LineColumn; -use crate::{fallback, Delimiter, Punct, Spacing, TokenTree}; -use core::fmt::{self, Debug, Display}; -#[cfg(span_locations)] -use core::ops::Range; -use core::ops::RangeBounds; -use core::str::FromStr; -use std::panic; -#[cfg(super_unstable)] -use std::path::PathBuf; - -#[derive(Clone)] -pub(crate) enum TokenStream { - Compiler(DeferredTokenStream), - Fallback(fallback::TokenStream), -} - -// Work around https://github.com/rust-lang/rust/issues/65080. -// In `impl Extend for TokenStream` which is used heavily by quote, -// we hold on to the appended tokens and do proc_macro::TokenStream::extend as -// late as possible to batch together consecutive uses of the Extend impl. -#[derive(Clone)] -pub(crate) struct DeferredTokenStream { - stream: proc_macro::TokenStream, - extra: Vec, -} - -pub(crate) enum LexError { - Compiler(proc_macro::LexError), - Fallback(fallback::LexError), - - // Rustc was supposed to return a LexError, but it panicked instead. - // https://github.com/rust-lang/rust/issues/58736 - CompilerPanic, -} - -#[cold] -fn mismatch(line: u32) -> ! { - #[cfg(procmacro2_backtrace)] - { - let backtrace = std::backtrace::Backtrace::force_capture(); - panic!("compiler/fallback mismatch #{}\n\n{}", line, backtrace) - } - #[cfg(not(procmacro2_backtrace))] - { - panic!("compiler/fallback mismatch #{}", line) - } -} - -impl DeferredTokenStream { - fn new(stream: proc_macro::TokenStream) -> Self { - DeferredTokenStream { - stream, - extra: Vec::new(), - } - } - - fn is_empty(&self) -> bool { - self.stream.is_empty() && self.extra.is_empty() - } - - fn evaluate_now(&mut self) { - // If-check provides a fast short circuit for the common case of `extra` - // being empty, which saves a round trip over the proc macro bridge. - // Improves macro expansion time in winrt by 6% in debug mode. - if !self.extra.is_empty() { - self.stream.extend(self.extra.drain(..)); - } - } - - fn into_token_stream(mut self) -> proc_macro::TokenStream { - self.evaluate_now(); - self.stream - } -} - -impl TokenStream { - pub fn new() -> Self { - if inside_proc_macro() { - TokenStream::Compiler(DeferredTokenStream::new(proc_macro::TokenStream::new())) - } else { - TokenStream::Fallback(fallback::TokenStream::new()) - } - } - - pub fn is_empty(&self) -> bool { - match self { - TokenStream::Compiler(tts) => tts.is_empty(), - TokenStream::Fallback(tts) => tts.is_empty(), - } - } - - fn unwrap_nightly(self) -> proc_macro::TokenStream { - match self { - TokenStream::Compiler(s) => s.into_token_stream(), - TokenStream::Fallback(_) => mismatch(line!()), - } - } - - fn unwrap_stable(self) -> fallback::TokenStream { - match self { - TokenStream::Compiler(_) => mismatch(line!()), - TokenStream::Fallback(s) => s, - } - } -} - -impl FromStr for TokenStream { - type Err = LexError; - - fn from_str(src: &str) -> Result { - if inside_proc_macro() { - Ok(TokenStream::Compiler(DeferredTokenStream::new( - proc_macro_parse(src)?, - ))) - } else { - Ok(TokenStream::Fallback(src.parse()?)) - } - } -} - -// Work around https://github.com/rust-lang/rust/issues/58736. -fn proc_macro_parse(src: &str) -> Result { - let result = panic::catch_unwind(|| src.parse().map_err(LexError::Compiler)); - result.unwrap_or_else(|_| Err(LexError::CompilerPanic)) -} - -impl Display for TokenStream { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - match self { - TokenStream::Compiler(tts) => Display::fmt(&tts.clone().into_token_stream(), f), - TokenStream::Fallback(tts) => Display::fmt(tts, f), - } - } -} - -impl From for TokenStream { - fn from(inner: proc_macro::TokenStream) -> Self { - TokenStream::Compiler(DeferredTokenStream::new(inner)) - } -} - -impl From for proc_macro::TokenStream { - fn from(inner: TokenStream) -> Self { - match inner { - TokenStream::Compiler(inner) => inner.into_token_stream(), - TokenStream::Fallback(inner) => inner.to_string().parse().unwrap(), - } - } -} - -impl From for TokenStream { - fn from(inner: fallback::TokenStream) -> Self { - TokenStream::Fallback(inner) - } -} - -// Assumes inside_proc_macro(). -fn into_compiler_token(token: TokenTree) -> proc_macro::TokenTree { - match token { - TokenTree::Group(tt) => tt.inner.unwrap_nightly().into(), - TokenTree::Punct(tt) => { - let spacing = match tt.spacing() { - Spacing::Joint => proc_macro::Spacing::Joint, - Spacing::Alone => proc_macro::Spacing::Alone, - }; - let mut punct = proc_macro::Punct::new(tt.as_char(), spacing); - punct.set_span(tt.span().inner.unwrap_nightly()); - punct.into() - } - TokenTree::Ident(tt) => tt.inner.unwrap_nightly().into(), - TokenTree::Literal(tt) => tt.inner.unwrap_nightly().into(), - } -} - -impl From for TokenStream { - fn from(token: TokenTree) -> Self { - if inside_proc_macro() { - TokenStream::Compiler(DeferredTokenStream::new(into_compiler_token(token).into())) - } else { - TokenStream::Fallback(token.into()) - } - } -} - -impl FromIterator for TokenStream { - fn from_iter>(trees: I) -> Self { - if inside_proc_macro() { - TokenStream::Compiler(DeferredTokenStream::new( - trees.into_iter().map(into_compiler_token).collect(), - )) - } else { - TokenStream::Fallback(trees.into_iter().collect()) - } - } -} - -impl FromIterator for TokenStream { - fn from_iter>(streams: I) -> Self { - let mut streams = streams.into_iter(); - match streams.next() { - Some(TokenStream::Compiler(mut first)) => { - first.evaluate_now(); - first.stream.extend(streams.map(|s| match s { - TokenStream::Compiler(s) => s.into_token_stream(), - TokenStream::Fallback(_) => mismatch(line!()), - })); - TokenStream::Compiler(first) - } - Some(TokenStream::Fallback(mut first)) => { - first.extend(streams.map(|s| match s { - TokenStream::Fallback(s) => s, - TokenStream::Compiler(_) => mismatch(line!()), - })); - TokenStream::Fallback(first) - } - None => TokenStream::new(), - } - } -} - -impl Extend for TokenStream { - fn extend>(&mut self, stream: I) { - match self { - TokenStream::Compiler(tts) => { - // Here is the reason for DeferredTokenStream. - for token in stream { - tts.extra.push(into_compiler_token(token)); - } - } - TokenStream::Fallback(tts) => tts.extend(stream), - } - } -} - -impl Extend for TokenStream { - fn extend>(&mut self, streams: I) { - match self { - TokenStream::Compiler(tts) => { - tts.evaluate_now(); - tts.stream - .extend(streams.into_iter().map(TokenStream::unwrap_nightly)); - } - TokenStream::Fallback(tts) => { - tts.extend(streams.into_iter().map(TokenStream::unwrap_stable)); - } - } - } -} - -impl Debug for TokenStream { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - match self { - TokenStream::Compiler(tts) => Debug::fmt(&tts.clone().into_token_stream(), f), - TokenStream::Fallback(tts) => Debug::fmt(tts, f), - } - } -} - -impl LexError { - pub(crate) fn span(&self) -> Span { - match self { - LexError::Compiler(_) | LexError::CompilerPanic => Span::call_site(), - LexError::Fallback(e) => Span::Fallback(e.span()), - } - } -} - -impl From for LexError { - fn from(e: proc_macro::LexError) -> Self { - LexError::Compiler(e) - } -} - -impl From for LexError { - fn from(e: fallback::LexError) -> Self { - LexError::Fallback(e) - } -} - -impl Debug for LexError { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - match self { - LexError::Compiler(e) => Debug::fmt(e, f), - LexError::Fallback(e) => Debug::fmt(e, f), - LexError::CompilerPanic => { - let fallback = fallback::LexError::call_site(); - Debug::fmt(&fallback, f) - } - } - } -} - -impl Display for LexError { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - match self { - LexError::Compiler(e) => Display::fmt(e, f), - LexError::Fallback(e) => Display::fmt(e, f), - LexError::CompilerPanic => { - let fallback = fallback::LexError::call_site(); - Display::fmt(&fallback, f) - } - } - } -} - -#[derive(Clone)] -pub(crate) enum TokenTreeIter { - Compiler(proc_macro::token_stream::IntoIter), - Fallback(fallback::TokenTreeIter), -} - -impl IntoIterator for TokenStream { - type Item = TokenTree; - type IntoIter = TokenTreeIter; - - fn into_iter(self) -> TokenTreeIter { - match self { - TokenStream::Compiler(tts) => { - TokenTreeIter::Compiler(tts.into_token_stream().into_iter()) - } - TokenStream::Fallback(tts) => TokenTreeIter::Fallback(tts.into_iter()), - } - } -} - -impl Iterator for TokenTreeIter { - type Item = TokenTree; - - fn next(&mut self) -> Option { - let token = match self { - TokenTreeIter::Compiler(iter) => iter.next()?, - TokenTreeIter::Fallback(iter) => return iter.next(), - }; - Some(match token { - proc_macro::TokenTree::Group(tt) => crate::Group::_new(Group::Compiler(tt)).into(), - proc_macro::TokenTree::Punct(tt) => { - let spacing = match tt.spacing() { - proc_macro::Spacing::Joint => Spacing::Joint, - proc_macro::Spacing::Alone => Spacing::Alone, - }; - let mut o = Punct::new(tt.as_char(), spacing); - o.set_span(crate::Span::_new(Span::Compiler(tt.span()))); - o.into() - } - proc_macro::TokenTree::Ident(s) => crate::Ident::_new(Ident::Compiler(s)).into(), - proc_macro::TokenTree::Literal(l) => crate::Literal::_new(Literal::Compiler(l)).into(), - }) - } - - fn size_hint(&self) -> (usize, Option) { - match self { - TokenTreeIter::Compiler(tts) => tts.size_hint(), - TokenTreeIter::Fallback(tts) => tts.size_hint(), - } - } -} - -#[derive(Clone, PartialEq, Eq)] -#[cfg(super_unstable)] -pub(crate) enum SourceFile { - Compiler(proc_macro::SourceFile), - Fallback(fallback::SourceFile), -} - -#[cfg(super_unstable)] -impl SourceFile { - fn nightly(sf: proc_macro::SourceFile) -> Self { - SourceFile::Compiler(sf) - } - - /// Get the path to this source file as a string. - pub fn path(&self) -> PathBuf { - match self { - SourceFile::Compiler(a) => a.path(), - SourceFile::Fallback(a) => a.path(), - } - } - - pub fn is_real(&self) -> bool { - match self { - SourceFile::Compiler(a) => a.is_real(), - SourceFile::Fallback(a) => a.is_real(), - } - } -} - -#[cfg(super_unstable)] -impl Debug for SourceFile { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - match self { - SourceFile::Compiler(a) => Debug::fmt(a, f), - SourceFile::Fallback(a) => Debug::fmt(a, f), - } - } -} - -#[derive(Copy, Clone)] -pub(crate) enum Span { - Compiler(proc_macro::Span), - Fallback(fallback::Span), -} - -impl Span { - pub fn call_site() -> Self { - if inside_proc_macro() { - Span::Compiler(proc_macro::Span::call_site()) - } else { - Span::Fallback(fallback::Span::call_site()) - } - } - - pub fn mixed_site() -> Self { - if inside_proc_macro() { - Span::Compiler(proc_macro::Span::mixed_site()) - } else { - Span::Fallback(fallback::Span::mixed_site()) - } - } - - #[cfg(super_unstable)] - pub fn def_site() -> Self { - if inside_proc_macro() { - Span::Compiler(proc_macro::Span::def_site()) - } else { - Span::Fallback(fallback::Span::def_site()) - } - } - - pub fn resolved_at(&self, other: Span) -> Span { - match (self, other) { - (Span::Compiler(a), Span::Compiler(b)) => Span::Compiler(a.resolved_at(b)), - (Span::Fallback(a), Span::Fallback(b)) => Span::Fallback(a.resolved_at(b)), - (Span::Compiler(_), Span::Fallback(_)) => mismatch(line!()), - (Span::Fallback(_), Span::Compiler(_)) => mismatch(line!()), - } - } - - pub fn located_at(&self, other: Span) -> Span { - match (self, other) { - (Span::Compiler(a), Span::Compiler(b)) => Span::Compiler(a.located_at(b)), - (Span::Fallback(a), Span::Fallback(b)) => Span::Fallback(a.located_at(b)), - (Span::Compiler(_), Span::Fallback(_)) => mismatch(line!()), - (Span::Fallback(_), Span::Compiler(_)) => mismatch(line!()), - } - } - - pub fn unwrap(self) -> proc_macro::Span { - match self { - Span::Compiler(s) => s, - Span::Fallback(_) => panic!("proc_macro::Span is only available in procedural macros"), - } - } - - #[cfg(super_unstable)] - pub fn source_file(&self) -> SourceFile { - match self { - Span::Compiler(s) => SourceFile::nightly(s.source_file()), - Span::Fallback(s) => SourceFile::Fallback(s.source_file()), - } - } - - #[cfg(span_locations)] - pub fn byte_range(&self) -> Range { - match self { - #[cfg(proc_macro_span)] - Span::Compiler(s) => s.byte_range(), - #[cfg(not(proc_macro_span))] - Span::Compiler(_) => 0..0, - Span::Fallback(s) => s.byte_range(), - } - } - - #[cfg(span_locations)] - pub fn start(&self) -> LineColumn { - match self { - Span::Compiler(_) => LineColumn { line: 0, column: 0 }, - Span::Fallback(s) => s.start(), - } - } - - #[cfg(span_locations)] - pub fn end(&self) -> LineColumn { - match self { - Span::Compiler(_) => LineColumn { line: 0, column: 0 }, - Span::Fallback(s) => s.end(), - } - } - - pub fn join(&self, other: Span) -> Option { - let ret = match (self, other) { - #[cfg(proc_macro_span)] - (Span::Compiler(a), Span::Compiler(b)) => Span::Compiler(a.join(b)?), - (Span::Fallback(a), Span::Fallback(b)) => Span::Fallback(a.join(b)?), - _ => return None, - }; - Some(ret) - } - - #[cfg(super_unstable)] - pub fn eq(&self, other: &Span) -> bool { - match (self, other) { - (Span::Compiler(a), Span::Compiler(b)) => a.eq(b), - (Span::Fallback(a), Span::Fallback(b)) => a.eq(b), - _ => false, - } - } - - pub fn source_text(&self) -> Option { - match self { - #[cfg(not(no_source_text))] - Span::Compiler(s) => s.source_text(), - #[cfg(no_source_text)] - Span::Compiler(_) => None, - Span::Fallback(s) => s.source_text(), - } - } - - fn unwrap_nightly(self) -> proc_macro::Span { - match self { - Span::Compiler(s) => s, - Span::Fallback(_) => mismatch(line!()), - } - } -} - -impl From for crate::Span { - fn from(proc_span: proc_macro::Span) -> Self { - crate::Span::_new(Span::Compiler(proc_span)) - } -} - -impl From for Span { - fn from(inner: fallback::Span) -> Self { - Span::Fallback(inner) - } -} - -impl Debug for Span { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - match self { - Span::Compiler(s) => Debug::fmt(s, f), - Span::Fallback(s) => Debug::fmt(s, f), - } - } -} - -pub(crate) fn debug_span_field_if_nontrivial(debug: &mut fmt::DebugStruct, span: Span) { - match span { - Span::Compiler(s) => { - debug.field("span", &s); - } - Span::Fallback(s) => fallback::debug_span_field_if_nontrivial(debug, s), - } -} - -#[derive(Clone)] -pub(crate) enum Group { - Compiler(proc_macro::Group), - Fallback(fallback::Group), -} - -impl Group { - pub fn new(delimiter: Delimiter, stream: TokenStream) -> Self { - match stream { - TokenStream::Compiler(tts) => { - let delimiter = match delimiter { - Delimiter::Parenthesis => proc_macro::Delimiter::Parenthesis, - Delimiter::Bracket => proc_macro::Delimiter::Bracket, - Delimiter::Brace => proc_macro::Delimiter::Brace, - Delimiter::None => proc_macro::Delimiter::None, - }; - Group::Compiler(proc_macro::Group::new(delimiter, tts.into_token_stream())) - } - TokenStream::Fallback(stream) => { - Group::Fallback(fallback::Group::new(delimiter, stream)) - } - } - } - - pub fn delimiter(&self) -> Delimiter { - match self { - Group::Compiler(g) => match g.delimiter() { - proc_macro::Delimiter::Parenthesis => Delimiter::Parenthesis, - proc_macro::Delimiter::Bracket => Delimiter::Bracket, - proc_macro::Delimiter::Brace => Delimiter::Brace, - proc_macro::Delimiter::None => Delimiter::None, - }, - Group::Fallback(g) => g.delimiter(), - } - } - - pub fn stream(&self) -> TokenStream { - match self { - Group::Compiler(g) => TokenStream::Compiler(DeferredTokenStream::new(g.stream())), - Group::Fallback(g) => TokenStream::Fallback(g.stream()), - } - } - - pub fn span(&self) -> Span { - match self { - Group::Compiler(g) => Span::Compiler(g.span()), - Group::Fallback(g) => Span::Fallback(g.span()), - } - } - - pub fn span_open(&self) -> Span { - match self { - Group::Compiler(g) => Span::Compiler(g.span_open()), - Group::Fallback(g) => Span::Fallback(g.span_open()), - } - } - - pub fn span_close(&self) -> Span { - match self { - Group::Compiler(g) => Span::Compiler(g.span_close()), - Group::Fallback(g) => Span::Fallback(g.span_close()), - } - } - - pub fn set_span(&mut self, span: Span) { - match (self, span) { - (Group::Compiler(g), Span::Compiler(s)) => g.set_span(s), - (Group::Fallback(g), Span::Fallback(s)) => g.set_span(s), - (Group::Compiler(_), Span::Fallback(_)) => mismatch(line!()), - (Group::Fallback(_), Span::Compiler(_)) => mismatch(line!()), - } - } - - fn unwrap_nightly(self) -> proc_macro::Group { - match self { - Group::Compiler(g) => g, - Group::Fallback(_) => mismatch(line!()), - } - } -} - -impl From for Group { - fn from(g: fallback::Group) -> Self { - Group::Fallback(g) - } -} - -impl Display for Group { - fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { - match self { - Group::Compiler(group) => Display::fmt(group, formatter), - Group::Fallback(group) => Display::fmt(group, formatter), - } - } -} - -impl Debug for Group { - fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { - match self { - Group::Compiler(group) => Debug::fmt(group, formatter), - Group::Fallback(group) => Debug::fmt(group, formatter), - } - } -} - -#[derive(Clone)] -pub(crate) enum Ident { - Compiler(proc_macro::Ident), - Fallback(fallback::Ident), -} - -impl Ident { - #[track_caller] - pub fn new_checked(string: &str, span: Span) -> Self { - match span { - Span::Compiler(s) => Ident::Compiler(proc_macro::Ident::new(string, s)), - Span::Fallback(s) => Ident::Fallback(fallback::Ident::new_checked(string, s)), - } - } - - pub fn new_unchecked(string: &str, span: fallback::Span) -> Self { - Ident::Fallback(fallback::Ident::new_unchecked(string, span)) - } - - #[track_caller] - pub fn new_raw_checked(string: &str, span: Span) -> Self { - match span { - Span::Compiler(s) => Ident::Compiler(proc_macro::Ident::new_raw(string, s)), - Span::Fallback(s) => Ident::Fallback(fallback::Ident::new_raw_checked(string, s)), - } - } - - pub fn new_raw_unchecked(string: &str, span: fallback::Span) -> Self { - Ident::Fallback(fallback::Ident::new_raw_unchecked(string, span)) - } - - pub fn span(&self) -> Span { - match self { - Ident::Compiler(t) => Span::Compiler(t.span()), - Ident::Fallback(t) => Span::Fallback(t.span()), - } - } - - pub fn set_span(&mut self, span: Span) { - match (self, span) { - (Ident::Compiler(t), Span::Compiler(s)) => t.set_span(s), - (Ident::Fallback(t), Span::Fallback(s)) => t.set_span(s), - (Ident::Compiler(_), Span::Fallback(_)) => mismatch(line!()), - (Ident::Fallback(_), Span::Compiler(_)) => mismatch(line!()), - } - } - - fn unwrap_nightly(self) -> proc_macro::Ident { - match self { - Ident::Compiler(s) => s, - Ident::Fallback(_) => mismatch(line!()), - } - } -} - -impl PartialEq for Ident { - fn eq(&self, other: &Ident) -> bool { - match (self, other) { - (Ident::Compiler(t), Ident::Compiler(o)) => t.to_string() == o.to_string(), - (Ident::Fallback(t), Ident::Fallback(o)) => t == o, - (Ident::Compiler(_), Ident::Fallback(_)) => mismatch(line!()), - (Ident::Fallback(_), Ident::Compiler(_)) => mismatch(line!()), - } - } -} - -impl PartialEq for Ident -where - T: ?Sized + AsRef, -{ - fn eq(&self, other: &T) -> bool { - let other = other.as_ref(); - match self { - Ident::Compiler(t) => t.to_string() == other, - Ident::Fallback(t) => t == other, - } - } -} - -impl Display for Ident { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - match self { - Ident::Compiler(t) => Display::fmt(t, f), - Ident::Fallback(t) => Display::fmt(t, f), - } - } -} - -impl Debug for Ident { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - match self { - Ident::Compiler(t) => Debug::fmt(t, f), - Ident::Fallback(t) => Debug::fmt(t, f), - } - } -} - -#[derive(Clone)] -pub(crate) enum Literal { - Compiler(proc_macro::Literal), - Fallback(fallback::Literal), -} - -macro_rules! suffixed_numbers { - ($($name:ident => $kind:ident,)*) => ($( - pub fn $name(n: $kind) -> Literal { - if inside_proc_macro() { - Literal::Compiler(proc_macro::Literal::$name(n)) - } else { - Literal::Fallback(fallback::Literal::$name(n)) - } - } - )*) -} - -macro_rules! unsuffixed_integers { - ($($name:ident => $kind:ident,)*) => ($( - pub fn $name(n: $kind) -> Literal { - if inside_proc_macro() { - Literal::Compiler(proc_macro::Literal::$name(n)) - } else { - Literal::Fallback(fallback::Literal::$name(n)) - } - } - )*) -} - -impl Literal { - pub unsafe fn from_str_unchecked(repr: &str) -> Self { - if inside_proc_macro() { - Literal::Compiler(proc_macro::Literal::from_str(repr).expect("invalid literal")) - } else { - Literal::Fallback(unsafe { fallback::Literal::from_str_unchecked(repr) }) - } - } - - suffixed_numbers! { - u8_suffixed => u8, - u16_suffixed => u16, - u32_suffixed => u32, - u64_suffixed => u64, - u128_suffixed => u128, - usize_suffixed => usize, - i8_suffixed => i8, - i16_suffixed => i16, - i32_suffixed => i32, - i64_suffixed => i64, - i128_suffixed => i128, - isize_suffixed => isize, - - f32_suffixed => f32, - f64_suffixed => f64, - } - - unsuffixed_integers! { - u8_unsuffixed => u8, - u16_unsuffixed => u16, - u32_unsuffixed => u32, - u64_unsuffixed => u64, - u128_unsuffixed => u128, - usize_unsuffixed => usize, - i8_unsuffixed => i8, - i16_unsuffixed => i16, - i32_unsuffixed => i32, - i64_unsuffixed => i64, - i128_unsuffixed => i128, - isize_unsuffixed => isize, - } - - pub fn f32_unsuffixed(f: f32) -> Literal { - if inside_proc_macro() { - Literal::Compiler(proc_macro::Literal::f32_unsuffixed(f)) - } else { - Literal::Fallback(fallback::Literal::f32_unsuffixed(f)) - } - } - - pub fn f64_unsuffixed(f: f64) -> Literal { - if inside_proc_macro() { - Literal::Compiler(proc_macro::Literal::f64_unsuffixed(f)) - } else { - Literal::Fallback(fallback::Literal::f64_unsuffixed(f)) - } - } - - pub fn string(t: &str) -> Literal { - if inside_proc_macro() { - Literal::Compiler(proc_macro::Literal::string(t)) - } else { - Literal::Fallback(fallback::Literal::string(t)) - } - } - - pub fn character(t: char) -> Literal { - if inside_proc_macro() { - Literal::Compiler(proc_macro::Literal::character(t)) - } else { - Literal::Fallback(fallback::Literal::character(t)) - } - } - - pub fn byte_string(bytes: &[u8]) -> Literal { - if inside_proc_macro() { - Literal::Compiler(proc_macro::Literal::byte_string(bytes)) - } else { - Literal::Fallback(fallback::Literal::byte_string(bytes)) - } - } - - pub fn span(&self) -> Span { - match self { - Literal::Compiler(lit) => Span::Compiler(lit.span()), - Literal::Fallback(lit) => Span::Fallback(lit.span()), - } - } - - pub fn set_span(&mut self, span: Span) { - match (self, span) { - (Literal::Compiler(lit), Span::Compiler(s)) => lit.set_span(s), - (Literal::Fallback(lit), Span::Fallback(s)) => lit.set_span(s), - (Literal::Compiler(_), Span::Fallback(_)) => mismatch(line!()), - (Literal::Fallback(_), Span::Compiler(_)) => mismatch(line!()), - } - } - - pub fn subspan>(&self, range: R) -> Option { - match self { - #[cfg(proc_macro_span)] - Literal::Compiler(lit) => lit.subspan(range).map(Span::Compiler), - #[cfg(not(proc_macro_span))] - Literal::Compiler(_lit) => None, - Literal::Fallback(lit) => lit.subspan(range).map(Span::Fallback), - } - } - - fn unwrap_nightly(self) -> proc_macro::Literal { - match self { - Literal::Compiler(s) => s, - Literal::Fallback(_) => mismatch(line!()), - } - } -} - -impl From for Literal { - fn from(s: fallback::Literal) -> Self { - Literal::Fallback(s) - } -} - -impl FromStr for Literal { - type Err = LexError; - - fn from_str(repr: &str) -> Result { - if inside_proc_macro() { - let literal = proc_macro::Literal::from_str(repr)?; - Ok(Literal::Compiler(literal)) - } else { - let literal = fallback::Literal::from_str(repr)?; - Ok(Literal::Fallback(literal)) - } - } -} - -impl Display for Literal { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - match self { - Literal::Compiler(t) => Display::fmt(t, f), - Literal::Fallback(t) => Display::fmt(t, f), - } - } -} - -impl Debug for Literal { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - match self { - Literal::Compiler(t) => Debug::fmt(t, f), - Literal::Fallback(t) => Debug::fmt(t, f), - } - } -} - -#[cfg(span_locations)] -pub(crate) fn invalidate_current_thread_spans() { - if inside_proc_macro() { - panic!( - "proc_macro2::extra::invalidate_current_thread_spans is not available in procedural macros" - ); - } else { - crate::fallback::invalidate_current_thread_spans(); - } -} diff --git a/third-party/vendor/proc-macro2/tests/comments.rs b/third-party/vendor/proc-macro2/tests/comments.rs deleted file mode 100644 index 4f7236de..00000000 --- a/third-party/vendor/proc-macro2/tests/comments.rs +++ /dev/null @@ -1,105 +0,0 @@ -#![allow(clippy::assertions_on_result_states)] - -use proc_macro2::{Delimiter, Literal, Spacing, TokenStream, TokenTree}; - -// #[doc = "..."] -> "..." -fn lit_of_outer_doc_comment(tokens: &TokenStream) -> Literal { - lit_of_doc_comment(tokens, false) -} - -// #![doc = "..."] -> "..." -fn lit_of_inner_doc_comment(tokens: &TokenStream) -> Literal { - lit_of_doc_comment(tokens, true) -} - -fn lit_of_doc_comment(tokens: &TokenStream, inner: bool) -> Literal { - let mut iter = tokens.clone().into_iter(); - match iter.next().unwrap() { - TokenTree::Punct(punct) => { - assert_eq!(punct.as_char(), '#'); - assert_eq!(punct.spacing(), Spacing::Alone); - } - _ => panic!("wrong token {:?}", tokens), - } - if inner { - match iter.next().unwrap() { - TokenTree::Punct(punct) => { - assert_eq!(punct.as_char(), '!'); - assert_eq!(punct.spacing(), Spacing::Alone); - } - _ => panic!("wrong token {:?}", tokens), - } - } - iter = match iter.next().unwrap() { - TokenTree::Group(group) => { - assert_eq!(group.delimiter(), Delimiter::Bracket); - assert!(iter.next().is_none(), "unexpected token {:?}", tokens); - group.stream().into_iter() - } - _ => panic!("wrong token {:?}", tokens), - }; - match iter.next().unwrap() { - TokenTree::Ident(ident) => assert_eq!(ident.to_string(), "doc"), - _ => panic!("wrong token {:?}", tokens), - } - match iter.next().unwrap() { - TokenTree::Punct(punct) => { - assert_eq!(punct.as_char(), '='); - assert_eq!(punct.spacing(), Spacing::Alone); - } - _ => panic!("wrong token {:?}", tokens), - } - match iter.next().unwrap() { - TokenTree::Literal(literal) => { - assert!(iter.next().is_none(), "unexpected token {:?}", tokens); - literal - } - _ => panic!("wrong token {:?}", tokens), - } -} - -#[test] -fn closed_immediately() { - let stream = "/**/".parse::().unwrap(); - let tokens = stream.into_iter().collect::>(); - assert!(tokens.is_empty(), "not empty -- {:?}", tokens); -} - -#[test] -fn incomplete() { - assert!("/*/".parse::().is_err()); -} - -#[test] -fn lit() { - let stream = "/// doc".parse::().unwrap(); - let lit = lit_of_outer_doc_comment(&stream); - assert_eq!(lit.to_string(), "\" doc\""); - - let stream = "//! doc".parse::().unwrap(); - let lit = lit_of_inner_doc_comment(&stream); - assert_eq!(lit.to_string(), "\" doc\""); - - let stream = "/** doc */".parse::().unwrap(); - let lit = lit_of_outer_doc_comment(&stream); - assert_eq!(lit.to_string(), "\" doc \""); - - let stream = "/*! doc */".parse::().unwrap(); - let lit = lit_of_inner_doc_comment(&stream); - assert_eq!(lit.to_string(), "\" doc \""); -} - -#[test] -fn carriage_return() { - let stream = "///\r\n".parse::().unwrap(); - let lit = lit_of_outer_doc_comment(&stream); - assert_eq!(lit.to_string(), "\"\""); - - let stream = "/**\r\n*/".parse::().unwrap(); - let lit = lit_of_outer_doc_comment(&stream); - assert_eq!(lit.to_string(), "\"\\r\\n\""); - - "///\r".parse::().unwrap_err(); - "///\r \n".parse::().unwrap_err(); - "/**\r \n*/".parse::().unwrap_err(); -} diff --git a/third-party/vendor/proc-macro2/tests/features.rs b/third-party/vendor/proc-macro2/tests/features.rs deleted file mode 100644 index 073f6e60..00000000 --- a/third-party/vendor/proc-macro2/tests/features.rs +++ /dev/null @@ -1,8 +0,0 @@ -#[test] -#[ignore] -fn make_sure_no_proc_macro() { - assert!( - !cfg!(feature = "proc-macro"), - "still compiled with proc_macro?" - ); -} diff --git a/third-party/vendor/proc-macro2/tests/marker.rs b/third-party/vendor/proc-macro2/tests/marker.rs deleted file mode 100644 index d08fbfc1..00000000 --- a/third-party/vendor/proc-macro2/tests/marker.rs +++ /dev/null @@ -1,99 +0,0 @@ -#![allow(clippy::extra_unused_type_parameters)] - -use proc_macro2::{ - Delimiter, Group, Ident, LexError, Literal, Punct, Spacing, Span, TokenStream, TokenTree, -}; - -macro_rules! assert_impl { - ($ty:ident is $($marker:ident) and +) => { - #[test] - #[allow(non_snake_case)] - fn $ty() { - fn assert_implemented() {} - assert_implemented::<$ty>(); - } - }; - - ($ty:ident is not $($marker:ident) or +) => { - #[test] - #[allow(non_snake_case)] - fn $ty() { - $( - { - // Implemented for types that implement $marker. - trait IsNotImplemented { - fn assert_not_implemented() {} - } - impl IsNotImplemented for T {} - - // Implemented for the type being tested. - trait IsImplemented { - fn assert_not_implemented() {} - } - impl IsImplemented for $ty {} - - // If $ty does not implement $marker, there is no ambiguity - // in the following trait method call. - <$ty>::assert_not_implemented(); - } - )+ - } - }; -} - -assert_impl!(Delimiter is Send and Sync); -assert_impl!(Spacing is Send and Sync); - -assert_impl!(Group is not Send or Sync); -assert_impl!(Ident is not Send or Sync); -assert_impl!(LexError is not Send or Sync); -assert_impl!(Literal is not Send or Sync); -assert_impl!(Punct is not Send or Sync); -assert_impl!(Span is not Send or Sync); -assert_impl!(TokenStream is not Send or Sync); -assert_impl!(TokenTree is not Send or Sync); - -#[cfg(procmacro2_semver_exempt)] -mod semver_exempt { - use proc_macro2::{LineColumn, SourceFile}; - - assert_impl!(LineColumn is Send and Sync); - - assert_impl!(SourceFile is not Send or Sync); -} - -mod unwind_safe { - use proc_macro2::{ - Delimiter, Group, Ident, LexError, Literal, Punct, Spacing, Span, TokenStream, TokenTree, - }; - #[cfg(procmacro2_semver_exempt)] - use proc_macro2::{LineColumn, SourceFile}; - use std::panic::{RefUnwindSafe, UnwindSafe}; - - macro_rules! assert_unwind_safe { - ($($types:ident)*) => { - $( - assert_impl!($types is UnwindSafe and RefUnwindSafe); - )* - }; - } - - assert_unwind_safe! { - Delimiter - Group - Ident - LexError - Literal - Punct - Spacing - Span - TokenStream - TokenTree - } - - #[cfg(procmacro2_semver_exempt)] - assert_unwind_safe! { - LineColumn - SourceFile - } -} diff --git a/third-party/vendor/proc-macro2/tests/test.rs b/third-party/vendor/proc-macro2/tests/test.rs deleted file mode 100644 index 486955cf..00000000 --- a/third-party/vendor/proc-macro2/tests/test.rs +++ /dev/null @@ -1,795 +0,0 @@ -#![allow( - clippy::assertions_on_result_states, - clippy::items_after_statements, - clippy::non_ascii_literal, - clippy::octal_escapes -)] - -use proc_macro2::{Ident, Literal, Punct, Spacing, Span, TokenStream, TokenTree}; -use std::iter; -use std::str::{self, FromStr}; - -#[test] -fn idents() { - assert_eq!( - Ident::new("String", Span::call_site()).to_string(), - "String" - ); - assert_eq!(Ident::new("fn", Span::call_site()).to_string(), "fn"); - assert_eq!(Ident::new("_", Span::call_site()).to_string(), "_"); -} - -#[test] -fn raw_idents() { - assert_eq!( - Ident::new_raw("String", Span::call_site()).to_string(), - "r#String" - ); - assert_eq!(Ident::new_raw("fn", Span::call_site()).to_string(), "r#fn"); -} - -#[test] -#[should_panic(expected = "`r#_` cannot be a raw identifier")] -fn ident_raw_underscore() { - Ident::new_raw("_", Span::call_site()); -} - -#[test] -#[should_panic(expected = "`r#super` cannot be a raw identifier")] -fn ident_raw_reserved() { - Ident::new_raw("super", Span::call_site()); -} - -#[test] -#[should_panic(expected = "Ident is not allowed to be empty; use Option")] -fn ident_empty() { - Ident::new("", Span::call_site()); -} - -#[test] -#[should_panic(expected = "Ident cannot be a number; use Literal instead")] -fn ident_number() { - Ident::new("255", Span::call_site()); -} - -#[test] -#[should_panic(expected = "\"a#\" is not a valid Ident")] -fn ident_invalid() { - Ident::new("a#", Span::call_site()); -} - -#[test] -#[should_panic(expected = "not a valid Ident")] -fn raw_ident_empty() { - Ident::new("r#", Span::call_site()); -} - -#[test] -#[should_panic(expected = "not a valid Ident")] -fn raw_ident_number() { - Ident::new("r#255", Span::call_site()); -} - -#[test] -#[should_panic(expected = "\"r#a#\" is not a valid Ident")] -fn raw_ident_invalid() { - Ident::new("r#a#", Span::call_site()); -} - -#[test] -#[should_panic(expected = "not a valid Ident")] -fn lifetime_empty() { - Ident::new("'", Span::call_site()); -} - -#[test] -#[should_panic(expected = "not a valid Ident")] -fn lifetime_number() { - Ident::new("'255", Span::call_site()); -} - -#[test] -#[should_panic(expected = r#""'a#" is not a valid Ident"#)] -fn lifetime_invalid() { - Ident::new("'a#", Span::call_site()); -} - -#[test] -fn literal_string() { - assert_eq!(Literal::string("foo").to_string(), "\"foo\""); - assert_eq!(Literal::string("\"").to_string(), "\"\\\"\""); - assert_eq!(Literal::string("didn't").to_string(), "\"didn't\""); - assert_eq!( - Literal::string("a\00b\07c\08d\0e\0").to_string(), - "\"a\\x000b\\x007c\\08d\\0e\\0\"", - ); - - "\"\\\r\n x\"".parse::().unwrap(); - "\"\\\r\n \rx\"".parse::().unwrap_err(); -} - -#[test] -fn literal_raw_string() { - "r\"\r\n\"".parse::().unwrap(); - - fn raw_string_literal_with_hashes(n: usize) -> String { - let mut literal = String::new(); - literal.push('r'); - literal.extend(iter::repeat('#').take(n)); - literal.push('"'); - literal.push('"'); - literal.extend(iter::repeat('#').take(n)); - literal - } - - raw_string_literal_with_hashes(255) - .parse::() - .unwrap(); - - // https://github.com/rust-lang/rust/pull/95251 - raw_string_literal_with_hashes(256) - .parse::() - .unwrap_err(); -} - -#[test] -fn literal_byte_string() { - assert_eq!(Literal::byte_string(b"").to_string(), "b\"\""); - assert_eq!( - Literal::byte_string(b"\0\t\n\r\"\\2\x10").to_string(), - "b\"\\0\\t\\n\\r\\\"\\\\2\\x10\"", - ); - assert_eq!( - Literal::byte_string(b"a\00b\07c\08d\0e\0").to_string(), - "b\"a\\x000b\\x007c\\08d\\0e\\0\"", - ); - - "b\"\\\r\n x\"".parse::().unwrap(); - "b\"\\\r\n \rx\"".parse::().unwrap_err(); - "b\"\\\r\n \u{a0}x\"".parse::().unwrap_err(); - "br\"\u{a0}\"".parse::().unwrap_err(); -} - -#[test] -fn literal_c_string() { - let strings = r###" - c"hello\x80我叫\u{1F980}" // from the RFC - cr"\" - cr##"Hello "world"!"## - c"\t\n\r\"\\" - "###; - - let mut tokens = strings.parse::().unwrap().into_iter(); - - for expected in &[ - r#"c"hello\x80我叫\u{1F980}""#, - r#"cr"\""#, - r###"cr##"Hello "world"!"##"###, - r#"c"\t\n\r\"\\""#, - ] { - match tokens.next().unwrap() { - TokenTree::Literal(literal) => { - assert_eq!(literal.to_string(), *expected); - } - unexpected => panic!("unexpected token: {:?}", unexpected), - } - } - - if let Some(unexpected) = tokens.next() { - panic!("unexpected token: {:?}", unexpected); - } - - for invalid in &[r#"c"\0""#, r#"c"\x00""#, r#"c"\u{0}""#, "c\"\0\""] { - if let Ok(unexpected) = invalid.parse::() { - panic!("unexpected token: {:?}", unexpected); - } - } -} - -#[test] -fn literal_character() { - assert_eq!(Literal::character('x').to_string(), "'x'"); - assert_eq!(Literal::character('\'').to_string(), "'\\''"); - assert_eq!(Literal::character('"').to_string(), "'\"'"); -} - -#[test] -fn literal_integer() { - assert_eq!(Literal::u8_suffixed(10).to_string(), "10u8"); - assert_eq!(Literal::u16_suffixed(10).to_string(), "10u16"); - assert_eq!(Literal::u32_suffixed(10).to_string(), "10u32"); - assert_eq!(Literal::u64_suffixed(10).to_string(), "10u64"); - assert_eq!(Literal::u128_suffixed(10).to_string(), "10u128"); - assert_eq!(Literal::usize_suffixed(10).to_string(), "10usize"); - - assert_eq!(Literal::i8_suffixed(10).to_string(), "10i8"); - assert_eq!(Literal::i16_suffixed(10).to_string(), "10i16"); - assert_eq!(Literal::i32_suffixed(10).to_string(), "10i32"); - assert_eq!(Literal::i64_suffixed(10).to_string(), "10i64"); - assert_eq!(Literal::i128_suffixed(10).to_string(), "10i128"); - assert_eq!(Literal::isize_suffixed(10).to_string(), "10isize"); - - assert_eq!(Literal::u8_unsuffixed(10).to_string(), "10"); - assert_eq!(Literal::u16_unsuffixed(10).to_string(), "10"); - assert_eq!(Literal::u32_unsuffixed(10).to_string(), "10"); - assert_eq!(Literal::u64_unsuffixed(10).to_string(), "10"); - assert_eq!(Literal::u128_unsuffixed(10).to_string(), "10"); - assert_eq!(Literal::usize_unsuffixed(10).to_string(), "10"); - - assert_eq!(Literal::i8_unsuffixed(10).to_string(), "10"); - assert_eq!(Literal::i16_unsuffixed(10).to_string(), "10"); - assert_eq!(Literal::i32_unsuffixed(10).to_string(), "10"); - assert_eq!(Literal::i64_unsuffixed(10).to_string(), "10"); - assert_eq!(Literal::i128_unsuffixed(10).to_string(), "10"); - assert_eq!(Literal::isize_unsuffixed(10).to_string(), "10"); -} - -#[test] -fn literal_float() { - assert_eq!(Literal::f32_suffixed(10.0).to_string(), "10f32"); - assert_eq!(Literal::f64_suffixed(10.0).to_string(), "10f64"); - - assert_eq!(Literal::f32_unsuffixed(10.0).to_string(), "10.0"); - assert_eq!(Literal::f64_unsuffixed(10.0).to_string(), "10.0"); -} - -#[test] -fn literal_suffix() { - fn token_count(p: &str) -> usize { - p.parse::().unwrap().into_iter().count() - } - - assert_eq!(token_count("999u256"), 1); - assert_eq!(token_count("999r#u256"), 3); - assert_eq!(token_count("1."), 1); - assert_eq!(token_count("1.f32"), 3); - assert_eq!(token_count("1.0_0"), 1); - assert_eq!(token_count("1._0"), 3); - assert_eq!(token_count("1._m"), 3); - assert_eq!(token_count("\"\"s"), 1); - assert_eq!(token_count("r\"\"r"), 1); - assert_eq!(token_count("b\"\"b"), 1); - assert_eq!(token_count("br\"\"br"), 1); - assert_eq!(token_count("r#\"\"#r"), 1); - assert_eq!(token_count("'c'c"), 1); - assert_eq!(token_count("b'b'b"), 1); - assert_eq!(token_count("0E"), 1); - assert_eq!(token_count("0o0A"), 1); - assert_eq!(token_count("0E--0"), 4); - assert_eq!(token_count("0.0ECMA"), 1); -} - -#[test] -fn literal_iter_negative() { - let negative_literal = Literal::i32_suffixed(-3); - let tokens = TokenStream::from(TokenTree::Literal(negative_literal)); - let mut iter = tokens.into_iter(); - match iter.next().unwrap() { - TokenTree::Punct(punct) => { - assert_eq!(punct.as_char(), '-'); - assert_eq!(punct.spacing(), Spacing::Alone); - } - unexpected => panic!("unexpected token {:?}", unexpected), - } - match iter.next().unwrap() { - TokenTree::Literal(literal) => { - assert_eq!(literal.to_string(), "3i32"); - } - unexpected => panic!("unexpected token {:?}", unexpected), - } - assert!(iter.next().is_none()); -} - -#[test] -fn literal_parse() { - assert!("1".parse::().is_ok()); - assert!("-1".parse::().is_ok()); - assert!("-1u12".parse::().is_ok()); - assert!("1.0".parse::().is_ok()); - assert!("-1.0".parse::().is_ok()); - assert!("-1.0f12".parse::().is_ok()); - assert!("'a'".parse::().is_ok()); - assert!("\"\n\"".parse::().is_ok()); - assert!("0 1".parse::().is_err()); - assert!(" 0".parse::().is_err()); - assert!("0 ".parse::().is_err()); - assert!("/* comment */0".parse::().is_err()); - assert!("0/* comment */".parse::().is_err()); - assert!("0// comment".parse::().is_err()); - assert!("- 1".parse::().is_err()); - assert!("- 1.0".parse::().is_err()); - assert!("-\"\"".parse::().is_err()); -} - -#[test] -fn literal_span() { - let positive = "0.1".parse::().unwrap(); - let negative = "-0.1".parse::().unwrap(); - let subspan = positive.subspan(1..2); - - #[cfg(not(span_locations))] - { - let _ = negative; - assert!(subspan.is_none()); - } - - #[cfg(span_locations)] - { - assert_eq!(positive.span().start().column, 0); - assert_eq!(positive.span().end().column, 3); - assert_eq!(negative.span().start().column, 0); - assert_eq!(negative.span().end().column, 4); - assert_eq!(subspan.unwrap().source_text().unwrap(), "."); - } - - assert!(positive.subspan(1..4).is_none()); -} - -#[cfg(span_locations)] -#[test] -fn source_text() { - let input = " 𓀕 a z "; - let mut tokens = input - .parse::() - .unwrap() - .into_iter(); - - let first = tokens.next().unwrap(); - assert_eq!("𓀕", first.span().source_text().unwrap()); - - let second = tokens.next().unwrap(); - let third = tokens.next().unwrap(); - assert_eq!("z", third.span().source_text().unwrap()); - assert_eq!("a", second.span().source_text().unwrap()); -} - -#[test] -fn roundtrip() { - fn roundtrip(p: &str) { - println!("parse: {}", p); - let s = p.parse::().unwrap().to_string(); - println!("first: {}", s); - let s2 = s.parse::().unwrap().to_string(); - assert_eq!(s, s2); - } - roundtrip("a"); - roundtrip("<<"); - roundtrip("<<="); - roundtrip( - " - 1 - 1.0 - 1f32 - 2f64 - 1usize - 4isize - 4e10 - 1_000 - 1_0i32 - 8u8 - 9 - 0 - 0xffffffffffffffffffffffffffffffff - 1x - 1u80 - 1f320 - ", - ); - roundtrip("'a"); - roundtrip("'_"); - roundtrip("'static"); - roundtrip("'\\u{10__FFFF}'"); - roundtrip("\"\\u{10_F0FF__}foo\\u{1_0_0_0__}\""); -} - -#[test] -fn fail() { - fn fail(p: &str) { - if let Ok(s) = p.parse::() { - panic!("should have failed to parse: {}\n{:#?}", p, s); - } - } - fail("' static"); - fail("r#1"); - fail("r#_"); - fail("\"\\u{0000000}\""); // overlong unicode escape (rust allows at most 6 hex digits) - fail("\"\\u{999999}\""); // outside of valid range of char - fail("\"\\u{_0}\""); // leading underscore - fail("\"\\u{}\""); // empty - fail("b\"\r\""); // bare carriage return in byte string - fail("r\"\r\""); // bare carriage return in raw string - fail("\"\\\r \""); // backslash carriage return - fail("'aa'aa"); - fail("br##\"\"#"); - fail("\"\\\n\u{85}\r\""); -} - -#[cfg(span_locations)] -#[test] -fn span_test() { - check_spans( - "\ -/// This is a document comment -testing 123 -{ - testing 234 -}", - &[ - (1, 0, 1, 30), // # - (1, 0, 1, 30), // [ ... ] - (1, 0, 1, 30), // doc - (1, 0, 1, 30), // = - (1, 0, 1, 30), // "This is..." - (2, 0, 2, 7), // testing - (2, 8, 2, 11), // 123 - (3, 0, 5, 1), // { ... } - (4, 2, 4, 9), // testing - (4, 10, 4, 13), // 234 - ], - ); -} - -#[cfg(procmacro2_semver_exempt)] -#[cfg(not(nightly))] -#[test] -fn default_span() { - let start = Span::call_site().start(); - assert_eq!(start.line, 1); - assert_eq!(start.column, 0); - let end = Span::call_site().end(); - assert_eq!(end.line, 1); - assert_eq!(end.column, 0); - let source_file = Span::call_site().source_file(); - assert_eq!(source_file.path().to_string_lossy(), ""); - assert!(!source_file.is_real()); -} - -#[cfg(procmacro2_semver_exempt)] -#[test] -fn span_join() { - let source1 = "aaa\nbbb" - .parse::() - .unwrap() - .into_iter() - .collect::>(); - let source2 = "ccc\nddd" - .parse::() - .unwrap() - .into_iter() - .collect::>(); - - assert!(source1[0].span().source_file() != source2[0].span().source_file()); - assert_eq!( - source1[0].span().source_file(), - source1[1].span().source_file() - ); - - let joined1 = source1[0].span().join(source1[1].span()); - let joined2 = source1[0].span().join(source2[0].span()); - assert!(joined1.is_some()); - assert!(joined2.is_none()); - - let start = joined1.unwrap().start(); - let end = joined1.unwrap().end(); - assert_eq!(start.line, 1); - assert_eq!(start.column, 0); - assert_eq!(end.line, 2); - assert_eq!(end.column, 3); - - assert_eq!( - joined1.unwrap().source_file(), - source1[0].span().source_file() - ); -} - -#[test] -fn no_panic() { - let s = str::from_utf8(b"b\'\xc2\x86 \x00\x00\x00^\"").unwrap(); - assert!(s.parse::().is_err()); -} - -#[test] -fn punct_before_comment() { - let mut tts = TokenStream::from_str("~// comment").unwrap().into_iter(); - match tts.next().unwrap() { - TokenTree::Punct(tt) => { - assert_eq!(tt.as_char(), '~'); - assert_eq!(tt.spacing(), Spacing::Alone); - } - wrong => panic!("wrong token {:?}", wrong), - } -} - -#[test] -fn joint_last_token() { - // This test verifies that we match the behavior of libproc_macro *not* in - // the range nightly-2020-09-06 through nightly-2020-09-10, in which this - // behavior was temporarily broken. - // See https://github.com/rust-lang/rust/issues/76399 - - let joint_punct = Punct::new(':', Spacing::Joint); - let stream = TokenStream::from(TokenTree::Punct(joint_punct)); - let punct = match stream.into_iter().next().unwrap() { - TokenTree::Punct(punct) => punct, - _ => unreachable!(), - }; - assert_eq!(punct.spacing(), Spacing::Joint); -} - -#[test] -fn raw_identifier() { - let mut tts = TokenStream::from_str("r#dyn").unwrap().into_iter(); - match tts.next().unwrap() { - TokenTree::Ident(raw) => assert_eq!("r#dyn", raw.to_string()), - wrong => panic!("wrong token {:?}", wrong), - } - assert!(tts.next().is_none()); -} - -#[test] -fn test_debug_ident() { - let ident = Ident::new("proc_macro", Span::call_site()); - - #[cfg(not(span_locations))] - let expected = "Ident(proc_macro)"; - - #[cfg(span_locations)] - let expected = "Ident { sym: proc_macro }"; - - assert_eq!(expected, format!("{:?}", ident)); -} - -#[test] -fn test_debug_tokenstream() { - let tts = TokenStream::from_str("[a + 1]").unwrap(); - - #[cfg(not(span_locations))] - let expected = "\ -TokenStream [ - Group { - delimiter: Bracket, - stream: TokenStream [ - Ident { - sym: a, - }, - Punct { - char: '+', - spacing: Alone, - }, - Literal { - lit: 1, - }, - ], - }, -]\ - "; - - #[cfg(not(span_locations))] - let expected_before_trailing_commas = "\ -TokenStream [ - Group { - delimiter: Bracket, - stream: TokenStream [ - Ident { - sym: a - }, - Punct { - char: '+', - spacing: Alone - }, - Literal { - lit: 1 - } - ] - } -]\ - "; - - #[cfg(span_locations)] - let expected = "\ -TokenStream [ - Group { - delimiter: Bracket, - stream: TokenStream [ - Ident { - sym: a, - span: bytes(2..3), - }, - Punct { - char: '+', - spacing: Alone, - span: bytes(4..5), - }, - Literal { - lit: 1, - span: bytes(6..7), - }, - ], - span: bytes(1..8), - }, -]\ - "; - - #[cfg(span_locations)] - let expected_before_trailing_commas = "\ -TokenStream [ - Group { - delimiter: Bracket, - stream: TokenStream [ - Ident { - sym: a, - span: bytes(2..3) - }, - Punct { - char: '+', - spacing: Alone, - span: bytes(4..5) - }, - Literal { - lit: 1, - span: bytes(6..7) - } - ], - span: bytes(1..8) - } -]\ - "; - - let actual = format!("{:#?}", tts); - if actual.ends_with(",\n]") { - assert_eq!(expected, actual); - } else { - assert_eq!(expected_before_trailing_commas, actual); - } -} - -#[test] -fn default_tokenstream_is_empty() { - let default_token_stream = ::default(); - - assert!(default_token_stream.is_empty()); -} - -#[test] -fn tokenstream_size_hint() { - let tokens = "a b (c d) e".parse::().unwrap(); - - assert_eq!(tokens.into_iter().size_hint(), (4, Some(4))); -} - -#[test] -fn tuple_indexing() { - // This behavior may change depending on https://github.com/rust-lang/rust/pull/71322 - let mut tokens = "tuple.0.0".parse::().unwrap().into_iter(); - assert_eq!("tuple", tokens.next().unwrap().to_string()); - assert_eq!(".", tokens.next().unwrap().to_string()); - assert_eq!("0.0", tokens.next().unwrap().to_string()); - assert!(tokens.next().is_none()); -} - -#[cfg(span_locations)] -#[test] -fn non_ascii_tokens() { - check_spans("// abc", &[]); - check_spans("// ábc", &[]); - check_spans("// abc x", &[]); - check_spans("// ábc x", &[]); - check_spans("/* abc */ x", &[(1, 10, 1, 11)]); - check_spans("/* ábc */ x", &[(1, 10, 1, 11)]); - check_spans("/* ab\nc */ x", &[(2, 5, 2, 6)]); - check_spans("/* áb\nc */ x", &[(2, 5, 2, 6)]); - check_spans("/*** abc */ x", &[(1, 12, 1, 13)]); - check_spans("/*** ábc */ x", &[(1, 12, 1, 13)]); - check_spans(r#""abc""#, &[(1, 0, 1, 5)]); - check_spans(r#""ábc""#, &[(1, 0, 1, 5)]); - check_spans(r##"r#"abc"#"##, &[(1, 0, 1, 8)]); - check_spans(r##"r#"ábc"#"##, &[(1, 0, 1, 8)]); - check_spans("r#\"a\nc\"#", &[(1, 0, 2, 3)]); - check_spans("r#\"á\nc\"#", &[(1, 0, 2, 3)]); - check_spans("'a'", &[(1, 0, 1, 3)]); - check_spans("'á'", &[(1, 0, 1, 3)]); - check_spans("//! abc", &[(1, 0, 1, 7), (1, 0, 1, 7), (1, 0, 1, 7)]); - check_spans("//! ábc", &[(1, 0, 1, 7), (1, 0, 1, 7), (1, 0, 1, 7)]); - check_spans("//! abc\n", &[(1, 0, 1, 7), (1, 0, 1, 7), (1, 0, 1, 7)]); - check_spans("//! ábc\n", &[(1, 0, 1, 7), (1, 0, 1, 7), (1, 0, 1, 7)]); - check_spans("/*! abc */", &[(1, 0, 1, 10), (1, 0, 1, 10), (1, 0, 1, 10)]); - check_spans("/*! ábc */", &[(1, 0, 1, 10), (1, 0, 1, 10), (1, 0, 1, 10)]); - check_spans("/*! a\nc */", &[(1, 0, 2, 4), (1, 0, 2, 4), (1, 0, 2, 4)]); - check_spans("/*! á\nc */", &[(1, 0, 2, 4), (1, 0, 2, 4), (1, 0, 2, 4)]); - check_spans("abc", &[(1, 0, 1, 3)]); - check_spans("ábc", &[(1, 0, 1, 3)]); - check_spans("ábć", &[(1, 0, 1, 3)]); - check_spans("abc// foo", &[(1, 0, 1, 3)]); - check_spans("ábc// foo", &[(1, 0, 1, 3)]); - check_spans("ábć// foo", &[(1, 0, 1, 3)]); - check_spans("b\"a\\\n c\"", &[(1, 0, 2, 3)]); -} - -#[cfg(span_locations)] -fn check_spans(p: &str, mut lines: &[(usize, usize, usize, usize)]) { - let ts = p.parse::().unwrap(); - check_spans_internal(ts, &mut lines); - assert!(lines.is_empty(), "leftover ranges: {:?}", lines); -} - -#[cfg(span_locations)] -fn check_spans_internal(ts: TokenStream, lines: &mut &[(usize, usize, usize, usize)]) { - for i in ts { - if let Some((&(sline, scol, eline, ecol), rest)) = lines.split_first() { - *lines = rest; - - let start = i.span().start(); - assert_eq!(start.line, sline, "sline did not match for {}", i); - assert_eq!(start.column, scol, "scol did not match for {}", i); - - let end = i.span().end(); - assert_eq!(end.line, eline, "eline did not match for {}", i); - assert_eq!(end.column, ecol, "ecol did not match for {}", i); - - if let TokenTree::Group(g) = i { - check_spans_internal(g.stream().clone(), lines); - } - } - } -} - -#[test] -fn whitespace() { - // space, horizontal tab, vertical tab, form feed, carriage return, line - // feed, non-breaking space, left-to-right mark, right-to-left mark - let various_spaces = " \t\u{b}\u{c}\r\n\u{a0}\u{200e}\u{200f}"; - let tokens = various_spaces.parse::().unwrap(); - assert_eq!(tokens.into_iter().count(), 0); - - let lone_carriage_returns = " \r \r\r\n "; - lone_carriage_returns.parse::().unwrap(); -} - -#[test] -fn byte_order_mark() { - let string = "\u{feff}foo"; - let tokens = string.parse::().unwrap(); - match tokens.into_iter().next().unwrap() { - TokenTree::Ident(ident) => assert_eq!(ident, "foo"), - _ => unreachable!(), - } - - let string = "foo\u{feff}"; - string.parse::().unwrap_err(); -} - -#[cfg(span_locations)] -fn create_span() -> proc_macro2::Span { - let tts: TokenStream = "1".parse().unwrap(); - match tts.into_iter().next().unwrap() { - TokenTree::Literal(literal) => literal.span(), - _ => unreachable!(), - } -} - -#[cfg(span_locations)] -#[test] -fn test_invalidate_current_thread_spans() { - let actual = format!("{:#?}", create_span()); - assert_eq!(actual, "bytes(1..2)"); - let actual = format!("{:#?}", create_span()); - assert_eq!(actual, "bytes(3..4)"); - - proc_macro2::extra::invalidate_current_thread_spans(); - - let actual = format!("{:#?}", create_span()); - // Test that span offsets have been reset after the call - // to invalidate_current_thread_spans() - assert_eq!(actual, "bytes(1..2)"); -} - -#[cfg(span_locations)] -#[test] -#[should_panic(expected = "Invalid span with no related FileInfo!")] -fn test_use_span_after_invalidation() { - let span = create_span(); - - proc_macro2::extra::invalidate_current_thread_spans(); - - span.source_text(); -} diff --git a/third-party/vendor/proc-macro2/tests/test_fmt.rs b/third-party/vendor/proc-macro2/tests/test_fmt.rs deleted file mode 100644 index 86a4c387..00000000 --- a/third-party/vendor/proc-macro2/tests/test_fmt.rs +++ /dev/null @@ -1,28 +0,0 @@ -#![allow(clippy::from_iter_instead_of_collect)] - -use proc_macro2::{Delimiter, Group, Ident, Span, TokenStream, TokenTree}; -use std::iter; - -#[test] -fn test_fmt_group() { - let ident = Ident::new("x", Span::call_site()); - let inner = TokenStream::from_iter(iter::once(TokenTree::Ident(ident))); - let parens_empty = Group::new(Delimiter::Parenthesis, TokenStream::new()); - let parens_nonempty = Group::new(Delimiter::Parenthesis, inner.clone()); - let brackets_empty = Group::new(Delimiter::Bracket, TokenStream::new()); - let brackets_nonempty = Group::new(Delimiter::Bracket, inner.clone()); - let braces_empty = Group::new(Delimiter::Brace, TokenStream::new()); - let braces_nonempty = Group::new(Delimiter::Brace, inner.clone()); - let none_empty = Group::new(Delimiter::None, TokenStream::new()); - let none_nonempty = Group::new(Delimiter::None, inner); - - // Matches libproc_macro. - assert_eq!("()", parens_empty.to_string()); - assert_eq!("(x)", parens_nonempty.to_string()); - assert_eq!("[]", brackets_empty.to_string()); - assert_eq!("[x]", brackets_nonempty.to_string()); - assert_eq!("{ }", braces_empty.to_string()); - assert_eq!("{ x }", braces_nonempty.to_string()); - assert_eq!("", none_empty.to_string()); - assert_eq!("x", none_nonempty.to_string()); -} diff --git a/third-party/vendor/proc-macro2/tests/test_size.rs b/third-party/vendor/proc-macro2/tests/test_size.rs deleted file mode 100644 index 46e58db4..00000000 --- a/third-party/vendor/proc-macro2/tests/test_size.rs +++ /dev/null @@ -1,42 +0,0 @@ -extern crate proc_macro; - -use std::mem; - -#[rustversion::attr(before(1.32), ignore)] -#[test] -fn test_proc_macro_span_size() { - assert_eq!(mem::size_of::(), 4); - assert_eq!(mem::size_of::>(), 4); -} - -#[cfg_attr(not(all(not(wrap_proc_macro), not(span_locations))), ignore)] -#[test] -fn test_proc_macro2_fallback_span_size_without_locations() { - assert_eq!(mem::size_of::(), 0); - assert_eq!(mem::size_of::>(), 1); -} - -#[cfg_attr(not(all(not(wrap_proc_macro), span_locations)), ignore)] -#[test] -fn test_proc_macro2_fallback_span_size_with_locations() { - assert_eq!(mem::size_of::(), 8); - assert_eq!(mem::size_of::>(), 12); -} - -#[rustversion::attr(before(1.32), ignore)] -#[rustversion::attr( - since(1.32), - cfg_attr(not(all(wrap_proc_macro, not(span_locations))), ignore) -)] -#[test] -fn test_proc_macro2_wrapper_span_size_without_locations() { - assert_eq!(mem::size_of::(), 4); - assert_eq!(mem::size_of::>(), 8); -} - -#[cfg_attr(not(all(wrap_proc_macro, span_locations)), ignore)] -#[test] -fn test_proc_macro2_wrapper_span_size_with_locations() { - assert_eq!(mem::size_of::(), 12); - assert_eq!(mem::size_of::>(), 12); -} diff --git a/third-party/vendor/quote/.cargo-checksum.json b/third-party/vendor/quote/.cargo-checksum.json deleted file mode 100644 index 0d900a27..00000000 --- a/third-party/vendor/quote/.cargo-checksum.json +++ /dev/null @@ -1 +0,0 @@ -{"files":{"Cargo.toml":"0ec1e0fd36354750321a12d04a5e4d9a8d5dc6a8af753183de50da55fc10391b","LICENSE-APACHE":"62c7a1e35f56406896d7aa7ca52d0cc0d272ac022b5d2796e7d6905db8a3636a","LICENSE-MIT":"23f18e03dc49df91622fe2a76176497404e46ced8a715d9d2b67a7446571cca3","README.md":"626e7079eab0baacf0fcaf3e244f407b2014ebaeca45905d72e8fb8bed18aaea","rust-toolchain.toml":"6bbb61302978c736b2da03e4fb40e3beab908f85d533ab46fd541e637b5f3e0f","src/ext.rs":"9881576cac3e476a4bf04f9b601cf9a53b79399fb0ca9634e8b861ac91709843","src/format.rs":"c595015418f35e6992e710441b9999f09b2afe4678b138039d670d100c0bdd86","src/ident_fragment.rs":"0b3e6c2129e55910fd2d240e1e7efba6f1796801d24352d1c0bfbceb0e8b678f","src/lib.rs":"cef1b4c031d401fb87e88a2ed51858c5f8f471e62a6261c1ef0f55ef9e1906a1","src/runtime.rs":"7f37326edaeac2c42ed806b447eeba12e36dd4b1bc25fbf52f8eb23140f3be7a","src/spanned.rs":"3ccf5120593f35787442c0a37d243e802c5262e7f8b35aed503873008ec035c5","src/to_tokens.rs":"1c76311fcc82098e630056d71fd6f3929194ee31b0840e2aa643ed7e78026e3e","tests/compiletest.rs":"022a8e400ef813d7ea1875b944549cee5125f6a995dc33e93b48cba3e1b57bd1","tests/test.rs":"3be80741f84a707376c230d9cf70ce9537caa359691d8d4c34968e28175e4ad7","tests/ui/does-not-have-iter-interpolated-dup.rs":"ad13eea21d4cdd2ab6c082f633392e1ff20fb0d1af5f2177041e0bf7f30da695","tests/ui/does-not-have-iter-interpolated-dup.stderr":"90a4bdb9267535f5d2785940148338d6b7d905548051d2c9c5dcbd58f2c11d8e","tests/ui/does-not-have-iter-interpolated.rs":"83a5b3f240651adcbe4b6e51076d76d653ad439b37442cf4054f1fd3c073f3b7","tests/ui/does-not-have-iter-interpolated.stderr":"ae7c2739554c862b331705e82781aa4687a4375210cef6ae899a4be4a4ec2d97","tests/ui/does-not-have-iter-separated.rs":"fe413c48331d5e3a7ae5fef6a5892a90c72f610d54595879eb49d0a94154ba3f","tests/ui/does-not-have-iter-separated.stderr":"03fd560979ebcd5aa6f83858bc2c3c01ba6546c16335101275505304895c1ae9","tests/ui/does-not-have-iter.rs":"09dc9499d861b63cebb0848b855b78e2dc9497bfde37ba6339f3625ae009a62f","tests/ui/does-not-have-iter.stderr":"d6da483c29e232ced72059bbdf05d31afb1df9e02954edaa9cfaea1ec6df72dc","tests/ui/not-quotable.rs":"5759d0884943417609f28faadc70254a3e2fd3d9bd6ff7297a3fb70a77fafd8a","tests/ui/not-quotable.stderr":"459bdadbf1e73b9401cf7d5d578dc053774bb4e5aa25ad2abf25d6b0f61aa306","tests/ui/not-repeatable.rs":"a4b115c04e4e41049a05f5b69450503fbffeba031218b4189cb931839f7f9a9c","tests/ui/not-repeatable.stderr":"594249d59d16f039c16816f1aaf9933176994e296fcf81d1b8b24d5b66ae0d0a","tests/ui/wrong-type-span.rs":"6195e35ea844c0c52ba1cff5d790c3a371af6915d137d377834ad984229ef9ea","tests/ui/wrong-type-span.stderr":"cad072e40e0ecc04f375122ae41aede2f0da2a9244492b3fcf70249e59d1b128"},"package":"291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef"} \ No newline at end of file diff --git a/third-party/vendor/quote/Cargo.toml b/third-party/vendor/quote/Cargo.toml deleted file mode 100644 index f3222c25..00000000 --- a/third-party/vendor/quote/Cargo.toml +++ /dev/null @@ -1,50 +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 are reading this file be aware that the original Cargo.toml -# will likely look very different (and much more reasonable). -# See Cargo.toml.orig for the original contents. - -[package] -edition = "2018" -rust-version = "1.56" -name = "quote" -version = "1.0.35" -authors = ["David Tolnay "] -autobenches = false -description = "Quasi-quoting macro quote!(...)" -documentation = "https://docs.rs/quote/" -readme = "README.md" -keywords = [ - "macros", - "syn", -] -categories = ["development-tools::procedural-macro-helpers"] -license = "MIT OR Apache-2.0" -repository = "https://github.com/dtolnay/quote" - -[package.metadata.docs.rs] -rustdoc-args = ["--generate-link-to-definition"] -targets = ["x86_64-unknown-linux-gnu"] - -[lib] -doc-scrape-examples = false - -[dependencies.proc-macro2] -version = "1.0.74" -default-features = false - -[dev-dependencies.rustversion] -version = "1.0" - -[dev-dependencies.trybuild] -version = "1.0.66" -features = ["diff"] - -[features] -default = ["proc-macro"] -proc-macro = ["proc-macro2/proc-macro"] diff --git a/third-party/vendor/quote/LICENSE-APACHE b/third-party/vendor/quote/LICENSE-APACHE deleted file mode 100644 index 1b5ec8b7..00000000 --- a/third-party/vendor/quote/LICENSE-APACHE +++ /dev/null @@ -1,176 +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 diff --git a/third-party/vendor/quote/LICENSE-MIT b/third-party/vendor/quote/LICENSE-MIT deleted file mode 100644 index 31aa7938..00000000 --- a/third-party/vendor/quote/LICENSE-MIT +++ /dev/null @@ -1,23 +0,0 @@ -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. diff --git a/third-party/vendor/quote/README.md b/third-party/vendor/quote/README.md deleted file mode 100644 index bfc91a97..00000000 --- a/third-party/vendor/quote/README.md +++ /dev/null @@ -1,272 +0,0 @@ -Rust Quasi-Quoting -================== - -[github](https://github.com/dtolnay/quote) -[crates.io](https://crates.io/crates/quote) -[docs.rs](https://docs.rs/quote) -[build status](https://github.com/dtolnay/quote/actions?query=branch%3Amaster) - -This crate provides the [`quote!`] macro for turning Rust syntax tree data -structures into tokens of source code. - -[`quote!`]: https://docs.rs/quote/1.0/quote/macro.quote.html - -Procedural macros in Rust receive a stream of tokens as input, execute arbitrary -Rust code to determine how to manipulate those tokens, and produce a stream of -tokens to hand back to the compiler to compile into the caller's crate. -Quasi-quoting is a solution to one piece of that — producing tokens to -return to the compiler. - -The idea of quasi-quoting is that we write *code* that we treat as *data*. -Within the `quote!` macro, we can write what looks like code to our text editor -or IDE. We get all the benefits of the editor's brace matching, syntax -highlighting, indentation, and maybe autocompletion. But rather than compiling -that as code into the current crate, we can treat it as data, pass it around, -mutate it, and eventually hand it back to the compiler as tokens to compile into -the macro caller's crate. - -This crate is motivated by the procedural macro use case, but is a -general-purpose Rust quasi-quoting library and is not specific to procedural -macros. - -```toml -[dependencies] -quote = "1.0" -``` - -*Version requirement: Quote supports rustc 1.56 and up.*
-[*Release notes*](https://github.com/dtolnay/quote/releases) - -
- -## Syntax - -The quote crate provides a [`quote!`] macro within which you can write Rust code -that gets packaged into a [`TokenStream`] and can be treated as data. You should -think of `TokenStream` as representing a fragment of Rust source code. - -[`TokenStream`]: https://docs.rs/proc-macro2/1.0/proc_macro2/struct.TokenStream.html - -Within the `quote!` macro, interpolation is done with `#var`. Any type -implementing the [`quote::ToTokens`] trait can be interpolated. This includes -most Rust primitive types as well as most of the syntax tree types from [`syn`]. - -[`quote::ToTokens`]: https://docs.rs/quote/1.0/quote/trait.ToTokens.html -[`syn`]: https://github.com/dtolnay/syn - -```rust -let tokens = quote! { - struct SerializeWith #generics #where_clause { - value: &'a #field_ty, - phantom: core::marker::PhantomData<#item_ty>, - } - - impl #generics serde::Serialize for SerializeWith #generics #where_clause { - fn serialize(&self, serializer: S) -> Result - where - S: serde::Serializer, - { - #path(self.value, serializer) - } - } - - SerializeWith { - value: #value, - phantom: core::marker::PhantomData::<#item_ty>, - } -}; -``` - -
- -## Repetition - -Repetition is done using `#(...)*` or `#(...),*` similar to `macro_rules!`. This -iterates through the elements of any variable interpolated within the repetition -and inserts a copy of the repetition body for each one. The variables in an -interpolation may be anything that implements `IntoIterator`, including `Vec` or -a pre-existing iterator. - -- `#(#var)*` — no separators -- `#(#var),*` — the character before the asterisk is used as a separator -- `#( struct #var; )*` — the repetition can contain other things -- `#( #k => println!("{}", #v), )*` — even multiple interpolations - -Note that there is a difference between `#(#var ,)*` and `#(#var),*`—the latter -does not produce a trailing comma. This matches the behavior of delimiters in -`macro_rules!`. - -
- -## Returning tokens to the compiler - -The `quote!` macro evaluates to an expression of type -`proc_macro2::TokenStream`. Meanwhile Rust procedural macros are expected to -return the type `proc_macro::TokenStream`. - -The difference between the two types is that `proc_macro` types are entirely -specific to procedural macros and cannot ever exist in code outside of a -procedural macro, while `proc_macro2` types may exist anywhere including tests -and non-macro code like main.rs and build.rs. This is why even the procedural -macro ecosystem is largely built around `proc_macro2`, because that ensures the -libraries are unit testable and accessible in non-macro contexts. - -There is a [`From`]-conversion in both directions so returning the output of -`quote!` from a procedural macro usually looks like `tokens.into()` or -`proc_macro::TokenStream::from(tokens)`. - -[`From`]: https://doc.rust-lang.org/std/convert/trait.From.html - -
- -## Examples - -### Combining quoted fragments - -Usually you don't end up constructing an entire final `TokenStream` in one -piece. Different parts may come from different helper functions. The tokens -produced by `quote!` themselves implement `ToTokens` and so can be interpolated -into later `quote!` invocations to build up a final result. - -```rust -let type_definition = quote! {...}; -let methods = quote! {...}; - -let tokens = quote! { - #type_definition - #methods -}; -``` - -### Constructing identifiers - -Suppose we have an identifier `ident` which came from somewhere in a macro -input and we need to modify it in some way for the macro output. Let's consider -prepending the identifier with an underscore. - -Simply interpolating the identifier next to an underscore will not have the -behavior of concatenating them. The underscore and the identifier will continue -to be two separate tokens as if you had written `_ x`. - -```rust -// incorrect -quote! { - let mut _#ident = 0; -} -``` - -The solution is to build a new identifier token with the correct value. As this -is such a common case, the `format_ident!` macro provides a convenient utility -for doing so correctly. - -```rust -let varname = format_ident!("_{}", ident); -quote! { - let mut #varname = 0; -} -``` - -Alternatively, the APIs provided by Syn and proc-macro2 can be used to directly -build the identifier. This is roughly equivalent to the above, but will not -handle `ident` being a raw identifier. - -```rust -let concatenated = format!("_{}", ident); -let varname = syn::Ident::new(&concatenated, ident.span()); -quote! { - let mut #varname = 0; -} -``` - -### Making method calls - -Let's say our macro requires some type specified in the macro input to have a -constructor called `new`. We have the type in a variable called `field_type` of -type `syn::Type` and want to invoke the constructor. - -```rust -// incorrect -quote! { - let value = #field_type::new(); -} -``` - -This works only sometimes. If `field_type` is `String`, the expanded code -contains `String::new()` which is fine. But if `field_type` is something like -`Vec` then the expanded code is `Vec::new()` which is invalid syntax. -Ordinarily in handwritten Rust we would write `Vec::::new()` but for macros -often the following is more convenient. - -```rust -quote! { - let value = <#field_type>::new(); -} -``` - -This expands to `>::new()` which behaves correctly. - -A similar pattern is appropriate for trait methods. - -```rust -quote! { - let value = <#field_type as core::default::Default>::default(); -} -``` - -
- -## Hygiene - -Any interpolated tokens preserve the `Span` information provided by their -`ToTokens` implementation. Tokens that originate within a `quote!` invocation -are spanned with [`Span::call_site()`]. - -[`Span::call_site()`]: https://docs.rs/proc-macro2/1.0/proc_macro2/struct.Span.html#method.call_site - -A different span can be provided explicitly through the [`quote_spanned!`] -macro. - -[`quote_spanned!`]: https://docs.rs/quote/1.0/quote/macro.quote_spanned.html - -
- -## Non-macro code generators - -When using `quote` in a build.rs or main.rs and writing the output out to a -file, consider having the code generator pass the tokens through [prettyplease] -before writing. This way if an error occurs in the generated code it is -convenient for a human to read and debug. - -Be aware that no kind of hygiene or span information is retained when tokens are -written to a file; the conversion from tokens to source code is lossy. - -Example usage in build.rs: - -```rust -let output = quote! { ... }; -let syntax_tree = syn::parse2(output).unwrap(); -let formatted = prettyplease::unparse(&syntax_tree); - -let out_dir = env::var_os("OUT_DIR").unwrap(); -let dest_path = Path::new(&out_dir).join("out.rs"); -fs::write(dest_path, formatted).unwrap(); -``` - -[prettyplease]: https://github.com/dtolnay/prettyplease - -
- -#### License - - -Licensed under either of Apache License, Version -2.0 or MIT license at your option. - - -
- - -Unless you explicitly state otherwise, any contribution intentionally submitted -for inclusion in this crate by you, as defined in the Apache-2.0 license, shall -be dual licensed as above, without any additional terms or conditions. - diff --git a/third-party/vendor/quote/rust-toolchain.toml b/third-party/vendor/quote/rust-toolchain.toml deleted file mode 100644 index 20fe888c..00000000 --- a/third-party/vendor/quote/rust-toolchain.toml +++ /dev/null @@ -1,2 +0,0 @@ -[toolchain] -components = ["rust-src"] diff --git a/third-party/vendor/quote/src/ext.rs b/third-party/vendor/quote/src/ext.rs deleted file mode 100644 index 92c2315b..00000000 --- a/third-party/vendor/quote/src/ext.rs +++ /dev/null @@ -1,110 +0,0 @@ -use super::ToTokens; -use core::iter; -use proc_macro2::{TokenStream, TokenTree}; - -/// TokenStream extension trait with methods for appending tokens. -/// -/// This trait is sealed and cannot be implemented outside of the `quote` crate. -pub trait TokenStreamExt: private::Sealed { - /// For use by `ToTokens` implementations. - /// - /// Appends the token specified to this list of tokens. - fn append(&mut self, token: U) - where - U: Into; - - /// For use by `ToTokens` implementations. - /// - /// ``` - /// # use quote::{quote, TokenStreamExt, ToTokens}; - /// # use proc_macro2::TokenStream; - /// # - /// struct X; - /// - /// impl ToTokens for X { - /// fn to_tokens(&self, tokens: &mut TokenStream) { - /// tokens.append_all(&[true, false]); - /// } - /// } - /// - /// let tokens = quote!(#X); - /// assert_eq!(tokens.to_string(), "true false"); - /// ``` - fn append_all(&mut self, iter: I) - where - I: IntoIterator, - I::Item: ToTokens; - - /// For use by `ToTokens` implementations. - /// - /// Appends all of the items in the iterator `I`, separated by the tokens - /// `U`. - fn append_separated(&mut self, iter: I, op: U) - where - I: IntoIterator, - I::Item: ToTokens, - U: ToTokens; - - /// For use by `ToTokens` implementations. - /// - /// Appends all tokens in the iterator `I`, appending `U` after each - /// element, including after the last element of the iterator. - fn append_terminated(&mut self, iter: I, term: U) - where - I: IntoIterator, - I::Item: ToTokens, - U: ToTokens; -} - -impl TokenStreamExt for TokenStream { - fn append(&mut self, token: U) - where - U: Into, - { - self.extend(iter::once(token.into())); - } - - fn append_all(&mut self, iter: I) - where - I: IntoIterator, - I::Item: ToTokens, - { - for token in iter { - token.to_tokens(self); - } - } - - fn append_separated(&mut self, iter: I, op: U) - where - I: IntoIterator, - I::Item: ToTokens, - U: ToTokens, - { - for (i, token) in iter.into_iter().enumerate() { - if i > 0 { - op.to_tokens(self); - } - token.to_tokens(self); - } - } - - fn append_terminated(&mut self, iter: I, term: U) - where - I: IntoIterator, - I::Item: ToTokens, - U: ToTokens, - { - for token in iter { - token.to_tokens(self); - term.to_tokens(self); - } - } -} - -mod private { - use proc_macro2::TokenStream; - - pub trait Sealed {} - - impl Sealed for TokenStream {} -} diff --git a/third-party/vendor/quote/src/format.rs b/third-party/vendor/quote/src/format.rs deleted file mode 100644 index 3cddbd28..00000000 --- a/third-party/vendor/quote/src/format.rs +++ /dev/null @@ -1,168 +0,0 @@ -/// Formatting macro for constructing `Ident`s. -/// -///
-/// -/// # Syntax -/// -/// Syntax is copied from the [`format!`] macro, supporting both positional and -/// named arguments. -/// -/// Only a limited set of formatting traits are supported. The current mapping -/// of format types to traits is: -/// -/// * `{}` ⇒ [`IdentFragment`] -/// * `{:o}` ⇒ [`Octal`](std::fmt::Octal) -/// * `{:x}` ⇒ [`LowerHex`](std::fmt::LowerHex) -/// * `{:X}` ⇒ [`UpperHex`](std::fmt::UpperHex) -/// * `{:b}` ⇒ [`Binary`](std::fmt::Binary) -/// -/// See [`std::fmt`] for more information. -/// -///
-/// -/// # IdentFragment -/// -/// Unlike `format!`, this macro uses the [`IdentFragment`] formatting trait by -/// default. This trait is like `Display`, with a few differences: -/// -/// * `IdentFragment` is only implemented for a limited set of types, such as -/// unsigned integers and strings. -/// * [`Ident`] arguments will have their `r#` prefixes stripped, if present. -/// -/// [`IdentFragment`]: crate::IdentFragment -/// [`Ident`]: proc_macro2::Ident -/// -///
-/// -/// # Hygiene -/// -/// The [`Span`] of the first `Ident` argument is used as the span of the final -/// identifier, falling back to [`Span::call_site`] when no identifiers are -/// provided. -/// -/// ``` -/// # use quote::format_ident; -/// # let ident = format_ident!("Ident"); -/// // If `ident` is an Ident, the span of `my_ident` will be inherited from it. -/// let my_ident = format_ident!("My{}{}", ident, "IsCool"); -/// assert_eq!(my_ident, "MyIdentIsCool"); -/// ``` -/// -/// Alternatively, the span can be overridden by passing the `span` named -/// argument. -/// -/// ``` -/// # use quote::format_ident; -/// # const IGNORE_TOKENS: &'static str = stringify! { -/// let my_span = /* ... */; -/// # }; -/// # let my_span = proc_macro2::Span::call_site(); -/// format_ident!("MyIdent", span = my_span); -/// ``` -/// -/// [`Span`]: proc_macro2::Span -/// [`Span::call_site`]: proc_macro2::Span::call_site -/// -///


-/// -/// # Panics -/// -/// This method will panic if the resulting formatted string is not a valid -/// identifier. -/// -///
-/// -/// # Examples -/// -/// Composing raw and non-raw identifiers: -/// ``` -/// # use quote::format_ident; -/// let my_ident = format_ident!("My{}", "Ident"); -/// assert_eq!(my_ident, "MyIdent"); -/// -/// let raw = format_ident!("r#Raw"); -/// assert_eq!(raw, "r#Raw"); -/// -/// let my_ident_raw = format_ident!("{}Is{}", my_ident, raw); -/// assert_eq!(my_ident_raw, "MyIdentIsRaw"); -/// ``` -/// -/// Integer formatting options: -/// ``` -/// # use quote::format_ident; -/// let num: u32 = 10; -/// -/// let decimal = format_ident!("Id_{}", num); -/// assert_eq!(decimal, "Id_10"); -/// -/// let octal = format_ident!("Id_{:o}", num); -/// assert_eq!(octal, "Id_12"); -/// -/// let binary = format_ident!("Id_{:b}", num); -/// assert_eq!(binary, "Id_1010"); -/// -/// let lower_hex = format_ident!("Id_{:x}", num); -/// assert_eq!(lower_hex, "Id_a"); -/// -/// let upper_hex = format_ident!("Id_{:X}", num); -/// assert_eq!(upper_hex, "Id_A"); -/// ``` -#[macro_export] -macro_rules! format_ident { - ($fmt:expr) => { - $crate::format_ident_impl!([ - $crate::__private::Option::None, - $fmt - ]) - }; - - ($fmt:expr, $($rest:tt)*) => { - $crate::format_ident_impl!([ - $crate::__private::Option::None, - $fmt - ] $($rest)*) - }; -} - -#[macro_export] -#[doc(hidden)] -macro_rules! format_ident_impl { - // Final state - ([$span:expr, $($fmt:tt)*]) => { - $crate::__private::mk_ident( - &$crate::__private::format!($($fmt)*), - $span, - ) - }; - - // Span argument - ([$old:expr, $($fmt:tt)*] span = $span:expr) => { - $crate::format_ident_impl!([$old, $($fmt)*] span = $span,) - }; - ([$old:expr, $($fmt:tt)*] span = $span:expr, $($rest:tt)*) => { - $crate::format_ident_impl!([ - $crate::__private::Option::Some::<$crate::__private::Span>($span), - $($fmt)* - ] $($rest)*) - }; - - // Named argument - ([$span:expr, $($fmt:tt)*] $name:ident = $arg:expr) => { - $crate::format_ident_impl!([$span, $($fmt)*] $name = $arg,) - }; - ([$span:expr, $($fmt:tt)*] $name:ident = $arg:expr, $($rest:tt)*) => { - match $crate::__private::IdentFragmentAdapter(&$arg) { - arg => $crate::format_ident_impl!([$span.or(arg.span()), $($fmt)*, $name = arg] $($rest)*), - } - }; - - // Positional argument - ([$span:expr, $($fmt:tt)*] $arg:expr) => { - $crate::format_ident_impl!([$span, $($fmt)*] $arg,) - }; - ([$span:expr, $($fmt:tt)*] $arg:expr, $($rest:tt)*) => { - match $crate::__private::IdentFragmentAdapter(&$arg) { - arg => $crate::format_ident_impl!([$span.or(arg.span()), $($fmt)*, arg] $($rest)*), - } - }; -} diff --git a/third-party/vendor/quote/src/ident_fragment.rs b/third-party/vendor/quote/src/ident_fragment.rs deleted file mode 100644 index 6c2a9a87..00000000 --- a/third-party/vendor/quote/src/ident_fragment.rs +++ /dev/null @@ -1,88 +0,0 @@ -use alloc::borrow::Cow; -use core::fmt; -use proc_macro2::{Ident, Span}; - -/// Specialized formatting trait used by `format_ident!`. -/// -/// [`Ident`] arguments formatted using this trait will have their `r#` prefix -/// stripped, if present. -/// -/// See [`format_ident!`] for more information. -/// -/// [`format_ident!`]: crate::format_ident -pub trait IdentFragment { - /// Format this value as an identifier fragment. - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result; - - /// Span associated with this `IdentFragment`. - /// - /// If non-`None`, may be inherited by formatted identifiers. - fn span(&self) -> Option { - None - } -} - -impl IdentFragment for &T { - fn span(&self) -> Option { - ::span(*self) - } - - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - IdentFragment::fmt(*self, f) - } -} - -impl IdentFragment for &mut T { - fn span(&self) -> Option { - ::span(*self) - } - - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - IdentFragment::fmt(*self, f) - } -} - -impl IdentFragment for Ident { - fn span(&self) -> Option { - Some(self.span()) - } - - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - let id = self.to_string(); - if let Some(id) = id.strip_prefix("r#") { - fmt::Display::fmt(id, f) - } else { - fmt::Display::fmt(&id[..], f) - } - } -} - -impl IdentFragment for Cow<'_, T> -where - T: IdentFragment + ToOwned + ?Sized, -{ - fn span(&self) -> Option { - T::span(self) - } - - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - T::fmt(self, f) - } -} - -// Limited set of types which this is implemented for, as we want to avoid types -// which will often include non-identifier characters in their `Display` impl. -macro_rules! ident_fragment_display { - ($($T:ty),*) => { - $( - impl IdentFragment for $T { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - fmt::Display::fmt(self, f) - } - } - )* - }; -} - -ident_fragment_display!(bool, str, String, char); -ident_fragment_display!(u8, u16, u32, u64, u128, usize); diff --git a/third-party/vendor/quote/src/lib.rs b/third-party/vendor/quote/src/lib.rs deleted file mode 100644 index 8b97abd7..00000000 --- a/third-party/vendor/quote/src/lib.rs +++ /dev/null @@ -1,1444 +0,0 @@ -//! [![github]](https://github.com/dtolnay/quote) [![crates-io]](https://crates.io/crates/quote) [![docs-rs]](https://docs.rs/quote) -//! -//! [github]: https://img.shields.io/badge/github-8da0cb?style=for-the-badge&labelColor=555555&logo=github -//! [crates-io]: https://img.shields.io/badge/crates.io-fc8d62?style=for-the-badge&labelColor=555555&logo=rust -//! [docs-rs]: https://img.shields.io/badge/docs.rs-66c2a5?style=for-the-badge&labelColor=555555&logo=docs.rs -//! -//!
-//! -//! This crate provides the [`quote!`] macro for turning Rust syntax tree data -//! structures into tokens of source code. -//! -//! [`quote!`]: macro.quote.html -//! -//! Procedural macros in Rust receive a stream of tokens as input, execute -//! arbitrary Rust code to determine how to manipulate those tokens, and produce -//! a stream of tokens to hand back to the compiler to compile into the caller's -//! crate. Quasi-quoting is a solution to one piece of that — producing -//! tokens to return to the compiler. -//! -//! The idea of quasi-quoting is that we write *code* that we treat as *data*. -//! Within the `quote!` macro, we can write what looks like code to our text -//! editor or IDE. We get all the benefits of the editor's brace matching, -//! syntax highlighting, indentation, and maybe autocompletion. But rather than -//! compiling that as code into the current crate, we can treat it as data, pass -//! it around, mutate it, and eventually hand it back to the compiler as tokens -//! to compile into the macro caller's crate. -//! -//! This crate is motivated by the procedural macro use case, but is a -//! general-purpose Rust quasi-quoting library and is not specific to procedural -//! macros. -//! -//! ```toml -//! [dependencies] -//! quote = "1.0" -//! ``` -//! -//!
-//! -//! # Example -//! -//! The following quasi-quoted block of code is something you might find in [a] -//! procedural macro having to do with data structure serialization. The `#var` -//! syntax performs interpolation of runtime variables into the quoted tokens. -//! Check out the documentation of the [`quote!`] macro for more detail about -//! the syntax. See also the [`quote_spanned!`] macro which is important for -//! implementing hygienic procedural macros. -//! -//! [a]: https://serde.rs/ -//! [`quote_spanned!`]: macro.quote_spanned.html -//! -//! ``` -//! # use quote::quote; -//! # -//! # let generics = ""; -//! # let where_clause = ""; -//! # let field_ty = ""; -//! # let item_ty = ""; -//! # let path = ""; -//! # let value = ""; -//! # -//! let tokens = quote! { -//! struct SerializeWith #generics #where_clause { -//! value: &'a #field_ty, -//! phantom: core::marker::PhantomData<#item_ty>, -//! } -//! -//! impl #generics serde::Serialize for SerializeWith #generics #where_clause { -//! fn serialize(&self, serializer: S) -> Result -//! where -//! S: serde::Serializer, -//! { -//! #path(self.value, serializer) -//! } -//! } -//! -//! SerializeWith { -//! value: #value, -//! phantom: core::marker::PhantomData::<#item_ty>, -//! } -//! }; -//! ``` -//! -//!
-//! -//! # Non-macro code generators -//! -//! When using `quote` in a build.rs or main.rs and writing the output out to a -//! file, consider having the code generator pass the tokens through -//! [prettyplease] before writing. This way if an error occurs in the generated -//! code it is convenient for a human to read and debug. -//! -//! [prettyplease]: https://github.com/dtolnay/prettyplease - -// Quote types in rustdoc of other crates get linked to here. -#![doc(html_root_url = "https://docs.rs/quote/1.0.35")] -#![allow( - clippy::doc_markdown, - clippy::missing_errors_doc, - clippy::missing_panics_doc, - clippy::module_name_repetitions, - // false positive https://github.com/rust-lang/rust-clippy/issues/6983 - clippy::wrong_self_convention, -)] - -extern crate alloc; - -#[cfg(feature = "proc-macro")] -extern crate proc_macro; - -mod ext; -mod format; -mod ident_fragment; -mod to_tokens; - -// Not public API. -#[doc(hidden)] -#[path = "runtime.rs"] -pub mod __private; - -pub use crate::ext::TokenStreamExt; -pub use crate::ident_fragment::IdentFragment; -pub use crate::to_tokens::ToTokens; - -// Not public API. -#[doc(hidden)] -pub mod spanned; - -/// The whole point. -/// -/// Performs variable interpolation against the input and produces it as -/// [`proc_macro2::TokenStream`]. -/// -/// Note: for returning tokens to the compiler in a procedural macro, use -/// `.into()` on the result to convert to [`proc_macro::TokenStream`]. -/// -/// [`TokenStream`]: https://docs.rs/proc-macro2/1.0/proc_macro2/struct.TokenStream.html -/// -///
-/// -/// # Interpolation -/// -/// Variable interpolation is done with `#var` (similar to `$var` in -/// `macro_rules!` macros). This grabs the `var` variable that is currently in -/// scope and inserts it in that location in the output tokens. Any type -/// implementing the [`ToTokens`] trait can be interpolated. This includes most -/// Rust primitive types as well as most of the syntax tree types from the [Syn] -/// crate. -/// -/// [`ToTokens`]: trait.ToTokens.html -/// [Syn]: https://github.com/dtolnay/syn -/// -/// Repetition is done using `#(...)*` or `#(...),*` again similar to -/// `macro_rules!`. This iterates through the elements of any variable -/// interpolated within the repetition and inserts a copy of the repetition body -/// for each one. The variables in an interpolation may be a `Vec`, slice, -/// `BTreeSet`, or any `Iterator`. -/// -/// - `#(#var)*` — no separators -/// - `#(#var),*` — the character before the asterisk is used as a separator -/// - `#( struct #var; )*` — the repetition can contain other tokens -/// - `#( #k => println!("{}", #v), )*` — even multiple interpolations -/// -///
-/// -/// # Hygiene -/// -/// Any interpolated tokens preserve the `Span` information provided by their -/// `ToTokens` implementation. Tokens that originate within the `quote!` -/// invocation are spanned with [`Span::call_site()`]. -/// -/// [`Span::call_site()`]: https://docs.rs/proc-macro2/1.0/proc_macro2/struct.Span.html#method.call_site -/// -/// A different span can be provided through the [`quote_spanned!`] macro. -/// -/// [`quote_spanned!`]: macro.quote_spanned.html -/// -///
-/// -/// # Return type -/// -/// The macro evaluates to an expression of type `proc_macro2::TokenStream`. -/// Meanwhile Rust procedural macros are expected to return the type -/// `proc_macro::TokenStream`. -/// -/// The difference between the two types is that `proc_macro` types are entirely -/// specific to procedural macros and cannot ever exist in code outside of a -/// procedural macro, while `proc_macro2` types may exist anywhere including -/// tests and non-macro code like main.rs and build.rs. This is why even the -/// procedural macro ecosystem is largely built around `proc_macro2`, because -/// that ensures the libraries are unit testable and accessible in non-macro -/// contexts. -/// -/// There is a [`From`]-conversion in both directions so returning the output of -/// `quote!` from a procedural macro usually looks like `tokens.into()` or -/// `proc_macro::TokenStream::from(tokens)`. -/// -/// [`From`]: https://doc.rust-lang.org/std/convert/trait.From.html -/// -///
-/// -/// # Examples -/// -/// ### Procedural macro -/// -/// The structure of a basic procedural macro is as follows. Refer to the [Syn] -/// crate for further useful guidance on using `quote!` as part of a procedural -/// macro. -/// -/// [Syn]: https://github.com/dtolnay/syn -/// -/// ``` -/// # #[cfg(any())] -/// extern crate proc_macro; -/// # extern crate proc_macro2; -/// -/// # #[cfg(any())] -/// use proc_macro::TokenStream; -/// # use proc_macro2::TokenStream; -/// use quote::quote; -/// -/// # const IGNORE_TOKENS: &'static str = stringify! { -/// #[proc_macro_derive(HeapSize)] -/// # }; -/// pub fn derive_heap_size(input: TokenStream) -> TokenStream { -/// // Parse the input and figure out what implementation to generate... -/// # const IGNORE_TOKENS: &'static str = stringify! { -/// let name = /* ... */; -/// let expr = /* ... */; -/// # }; -/// # -/// # let name = 0; -/// # let expr = 0; -/// -/// let expanded = quote! { -/// // The generated impl. -/// impl heapsize::HeapSize for #name { -/// fn heap_size_of_children(&self) -> usize { -/// #expr -/// } -/// } -/// }; -/// -/// // Hand the output tokens back to the compiler. -/// TokenStream::from(expanded) -/// } -/// ``` -/// -///


-/// -/// ### Combining quoted fragments -/// -/// Usually you don't end up constructing an entire final `TokenStream` in one -/// piece. Different parts may come from different helper functions. The tokens -/// produced by `quote!` themselves implement `ToTokens` and so can be -/// interpolated into later `quote!` invocations to build up a final result. -/// -/// ``` -/// # use quote::quote; -/// # -/// let type_definition = quote! {...}; -/// let methods = quote! {...}; -/// -/// let tokens = quote! { -/// #type_definition -/// #methods -/// }; -/// ``` -/// -///


-/// -/// ### Constructing identifiers -/// -/// Suppose we have an identifier `ident` which came from somewhere in a macro -/// input and we need to modify it in some way for the macro output. Let's -/// consider prepending the identifier with an underscore. -/// -/// Simply interpolating the identifier next to an underscore will not have the -/// behavior of concatenating them. The underscore and the identifier will -/// continue to be two separate tokens as if you had written `_ x`. -/// -/// ``` -/// # use proc_macro2::{self as syn, Span}; -/// # use quote::quote; -/// # -/// # let ident = syn::Ident::new("i", Span::call_site()); -/// # -/// // incorrect -/// quote! { -/// let mut _#ident = 0; -/// } -/// # ; -/// ``` -/// -/// The solution is to build a new identifier token with the correct value. As -/// this is such a common case, the [`format_ident!`] macro provides a -/// convenient utility for doing so correctly. -/// -/// ``` -/// # use proc_macro2::{Ident, Span}; -/// # use quote::{format_ident, quote}; -/// # -/// # let ident = Ident::new("i", Span::call_site()); -/// # -/// let varname = format_ident!("_{}", ident); -/// quote! { -/// let mut #varname = 0; -/// } -/// # ; -/// ``` -/// -/// Alternatively, the APIs provided by Syn and proc-macro2 can be used to -/// directly build the identifier. This is roughly equivalent to the above, but -/// will not handle `ident` being a raw identifier. -/// -/// ``` -/// # use proc_macro2::{self as syn, Span}; -/// # use quote::quote; -/// # -/// # let ident = syn::Ident::new("i", Span::call_site()); -/// # -/// let concatenated = format!("_{}", ident); -/// let varname = syn::Ident::new(&concatenated, ident.span()); -/// quote! { -/// let mut #varname = 0; -/// } -/// # ; -/// ``` -/// -///


-/// -/// ### Making method calls -/// -/// Let's say our macro requires some type specified in the macro input to have -/// a constructor called `new`. We have the type in a variable called -/// `field_type` of type `syn::Type` and want to invoke the constructor. -/// -/// ``` -/// # use quote::quote; -/// # -/// # let field_type = quote!(...); -/// # -/// // incorrect -/// quote! { -/// let value = #field_type::new(); -/// } -/// # ; -/// ``` -/// -/// This works only sometimes. If `field_type` is `String`, the expanded code -/// contains `String::new()` which is fine. But if `field_type` is something -/// like `Vec` then the expanded code is `Vec::new()` which is invalid -/// syntax. Ordinarily in handwritten Rust we would write `Vec::::new()` -/// but for macros often the following is more convenient. -/// -/// ``` -/// # use quote::quote; -/// # -/// # let field_type = quote!(...); -/// # -/// quote! { -/// let value = <#field_type>::new(); -/// } -/// # ; -/// ``` -/// -/// This expands to `>::new()` which behaves correctly. -/// -/// A similar pattern is appropriate for trait methods. -/// -/// ``` -/// # use quote::quote; -/// # -/// # let field_type = quote!(...); -/// # -/// quote! { -/// let value = <#field_type as core::default::Default>::default(); -/// } -/// # ; -/// ``` -/// -///


-/// -/// ### Interpolating text inside of doc comments -/// -/// Neither doc comments nor string literals get interpolation behavior in -/// quote: -/// -/// ```compile_fail -/// quote! { -/// /// try to interpolate: #ident -/// /// -/// /// ... -/// } -/// ``` -/// -/// ```compile_fail -/// quote! { -/// #[doc = "try to interpolate: #ident"] -/// } -/// ``` -/// -/// Instead the best way to build doc comments that involve variables is by -/// formatting the doc string literal outside of quote. -/// -/// ```rust -/// # use proc_macro2::{Ident, Span}; -/// # use quote::quote; -/// # -/// # const IGNORE: &str = stringify! { -/// let msg = format!(...); -/// # }; -/// # -/// # let ident = Ident::new("var", Span::call_site()); -/// # let msg = format!("try to interpolate: {}", ident); -/// quote! { -/// #[doc = #msg] -/// /// -/// /// ... -/// } -/// # ; -/// ``` -/// -///


-/// -/// ### Indexing into a tuple struct -/// -/// When interpolating indices of a tuple or tuple struct, we need them not to -/// appears suffixed as integer literals by interpolating them as [`syn::Index`] -/// instead. -/// -/// [`syn::Index`]: https://docs.rs/syn/2.0/syn/struct.Index.html -/// -/// ```compile_fail -/// let i = 0usize..self.fields.len(); -/// -/// // expands to 0 + self.0usize.heap_size() + self.1usize.heap_size() + ... -/// // which is not valid syntax -/// quote! { -/// 0 #( + self.#i.heap_size() )* -/// } -/// ``` -/// -/// ``` -/// # use proc_macro2::{Ident, TokenStream}; -/// # use quote::quote; -/// # -/// # mod syn { -/// # use proc_macro2::{Literal, TokenStream}; -/// # use quote::{ToTokens, TokenStreamExt}; -/// # -/// # pub struct Index(usize); -/// # -/// # impl From for Index { -/// # fn from(i: usize) -> Self { -/// # Index(i) -/// # } -/// # } -/// # -/// # impl ToTokens for Index { -/// # fn to_tokens(&self, tokens: &mut TokenStream) { -/// # tokens.append(Literal::usize_unsuffixed(self.0)); -/// # } -/// # } -/// # } -/// # -/// # struct Struct { -/// # fields: Vec, -/// # } -/// # -/// # impl Struct { -/// # fn example(&self) -> TokenStream { -/// let i = (0..self.fields.len()).map(syn::Index::from); -/// -/// // expands to 0 + self.0.heap_size() + self.1.heap_size() + ... -/// quote! { -/// 0 #( + self.#i.heap_size() )* -/// } -/// # } -/// # } -/// ``` -#[cfg(doc)] -#[macro_export] -macro_rules! quote { - ($($tt:tt)*) => { - ... - }; -} - -#[cfg(not(doc))] -#[macro_export] -macro_rules! quote { - () => { - $crate::__private::TokenStream::new() - }; - - // Special case rule for a single tt, for performance. - ($tt:tt) => {{ - let mut _s = $crate::__private::TokenStream::new(); - $crate::quote_token!{$tt _s} - _s - }}; - - // Special case rules for two tts, for performance. - (# $var:ident) => {{ - let mut _s = $crate::__private::TokenStream::new(); - $crate::ToTokens::to_tokens(&$var, &mut _s); - _s - }}; - ($tt1:tt $tt2:tt) => {{ - let mut _s = $crate::__private::TokenStream::new(); - $crate::quote_token!{$tt1 _s} - $crate::quote_token!{$tt2 _s} - _s - }}; - - // Rule for any other number of tokens. - ($($tt:tt)*) => {{ - let mut _s = $crate::__private::TokenStream::new(); - $crate::quote_each_token!{_s $($tt)*} - _s - }}; -} - -/// Same as `quote!`, but applies a given span to all tokens originating within -/// the macro invocation. -/// -///
-/// -/// # Syntax -/// -/// A span expression of type [`Span`], followed by `=>`, followed by the tokens -/// to quote. The span expression should be brief — use a variable for -/// anything more than a few characters. There should be no space before the -/// `=>` token. -/// -/// [`Span`]: https://docs.rs/proc-macro2/1.0/proc_macro2/struct.Span.html -/// -/// ``` -/// # use proc_macro2::Span; -/// # use quote::quote_spanned; -/// # -/// # const IGNORE_TOKENS: &'static str = stringify! { -/// let span = /* ... */; -/// # }; -/// # let span = Span::call_site(); -/// # let init = 0; -/// -/// // On one line, use parentheses. -/// let tokens = quote_spanned!(span=> Box::into_raw(Box::new(#init))); -/// -/// // On multiple lines, place the span at the top and use braces. -/// let tokens = quote_spanned! {span=> -/// Box::into_raw(Box::new(#init)) -/// }; -/// ``` -/// -/// The lack of space before the `=>` should look jarring to Rust programmers -/// and this is intentional. The formatting is designed to be visibly -/// off-balance and draw the eye a particular way, due to the span expression -/// being evaluated in the context of the procedural macro and the remaining -/// tokens being evaluated in the generated code. -/// -///
-/// -/// # Hygiene -/// -/// Any interpolated tokens preserve the `Span` information provided by their -/// `ToTokens` implementation. Tokens that originate within the `quote_spanned!` -/// invocation are spanned with the given span argument. -/// -///
-/// -/// # Example -/// -/// The following procedural macro code uses `quote_spanned!` to assert that a -/// particular Rust type implements the [`Sync`] trait so that references can be -/// safely shared between threads. -/// -/// [`Sync`]: https://doc.rust-lang.org/std/marker/trait.Sync.html -/// -/// ``` -/// # use quote::{quote_spanned, TokenStreamExt, ToTokens}; -/// # use proc_macro2::{Span, TokenStream}; -/// # -/// # struct Type; -/// # -/// # impl Type { -/// # fn span(&self) -> Span { -/// # Span::call_site() -/// # } -/// # } -/// # -/// # impl ToTokens for Type { -/// # fn to_tokens(&self, _tokens: &mut TokenStream) {} -/// # } -/// # -/// # let ty = Type; -/// # let call_site = Span::call_site(); -/// # -/// let ty_span = ty.span(); -/// let assert_sync = quote_spanned! {ty_span=> -/// struct _AssertSync where #ty: Sync; -/// }; -/// ``` -/// -/// If the assertion fails, the user will see an error like the following. The -/// input span of their type is highlighted in the error. -/// -/// ```text -/// error[E0277]: the trait bound `*const (): std::marker::Sync` is not satisfied -/// --> src/main.rs:10:21 -/// | -/// 10 | static ref PTR: *const () = &(); -/// | ^^^^^^^^^ `*const ()` cannot be shared between threads safely -/// ``` -/// -/// In this example it is important for the where-clause to be spanned with the -/// line/column information of the user's input type so that error messages are -/// placed appropriately by the compiler. -#[cfg(doc)] -#[macro_export] -macro_rules! quote_spanned { - ($span:expr=> $($tt:tt)*) => { - ... - }; -} - -#[cfg(not(doc))] -#[macro_export] -macro_rules! quote_spanned { - ($span:expr=>) => {{ - let _: $crate::__private::Span = $crate::__private::get_span($span).__into_span(); - $crate::__private::TokenStream::new() - }}; - - // Special case rule for a single tt, for performance. - ($span:expr=> $tt:tt) => {{ - let mut _s = $crate::__private::TokenStream::new(); - let _span: $crate::__private::Span = $crate::__private::get_span($span).__into_span(); - $crate::quote_token_spanned!{$tt _s _span} - _s - }}; - - // Special case rules for two tts, for performance. - ($span:expr=> # $var:ident) => {{ - let mut _s = $crate::__private::TokenStream::new(); - let _: $crate::__private::Span = $crate::__private::get_span($span).__into_span(); - $crate::ToTokens::to_tokens(&$var, &mut _s); - _s - }}; - ($span:expr=> $tt1:tt $tt2:tt) => {{ - let mut _s = $crate::__private::TokenStream::new(); - let _span: $crate::__private::Span = $crate::__private::get_span($span).__into_span(); - $crate::quote_token_spanned!{$tt1 _s _span} - $crate::quote_token_spanned!{$tt2 _s _span} - _s - }}; - - // Rule for any other number of tokens. - ($span:expr=> $($tt:tt)*) => {{ - let mut _s = $crate::__private::TokenStream::new(); - let _span: $crate::__private::Span = $crate::__private::get_span($span).__into_span(); - $crate::quote_each_token_spanned!{_s _span $($tt)*} - _s - }}; -} - -// Extract the names of all #metavariables and pass them to the $call macro. -// -// in: pounded_var_names!(then!(...) a #b c #( #d )* #e) -// out: then!(... b); -// then!(... d); -// then!(... e); -#[macro_export] -#[doc(hidden)] -macro_rules! pounded_var_names { - ($call:ident! $extra:tt $($tts:tt)*) => { - $crate::pounded_var_names_with_context!{$call! $extra - (@ $($tts)*) - ($($tts)* @) - } - }; -} - -#[macro_export] -#[doc(hidden)] -macro_rules! pounded_var_names_with_context { - ($call:ident! $extra:tt ($($b1:tt)*) ($($curr:tt)*)) => { - $( - $crate::pounded_var_with_context!{$call! $extra $b1 $curr} - )* - }; -} - -#[macro_export] -#[doc(hidden)] -macro_rules! pounded_var_with_context { - ($call:ident! $extra:tt $b1:tt ( $($inner:tt)* )) => { - $crate::pounded_var_names!{$call! $extra $($inner)*} - }; - - ($call:ident! $extra:tt $b1:tt [ $($inner:tt)* ]) => { - $crate::pounded_var_names!{$call! $extra $($inner)*} - }; - - ($call:ident! $extra:tt $b1:tt { $($inner:tt)* }) => { - $crate::pounded_var_names!{$call! $extra $($inner)*} - }; - - ($call:ident!($($extra:tt)*) # $var:ident) => { - $crate::$call!($($extra)* $var); - }; - - ($call:ident! $extra:tt $b1:tt $curr:tt) => {}; -} - -#[macro_export] -#[doc(hidden)] -macro_rules! quote_bind_into_iter { - ($has_iter:ident $var:ident) => { - // `mut` may be unused if $var occurs multiple times in the list. - #[allow(unused_mut)] - let (mut $var, i) = $var.quote_into_iter(); - let $has_iter = $has_iter | i; - }; -} - -#[macro_export] -#[doc(hidden)] -macro_rules! quote_bind_next_or_break { - ($var:ident) => { - let $var = match $var.next() { - Some(_x) => $crate::__private::RepInterp(_x), - None => break, - }; - }; -} - -// The obvious way to write this macro is as a tt muncher. This implementation -// does something more complex for two reasons. -// -// - With a tt muncher it's easy to hit Rust's built-in recursion_limit, which -// this implementation avoids because it isn't tail recursive. -// -// - Compile times for a tt muncher are quadratic relative to the length of -// the input. This implementation is linear, so it will be faster -// (potentially much faster) for big inputs. However, the constant factors -// of this implementation are higher than that of a tt muncher, so it is -// somewhat slower than a tt muncher if there are many invocations with -// short inputs. -// -// An invocation like this: -// -// quote_each_token!(_s a b c d e f g h i j); -// -// expands to this: -// -// quote_tokens_with_context!(_s -// (@ @ @ @ @ @ a b c d e f g h i j) -// (@ @ @ @ @ a b c d e f g h i j @) -// (@ @ @ @ a b c d e f g h i j @ @) -// (@ @ @ (a) (b) (c) (d) (e) (f) (g) (h) (i) (j) @ @ @) -// (@ @ a b c d e f g h i j @ @ @ @) -// (@ a b c d e f g h i j @ @ @ @ @) -// (a b c d e f g h i j @ @ @ @ @ @) -// ); -// -// which gets transposed and expanded to this: -// -// quote_token_with_context!(_s @ @ @ @ @ @ a); -// quote_token_with_context!(_s @ @ @ @ @ a b); -// quote_token_with_context!(_s @ @ @ @ a b c); -// quote_token_with_context!(_s @ @ @ (a) b c d); -// quote_token_with_context!(_s @ @ a (b) c d e); -// quote_token_with_context!(_s @ a b (c) d e f); -// quote_token_with_context!(_s a b c (d) e f g); -// quote_token_with_context!(_s b c d (e) f g h); -// quote_token_with_context!(_s c d e (f) g h i); -// quote_token_with_context!(_s d e f (g) h i j); -// quote_token_with_context!(_s e f g (h) i j @); -// quote_token_with_context!(_s f g h (i) j @ @); -// quote_token_with_context!(_s g h i (j) @ @ @); -// quote_token_with_context!(_s h i j @ @ @ @); -// quote_token_with_context!(_s i j @ @ @ @ @); -// quote_token_with_context!(_s j @ @ @ @ @ @); -// -// Without having used muncher-style recursion, we get one invocation of -// quote_token_with_context for each original tt, with three tts of context on -// either side. This is enough for the longest possible interpolation form (a -// repetition with separator, as in `# (#var) , *`) to be fully represented with -// the first or last tt in the middle. -// -// The middle tt (surrounded by parentheses) is the tt being processed. -// -// - When it is a `#`, quote_token_with_context can do an interpolation. The -// interpolation kind will depend on the three subsequent tts. -// -// - When it is within a later part of an interpolation, it can be ignored -// because the interpolation has already been done. -// -// - When it is not part of an interpolation it can be pushed as a single -// token into the output. -// -// - When the middle token is an unparenthesized `@`, that call is one of the -// first 3 or last 3 calls of quote_token_with_context and does not -// correspond to one of the original input tokens, so turns into nothing. -#[macro_export] -#[doc(hidden)] -macro_rules! quote_each_token { - ($tokens:ident $($tts:tt)*) => { - $crate::quote_tokens_with_context!{$tokens - (@ @ @ @ @ @ $($tts)*) - (@ @ @ @ @ $($tts)* @) - (@ @ @ @ $($tts)* @ @) - (@ @ @ $(($tts))* @ @ @) - (@ @ $($tts)* @ @ @ @) - (@ $($tts)* @ @ @ @ @) - ($($tts)* @ @ @ @ @ @) - } - }; -} - -// See the explanation on quote_each_token. -#[macro_export] -#[doc(hidden)] -macro_rules! quote_each_token_spanned { - ($tokens:ident $span:ident $($tts:tt)*) => { - $crate::quote_tokens_with_context_spanned!{$tokens $span - (@ @ @ @ @ @ $($tts)*) - (@ @ @ @ @ $($tts)* @) - (@ @ @ @ $($tts)* @ @) - (@ @ @ $(($tts))* @ @ @) - (@ @ $($tts)* @ @ @ @) - (@ $($tts)* @ @ @ @ @) - ($($tts)* @ @ @ @ @ @) - } - }; -} - -// See the explanation on quote_each_token. -#[macro_export] -#[doc(hidden)] -macro_rules! quote_tokens_with_context { - ($tokens:ident - ($($b3:tt)*) ($($b2:tt)*) ($($b1:tt)*) - ($($curr:tt)*) - ($($a1:tt)*) ($($a2:tt)*) ($($a3:tt)*) - ) => { - $( - $crate::quote_token_with_context!{$tokens $b3 $b2 $b1 $curr $a1 $a2 $a3} - )* - }; -} - -// See the explanation on quote_each_token. -#[macro_export] -#[doc(hidden)] -macro_rules! quote_tokens_with_context_spanned { - ($tokens:ident $span:ident - ($($b3:tt)*) ($($b2:tt)*) ($($b1:tt)*) - ($($curr:tt)*) - ($($a1:tt)*) ($($a2:tt)*) ($($a3:tt)*) - ) => { - $( - $crate::quote_token_with_context_spanned!{$tokens $span $b3 $b2 $b1 $curr $a1 $a2 $a3} - )* - }; -} - -// See the explanation on quote_each_token. -#[macro_export] -#[doc(hidden)] -macro_rules! quote_token_with_context { - // Unparenthesized `@` indicates this call does not correspond to one of the - // original input tokens. Ignore it. - ($tokens:ident $b3:tt $b2:tt $b1:tt @ $a1:tt $a2:tt $a3:tt) => {}; - - // A repetition with no separator. - ($tokens:ident $b3:tt $b2:tt $b1:tt (#) ( $($inner:tt)* ) * $a3:tt) => {{ - use $crate::__private::ext::*; - let has_iter = $crate::__private::ThereIsNoIteratorInRepetition; - $crate::pounded_var_names!{quote_bind_into_iter!(has_iter) () $($inner)*} - let _: $crate::__private::HasIterator = has_iter; - // This is `while true` instead of `loop` because if there are no - // iterators used inside of this repetition then the body would not - // contain any `break`, so the compiler would emit unreachable code - // warnings on anything below the loop. We use has_iter to detect and - // fail to compile when there are no iterators, so here we just work - // around the unneeded extra warning. - while true { - $crate::pounded_var_names!{quote_bind_next_or_break!() () $($inner)*} - $crate::quote_each_token!{$tokens $($inner)*} - } - }}; - // ... and one step later. - ($tokens:ident $b3:tt $b2:tt # (( $($inner:tt)* )) * $a2:tt $a3:tt) => {}; - // ... and one step later. - ($tokens:ident $b3:tt # ( $($inner:tt)* ) (*) $a1:tt $a2:tt $a3:tt) => {}; - - // A repetition with separator. - ($tokens:ident $b3:tt $b2:tt $b1:tt (#) ( $($inner:tt)* ) $sep:tt *) => {{ - use $crate::__private::ext::*; - let mut _i = 0usize; - let has_iter = $crate::__private::ThereIsNoIteratorInRepetition; - $crate::pounded_var_names!{quote_bind_into_iter!(has_iter) () $($inner)*} - let _: $crate::__private::HasIterator = has_iter; - while true { - $crate::pounded_var_names!{quote_bind_next_or_break!() () $($inner)*} - if _i > 0 { - $crate::quote_token!{$sep $tokens} - } - _i += 1; - $crate::quote_each_token!{$tokens $($inner)*} - } - }}; - // ... and one step later. - ($tokens:ident $b3:tt $b2:tt # (( $($inner:tt)* )) $sep:tt * $a3:tt) => {}; - // ... and one step later. - ($tokens:ident $b3:tt # ( $($inner:tt)* ) ($sep:tt) * $a2:tt $a3:tt) => {}; - // (A special case for `#(var)**`, where the first `*` is treated as the - // repetition symbol and the second `*` is treated as an ordinary token.) - ($tokens:ident # ( $($inner:tt)* ) * (*) $a1:tt $a2:tt $a3:tt) => { - // https://github.com/dtolnay/quote/issues/130 - $crate::quote_token!{* $tokens} - }; - // ... and one step later. - ($tokens:ident # ( $($inner:tt)* ) $sep:tt (*) $a1:tt $a2:tt $a3:tt) => {}; - - // A non-repetition interpolation. - ($tokens:ident $b3:tt $b2:tt $b1:tt (#) $var:ident $a2:tt $a3:tt) => { - $crate::ToTokens::to_tokens(&$var, &mut $tokens); - }; - // ... and one step later. - ($tokens:ident $b3:tt $b2:tt # ($var:ident) $a1:tt $a2:tt $a3:tt) => {}; - - // An ordinary token, not part of any interpolation. - ($tokens:ident $b3:tt $b2:tt $b1:tt ($curr:tt) $a1:tt $a2:tt $a3:tt) => { - $crate::quote_token!{$curr $tokens} - }; -} - -// See the explanation on quote_each_token, and on the individual rules of -// quote_token_with_context. -#[macro_export] -#[doc(hidden)] -macro_rules! quote_token_with_context_spanned { - ($tokens:ident $span:ident $b3:tt $b2:tt $b1:tt @ $a1:tt $a2:tt $a3:tt) => {}; - - ($tokens:ident $span:ident $b3:tt $b2:tt $b1:tt (#) ( $($inner:tt)* ) * $a3:tt) => {{ - use $crate::__private::ext::*; - let has_iter = $crate::__private::ThereIsNoIteratorInRepetition; - $crate::pounded_var_names!{quote_bind_into_iter!(has_iter) () $($inner)*} - let _: $crate::__private::HasIterator = has_iter; - while true { - $crate::pounded_var_names!{quote_bind_next_or_break!() () $($inner)*} - $crate::quote_each_token_spanned!{$tokens $span $($inner)*} - } - }}; - ($tokens:ident $span:ident $b3:tt $b2:tt # (( $($inner:tt)* )) * $a2:tt $a3:tt) => {}; - ($tokens:ident $span:ident $b3:tt # ( $($inner:tt)* ) (*) $a1:tt $a2:tt $a3:tt) => {}; - - ($tokens:ident $span:ident $b3:tt $b2:tt $b1:tt (#) ( $($inner:tt)* ) $sep:tt *) => {{ - use $crate::__private::ext::*; - let mut _i = 0usize; - let has_iter = $crate::__private::ThereIsNoIteratorInRepetition; - $crate::pounded_var_names!{quote_bind_into_iter!(has_iter) () $($inner)*} - let _: $crate::__private::HasIterator = has_iter; - while true { - $crate::pounded_var_names!{quote_bind_next_or_break!() () $($inner)*} - if _i > 0 { - $crate::quote_token_spanned!{$sep $tokens $span} - } - _i += 1; - $crate::quote_each_token_spanned!{$tokens $span $($inner)*} - } - }}; - ($tokens:ident $span:ident $b3:tt $b2:tt # (( $($inner:tt)* )) $sep:tt * $a3:tt) => {}; - ($tokens:ident $span:ident $b3:tt # ( $($inner:tt)* ) ($sep:tt) * $a2:tt $a3:tt) => {}; - ($tokens:ident $span:ident # ( $($inner:tt)* ) * (*) $a1:tt $a2:tt $a3:tt) => { - // https://github.com/dtolnay/quote/issues/130 - $crate::quote_token_spanned!{* $tokens $span} - }; - ($tokens:ident $span:ident # ( $($inner:tt)* ) $sep:tt (*) $a1:tt $a2:tt $a3:tt) => {}; - - ($tokens:ident $span:ident $b3:tt $b2:tt $b1:tt (#) $var:ident $a2:tt $a3:tt) => { - $crate::ToTokens::to_tokens(&$var, &mut $tokens); - }; - ($tokens:ident $span:ident $b3:tt $b2:tt # ($var:ident) $a1:tt $a2:tt $a3:tt) => {}; - - ($tokens:ident $span:ident $b3:tt $b2:tt $b1:tt ($curr:tt) $a1:tt $a2:tt $a3:tt) => { - $crate::quote_token_spanned!{$curr $tokens $span} - }; -} - -// These rules are ordered by approximate token frequency, at least for the -// first 10 or so, to improve compile times. Having `ident` first is by far the -// most important because it's typically 2-3x more common than the next most -// common token. -// -// Separately, we put the token being matched in the very front so that failing -// rules may fail to match as quickly as possible. -#[macro_export] -#[doc(hidden)] -macro_rules! quote_token { - ($ident:ident $tokens:ident) => { - $crate::__private::push_ident(&mut $tokens, stringify!($ident)); - }; - - (:: $tokens:ident) => { - $crate::__private::push_colon2(&mut $tokens); - }; - - (( $($inner:tt)* ) $tokens:ident) => { - $crate::__private::push_group( - &mut $tokens, - $crate::__private::Delimiter::Parenthesis, - $crate::quote!($($inner)*), - ); - }; - - ([ $($inner:tt)* ] $tokens:ident) => { - $crate::__private::push_group( - &mut $tokens, - $crate::__private::Delimiter::Bracket, - $crate::quote!($($inner)*), - ); - }; - - ({ $($inner:tt)* } $tokens:ident) => { - $crate::__private::push_group( - &mut $tokens, - $crate::__private::Delimiter::Brace, - $crate::quote!($($inner)*), - ); - }; - - (# $tokens:ident) => { - $crate::__private::push_pound(&mut $tokens); - }; - - (, $tokens:ident) => { - $crate::__private::push_comma(&mut $tokens); - }; - - (. $tokens:ident) => { - $crate::__private::push_dot(&mut $tokens); - }; - - (; $tokens:ident) => { - $crate::__private::push_semi(&mut $tokens); - }; - - (: $tokens:ident) => { - $crate::__private::push_colon(&mut $tokens); - }; - - (+ $tokens:ident) => { - $crate::__private::push_add(&mut $tokens); - }; - - (+= $tokens:ident) => { - $crate::__private::push_add_eq(&mut $tokens); - }; - - (& $tokens:ident) => { - $crate::__private::push_and(&mut $tokens); - }; - - (&& $tokens:ident) => { - $crate::__private::push_and_and(&mut $tokens); - }; - - (&= $tokens:ident) => { - $crate::__private::push_and_eq(&mut $tokens); - }; - - (@ $tokens:ident) => { - $crate::__private::push_at(&mut $tokens); - }; - - (! $tokens:ident) => { - $crate::__private::push_bang(&mut $tokens); - }; - - (^ $tokens:ident) => { - $crate::__private::push_caret(&mut $tokens); - }; - - (^= $tokens:ident) => { - $crate::__private::push_caret_eq(&mut $tokens); - }; - - (/ $tokens:ident) => { - $crate::__private::push_div(&mut $tokens); - }; - - (/= $tokens:ident) => { - $crate::__private::push_div_eq(&mut $tokens); - }; - - (.. $tokens:ident) => { - $crate::__private::push_dot2(&mut $tokens); - }; - - (... $tokens:ident) => { - $crate::__private::push_dot3(&mut $tokens); - }; - - (..= $tokens:ident) => { - $crate::__private::push_dot_dot_eq(&mut $tokens); - }; - - (= $tokens:ident) => { - $crate::__private::push_eq(&mut $tokens); - }; - - (== $tokens:ident) => { - $crate::__private::push_eq_eq(&mut $tokens); - }; - - (>= $tokens:ident) => { - $crate::__private::push_ge(&mut $tokens); - }; - - (> $tokens:ident) => { - $crate::__private::push_gt(&mut $tokens); - }; - - (<= $tokens:ident) => { - $crate::__private::push_le(&mut $tokens); - }; - - (< $tokens:ident) => { - $crate::__private::push_lt(&mut $tokens); - }; - - (*= $tokens:ident) => { - $crate::__private::push_mul_eq(&mut $tokens); - }; - - (!= $tokens:ident) => { - $crate::__private::push_ne(&mut $tokens); - }; - - (| $tokens:ident) => { - $crate::__private::push_or(&mut $tokens); - }; - - (|= $tokens:ident) => { - $crate::__private::push_or_eq(&mut $tokens); - }; - - (|| $tokens:ident) => { - $crate::__private::push_or_or(&mut $tokens); - }; - - (? $tokens:ident) => { - $crate::__private::push_question(&mut $tokens); - }; - - (-> $tokens:ident) => { - $crate::__private::push_rarrow(&mut $tokens); - }; - - (<- $tokens:ident) => { - $crate::__private::push_larrow(&mut $tokens); - }; - - (% $tokens:ident) => { - $crate::__private::push_rem(&mut $tokens); - }; - - (%= $tokens:ident) => { - $crate::__private::push_rem_eq(&mut $tokens); - }; - - (=> $tokens:ident) => { - $crate::__private::push_fat_arrow(&mut $tokens); - }; - - (<< $tokens:ident) => { - $crate::__private::push_shl(&mut $tokens); - }; - - (<<= $tokens:ident) => { - $crate::__private::push_shl_eq(&mut $tokens); - }; - - (>> $tokens:ident) => { - $crate::__private::push_shr(&mut $tokens); - }; - - (>>= $tokens:ident) => { - $crate::__private::push_shr_eq(&mut $tokens); - }; - - (* $tokens:ident) => { - $crate::__private::push_star(&mut $tokens); - }; - - (- $tokens:ident) => { - $crate::__private::push_sub(&mut $tokens); - }; - - (-= $tokens:ident) => { - $crate::__private::push_sub_eq(&mut $tokens); - }; - - ($lifetime:lifetime $tokens:ident) => { - $crate::__private::push_lifetime(&mut $tokens, stringify!($lifetime)); - }; - - (_ $tokens:ident) => { - $crate::__private::push_underscore(&mut $tokens); - }; - - ($other:tt $tokens:ident) => { - $crate::__private::parse(&mut $tokens, stringify!($other)); - }; -} - -// See the comment above `quote_token!` about the rule ordering. -#[macro_export] -#[doc(hidden)] -macro_rules! quote_token_spanned { - ($ident:ident $tokens:ident $span:ident) => { - $crate::__private::push_ident_spanned(&mut $tokens, $span, stringify!($ident)); - }; - - (:: $tokens:ident $span:ident) => { - $crate::__private::push_colon2_spanned(&mut $tokens, $span); - }; - - (( $($inner:tt)* ) $tokens:ident $span:ident) => { - $crate::__private::push_group_spanned( - &mut $tokens, - $span, - $crate::__private::Delimiter::Parenthesis, - $crate::quote_spanned!($span=> $($inner)*), - ); - }; - - ([ $($inner:tt)* ] $tokens:ident $span:ident) => { - $crate::__private::push_group_spanned( - &mut $tokens, - $span, - $crate::__private::Delimiter::Bracket, - $crate::quote_spanned!($span=> $($inner)*), - ); - }; - - ({ $($inner:tt)* } $tokens:ident $span:ident) => { - $crate::__private::push_group_spanned( - &mut $tokens, - $span, - $crate::__private::Delimiter::Brace, - $crate::quote_spanned!($span=> $($inner)*), - ); - }; - - (# $tokens:ident $span:ident) => { - $crate::__private::push_pound_spanned(&mut $tokens, $span); - }; - - (, $tokens:ident $span:ident) => { - $crate::__private::push_comma_spanned(&mut $tokens, $span); - }; - - (. $tokens:ident $span:ident) => { - $crate::__private::push_dot_spanned(&mut $tokens, $span); - }; - - (; $tokens:ident $span:ident) => { - $crate::__private::push_semi_spanned(&mut $tokens, $span); - }; - - (: $tokens:ident $span:ident) => { - $crate::__private::push_colon_spanned(&mut $tokens, $span); - }; - - (+ $tokens:ident $span:ident) => { - $crate::__private::push_add_spanned(&mut $tokens, $span); - }; - - (+= $tokens:ident $span:ident) => { - $crate::__private::push_add_eq_spanned(&mut $tokens, $span); - }; - - (& $tokens:ident $span:ident) => { - $crate::__private::push_and_spanned(&mut $tokens, $span); - }; - - (&& $tokens:ident $span:ident) => { - $crate::__private::push_and_and_spanned(&mut $tokens, $span); - }; - - (&= $tokens:ident $span:ident) => { - $crate::__private::push_and_eq_spanned(&mut $tokens, $span); - }; - - (@ $tokens:ident $span:ident) => { - $crate::__private::push_at_spanned(&mut $tokens, $span); - }; - - (! $tokens:ident $span:ident) => { - $crate::__private::push_bang_spanned(&mut $tokens, $span); - }; - - (^ $tokens:ident $span:ident) => { - $crate::__private::push_caret_spanned(&mut $tokens, $span); - }; - - (^= $tokens:ident $span:ident) => { - $crate::__private::push_caret_eq_spanned(&mut $tokens, $span); - }; - - (/ $tokens:ident $span:ident) => { - $crate::__private::push_div_spanned(&mut $tokens, $span); - }; - - (/= $tokens:ident $span:ident) => { - $crate::__private::push_div_eq_spanned(&mut $tokens, $span); - }; - - (.. $tokens:ident $span:ident) => { - $crate::__private::push_dot2_spanned(&mut $tokens, $span); - }; - - (... $tokens:ident $span:ident) => { - $crate::__private::push_dot3_spanned(&mut $tokens, $span); - }; - - (..= $tokens:ident $span:ident) => { - $crate::__private::push_dot_dot_eq_spanned(&mut $tokens, $span); - }; - - (= $tokens:ident $span:ident) => { - $crate::__private::push_eq_spanned(&mut $tokens, $span); - }; - - (== $tokens:ident $span:ident) => { - $crate::__private::push_eq_eq_spanned(&mut $tokens, $span); - }; - - (>= $tokens:ident $span:ident) => { - $crate::__private::push_ge_spanned(&mut $tokens, $span); - }; - - (> $tokens:ident $span:ident) => { - $crate::__private::push_gt_spanned(&mut $tokens, $span); - }; - - (<= $tokens:ident $span:ident) => { - $crate::__private::push_le_spanned(&mut $tokens, $span); - }; - - (< $tokens:ident $span:ident) => { - $crate::__private::push_lt_spanned(&mut $tokens, $span); - }; - - (*= $tokens:ident $span:ident) => { - $crate::__private::push_mul_eq_spanned(&mut $tokens, $span); - }; - - (!= $tokens:ident $span:ident) => { - $crate::__private::push_ne_spanned(&mut $tokens, $span); - }; - - (| $tokens:ident $span:ident) => { - $crate::__private::push_or_spanned(&mut $tokens, $span); - }; - - (|= $tokens:ident $span:ident) => { - $crate::__private::push_or_eq_spanned(&mut $tokens, $span); - }; - - (|| $tokens:ident $span:ident) => { - $crate::__private::push_or_or_spanned(&mut $tokens, $span); - }; - - (? $tokens:ident $span:ident) => { - $crate::__private::push_question_spanned(&mut $tokens, $span); - }; - - (-> $tokens:ident $span:ident) => { - $crate::__private::push_rarrow_spanned(&mut $tokens, $span); - }; - - (<- $tokens:ident $span:ident) => { - $crate::__private::push_larrow_spanned(&mut $tokens, $span); - }; - - (% $tokens:ident $span:ident) => { - $crate::__private::push_rem_spanned(&mut $tokens, $span); - }; - - (%= $tokens:ident $span:ident) => { - $crate::__private::push_rem_eq_spanned(&mut $tokens, $span); - }; - - (=> $tokens:ident $span:ident) => { - $crate::__private::push_fat_arrow_spanned(&mut $tokens, $span); - }; - - (<< $tokens:ident $span:ident) => { - $crate::__private::push_shl_spanned(&mut $tokens, $span); - }; - - (<<= $tokens:ident $span:ident) => { - $crate::__private::push_shl_eq_spanned(&mut $tokens, $span); - }; - - (>> $tokens:ident $span:ident) => { - $crate::__private::push_shr_spanned(&mut $tokens, $span); - }; - - (>>= $tokens:ident $span:ident) => { - $crate::__private::push_shr_eq_spanned(&mut $tokens, $span); - }; - - (* $tokens:ident $span:ident) => { - $crate::__private::push_star_spanned(&mut $tokens, $span); - }; - - (- $tokens:ident $span:ident) => { - $crate::__private::push_sub_spanned(&mut $tokens, $span); - }; - - (-= $tokens:ident $span:ident) => { - $crate::__private::push_sub_eq_spanned(&mut $tokens, $span); - }; - - ($lifetime:lifetime $tokens:ident $span:ident) => { - $crate::__private::push_lifetime_spanned(&mut $tokens, $span, stringify!($lifetime)); - }; - - (_ $tokens:ident $span:ident) => { - $crate::__private::push_underscore_spanned(&mut $tokens, $span); - }; - - ($other:tt $tokens:ident $span:ident) => { - $crate::__private::parse_spanned(&mut $tokens, $span, stringify!($other)); - }; -} diff --git a/third-party/vendor/quote/src/runtime.rs b/third-party/vendor/quote/src/runtime.rs deleted file mode 100644 index eff044a9..00000000 --- a/third-party/vendor/quote/src/runtime.rs +++ /dev/null @@ -1,530 +0,0 @@ -use self::get_span::{GetSpan, GetSpanBase, GetSpanInner}; -use crate::{IdentFragment, ToTokens, TokenStreamExt}; -use core::fmt; -use core::iter; -use core::ops::BitOr; -use proc_macro2::{Group, Ident, Punct, Spacing, TokenTree}; - -#[doc(hidden)] -pub use alloc::format; -#[doc(hidden)] -pub use core::option::Option; - -#[doc(hidden)] -pub type Delimiter = proc_macro2::Delimiter; -#[doc(hidden)] -pub type Span = proc_macro2::Span; -#[doc(hidden)] -pub type TokenStream = proc_macro2::TokenStream; - -#[doc(hidden)] -pub struct HasIterator; // True -#[doc(hidden)] -pub struct ThereIsNoIteratorInRepetition; // False - -impl BitOr for ThereIsNoIteratorInRepetition { - type Output = ThereIsNoIteratorInRepetition; - fn bitor(self, _rhs: ThereIsNoIteratorInRepetition) -> ThereIsNoIteratorInRepetition { - ThereIsNoIteratorInRepetition - } -} - -impl BitOr for HasIterator { - type Output = HasIterator; - fn bitor(self, _rhs: ThereIsNoIteratorInRepetition) -> HasIterator { - HasIterator - } -} - -impl BitOr for ThereIsNoIteratorInRepetition { - type Output = HasIterator; - fn bitor(self, _rhs: HasIterator) -> HasIterator { - HasIterator - } -} - -impl BitOr for HasIterator { - type Output = HasIterator; - fn bitor(self, _rhs: HasIterator) -> HasIterator { - HasIterator - } -} - -/// Extension traits used by the implementation of `quote!`. These are defined -/// in separate traits, rather than as a single trait due to ambiguity issues. -/// -/// These traits expose a `quote_into_iter` method which should allow calling -/// whichever impl happens to be applicable. Calling that method repeatedly on -/// the returned value should be idempotent. -#[doc(hidden)] -pub mod ext { - use super::RepInterp; - use super::{HasIterator as HasIter, ThereIsNoIteratorInRepetition as DoesNotHaveIter}; - use crate::ToTokens; - use alloc::collections::btree_set::{self, BTreeSet}; - use core::slice; - - /// Extension trait providing the `quote_into_iter` method on iterators. - #[doc(hidden)] - pub trait RepIteratorExt: Iterator + Sized { - fn quote_into_iter(self) -> (Self, HasIter) { - (self, HasIter) - } - } - - impl RepIteratorExt for T {} - - /// Extension trait providing the `quote_into_iter` method for - /// non-iterable types. These types interpolate the same value in each - /// iteration of the repetition. - #[doc(hidden)] - pub trait RepToTokensExt { - /// Pretend to be an iterator for the purposes of `quote_into_iter`. - /// This allows repeated calls to `quote_into_iter` to continue - /// correctly returning DoesNotHaveIter. - fn next(&self) -> Option<&Self> { - Some(self) - } - - fn quote_into_iter(&self) -> (&Self, DoesNotHaveIter) { - (self, DoesNotHaveIter) - } - } - - impl RepToTokensExt for T {} - - /// Extension trait providing the `quote_into_iter` method for types that - /// can be referenced as an iterator. - #[doc(hidden)] - pub trait RepAsIteratorExt<'q> { - type Iter: Iterator; - - fn quote_into_iter(&'q self) -> (Self::Iter, HasIter); - } - - impl<'q, 'a, T: RepAsIteratorExt<'q> + ?Sized> RepAsIteratorExt<'q> for &'a T { - type Iter = T::Iter; - - fn quote_into_iter(&'q self) -> (Self::Iter, HasIter) { - ::quote_into_iter(*self) - } - } - - impl<'q, 'a, T: RepAsIteratorExt<'q> + ?Sized> RepAsIteratorExt<'q> for &'a mut T { - type Iter = T::Iter; - - fn quote_into_iter(&'q self) -> (Self::Iter, HasIter) { - ::quote_into_iter(*self) - } - } - - impl<'q, T: 'q> RepAsIteratorExt<'q> for [T] { - type Iter = slice::Iter<'q, T>; - - fn quote_into_iter(&'q self) -> (Self::Iter, HasIter) { - (self.iter(), HasIter) - } - } - - impl<'q, T: 'q> RepAsIteratorExt<'q> for Vec { - type Iter = slice::Iter<'q, T>; - - fn quote_into_iter(&'q self) -> (Self::Iter, HasIter) { - (self.iter(), HasIter) - } - } - - impl<'q, T: 'q> RepAsIteratorExt<'q> for BTreeSet { - type Iter = btree_set::Iter<'q, T>; - - fn quote_into_iter(&'q self) -> (Self::Iter, HasIter) { - (self.iter(), HasIter) - } - } - - impl<'q, T: RepAsIteratorExt<'q>> RepAsIteratorExt<'q> for RepInterp { - type Iter = T::Iter; - - fn quote_into_iter(&'q self) -> (Self::Iter, HasIter) { - self.0.quote_into_iter() - } - } -} - -// Helper type used within interpolations to allow for repeated binding names. -// Implements the relevant traits, and exports a dummy `next()` method. -#[derive(Copy, Clone)] -#[doc(hidden)] -pub struct RepInterp(pub T); - -impl RepInterp { - // This method is intended to look like `Iterator::next`, and is called when - // a name is bound multiple times, as the previous binding will shadow the - // original `Iterator` object. This allows us to avoid advancing the - // iterator multiple times per iteration. - pub fn next(self) -> Option { - Some(self.0) - } -} - -impl Iterator for RepInterp { - type Item = T::Item; - - fn next(&mut self) -> Option { - self.0.next() - } -} - -impl ToTokens for RepInterp { - fn to_tokens(&self, tokens: &mut TokenStream) { - self.0.to_tokens(tokens); - } -} - -#[doc(hidden)] -#[inline] -pub fn get_span(span: T) -> GetSpan { - GetSpan(GetSpanInner(GetSpanBase(span))) -} - -mod get_span { - use core::ops::Deref; - use proc_macro2::extra::DelimSpan; - use proc_macro2::Span; - - pub struct GetSpan(pub(crate) GetSpanInner); - - pub struct GetSpanInner(pub(crate) GetSpanBase); - - pub struct GetSpanBase(pub(crate) T); - - impl GetSpan { - #[inline] - pub fn __into_span(self) -> Span { - ((self.0).0).0 - } - } - - impl GetSpanInner { - #[inline] - pub fn __into_span(&self) -> Span { - (self.0).0.join() - } - } - - impl GetSpanBase { - #[allow(clippy::unused_self)] - pub fn __into_span(&self) -> T { - unreachable!() - } - } - - impl Deref for GetSpan { - type Target = GetSpanInner; - - #[inline] - fn deref(&self) -> &Self::Target { - &self.0 - } - } - - impl Deref for GetSpanInner { - type Target = GetSpanBase; - - #[inline] - fn deref(&self) -> &Self::Target { - &self.0 - } - } -} - -#[doc(hidden)] -pub fn push_group(tokens: &mut TokenStream, delimiter: Delimiter, inner: TokenStream) { - tokens.append(Group::new(delimiter, inner)); -} - -#[doc(hidden)] -pub fn push_group_spanned( - tokens: &mut TokenStream, - span: Span, - delimiter: Delimiter, - inner: TokenStream, -) { - let mut g = Group::new(delimiter, inner); - g.set_span(span); - tokens.append(g); -} - -#[doc(hidden)] -pub fn parse(tokens: &mut TokenStream, s: &str) { - let s: TokenStream = s.parse().expect("invalid token stream"); - tokens.extend(iter::once(s)); -} - -#[doc(hidden)] -pub fn parse_spanned(tokens: &mut TokenStream, span: Span, s: &str) { - let s: TokenStream = s.parse().expect("invalid token stream"); - tokens.extend(s.into_iter().map(|t| respan_token_tree(t, span))); -} - -// Token tree with every span replaced by the given one. -fn respan_token_tree(mut token: TokenTree, span: Span) -> TokenTree { - match &mut token { - TokenTree::Group(g) => { - let stream = g - .stream() - .into_iter() - .map(|token| respan_token_tree(token, span)) - .collect(); - *g = Group::new(g.delimiter(), stream); - g.set_span(span); - } - other => other.set_span(span), - } - token -} - -#[doc(hidden)] -pub fn push_ident(tokens: &mut TokenStream, s: &str) { - let span = Span::call_site(); - push_ident_spanned(tokens, span, s); -} - -#[doc(hidden)] -pub fn push_ident_spanned(tokens: &mut TokenStream, span: Span, s: &str) { - tokens.append(ident_maybe_raw(s, span)); -} - -#[doc(hidden)] -pub fn push_lifetime(tokens: &mut TokenStream, lifetime: &str) { - struct Lifetime<'a> { - name: &'a str, - state: u8, - } - - impl<'a> Iterator for Lifetime<'a> { - type Item = TokenTree; - - fn next(&mut self) -> Option { - match self.state { - 0 => { - self.state = 1; - Some(TokenTree::Punct(Punct::new('\'', Spacing::Joint))) - } - 1 => { - self.state = 2; - Some(TokenTree::Ident(Ident::new(self.name, Span::call_site()))) - } - _ => None, - } - } - } - - tokens.extend(Lifetime { - name: &lifetime[1..], - state: 0, - }); -} - -#[doc(hidden)] -pub fn push_lifetime_spanned(tokens: &mut TokenStream, span: Span, lifetime: &str) { - struct Lifetime<'a> { - name: &'a str, - span: Span, - state: u8, - } - - impl<'a> Iterator for Lifetime<'a> { - type Item = TokenTree; - - fn next(&mut self) -> Option { - match self.state { - 0 => { - self.state = 1; - let mut apostrophe = Punct::new('\'', Spacing::Joint); - apostrophe.set_span(self.span); - Some(TokenTree::Punct(apostrophe)) - } - 1 => { - self.state = 2; - Some(TokenTree::Ident(Ident::new(self.name, self.span))) - } - _ => None, - } - } - } - - tokens.extend(Lifetime { - name: &lifetime[1..], - span, - state: 0, - }); -} - -macro_rules! push_punct { - ($name:ident $spanned:ident $char1:tt) => { - #[doc(hidden)] - pub fn $name(tokens: &mut TokenStream) { - tokens.append(Punct::new($char1, Spacing::Alone)); - } - #[doc(hidden)] - pub fn $spanned(tokens: &mut TokenStream, span: Span) { - let mut punct = Punct::new($char1, Spacing::Alone); - punct.set_span(span); - tokens.append(punct); - } - }; - ($name:ident $spanned:ident $char1:tt $char2:tt) => { - #[doc(hidden)] - pub fn $name(tokens: &mut TokenStream) { - tokens.append(Punct::new($char1, Spacing::Joint)); - tokens.append(Punct::new($char2, Spacing::Alone)); - } - #[doc(hidden)] - pub fn $spanned(tokens: &mut TokenStream, span: Span) { - let mut punct = Punct::new($char1, Spacing::Joint); - punct.set_span(span); - tokens.append(punct); - let mut punct = Punct::new($char2, Spacing::Alone); - punct.set_span(span); - tokens.append(punct); - } - }; - ($name:ident $spanned:ident $char1:tt $char2:tt $char3:tt) => { - #[doc(hidden)] - pub fn $name(tokens: &mut TokenStream) { - tokens.append(Punct::new($char1, Spacing::Joint)); - tokens.append(Punct::new($char2, Spacing::Joint)); - tokens.append(Punct::new($char3, Spacing::Alone)); - } - #[doc(hidden)] - pub fn $spanned(tokens: &mut TokenStream, span: Span) { - let mut punct = Punct::new($char1, Spacing::Joint); - punct.set_span(span); - tokens.append(punct); - let mut punct = Punct::new($char2, Spacing::Joint); - punct.set_span(span); - tokens.append(punct); - let mut punct = Punct::new($char3, Spacing::Alone); - punct.set_span(span); - tokens.append(punct); - } - }; -} - -push_punct!(push_add push_add_spanned '+'); -push_punct!(push_add_eq push_add_eq_spanned '+' '='); -push_punct!(push_and push_and_spanned '&'); -push_punct!(push_and_and push_and_and_spanned '&' '&'); -push_punct!(push_and_eq push_and_eq_spanned '&' '='); -push_punct!(push_at push_at_spanned '@'); -push_punct!(push_bang push_bang_spanned '!'); -push_punct!(push_caret push_caret_spanned '^'); -push_punct!(push_caret_eq push_caret_eq_spanned '^' '='); -push_punct!(push_colon push_colon_spanned ':'); -push_punct!(push_colon2 push_colon2_spanned ':' ':'); -push_punct!(push_comma push_comma_spanned ','); -push_punct!(push_div push_div_spanned '/'); -push_punct!(push_div_eq push_div_eq_spanned '/' '='); -push_punct!(push_dot push_dot_spanned '.'); -push_punct!(push_dot2 push_dot2_spanned '.' '.'); -push_punct!(push_dot3 push_dot3_spanned '.' '.' '.'); -push_punct!(push_dot_dot_eq push_dot_dot_eq_spanned '.' '.' '='); -push_punct!(push_eq push_eq_spanned '='); -push_punct!(push_eq_eq push_eq_eq_spanned '=' '='); -push_punct!(push_ge push_ge_spanned '>' '='); -push_punct!(push_gt push_gt_spanned '>'); -push_punct!(push_le push_le_spanned '<' '='); -push_punct!(push_lt push_lt_spanned '<'); -push_punct!(push_mul_eq push_mul_eq_spanned '*' '='); -push_punct!(push_ne push_ne_spanned '!' '='); -push_punct!(push_or push_or_spanned '|'); -push_punct!(push_or_eq push_or_eq_spanned '|' '='); -push_punct!(push_or_or push_or_or_spanned '|' '|'); -push_punct!(push_pound push_pound_spanned '#'); -push_punct!(push_question push_question_spanned '?'); -push_punct!(push_rarrow push_rarrow_spanned '-' '>'); -push_punct!(push_larrow push_larrow_spanned '<' '-'); -push_punct!(push_rem push_rem_spanned '%'); -push_punct!(push_rem_eq push_rem_eq_spanned '%' '='); -push_punct!(push_fat_arrow push_fat_arrow_spanned '=' '>'); -push_punct!(push_semi push_semi_spanned ';'); -push_punct!(push_shl push_shl_spanned '<' '<'); -push_punct!(push_shl_eq push_shl_eq_spanned '<' '<' '='); -push_punct!(push_shr push_shr_spanned '>' '>'); -push_punct!(push_shr_eq push_shr_eq_spanned '>' '>' '='); -push_punct!(push_star push_star_spanned '*'); -push_punct!(push_sub push_sub_spanned '-'); -push_punct!(push_sub_eq push_sub_eq_spanned '-' '='); - -#[doc(hidden)] -pub fn push_underscore(tokens: &mut TokenStream) { - push_underscore_spanned(tokens, Span::call_site()); -} - -#[doc(hidden)] -pub fn push_underscore_spanned(tokens: &mut TokenStream, span: Span) { - tokens.append(Ident::new("_", span)); -} - -// Helper method for constructing identifiers from the `format_ident!` macro, -// handling `r#` prefixes. -#[doc(hidden)] -pub fn mk_ident(id: &str, span: Option) -> Ident { - let span = span.unwrap_or_else(Span::call_site); - ident_maybe_raw(id, span) -} - -fn ident_maybe_raw(id: &str, span: Span) -> Ident { - if let Some(id) = id.strip_prefix("r#") { - Ident::new_raw(id, span) - } else { - Ident::new(id, span) - } -} - -// Adapts from `IdentFragment` to `fmt::Display` for use by the `format_ident!` -// macro, and exposes span information from these fragments. -// -// This struct also has forwarding implementations of the formatting traits -// `Octal`, `LowerHex`, `UpperHex`, and `Binary` to allow for their use within -// `format_ident!`. -#[derive(Copy, Clone)] -#[doc(hidden)] -pub struct IdentFragmentAdapter(pub T); - -impl IdentFragmentAdapter { - pub fn span(&self) -> Option { - self.0.span() - } -} - -impl fmt::Display for IdentFragmentAdapter { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - IdentFragment::fmt(&self.0, f) - } -} - -impl fmt::Octal for IdentFragmentAdapter { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - fmt::Octal::fmt(&self.0, f) - } -} - -impl fmt::LowerHex for IdentFragmentAdapter { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - fmt::LowerHex::fmt(&self.0, f) - } -} - -impl fmt::UpperHex for IdentFragmentAdapter { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - fmt::UpperHex::fmt(&self.0, f) - } -} - -impl fmt::Binary for IdentFragmentAdapter { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - fmt::Binary::fmt(&self.0, f) - } -} diff --git a/third-party/vendor/quote/src/spanned.rs b/third-party/vendor/quote/src/spanned.rs deleted file mode 100644 index 6eba6444..00000000 --- a/third-party/vendor/quote/src/spanned.rs +++ /dev/null @@ -1,50 +0,0 @@ -use crate::ToTokens; -use proc_macro2::extra::DelimSpan; -use proc_macro2::{Span, TokenStream}; - -// Not public API other than via the syn crate. Use syn::spanned::Spanned. -pub trait Spanned: private::Sealed { - fn __span(&self) -> Span; -} - -impl Spanned for Span { - fn __span(&self) -> Span { - *self - } -} - -impl Spanned for DelimSpan { - fn __span(&self) -> Span { - self.join() - } -} - -impl Spanned for T { - fn __span(&self) -> Span { - join_spans(self.into_token_stream()) - } -} - -fn join_spans(tokens: TokenStream) -> Span { - let mut iter = tokens.into_iter().map(|tt| tt.span()); - - let first = match iter.next() { - Some(span) => span, - None => return Span::call_site(), - }; - - iter.fold(None, |_prev, next| Some(next)) - .and_then(|last| first.join(last)) - .unwrap_or(first) -} - -mod private { - use crate::ToTokens; - use proc_macro2::extra::DelimSpan; - use proc_macro2::Span; - - pub trait Sealed {} - impl Sealed for Span {} - impl Sealed for DelimSpan {} - impl Sealed for T {} -} diff --git a/third-party/vendor/quote/src/to_tokens.rs b/third-party/vendor/quote/src/to_tokens.rs deleted file mode 100644 index 23b6ec2c..00000000 --- a/third-party/vendor/quote/src/to_tokens.rs +++ /dev/null @@ -1,209 +0,0 @@ -use super::TokenStreamExt; -use alloc::borrow::Cow; -use alloc::rc::Rc; -use core::iter; -use proc_macro2::{Group, Ident, Literal, Punct, Span, TokenStream, TokenTree}; - -/// Types that can be interpolated inside a `quote!` invocation. -/// -/// [`quote!`]: macro.quote.html -pub trait ToTokens { - /// Write `self` to the given `TokenStream`. - /// - /// The token append methods provided by the [`TokenStreamExt`] extension - /// trait may be useful for implementing `ToTokens`. - /// - /// [`TokenStreamExt`]: trait.TokenStreamExt.html - /// - /// # Example - /// - /// Example implementation for a struct representing Rust paths like - /// `std::cmp::PartialEq`: - /// - /// ``` - /// use proc_macro2::{TokenTree, Spacing, Span, Punct, TokenStream}; - /// use quote::{TokenStreamExt, ToTokens}; - /// - /// pub struct Path { - /// pub global: bool, - /// pub segments: Vec, - /// } - /// - /// impl ToTokens for Path { - /// fn to_tokens(&self, tokens: &mut TokenStream) { - /// for (i, segment) in self.segments.iter().enumerate() { - /// if i > 0 || self.global { - /// // Double colon `::` - /// tokens.append(Punct::new(':', Spacing::Joint)); - /// tokens.append(Punct::new(':', Spacing::Alone)); - /// } - /// segment.to_tokens(tokens); - /// } - /// } - /// } - /// # - /// # pub struct PathSegment; - /// # - /// # impl ToTokens for PathSegment { - /// # fn to_tokens(&self, tokens: &mut TokenStream) { - /// # unimplemented!() - /// # } - /// # } - /// ``` - fn to_tokens(&self, tokens: &mut TokenStream); - - /// Convert `self` directly into a `TokenStream` object. - /// - /// This method is implicitly implemented using `to_tokens`, and acts as a - /// convenience method for consumers of the `ToTokens` trait. - fn to_token_stream(&self) -> TokenStream { - let mut tokens = TokenStream::new(); - self.to_tokens(&mut tokens); - tokens - } - - /// Convert `self` directly into a `TokenStream` object. - /// - /// This method is implicitly implemented using `to_tokens`, and acts as a - /// convenience method for consumers of the `ToTokens` trait. - fn into_token_stream(self) -> TokenStream - where - Self: Sized, - { - self.to_token_stream() - } -} - -impl<'a, T: ?Sized + ToTokens> ToTokens for &'a T { - fn to_tokens(&self, tokens: &mut TokenStream) { - (**self).to_tokens(tokens); - } -} - -impl<'a, T: ?Sized + ToTokens> ToTokens for &'a mut T { - fn to_tokens(&self, tokens: &mut TokenStream) { - (**self).to_tokens(tokens); - } -} - -impl<'a, T: ?Sized + ToOwned + ToTokens> ToTokens for Cow<'a, T> { - fn to_tokens(&self, tokens: &mut TokenStream) { - (**self).to_tokens(tokens); - } -} - -impl ToTokens for Box { - fn to_tokens(&self, tokens: &mut TokenStream) { - (**self).to_tokens(tokens); - } -} - -impl ToTokens for Rc { - fn to_tokens(&self, tokens: &mut TokenStream) { - (**self).to_tokens(tokens); - } -} - -impl ToTokens for Option { - fn to_tokens(&self, tokens: &mut TokenStream) { - if let Some(ref t) = *self { - t.to_tokens(tokens); - } - } -} - -impl ToTokens for str { - fn to_tokens(&self, tokens: &mut TokenStream) { - tokens.append(Literal::string(self)); - } -} - -impl ToTokens for String { - fn to_tokens(&self, tokens: &mut TokenStream) { - self.as_str().to_tokens(tokens); - } -} - -macro_rules! primitive { - ($($t:ident => $name:ident)*) => { - $( - impl ToTokens for $t { - fn to_tokens(&self, tokens: &mut TokenStream) { - tokens.append(Literal::$name(*self)); - } - } - )* - }; -} - -primitive! { - i8 => i8_suffixed - i16 => i16_suffixed - i32 => i32_suffixed - i64 => i64_suffixed - i128 => i128_suffixed - isize => isize_suffixed - - u8 => u8_suffixed - u16 => u16_suffixed - u32 => u32_suffixed - u64 => u64_suffixed - u128 => u128_suffixed - usize => usize_suffixed - - f32 => f32_suffixed - f64 => f64_suffixed -} - -impl ToTokens for char { - fn to_tokens(&self, tokens: &mut TokenStream) { - tokens.append(Literal::character(*self)); - } -} - -impl ToTokens for bool { - fn to_tokens(&self, tokens: &mut TokenStream) { - let word = if *self { "true" } else { "false" }; - tokens.append(Ident::new(word, Span::call_site())); - } -} - -impl ToTokens for Group { - fn to_tokens(&self, tokens: &mut TokenStream) { - tokens.append(self.clone()); - } -} - -impl ToTokens for Ident { - fn to_tokens(&self, tokens: &mut TokenStream) { - tokens.append(self.clone()); - } -} - -impl ToTokens for Punct { - fn to_tokens(&self, tokens: &mut TokenStream) { - tokens.append(self.clone()); - } -} - -impl ToTokens for Literal { - fn to_tokens(&self, tokens: &mut TokenStream) { - tokens.append(self.clone()); - } -} - -impl ToTokens for TokenTree { - fn to_tokens(&self, dst: &mut TokenStream) { - dst.append(self.clone()); - } -} - -impl ToTokens for TokenStream { - fn to_tokens(&self, dst: &mut TokenStream) { - dst.extend(iter::once(self.clone())); - } - - fn into_token_stream(self) -> TokenStream { - self - } -} diff --git a/third-party/vendor/quote/tests/compiletest.rs b/third-party/vendor/quote/tests/compiletest.rs deleted file mode 100644 index 7974a624..00000000 --- a/third-party/vendor/quote/tests/compiletest.rs +++ /dev/null @@ -1,7 +0,0 @@ -#[rustversion::attr(not(nightly), ignore)] -#[cfg_attr(miri, ignore)] -#[test] -fn ui() { - let t = trybuild::TestCases::new(); - t.compile_fail("tests/ui/*.rs"); -} diff --git a/third-party/vendor/quote/tests/test.rs b/third-party/vendor/quote/tests/test.rs deleted file mode 100644 index eab4f55a..00000000 --- a/third-party/vendor/quote/tests/test.rs +++ /dev/null @@ -1,549 +0,0 @@ -#![allow( - clippy::disallowed_names, - clippy::let_underscore_untyped, - clippy::shadow_unrelated, - clippy::unseparated_literal_suffix, - clippy::used_underscore_binding -)] - -extern crate proc_macro; - -use std::borrow::Cow; -use std::collections::BTreeSet; - -use proc_macro2::{Delimiter, Group, Ident, Span, TokenStream}; -use quote::{format_ident, quote, quote_spanned, TokenStreamExt}; - -struct X; - -impl quote::ToTokens for X { - fn to_tokens(&self, tokens: &mut TokenStream) { - tokens.append(Ident::new("X", Span::call_site())); - } -} - -#[test] -fn test_quote_impl() { - let tokens = quote! { - impl<'a, T: ToTokens> ToTokens for &'a T { - fn to_tokens(&self, tokens: &mut TokenStream) { - (**self).to_tokens(tokens) - } - } - }; - - let expected = concat!( - "impl < 'a , T : ToTokens > ToTokens for & 'a T { ", - "fn to_tokens (& self , tokens : & mut TokenStream) { ", - "(* * self) . to_tokens (tokens) ", - "} ", - "}" - ); - - assert_eq!(expected, tokens.to_string()); -} - -#[test] -fn test_quote_spanned_impl() { - let span = Span::call_site(); - let tokens = quote_spanned! {span=> - impl<'a, T: ToTokens> ToTokens for &'a T { - fn to_tokens(&self, tokens: &mut TokenStream) { - (**self).to_tokens(tokens) - } - } - }; - - let expected = concat!( - "impl < 'a , T : ToTokens > ToTokens for & 'a T { ", - "fn to_tokens (& self , tokens : & mut TokenStream) { ", - "(* * self) . to_tokens (tokens) ", - "} ", - "}" - ); - - assert_eq!(expected, tokens.to_string()); -} - -#[test] -fn test_substitution() { - let x = X; - let tokens = quote!(#x <#x> (#x) [#x] {#x}); - - let expected = "X < X > (X) [X] { X }"; - - assert_eq!(expected, tokens.to_string()); -} - -#[test] -fn test_iter() { - let primes = &[X, X, X, X]; - - assert_eq!("X X X X", quote!(#(#primes)*).to_string()); - - assert_eq!("X , X , X , X ,", quote!(#(#primes,)*).to_string()); - - assert_eq!("X , X , X , X", quote!(#(#primes),*).to_string()); -} - -#[test] -fn test_array() { - let array: [u8; 40] = [0; 40]; - let _ = quote!(#(#array #array)*); - - let ref_array: &[u8; 40] = &[0; 40]; - let _ = quote!(#(#ref_array #ref_array)*); - - let ref_slice: &[u8] = &[0; 40]; - let _ = quote!(#(#ref_slice #ref_slice)*); - - let array: [X; 2] = [X, X]; // !Copy - let _ = quote!(#(#array #array)*); - - let ref_array: &[X; 2] = &[X, X]; - let _ = quote!(#(#ref_array #ref_array)*); - - let ref_slice: &[X] = &[X, X]; - let _ = quote!(#(#ref_slice #ref_slice)*); -} - -#[test] -fn test_advanced() { - let generics = quote!( <'a, T> ); - - let where_clause = quote!( where T: Serialize ); - - let field_ty = quote!(String); - - let item_ty = quote!(Cow<'a, str>); - - let path = quote!(SomeTrait::serialize_with); - - let value = quote!(self.x); - - let tokens = quote! { - struct SerializeWith #generics #where_clause { - value: &'a #field_ty, - phantom: ::std::marker::PhantomData<#item_ty>, - } - - impl #generics ::serde::Serialize for SerializeWith #generics #where_clause { - fn serialize(&self, s: &mut S) -> Result<(), S::Error> - where S: ::serde::Serializer - { - #path(self.value, s) - } - } - - SerializeWith { - value: #value, - phantom: ::std::marker::PhantomData::<#item_ty>, - } - }; - - let expected = concat!( - "struct SerializeWith < 'a , T > where T : Serialize { ", - "value : & 'a String , ", - "phantom : :: std :: marker :: PhantomData < Cow < 'a , str > > , ", - "} ", - "impl < 'a , T > :: serde :: Serialize for SerializeWith < 'a , T > where T : Serialize { ", - "fn serialize < S > (& self , s : & mut S) -> Result < () , S :: Error > ", - "where S : :: serde :: Serializer ", - "{ ", - "SomeTrait :: serialize_with (self . value , s) ", - "} ", - "} ", - "SerializeWith { ", - "value : self . x , ", - "phantom : :: std :: marker :: PhantomData :: < Cow < 'a , str > > , ", - "}" - ); - - assert_eq!(expected, tokens.to_string()); -} - -#[test] -fn test_integer() { - let ii8 = -1i8; - let ii16 = -1i16; - let ii32 = -1i32; - let ii64 = -1i64; - let ii128 = -1i128; - let iisize = -1isize; - let uu8 = 1u8; - let uu16 = 1u16; - let uu32 = 1u32; - let uu64 = 1u64; - let uu128 = 1u128; - let uusize = 1usize; - - let tokens = quote! { - 1 1i32 1u256 - #ii8 #ii16 #ii32 #ii64 #ii128 #iisize - #uu8 #uu16 #uu32 #uu64 #uu128 #uusize - }; - let expected = - "1 1i32 1u256 - 1i8 - 1i16 - 1i32 - 1i64 - 1i128 - 1isize 1u8 1u16 1u32 1u64 1u128 1usize"; - assert_eq!(expected, tokens.to_string()); -} - -#[test] -fn test_floating() { - let e32 = 2.345f32; - - let e64 = 2.345f64; - - let tokens = quote! { - #e32 - #e64 - }; - let expected = concat!("2.345f32 2.345f64"); - assert_eq!(expected, tokens.to_string()); -} - -#[test] -fn test_char() { - let zero = '\u{1}'; - let pound = '#'; - let quote = '"'; - let apost = '\''; - let newline = '\n'; - let heart = '\u{2764}'; - - let tokens = quote! { - #zero #pound #quote #apost #newline #heart - }; - let expected = "'\\u{1}' '#' '\"' '\\'' '\\n' '\u{2764}'"; - assert_eq!(expected, tokens.to_string()); -} - -#[test] -fn test_str() { - let s = "\u{1} a 'b \" c"; - let tokens = quote!(#s); - let expected = "\"\\u{1} a 'b \\\" c\""; - assert_eq!(expected, tokens.to_string()); -} - -#[test] -fn test_string() { - let s = "\u{1} a 'b \" c".to_string(); - let tokens = quote!(#s); - let expected = "\"\\u{1} a 'b \\\" c\""; - assert_eq!(expected, tokens.to_string()); -} - -#[test] -fn test_interpolated_literal() { - macro_rules! m { - ($literal:literal) => { - quote!($literal) - }; - } - - let tokens = m!(1); - let expected = "1"; - assert_eq!(expected, tokens.to_string()); - - let tokens = m!(-1); - let expected = "- 1"; - assert_eq!(expected, tokens.to_string()); - - let tokens = m!(true); - let expected = "true"; - assert_eq!(expected, tokens.to_string()); - - let tokens = m!(-true); - let expected = "- true"; - assert_eq!(expected, tokens.to_string()); -} - -#[test] -fn test_ident() { - let foo = Ident::new("Foo", Span::call_site()); - let bar = Ident::new(&format!("Bar{}", 7), Span::call_site()); - let tokens = quote!(struct #foo; enum #bar {}); - let expected = "struct Foo ; enum Bar7 { }"; - assert_eq!(expected, tokens.to_string()); -} - -#[test] -fn test_underscore() { - let tokens = quote!(let _;); - let expected = "let _ ;"; - assert_eq!(expected, tokens.to_string()); -} - -#[test] -fn test_duplicate() { - let ch = 'x'; - - let tokens = quote!(#ch #ch); - - let expected = "'x' 'x'"; - assert_eq!(expected, tokens.to_string()); -} - -#[test] -fn test_fancy_repetition() { - let foo = vec!["a", "b"]; - let bar = vec![true, false]; - - let tokens = quote! { - #(#foo: #bar),* - }; - - let expected = r#""a" : true , "b" : false"#; - assert_eq!(expected, tokens.to_string()); -} - -#[test] -fn test_nested_fancy_repetition() { - let nested = vec![vec!['a', 'b', 'c'], vec!['x', 'y', 'z']]; - - let tokens = quote! { - #( - #(#nested)* - ),* - }; - - let expected = "'a' 'b' 'c' , 'x' 'y' 'z'"; - assert_eq!(expected, tokens.to_string()); -} - -#[test] -fn test_duplicate_name_repetition() { - let foo = &["a", "b"]; - - let tokens = quote! { - #(#foo: #foo),* - #(#foo: #foo),* - }; - - let expected = r#""a" : "a" , "b" : "b" "a" : "a" , "b" : "b""#; - assert_eq!(expected, tokens.to_string()); -} - -#[test] -fn test_duplicate_name_repetition_no_copy() { - let foo = vec!["a".to_owned(), "b".to_owned()]; - - let tokens = quote! { - #(#foo: #foo),* - }; - - let expected = r#""a" : "a" , "b" : "b""#; - assert_eq!(expected, tokens.to_string()); -} - -#[test] -fn test_btreeset_repetition() { - let mut set = BTreeSet::new(); - set.insert("a".to_owned()); - set.insert("b".to_owned()); - - let tokens = quote! { - #(#set: #set),* - }; - - let expected = r#""a" : "a" , "b" : "b""#; - assert_eq!(expected, tokens.to_string()); -} - -#[test] -fn test_variable_name_conflict() { - // The implementation of `#(...),*` uses the variable `_i` but it should be - // fine, if a little confusing when debugging. - let _i = vec!['a', 'b']; - let tokens = quote! { #(#_i),* }; - let expected = "'a' , 'b'"; - assert_eq!(expected, tokens.to_string()); -} - -#[test] -fn test_nonrep_in_repetition() { - let rep = vec!["a", "b"]; - let nonrep = "c"; - - let tokens = quote! { - #(#rep #rep : #nonrep #nonrep),* - }; - - let expected = r#""a" "a" : "c" "c" , "b" "b" : "c" "c""#; - assert_eq!(expected, tokens.to_string()); -} - -#[test] -fn test_empty_quote() { - let tokens = quote!(); - assert_eq!("", tokens.to_string()); -} - -#[test] -fn test_box_str() { - let b = "str".to_owned().into_boxed_str(); - let tokens = quote! { #b }; - assert_eq!("\"str\"", tokens.to_string()); -} - -#[test] -fn test_cow() { - let owned: Cow = Cow::Owned(Ident::new("owned", Span::call_site())); - - let ident = Ident::new("borrowed", Span::call_site()); - let borrowed = Cow::Borrowed(&ident); - - let tokens = quote! { #owned #borrowed }; - assert_eq!("owned borrowed", tokens.to_string()); -} - -#[test] -fn test_closure() { - fn field_i(i: usize) -> Ident { - format_ident!("__field{}", i) - } - - let fields = (0usize..3) - .map(field_i as fn(_) -> _) - .map(|var| quote! { #var }); - - let tokens = quote! { #(#fields)* }; - assert_eq!("__field0 __field1 __field2", tokens.to_string()); -} - -#[test] -fn test_append_tokens() { - let mut a = quote!(a); - let b = quote!(b); - a.append_all(b); - assert_eq!("a b", a.to_string()); -} - -#[test] -fn test_format_ident() { - let id0 = format_ident!("Aa"); - let id1 = format_ident!("Hello{x}", x = id0); - let id2 = format_ident!("Hello{x}", x = 5usize); - let id3 = format_ident!("Hello{}_{x}", id0, x = 10usize); - let id4 = format_ident!("Aa", span = Span::call_site()); - let id5 = format_ident!("Hello{}", Cow::Borrowed("World")); - - assert_eq!(id0, "Aa"); - assert_eq!(id1, "HelloAa"); - assert_eq!(id2, "Hello5"); - assert_eq!(id3, "HelloAa_10"); - assert_eq!(id4, "Aa"); - assert_eq!(id5, "HelloWorld"); -} - -#[test] -fn test_format_ident_strip_raw() { - let id = format_ident!("r#struct"); - let my_id = format_ident!("MyId{}", id); - let raw_my_id = format_ident!("r#MyId{}", id); - - assert_eq!(id, "r#struct"); - assert_eq!(my_id, "MyIdstruct"); - assert_eq!(raw_my_id, "r#MyIdstruct"); -} - -#[test] -fn test_outer_line_comment() { - let tokens = quote! { - /// doc - }; - let expected = "# [doc = r\" doc\"]"; - assert_eq!(expected, tokens.to_string()); -} - -#[test] -fn test_inner_line_comment() { - let tokens = quote! { - //! doc - }; - let expected = "# ! [doc = r\" doc\"]"; - assert_eq!(expected, tokens.to_string()); -} - -#[test] -fn test_outer_block_comment() { - let tokens = quote! { - /** doc */ - }; - let expected = "# [doc = r\" doc \"]"; - assert_eq!(expected, tokens.to_string()); -} - -#[test] -fn test_inner_block_comment() { - let tokens = quote! { - /*! doc */ - }; - let expected = "# ! [doc = r\" doc \"]"; - assert_eq!(expected, tokens.to_string()); -} - -#[test] -fn test_outer_attr() { - let tokens = quote! { - #[inline] - }; - let expected = "# [inline]"; - assert_eq!(expected, tokens.to_string()); -} - -#[test] -fn test_inner_attr() { - let tokens = quote! { - #![no_std] - }; - let expected = "# ! [no_std]"; - assert_eq!(expected, tokens.to_string()); -} - -// https://github.com/dtolnay/quote/issues/130 -#[test] -fn test_star_after_repetition() { - let c = vec!['0', '1']; - let tokens = quote! { - #( - f(#c); - )* - *out = None; - }; - let expected = "f ('0') ; f ('1') ; * out = None ;"; - assert_eq!(expected, tokens.to_string()); -} - -#[test] -fn test_quote_raw_id() { - let id = quote!(r#raw_id); - assert_eq!(id.to_string(), "r#raw_id"); -} - -#[test] -fn test_type_inference_for_span() { - trait CallSite { - fn get() -> Self; - } - - impl CallSite for Span { - fn get() -> Self { - Span::call_site() - } - } - - let span = Span::call_site(); - let _ = quote_spanned!(span=> ...); - - let delim_span = Group::new(Delimiter::Parenthesis, TokenStream::new()).delim_span(); - let _ = quote_spanned!(delim_span=> ...); - - let inferred = CallSite::get(); - let _ = quote_spanned!(inferred=> ...); - - if false { - let proc_macro_span = proc_macro::Span::call_site(); - let _ = quote_spanned!(proc_macro_span.into()=> ...); - } -} diff --git a/third-party/vendor/quote/tests/ui/does-not-have-iter-interpolated-dup.rs b/third-party/vendor/quote/tests/ui/does-not-have-iter-interpolated-dup.rs deleted file mode 100644 index 0a39f415..00000000 --- a/third-party/vendor/quote/tests/ui/does-not-have-iter-interpolated-dup.rs +++ /dev/null @@ -1,9 +0,0 @@ -use quote::quote; - -fn main() { - let nonrep = ""; - - // Without some protection against repetitions with no iterator somewhere - // inside, this would loop infinitely. - quote!(#(#nonrep #nonrep)*); -} diff --git a/third-party/vendor/quote/tests/ui/does-not-have-iter-interpolated-dup.stderr b/third-party/vendor/quote/tests/ui/does-not-have-iter-interpolated-dup.stderr deleted file mode 100644 index 99c20a56..00000000 --- a/third-party/vendor/quote/tests/ui/does-not-have-iter-interpolated-dup.stderr +++ /dev/null @@ -1,11 +0,0 @@ -error[E0308]: mismatched types - --> tests/ui/does-not-have-iter-interpolated-dup.rs:8:5 - | -8 | quote!(#(#nonrep #nonrep)*); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | | - | expected `HasIterator`, found `ThereIsNoIteratorInRepetition` - | expected due to this - | here the type of `has_iter` is inferred to be `ThereIsNoIteratorInRepetition` - | - = note: this error originates in the macro `$crate::quote_token_with_context` which comes from the expansion of the macro `quote` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/third-party/vendor/quote/tests/ui/does-not-have-iter-interpolated.rs b/third-party/vendor/quote/tests/ui/does-not-have-iter-interpolated.rs deleted file mode 100644 index 2c740cc0..00000000 --- a/third-party/vendor/quote/tests/ui/does-not-have-iter-interpolated.rs +++ /dev/null @@ -1,9 +0,0 @@ -use quote::quote; - -fn main() { - let nonrep = ""; - - // Without some protection against repetitions with no iterator somewhere - // inside, this would loop infinitely. - quote!(#(#nonrep)*); -} diff --git a/third-party/vendor/quote/tests/ui/does-not-have-iter-interpolated.stderr b/third-party/vendor/quote/tests/ui/does-not-have-iter-interpolated.stderr deleted file mode 100644 index ef908131..00000000 --- a/third-party/vendor/quote/tests/ui/does-not-have-iter-interpolated.stderr +++ /dev/null @@ -1,11 +0,0 @@ -error[E0308]: mismatched types - --> tests/ui/does-not-have-iter-interpolated.rs:8:5 - | -8 | quote!(#(#nonrep)*); - | ^^^^^^^^^^^^^^^^^^^ - | | - | expected `HasIterator`, found `ThereIsNoIteratorInRepetition` - | expected due to this - | here the type of `has_iter` is inferred to be `ThereIsNoIteratorInRepetition` - | - = note: this error originates in the macro `$crate::quote_token_with_context` which comes from the expansion of the macro `quote` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/third-party/vendor/quote/tests/ui/does-not-have-iter-separated.rs b/third-party/vendor/quote/tests/ui/does-not-have-iter-separated.rs deleted file mode 100644 index c027243d..00000000 --- a/third-party/vendor/quote/tests/ui/does-not-have-iter-separated.rs +++ /dev/null @@ -1,5 +0,0 @@ -use quote::quote; - -fn main() { - quote!(#(a b),*); -} diff --git a/third-party/vendor/quote/tests/ui/does-not-have-iter-separated.stderr b/third-party/vendor/quote/tests/ui/does-not-have-iter-separated.stderr deleted file mode 100644 index 7c6e30f2..00000000 --- a/third-party/vendor/quote/tests/ui/does-not-have-iter-separated.stderr +++ /dev/null @@ -1,10 +0,0 @@ -error[E0308]: mismatched types - --> tests/ui/does-not-have-iter-separated.rs:4:5 - | -4 | quote!(#(a b),*); - | ^^^^^^^^^^^^^^^^ - | | - | expected `HasIterator`, found `ThereIsNoIteratorInRepetition` - | expected due to this - | - = note: this error originates in the macro `$crate::quote_token_with_context` which comes from the expansion of the macro `quote` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/third-party/vendor/quote/tests/ui/does-not-have-iter.rs b/third-party/vendor/quote/tests/ui/does-not-have-iter.rs deleted file mode 100644 index 8908353b..00000000 --- a/third-party/vendor/quote/tests/ui/does-not-have-iter.rs +++ /dev/null @@ -1,5 +0,0 @@ -use quote::quote; - -fn main() { - quote!(#(a b)*); -} diff --git a/third-party/vendor/quote/tests/ui/does-not-have-iter.stderr b/third-party/vendor/quote/tests/ui/does-not-have-iter.stderr deleted file mode 100644 index 0b13e5cb..00000000 --- a/third-party/vendor/quote/tests/ui/does-not-have-iter.stderr +++ /dev/null @@ -1,10 +0,0 @@ -error[E0308]: mismatched types - --> tests/ui/does-not-have-iter.rs:4:5 - | -4 | quote!(#(a b)*); - | ^^^^^^^^^^^^^^^ - | | - | expected `HasIterator`, found `ThereIsNoIteratorInRepetition` - | expected due to this - | - = note: this error originates in the macro `$crate::quote_token_with_context` which comes from the expansion of the macro `quote` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/third-party/vendor/quote/tests/ui/not-quotable.rs b/third-party/vendor/quote/tests/ui/not-quotable.rs deleted file mode 100644 index f991c188..00000000 --- a/third-party/vendor/quote/tests/ui/not-quotable.rs +++ /dev/null @@ -1,7 +0,0 @@ -use quote::quote; -use std::net::Ipv4Addr; - -fn main() { - let ip = Ipv4Addr::LOCALHOST; - let _ = quote! { #ip }; -} diff --git a/third-party/vendor/quote/tests/ui/not-quotable.stderr b/third-party/vendor/quote/tests/ui/not-quotable.stderr deleted file mode 100644 index 35cb6f2b..00000000 --- a/third-party/vendor/quote/tests/ui/not-quotable.stderr +++ /dev/null @@ -1,20 +0,0 @@ -error[E0277]: the trait bound `Ipv4Addr: ToTokens` is not satisfied - --> tests/ui/not-quotable.rs:6:13 - | -6 | let _ = quote! { #ip }; - | ^^^^^^^^^^^^^^ - | | - | the trait `ToTokens` is not implemented for `Ipv4Addr` - | required by a bound introduced by this call - | - = help: the following other types implement trait `ToTokens`: - bool - char - isize - i8 - i16 - i32 - i64 - i128 - and $N others - = note: this error originates in the macro `quote` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/third-party/vendor/quote/tests/ui/not-repeatable.rs b/third-party/vendor/quote/tests/ui/not-repeatable.rs deleted file mode 100644 index a8f0fe77..00000000 --- a/third-party/vendor/quote/tests/ui/not-repeatable.rs +++ /dev/null @@ -1,8 +0,0 @@ -use quote::quote; - -struct Ipv4Addr; - -fn main() { - let ip = Ipv4Addr; - let _ = quote! { #(#ip)* }; -} diff --git a/third-party/vendor/quote/tests/ui/not-repeatable.stderr b/third-party/vendor/quote/tests/ui/not-repeatable.stderr deleted file mode 100644 index 2ed1da04..00000000 --- a/third-party/vendor/quote/tests/ui/not-repeatable.stderr +++ /dev/null @@ -1,35 +0,0 @@ -error[E0599]: the method `quote_into_iter` exists for struct `Ipv4Addr`, but its trait bounds were not satisfied - --> tests/ui/not-repeatable.rs:7:13 - | -3 | struct Ipv4Addr; - | --------------- - | | - | method `quote_into_iter` not found for this struct - | doesn't satisfy `Ipv4Addr: Iterator` - | doesn't satisfy `Ipv4Addr: ToTokens` - | doesn't satisfy `Ipv4Addr: ext::RepIteratorExt` - | doesn't satisfy `Ipv4Addr: ext::RepToTokensExt` -... -7 | let _ = quote! { #(#ip)* }; - | ^^^^^^^^^^^^^^^^^^ method cannot be called on `Ipv4Addr` due to unsatisfied trait bounds - | - = note: the following trait bounds were not satisfied: - `Ipv4Addr: Iterator` - which is required by `Ipv4Addr: ext::RepIteratorExt` - `&Ipv4Addr: Iterator` - which is required by `&Ipv4Addr: ext::RepIteratorExt` - `Ipv4Addr: ToTokens` - which is required by `Ipv4Addr: ext::RepToTokensExt` - `&mut Ipv4Addr: Iterator` - which is required by `&mut Ipv4Addr: ext::RepIteratorExt` -note: the traits `ToTokens` and `Iterator` must be implemented - --> src/to_tokens.rs - | - | pub trait ToTokens { - | ^^^^^^^^^^^^^^^^^^ - | - ::: $RUST/core/src/iter/traits/iterator.rs - | - | pub trait Iterator { - | ^^^^^^^^^^^^^^^^^^ - = note: this error originates in the macro `$crate::quote_bind_into_iter` which comes from the expansion of the macro `quote` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/third-party/vendor/quote/tests/ui/wrong-type-span.rs b/third-party/vendor/quote/tests/ui/wrong-type-span.rs deleted file mode 100644 index d5601c8a..00000000 --- a/third-party/vendor/quote/tests/ui/wrong-type-span.rs +++ /dev/null @@ -1,7 +0,0 @@ -use quote::quote_spanned; - -fn main() { - let span = ""; - let x = 0i32; - quote_spanned!(span=> #x); -} diff --git a/third-party/vendor/quote/tests/ui/wrong-type-span.stderr b/third-party/vendor/quote/tests/ui/wrong-type-span.stderr deleted file mode 100644 index 12ad3077..00000000 --- a/third-party/vendor/quote/tests/ui/wrong-type-span.stderr +++ /dev/null @@ -1,10 +0,0 @@ -error[E0308]: mismatched types - --> tests/ui/wrong-type-span.rs:6:5 - | -6 | quote_spanned!(span=> #x); - | ^^^^^^^^^^^^^^^^^^^^^^^^^ - | | - | expected `Span`, found `&str` - | expected due to this - | - = note: this error originates in the macro `quote_spanned` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/third-party/vendor/riscv-rt-macros/.cargo-checksum.json b/third-party/vendor/riscv-rt-macros/.cargo-checksum.json deleted file mode 100644 index 5445cb55..00000000 --- a/third-party/vendor/riscv-rt-macros/.cargo-checksum.json +++ /dev/null @@ -1 +0,0 @@ -{"files":{"Cargo.toml":"ea761bd47940eeb0eb3dc5b1a0e27980127394de9828f1b15993ef810f49ee7f","src/lib.rs":"51c18c170fd1e03195556633917f21328fff9c48ac57e9e69a253a2d3a47f4cb"},"package":"a8d100d466dbb76681ef6a9386f3da9abc570d57394e86da0ba5af8c4408486d"} \ No newline at end of file diff --git a/third-party/vendor/riscv-rt-macros/Cargo.toml b/third-party/vendor/riscv-rt-macros/Cargo.toml deleted file mode 100644 index afea5ed9..00000000 --- a/third-party/vendor/riscv-rt-macros/Cargo.toml +++ /dev/null @@ -1,48 +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 are reading this file be aware that the original Cargo.toml -# will likely look very different (and much more reasonable). -# See Cargo.toml.orig for the original contents. - -[package] -name = "riscv-rt-macros" -version = "0.2.1" -authors = [ - "The RISC-V Team ", - "Jorge Aparicio ", -] -description = "Attributes re-exported in `riscv-rt`" -documentation = "https://docs.rs/riscv-rt" -keywords = [ - "riscv", - "runtime", - "startup", -] -categories = [ - "embedded", - "no-std", -] -license = "MIT OR Apache-2.0" -repository = "https://github.com/rust-embedded/riscv" -resolver = "2" - -[lib] -proc-macro = true - -[dependencies.proc-macro2] -version = "1.0" - -[dependencies.quote] -version = "1.0" - -[dependencies.syn] -version = "1.0" -features = [ - "extra-traits", - "full", -] diff --git a/third-party/vendor/riscv-rt-macros/src/lib.rs b/third-party/vendor/riscv-rt-macros/src/lib.rs deleted file mode 100644 index b48cc111..00000000 --- a/third-party/vendor/riscv-rt-macros/src/lib.rs +++ /dev/null @@ -1,263 +0,0 @@ -#![deny(warnings)] - -extern crate proc_macro; -#[macro_use] -extern crate quote; -extern crate core; -extern crate proc_macro2; -#[macro_use] -extern crate syn; - -use proc_macro2::Span; -use syn::{ - parse::{self, Parse}, - spanned::Spanned, - FnArg, ItemFn, LitInt, LitStr, PathArguments, ReturnType, Type, Visibility, -}; - -use proc_macro::TokenStream; - -/// Attribute to declare the entry point of the program -/// -/// **IMPORTANT**: This attribute must appear exactly *once* in the dependency graph. Also, if you -/// are using Rust 1.30 the attribute must be used on a reachable item (i.e. there must be no -/// private modules between the item and the root of the crate); if the item is in the root of the -/// crate you'll be fine. This reachability restriction doesn't apply to Rust 1.31 and newer releases. -/// -/// The specified function will be called by the reset handler *after* RAM has been initialized. -/// If present, the FPU will also be enabled before the function is called. -/// -/// The type of the specified function must be `[unsafe] fn() -> !` (never ending function) -/// -/// # Properties -/// -/// The entry point will be called by the reset handler. The program can't reference to the entry -/// point, much less invoke it. -/// -/// # Examples -/// -/// - Simple entry point -/// -/// ``` no_run -/// # #![no_main] -/// # use riscv_rt_macros::entry; -/// #[entry] -/// fn main() -> ! { -/// loop { -/// /* .. */ -/// } -/// } -/// ``` -#[proc_macro_attribute] -pub fn entry(args: TokenStream, input: TokenStream) -> TokenStream { - let f = parse_macro_input!(input as ItemFn); - - // check the function arguments - if f.sig.inputs.len() > 3 { - return parse::Error::new( - f.sig.inputs.last().unwrap().span(), - "`#[entry]` function has too many arguments", - ) - .to_compile_error() - .into(); - } - for arg in &f.sig.inputs { - match arg { - FnArg::Receiver(_) => { - return parse::Error::new(arg.span(), "invalid argument") - .to_compile_error() - .into(); - } - FnArg::Typed(t) => { - if !is_simple_type(&t.ty, "usize") { - return parse::Error::new(t.ty.span(), "argument type must be usize") - .to_compile_error() - .into(); - } - } - } - } - - // check the function signature - let valid_signature = f.sig.constness.is_none() - && f.sig.asyncness.is_none() - && f.vis == Visibility::Inherited - && f.sig.abi.is_none() - && f.sig.generics.params.is_empty() - && f.sig.generics.where_clause.is_none() - && f.sig.variadic.is_none() - && match f.sig.output { - ReturnType::Default => false, - ReturnType::Type(_, ref ty) => matches!(**ty, Type::Never(_)), - }; - - if !valid_signature { - return parse::Error::new( - f.span(), - "`#[entry]` function must have signature `[unsafe] fn([arg0: usize, ...]) -> !`", - ) - .to_compile_error() - .into(); - } - - if !args.is_empty() { - return parse::Error::new(Span::call_site(), "This attribute accepts no arguments") - .to_compile_error() - .into(); - } - - // XXX should we blacklist other attributes? - let attrs = f.attrs; - let unsafety = f.sig.unsafety; - let args = f.sig.inputs; - let stmts = f.block.stmts; - - quote!( - #[allow(non_snake_case)] - #[export_name = "main"] - #(#attrs)* - pub #unsafety fn __risc_v_rt__main(#args) -> ! { - #(#stmts)* - } - ) - .into() -} - -#[allow(unused)] -fn is_simple_type(ty: &Type, name: &str) -> bool { - if let Type::Path(p) = ty { - if p.qself.is_none() && p.path.leading_colon.is_none() && p.path.segments.len() == 1 { - let segment = p.path.segments.first().unwrap(); - if segment.ident == name && segment.arguments == PathArguments::None { - return true; - } - } - } - false -} - -/// Attribute to mark which function will be called at the beginning of the reset handler. -/// -/// **IMPORTANT**: This attribute can appear at most *once* in the dependency graph. Also, if you -/// are using Rust 1.30 the attribute must be used on a reachable item (i.e. there must be no -/// private modules between the item and the root of the crate); if the item is in the root of the -/// crate you'll be fine. This reachability restriction doesn't apply to Rust 1.31 and newer -/// releases. -/// -/// The function must have the signature of `unsafe fn()`. -/// -/// The function passed will be called before static variables are initialized. Any access of static -/// variables will result in undefined behavior. -/// -/// # Examples -/// -/// ``` -/// # use riscv_rt_macros::pre_init; -/// #[pre_init] -/// unsafe fn before_main() { -/// // do something here -/// } -/// -/// # fn main() {} -/// ``` -#[proc_macro_attribute] -pub fn pre_init(args: TokenStream, input: TokenStream) -> TokenStream { - let f = parse_macro_input!(input as ItemFn); - - // check the function signature - let valid_signature = f.sig.constness.is_none() - && f.sig.asyncness.is_none() - && f.vis == Visibility::Inherited - && f.sig.unsafety.is_some() - && f.sig.abi.is_none() - && f.sig.inputs.is_empty() - && f.sig.generics.params.is_empty() - && f.sig.generics.where_clause.is_none() - && f.sig.variadic.is_none() - && match f.sig.output { - ReturnType::Default => true, - ReturnType::Type(_, ref ty) => match **ty { - Type::Tuple(ref tuple) => tuple.elems.is_empty(), - _ => false, - }, - }; - - if !valid_signature { - return parse::Error::new( - f.span(), - "`#[pre_init]` function must have signature `unsafe fn()`", - ) - .to_compile_error() - .into(); - } - - if !args.is_empty() { - return parse::Error::new(Span::call_site(), "This attribute accepts no arguments") - .to_compile_error() - .into(); - } - - // XXX should we blacklist other attributes? - let attrs = f.attrs; - let ident = f.sig.ident; - let block = f.block; - - quote!( - #[export_name = "__pre_init"] - #(#attrs)* - pub unsafe fn #ident() #block - ) - .into() -} - -struct AsmLoopArgs { - asm_template: String, - count: usize, -} - -impl Parse for AsmLoopArgs { - fn parse(input: syn::parse::ParseStream) -> syn::Result { - let template: LitStr = input.parse().unwrap(); - _ = input.parse::().unwrap(); - let count: LitInt = input.parse().unwrap(); - - Ok(Self { - asm_template: template.value(), - count: count.base10_parse().unwrap(), - }) - } -} - -/// Loops an asm expression n times. -/// -/// `loop_asm!` takes 2 arguments, the first is a string literal and the second is a number literal -/// See [the formatting syntax documentation in `std::fmt`](../std/fmt/index.html) -/// for details. -/// -/// Argument 1 is an assembly expression, all "{}" in this assembly expression will be replaced with the -/// current loop index. -/// -/// Argument 2 is the number of loops to do with the provided expression. -/// -/// # Examples -/// -/// ``` -/// # use riscv_rt_macros::loop_asm; -/// unsafe { -/// loop_asm!("fmv.w.x f{}, x0", 32); // => core::arch::asm!("fmv.w.x f0, x0") ... core::arch::asm!("fmv.w.x f31, x0") -/// } -/// ``` -#[proc_macro] -pub fn loop_asm(input: TokenStream) -> TokenStream { - let args = parse_macro_input!(input as AsmLoopArgs); - - let tokens = (0..args.count) - .map(|i| { - let i = i.to_string(); - let asm = args.asm_template.replace("{}", &i); - format!("core::arch::asm!(\"{}\");", asm) - }) - .collect::>() - .join("\n"); - tokens.parse().unwrap() -} diff --git a/third-party/vendor/riscv-rt/.cargo-checksum.json b/third-party/vendor/riscv-rt/.cargo-checksum.json deleted file mode 100644 index cc537c56..00000000 --- a/third-party/vendor/riscv-rt/.cargo-checksum.json +++ /dev/null @@ -1 +0,0 @@ -{"files":{"CHANGELOG.md":"9c876fbec5ced162ed337e39fb6b4f14d5b82d2e4a0c4c25ff2bdfd3a18526ce","Cargo.lock":"d9d0bd76547cd02f7772461a9b0fe4dba5db3f09f69990189219891524c33a98","Cargo.toml":"32da80d8e7ae986bfe4b6139244952df8dc00e7e6b3e9650e62792e9ebd479ce","README.md":"345e80c26ba58cbf178f24be3e24b32cc75ed6886329f6d6ce57dc7476d410ce","build.rs":"6171e83ad149b35f4717ddccf0e521420503f7cb1455e29fc52f10051b34c3a3","examples/device.x":"41a02ab435609a2a4817f897185af5f587f95d055273e04fd397afd3ac43f18c","examples/empty.rs":"1d2c04e00039ca3d3afb365c3144aad8efe972b9e6ff406a8a1a5dd4b3cba46a","examples/multi_core.rs":"13ee025a52a2d39b8b4018c6ed18f87ab7d8f67c8b7f0e76ad7bb3247ff4ca04","link.x.in":"4078d9b8ffacd210fb7718ae63fded13c509876d7b92b580d6683fe0e75555ee","src/asm.rs":"b759cd18dc6f025a17330daa4af2300e65df91e9a853dfb51d0e2f5ac6627d5e","src/lib.rs":"2b0b9b913e019f6d27d48b9b23cf21833ff8ab938c118c774b06592500bf98a4"},"package":"c0d35e32cf1383183e8885d8a9aa4402a087fd094dc34c2cb6df6687d0229dfe"} \ No newline at end of file diff --git a/third-party/vendor/riscv-rt/CHANGELOG.md b/third-party/vendor/riscv-rt/CHANGELOG.md deleted file mode 100644 index 4a72f025..00000000 --- a/third-party/vendor/riscv-rt/CHANGELOG.md +++ /dev/null @@ -1,150 +0,0 @@ -# Change Log - -All notable changes to this project will be documented in this file. - -The format is based on [Keep a Changelog](http://keepachangelog.com/) -and this project adheres to [Semantic Versioning](http://semver.org/). - -## [Unreleased] - -## [v0.12.2] - 2024-02-15 - -### Added - -- Implementation of `default_mp_hook` when `single-hart` feature is enabled. - -## [v0.12.1] - 2024-01-24 - -### Added - -- Patch in assembly code to avoid spurious errors from LLVM - -## [v0.12.0] - 2024-01-14 - -### Added - -- Add `links` field in `Cargo.toml` -- Add FPU initialization -- Static array for vectored-like handling of exceptions -- New GitHub workflow for checking invalid labels in PRs -- New GitHub workflow for checking modifications on CHANGELOG.md -- New GitHub workflow for checking clippy lints in PRs -- Optional cargo feature `single-hart` for single CPU targets - -### Changed - -- Removed U-mode interrupts to align with latest RISC-V specification -- Changed `Vector` union. Now, it uses `Option`, which is more idiomatic in Rust -- Removed riscv-target dependency for build -- Upgrade rust-version to 1.60 -- Cargo workspace for riscv and riscv-rt -- Use inline assembly instead of pre-compiled blobs -- Removed bors in favor of GitHub Merge Queue -- `start_trap_rust` is now marked as `unsafe` -- Implement `r0` as inline assembly -- Use `${ARCH_WIDTH}` in `link.x.in` to adapt to different archs -- mhartid CSR is no longer read in single-hart mode, assumed zero -- Ensure stack pointer is 16-byte aligned before jumping to Rust entry point - -## [v0.11.0] - 2023-01-18 - -### Changed - -- Update `riscv` to version 0.10.1 fixing a critical section bug - -## [v0.10.0] - 2022-11-04 - -### Added - -- Optional cargo feature `s-mode` for supervisor mode, including conditional compilation for supervisor/machine mode instructions. - -### Changed - -- Remove superfluous parentheses from link.x, which caused linker errors with nightly. -- Changed `mp_hook` signature, hartid as passed as usize parameter by the caller (required for `s-mode` feature). -- Update `riscv` to version 0.9 - -## [v0.9.0] - 2022-07-01 - -### Added - -- Pass `a0..a2` register values to the `#[entry]` function. - -### Changed - -- Update `riscv` to version 0.8 -- Update `riscv-rt-macros` to 0.2.0 -- Update Minimum Supported Rust Version to 1.59 -- The main symbol is no longer randomly generated in the `#[entry]` macro, instead it uses `__risc_v_rt__main`. - -### Removed - -- Remove `inline-asm` feature which is now always enabled - -## [v0.8.1] - 2022-01-25 - -### Added - -- Enable float support for targets with extension sets F and D -- Add ability to override trap handling mechanism - -### Changed - -- Update `riscv` to version 0.7 -- Update `quote` to version 1.0 -- Update `proc-macro2` to version 1.0 -- Update `rand` to version to version 0.7.3 - -## [v0.8.0] - 2020-07-18 - -### Changed - -- Update `riscv` to version 0.6 -- Update Minimum Supported Rust Version to 1.42.0 - -## [v0.7.2] - 2020-07-16 - -### Changed - -- Preserve `.eh_frame` and `.eh_frame_hdr` sections -- Place `.srodata` and `.srodata.*` sections in `.rodata` - -## [v0.7.1] - 2020-06-02 - -### Added - -- Add support to initialize custom interrupt controllers. - -### Changed - -- Exception handler may return now - -## [v0.7.0] - 2020-03-10 - -### Added - -- Assure address of PC at startup -- Implement interrupt and exception handling -- Add support for the `riscv32i-unknown-none-elf` target -- Added Changelog - -### Fixed - -- Fix linker script compatibility with GNU linker - -### Changed - -- Move `abort` out of the `.init` section -- Update `r0` to v1.0.0 -- Set MSRV to 1.38 - - -[Unreleased]: https://github.com/rust-embedded/riscv-rt/compare/v0.11.0..HEAD -[v0.10.1]: https://github.com/rust-embedded/riscv-rt/compare/v0.10.0...v0.11.0 -[v0.10.0]: https://github.com/rust-embedded/riscv-rt/compare/v0.9.1...v0.10.0 -[v0.9.0]: https://github.com/rust-embedded/riscv-rt/compare/v0.8.1...v0.9.0 -[v0.8.1]: https://github.com/rust-embedded/riscv-rt/compare/v0.8.0...v0.8.1 -[v0.8.0]: https://github.com/rust-embedded/riscv-rt/compare/v0.7.2...v0.8.0 -[v0.7.2]: https://github.com/rust-embedded/riscv-rt/compare/v0.7.1...v0.7.2 -[v0.7.1]: https://github.com/rust-embedded/riscv-rt/compare/v0.7.0...v0.7.1 -[v0.7.0]: https://github.com/rust-embedded/riscv-rt/compare/v0.6.1...v0.7.0 diff --git a/third-party/vendor/riscv-rt/Cargo.lock b/third-party/vendor/riscv-rt/Cargo.lock deleted file mode 100644 index fdbcd773..00000000 --- a/third-party/vendor/riscv-rt/Cargo.lock +++ /dev/null @@ -1,86 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -version = 3 - -[[package]] -name = "critical-section" -version = "1.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7059fff8937831a9ae6f0fe4d658ffabf58f2ca96aa9dec1c889f936f705f216" - -[[package]] -name = "embedded-hal" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "361a90feb7004eca4019fb28352a9465666b24f840f5c3cddf0ff13920590b89" - -[[package]] -name = "panic-halt" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "de96540e0ebde571dc55c73d60ef407c653844e6f9a1e2fdbd40c07b9252d812" - -[[package]] -name = "proc-macro2" -version = "1.0.74" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2de98502f212cfcea8d0bb305bd0f49d7ebdd75b64ba0a68f937d888f4e0d6db" -dependencies = [ - "unicode-ident", -] - -[[package]] -name = "quote" -version = "1.0.35" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" -dependencies = [ - "proc-macro2", -] - -[[package]] -name = "riscv" -version = "0.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f5c1b8bf41ea746266cdee443d1d1e9125c86ce1447e1a2615abd34330d33a9" -dependencies = [ - "critical-section", - "embedded-hal", -] - -[[package]] -name = "riscv-rt" -version = "0.12.2" -dependencies = [ - "panic-halt", - "riscv", - "riscv-rt-macros", -] - -[[package]] -name = "riscv-rt-macros" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8d100d466dbb76681ef6a9386f3da9abc570d57394e86da0ba5af8c4408486d" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "syn" -version = "1.0.109" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "unicode-ident" -version = "1.0.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" diff --git a/third-party/vendor/riscv-rt/Cargo.toml b/third-party/vendor/riscv-rt/Cargo.toml deleted file mode 100644 index 420b0496..00000000 --- a/third-party/vendor/riscv-rt/Cargo.toml +++ /dev/null @@ -1,45 +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 are reading this file be aware that the original Cargo.toml -# will likely look very different (and much more reasonable). -# See Cargo.toml.orig for the original contents. - -[package] -edition = "2021" -rust-version = "1.60" -name = "riscv-rt" -version = "0.12.2" -authors = ["The RISC-V Team "] -links = "riscv-rt" -description = "Minimal runtime / startup for RISC-V CPU's" -documentation = "https://docs.rs/riscv-rt" -readme = "README.md" -keywords = [ - "riscv", - "runtime", - "startup", -] -categories = [ - "embedded", - "no-std", -] -license = "ISC" -repository = "https://github.com/rust-embedded/riscv" - -[dependencies.riscv] -version = "0.11.1" - -[dependencies.riscv-rt-macros] -version = "0.2.1" - -[dev-dependencies.panic-halt] -version = "0.2.0" - -[features] -s-mode = [] -single-hart = [] diff --git a/third-party/vendor/riscv-rt/README.md b/third-party/vendor/riscv-rt/README.md deleted file mode 100644 index 74cdfeea..00000000 --- a/third-party/vendor/riscv-rt/README.md +++ /dev/null @@ -1,40 +0,0 @@ -[![crates.io](https://img.shields.io/crates/d/riscv-rt.svg)](https://crates.io/crates/riscv-rt) -[![crates.io](https://img.shields.io/crates/v/riscv-rt.svg)](https://crates.io/crates/riscv-rt) - -# `riscv-rt` - -> Minimal runtime / startup for RISC-V CPU's. - -This project is developed and maintained by the [RISC-V team][team]. - -## [Documentation](https://docs.rs/crate/riscv-rt) - -## Minimum Supported Rust Version (MSRV) - -This crate is guaranteed to compile on stable Rust 1.60 and up. It *might* -compile with older versions but that may change in any new patch release. - -## License - -Copyright 2018-2022 [RISC-V team][team] - -Permission to use, copy, modify, and/or distribute this software for any purpose -with or without fee is hereby granted, provided that the above copyright notice -and this permission notice appear in all copies. - -THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH -REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND -FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, -INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS -OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER -TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF -THIS SOFTWARE. - -## Code of Conduct - -Contribution to this crate is organized under the terms of the [Rust Code of -Conduct][CoC], the maintainer of this crate, the [RISC-V team][team], promises -to intervene to uphold that code of conduct. - -[CoC]: CODE_OF_CONDUCT.md -[team]: https://github.com/rust-embedded/wg#the-risc-v-team diff --git a/third-party/vendor/riscv-rt/build.rs b/third-party/vendor/riscv-rt/build.rs deleted file mode 100644 index fa405808..00000000 --- a/third-party/vendor/riscv-rt/build.rs +++ /dev/null @@ -1,106 +0,0 @@ -// NOTE: Adapted from cortex-m/build.rs - -use std::{collections::HashSet, env, fs, io, path::PathBuf}; - -fn add_linker_script(arch_width: u32) -> io::Result<()> { - // Read the file to a string and replace all occurrences of ${ARCH_WIDTH} with the arch width - let mut content = fs::read_to_string("link.x.in")?; - content = content.replace("${ARCH_WIDTH}", &arch_width.to_string()); - - let out_dir = PathBuf::from(env::var("OUT_DIR").unwrap()); - - // Put the linker script somewhere the linker can find it - fs::write(out_dir.join("link.x"), content)?; - println!("cargo:rustc-link-search={}", out_dir.display()); - println!("cargo:rerun-if-changed=link.x"); - - Ok(()) -} - -/// Parse the target RISC-V architecture and returns its bit width and the extension set -fn parse_target(target: &str, cargo_flags: &str) -> (u32, HashSet) { - // isolate bit width and extensions from the rest of the target information - let arch = target - .trim_start_matches("riscv") - .split('-') - .next() - .unwrap(); - - let bits = arch - .chars() - .take_while(|c| c.is_ascii_digit()) - .collect::() - .parse::() - .unwrap(); - - let mut extensions: HashSet = arch.chars().skip_while(|c| c.is_ascii_digit()).collect(); - // expand the 'g' shorthand extension - if extensions.contains(&'g') { - extensions.insert('i'); - extensions.insert('m'); - extensions.insert('a'); - extensions.insert('f'); - extensions.insert('d'); - } - - let cargo_flags = cargo_flags - .split(0x1fu8 as char) - .filter(|arg| !arg.is_empty()); - - cargo_flags - .filter(|k| k.starts_with("target-feature=")) - .flat_map(|str| { - let flags = str.split('=').collect::>()[1]; - flags.split(',') - }) - .for_each(|feature| { - let chars = feature.chars().collect::>(); - match chars[0] { - '+' => { - extensions.insert(chars[1]); - } - '-' => { - extensions.remove(&chars[1]); - } - _ => { - panic!("Unsupported target feature operation"); - } - } - }); - - (bits, extensions) -} - -fn main() { - let target = env::var("TARGET").unwrap(); - let cargo_flags = env::var("CARGO_ENCODED_RUSTFLAGS").unwrap(); - let _name = env::var("CARGO_PKG_NAME").unwrap(); - - // set configuration flags depending on the target - if target.starts_with("riscv") { - println!("cargo:rustc-cfg=riscv"); - - // This is required until target_arch & target_feature risc-v work is - // stable and in-use (rust 1.75.0) - let (bits, extensions) = parse_target(&target, &cargo_flags); - - // generate the linker script and expose the ISA width - let arch_width = match bits { - 32 => { - println!("cargo:rustc-cfg=riscv32"); - 4 - } - 64 => { - println!("cargo:rustc-cfg=riscv64"); - 8 - } - _ => panic!("Unsupported bit width"), - }; - add_linker_script(arch_width).unwrap(); - - // expose the ISA extensions - for ext in &extensions { - println!("cargo:rustc-cfg=riscv{}", ext); - } - } -} diff --git a/third-party/vendor/riscv-rt/examples/device.x b/third-party/vendor/riscv-rt/examples/device.x deleted file mode 100644 index 78e7bac8..00000000 --- a/third-party/vendor/riscv-rt/examples/device.x +++ /dev/null @@ -1,14 +0,0 @@ -MEMORY -{ - RAM : ORIGIN = 0x80000000, LENGTH = 16K - FLASH : ORIGIN = 0x20000000, LENGTH = 4M -} - -REGION_ALIAS("REGION_TEXT", FLASH); -REGION_ALIAS("REGION_RODATA", FLASH); -REGION_ALIAS("REGION_DATA", RAM); -REGION_ALIAS("REGION_BSS", RAM); -REGION_ALIAS("REGION_HEAP", RAM); -REGION_ALIAS("REGION_STACK", RAM); - -INCLUDE link.x diff --git a/third-party/vendor/riscv-rt/examples/empty.rs b/third-party/vendor/riscv-rt/examples/empty.rs deleted file mode 100644 index 5e4d2384..00000000 --- a/third-party/vendor/riscv-rt/examples/empty.rs +++ /dev/null @@ -1,13 +0,0 @@ -#![no_std] -#![no_main] - -extern crate panic_halt; -extern crate riscv_rt; - -use riscv_rt::entry; - -#[entry] -fn main() -> ! { - // do something here - loop {} -} diff --git a/third-party/vendor/riscv-rt/examples/multi_core.rs b/third-party/vendor/riscv-rt/examples/multi_core.rs deleted file mode 100644 index a3cbab79..00000000 --- a/third-party/vendor/riscv-rt/examples/multi_core.rs +++ /dev/null @@ -1,54 +0,0 @@ -#![no_std] -#![no_main] - -extern crate panic_halt; -extern crate riscv; -extern crate riscv_rt; - -use riscv::asm::wfi; -use riscv::register::{mie, mip}; -use riscv_rt::entry; - -#[export_name = "_mp_hook"] -#[rustfmt::skip] -pub extern "Rust" fn user_mp_hook(hartid: usize) -> bool { - if hartid == 0 { - true - } else { - let addr = 0x02000000 + hartid * 4; - unsafe { - // Clear IPI - (addr as *mut u32).write_volatile(0); - - // Start listening for software interrupts - mie::set_msoft(); - - loop { - wfi(); - if mip::read().msoft() { - break; - } - } - - // Stop listening for software interrupts - mie::clear_msoft(); - - // Clear IPI - (addr as *mut u32).write_volatile(0); - } - false - } -} - -#[entry] -fn main(hartid: usize) -> ! { - if hartid == 0 { - // Waking hart 1... - let addr = 0x02000004; - unsafe { - (addr as *mut u32).write_volatile(1); - } - } - - loop {} -} diff --git a/third-party/vendor/riscv-rt/link.x.in b/third-party/vendor/riscv-rt/link.x.in deleted file mode 100644 index 4ae8c81f..00000000 --- a/third-party/vendor/riscv-rt/link.x.in +++ /dev/null @@ -1,210 +0,0 @@ -/* # Developer notes - -- Symbols that start with a double underscore (__) are considered "private" - -- Symbols that start with a single underscore (_) are considered "semi-public"; they can be - overridden in a user linker script, but should not be referred from user code (e.g. `extern "C" { - static mut _heap_size }`). - -- `EXTERN` forces the linker to keep a symbol in the final binary. We use this to make sure a - symbol if not dropped if it appears in or near the front of the linker arguments and "it's not - needed" by any of the preceding objects (linker arguments) - -- `PROVIDE` is used to provide default values that can be overridden by a user linker script - -- In this linker script, you may find symbols that look like `${...}` (e.g., `${ARCH_WIDTH}`). - These are wildcards used by the `build.rs` script to adapt to different target particularities. - Check `build.rs` for more details about these symbols. - -- On alignment: it's important for correctness that the VMA boundaries of both .bss and .data *and* - the LMA of .data are all `${ARCH_WIDTH}`-byte aligned. These alignments are assumed by the RAM - initialization routine. There's also a second benefit: `${ARCH_WIDTH}`-byte aligned boundaries - means that you won't see "Address (..) is out of bounds" in the disassembly produced by `objdump`. -*/ - -PROVIDE(_stext = ORIGIN(REGION_TEXT)); -PROVIDE(_stack_start = ORIGIN(REGION_STACK) + LENGTH(REGION_STACK)); -PROVIDE(_max_hart_id = 0); -PROVIDE(_hart_stack_size = 2K); -PROVIDE(_heap_size = 0); - -PROVIDE(InstructionMisaligned = ExceptionHandler); -PROVIDE(InstructionFault = ExceptionHandler); -PROVIDE(IllegalInstruction = ExceptionHandler); -PROVIDE(Breakpoint = ExceptionHandler); -PROVIDE(LoadMisaligned = ExceptionHandler); -PROVIDE(LoadFault = ExceptionHandler); -PROVIDE(StoreMisaligned = ExceptionHandler); -PROVIDE(StoreFault = ExceptionHandler);; -PROVIDE(UserEnvCall = ExceptionHandler); -PROVIDE(SupervisorEnvCall = ExceptionHandler); -PROVIDE(MachineEnvCall = ExceptionHandler); -PROVIDE(InstructionPageFault = ExceptionHandler); -PROVIDE(LoadPageFault = ExceptionHandler); -PROVIDE(StorePageFault = ExceptionHandler); - -PROVIDE(SupervisorSoft = DefaultHandler); -PROVIDE(MachineSoft = DefaultHandler); -PROVIDE(SupervisorTimer = DefaultHandler); -PROVIDE(MachineTimer = DefaultHandler); -PROVIDE(SupervisorExternal = DefaultHandler); -PROVIDE(MachineExternal = DefaultHandler); - -PROVIDE(DefaultHandler = DefaultInterruptHandler); -PROVIDE(ExceptionHandler = DefaultExceptionHandler); - -/* # Pre-initialization function */ -/* If the user overrides this using the `#[pre_init]` attribute or by creating a `__pre_init` function, - then the function this points to will be called before the RAM is initialized. */ -PROVIDE(__pre_init = default_pre_init); - -/* A PAC/HAL defined routine that should initialize custom interrupt controller if needed. */ -PROVIDE(_setup_interrupts = default_setup_interrupts); - -/* # Multi-processing hook function - fn _mp_hook() -> bool; - - This function is called from all the harts and must return true only for one hart, - which will perform memory initialization. For other harts it must return false - and implement wake-up in platform-dependent way (e.g. after waiting for a user interrupt). -*/ -PROVIDE(_mp_hook = default_mp_hook); - -/* # Start trap function override - By default uses the riscv crates default trap handler - but by providing the `_start_trap` symbol external crates can override. -*/ -PROVIDE(_start_trap = default_start_trap); - -SECTIONS -{ - .text.dummy (NOLOAD) : - { - /* This section is intended to make _stext address work */ - . = ABSOLUTE(_stext); - } > REGION_TEXT - - .text _stext : - { - /* Put reset handler first in .text section so it ends up as the entry */ - /* point of the program. */ - KEEP(*(.init)); - KEEP(*(.init.rust)); - . = ALIGN(4); - *(.trap); - *(.trap.rust); - *(.text.abort); - *(.text .text.*); - } > REGION_TEXT - - .rodata : ALIGN(4) - { - *(.srodata .srodata.*); - *(.rodata .rodata.*); - - /* 4-byte align the end (VMA) of this section. - This is required by LLD to ensure the LMA of the following .data - section will have the correct alignment. */ - . = ALIGN(4); - } > REGION_RODATA - - .data : ALIGN(${ARCH_WIDTH}) - { - _sidata = LOADADDR(.data); - _sdata = .; - /* Must be called __global_pointer$ for linker relaxations to work. */ - PROVIDE(__global_pointer$ = . + 0x800); - *(.sdata .sdata.* .sdata2 .sdata2.*); - *(.data .data.*); - . = ALIGN(${ARCH_WIDTH}); - _edata = .; - } > REGION_DATA AT > REGION_RODATA - - .bss (NOLOAD) : ALIGN(${ARCH_WIDTH}) - { - _sbss = .; - *(.sbss .sbss.* .bss .bss.*); - . = ALIGN(${ARCH_WIDTH}); - _ebss = .; - } > REGION_BSS - - /* fictitious region that represents the memory available for the heap */ - .heap (NOLOAD) : - { - _sheap = .; - . += _heap_size; - . = ALIGN(4); - _eheap = .; - } > REGION_HEAP - - /* fictitious region that represents the memory available for the stack */ - .stack (NOLOAD) : - { - _estack = .; - . = ABSOLUTE(_stack_start); - _sstack = .; - } > REGION_STACK - - /* fake output .got section */ - /* Dynamic relocations are unsupported. This section is only used to detect - relocatable code in the input files and raise an error if relocatable code - is found */ - .got (INFO) : - { - KEEP(*(.got .got.*)); - } - - .eh_frame (INFO) : { KEEP(*(.eh_frame)) } - .eh_frame_hdr (INFO) : { *(.eh_frame_hdr) } -} - -/* Do not exceed this mark in the error messages above | */ -ASSERT(ORIGIN(REGION_TEXT) % 4 == 0, " -ERROR(riscv-rt): the start of the REGION_TEXT must be 4-byte aligned"); - -ASSERT(ORIGIN(REGION_RODATA) % 4 == 0, " -ERROR(riscv-rt): the start of the REGION_RODATA must be 4-byte aligned"); - -ASSERT(ORIGIN(REGION_DATA) % ${ARCH_WIDTH} == 0, " -ERROR(riscv-rt): the start of the REGION_DATA must be ${ARCH_WIDTH}-byte aligned"); - -ASSERT(ORIGIN(REGION_HEAP) % 4 == 0, " -ERROR(riscv-rt): the start of the REGION_HEAP must be 4-byte aligned"); - -ASSERT(ORIGIN(REGION_TEXT) % 4 == 0, " -ERROR(riscv-rt): the start of the REGION_TEXT must be 4-byte aligned"); - -ASSERT(ORIGIN(REGION_STACK) % 4 == 0, " -ERROR(riscv-rt): the start of the REGION_STACK must be 4-byte aligned"); - -ASSERT(_stext % 4 == 0, " -ERROR(riscv-rt): `_stext` must be 4-byte aligned"); - -ASSERT(_sdata % ${ARCH_WIDTH} == 0 && _edata % ${ARCH_WIDTH} == 0, " -BUG(riscv-rt): .data is not ${ARCH_WIDTH}-byte aligned"); - -ASSERT(_sidata % ${ARCH_WIDTH} == 0, " -BUG(riscv-rt): the LMA of .data is not ${ARCH_WIDTH}-byte aligned"); - -ASSERT(_sbss % ${ARCH_WIDTH} == 0 && _ebss % ${ARCH_WIDTH} == 0, " -BUG(riscv-rt): .bss is not ${ARCH_WIDTH}-byte aligned"); - -ASSERT(_sheap % 4 == 0, " -BUG(riscv-rt): start of .heap is not 4-byte aligned"); - -ASSERT(_stext + SIZEOF(.text) < ORIGIN(REGION_TEXT) + LENGTH(REGION_TEXT), " -ERROR(riscv-rt): The .text section must be placed inside the REGION_TEXT region. -Set _stext to an address smaller than 'ORIGIN(REGION_TEXT) + LENGTH(REGION_TEXT)'"); - -ASSERT(SIZEOF(.stack) > (_max_hart_id + 1) * _hart_stack_size, " -ERROR(riscv-rt): .stack section is too small for allocating stacks for all the harts. -Consider changing `_max_hart_id` or `_hart_stack_size`."); - -ASSERT(SIZEOF(.got) == 0, " -.got section detected in the input files. Dynamic relocations are not -supported. If you are linking to C code compiled using the `gcc` crate -then modify your build script to compile the C code _without_ the --fPIC flag. See the documentation of the `gcc::Config.fpic` method for -details."); - -/* Do not exceed this mark in the error messages above | */ diff --git a/third-party/vendor/riscv-rt/src/asm.rs b/third-party/vendor/riscv-rt/src/asm.rs deleted file mode 100644 index ea4b5233..00000000 --- a/third-party/vendor/riscv-rt/src/asm.rs +++ /dev/null @@ -1,209 +0,0 @@ -use core::arch::global_asm; - -/// Parse cfg attributes inside a global_asm call. -macro_rules! cfg_global_asm { - {@inner, [$($x:tt)*], } => { - global_asm!{$($x)*} - }; - (@inner, [$($x:tt)*], #[cfg($meta:meta)] $asm:literal, $($rest:tt)*) => { - #[cfg($meta)] - cfg_global_asm!{@inner, [$($x)* $asm,], $($rest)*} - #[cfg(not($meta))] - cfg_global_asm!{@inner, [$($x)*], $($rest)*} - }; - {@inner, [$($x:tt)*], $asm:literal, $($rest:tt)*} => { - cfg_global_asm!{@inner, [$($x)* $asm,], $($rest)*} - }; - {$($asms:tt)*} => { - cfg_global_asm!{@inner, [], $($asms)*} - }; -} - -// Provisional patch to avoid LLVM spurious errors when compiling in release mode. -// This patch is somewhat hardcoded and relies on the fact that the rustc compiler -// only supports a limited combination of ISA extensions. This patch should be -// removed when LLVM fixes the issue. Alternatively, it must be updated when rustc -// supports more ISA extension combinations. -// -// Related issues: -// - https://github.com/rust-embedded/riscv/issues/175 -// - https://github.com/rust-lang/rust/issues/80608 -// - https://github.com/llvm/llvm-project/issues/61991 -cfg_global_asm!( - "// Provisional patch to avoid LLVM spurious errors when compiling in release mode.", - #[cfg(all(riscv32, riscvm))] - ".attribute arch, \"rv32im\"", - #[cfg(all(riscv64, riscvm, not(riscvg)))] - ".attribute arch, \"rv64im\"", - #[cfg(all(riscv64, riscvg))] - ".attribute arch, \"rv64g\"", -); - -// Entry point of all programs (_start). It initializes DWARF call frame information, -// the stack pointer, the frame pointer (needed for closures to work in start_rust) -// and the global pointer. Then it calls _start_rust. -cfg_global_asm!( - ".section .init, \"ax\" - .global _start - -_start:", - #[cfg(riscv32)] - "lui ra, %hi(_abs_start) - jr %lo(_abs_start)(ra)", - #[cfg(riscv64)] - ".option push - .option norelax // to prevent an unsupported R_RISCV_ALIGN relocation from being generated -1: - auipc ra, %pcrel_hi(1f) - ld ra, %pcrel_lo(1b)(ra) - jr ra - .align 3 -1: - .dword _abs_start - .option pop", - " -_abs_start: - .option norelax - .cfi_startproc - .cfi_undefined ra", - #[cfg(feature = "s-mode")] - "csrw sie, 0 - csrw sip, 0", - #[cfg(not(feature = "s-mode"))] - "csrw mie, 0 - csrw mip, 0", - "li x1, 0 - li x2, 0 - li x3, 0 - li x4, 0 - li x5, 0 - li x6, 0 - li x7, 0 - li x8, 0 - li x9, 0 - // a0..a2 (x10..x12) skipped - li x13, 0 - li x14, 0 - li x15, 0 - li x16, 0 - li x17, 0 - li x18, 0 - li x19, 0 - li x20, 0 - li x21, 0 - li x22, 0 - li x23, 0 - li x24, 0 - li x25, 0 - li x26, 0 - li x27, 0 - li x28, 0 - li x29, 0 - li x30, 0 - li x31, 0 - - .option push - .option norelax - la gp, __global_pointer$ - .option pop - // Allocate stacks", - #[cfg(all(not(feature = "single-hart"), feature = "s-mode"))] - "mv t2, a0 // the hartid is passed as parameter by SMODE", - #[cfg(all(not(feature = "single-hart"), not(feature = "s-mode")))] - "csrr t2, mhartid", - #[cfg(not(feature = "single-hart"))] - "lui t0, %hi(_max_hart_id) - add t0, t0, %lo(_max_hart_id) - bgtu t2, t0, abort - lui t0, %hi(_hart_stack_size) - add t0, t0, %lo(_hart_stack_size)", - #[cfg(all(not(feature = "single-hart"), riscvm))] - "mul t0, t2, t0", - #[cfg(all(not(feature = "single-hart"), not(riscvm)))] - "beqz t2, 2f // Jump if single-hart - mv t1, t2 - mv t3, t0 -1: - add t0, t0, t3 - addi t1, t1, -1 - bnez t1, 1b -2: ", - "la t1, _stack_start", - #[cfg(not(feature = "single-hart"))] - "sub t1, t1, t0", - "andi sp, t1, -16 // Force 16-byte alignment - // Set frame pointer - add s0, sp, zero - - jal zero, _start_rust - - .cfi_endproc", -); - -/// Trap entry point (_start_trap). It saves caller saved registers, calls -/// _start_trap_rust, restores caller saved registers and then returns. -/// -/// # Usage -/// -/// The macro takes 5 arguments: -/// - `$STORE`: the instruction used to store a register in the stack (e.g. `sd` for riscv64) -/// - `$LOAD`: the instruction used to load a register from the stack (e.g. `ld` for riscv64) -/// - `$BYTES`: the number of bytes used to store a register (e.g. 8 for riscv64) -/// - `$TRAP_SIZE`: the number of registers to store in the stack (e.g. 32 for all the user registers) -/// - list of tuples of the form `($REG, $LOCATION)`, where: -/// - `$REG`: the register to store/load -/// - `$LOCATION`: the location in the stack where to store/load the register -#[rustfmt::skip] -macro_rules! trap_handler { - ($STORE:ident, $LOAD:ident, $BYTES:literal, $TRAP_SIZE:literal, [$(($REG:ident, $LOCATION:literal)),*]) => { - // ensure we do not break that sp is 16-byte aligned - const _: () = assert!(($TRAP_SIZE * $BYTES) % 16 == 0); - global_asm!( - " - .section .trap, \"ax\" - .global default_start_trap - default_start_trap:", - // save space for trap handler in stack - concat!("addi sp, sp, -", stringify!($TRAP_SIZE * $BYTES)), - // save registers in the desired order - $(concat!(stringify!($STORE), " ", stringify!($REG), ", ", stringify!($LOCATION * $BYTES), "(sp)"),)* - // call rust trap handler - "add a0, sp, zero - jal ra, _start_trap_rust", - // restore registers in the desired order - $(concat!(stringify!($LOAD), " ", stringify!($REG), ", ", stringify!($LOCATION * $BYTES), "(sp)"),)* - // free stack - concat!("addi sp, sp, ", stringify!($TRAP_SIZE * $BYTES)), - ); - cfg_global_asm!( - // return from trap - #[cfg(feature = "s-mode")] - "sret", - #[cfg(not(feature = "s-mode"))] - "mret", - ); - }; -} - -#[rustfmt::skip] -#[cfg(riscv32)] -trap_handler!( - sw, lw, 4, 16, - [(ra, 0), (t0, 1), (t1, 2), (t2, 3), (t3, 4), (t4, 5), (t5, 6), (t6, 7), - (a0, 8), (a1, 9), (a2, 10), (a3, 11), (a4, 12), (a5, 13), (a6, 14), (a7, 15)] -); -#[rustfmt::skip] -#[cfg(riscv64)] -trap_handler!( - sd, ld, 8, 16, - [(ra, 0), (t0, 1), (t1, 2), (t2, 3), (t3, 4), (t4, 5), (t5, 6), (t6, 7), - (a0, 8), (a1, 9), (a2, 10), (a3, 11), (a4, 12), (a5, 13), (a6, 14), (a7, 15)] -); - -// Make sure there is an abort when linking -global_asm!( - ".section .text.abort - .globl abort -abort: - j abort" -); diff --git a/third-party/vendor/riscv-rt/src/lib.rs b/third-party/vendor/riscv-rt/src/lib.rs deleted file mode 100644 index 164b39bc..00000000 --- a/third-party/vendor/riscv-rt/src/lib.rs +++ /dev/null @@ -1,774 +0,0 @@ -//! Minimal startup / runtime for RISC-V CPU's -//! -//! # Minimum Supported Rust Version (MSRV) -//! -//! This crate is guaranteed to compile on stable Rust 1.60 and up. It *might* -//! compile with older versions but that may change in any new patch release. -//! -//! # Features -//! -//! This crate provides -//! -//! - Before main initialization of the `.bss` and `.data` sections. -//! -//! - `#[entry]` to declare the entry point of the program -//! - `#[pre_init]` to run code *before* `static` variables are initialized -//! -//! - A linker script that encodes the memory layout of a generic RISC-V -//! microcontroller. This linker script is missing some information that must -//! be supplied through a `memory.x` file (see example below). This file -//! must be supplied using rustflags and listed *before* `link.x`. Arbitrary -//! filename can be use instead of `memory.x`. -//! -//! - A `_sheap` symbol at whose address you can locate a heap. -//! -//! - Support for a runtime in supervisor mode, that can be bootstrapped via [Supervisor Binary Interface (SBI)](https://github.com/riscv-non-isa/riscv-sbi-doc) -//! -//! ``` text -//! $ cargo new --bin app && cd $_ -//! -//! $ # add this crate as a dependency -//! $ edit Cargo.toml && cat $_ -//! [dependencies] -//! riscv-rt = "0.6.1" -//! panic-halt = "0.2.0" -//! -//! $ # memory layout of the device -//! $ edit memory.x && cat $_ -//! MEMORY -//! { -//! RAM : ORIGIN = 0x80000000, LENGTH = 16K -//! FLASH : ORIGIN = 0x20000000, LENGTH = 16M -//! } -//! -//! REGION_ALIAS("REGION_TEXT", FLASH); -//! REGION_ALIAS("REGION_RODATA", FLASH); -//! REGION_ALIAS("REGION_DATA", RAM); -//! REGION_ALIAS("REGION_BSS", RAM); -//! REGION_ALIAS("REGION_HEAP", RAM); -//! REGION_ALIAS("REGION_STACK", RAM); -//! -//! $ edit src/main.rs && cat $_ -//! ``` -//! -//! ``` ignore,no_run -//! #![no_std] -//! #![no_main] -//! -//! extern crate panic_halt; -//! -//! use riscv_rt::entry; -//! -//! // use `main` as the entry point of this application -//! // `main` is not allowed to return -//! #[entry] -//! fn main() -> ! { -//! // do something here -//! loop { } -//! } -//! ``` -//! -//! ``` text -//! $ mkdir .cargo && edit .cargo/config && cat $_ -//! [target.riscv32imac-unknown-none-elf] -//! rustflags = [ -//! "-C", "link-arg=-Tmemory.x", -//! "-C", "link-arg=-Tlink.x", -//! ] -//! -//! [build] -//! target = "riscv32imac-unknown-none-elf" -//! $ edit build.rs && cat $_ -//! ``` -//! -//! ``` ignore,no_run -//! use std::env; -//! use std::fs; -//! use std::path::PathBuf; -//! -//! fn main() { -//! let out_dir = PathBuf::from(env::var("OUT_DIR").unwrap()); -//! -//! // Put the linker script somewhere the linker can find it. -//! fs::write(out_dir.join("memory.x"), include_bytes!("memory.x")).unwrap(); -//! println!("cargo:rustc-link-search={}", out_dir.display()); -//! println!("cargo:rerun-if-changed=memory.x"); -//! -//! println!("cargo:rerun-if-changed=build.rs"); -//! } -//! ``` -//! -//! ``` text -//! $ cargo build -//! -//! $ riscv32-unknown-elf-objdump -Cd $(find target -name app) | head -//! -//! Disassembly of section .text: -//! -//! 20000000 <_start>: -//! 20000000: 800011b7 lui gp,0x80001 -//! 20000004: 80018193 addi gp,gp,-2048 # 80000800 <_stack_start+0xffffc800> -//! 20000008: 80004137 lui sp,0x80004 -//! ``` -//! -//! # Symbol interfaces -//! -//! This crate makes heavy use of symbols, linker sections and linker scripts to -//! provide most of its functionality. Below are described the main symbol -//! interfaces. -//! -//! ## `memory.x` -//! -//! This file supplies the information about the device to the linker. -//! -//! ### `MEMORY` -//! -//! The main information that this file must provide is the memory layout of -//! the device in the form of the `MEMORY` command. The command is documented -//! [here][2], but at a minimum you'll want to create at least one memory region. -//! -//! [2]: https://sourceware.org/binutils/docs/ld/MEMORY.html -//! -//! To support different relocation models (RAM-only, FLASH+RAM) multiple regions are used: -//! -//! - `REGION_TEXT` - for `.init`, `.trap` and `.text` sections -//! - `REGION_RODATA` - for `.rodata` section and storing initial values for `.data` section -//! - `REGION_DATA` - for `.data` section -//! - `REGION_BSS` - for `.bss` section -//! - `REGION_HEAP` - for the heap area -//! - `REGION_STACK` - for hart stacks -//! -//! Specific aliases for these regions must be defined in `memory.x` file (see example below). -//! -//! ### `_stext` -//! -//! This symbol provides the loading address of `.text` section. This value can be changed -//! to override the loading address of the firmware (for example, in case of bootloader present). -//! -//! If omitted this symbol value will default to `ORIGIN(REGION_TEXT)`. -//! -//! ### `_stack_start` -//! -//! This symbol provides the address at which the call stack will be allocated. -//! The call stack grows downwards so this address is usually set to the highest -//! valid RAM address plus one (this *is* an invalid address but the processor -//! will decrement the stack pointer *before* using its value as an address). -//! -//! In case of multiple harts present, this address defines the initial stack pointer for hart 0. -//! Stack pointer for hart `N` is calculated as `_stack_start - N * _hart_stack_size`. -//! -//! If omitted this symbol value will default to `ORIGIN(REGION_STACK) + LENGTH(REGION_STACK)`. -//! -//! #### Example -//! -//! Allocating the call stack on a different RAM region. -//! -//! ``` text -//! MEMORY -//! { -//! L2_LIM : ORIGIN = 0x08000000, LENGTH = 1M -//! RAM : ORIGIN = 0x80000000, LENGTH = 16K -//! FLASH : ORIGIN = 0x20000000, LENGTH = 16M -//! } -//! -//! REGION_ALIAS("REGION_TEXT", FLASH); -//! REGION_ALIAS("REGION_RODATA", FLASH); -//! REGION_ALIAS("REGION_DATA", RAM); -//! REGION_ALIAS("REGION_BSS", RAM); -//! REGION_ALIAS("REGION_HEAP", RAM); -//! REGION_ALIAS("REGION_STACK", L2_LIM); -//! -//! _stack_start = ORIGIN(L2_LIM) + LENGTH(L2_LIM); -//! ``` -//! -//! ### `_max_hart_id` -//! -//! This symbol defines the maximum hart id supported. All harts with id -//! greater than `_max_hart_id` will be redirected to `abort()`. -//! -//! This symbol is supposed to be redefined in platform support crates for -//! multi-core targets. -//! -//! If omitted this symbol value will default to 0 (single core). -//! -//! ### `_hart_stack_size` -//! -//! This symbol defines stack area size for *one* hart. -//! -//! If omitted this symbol value will default to 2K. -//! -//! ### `_heap_size` -//! -//! This symbol provides the size of a heap region. The default value is 0. You can set `_heap_size` -//! to a non-zero value if you are planning to use heap allocations. -//! -//! ### `_sheap` -//! -//! This symbol is located in RAM right after the `.bss` and `.data` sections. -//! You can use the address of this symbol as the start address of a heap -//! region. This symbol is 4 byte aligned so that address will be a multiple of 4. -//! -//! #### Example -//! -//! ``` no_run -//! extern crate some_allocator; -//! -//! extern "C" { -//! static _sheap: u8; -//! static _heap_size: u8; -//! } -//! -//! fn main() { -//! unsafe { -//! let heap_bottom = &_sheap as *const u8 as usize; -//! let heap_size = &_heap_size as *const u8 as usize; -//! some_allocator::initialize(heap_bottom, heap_size); -//! } -//! } -//! ``` -//! -//! ### `_mp_hook` -//! -//! This function is called from all the harts and must return true only for one hart, -//! which will perform memory initialization. For other harts it must return false -//! and implement wake-up in platform-dependent way (e.g. after waiting for a user interrupt). -//! The parameter `hartid` specifies the hartid of the caller. -//! -//! This function can be redefined in the following way: -//! -//! ``` no_run -//! #[export_name = "_mp_hook"] -//! pub extern "Rust" fn mp_hook(hartid: usize) -> bool { -//! // ... -//! } -//! ``` -//! -//! Default implementation of this function wakes hart 0 and busy-loops all the other harts. -//! -//! -//! ### Core exception handlers -//! -//! This functions are called when corresponding exception occurs. -//! You can define an exception handler with one of the following names: -//! * `InstructionMisaligned` -//! * `InstructionFault` -//! * `IllegalInstruction` -//! * `Breakpoint` -//! * `LoadMisaligned` -//! * `LoadFault` -//! * `StoreMisaligned` -//! * `StoreFault` -//! * `UserEnvCall` -//! * `SupervisorEnvCall` -//! * `MachineEnvCall` -//! * `InstructionPageFault` -//! * `LoadPageFault` -//! * `StorePageFault` -//! -//! For example: -//! ``` no_run -//! #[export_name = "MachineEnvCall"] -//! fn custom_menv_call_handler(trap_frame: &riscv_rt::TrapFrame) { -//! // ... -//! } -//! ``` -//! or -//! ``` no_run -//! #[no_mangle] -//! fn MachineEnvCall(trap_frame: &riscv_rt::TrapFrame) -> ! { -//! // ... -//! } -//! ``` -//! -//! If exception handler is not explicitly defined, `ExceptionHandler` is called. -//! -//! ### `ExceptionHandler` -//! -//! This function is called when exception without defined exception handler is occured. -//! The exception reason can be decoded from the -//! `mcause`/`scause` register. -//! -//! This function can be redefined in the following way: -//! -//! ``` no_run -//! #[export_name = "ExceptionHandler"] -//! fn custom_exception_handler(trap_frame: &riscv_rt::TrapFrame) -> ! { -//! // ... -//! } -//! ``` -//! or -//! ``` no_run -//! #[no_mangle] -//! fn ExceptionHandler(trap_frame: &riscv_rt::TrapFrame) -> ! { -//! // ... -//! } -//! ``` -//! -//! Default implementation of this function stucks in a busy-loop. -//! -//! -//! ### Core interrupt handlers -//! -//! This functions are called when corresponding interrupt is occured. -//! You can define an interrupt handler with one of the following names: -//! * `UserSoft` -//! * `SupervisorSoft` -//! * `MachineSoft` -//! * `UserTimer` -//! * `SupervisorTimer` -//! * `MachineTimer` -//! * `UserExternal` -//! * `SupervisorExternal` -//! * `MachineExternal` -//! -//! For example: -//! ``` no_run -//! #[export_name = "MachineTimer"] -//! fn custom_timer_handler() { -//! // ... -//! } -//! ``` -//! or -//! ``` no_run -//! #[no_mangle] -//! fn MachineTimer() { -//! // ... -//! } -//! ``` -//! -//! If interrupt handler is not explicitly defined, `DefaultHandler` is called. -//! -//! ### `DefaultHandler` -//! -//! This function is called when interrupt without defined interrupt handler is occured. -//! The interrupt reason can be decoded from the `mcause`/`scause` register. -//! -//! This function can be redefined in the following way: -//! -//! ``` no_run -//! #[export_name = "DefaultHandler"] -//! fn custom_interrupt_handler() { -//! // ... -//! } -//! ``` -//! or -//! ``` no_run -//! #[no_mangle] -//! fn DefaultHandler() { -//! // ... -//! } -//! ``` -//! -//! Default implementation of this function stucks in a busy-loop. -//! -//! # Features -//! -//! ## `single-hart` -//! -//! This feature saves a little code size if there is only one hart on the target. -//! -//! ## `s-mode` -//! -//! The supervisor mode feature (`s-mode`) can be activated via [Cargo features](https://doc.rust-lang.org/cargo/reference/features.html). -//! -//! For example: -//! ``` text -//! [dependencies] -//! riscv-rt = {features=["s-mode"]} -//! ``` -//! Internally, riscv-rt uses different versions of precompiled static libraries -//! for (i) machine mode and (ii) supervisor mode. If the `s-mode` feature was activated, -//! the build script selects the s-mode library. While most registers/instructions have variants for -//! both `mcause` and `scause`, the `mhartid` hardware thread register is not available in supervisor -//! mode. Instead, the hartid is passed as parameter by a bootstrapping firmware (i.e., SBI). -//! -//! Use case: QEMU supports [OpenSBI](https://github.com/riscv-software-src/opensbi) as default firmware. -//! Using the SBI requires riscv-rt to be run in supervisor mode instead of machine mode. -//! ``` text -//! APP_BINARY=$(find target -name app) -//! sudo qemu-system-riscv64 -m 2G -nographic -machine virt -kernel $APP_BINARY -//! ``` -//! It requires the memory layout to be non-overlapping, like -//! ``` text -//! MEMORY -//! { -//! RAM : ORIGIN = 0x80200000, LENGTH = 0x8000000 -//! FLASH : ORIGIN = 0x20000000, LENGTH = 16M -//! } -//! ``` - -// NOTE: Adapted from cortex-m/src/lib.rs -#![no_std] -#![deny(missing_docs)] - -#[cfg(riscv)] -mod asm; - -use core::sync::atomic::{compiler_fence, Ordering}; - -#[cfg(feature = "s-mode")] -use riscv::register::{scause as xcause, stvec as xtvec, stvec::TrapMode as xTrapMode}; - -#[cfg(not(feature = "s-mode"))] -use riscv::register::{mcause as xcause, mtvec as xtvec, mtvec::TrapMode as xTrapMode}; - -#[cfg(all(not(feature = "single-hart"), not(feature = "s-mode")))] -use riscv::register::mhartid; - -#[cfg(all(feature = "s-mode", any(riscvf, riscvd)))] -use riscv::register::sstatus as xstatus; - -#[cfg(all(not(feature = "s-mode"), any(riscvf, riscvd)))] -use riscv::register::mstatus as xstatus; - -pub use riscv_rt_macros::{entry, pre_init}; - -/// We export this static with an informative name so that if an application attempts to link -/// two copies of riscv-rt together, linking will fail. We also declare a links key in -/// Cargo.toml which is the more modern way to solve the same problem, but we have to keep -/// __ONCE__ around to prevent linking with versions before the links key was added. -#[export_name = "error: riscv-rt appears more than once in the dependency graph"] -#[doc(hidden)] -pub static __ONCE__: () = (); - -/// Rust entry point (_start_rust) -/// -/// Zeros bss section, initializes data section and calls main. This function never returns. -/// -/// # Safety -/// -/// This function must be called only from assembly `_start` function. -/// Do **NOT** call this function directly. -#[link_section = ".init.rust"] -#[export_name = "_start_rust"] -pub unsafe extern "C" fn start_rust(a0: usize, a1: usize, a2: usize) -> ! { - #[rustfmt::skip] - extern "Rust" { - // This symbol will be provided by the user via `#[entry]` - fn main(a0: usize, a1: usize, a2: usize) -> !; - - // This symbol will be provided by the user via `#[pre_init]` - fn __pre_init(); - - fn _setup_interrupts(); - - fn _mp_hook(hartid: usize) -> bool; - } - - #[cfg(not(feature = "single-hart"))] - let run_init = { - // sbi passes hartid as first parameter (a0) - #[cfg(feature = "s-mode")] - let hartid = a0; - #[cfg(not(feature = "s-mode"))] - let hartid = mhartid::read(); - - _mp_hook(hartid) - }; - #[cfg(feature = "single-hart")] - let run_init = true; - - if run_init { - __pre_init(); - - // Initialize RAM - // 1. Copy over .data from flash to RAM - // 2. Zero out .bss - - #[cfg(target_arch = "riscv32")] - core::arch::asm!( - " - // Copy over .data - la {start},_sdata - la {end},_edata - la {input},_sidata - - bgeu {start},{end},2f - 1: - lw {a},0({input}) - addi {input},{input},4 - sw {a},0({start}) - addi {start},{start},4 - bltu {start},{end},1b - - 2: - li {a},0 - li {input},0 - - // Zero out .bss - la {start},_sbss - la {end},_ebss - - bgeu {start},{end},3f - 2: - sw zero,0({start}) - addi {start},{start},4 - bltu {start},{end},2b - - 3: - li {start},0 - li {end},0 - ", - start = out(reg) _, - end = out(reg) _, - input = out(reg) _, - a = out(reg) _, - ); - - #[cfg(target_arch = "riscv64")] - core::arch::asm!( - " - // Copy over .data - la {start},_sdata - la {end},_edata - la {input},_sidata - - bgeu {start},{end},2f - - 1: // .data Main Loop - ld {a},0({input}) - addi {input},{input},8 - sd {a},0({start}) - addi {start},{start},8 - bltu {start},{end},1b - - 2: // .data zero registers - li {a},0 - li {input},0 - - la {start},_sbss - la {end},_ebss - - bgeu {start},{end},4f - - 3: // .bss main loop - sd zero,0({start}) - addi {start},{start},8 - bltu {start},{end},3b - - 4: // .bss zero registers - // Zero out used registers - li {start},0 - li {end},0 - ", - start = out(reg) _, - end = out(reg) _, - input = out(reg) _, - a = out(reg) _, - ); - - compiler_fence(Ordering::SeqCst); - } - - #[cfg(any(riscvf, riscvd))] - { - xstatus::set_fs(xstatus::FS::Initial); // Enable fpu in xstatus - core::arch::asm!("fscsr x0"); // Zero out fcsr register csrrw x0, fcsr, x0 - - // Zero out floating point registers - #[cfg(all(target_arch = "riscv32", riscvd))] - riscv_rt_macros::loop_asm!("fcvt.d.w f{}, x0", 32); - - #[cfg(all(target_arch = "riscv64", riscvd))] - riscv_rt_macros::loop_asm!("fmv.d.x f{}, x0", 32); - - #[cfg(not(riscvd))] - riscv_rt_macros::loop_asm!("fmv.w.x f{}, x0", 32); - } - - _setup_interrupts(); - - main(a0, a1, a2); -} - -/// Registers saved in trap handler -#[allow(missing_docs)] -#[repr(C)] -#[derive(Debug)] -pub struct TrapFrame { - pub ra: usize, - pub t0: usize, - pub t1: usize, - pub t2: usize, - pub t3: usize, - pub t4: usize, - pub t5: usize, - pub t6: usize, - pub a0: usize, - pub a1: usize, - pub a2: usize, - pub a3: usize, - pub a4: usize, - pub a5: usize, - pub a6: usize, - pub a7: usize, -} - -/// Trap entry point rust (_start_trap_rust) -/// -/// `scause`/`mcause` is read to determine the cause of the trap. XLEN-1 bit indicates -/// if it's an interrupt or an exception. The result is examined and ExceptionHandler -/// or one of the core interrupt handlers is called. -/// -/// # Safety -/// -/// This function must be called only from assembly `_start_trap` function. -/// Do **NOT** call this function directly. -#[link_section = ".trap.rust"] -#[export_name = "_start_trap_rust"] -pub unsafe extern "C" fn start_trap_rust(trap_frame: *const TrapFrame) { - extern "C" { - fn ExceptionHandler(trap_frame: &TrapFrame); - fn DefaultHandler(); - } - - let cause = xcause::read(); - let code = cause.code(); - - if cause.is_exception() { - let trap_frame = &*trap_frame; - if code < __EXCEPTIONS.len() { - let h = &__EXCEPTIONS[code]; - if let Some(handler) = h { - handler(trap_frame); - } else { - ExceptionHandler(trap_frame); - } - } else { - ExceptionHandler(trap_frame); - } - ExceptionHandler(trap_frame) - } else if code < __INTERRUPTS.len() { - let h = &__INTERRUPTS[code]; - if let Some(handler) = h { - handler(); - } else { - DefaultHandler(); - } - } else { - DefaultHandler(); - } -} - -#[doc(hidden)] -#[no_mangle] -#[allow(unused_variables, non_snake_case)] -pub fn DefaultExceptionHandler(trap_frame: &TrapFrame) -> ! { - loop { - // Prevent this from turning into a UDF instruction - // see rust-lang/rust#28728 for details - continue; - } -} - -#[doc(hidden)] -#[no_mangle] -#[allow(non_snake_case)] -pub fn DefaultInterruptHandler() { - loop { - // Prevent this from turning into a UDF instruction - // see rust-lang/rust#28728 for details - continue; - } -} - -extern "C" { - fn InstructionMisaligned(trap_frame: &TrapFrame); - fn InstructionFault(trap_frame: &TrapFrame); - fn IllegalInstruction(trap_frame: &TrapFrame); - fn Breakpoint(trap_frame: &TrapFrame); - fn LoadMisaligned(trap_frame: &TrapFrame); - fn LoadFault(trap_frame: &TrapFrame); - fn StoreMisaligned(trap_frame: &TrapFrame); - fn StoreFault(trap_frame: &TrapFrame); - fn UserEnvCall(trap_frame: &TrapFrame); - fn SupervisorEnvCall(trap_frame: &TrapFrame); - fn MachineEnvCall(trap_frame: &TrapFrame); - fn InstructionPageFault(trap_frame: &TrapFrame); - fn LoadPageFault(trap_frame: &TrapFrame); - fn StorePageFault(trap_frame: &TrapFrame); -} - -#[doc(hidden)] -#[no_mangle] -pub static __EXCEPTIONS: [Option; 16] = [ - Some(InstructionMisaligned), - Some(InstructionFault), - Some(IllegalInstruction), - Some(Breakpoint), - Some(LoadMisaligned), - Some(LoadFault), - Some(StoreMisaligned), - Some(StoreFault), - Some(UserEnvCall), - Some(SupervisorEnvCall), - None, - Some(MachineEnvCall), - Some(InstructionPageFault), - Some(LoadPageFault), - None, - Some(StorePageFault), -]; - -extern "C" { - fn SupervisorSoft(); - fn MachineSoft(); - fn SupervisorTimer(); - fn MachineTimer(); - fn SupervisorExternal(); - fn MachineExternal(); -} - -#[doc(hidden)] -#[no_mangle] -pub static __INTERRUPTS: [Option; 12] = [ - None, - Some(SupervisorSoft), - None, - Some(MachineSoft), - None, - Some(SupervisorTimer), - None, - Some(MachineTimer), - None, - Some(SupervisorExternal), - None, - Some(MachineExternal), -]; - -/// Default implementation of `_pre_init` does nothing. -/// Users can override this function with the [`#[pre_init]`] macro. -#[doc(hidden)] -#[no_mangle] -#[rustfmt::skip] -pub extern "Rust" fn default_pre_init() {} - -/// Default implementation of `_mp_hook` wakes hart 0 and busy-loops all the other harts. -/// Users can override this function by defining their own `_mp_hook`. -/// -/// # Note -/// -/// If the `single-hart` feature is enabled, `_mp_hook` is not called. -#[doc(hidden)] -#[no_mangle] -#[rustfmt::skip] -pub extern "Rust" fn default_mp_hook(hartid: usize) -> bool { - match hartid { - 0 => true, - _ => loop { - riscv::asm::wfi(); - }, - } -} - -/// Default implementation of `_setup_interrupts` sets `mtvec`/`stvec` to the address of `_start_trap`. -#[doc(hidden)] -#[no_mangle] -#[rustfmt::skip] -pub unsafe extern "Rust" fn default_setup_interrupts() { - extern "C" { - fn _start_trap(); - } - - xtvec::write(_start_trap as usize, xTrapMode::Direct); -} diff --git a/third-party/vendor/riscv/.cargo-checksum.json b/third-party/vendor/riscv/.cargo-checksum.json deleted file mode 100644 index 602dfe62..00000000 --- a/third-party/vendor/riscv/.cargo-checksum.json +++ /dev/null @@ -1 +0,0 @@ -{"files":{"CHANGELOG.md":"793c7eac934c52c379e3034a2369b21faa85bba1b355551866d58a515f0003c5","Cargo.toml":"e4d926036a23e998e334fbc905f80f0fcd97fd629f953e0714720db6ab4695e4","README.md":"ac9fec60ca01c9b0546359396b9396284321bd6605bf132eeecceaa10be4cf71","build.rs":"0f731ac6357fb19b1aed4dd6299755c423be010f49d62a706839144cc6a63958","src/asm.rs":"63b3d52c36343c8200ecc4910a96296e7fbe7552bcc0cc1ed07711dbd40fee23","src/critical_section.rs":"1769ed6055502d377c5c5f4449e230ae7558ce34acc0a77fe6ed64cf391795c0","src/delay.rs":"8e91f278b667ca7094d3d40ca9e180d18e164eb8c6f6654562b7aa96b5534a8f","src/interrupt.rs":"183826fe859eef27986f6c7f827147db3b535c5c995ba63a24908397fb5610de","src/lib.rs":"19cd797360d4222c8afa8d57e008d7d7d0948c1bcb27e4154887a5d587dc223d","src/macros.rs":"ea6625a15be6a9ec2f9fa9a7134d1bc93bd1f25b5d3435141325ffb697dcb055","src/register.rs":"d97d8a4fcfe798cfcfb148904a53345290addee68c23d95f13837d1a87f938dc","src/register/cycle.rs":"a2347cd9cbe2d90cc65b4e71b6815d736cf31a8ea22a18e4c843b1722d11eca8","src/register/cycleh.rs":"38625bf272a0b1c2a364e90f1639835ffc40dbfbad6df144a9f2b49573b0a1d5","src/register/hpmcounterx.rs":"d7b1c69d10e5c76427965b4c8f9139dac2aa7a5a1eb8c032d664244ec6ccbdcb","src/register/instret.rs":"a1469afa9876a27f2cb129f174a5d5f25f81529be77a86a534a57cbc00157e60","src/register/instreth.rs":"5f61fd655029ce9cf781225d4fe99c4319f8c7685b2e6b9524845721bf2b48e8","src/register/macros.rs":"8bc772b733386ecf919d714b0923d0eb092c64a0201c07e6c907edecbc657edf","src/register/marchid.rs":"2f1ac5d12ba5fe76e2598e4a7a964c6c40eb357fbdc966d436484edac6fa2232","src/register/mcause.rs":"0e13ee8ac6f9bbc996d575bf39708a68102594209e33e8ad0dbd7adb070de681","src/register/mcounteren.rs":"7ce2afa2caf544f866afb3ced50bd2c6b51d9688536e07217634f22d3257eb10","src/register/mcycle.rs":"f390d208a7b42841f3f1ff73741f822ea3f2808861f127b90a72d18990d30138","src/register/mcycleh.rs":"d519a131218baaab010ebfd35e96372b28f6e87c1135a1bc55dcd3fe90a1ee01","src/register/medeleg.rs":"5407b033c4d169125a768f9171f169ddbc17e0298cad9e3272875ce2c4485316","src/register/mepc.rs":"6579dcb903788605c02e963de8aca3e95678eba526e009e0ef037facb1e15bdb","src/register/mhartid.rs":"20306fee750b115d09539c897dc741c220048e763ca9e7fbd17a56bf362c2935","src/register/mhpmcounterx.rs":"fb08a4bc3a13ac148540bd40b321468e2516d4b8498181b904076c4458bfba65","src/register/mhpmeventx.rs":"0e92dd9a157d8faff8c44b99a4e4225a49f8b721b400b3d091fd5f4238443259","src/register/mideleg.rs":"bf19c0f501703102870e0ecbc8889f603349e0a8c40330dd86e82c03188db3fe","src/register/mie.rs":"c9631af837fdb0cec860b040d40cd2643118c2fa1a20a47fe4496a79f1d88a8d","src/register/mimpid.rs":"5b028ac73ca7ac721d82fac984af3fdf50cf5cef2dd24549ac05d1b04e4b2e7e","src/register/minstret.rs":"530c2ac2fb5fb79a4645ea2c80045148a233d0e69f9a9f441e41113cea634eae","src/register/minstreth.rs":"f623afd2a281175b89670491540d1f2dea0c8baab6742c3ba71865f189c1965e","src/register/mip.rs":"a21c08a83e098408e3c140de291ecb282be9bec95ea6ab6d736ddc0bbdbab976","src/register/misa.rs":"af52969ab3d2f502ad524f5d30471a02e9f7d8e2f0316d0797d7466eb4f1e61b","src/register/mscratch.rs":"f94cd3a81d2864b05e7801fbb604d510a0ff1698dffdbebe0f893f7ec648cd27","src/register/mstatus.rs":"e96f110fe28671fc8fd42d32e801178995c7398f88b6dc0ef82b25a2a8c7431f","src/register/mstatush.rs":"b4e4eab941b4933b45351b5c7db4b4187a2852df46a2a6ebb0d324f21d56a412","src/register/mtval.rs":"f0c68cd85c9af1131850a8b2595abe9e12d07471b51a95d7218f50d894428b42","src/register/mtvec.rs":"0e6f6837d5b672b1f586b2d68fb33d1456b033338c990bf9ec93b56293a27d69","src/register/mvendorid.rs":"961e66a85ea67b6795874f61852e195f96effdeb1c24b060f8a45e2072602e33","src/register/pmpaddrx.rs":"402a915899f770562cbf2dd56a7631fef6da0a16cfe6559ef4b956d40ce7e45d","src/register/pmpcfgx.rs":"077a258eae30c3c457b9fea66653a11a21032485cdae22c4eaac0ded104a7ed7","src/register/satp.rs":"832703ae6e60a7c5610604d32b359fb6e51f1398958f3c88a6030c6494d18771","src/register/scause.rs":"f8be55df547b13855951db9a4083ed669ce2f02ffa0f86bfc1350bb9f010287b","src/register/scounteren.rs":"f674572b2a35fb401d7523934601fd5c4f1b69a94e87beb7a043190df5b8e609","src/register/sepc.rs":"c70602e54be39cc5322b7521dfe22d0b70dc1ad8f264cae98f9d3dadbc59cd2b","src/register/sie.rs":"30c5add548f48c014647eda99548ecfdb89a89a271abcc4310672f362558791e","src/register/sip.rs":"35f1b3e28ef17a39f807230acfdab591f5ae6be2f7a768406564a9bb7657967d","src/register/sscratch.rs":"35123597ef3fcc765f305eb29f66c65f0e038f8b74ae73e2fecdb1c6d614672a","src/register/sstatus.rs":"688ffc6d563a406ab7464ce4272b18e7f454c374241c8029b5c0bacd72da89a6","src/register/stval.rs":"5f0ed16dd5c627658ec57667cc11ef01c575e9709768dbace0975117c88784bc","src/register/stvec.rs":"f3a35a4611a9bacb7e79b0b6aebe08de606873855c8d13a0a3fc42385ea11ca3","src/register/time.rs":"309dfa983af73ca81bd49d2ef282b71b11aadaf1ca26c0a65ba6f0a41fd7e7be","src/register/timeh.rs":"1a37393319803541df77a749da86ae005ec2c5ef5e7c7f1e53589e19cd530218"},"package":"2f5c1b8bf41ea746266cdee443d1d1e9125c86ce1447e1a2615abd34330d33a9"} \ No newline at end of file diff --git a/third-party/vendor/riscv/CHANGELOG.md b/third-party/vendor/riscv/CHANGELOG.md deleted file mode 100644 index 12b68fc1..00000000 --- a/third-party/vendor/riscv/CHANGELOG.md +++ /dev/null @@ -1,165 +0,0 @@ -# Change Log - -All notable changes to this project will be documented in this file. - -The format is based on [Keep a Changelog](http://keepachangelog.com/) -and this project adheres to [Semantic Versioning](http://semver.org/). - -## [Unreleased] - -## [v0.11.1] - 2024-02-15 - -### Changed - -- Made `asm::wfi`, `fence`, `fence_i` and `sfence` safe (ie, removed `unsafe` from their definitions) - -## [v0.11.0] - 2024-01-14 - -### Added - -- Add `asm::ecall()`, a wrapper for implementing an `ecall` instruction -- Add `nested` function for nested ISRs in `interrupt::machine` and `interrupt::supervisor` -- `s-mode` feature for reexporting `interrupt::machine` or `interrupt::supervisor` to `interrupt` -- Support for supervisor-level interrupts in `interrupt::supervisor` -- Add CI workflow to check that CHANGELOG.md file has been modified in PRs -- Add `read_csr_as_rv32`, `set_rv32`, and `clear_rv32` macros -- Add `mstatus::uxl` and `mstatus::sxl` -- Add `mstatus::ube`, `mstatus::sbe`, and `mstatus::mbe` endianness bit fields -- Add `mstatush` registers (RISCV-32 only) -- Add `asm::fence()`, a wrapper for implementing a `fence` instruction -- Add `asm::fence_i()`, a wrapper for implementing a `fence.i` instruction -- Add `TryFrom` implementation for `mcause::{Interrupt, Exception}` and `scause::{Interrupt, Exception}` - -### Changed - -- Cargo workspace for riscv and riscv-rt -- Update `embedded-hal` dependency to v1.0.0 (bumps MSRV to 1.60) -- `misa::MXL` renamed to `misa::XLEN` -- Removed `bit_field` dependency -- CI actions updated. They now use `checkout@v3` and `dtolnay/rust-toolchain`. -- `mcause::{Interrupt, Exception}` and `scause::{Interrupt, Exception}` now implement `From` trait for `usize` -- Set safety of `asm::nop` and `asm::delay` functions to safe. - -### Fixed - -- Fix `scause::Exception` missing `LoadMisaligned` -- Fix `scause::Exception` missing `SupervisorEnvCall` -- Removed user-level interrupts from `mcause::Interrupt` and `scause::Interrupt` -- Removed user-level interrupts from `mstatus` -- Removed machine environment call delegation from `medeleg` -- Removed user-level interrupts from machine and supervisor mode interrupt-related registers. - -### Removed - -- User mode registers removed, as they are no longer supported in RISC-V -- FCSR register operations removed to avoid UB (#148) - -## [v0.10.1] - 2023-01-18 - -### Fixed - -- Fix implementation for `SingleHartCriticalSection` - -## [v0.10.0] - 2022-11-09 - -### Added - -- `critical-section-single-hart` feature which provides an implementation for the `critical_section` crate for single-hart systems, based on disabling all interrupts. - -## [v0.9.0] - 2022-10-06 - -### Fixed - -- Fix `asm::delay()` to ensure count register is always reloaded -- Fix reading marchid and mimpid (#107) - -### Removed -- `set_msoft`, `clear_msoft`, `set_mtimer` and `clear_mtimer` removed as part of fixing issue #62 - -## [v0.8.0] - 2022-04-20 - -### Added - -- Add `#[cfg(riscv32)]` to `pmpcfg1` and `pmpcfg3` modules -- Add enums `Range`, `Permission` for PMP configuration -- Add `set_pmp()` and `clear_pmp()` functions to pmpcfg(x) modules -- Add struct `Pmpcsr` and is returned from `pmpcfgx::read()` -- Add `singleton!` macro -- Add delay structure and methods using embedded-hal traits and `mcycle` register -- Add `asm::delay()` function for assembly-based busy-loops -- Add `asm::nop()`, a wrapper for implementing a `nop` instruction -- Add missing `#[inline]` attribute to register reads, type conversations and `interrupt::free` - -### Changed - -- Use new `asm!` instead of `llvm_asm!` -- Change `pmpcfgx::read()` macro to `read_csr_as!()` from `read_csr_as_usize!()` -- Inline assembly is now always used -- Update Minimum Supported Rust Version to 1.59 - -### Fixed - -- Fix `sfence.vma` operand order - -### Removed - -- Remove `inline-asm` feature which is now always enabled - -## [v0.7.0] - 2021-07-29 - -### Added - -- Add `medeleg` register -- Add `cycle[h]`, `instret[h]` and `mcounteren` -- Add additional binaries for floating-point ABIs -- Add support for `mxr` -- Add support for `mprv` - -### Changed - -- Fix `scause::set` -- Various formatting and comment fixes -- Update `bare-metal` to `v1.0.0` removing `Nr` trait -- Build targets on `docs.rs` are now RISC-V targets other than default ones - -## [v0.6.0] - 2020-06-20 - -### Changed - -- `Mtvec::trap_mode()`, `Stvec::trap_mode()` and `Utvec::trap_mode()` functions now return `Option` (breaking change) -- Updated Minimum Supported Rust Version to 1.42.0 -- Use `llvm_asm!` instead of `asm!` - -### Removed - -- vexriscv-specific registers were moved to the `vexriscv` crate - -## [v0.5.6] - 2020-03-14 - -### Added - -- Added vexriscv-specific registers - -## [v0.5.5] - 2020-02-28 - -### Added - -- Added `riscv32i-unknown-none-elf` target support -- Added user trap setup and handling registers -- Added write methods for the `mip` and `satp` registers -- Added `mideleg` register -- Added Changelog - -### Changed - -- Fixed MSRV by restricting the upper bound of `bare-metal` version - -[Unreleased]: https://github.com/rust-embedded/riscv/compare/v0.10.1...HEAD -[v0.10.1]: https://github.com/rust-embedded/riscv/compare/v0.10.0...v0.10.1 -[v0.10.0]: https://github.com/rust-embedded/riscv/compare/v0.9.0...v0.10.0 -[v0.9.0]: https://github.com/rust-embedded/riscv/compare/v0.8.0...v0.9.0 -[v0.8.0]: https://github.com/rust-embedded/riscv/compare/v0.7.0...v0.8.0 -[v0.7.0]: https://github.com/rust-embedded/riscv/compare/v0.6.0...v0.7.0 -[v0.6.0]: https://github.com/rust-embedded/riscv/compare/v0.5.6...v0.6.0 -[v0.5.6]: https://github.com/rust-embedded/riscv/compare/v0.5.5...v0.5.6 -[v0.5.5]: https://github.com/rust-embedded/riscv/compare/v0.5.4...v0.5.5 diff --git a/third-party/vendor/riscv/Cargo.toml b/third-party/vendor/riscv/Cargo.toml deleted file mode 100644 index 844eb7db..00000000 --- a/third-party/vendor/riscv/Cargo.toml +++ /dev/null @@ -1,53 +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 are reading this file be aware that the original Cargo.toml -# will likely look very different (and much more reasonable). -# See Cargo.toml.orig for the original contents. - -[package] -edition = "2021" -rust-version = "1.60" -name = "riscv" -version = "0.11.1" -authors = ["The RISC-V Team "] -description = "Low level access to RISC-V processors" -documentation = "https://docs.rs/riscv" -readme = "README.md" -keywords = [ - "riscv", - "register", - "peripheral", -] -categories = [ - "embedded", - "hardware-support", - "no-std", -] -license = "ISC" -repository = "https://github.com/rust-embedded/riscv" - -[package.metadata.docs.rs] -all-features = true -default-target = "riscv64imac-unknown-none-elf" -targets = [ - "riscv32i-unknown-none-elf", - "riscv32imc-unknown-none-elf", - "riscv32imac-unknown-none-elf", - "riscv64imac-unknown-none-elf", - "riscv64gc-unknown-none-elf", -] - -[dependencies.critical-section] -version = "1.1.2" - -[dependencies.embedded-hal] -version = "1.0.0" - -[features] -critical-section-single-hart = ["critical-section/restore-state-bool"] -s-mode = [] diff --git a/third-party/vendor/riscv/README.md b/third-party/vendor/riscv/README.md deleted file mode 100644 index f67ac78c..00000000 --- a/third-party/vendor/riscv/README.md +++ /dev/null @@ -1,40 +0,0 @@ -[![crates.io](https://img.shields.io/crates/d/riscv.svg)](https://crates.io/crates/riscv) -[![crates.io](https://img.shields.io/crates/v/riscv.svg)](https://crates.io/crates/riscv) - -# `riscv` - -> Low level access to RISC-V processors - -This project is developed and maintained by the [RISC-V team][team]. - -## [Documentation](https://docs.rs/crate/riscv) - -## Minimum Supported Rust Version (MSRV) - -This crate is guaranteed to compile on stable Rust 1.60 and up. It *might* -compile with older versions but that may change in any new patch release. - -## License - -Copyright 2019-2022 [RISC-V team][team] - -Permission to use, copy, modify, and/or distribute this software for any purpose -with or without fee is hereby granted, provided that the above copyright notice -and this permission notice appear in all copies. - -THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH -REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND -FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, -INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS -OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER -TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF -THIS SOFTWARE. - -## Code of Conduct - -Contribution to this crate is organized under the terms of the [Rust Code of -Conduct][CoC], the maintainer of this crate, the [RISC-V team][team], promises -to intervene to uphold that code of conduct. - -[CoC]: CODE_OF_CONDUCT.md -[team]: https://github.com/rust-embedded/wg#the-risc-v-team diff --git a/third-party/vendor/riscv/build.rs b/third-party/vendor/riscv/build.rs deleted file mode 100644 index 30db72e7..00000000 --- a/third-party/vendor/riscv/build.rs +++ /dev/null @@ -1,13 +0,0 @@ -use std::env; - -fn main() { - let target = env::var("TARGET").unwrap(); - - if target.starts_with("riscv32") { - println!("cargo:rustc-cfg=riscv"); - println!("cargo:rustc-cfg=riscv32"); - } else if target.starts_with("riscv64") { - println!("cargo:rustc-cfg=riscv"); - println!("cargo:rustc-cfg=riscv64"); - } -} diff --git a/third-party/vendor/riscv/src/asm.rs b/third-party/vendor/riscv/src/asm.rs deleted file mode 100644 index 682e83ae..00000000 --- a/third-party/vendor/riscv/src/asm.rs +++ /dev/null @@ -1,163 +0,0 @@ -//! Assembly instructions - -macro_rules! instruction { - ($(#[$attr:meta])*, unsafe $fnname:ident, $asm:expr) => ( - $(#[$attr])* - #[inline] - pub unsafe fn $fnname() { - match () { - #[cfg(riscv)] - () => core::arch::asm!($asm), - - #[cfg(not(riscv))] - () => unimplemented!(), - } - } - ); - ($(#[$attr:meta])*, $fnname:ident, $asm:expr) => ( - $(#[$attr])* - #[inline] - pub fn $fnname() { - match () { - #[cfg(riscv)] - () => unsafe { core::arch::asm!($asm) }, - - #[cfg(not(riscv))] - () => unimplemented!(), - } - } - ); -} - -instruction!( - /// `nop` instruction wrapper - /// - /// The `NOP` instruction does not change any architecturally visible state, except for - /// advancing the pc and incrementing any applicable performance counters. - /// - /// This function generates a no-operation; it's useful to prevent delay loops from being - /// optimized away. - , nop, "nop"); -instruction!( - /// `EBREAK` instruction wrapper - /// - /// Generates a breakpoint exception. - , unsafe ebreak, "ebreak"); -instruction!( - /// `WFI` instruction wrapper - /// - /// Provides a hint to the implementation that the current hart can be stalled until an interrupt might need servicing. - /// The WFI instruction is just a hint, and a legal implementation is to implement WFI as a NOP. - , wfi, "wfi"); -instruction!( - /// `SFENCE.VMA` instruction wrapper (all address spaces and page table levels) - /// - /// Synchronizes updates to in-memory memory-management data structures with current execution. - /// Instruction execution causes implicit reads and writes to these data structures; however, these implicit references - /// are ordinarily not ordered with respect to loads and stores in the instruction stream. - /// Executing an `SFENCE.VMA` instruction guarantees that any stores in the instruction stream prior to the - /// `SFENCE.VMA` are ordered before all implicit references subsequent to the `SFENCE.VMA`. - , sfence_vma_all, "sfence.vma"); -instruction!( - /// `FENCE` instruction wrapper - /// - /// The FENCE instruction is used to order device I/O and memory accesses as viewed by other RISC-V - /// harts and external devices or coprocessors. Any combination of device input (I), device output - /// (O), memory reads (R), and memory writes (W) may be ordered with respect to any combination - /// of the same. Informally, no other RISC-V hart or external device can observe any operation in the - /// successor set following a FENCE before any operation in the predecessor set preceding the FENCE. - /// Chapter 17 provides a precise description of the RISC-V memory consistency model. - /// - /// The FENCE instruction also orders memory reads and writes made by the hart as observed by - /// memory reads and writes made by an external device. However, FENCE does not order observations - /// of events made by an external device using any other signaling mechanism. - , fence, "fence"); -instruction!( - /// `FENCE.I` instruction wrapper - /// - /// Used to synchronize the instruction and data streams. RISC-V does not guarantee that - /// stores to instruction memory will be made visible to instruction fetches on a - /// RISC-V hart until that hart executes a FENCE.I instruction. - /// - /// A FENCE.I instruction ensures that a subsequent instruction fetch on a RISC-V hart - /// will see any previous data stores already visible to the same RISC-V hart. - /// FENCE.I does not ensure that other RISC-V harts’ instruction fetches will observe the - /// local hart’s stores in a multiprocessor system. To make a store to instruction memory - /// visible to all RISC-V harts, the writing hart also has to execute a data FENCE before - /// requesting that all remote RISC-V harts execute a FENCE.I. - /// - /// The unused fields in the FENCE.I instruction, imm\[11:0\], rs1, and rd, are reserved for - /// finer-grain fences in future extensions. For forward compatibility, base - /// implementations shall ignore these fields, and standard software shall zero these fields. - , fence_i, "fence.i"); - -/// `SFENCE.VMA` instruction wrapper -/// -/// Synchronizes updates to in-memory memory-management data structures with current execution. -/// Instruction execution causes implicit reads and writes to these data structures; however, these implicit references -/// are ordinarily not ordered with respect to loads and stores in the instruction stream. -/// Executing an `SFENCE.VMA` instruction guarantees that any stores in the instruction stream prior to the -/// `SFENCE.VMA` are ordered before all implicit references subsequent to the `SFENCE.VMA`. -#[inline] -#[allow(unused_variables)] -pub unsafe fn sfence_vma(asid: usize, addr: usize) { - match () { - #[cfg(riscv)] - () => core::arch::asm!("sfence.vma {0}, {1}", in(reg) addr, in(reg) asid), - - #[cfg(not(riscv))] - () => unimplemented!(), - } -} - -/// `ECALL` instruction wrapper -/// -/// Generates an exception for a service request to the execution environment. -/// When executed in U-mode, S-mode, or M-mode, it generates an environment-call-from-U-mode -/// exception, environment-call-from-S-mode exception, or environment-call-from-M-mode exception, -/// respectively, and performs no other operation. -/// -/// # Note -/// -/// The ECALL instruction will **NOT** save and restore the stack pointer, as it triggers an exception. -/// The stack pointer must be saved and restored accordingly by the exception handler. -#[inline] -pub unsafe fn ecall() { - match () { - #[cfg(riscv)] - () => core::arch::asm!("ecall", options(nostack)), - - #[cfg(not(riscv))] - () => unimplemented!(), - } -} - -/// Blocks the program for *at least* `cycles` CPU cycles. -/// -/// This is implemented in assembly so its execution time is independent of the optimization -/// level, however it is dependent on the specific architecture and core configuration. -/// -/// NOTE that the delay can take much longer if interrupts are serviced during its execution -/// and the execution time may vary with other factors. This delay is mainly useful for simple -/// timer-less initialization of peripherals if and only if accurate timing is not essential. In -/// any other case please use a more accurate method to produce a delay. -#[inline] -#[allow(unused_variables)] -pub fn delay(cycles: u32) { - match () { - #[cfg(riscv)] - () => unsafe { - let real_cyc = 1 + cycles / 2; - core::arch::asm!( - "1:", - "addi {0}, {0}, -1", - "bne {0}, zero, 1b", - inout(reg) real_cyc => _, - options(nomem, nostack), - ) - }, - - #[cfg(not(riscv))] - () => unimplemented!(), - } -} diff --git a/third-party/vendor/riscv/src/critical_section.rs b/third-party/vendor/riscv/src/critical_section.rs deleted file mode 100644 index 908daec7..00000000 --- a/third-party/vendor/riscv/src/critical_section.rs +++ /dev/null @@ -1,29 +0,0 @@ -use critical_section::{set_impl, Impl, RawRestoreState}; - -use crate::interrupt; - -struct SingleHartCriticalSection; -set_impl!(SingleHartCriticalSection); - -unsafe impl Impl for SingleHartCriticalSection { - #[cfg(not(feature = "s-mode"))] - unsafe fn acquire() -> RawRestoreState { - let mut mstatus: usize; - core::arch::asm!("csrrci {}, mstatus, 0b1000", out(reg) mstatus); - core::mem::transmute::<_, crate::register::mstatus::Mstatus>(mstatus).mie() - } - - #[cfg(feature = "s-mode")] - unsafe fn acquire() -> RawRestoreState { - let mut sstatus: usize; - core::arch::asm!("csrrci {}, sstatus, 0b0010", out(reg) sstatus); - core::mem::transmute::<_, crate::register::sstatus::Sstatus>(sstatus).sie() - } - - unsafe fn release(was_active: RawRestoreState) { - // Only re-enable interrupts if they were enabled before the critical section. - if was_active { - interrupt::enable() - } - } -} diff --git a/third-party/vendor/riscv/src/delay.rs b/third-party/vendor/riscv/src/delay.rs deleted file mode 100644 index ee501f08..00000000 --- a/third-party/vendor/riscv/src/delay.rs +++ /dev/null @@ -1,30 +0,0 @@ -//! Delay devices and providers -use crate::register::mcycle; -use embedded_hal::delay::DelayNs; - -/// Machine mode cycle counter (`mcycle`) as a delay provider -#[derive(Copy, Clone)] -#[repr(transparent)] -pub struct McycleDelay { - /// The clock speed of the core, in Hertz - ticks_second: u32, -} - -impl McycleDelay { - /// Constructs the delay provider. - /// `ticks_second` should be the clock speed of the core, in Hertz - #[inline] - pub const fn new(ticks_second: u32) -> Self { - Self { ticks_second } - } -} - -impl DelayNs for McycleDelay { - #[inline] - fn delay_ns(&mut self, ns: u32) { - let t0 = mcycle::read64(); - let ns_64: u64 = ns.into(); - let clock = (ns_64 * (self.ticks_second as u64)) / 1_000_000_000u64; - while mcycle::read64().wrapping_sub(t0) <= clock {} - } -} diff --git a/third-party/vendor/riscv/src/interrupt.rs b/third-party/vendor/riscv/src/interrupt.rs deleted file mode 100644 index fefdb14b..00000000 --- a/third-party/vendor/riscv/src/interrupt.rs +++ /dev/null @@ -1,188 +0,0 @@ -//! Interrupts - -// NOTE: Adapted from cortex-m/src/interrupt.rs - -pub mod machine { - use crate::register::{mepc, mstatus}; - - /// Disables all interrupts in the current hart (machine mode). - #[inline] - pub fn disable() { - // SAFETY: It is safe to disable interrupts - unsafe { mstatus::clear_mie() } - } - - /// Enables all the interrupts in the current hart (machine mode). - /// - /// # Safety - /// - /// Do not call this function inside a critical section. - #[inline] - pub unsafe fn enable() { - mstatus::set_mie() - } - - /// Execute closure `f` with interrupts disabled in the current hart (machine mode). - /// - /// This method does not synchronise multiple harts, so it is not suitable for - /// using as a critical section. See the `critical-section` crate for a cross-platform - /// way to enter a critical section which provides a `CriticalSection` token. - /// - /// This crate provides an implementation for `critical-section` suitable for single-hart systems, - /// based on disabling all interrupts. It can be enabled with the `critical-section-single-hart` feature. - #[inline] - pub fn free(f: F) -> R - where - F: FnOnce() -> R, - { - let mstatus = mstatus::read(); - - // disable interrupts - disable(); - - let r = f(); - - // If the interrupts were active before our `disable` call, then re-enable - // them. Otherwise, keep them disabled - if mstatus.mie() { - unsafe { enable() }; - } - - r - } - - /// Execute closure `f` with interrupts enabled in the current hart (machine mode). - /// - /// This method is assumed to be called within an interrupt handler, and allows - /// nested interrupts to occur. After the closure `f` is executed, the [`mstatus`] - /// and [`mepc`] registers are properly restored to their previous values. - /// - /// # Safety - /// - /// - Do not call this function inside a critical section. - /// - This method is assumed to be called within an interrupt handler. - /// - Make sure to clear the interrupt flag that caused the interrupt before calling - /// this method. Otherwise, the interrupt will be re-triggered before executing `f`. - #[inline] - pub unsafe fn nested(f: F) -> R - where - F: FnOnce() -> R, - { - let mstatus = mstatus::read(); - let mepc = mepc::read(); - - // enable interrupts to allow nested interrupts - enable(); - - let r = f(); - - // If the interrupts were inactive before our `enable` call, then re-disable - // them. Otherwise, keep them enabled - if !mstatus.mie() { - disable(); - } - - // Restore MSTATUS.PIE, MSTATUS.MPP, and SEPC - if mstatus.mpie() { - mstatus::set_mpie(); - } - mstatus::set_mpp(mstatus.mpp()); - mepc::write(mepc); - - r - } -} -pub mod supervisor { - use crate::register::{sepc, sstatus}; - - /// Disables all interrupts in the current hart (supervisor mode). - #[inline] - pub fn disable() { - // SAFETY: It is safe to disable interrupts - unsafe { sstatus::clear_sie() } - } - - /// Enables all the interrupts in the current hart (supervisor mode). - /// - /// # Safety - /// - /// Do not call this function inside a critical section. - #[inline] - pub unsafe fn enable() { - sstatus::set_sie() - } - - /// Execute closure `f` with interrupts disabled in the current hart (supervisor mode). - /// - /// This method does not synchronise multiple harts, so it is not suitable for - /// using as a critical section. See the `critical-section` crate for a cross-platform - /// way to enter a critical section which provides a `CriticalSection` token. - /// - /// This crate provides an implementation for `critical-section` suitable for single-hart systems, - /// based on disabling all interrupts. It can be enabled with the `critical-section-single-hart` feature. - #[inline] - pub fn free(f: F) -> R - where - F: FnOnce() -> R, - { - let sstatus = sstatus::read(); - - // disable interrupts - disable(); - - let r = f(); - - // If the interrupts were active before our `disable` call, then re-enable - // them. Otherwise, keep them disabled - if sstatus.sie() { - unsafe { enable() }; - } - - r - } - - /// Execute closure `f` with interrupts enabled in the current hart (supervisor mode). - /// This method is assumed to be called within an interrupt handler, and allows - /// nested interrupts to occur. After the closure `f` is executed, the [`sstatus`] - /// and [`sepc`] registers are properly restored to their previous values. - /// - /// # Safety - /// - /// - Do not call this function inside a critical section. - /// - This method is assumed to be called within an interrupt handler. - /// - Make sure to clear the interrupt flag that caused the interrupt before calling - /// this method. Otherwise, the interrupt will be re-triggered before executing `f`. - #[inline] - pub unsafe fn nested(f: F) -> R - where - F: FnOnce() -> R, - { - let sstatus = sstatus::read(); - let sepc = sepc::read(); - - // enable interrupts to allow nested interrupts - enable(); - - let r = f(); - - // If the interrupts were inactive before our `enable` call, then re-disable - // them. Otherwise, keep them enabled - if !sstatus.sie() { - disable(); - } - - // Restore SSTATUS.SPIE, SSTATUS.SPP, and SEPC - if sstatus.spie() { - sstatus::set_spie(); - } - sstatus::set_spp(sstatus.spp()); - sepc::write(sepc); - - r - } -} - -#[cfg(not(feature = "s-mode"))] -pub use machine::*; -#[cfg(feature = "s-mode")] -pub use supervisor::*; diff --git a/third-party/vendor/riscv/src/lib.rs b/third-party/vendor/riscv/src/lib.rs deleted file mode 100644 index 7eacac7a..00000000 --- a/third-party/vendor/riscv/src/lib.rs +++ /dev/null @@ -1,54 +0,0 @@ -//! Low level access to RISC-V processors -//! -//! # Minimum Supported Rust Version (MSRV) -//! -//! This crate is guaranteed to compile on stable Rust 1.60 and up. It *might* -//! compile with older versions but that may change in any new patch release. -//! -//! # Features -//! -//! This crate provides: -//! -//! - Access to core registers like `mstatus` or `mcause`. -//! - Interrupt manipulation mechanisms. -//! - Wrappers around assembly instructions like `WFI`. -//! -//! # Optional features -//! -//! ## `s-mode` -//! -//! This feature re-exports in `interrupt` S-mode interrupt functions defined in `interrupt::supervisor`. -//! By default, the crate assumes that the target is running in M-mode. -//! Thus, `interrupt` re-exports the M-mode functions defined in `interrupt::machine`. -//! -//! ## `critical-section-single-hart` -//! -//! This feature enables a [`critical-section`](https://github.com/rust-embedded/critical-section) -//! implementation suitable for single-hart targets, based on disabling interrupts globally. -//! This feature uses S-mode interrupt handling if the `s-mode` feature is enabled, and M-mode otherwise. -//! -//! It is **unsound** to enable it on multi-hart targets, -//! and may cause functional problems in systems where some interrupts must NOT be disabled -//! or critical sections are managed as part of an RTOS. In these cases, you should use -//! a target-specific implementation instead, typically provided by a HAL or RTOS crate. - -#![no_std] -#![allow(clippy::missing_safety_doc)] - -pub mod asm; -pub mod delay; -pub mod interrupt; -pub mod register; - -#[macro_use] -mod macros; - -#[cfg(all(riscv, feature = "critical-section-single-hart"))] -mod critical_section; - -/// Used to reexport items for use in macros. Do not use directly. -/// Not covered by semver guarantees. -#[doc(hidden)] -pub mod _export { - pub use critical_section; -} diff --git a/third-party/vendor/riscv/src/macros.rs b/third-party/vendor/riscv/src/macros.rs deleted file mode 100644 index 012063a4..00000000 --- a/third-party/vendor/riscv/src/macros.rs +++ /dev/null @@ -1,57 +0,0 @@ -/// Macro to create a mutable reference to a statically allocated value -/// -/// This macro returns a value with type `Option<&'static mut $ty>`. `Some($expr)` will be returned -/// the first time the macro is executed; further calls will return `None`. To avoid `unwrap`ping a -/// `None` variant the caller must ensure that the macro is called from a function that's executed -/// at most once in the whole lifetime of the program. -/// -/// # Note -/// -/// This macro requires a `critical-section` implementation to be set. For most single-hart systems, -/// you can enable the `critical-section-single-hart` feature for this crate. For other systems, you -/// have to provide one from elsewhere, typically your chip's HAL crate. -/// -/// # Example -/// -/// ``` no_run -/// use riscv::singleton; -/// -/// fn main() { -/// // OK if `main` is executed only once -/// let x: &'static mut bool = singleton!(: bool = false).unwrap(); -/// -/// let y = alias(); -/// // BAD this second call to `alias` will definitively `panic!` -/// let y_alias = alias(); -/// } -/// -/// fn alias() -> &'static mut bool { -/// singleton!(: bool = false).unwrap() -/// } -/// ``` -#[macro_export] -macro_rules! singleton { - (: $ty:ty = $expr:expr) => { - $crate::_export::critical_section::with(|_| { - static mut VAR: Option<$ty> = None; - - #[allow(unsafe_code)] - let used = unsafe { VAR.is_some() }; - if used { - None - } else { - let expr = $expr; - - #[allow(unsafe_code)] - unsafe { - VAR = Some(expr) - } - - #[allow(unsafe_code)] - unsafe { - VAR.as_mut() - } - } - }) - }; -} diff --git a/third-party/vendor/riscv/src/register.rs b/third-party/vendor/riscv/src/register.rs deleted file mode 100644 index d38db22d..00000000 --- a/third-party/vendor/riscv/src/register.rs +++ /dev/null @@ -1,111 +0,0 @@ -//! RISC-V CSR's -//! -//! The following registers are not available on 64-bit implementations. -//! -//! - cycleh -//! - timeh -//! - instreth -//! - hpmcounter<3-31>h -//! - mcycleh -//! - minstreth -//! - mhpmcounter<3-31>h -//! - mstatush -//! -//! # On Floating-Point CSRs -//! -//! We are deliberately *not* providing instructions that could change the floating-point rounding -//! mode or exception behavior or read the accrued exceptions flags: `frcsr`, `fscsr`, `fsrm`, -//! `frflags`, `fsflags`. -//! -//! Rust makes no guarantees whatsoever about the contents of the accrued exceptions register: Rust -//! floating-point operations may or may not result in this register getting updated with exception -//! state, and the register can change between two invocations of this function even when no -//! floating-point operations appear in the source code (since floating-point operations appearing -//! earlier or later can be reordered). -//! -//! Modifying the rounding mode leads to **immediate Undefined Behavior**: Rust assumes that the -//! default rounding mode is always set and will optimize accordingly. This even applies when the -//! rounding mode is altered and later reset to its original value without any floating-point -//! operations appearing in the source code between those operations (since floating-point -//! operations appearing earlier or later can be reordered). -//! -//! If you need to perform some floating-point operations and check whether they raised an -//! exception, use a single inline assembly block for the entire sequence of operations. -//! -//! If you need to perform some floating-point operations under a different rounding mode, use a -//! single inline assembly block and make sure to restore the original rounding mode before the end -//! of the block. - -#[macro_use] -mod macros; - -// User Counter/Timers -pub mod cycle; -pub mod cycleh; -mod hpmcounterx; -pub use self::hpmcounterx::*; -pub mod instret; -pub mod instreth; -pub mod time; -pub mod timeh; - -// Supervisor Trap Setup -pub mod scounteren; -pub mod sie; -pub mod sstatus; -pub mod stvec; - -// Supervisor Trap Handling -pub mod scause; -pub mod sepc; -pub mod sip; -pub mod sscratch; -pub mod stval; - -// Supervisor Protection and Translation -pub mod satp; - -// Machine Information Registers -pub mod marchid; -pub mod mhartid; -pub mod mimpid; -pub mod mvendorid; - -// Machine Trap Setup -pub mod mcounteren; -pub mod medeleg; -pub mod mideleg; -pub mod mie; -pub mod misa; -pub mod mstatus; -pub mod mstatush; -pub mod mtvec; - -// Machine Trap Handling -pub mod mcause; -pub mod mepc; -pub mod mip; -pub mod mscratch; -pub mod mtval; - -// Machine Protection and Translation -mod pmpcfgx; -pub use self::pmpcfgx::*; -mod pmpaddrx; -pub use self::pmpaddrx::*; - -// Machine Counter/Timers -pub mod mcycle; -pub mod mcycleh; -mod mhpmcounterx; -pub use self::mhpmcounterx::*; -pub mod minstret; -pub mod minstreth; - -// Machine Counter Setup -mod mhpmeventx; -pub use self::mhpmeventx::*; - -// TODO: Debug/Trace Registers (shared with Debug Mode) - -// TODO: Debug Mode Registers diff --git a/third-party/vendor/riscv/src/register/cycle.rs b/third-party/vendor/riscv/src/register/cycle.rs deleted file mode 100644 index 8499de3d..00000000 --- a/third-party/vendor/riscv/src/register/cycle.rs +++ /dev/null @@ -1,8 +0,0 @@ -//! cycle register -//! -//! Shadow of mcycle register -//! must have `scounteren::cy` or `mcounteren::cy` bit enabled depending on whether -//! S-mode is implemented or not - -read_csr_as_usize!(0xC00); -read_composite_csr!(super::cycleh::read(), read()); diff --git a/third-party/vendor/riscv/src/register/cycleh.rs b/third-party/vendor/riscv/src/register/cycleh.rs deleted file mode 100644 index 99bcaeab..00000000 --- a/third-party/vendor/riscv/src/register/cycleh.rs +++ /dev/null @@ -1,7 +0,0 @@ -//! cycleh register -//! -//! Shadow of mcycleh register (rv32) -//! must have `scounteren::cy` or `mcounteren::cy` bit enabled depending on whether -//! S-mode is implemented or not - -read_csr_as_usize_rv32!(0xC80); diff --git a/third-party/vendor/riscv/src/register/hpmcounterx.rs b/third-party/vendor/riscv/src/register/hpmcounterx.rs deleted file mode 100644 index 62fbc8a2..00000000 --- a/third-party/vendor/riscv/src/register/hpmcounterx.rs +++ /dev/null @@ -1,82 +0,0 @@ -macro_rules! reg { - ( - $addr:expr, $csrl:ident, $csrh:ident - ) => { - /// Performance-monitoring counter - pub mod $csrl { - read_csr_as_usize!($addr); - read_composite_csr!(super::$csrh::read(), read()); - } - }; -} - -macro_rules! regh { - ( - $addr:expr, $csrh:ident - ) => { - /// Upper 32 bits of performance-monitoring counter (RV32I only) - pub mod $csrh { - read_csr_as_usize_rv32!($addr); - } - }; -} - -reg!(0xC03, hpmcounter3, hpmcounter3h); -reg!(0xC04, hpmcounter4, hpmcounter4h); -reg!(0xC05, hpmcounter5, hpmcounter5h); -reg!(0xC06, hpmcounter6, hpmcounter6h); -reg!(0xC07, hpmcounter7, hpmcounter7h); -reg!(0xC08, hpmcounter8, hpmcounter8h); -reg!(0xC09, hpmcounter9, hpmcounter9h); -reg!(0xC0A, hpmcounter10, hpmcounter10h); -reg!(0xC0B, hpmcounter11, hpmcounter11h); -reg!(0xC0C, hpmcounter12, hpmcounter12h); -reg!(0xC0D, hpmcounter13, hpmcounter13h); -reg!(0xC0E, hpmcounter14, hpmcounter14h); -reg!(0xC0F, hpmcounter15, hpmcounter15h); -reg!(0xC10, hpmcounter16, hpmcounter16h); -reg!(0xC11, hpmcounter17, hpmcounter17h); -reg!(0xC12, hpmcounter18, hpmcounter18h); -reg!(0xC13, hpmcounter19, hpmcounter19h); -reg!(0xC14, hpmcounter20, hpmcounter20h); -reg!(0xC15, hpmcounter21, hpmcounter21h); -reg!(0xC16, hpmcounter22, hpmcounter22h); -reg!(0xC17, hpmcounter23, hpmcounter23h); -reg!(0xC18, hpmcounter24, hpmcounter24h); -reg!(0xC19, hpmcounter25, hpmcounter25h); -reg!(0xC1A, hpmcounter26, hpmcounter26h); -reg!(0xC1B, hpmcounter27, hpmcounter27h); -reg!(0xC1C, hpmcounter28, hpmcounter28h); -reg!(0xC1D, hpmcounter29, hpmcounter29h); -reg!(0xC1E, hpmcounter30, hpmcounter30h); -reg!(0xC1F, hpmcounter31, hpmcounter31h); - -regh!(0xC83, hpmcounter3h); -regh!(0xC84, hpmcounter4h); -regh!(0xC85, hpmcounter5h); -regh!(0xC86, hpmcounter6h); -regh!(0xC87, hpmcounter7h); -regh!(0xC88, hpmcounter8h); -regh!(0xC89, hpmcounter9h); -regh!(0xC8A, hpmcounter10h); -regh!(0xC8B, hpmcounter11h); -regh!(0xC8C, hpmcounter12h); -regh!(0xC8D, hpmcounter13h); -regh!(0xC8E, hpmcounter14h); -regh!(0xC8F, hpmcounter15h); -regh!(0xC90, hpmcounter16h); -regh!(0xC91, hpmcounter17h); -regh!(0xC92, hpmcounter18h); -regh!(0xC93, hpmcounter19h); -regh!(0xC94, hpmcounter20h); -regh!(0xC95, hpmcounter21h); -regh!(0xC96, hpmcounter22h); -regh!(0xC97, hpmcounter23h); -regh!(0xC98, hpmcounter24h); -regh!(0xC99, hpmcounter25h); -regh!(0xC9A, hpmcounter26h); -regh!(0xC9B, hpmcounter27h); -regh!(0xC9C, hpmcounter28h); -regh!(0xC9D, hpmcounter29h); -regh!(0xC9E, hpmcounter30h); -regh!(0xC9F, hpmcounter31h); diff --git a/third-party/vendor/riscv/src/register/instret.rs b/third-party/vendor/riscv/src/register/instret.rs deleted file mode 100644 index 95c0b518..00000000 --- a/third-party/vendor/riscv/src/register/instret.rs +++ /dev/null @@ -1,8 +0,0 @@ -//! instret register -//! -//! Shadow of minstret register -//! must have `scounteren::ir` or `mcounteren::ir` bit enabled depending on whether -//! S-mode is implemented or not - -read_csr_as_usize!(0xC02); -read_composite_csr!(super::instreth::read(), read()); diff --git a/third-party/vendor/riscv/src/register/instreth.rs b/third-party/vendor/riscv/src/register/instreth.rs deleted file mode 100644 index 257b6434..00000000 --- a/third-party/vendor/riscv/src/register/instreth.rs +++ /dev/null @@ -1,7 +0,0 @@ -//! instreth register -//! -//! Shadow of minstreth register (rv32) -//! must have `scounteren::ir` or `mcounteren::ir` bit enabled depending on whether -//! S-mode is implemented or not - -read_csr_as_usize!(0xC82); diff --git a/third-party/vendor/riscv/src/register/macros.rs b/third-party/vendor/riscv/src/register/macros.rs deleted file mode 100644 index 24f880f9..00000000 --- a/third-party/vendor/riscv/src/register/macros.rs +++ /dev/null @@ -1,304 +0,0 @@ -macro_rules! read_csr { - ($csr_number:literal) => { - /// Reads the CSR - #[inline] - unsafe fn _read() -> usize { - match () { - #[cfg(riscv)] - () => { - let r: usize; - core::arch::asm!(concat!("csrrs {0}, ", stringify!($csr_number), ", x0"), out(reg) r); - r - } - - #[cfg(not(riscv))] - () => unimplemented!(), - } - } - }; -} - -macro_rules! read_csr_rv32 { - ($csr_number:literal) => { - /// Reads the CSR - #[inline] - unsafe fn _read() -> usize { - match () { - #[cfg(riscv32)] - () => { - let r: usize; - core::arch::asm!(concat!("csrrs {0}, ", stringify!($csr_number), ", x0"), out(reg) r); - r - } - - #[cfg(not(riscv32))] - () => unimplemented!(), - } - } - }; -} - -macro_rules! read_csr_as { - ($register:ident, $csr_number:literal) => { - read_csr!($csr_number); - - /// Reads the CSR - #[inline] - pub fn read() -> $register { - $register { - bits: unsafe { _read() }, - } - } - }; -} - -macro_rules! read_csr_as_rv32 { - ($register:ident, $csr_number:literal) => { - read_csr_rv32!($csr_number); - - /// Reads the CSR - #[inline] - pub fn read() -> $register { - $register { - bits: unsafe { _read() }, - } - } - }; -} - -macro_rules! read_csr_as_usize { - ($csr_number:literal) => { - read_csr!($csr_number); - - /// Reads the CSR - #[inline] - pub fn read() -> usize { - unsafe { _read() } - } - }; -} - -macro_rules! read_csr_as_usize_rv32 { - ($csr_number:literal) => { - read_csr_rv32!($csr_number); - - /// Reads the CSR - #[inline] - pub fn read() -> usize { - unsafe { _read() } - } - }; -} - -macro_rules! write_csr { - ($csr_number:literal) => { - /// Writes the CSR - #[inline] - #[allow(unused_variables)] - unsafe fn _write(bits: usize) { - match () { - #[cfg(riscv)] - () => core::arch::asm!(concat!("csrrw x0, ", stringify!($csr_number), ", {0}"), in(reg) bits), - - #[cfg(not(riscv))] - () => unimplemented!(), - } - } - }; -} - -macro_rules! write_csr_rv32 { - ($csr_number:literal) => { - /// Writes the CSR - #[inline] - #[allow(unused_variables)] - unsafe fn _write(bits: usize) { - match () { - #[cfg(riscv32)] - () => core::arch::asm!(concat!("csrrw x0, ", stringify!($csr_number), ", {0}"), in(reg) bits), - - #[cfg(not(riscv32))] - () => unimplemented!(), - } - } - }; -} - -macro_rules! write_csr_as_usize { - ($csr_number:literal) => { - write_csr!($csr_number); - - /// Writes the CSR - #[inline] - pub fn write(bits: usize) { - unsafe { _write(bits) } - } - }; -} - -macro_rules! write_csr_as_usize_rv32 { - ($csr_number:literal) => { - write_csr_rv32!($csr_number); - - /// Writes the CSR - #[inline] - pub fn write(bits: usize) { - unsafe { _write(bits) } - } - }; -} - -macro_rules! set { - ($csr_number:literal) => { - /// Set the CSR - #[inline] - #[allow(unused_variables)] - unsafe fn _set(bits: usize) { - match () { - #[cfg(riscv)] - () => core::arch::asm!(concat!("csrrs x0, ", stringify!($csr_number), ", {0}"), in(reg) bits), - - #[cfg(not(riscv))] - () => unimplemented!(), - } - } - }; -} - -macro_rules! set_rv32 { - ($csr_number:literal) => { - /// Set the CSR - #[inline] - #[allow(unused_variables)] - unsafe fn _set(bits: usize) { - match () { - #[cfg(riscv32)] - () => core::arch::asm!(concat!("csrrs x0, ", stringify!($csr_number), ", {0}"), in(reg) bits), - - #[cfg(not(riscv32))] - () => unimplemented!(), - } - } - }; -} - -macro_rules! clear { - ($csr_number:literal) => { - /// Clear the CSR - #[inline] - #[allow(unused_variables)] - unsafe fn _clear(bits: usize) { - match () { - #[cfg(riscv)] - () => core::arch::asm!(concat!("csrrc x0, ", stringify!($csr_number), ", {0}"), in(reg) bits), - - #[cfg(not(riscv))] - () => unimplemented!(), - } - } - }; -} - -macro_rules! clear_rv32 { - ($csr_number:literal) => { - /// Clear the CSR - #[inline] - #[allow(unused_variables)] - unsafe fn _clear(bits: usize) { - match () { - #[cfg(riscv32)] - () => core::arch::asm!(concat!("csrrc x0, ", stringify!($csr_number), ", {0}"), in(reg) bits), - - #[cfg(not(riscv32))] - () => unimplemented!(), - } - } - }; -} - -macro_rules! set_csr { - ($(#[$attr:meta])*, $set_field:ident, $e:expr) => { - $(#[$attr])* - #[inline] - pub unsafe fn $set_field() { - _set($e); - } - }; -} - -macro_rules! clear_csr { - ($(#[$attr:meta])*, $clear_field:ident, $e:expr) => { - $(#[$attr])* - #[inline] - pub unsafe fn $clear_field() { - _clear($e); - } - }; -} - -macro_rules! set_clear_csr { - ($(#[$attr:meta])*, $set_field:ident, $clear_field:ident, $e:expr) => { - set_csr!($(#[$attr])*, $set_field, $e); - clear_csr!($(#[$attr])*, $clear_field, $e); - } -} - -macro_rules! read_composite_csr { - ($hi:expr, $lo:expr) => { - /// Reads the CSR as a 64-bit value - #[inline] - pub fn read64() -> u64 { - match () { - #[cfg(riscv32)] - () => loop { - let hi = $hi; - let lo = $lo; - if hi == $hi { - return ((hi as u64) << 32) | lo as u64; - } - }, - - #[cfg(not(riscv32))] - () => $lo as u64, - } - } - }; -} - -macro_rules! set_pmp { - () => { - /// Set the pmp configuration corresponding to the index - #[inline] - pub unsafe fn set_pmp(index: usize, range: Range, permission: Permission, locked: bool) { - #[cfg(riscv32)] - assert!(index < 4); - - #[cfg(riscv64)] - assert!(index < 8); - - let mut value = _read(); - value &= !(0xFF << (8 * index)); // clear previous value - let byte = (locked as usize) << 7 | (range as usize) << 3 | (permission as usize); - value |= byte << (8 * index); - _write(value); - } - }; -} - -macro_rules! clear_pmp { - () => { - /// Clear the pmp configuration corresponding to the index - #[inline] - pub unsafe fn clear_pmp(index: usize) { - #[cfg(riscv32)] - assert!(index < 4); - - #[cfg(riscv64)] - assert!(index < 8); - - let mut value = _read(); - value &= !(0xFF << (8 * index)); // clear previous value - _write(value); - } - }; -} diff --git a/third-party/vendor/riscv/src/register/marchid.rs b/third-party/vendor/riscv/src/register/marchid.rs deleted file mode 100644 index feca296a..00000000 --- a/third-party/vendor/riscv/src/register/marchid.rs +++ /dev/null @@ -1,28 +0,0 @@ -//! marchid register - -use core::num::NonZeroUsize; - -/// marchid register -#[derive(Clone, Copy, Debug)] -pub struct Marchid { - bits: NonZeroUsize, -} - -impl Marchid { - /// Returns the contents of the register as raw bits - #[inline] - pub fn bits(&self) -> usize { - self.bits.get() - } -} - -read_csr!(0xF12); - -/// Reads the CSR -#[inline] -pub fn read() -> Option { - let r = unsafe { _read() }; - // When marchid is hardwired to zero it means that the marchid - // csr isn't implemented. - NonZeroUsize::new(r).map(|bits| Marchid { bits }) -} diff --git a/third-party/vendor/riscv/src/register/mcause.rs b/third-party/vendor/riscv/src/register/mcause.rs deleted file mode 100644 index efe9e6a7..00000000 --- a/third-party/vendor/riscv/src/register/mcause.rs +++ /dev/null @@ -1,148 +0,0 @@ -//! mcause register - -/// mcause register -#[derive(Clone, Copy, Debug)] -pub struct Mcause { - bits: usize, -} - -/// Trap Cause -#[derive(Copy, Clone, Debug, PartialEq, Eq)] -pub enum Trap { - Interrupt(Interrupt), - Exception(Exception), -} - -/// Interrupt -#[derive(Copy, Clone, Debug, PartialEq, Eq)] -#[repr(usize)] -pub enum Interrupt { - SupervisorSoft = 1, - MachineSoft = 3, - SupervisorTimer = 5, - MachineTimer = 7, - SupervisorExternal = 9, - MachineExternal = 11, - Unknown, -} - -/// Exception -#[derive(Copy, Clone, Debug, PartialEq, Eq)] -#[repr(usize)] -pub enum Exception { - InstructionMisaligned = 0, - InstructionFault = 1, - IllegalInstruction = 2, - Breakpoint = 3, - LoadMisaligned = 4, - LoadFault = 5, - StoreMisaligned = 6, - StoreFault = 7, - UserEnvCall = 8, - SupervisorEnvCall = 9, - MachineEnvCall = 11, - InstructionPageFault = 12, - LoadPageFault = 13, - StorePageFault = 15, - Unknown, -} - -impl From for Interrupt { - #[inline] - fn from(nr: usize) -> Self { - match nr { - 1 => Self::SupervisorSoft, - 3 => Self::MachineSoft, - 5 => Self::SupervisorTimer, - 7 => Self::MachineTimer, - 9 => Self::SupervisorExternal, - 11 => Self::MachineExternal, - _ => Self::Unknown, - } - } -} - -impl TryFrom for usize { - type Error = Interrupt; - - #[inline] - fn try_from(value: Interrupt) -> Result { - match value { - Interrupt::Unknown => Err(Self::Error::Unknown), - _ => Ok(value as Self), - } - } -} - -impl From for Exception { - #[inline] - fn from(nr: usize) -> Self { - match nr { - 0 => Self::InstructionMisaligned, - 1 => Self::InstructionFault, - 2 => Self::IllegalInstruction, - 3 => Self::Breakpoint, - 4 => Self::LoadMisaligned, - 5 => Self::LoadFault, - 6 => Self::StoreMisaligned, - 7 => Self::StoreFault, - 8 => Self::UserEnvCall, - 9 => Self::SupervisorEnvCall, - 11 => Self::MachineEnvCall, - 12 => Self::InstructionPageFault, - 13 => Self::LoadPageFault, - 15 => Self::StorePageFault, - _ => Self::Unknown, - } - } -} - -impl TryFrom for usize { - type Error = Exception; - - #[inline] - fn try_from(value: Exception) -> Result { - match value { - Exception::Unknown => Err(Self::Error::Unknown), - _ => Ok(value as Self), - } - } -} - -impl Mcause { - /// Returns the contents of the register as raw bits - #[inline] - pub fn bits(&self) -> usize { - self.bits - } - - /// Returns the code field - #[inline] - pub fn code(&self) -> usize { - self.bits & !(1 << (usize::BITS as usize - 1)) - } - - /// Trap Cause - #[inline] - pub fn cause(&self) -> Trap { - if self.is_interrupt() { - Trap::Interrupt(Interrupt::from(self.code())) - } else { - Trap::Exception(Exception::from(self.code())) - } - } - - /// Is trap cause an interrupt. - #[inline] - pub fn is_interrupt(&self) -> bool { - self.bits & (1 << (usize::BITS as usize - 1)) != 0 - } - - /// Is trap cause an exception. - #[inline] - pub fn is_exception(&self) -> bool { - !self.is_interrupt() - } -} - -read_csr_as!(Mcause, 0x342); diff --git a/third-party/vendor/riscv/src/register/mcounteren.rs b/third-party/vendor/riscv/src/register/mcounteren.rs deleted file mode 100644 index 258155d0..00000000 --- a/third-party/vendor/riscv/src/register/mcounteren.rs +++ /dev/null @@ -1,63 +0,0 @@ -//! mcounteren register - -/// mcounteren register -#[derive(Clone, Copy, Debug)] -pub struct Mcounteren { - bits: usize, -} - -impl Mcounteren { - /// Supervisor "cycle\[h\]" Enable - #[inline] - pub fn cy(&self) -> bool { - self.bits & (1 << 0) != 0 - } - - /// Supervisor "time\[h\]" Enable - #[inline] - pub fn tm(&self) -> bool { - self.bits & (1 << 1) != 0 - } - - /// Supervisor "instret\[h\]" Enable - #[inline] - pub fn ir(&self) -> bool { - self.bits & (1 << 2) != 0 - } - - /// Supervisor "hpm\[x\]" Enable (bits 3-31) - #[inline] - pub fn hpm(&self, index: usize) -> bool { - assert!((3..32).contains(&index)); - self.bits & (1 << index) != 0 - } -} - -read_csr_as!(Mcounteren, 0x306); -write_csr!(0x306); -set!(0x306); -clear!(0x306); - -set_clear_csr!( -/// Supervisor cycle Enable - , set_cy, clear_cy, 1 << 0); - -set_clear_csr!( -/// Supervisor time Enable - , set_tm, clear_tm, 1 << 1); - -set_clear_csr!( -/// Supervisor instret Enable - , set_ir, clear_ir, 1 << 2); - -#[inline] -pub unsafe fn set_hpm(index: usize) { - assert!((3..32).contains(&index)); - _set(1 << index); -} - -#[inline] -pub unsafe fn clear_hpm(index: usize) { - assert!((3..32).contains(&index)); - _clear(1 << index); -} diff --git a/third-party/vendor/riscv/src/register/mcycle.rs b/third-party/vendor/riscv/src/register/mcycle.rs deleted file mode 100644 index 0ab8dfc3..00000000 --- a/third-party/vendor/riscv/src/register/mcycle.rs +++ /dev/null @@ -1,4 +0,0 @@ -//! mcycle register - -read_csr_as_usize!(0xB00); -read_composite_csr!(super::mcycleh::read(), read()); diff --git a/third-party/vendor/riscv/src/register/mcycleh.rs b/third-party/vendor/riscv/src/register/mcycleh.rs deleted file mode 100644 index 31ca70cb..00000000 --- a/third-party/vendor/riscv/src/register/mcycleh.rs +++ /dev/null @@ -1,3 +0,0 @@ -//! mcycleh register - -read_csr_as_usize_rv32!(0xB80); diff --git a/third-party/vendor/riscv/src/register/medeleg.rs b/third-party/vendor/riscv/src/register/medeleg.rs deleted file mode 100644 index 81de5baa..00000000 --- a/third-party/vendor/riscv/src/register/medeleg.rs +++ /dev/null @@ -1,137 +0,0 @@ -//! medeleg register - -/// medeleg register -#[derive(Clone, Copy, Debug)] -pub struct Medeleg { - bits: usize, -} - -impl Medeleg { - /// Returns the contents of the register as raw bits - #[inline] - pub fn bits(&self) -> usize { - self.bits - } - - /// Instruction Address Misaligned Delegate - #[inline] - pub fn instruction_misaligned(&self) -> bool { - self.bits & (1 << 0) != 0 - } - - /// Instruction Access Fault Delegate - #[inline] - pub fn instruction_fault(&self) -> bool { - self.bits & (1 << 1) != 0 - } - - /// Illegal Instruction Delegate - #[inline] - pub fn illegal_instruction(&self) -> bool { - self.bits & (1 << 2) != 0 - } - - /// Breakpoint Delegate - #[inline] - pub fn breakpoint(&self) -> bool { - self.bits & (1 << 3) != 0 - } - - /// Load Address Misaligned Delegate - #[inline] - pub fn load_misaligned(&self) -> bool { - self.bits & (1 << 4) != 0 - } - - /// Load Access Fault Delegate - #[inline] - pub fn load_fault(&self) -> bool { - self.bits & (1 << 5) != 0 - } - - /// Store/AMO Address Misaligned Delegate - #[inline] - pub fn store_misaligned(&self) -> bool { - self.bits & (1 << 6) != 0 - } - - /// Store/AMO Access Fault Delegate - #[inline] - pub fn store_fault(&self) -> bool { - self.bits & (1 << 7) != 0 - } - - /// Environment Call from U-mode Delegate - #[inline] - pub fn user_env_call(&self) -> bool { - self.bits & (1 << 8) != 0 - } - - /// Environment Call from S-mode Delegate - #[inline] - pub fn supervisor_env_call(&self) -> bool { - self.bits & (1 << 9) != 0 - } - - /// Instruction Page Fault Delegate - #[inline] - pub fn instruction_page_fault(&self) -> bool { - self.bits & (1 << 12) != 0 - } - - /// Load Page Fault Delegate - #[inline] - pub fn load_page_fault(&self) -> bool { - self.bits & (1 << 13) != 0 - } - - /// Store/AMO Page Fault Delegate - #[inline] - pub fn store_page_fault(&self) -> bool { - self.bits & (1 << 15) != 0 - } -} - -read_csr_as!(Medeleg, 0x302); -set!(0x302); -clear!(0x302); - -set_clear_csr!( - /// Instruction Address Misaligned Delegate - , set_instruction_misaligned, clear_instruction_misaligned, 1 << 0); -set_clear_csr!( - /// Instruction Access Fault Delegate - , set_instruction_fault, clear_instruction_fault, 1 << 1); -set_clear_csr!( - /// Illegal Instruction Delegate - , set_illegal_instruction, clear_illegal_instruction, 1 << 2); -set_clear_csr!( - /// Breakpoint Delegate - , set_breakpoint, clear_breakpoint, 1 << 3); -set_clear_csr!( - /// Load Address Misaligned Delegate - , set_load_misaligned, clear_load_misaligned, 1 << 4); -set_clear_csr!( - /// Load Access Fault Delegate - , set_load_fault, clear_load_fault, 1 << 5); -set_clear_csr!( - /// Store/AMO Address Misaligned Delegate - , set_store_misaligned, clear_store_misaligned, 1 << 6); -set_clear_csr!( - /// Store/AMO Access fault - , set_store_fault, clear_store_fault, 1 << 7); -set_clear_csr!( - /// Environment Call from U-mode Delegate - , set_user_env_call, clear_user_env_call, 1 << 8); -set_clear_csr!( - /// Environment Call from S-mode Delegate - , set_supervisor_env_call, clear_supervisor_env_call, 1 << 9); -set_clear_csr!( - /// Instruction Page Fault Delegate - , set_instruction_page_fault, clear_instruction_page_fault, 1 << 12); -set_clear_csr!( - /// Load Page Fault Delegate - , set_load_page_fault, clear_load_page_fault, 1 << 13); -set_clear_csr!( - /// Store/AMO Page Fault Delegate - , set_store_page_fault, clear_store_page_fault, 1 << 15); diff --git a/third-party/vendor/riscv/src/register/mepc.rs b/third-party/vendor/riscv/src/register/mepc.rs deleted file mode 100644 index 4fc80d4c..00000000 --- a/third-party/vendor/riscv/src/register/mepc.rs +++ /dev/null @@ -1,4 +0,0 @@ -//! mepc register - -read_csr_as_usize!(0x341); -write_csr_as_usize!(0x341); diff --git a/third-party/vendor/riscv/src/register/mhartid.rs b/third-party/vendor/riscv/src/register/mhartid.rs deleted file mode 100644 index 0ff96a0f..00000000 --- a/third-party/vendor/riscv/src/register/mhartid.rs +++ /dev/null @@ -1,3 +0,0 @@ -//! mhartid register - -read_csr_as_usize!(0xf14); diff --git a/third-party/vendor/riscv/src/register/mhpmcounterx.rs b/third-party/vendor/riscv/src/register/mhpmcounterx.rs deleted file mode 100644 index e4c1b01f..00000000 --- a/third-party/vendor/riscv/src/register/mhpmcounterx.rs +++ /dev/null @@ -1,84 +0,0 @@ -macro_rules! reg { - ( - $addr:expr, $csrl:ident, $csrh:ident - ) => { - /// Machine performance-monitoring counter - pub mod $csrl { - read_csr_as_usize!($addr); - write_csr_as_usize!($addr); - read_composite_csr!(super::$csrh::read(), read()); - } - }; -} - -macro_rules! regh { - ( - $addr:expr, $csrh:ident - ) => { - /// Upper 32 bits of machine performance-monitoring counter (RV32I only) - pub mod $csrh { - read_csr_as_usize_rv32!($addr); - write_csr_as_usize_rv32!($addr); - } - }; -} - -reg!(0xB03, mhpmcounter3, mhpmcounter3h); -reg!(0xB04, mhpmcounter4, mhpmcounter4h); -reg!(0xB05, mhpmcounter5, mhpmcounter5h); -reg!(0xB06, mhpmcounter6, mhpmcounter6h); -reg!(0xB07, mhpmcounter7, mhpmcounter7h); -reg!(0xB08, mhpmcounter8, mhpmcounter8h); -reg!(0xB09, mhpmcounter9, mhpmcounter9h); -reg!(0xB0A, mhpmcounter10, mhpmcounter10h); -reg!(0xB0B, mhpmcounter11, mhpmcounter11h); -reg!(0xB0C, mhpmcounter12, mhpmcounter12h); -reg!(0xB0D, mhpmcounter13, mhpmcounter13h); -reg!(0xB0E, mhpmcounter14, mhpmcounter14h); -reg!(0xB0F, mhpmcounter15, mhpmcounter15h); -reg!(0xB10, mhpmcounter16, mhpmcounter16h); -reg!(0xB11, mhpmcounter17, mhpmcounter17h); -reg!(0xB12, mhpmcounter18, mhpmcounter18h); -reg!(0xB13, mhpmcounter19, mhpmcounter19h); -reg!(0xB14, mhpmcounter20, mhpmcounter20h); -reg!(0xB15, mhpmcounter21, mhpmcounter21h); -reg!(0xB16, mhpmcounter22, mhpmcounter22h); -reg!(0xB17, mhpmcounter23, mhpmcounter23h); -reg!(0xB18, mhpmcounter24, mhpmcounter24h); -reg!(0xB19, mhpmcounter25, mhpmcounter25h); -reg!(0xB1A, mhpmcounter26, mhpmcounter26h); -reg!(0xB1B, mhpmcounter27, mhpmcounter27h); -reg!(0xB1C, mhpmcounter28, mhpmcounter28h); -reg!(0xB1D, mhpmcounter29, mhpmcounter29h); -reg!(0xB1E, mhpmcounter30, mhpmcounter30h); -reg!(0xB1F, mhpmcounter31, mhpmcounter31h); - -regh!(0xB83, mhpmcounter3h); -regh!(0xB84, mhpmcounter4h); -regh!(0xB85, mhpmcounter5h); -regh!(0xB86, mhpmcounter6h); -regh!(0xB87, mhpmcounter7h); -regh!(0xB88, mhpmcounter8h); -regh!(0xB89, mhpmcounter9h); -regh!(0xB8A, mhpmcounter10h); -regh!(0xB8B, mhpmcounter11h); -regh!(0xB8C, mhpmcounter12h); -regh!(0xB8D, mhpmcounter13h); -regh!(0xB8E, mhpmcounter14h); -regh!(0xB8F, mhpmcounter15h); -regh!(0xB90, mhpmcounter16h); -regh!(0xB91, mhpmcounter17h); -regh!(0xB92, mhpmcounter18h); -regh!(0xB93, mhpmcounter19h); -regh!(0xB94, mhpmcounter20h); -regh!(0xB95, mhpmcounter21h); -regh!(0xB96, mhpmcounter22h); -regh!(0xB97, mhpmcounter23h); -regh!(0xB98, mhpmcounter24h); -regh!(0xB99, mhpmcounter25h); -regh!(0xB9A, mhpmcounter26h); -regh!(0xB9B, mhpmcounter27h); -regh!(0xB9C, mhpmcounter28h); -regh!(0xB9D, mhpmcounter29h); -regh!(0xB9E, mhpmcounter30h); -regh!(0xB9F, mhpmcounter31h); diff --git a/third-party/vendor/riscv/src/register/mhpmeventx.rs b/third-party/vendor/riscv/src/register/mhpmeventx.rs deleted file mode 100644 index 93ed7a54..00000000 --- a/third-party/vendor/riscv/src/register/mhpmeventx.rs +++ /dev/null @@ -1,41 +0,0 @@ -macro_rules! reg { - ( - $addr:expr, $csr:ident - ) => { - /// Machine performance-monitoring event selector - pub mod $csr { - read_csr_as_usize!($addr); - write_csr_as_usize!($addr); - } - }; -} - -reg!(0x323, mhpmevent3); -reg!(0x324, mhpmevent4); -reg!(0x325, mhpmevent5); -reg!(0x326, mhpmevent6); -reg!(0x327, mhpmevent7); -reg!(0x328, mhpmevent8); -reg!(0x329, mhpmevent9); -reg!(0x32A, mhpmevent10); -reg!(0x32B, mhpmevent11); -reg!(0x32C, mhpmevent12); -reg!(0x32D, mhpmevent13); -reg!(0x32E, mhpmevent14); -reg!(0x32F, mhpmevent15); -reg!(0x330, mhpmevent16); -reg!(0x331, mhpmevent17); -reg!(0x332, mhpmevent18); -reg!(0x333, mhpmevent19); -reg!(0x334, mhpmevent20); -reg!(0x335, mhpmevent21); -reg!(0x336, mhpmevent22); -reg!(0x337, mhpmevent23); -reg!(0x338, mhpmevent24); -reg!(0x339, mhpmevent25); -reg!(0x33A, mhpmevent26); -reg!(0x33B, mhpmevent27); -reg!(0x33C, mhpmevent28); -reg!(0x33D, mhpmevent29); -reg!(0x33E, mhpmevent30); -reg!(0x33F, mhpmevent31); diff --git a/third-party/vendor/riscv/src/register/mideleg.rs b/third-party/vendor/riscv/src/register/mideleg.rs deleted file mode 100644 index 85200c26..00000000 --- a/third-party/vendor/riscv/src/register/mideleg.rs +++ /dev/null @@ -1,47 +0,0 @@ -//! mideleg register - -/// mideleg register -#[derive(Clone, Copy, Debug)] -pub struct Mideleg { - bits: usize, -} - -impl Mideleg { - /// Returns the contents of the register as raw bits - #[inline] - pub fn bits(&self) -> usize { - self.bits - } - - /// Supervisor Software Interrupt Delegate - #[inline] - pub fn ssoft(&self) -> bool { - self.bits & (1 << 1) != 0 - } - - /// Supervisor Timer Interrupt Delegate - #[inline] - pub fn stimer(&self) -> bool { - self.bits & (1 << 5) != 0 - } - - /// Supervisor External Interrupt Delegate - #[inline] - pub fn sext(&self) -> bool { - self.bits & (1 << 9) != 0 - } -} - -read_csr_as!(Mideleg, 0x303); -set!(0x303); -clear!(0x303); - -set_clear_csr!( - /// Supervisor Software Interrupt Delegate - , set_ssoft, clear_ssoft, 1 << 1); -set_clear_csr!( - /// Supervisor Timer Interrupt Delegate - , set_stimer, clear_stimer, 1 << 5); -set_clear_csr!( - /// Supervisor External Interrupt Delegate - , set_sext, clear_sext, 1 << 9); diff --git a/third-party/vendor/riscv/src/register/mie.rs b/third-party/vendor/riscv/src/register/mie.rs deleted file mode 100644 index d2afb447..00000000 --- a/third-party/vendor/riscv/src/register/mie.rs +++ /dev/null @@ -1,74 +0,0 @@ -//! mie register - -/// mie register -#[derive(Clone, Copy, Debug)] -pub struct Mie { - bits: usize, -} - -impl Mie { - /// Returns the contents of the register as raw bits - #[inline] - pub fn bits(&self) -> usize { - self.bits - } - - /// Supervisor Software Interrupt Enable - #[inline] - pub fn ssoft(&self) -> bool { - self.bits & (1 << 1) != 0 - } - - /// Machine Software Interrupt Enable - #[inline] - pub fn msoft(&self) -> bool { - self.bits & (1 << 3) != 0 - } - - /// Supervisor Timer Interrupt Enable - #[inline] - pub fn stimer(&self) -> bool { - self.bits & (1 << 5) != 0 - } - - /// Machine Timer Interrupt Enable - #[inline] - pub fn mtimer(&self) -> bool { - self.bits & (1 << 7) != 0 - } - - /// Supervisor External Interrupt Enable - #[inline] - pub fn sext(&self) -> bool { - self.bits & (1 << 9) != 0 - } - - /// Machine External Interrupt Enable - #[inline] - pub fn mext(&self) -> bool { - self.bits & (1 << 11) != 0 - } -} - -read_csr_as!(Mie, 0x304); -set!(0x304); -clear!(0x304); - -set_clear_csr!( - /// Supervisor Software Interrupt Enable - , set_ssoft, clear_ssoft, 1 << 1); -set_clear_csr!( - /// Machine Software Interrupt Enable - , set_msoft, clear_msoft, 1 << 3); -set_clear_csr!( - /// Supervisor Timer Interrupt Enable - , set_stimer, clear_stimer, 1 << 5); -set_clear_csr!( - /// Machine Timer Interrupt Enable - , set_mtimer, clear_mtimer, 1 << 7); -set_clear_csr!( - /// Supervisor External Interrupt Enable - , set_sext, clear_sext, 1 << 9); -set_clear_csr!( - /// Machine External Interrupt Enable - , set_mext, clear_mext, 1 << 11); diff --git a/third-party/vendor/riscv/src/register/mimpid.rs b/third-party/vendor/riscv/src/register/mimpid.rs deleted file mode 100644 index b7610ff7..00000000 --- a/third-party/vendor/riscv/src/register/mimpid.rs +++ /dev/null @@ -1,28 +0,0 @@ -//! mimpid register - -use core::num::NonZeroUsize; - -/// mimpid register -#[derive(Clone, Copy, Debug)] -pub struct Mimpid { - bits: NonZeroUsize, -} - -impl Mimpid { - /// Returns the contents of the register as raw bits - #[inline] - pub fn bits(&self) -> usize { - self.bits.get() - } -} - -read_csr!(0xF13); - -/// Reads the CSR -#[inline] -pub fn read() -> Option { - let r = unsafe { _read() }; - // When mimpid is hardwired to zero it means that the mimpid - // csr isn't implemented. - NonZeroUsize::new(r).map(|bits| Mimpid { bits }) -} diff --git a/third-party/vendor/riscv/src/register/minstret.rs b/third-party/vendor/riscv/src/register/minstret.rs deleted file mode 100644 index 17ba0d6b..00000000 --- a/third-party/vendor/riscv/src/register/minstret.rs +++ /dev/null @@ -1,4 +0,0 @@ -//! minstret register - -read_csr_as_usize!(0xB02); -read_composite_csr!(super::minstreth::read(), read()); diff --git a/third-party/vendor/riscv/src/register/minstreth.rs b/third-party/vendor/riscv/src/register/minstreth.rs deleted file mode 100644 index 5548399f..00000000 --- a/third-party/vendor/riscv/src/register/minstreth.rs +++ /dev/null @@ -1,3 +0,0 @@ -//! minstreth register - -read_csr_as_usize_rv32!(0xB82); diff --git a/third-party/vendor/riscv/src/register/mip.rs b/third-party/vendor/riscv/src/register/mip.rs deleted file mode 100644 index b5d22580..00000000 --- a/third-party/vendor/riscv/src/register/mip.rs +++ /dev/null @@ -1,65 +0,0 @@ -//! mip register - -/// mip register -#[derive(Clone, Copy, Debug)] -pub struct Mip { - bits: usize, -} - -impl Mip { - /// Returns the contents of the register as raw bits - #[inline] - pub fn bits(&self) -> usize { - self.bits - } - - /// Supervisor Software Interrupt Pending - #[inline] - pub fn ssoft(&self) -> bool { - self.bits & (1 << 1) != 0 - } - - /// Machine Software Interrupt Pending - #[inline] - pub fn msoft(&self) -> bool { - self.bits & (1 << 3) != 0 - } - - /// Supervisor Timer Interrupt Pending - #[inline] - pub fn stimer(&self) -> bool { - self.bits & (1 << 5) != 0 - } - - /// Machine Timer Interrupt Pending - #[inline] - pub fn mtimer(&self) -> bool { - self.bits & (1 << 7) != 0 - } - - /// Supervisor External Interrupt Pending - #[inline] - pub fn sext(&self) -> bool { - self.bits & (1 << 9) != 0 - } - - /// Machine External Interrupt Pending - #[inline] - pub fn mext(&self) -> bool { - self.bits & (1 << 11) != 0 - } -} - -read_csr_as!(Mip, 0x344); -set!(0x344); -clear!(0x344); - -set_clear_csr!( - /// Supervisor Software Interrupt Pending - , set_ssoft, clear_ssoft, 1 << 1); -set_clear_csr!( - /// Supervisor Timer Interrupt Pending - , set_stimer, clear_stimer, 1 << 5); -set_clear_csr!( - /// Supervisor External Interrupt Pending - , set_sext, clear_sext, 1 << 9); diff --git a/third-party/vendor/riscv/src/register/misa.rs b/third-party/vendor/riscv/src/register/misa.rs deleted file mode 100644 index db2cbc96..00000000 --- a/third-party/vendor/riscv/src/register/misa.rs +++ /dev/null @@ -1,72 +0,0 @@ -//! misa register - -use core::num::NonZeroUsize; - -/// misa register -#[derive(Clone, Copy, Debug)] -pub struct Misa { - bits: NonZeroUsize, -} - -/// Base integer ISA width -#[derive(Copy, Clone, Debug, Eq, PartialEq)] -pub enum XLEN { - XLEN32, - XLEN64, - XLEN128, -} - -impl XLEN { - /// Converts a number into an ISA width - pub(crate) fn from(value: u8) -> Self { - match value { - 1 => XLEN::XLEN32, - 2 => XLEN::XLEN64, - 3 => XLEN::XLEN128, - _ => unreachable!(), - } - } -} - -impl Misa { - /// Returns the contents of the register as raw bits - #[inline] - pub fn bits(&self) -> usize { - self.bits.get() - } - - /// Effective xlen in M-mode (i.e., `MXLEN`). - #[inline] - pub fn mxl(&self) -> XLEN { - let value = (self.bits() >> (usize::BITS - 2)) as u8; - XLEN::from(value) - } - - /// Returns true when a given extension is implemented. - /// - /// # Example - /// - /// ```no_run - /// let misa = unsafe { riscv::register::misa::read() }.unwrap(); - /// assert!(misa.has_extension('A')); // panics if atomic extension is not implemented - /// ``` - #[inline] - pub fn has_extension(&self, extension: char) -> bool { - let bit = extension as u8 - 65; - if bit > 25 { - return false; - } - self.bits() & (1 << bit) == (1 << bit) - } -} - -read_csr!(0x301); - -/// Reads the CSR -#[inline] -pub fn read() -> Option { - let r = unsafe { _read() }; - // When misa is hardwired to zero it means that the misa csr - // isn't implemented. - NonZeroUsize::new(r).map(|bits| Misa { bits }) -} diff --git a/third-party/vendor/riscv/src/register/mscratch.rs b/third-party/vendor/riscv/src/register/mscratch.rs deleted file mode 100644 index f6c6f96a..00000000 --- a/third-party/vendor/riscv/src/register/mscratch.rs +++ /dev/null @@ -1,4 +0,0 @@ -//! mscratch register - -read_csr_as_usize!(0x340); -write_csr_as_usize!(0x340); diff --git a/third-party/vendor/riscv/src/register/mstatus.rs b/third-party/vendor/riscv/src/register/mstatus.rs deleted file mode 100644 index 4f225ac2..00000000 --- a/third-party/vendor/riscv/src/register/mstatus.rs +++ /dev/null @@ -1,373 +0,0 @@ -//! mstatus register - -pub use super::misa::XLEN; - -/// mstatus register -#[derive(Clone, Copy, Debug)] -pub struct Mstatus { - bits: usize, -} - -/// Additional extension state -#[derive(Copy, Clone, Debug, Eq, PartialEq)] -pub enum XS { - /// All off - AllOff = 0, - - /// None dirty or clean, some on - NoneDirtyOrClean = 1, - - /// None dirty, some clean - NoneDirtySomeClean = 2, - - /// Some dirty - SomeDirty = 3, -} - -/// Floating-point extension state -#[derive(Copy, Clone, Debug, Eq, PartialEq)] -pub enum FS { - Off = 0, - Initial = 1, - Clean = 2, - Dirty = 3, -} - -/// Machine Previous Privilege Mode -#[derive(Copy, Clone, Debug, Eq, PartialEq)] -pub enum MPP { - Machine = 3, - Supervisor = 1, - User = 0, -} - -/// Supervisor Previous Privilege Mode -#[derive(Copy, Clone, Debug, Eq, PartialEq)] -pub enum SPP { - Supervisor = 1, - User = 0, -} - -/// Non-instruction-fetch memory endianness -#[derive(Copy, Clone, Debug, Eq, PartialEq)] -pub enum Endianness { - BigEndian = 1, - LittleEndian = 0, -} - -impl From for Endianness { - fn from(value: bool) -> Self { - match value { - true => Self::BigEndian, - false => Self::LittleEndian, - } - } -} - -impl Mstatus { - /// Supervisor Interrupt Enable - #[inline] - pub fn sie(&self) -> bool { - self.bits & (1 << 1) != 0 - } - - /// Machine Interrupt Enable - #[inline] - pub fn mie(&self) -> bool { - self.bits & (1 << 3) != 0 - } - - /// Supervisor Previous Interrupt Enable - #[inline] - pub fn spie(&self) -> bool { - self.bits & (1 << 5) != 0 - } - - /// U-mode non-instruction-fetch memory endianness - #[inline] - pub fn ube(&self) -> Endianness { - Endianness::from(self.bits & (1 << 6) != 0) - } - - /// Machine Previous Interrupt Enable - #[inline] - pub fn mpie(&self) -> bool { - self.bits & (1 << 7) != 0 - } - - /// Supervisor Previous Privilege Mode - #[inline] - pub fn spp(&self) -> SPP { - match self.bits & (1 << 8) != 0 { - true => SPP::Supervisor, - false => SPP::User, - } - } - - /// Machine Previous Privilege Mode - #[inline] - pub fn mpp(&self) -> MPP { - let mpp = (self.bits >> 11) & 0x3; // bits 11-12 - match mpp { - 0b00 => MPP::User, - 0b01 => MPP::Supervisor, - 0b11 => MPP::Machine, - _ => unreachable!(), - } - } - - /// Floating-point extension state - /// - /// Encodes the status of the floating-point unit, - /// including the CSR `fcsr` and floating-point data registers `f0–f31`. - #[inline] - pub fn fs(&self) -> FS { - let fs = (self.bits >> 13) & 0x3; // bits 13-14 - match fs { - 0b00 => FS::Off, - 0b01 => FS::Initial, - 0b10 => FS::Clean, - 0b11 => FS::Dirty, - _ => unreachable!(), - } - } - - /// Additional extension state - /// - /// Encodes the status of additional user-mode extensions and associated state. - #[inline] - pub fn xs(&self) -> XS { - let xs = (self.bits >> 15) & 0x3; // bits 15-16 - match xs { - 0b00 => XS::AllOff, - 0b01 => XS::NoneDirtyOrClean, - 0b10 => XS::NoneDirtySomeClean, - 0b11 => XS::SomeDirty, - _ => unreachable!(), - } - } - - /// Modify Memory PRiVilege - #[inline] - pub fn mprv(&self) -> bool { - self.bits & (1 << 17) != 0 - } - - /// Permit Supervisor User Memory access - #[inline] - pub fn sum(&self) -> bool { - self.bits & (1 << 18) != 0 - } - - /// Make eXecutable Readable - #[inline] - pub fn mxr(&self) -> bool { - self.bits & (1 << 19) != 0 - } - - /// Trap Virtual Memory - /// - /// If this bit is set, reads or writes to `satp` CSR or execute `sfence.vma` - /// instruction when in S-mode will raise an illegal instruction exception. - /// - /// TVM is hard-wired to 0 when S-mode is not supported. - #[inline] - pub fn tvm(&self) -> bool { - self.bits & (1 << 20) != 0 - } - - /// Timeout Wait - /// - /// Indicates that if WFI instruction should be intercepted. - /// - /// If this bit is set, when WFI is executed in S-mode, and it does not complete - /// within an implementation specific, bounded time limit, the WFI instruction will cause - /// an illegal instruction trap; or could always cause trap then the time limit is zero. - /// - /// TW is hard-wired to 0 when S-mode is not supported. - #[inline] - pub fn tw(&self) -> bool { - self.bits & (1 << 21) != 0 - } - - /// Trap SRET - /// - /// Indicates that if SRET instruction should be trapped to raise illegal - /// instruction exception. - /// - /// If S-mode is not supported, TSR bit is hard-wired to 0. - #[inline] - pub fn tsr(&self) -> bool { - self.bits & (1 << 22) != 0 - } - - /// Effective xlen in U-mode (i.e., `UXLEN`). - /// - /// In RISCV-32, UXL does not exist, and `UXLEN` is always [`XLEN::XLEN32`]. - #[inline] - pub fn uxl(&self) -> XLEN { - match () { - #[cfg(riscv32)] - () => XLEN::XLEN32, - #[cfg(not(riscv32))] - () => XLEN::from((self.bits >> 32) as u8 & 0x3), - } - } - - /// Effective xlen in S-mode (i.e., `SXLEN`). - /// - /// In RISCV-32, SXL does not exist, and SXLEN is always [`XLEN::XLEN32`]. - #[inline] - pub fn sxl(&self) -> XLEN { - match () { - #[cfg(riscv32)] - () => XLEN::XLEN32, - #[cfg(not(riscv32))] - () => XLEN::from((self.bits >> 34) as u8 & 0x3), - } - } - - /// S-mode non-instruction-fetch memory endianness. - /// - /// In RISCV-32, this field is read from the [`crate::register::mstatush`] register. - pub fn sbe(&self) -> Endianness { - match () { - #[cfg(riscv32)] - () => super::mstatush::read().sbe(), - #[cfg(not(riscv32))] - () => Endianness::from(self.bits & (1 << 36) != 0), - } - } - - /// M-mode non-instruction-fetch memory endianness - /// - /// In RISCV-32, this field is read from the [`crate::register::mstatush`] register - pub fn mbe(&self) -> Endianness { - match () { - #[cfg(riscv32)] - () => super::mstatush::read().mbe(), - #[cfg(not(riscv32))] - () => Endianness::from(self.bits & (1 << 37) != 0), - } - } - - /// Whether either the FS field or XS field signals the presence of some dirty state - #[inline] - pub fn sd(&self) -> bool { - self.bits & (1 << (usize::BITS as usize - 1)) != 0 - } -} - -read_csr_as!(Mstatus, 0x300); -write_csr!(0x300); -set!(0x300); -clear!(0x300); - -set_clear_csr!( - /// User Interrupt Enable - , set_uie, clear_uie, 1 << 0); -set_clear_csr!( - /// Supervisor Interrupt Enable - , set_sie, clear_sie, 1 << 1); -set_clear_csr!( - /// Machine Interrupt Enable - , set_mie, clear_mie, 1 << 3); -set_csr!( - /// User Previous Interrupt Enable - , set_upie, 1 << 4); -set_csr!( - /// Supervisor Previous Interrupt Enable - , set_spie, 1 << 5); -set_csr!( - /// Machine Previous Interrupt Enable - , set_mpie, 1 << 7); -set_clear_csr!( - /// Modify Memory PRiVilege - , set_mprv, clear_mprv, 1 << 17); -set_clear_csr!( - /// Permit Supervisor User Memory access - , set_sum, clear_sum, 1 << 18); -set_clear_csr!( - /// Make eXecutable Readable - , set_mxr, clear_mxr, 1 << 19); -set_clear_csr!( - /// Trap Virtual Memory - , set_tvm, clear_tvm, 1 << 20); -set_clear_csr!( - /// Timeout Wait - , set_tw, clear_tw, 1 << 21); -set_clear_csr!( - /// Trap SRET - , set_tsr, clear_tsr, 1 << 22); - -/// Set U-mode non-instruction-fetch memory endianness -#[inline] -pub unsafe fn set_ube(endianness: Endianness) { - match endianness { - Endianness::BigEndian => _set(1 << 6), - Endianness::LittleEndian => _clear(1 << 6), - } -} - -/// Supervisor Previous Privilege Mode -#[inline] -pub unsafe fn set_spp(spp: SPP) { - match spp { - SPP::Supervisor => _set(1 << 8), - SPP::User => _clear(1 << 8), - } -} - -/// Machine Previous Privilege Mode -#[inline] -pub unsafe fn set_mpp(mpp: MPP) { - let mut value = _read(); - value &= !(0x3 << 11); // clear previous value - value |= (mpp as usize) << 11; - _write(value); -} - -/// Floating-point extension state -#[inline] -pub unsafe fn set_fs(fs: FS) { - let mut value = _read(); - value &= !(0x3 << 13); // clear previous value - value |= (fs as usize) << 13; - _write(value); -} - -/// Set S-mode non-instruction-fetch memory endianness -/// -/// # Note -/// -/// In RISCV-32, this function calls [`crate::register::mstatush::set_sbe`] -#[inline] -pub unsafe fn set_sbe(endianness: Endianness) { - match () { - #[cfg(riscv32)] - () => super::mstatush::set_sbe(endianness), - #[cfg(not(riscv32))] - () => match endianness { - Endianness::BigEndian => _set(1 << 36), - Endianness::LittleEndian => _clear(1 << 36), - }, - } -} - -/// Set M-mode non-instruction-fetch memory endianness -/// -/// # Note -/// -/// In RISCV-32, this function calls [`crate::register::mstatush::set_mbe`] -#[inline] -pub unsafe fn set_mbe(endianness: Endianness) { - match () { - #[cfg(riscv32)] - () => super::mstatush::set_mbe(endianness), - #[cfg(not(riscv32))] - () => match endianness { - Endianness::BigEndian => _set(1 << 37), - Endianness::LittleEndian => _clear(1 << 37), - }, - } -} diff --git a/third-party/vendor/riscv/src/register/mstatush.rs b/third-party/vendor/riscv/src/register/mstatush.rs deleted file mode 100644 index 5fbab3b8..00000000 --- a/third-party/vendor/riscv/src/register/mstatush.rs +++ /dev/null @@ -1,46 +0,0 @@ -//! mstatush register (RISCV-32 only) - -pub use super::mstatus::Endianness; - -/// mstatus register -#[derive(Clone, Copy, Debug)] -pub struct Mstatush { - bits: usize, -} - -impl Mstatush { - /// S-mode non-instruction-fetch memory endianness - #[inline] - pub fn sbe(&self) -> Endianness { - Endianness::from(self.bits & (1 << 4) != 0) - } - - /// M-mode non-instruction-fetch memory endianness - #[inline] - pub fn mbe(&self) -> Endianness { - Endianness::from(self.bits & (1 << 5) != 0) - } -} - -read_csr_as_rv32!(Mstatush, 0x310); -write_csr_rv32!(0x310); -set_rv32!(0x310); -clear_rv32!(0x310); - -/// Set S-mode non-instruction-fetch memory endianness -#[inline] -pub unsafe fn set_sbe(endianness: Endianness) { - match endianness { - Endianness::BigEndian => _set(1 << 4), - Endianness::LittleEndian => _clear(1 << 4), - } -} - -/// Set M-mode non-instruction-fetch memory endianness -#[inline] -pub unsafe fn set_mbe(endianness: Endianness) { - match endianness { - Endianness::BigEndian => _set(1 << 5), - Endianness::LittleEndian => _clear(1 << 5), - } -} diff --git a/third-party/vendor/riscv/src/register/mtval.rs b/third-party/vendor/riscv/src/register/mtval.rs deleted file mode 100644 index 291aef5a..00000000 --- a/third-party/vendor/riscv/src/register/mtval.rs +++ /dev/null @@ -1,3 +0,0 @@ -//! mtval register - -read_csr_as_usize!(0x343); diff --git a/third-party/vendor/riscv/src/register/mtvec.rs b/third-party/vendor/riscv/src/register/mtvec.rs deleted file mode 100644 index cc77011e..00000000 --- a/third-party/vendor/riscv/src/register/mtvec.rs +++ /dev/null @@ -1,50 +0,0 @@ -//! mtvec register - -/// mtvec register -#[derive(Clone, Copy, Debug)] -pub struct Mtvec { - bits: usize, -} - -/// Trap mode -#[derive(Copy, Clone, Debug, Eq, PartialEq)] -pub enum TrapMode { - Direct = 0, - Vectored = 1, -} - -impl Mtvec { - /// Returns the contents of the register as raw bits - #[inline] - pub fn bits(&self) -> usize { - self.bits - } - - /// Returns the trap-vector base-address - #[inline] - pub fn address(&self) -> usize { - self.bits - (self.bits & 0b11) - } - - /// Returns the trap-vector mode - #[inline] - pub fn trap_mode(&self) -> Option { - let mode = self.bits & 0b11; - match mode { - 0 => Some(TrapMode::Direct), - 1 => Some(TrapMode::Vectored), - _ => None, - } - } -} - -read_csr_as!(Mtvec, 0x305); - -write_csr!(0x305); - -/// Writes the CSR -#[inline] -pub unsafe fn write(addr: usize, mode: TrapMode) { - let bits = addr + mode as usize; - _write(bits); -} diff --git a/third-party/vendor/riscv/src/register/mvendorid.rs b/third-party/vendor/riscv/src/register/mvendorid.rs deleted file mode 100644 index 5c621478..00000000 --- a/third-party/vendor/riscv/src/register/mvendorid.rs +++ /dev/null @@ -1,34 +0,0 @@ -//! mvendorid register - -use core::num::NonZeroUsize; - -/// mvendorid register -#[derive(Clone, Copy, Debug)] -pub struct Mvendorid { - bits: NonZeroUsize, -} - -impl Mvendorid { - /// Returns the contents of the register as raw bits - #[inline] - pub fn bits(&self) -> usize { - self.bits.get() - } - - /// Returns the JEDEC manufacturer ID - #[inline] - pub fn jedec_manufacturer(&self) -> usize { - self.bits() >> 7 - } -} - -read_csr!(0xF11); - -/// Reads the CSR -#[inline] -pub fn read() -> Option { - let r = unsafe { _read() }; - // When mvendorid is hardwired to zero it means that the mvendorid - // csr isn't implemented. - NonZeroUsize::new(r).map(|bits| Mvendorid { bits }) -} diff --git a/third-party/vendor/riscv/src/register/pmpaddrx.rs b/third-party/vendor/riscv/src/register/pmpaddrx.rs deleted file mode 100644 index 2431ef0b..00000000 --- a/third-party/vendor/riscv/src/register/pmpaddrx.rs +++ /dev/null @@ -1,28 +0,0 @@ -macro_rules! reg { - ( - $addr:expr, $csr:ident - ) => { - /// Physical memory protection address register - pub mod $csr { - read_csr_as_usize!($addr); - write_csr_as_usize!($addr); - } - }; -} - -reg!(0x3B0, pmpaddr0); -reg!(0x3B1, pmpaddr1); -reg!(0x3B2, pmpaddr2); -reg!(0x3B3, pmpaddr3); -reg!(0x3B4, pmpaddr4); -reg!(0x3B5, pmpaddr5); -reg!(0x3B6, pmpaddr6); -reg!(0x3B7, pmpaddr7); -reg!(0x3B8, pmpaddr8); -reg!(0x3B9, pmpaddr9); -reg!(0x3BA, pmpaddr10); -reg!(0x3BB, pmpaddr11); -reg!(0x3BC, pmpaddr12); -reg!(0x3BD, pmpaddr13); -reg!(0x3BE, pmpaddr14); -reg!(0x3BF, pmpaddr15); diff --git a/third-party/vendor/riscv/src/register/pmpcfgx.rs b/third-party/vendor/riscv/src/register/pmpcfgx.rs deleted file mode 100644 index 211c275d..00000000 --- a/third-party/vendor/riscv/src/register/pmpcfgx.rs +++ /dev/null @@ -1,129 +0,0 @@ -//! Physical memory protection configuration - -/// Permission enum contains all possible permission modes for pmp registers -#[derive(Clone, Copy, Debug)] -pub enum Permission { - NONE = 0b000, - R = 0b001, - W = 0b010, - RW = 0b011, - X = 0b100, - RX = 0b101, - WX = 0b110, - RWX = 0b111, -} - -/// Range enum contains all possible addressing modes for pmp registers -#[derive(Clone, Copy, Debug)] -pub enum Range { - OFF = 0b00, - TOR = 0b01, - NA4 = 0b10, - NAPOT = 0b11, -} - -/// Pmp struct holds a high-level representation of a single pmp configuration -#[derive(Clone, Copy, Debug)] -pub struct Pmp { - /// raw bits - pub byte: u8, - /// Current PMP Permission - pub permission: Permission, - /// Current PMP Range - pub range: Range, - /// Is PMP locked? - pub locked: bool, -} - -pub struct Pmpcsr { - /// Holds the raw contents of a PMP CSR Register - pub bits: usize, -} - -impl Pmpcsr { - /// Take the register contents and translate into a Pmp configuration struct - #[inline] - pub fn into_config(&self, index: usize) -> Pmp { - #[cfg(riscv32)] - assert!(index < 4); - - #[cfg(riscv64)] - assert!(index < 8); - - let byte = (self.bits >> (8 * index)) as u8; // move config to LSB and drop the rest - let permission = byte & 0x7; // bits 0-2 - let range = (byte >> 3) & 0x3; // bits 3-4 - Pmp { - byte, - permission: match permission { - 0 => Permission::NONE, - 1 => Permission::R, - 2 => Permission::W, - 3 => Permission::RW, - 4 => Permission::X, - 5 => Permission::RX, - 6 => Permission::WX, - 7 => Permission::RWX, - _ => unreachable!(), - }, - range: match range { - 0 => Range::OFF, - 1 => Range::TOR, - 2 => Range::NA4, - 3 => Range::NAPOT, - _ => unreachable!(), - }, - locked: (byte & (1 << 7)) != 0, - } - } -} - -/// Physical memory protection configuration -/// pmpcfg0 struct contains pmp0cfg - pmp3cfg for RV32, and pmp0cfg - pmp7cfg for RV64 -pub mod pmpcfg0 { - use super::{Permission, Pmpcsr, Range}; - - read_csr_as!(Pmpcsr, 0x3A0); - write_csr_as_usize!(0x3A0); - - set_pmp!(); - clear_pmp!(); -} - -/// Physical memory protection configuration -/// pmpcfg1 struct contains pmp4cfg - pmp7cfg for RV32 only -#[cfg(riscv32)] -pub mod pmpcfg1 { - use super::{Permission, Pmpcsr, Range}; - - read_csr_as!(Pmpcsr, 0x3A1); - write_csr_as_usize_rv32!(0x3A1); - - set_pmp!(); - clear_pmp!(); -} - -/// Physical memory protection configuration -/// pmpcfg2 struct contains pmp8cfg - pmp11cfg for RV32, or pmp8cfg - pmp15cfg for RV64 -pub mod pmpcfg2 { - use super::{Permission, Pmpcsr, Range}; - - read_csr_as!(Pmpcsr, 0x3A2); - write_csr_as_usize!(0x3A2); - - set_pmp!(); - clear_pmp!(); -} - -/// Physical memory protection configuration -/// pmpcfg3 struct contains pmp12cfg - pmp15cfg for RV32 only -#[cfg(riscv32)] -pub mod pmpcfg3 { - use super::{Permission, Pmpcsr, Range}; - - read_csr_as!(Pmpcsr, 0x3A3); - write_csr_as_usize_rv32!(0x3A3); - - set_pmp!(); - clear_pmp!(); -} diff --git a/third-party/vendor/riscv/src/register/satp.rs b/third-party/vendor/riscv/src/register/satp.rs deleted file mode 100644 index c23041fa..00000000 --- a/third-party/vendor/riscv/src/register/satp.rs +++ /dev/null @@ -1,116 +0,0 @@ -//! satp register - -/// satp register -#[derive(Clone, Copy, Debug)] -pub struct Satp { - bits: usize, -} - -impl Satp { - /// Returns the contents of the register as raw bits - #[inline] - pub fn bits(&self) -> usize { - self.bits - } - - /// Current address-translation scheme - #[inline] - #[cfg(target_pointer_width = "32")] - pub fn mode(&self) -> Mode { - match self.bits & (1 << 31) != 0 { - false => Mode::Bare, - true => Mode::Sv32, - } - } - - /// Current address-translation scheme - #[inline] - #[cfg(target_pointer_width = "64")] - pub fn mode(&self) -> Mode { - match self.bits >> 60 { - 0 => Mode::Bare, - 8 => Mode::Sv39, - 9 => Mode::Sv48, - 10 => Mode::Sv57, - 11 => Mode::Sv64, - _ => unreachable!(), - } - } - - /// Address space identifier - #[inline] - #[cfg(target_pointer_width = "32")] - pub fn asid(&self) -> usize { - (self.bits >> 22) & 0x1FF // bits 22-30 - } - - /// Address space identifier - #[inline] - #[cfg(target_pointer_width = "64")] - pub fn asid(&self) -> usize { - self.bits >> 44 & 0xFFFF // bits 44-59 - } - - /// Physical page number - #[inline] - #[cfg(target_pointer_width = "32")] - pub fn ppn(&self) -> usize { - self.bits & 0x3F_FFFF // bits 0-21 - } - - /// Physical page number - #[inline] - #[cfg(target_pointer_width = "64")] - pub fn ppn(&self) -> usize { - self.bits & 0xFFF_FFFF_FFFF // bits 0-43 - } -} - -/// 32-bit satp mode -#[cfg(target_pointer_width = "32")] -#[derive(Clone, Copy, Debug, Eq, PartialEq)] -pub enum Mode { - /// No translation or protection - Bare = 0, - /// Page-based 32-bit virtual addressing - Sv32 = 1, -} - -/// 64-bit satp mode -#[cfg(target_pointer_width = "64")] -#[derive(Clone, Copy, Debug, Eq, PartialEq)] -pub enum Mode { - /// No translation or protection - Bare = 0, - /// Page-based 39-bit virtual addressing - Sv39 = 8, - /// Page-based 48-bit virtual addressing - Sv48 = 9, - /// Page-based 57-bit virtual addressing - Sv57 = 10, - /// Page-based 64-bit virtual addressing - Sv64 = 11, -} - -read_csr_as!(Satp, 0x180); -write_csr_as_usize!(0x180); - -/// Sets the register to corresponding page table mode, physical page number and address space id. -#[inline] -#[cfg(target_pointer_width = "32")] -pub unsafe fn set(mode: Mode, asid: usize, ppn: usize) { - assert_eq!(asid, asid & 0x1FF, "invalid value for asid"); - assert_eq!(ppn, ppn & 0x3F_FFFF, "invalid value for ppn"); - let bits = (mode as usize) << 31 | (asid << 22) | ppn; - _write(bits); -} - -/// Sets the register to corresponding page table mode, physical page number and address space id. -#[inline] -#[cfg(target_pointer_width = "64")] -pub unsafe fn set(mode: Mode, asid: usize, ppn: usize) { - assert_eq!(asid, asid & 0xFFFF, "invalid value for asid"); - assert_eq!(ppn, ppn & 0xFFF_FFFF_FFFF, "invalid value for ppn"); - let bits = (mode as usize) << 60 | (asid << 44) | ppn; - _write(bits); -} diff --git a/third-party/vendor/riscv/src/register/scause.rs b/third-party/vendor/riscv/src/register/scause.rs deleted file mode 100644 index 79fa1b9e..00000000 --- a/third-party/vendor/riscv/src/register/scause.rs +++ /dev/null @@ -1,160 +0,0 @@ -//! scause register - -/// scause register -#[derive(Clone, Copy)] -pub struct Scause { - bits: usize, -} - -/// Trap Cause -#[derive(Copy, Clone, Debug, Eq, PartialEq)] -pub enum Trap { - Interrupt(Interrupt), - Exception(Exception), -} - -/// Interrupt -#[derive(Copy, Clone, Debug, Eq, PartialEq)] -#[repr(usize)] -pub enum Interrupt { - SupervisorSoft = 1, - SupervisorTimer = 5, - SupervisorExternal = 9, - Unknown, -} - -/// Exception -#[derive(Copy, Clone, Debug, Eq, PartialEq)] -#[repr(usize)] -pub enum Exception { - InstructionMisaligned = 0, - InstructionFault = 1, - IllegalInstruction = 2, - Breakpoint = 3, - LoadMisaligned = 4, - LoadFault = 5, - StoreMisaligned = 6, - StoreFault = 7, - UserEnvCall = 8, - SupervisorEnvCall = 9, - InstructionPageFault = 12, - LoadPageFault = 13, - StorePageFault = 15, - Unknown, -} - -impl From for Interrupt { - #[inline] - fn from(nr: usize) -> Self { - match nr { - 1 => Self::SupervisorSoft, - 5 => Self::SupervisorTimer, - 9 => Self::SupervisorExternal, - _ => Self::Unknown, - } - } -} - -impl TryFrom for usize { - type Error = Interrupt; - - #[inline] - fn try_from(value: Interrupt) -> Result { - match value { - Interrupt::Unknown => Err(Self::Error::Unknown), - _ => Ok(value as Self), - } - } -} - -impl From for Exception { - #[inline] - fn from(nr: usize) -> Self { - match nr { - 0 => Self::InstructionMisaligned, - 1 => Self::InstructionFault, - 2 => Self::IllegalInstruction, - 3 => Self::Breakpoint, - 4 => Self::LoadMisaligned, - 5 => Self::LoadFault, - 6 => Self::StoreMisaligned, - 7 => Self::StoreFault, - 8 => Self::UserEnvCall, - 9 => Self::SupervisorEnvCall, - 12 => Self::InstructionPageFault, - 13 => Self::LoadPageFault, - 15 => Self::StorePageFault, - _ => Self::Unknown, - } - } -} - -impl TryFrom for usize { - type Error = Exception; - - #[inline] - fn try_from(value: Exception) -> Result { - match value { - Exception::Unknown => Err(Self::Error::Unknown), - _ => Ok(value as Self), - } - } -} - -impl Scause { - /// Returns the contents of the register as raw bits - #[inline] - pub fn bits(&self) -> usize { - self.bits - } - - /// Returns the code field - #[inline] - pub fn code(&self) -> usize { - self.bits & !(1 << (usize::BITS as usize - 1)) - } - - /// Trap Cause - #[inline] - pub fn cause(&self) -> Trap { - if self.is_interrupt() { - Trap::Interrupt(Interrupt::from(self.code())) - } else { - Trap::Exception(Exception::from(self.code())) - } - } - - /// Is trap cause an interrupt. - #[inline] - pub fn is_interrupt(&self) -> bool { - self.bits & (1 << (usize::BITS as usize - 1)) != 0 - } - - /// Is trap cause an exception. - #[inline] - pub fn is_exception(&self) -> bool { - !self.is_interrupt() - } -} - -read_csr_as!(Scause, 0x142); -write_csr!(0x142); - -/// Writes the CSR -#[inline] -pub unsafe fn write(bits: usize) { - _write(bits) -} - -/// Set supervisor cause register to corresponding cause. -#[inline] -pub unsafe fn set(cause: Trap) { - let bits = match cause { - Trap::Interrupt(i) => { - let i = usize::try_from(i).expect("unknown interrupt"); - i | (1 << (usize::BITS as usize - 1)) // interrupt bit is 1 - } - Trap::Exception(e) => usize::try_from(e).expect("unknown exception"), - }; - _write(bits); -} diff --git a/third-party/vendor/riscv/src/register/scounteren.rs b/third-party/vendor/riscv/src/register/scounteren.rs deleted file mode 100644 index 5242734b..00000000 --- a/third-party/vendor/riscv/src/register/scounteren.rs +++ /dev/null @@ -1,63 +0,0 @@ -//! scounteren register - -/// scounteren register -#[derive(Clone, Copy, Debug)] -pub struct Scounteren { - bits: usize, -} - -impl Scounteren { - /// User "cycle\[h\]" Enable - #[inline] - pub fn cy(&self) -> bool { - self.bits & (1 << 0) != 0 - } - - /// User "time\[h\]" Enable - #[inline] - pub fn tm(&self) -> bool { - self.bits & (1 << 1) != 0 - } - - /// User "instret\[h]\" Enable - #[inline] - pub fn ir(&self) -> bool { - self.bits & (1 << 2) != 0 - } - - /// User "hpm\[x\]" Enable (bits 3-31) - #[inline] - pub fn hpm(&self, index: usize) -> bool { - assert!((3..32).contains(&index)); - self.bits & (1 << index) != 0 - } -} - -read_csr_as!(Scounteren, 0x106); -write_csr!(0x106); -set!(0x106); -clear!(0x106); - -set_clear_csr!( -/// User cycle Enable - , set_cy, clear_cy, 1 << 0); - -set_clear_csr!( -/// User time Enable - , set_tm, clear_tm, 1 << 1); - -set_clear_csr!( -/// User instret Enable - , set_ir, clear_ir, 1 << 2); - -#[inline] -pub unsafe fn set_hpm(index: usize) { - assert!((3..32).contains(&index)); - _set(1 << index); -} - -#[inline] -pub unsafe fn clear_hpm(index: usize) { - assert!((3..32).contains(&index)); - _clear(1 << index); -} diff --git a/third-party/vendor/riscv/src/register/sepc.rs b/third-party/vendor/riscv/src/register/sepc.rs deleted file mode 100644 index a39d1bdb..00000000 --- a/third-party/vendor/riscv/src/register/sepc.rs +++ /dev/null @@ -1,4 +0,0 @@ -//! sepc register - -read_csr_as_usize!(0x141); -write_csr_as_usize!(0x141); diff --git a/third-party/vendor/riscv/src/register/sie.rs b/third-party/vendor/riscv/src/register/sie.rs deleted file mode 100644 index d6662740..00000000 --- a/third-party/vendor/riscv/src/register/sie.rs +++ /dev/null @@ -1,47 +0,0 @@ -//! sie register - -/// sie register -#[derive(Clone, Copy, Debug)] -pub struct Sie { - bits: usize, -} - -impl Sie { - /// Returns the contents of the register as raw bits - #[inline] - pub fn bits(&self) -> usize { - self.bits - } - - /// Supervisor Software Interrupt Enable - #[inline] - pub fn ssoft(&self) -> bool { - self.bits & (1 << 1) != 0 - } - - /// Supervisor Timer Interrupt Enable - #[inline] - pub fn stimer(&self) -> bool { - self.bits & (1 << 5) != 0 - } - - /// Supervisor External Interrupt Enable - #[inline] - pub fn sext(&self) -> bool { - self.bits & (1 << 9) != 0 - } -} - -read_csr_as!(Sie, 0x104); -set!(0x104); -clear!(0x104); - -set_clear_csr!( - /// Supervisor Software Interrupt Enable - , set_ssoft, clear_ssoft, 1 << 1); -set_clear_csr!( - /// Supervisor Timer Interrupt Enable - , set_stimer, clear_stimer, 1 << 5); -set_clear_csr!( - /// Supervisor External Interrupt Enable - , set_sext, clear_sext, 1 << 9); diff --git a/third-party/vendor/riscv/src/register/sip.rs b/third-party/vendor/riscv/src/register/sip.rs deleted file mode 100644 index 715abc39..00000000 --- a/third-party/vendor/riscv/src/register/sip.rs +++ /dev/null @@ -1,41 +0,0 @@ -//! sip register - -/// sip register -#[derive(Clone, Copy, Debug)] -pub struct Sip { - bits: usize, -} - -impl Sip { - /// Returns the contents of the register as raw bits - #[inline] - pub fn bits(&self) -> usize { - self.bits - } - - /// Supervisor Software Interrupt Pending - #[inline] - pub fn ssoft(&self) -> bool { - self.bits & (1 << 1) != 0 - } - - /// Supervisor Timer Interrupt Pending - #[inline] - pub fn stimer(&self) -> bool { - self.bits & (1 << 5) != 0 - } - - /// Supervisor External Interrupt Pending - #[inline] - pub fn sext(&self) -> bool { - self.bits & (1 << 9) != 0 - } -} - -read_csr_as!(Sip, 0x144); -set!(0x344); -clear!(0x104); - -set_clear_csr!( - /// Supervisor Software Interrupt Pending - , set_ssoft, clear_ssoft, 1 << 1); diff --git a/third-party/vendor/riscv/src/register/sscratch.rs b/third-party/vendor/riscv/src/register/sscratch.rs deleted file mode 100644 index d910d6e5..00000000 --- a/third-party/vendor/riscv/src/register/sscratch.rs +++ /dev/null @@ -1,4 +0,0 @@ -//! sscratch register - -read_csr_as_usize!(0x140); -write_csr_as_usize!(0x140); diff --git a/third-party/vendor/riscv/src/register/sstatus.rs b/third-party/vendor/riscv/src/register/sstatus.rs deleted file mode 100644 index 81a25fbf..00000000 --- a/third-party/vendor/riscv/src/register/sstatus.rs +++ /dev/null @@ -1,141 +0,0 @@ -//! sstatus register - -pub use super::misa::XLEN; -pub use super::mstatus::FS; - -/// Supervisor Status Register -#[derive(Clone, Copy, Debug)] -pub struct Sstatus { - bits: usize, -} - -/// Supervisor Previous Privilege Mode -#[derive(Copy, Clone, Debug, Eq, PartialEq)] -pub enum SPP { - Supervisor = 1, - User = 0, -} - -impl Sstatus { - /// Supervisor Interrupt Enable - #[inline] - pub fn sie(&self) -> bool { - self.bits & (1 << 1) != 0 - } - - /// Supervisor Previous Interrupt Enable - #[inline] - pub fn spie(&self) -> bool { - self.bits & (1 << 5) != 0 - } - - /// Supervisor Previous Privilege Mode - #[inline] - pub fn spp(&self) -> SPP { - match self.bits & (1 << 8) != 0 { - true => SPP::Supervisor, - false => SPP::User, - } - } - - /// The status of the floating-point unit - #[inline] - pub fn fs(&self) -> FS { - let fs = (self.bits >> 13) & 0x3; // bits 13-14 - match fs { - 0 => FS::Off, - 1 => FS::Initial, - 2 => FS::Clean, - 3 => FS::Dirty, - _ => unreachable!(), - } - } - - /// The status of additional user-mode extensions - /// and associated state - #[inline] - pub fn xs(&self) -> FS { - let xs = (self.bits >> 15) & 0x3; // bits 15-16 - match xs { - 0 => FS::Off, - 1 => FS::Initial, - 2 => FS::Clean, - 3 => FS::Dirty, - _ => unreachable!(), - } - } - - /// Permit Supervisor User Memory access - #[inline] - pub fn sum(&self) -> bool { - self.bits & (1 << 18) != 0 - } - - /// Make eXecutable Readable - #[inline] - pub fn mxr(&self) -> bool { - self.bits & (1 << 19) != 0 - } - - /// Effective xlen in U-mode (i.e., `UXLEN`). - /// - /// In RISCV-32, UXL does not exist, and `UXLEN` is always [`XLEN::XLEN32`]. - #[inline] - pub fn uxl(&self) -> XLEN { - match () { - #[cfg(riscv32)] - () => XLEN::XLEN32, - #[cfg(not(riscv32))] - () => XLEN::from((self.bits >> 32) as u8 & 0x3), - } - } - - /// Whether either the FS field or XS field - /// signals the presence of some dirty state - #[inline] - pub fn sd(&self) -> bool { - self.bits & (1 << (usize::BITS as usize - 1)) != 0 - } -} - -read_csr_as!(Sstatus, 0x100); -write_csr!(0x100); -set!(0x100); -clear!(0x100); - -set_clear_csr!( - /// User Interrupt Enable - , set_uie, clear_uie, 1 << 0); -set_clear_csr!( - /// Supervisor Interrupt Enable - , set_sie, clear_sie, 1 << 1); -set_csr!( - /// User Previous Interrupt Enable - , set_upie, 1 << 4); -set_csr!( - /// Supervisor Previous Interrupt Enable - , set_spie, 1 << 5); -set_clear_csr!( - /// Permit Supervisor User Memory access - , set_sum, clear_sum, 1 << 18); -set_clear_csr!( - /// Make eXecutable Readable - , set_mxr, clear_mxr, 1 << 19); - -/// Supervisor Previous Privilege Mode -#[inline] -pub unsafe fn set_spp(spp: SPP) { - match spp { - SPP::Supervisor => _set(1 << 8), - SPP::User => _clear(1 << 8), - } -} - -/// The status of the floating-point unit -#[inline] -pub unsafe fn set_fs(fs: FS) { - let mut value = _read(); - value &= !(0x3 << 13); // clear previous value - value |= (fs as usize) << 13; - _write(value); -} diff --git a/third-party/vendor/riscv/src/register/stval.rs b/third-party/vendor/riscv/src/register/stval.rs deleted file mode 100644 index c330d183..00000000 --- a/third-party/vendor/riscv/src/register/stval.rs +++ /dev/null @@ -1,10 +0,0 @@ -//! stval register - -read_csr_as_usize!(0x143); -write_csr!(0x143); - -/// Writes the CSR -#[inline] -pub unsafe fn write(bits: usize) { - _write(bits) -} diff --git a/third-party/vendor/riscv/src/register/stvec.rs b/third-party/vendor/riscv/src/register/stvec.rs deleted file mode 100644 index f9bd06fd..00000000 --- a/third-party/vendor/riscv/src/register/stvec.rs +++ /dev/null @@ -1,43 +0,0 @@ -//! stvec register - -pub use crate::register::mtvec::TrapMode; - -/// stvec register -#[derive(Clone, Copy, Debug)] -pub struct Stvec { - bits: usize, -} - -impl Stvec { - /// Returns the contents of the register as raw bits - #[inline] - pub fn bits(&self) -> usize { - self.bits - } - - /// Returns the trap-vector base-address - #[inline] - pub fn address(&self) -> usize { - self.bits - (self.bits & 0b11) - } - - /// Returns the trap-vector mode - #[inline] - pub fn trap_mode(&self) -> Option { - let mode = self.bits & 0b11; - match mode { - 0 => Some(TrapMode::Direct), - 1 => Some(TrapMode::Vectored), - _ => None, - } - } -} - -read_csr_as!(Stvec, 0x105); -write_csr!(0x105); - -/// Writes the CSR -#[inline] -pub unsafe fn write(addr: usize, mode: TrapMode) { - _write(addr + mode as usize); -} diff --git a/third-party/vendor/riscv/src/register/time.rs b/third-party/vendor/riscv/src/register/time.rs deleted file mode 100644 index ad5e8bbf..00000000 --- a/third-party/vendor/riscv/src/register/time.rs +++ /dev/null @@ -1,4 +0,0 @@ -//! time register - -read_csr_as_usize!(0xC01); -read_composite_csr!(super::timeh::read(), read()); diff --git a/third-party/vendor/riscv/src/register/timeh.rs b/third-party/vendor/riscv/src/register/timeh.rs deleted file mode 100644 index 884c9ab3..00000000 --- a/third-party/vendor/riscv/src/register/timeh.rs +++ /dev/null @@ -1,3 +0,0 @@ -//! timeh register - -read_csr_as_usize_rv32!(0xC81); diff --git a/third-party/vendor/sbi-rt/.cargo-checksum.json b/third-party/vendor/sbi-rt/.cargo-checksum.json deleted file mode 100644 index acef6404..00000000 --- a/third-party/vendor/sbi-rt/.cargo-checksum.json +++ /dev/null @@ -1 +0,0 @@ -{"files":{"CHANGELOG.md":"36ced3c1f62e1176563f3543e27104b207c47db4e647c74f9eb125ae52357129","Cargo.toml":"2d80048b719c0e0faf4b490e509c2de957b3fe7bdb959692e26026e1d82a7923","LICENSE-MIT":"dbe70a478d73778735f3b16fceb7877536b8f827290872ccddd597f3e9f49a9a","LICENSE-MULAN":"483224ec3915ccee80b46f27ae736553c1194aa58194ab98dee08496f21b98d9","README.md":"c7ec848898020c24b26313f788fa13025ebc519312893248bfa812f320fb1f8a","README_EN.md":"5594720cd0b3325093b3d886387918cfbd39fd8cff7f7762a1f9a001fdd4c0b5","src/base.rs":"fa80230a0a6769d6edddf9adb83ae24c8e48bc10e49a3ef62369d91377dc5919","src/binary.rs":"d722d047e1790ea82efe3c88727c3c46d3dcfdb7ea4c5f8c317a386bf1ca8747","src/cppc.rs":"413da8f2f24d39e915676ce916f91f4ad764845a357beadc88412c8aacf4437e","src/dbcn.rs":"c9b633afd1a6db0bda698e4930b4d88c6a1d403565d7fd0d08e3e29a00be163a","src/hsm.rs":"58e5cff1dbfa44980ea7b30ca6b5e39ef0702f5fb3268889257d40133adf60f5","src/legacy.rs":"0b3c7117ce718db2d7c7ef43f82e5dd6ff8f02ee1d6b2734faf8f42f593abf68","src/lib.rs":"71180a301e55a3e9f103cc031447165da6bd223e7bc16b3ee3ee7859f4d551bd","src/nacl.rs":"ace579303d1c270f080c722342feae9582cfc38141ede18febe8ecda4f7db73a","src/pmu.rs":"7801da847fe1253701a2a627614265d98b89d05fc62f7608ca99fa6e4f138570","src/rfnc.rs":"deacbbedf65e656ebedd2ce10ecfb1cdef0110e5d2bb30f135c3a22ba8055dd8","src/spi.rs":"ea50a1123ee759cd301f99422e628a8b2f31744dda533b46d642f533a1ef7491","src/srst.rs":"4aeb37ac13107fe6e428dc0204dc751335f2bd6a6a7819a406e3b2aef42f923c","src/sta.rs":"d5eca5456d37ec6695a06d56ca23c6662f0aa64d06ecda727a23bd725b43e53f","src/susp.rs":"6069285050c252ba680c5855de231cbfde47c4ccc50b6a047fe892990a58a63f","src/time.rs":"1756c328fe53cecef02f6fd4087c6e0123594ed9272233b9d908899a4972a160"},"package":"7fbaa69be1eedc61c426e6d489b2260482e928b465360576900d52d496a58bd0"} \ No newline at end of file diff --git a/third-party/vendor/sbi-rt/CHANGELOG.md b/third-party/vendor/sbi-rt/CHANGELOG.md deleted file mode 100644 index 1a69632f..00000000 --- a/third-party/vendor/sbi-rt/CHANGELOG.md +++ /dev/null @@ -1,54 +0,0 @@ -# Changelog - -All notable changes to this project will be documented in this file. - -The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres -to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). - -## [Unreleased] - -## [0.0.3] - 2024-02-08 - -This version adds support to the RISC-V SBI Specification version 2.0 ratified. - -### Added - -- Debug Console extension support -- `pmu_counter_fw_read_hi` in PMU extension -- Support for SBI CPPC extension -- Support for NACL and STA extensions -- Re-export `HartMask`, `Physical`, `SbiRet` and `SharedPtr` on `sbi-rt` library root - -### Modified - -- SPI and RFNC extensions now use `HartMask` parameter - -### Fixed - -- Minor document fixes on `ConfigFlags` and `set_timer` -- Document fixes on the HSM extension from SBI 2.0 -- Extension ID of the Nacl and Sta extensions. - -## [0.0.2] - 2022-10-10 - -In this version, we changed API style to trait-based type parameters, which would make it easier to -check parameter types at runtime to reduce errors. -If user chooses to use `integer-impls` feature, it would fall back to older style functions using integer types. - -### Added - -- Trait-based type parameter for all extensions -- Feature `integer-impls` to allow fast prototyping with sbi-rt crate -- Feature `legacy` to gate the SBI legacy extension -- Documents on various functions - -### Modified - -- Update `sbi-spec` to version 0.0.4, re-export `Version` structure -- Function `probe_extension` now returns an `ExtensionInfo` value -- Function `pmu_num_counters` returns a `usize` value - -[Unreleased]: https://github.com/rustsbi/sbi-rt/compare/v0.0.3...HEAD -[0.0.3]: https://github.com/rustsbi/sbi-rt/compare/v0.0.2...v0.0.3 -[0.0.2]: https://github.com/rustsbi/sbi-rt/compare/v0.0.1...v0.0.2 -[0.0.1]: https://github.com/rustsbi/sbi-rt/releases/tag/v0.0.1 diff --git a/third-party/vendor/sbi-rt/Cargo.toml b/third-party/vendor/sbi-rt/Cargo.toml deleted file mode 100644 index 2ec50d72..00000000 --- a/third-party/vendor/sbi-rt/Cargo.toml +++ /dev/null @@ -1,50 +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 are reading this file be aware that the original Cargo.toml -# will likely look very different (and much more reasonable). -# See Cargo.toml.orig for the original contents. - -[package] -edition = "2021" -name = "sbi-rt" -version = "0.0.3" -authors = [ - "YdrMaster ", - "Luo Jia ", -] -description = "Runtime library for supervisors to call RISC-V Supervisor Binary Interface (RISC-V SBI)" -documentation = "https://docs.rs/sbi-rt" -readme = "README.md" -keywords = [ - "riscv", - "sbi", - "rustsbi", -] -categories = [ - "os", - "embedded", - "hardware-support", - "no-std", -] -license = "MulanPSL-2.0 OR MIT" -repository = "https://github.com/rustsbi/rustsbi" - -[package.metadata.docs.rs] -default-target = "riscv64imac-unknown-none-elf" -targets = [ - "riscv32imac-unknown-none-elf", - "riscv64imac-unknown-none-elf", -] - -[dependencies.sbi-spec] -version = "0.0.7" - -[features] -default = [] -integer-impls = [] -legacy = ["sbi-spec/legacy"] diff --git a/third-party/vendor/sbi-rt/LICENSE-MIT b/third-party/vendor/sbi-rt/LICENSE-MIT deleted file mode 100644 index 36adedf3..00000000 --- a/third-party/vendor/sbi-rt/LICENSE-MIT +++ /dev/null @@ -1,9 +0,0 @@ -The MIT License (MIT) - -Copyright © 2022 YdrMaster - -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. diff --git a/third-party/vendor/sbi-rt/LICENSE-MULAN b/third-party/vendor/sbi-rt/LICENSE-MULAN deleted file mode 100644 index c480e52d..00000000 --- a/third-party/vendor/sbi-rt/LICENSE-MULAN +++ /dev/null @@ -1,101 +0,0 @@ -木兰宽松许可证, 第2版 - -2020年1月 - -您对“软件”的复制、使用、修改及分发受木兰宽松许可证,第2版(“本许可证”)的如下条款的约束: - -0. 定义 - -“软件”是指由“贡献”构成的许可在“本许可证”下的程序和相关文档的集合。 - -“贡献”是指由任一“贡献者”许可在“本许可证”下的受版权法保护的作品。 - -“贡献者”是指将受版权法保护的作品许可在“本许可证”下的自然人或“法人实体”。 - -“法人实体”是指提交贡献的机构及其“关联实体”。 - -“关联实体”是指,对“本许可证”下的行为方而言,控制、受控制或与其共同受控制的机构,此处的控制是指有受控方或共同受控方至少50%直接或间接的投票权、资金或其他有价证券。 - -1. 授予版权许可 - -每个“贡献者”根据“本许可证”授予您永久性的、全球性的、免费的、非独占的、不可撤销的版权许可,您可以复制、使用、修改、分发其“贡献”,不论修改与否。 - -2. 授予专利许可 - -每个“贡献者”根据“本许可证”授予您永久性的、全球性的、免费的、非独占的、不可撤销的(根据本条规定撤销除外)专利许可,供您制造、委托制造、使用、许诺销售、销售、进口其“贡献”或以其他方式转移其“贡献”。前述专利许可仅限于“贡献者”现在或将来拥有或控制的其“贡献”本身或其“贡献”与许可“贡献”时的“软件”结合而将必然会侵犯的专利权利要求,不包括对“贡献”的修改或包含“贡献”的其他结合。如果您或您的“关联实体”直接或间接地,就“软件”或其中的“贡献”对任何人发起专利侵权诉讼(包括反诉或交叉诉讼)或其他专利维权行动,指控其侵犯专利权,则“本许可证”授予您对“软件”的专利许可自您提起诉讼或发起维权行动之日终止。 - -3. 无商标许可 - -“本许可证”不提供对“贡献者”的商品名称、商标、服务标志或产品名称的商标许可,但您为满足第4条规定的声明义务而必须使用除外。 - -4. 分发限制 - -您可以在任何媒介中将“软件”以源程序形式或可执行形式重新分发,不论修改与否,但您必须向接收者提供“本许可证”的副本,并保留“软件”中的版权、商标、专利及免责声明。 - -5. 免责声明与责任限制 - -“软件”及其中的“贡献”在提供时不带任何明示或默示的担保。在任何情况下,“贡献者”或版权所有者不对任何人因使用“软件”或其中的“贡献”而引发的任何直接或间接损失承担责任,不论因何种原因导致或者基于何种法律理论,即使其曾被建议有此种损失的可能性。 - -6. 语言 - -“本许可证”以中英文双语表述,中英文版本具有同等法律效力。如果中英文版本存在任何冲突不一致,以中文版为准。 - -条款结束 - -如何将木兰宽松许可证,第2版,应用到您的软件 - -如果您希望将木兰宽松许可证,第2版,应用到您的新软件,为了方便接收者查阅,建议您完成如下三步: - -1,请您补充如下声明中的空白,包括软件名、软件的首次发表年份以及您作为版权人的名字; - -2,请您在软件包的一级目录下创建以“LICENSE”为名的文件,将整个许可证文本放入该文件中; - -3,请将如下声明文本放入每个源文件的头部注释中。 - -Copyright (c) 2020 Luo Jia - -RustSBI is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: - -THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. See the Mulan PSL v2 for more details. - -January 2020 - -Your reproduction, use, modification and distribution of the Software shall be subject to Mulan PSL v2 (this License) with the following terms and conditions: - -0. Definition - -Software means the program and related documents which are licensed under this License and comprise all Contribution(s). - -Contribution means the copyrightable work licensed by a particular Contributor under this License. - -Contributor means the Individual or Legal Entity who licenses its copyrightable work under this License. - -Legal Entity means the entity making a Contribution and all its Affiliates. - -Affiliates means entities that control, are controlled by, or are under common control with the acting entity under this License, ‘control’ means direct or indirect ownership of at least fifty percent (50%) of the voting power, capital or other securities of controlled or commonly controlled entity. - -1. Grant of Copyright License - -Subject to the terms and conditions of this License, each Contributor hereby grants to you a perpetual, worldwide, royalty-free, non-exclusive, irrevocable copyright license to reproduce, use, modify, or distribute its Contribution, with modification or not. - -2. Grant of Patent License - -Subject to the terms and conditions of this License, each Contributor hereby grants to you a perpetual, worldwide, royalty-free, non-exclusive, irrevocable (except for revocation under this Section) patent license to make, have made, use, offer for sale, sell, import or otherwise transfer its Contribution, where such patent license is only limited to the patent claims owned or controlled by such Contributor now or in future which will be necessarily infringed by its Contribution alone, or by combination of the Contribution with the Software to which the Contribution was contributed. The patent license shall not apply to any modification of the Contribution, and any other combination which includes the Contribution. If you or your Affiliates directly or indirectly institute patent litigation (including a cross claim or counterclaim in a litigation) or other patent enforcement activities against any individual or entity by alleging that the Software or any Contribution in it infringes patents, then any patent license granted to you under this License for the Software shall terminate as of the date such litigation or activity is filed or taken. - -3. No Trademark License - -No trademark license is granted to use the trade names, trademarks, service marks, or product names of Contributor, except as required to fulfill notice requirements in Section 4. - -4. Distribution Restriction - -You may distribute the Software in any medium with or without modification, whether in source or executable forms, provided that you provide recipients with a copy of this License and retain copyright, patent, trademark and disclaimer statements in the Software. - -5. Disclaimer of Warranty and Limitation of Liability - -THE SOFTWARE AND CONTRIBUTION IN IT ARE PROVIDED WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED. IN NO EVENT SHALL ANY CONTRIBUTOR OR COPYRIGHT HOLDER BE LIABLE TO YOU FOR ANY DAMAGES, INCLUDING, BUT NOT LIMITED TO ANY DIRECT, OR INDIRECT, SPECIAL OR CONSEQUENTIAL DAMAGES ARISING FROM YOUR USE OR INABILITY TO USE THE SOFTWARE OR THE CONTRIBUTION IN IT, NO MATTER HOW IT’S CAUSED OR BASED ON WHICH LEGAL THEORY, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. - -6. Language - -THIS LICENSE IS WRITTEN IN BOTH CHINESE AND ENGLISH, AND THE CHINESE VERSION AND ENGLISH VERSION SHALL HAVE THE SAME LEGAL EFFECT. IN THE CASE OF DIVERGENCE BETWEEN THE CHINESE AND ENGLISH VERSIONS, THE CHINESE VERSION SHALL PREVAIL. - -END OF THE TERMS AND CONDITIONS diff --git a/third-party/vendor/sbi-rt/README.md b/third-party/vendor/sbi-rt/README.md deleted file mode 100644 index ec734f8e..00000000 --- a/third-party/vendor/sbi-rt/README.md +++ /dev/null @@ -1,26 +0,0 @@ -# sbi-rt - -[![crates.io](https://img.shields.io/crates/v/sbi-rt.svg)](https://crates.io/crates/sbi-rt) -[![Documentation](https://docs.rs/sbi-rt/badge.svg)](https://docs.rs/sbi-rt) -![License](https://img.shields.io/crates/l/sbi-rt.svg) - -- [An English README](README_EN.md) - -为特权软件提供 RISC-V 特权二进制接口(Supervisor Binary Interface)的运行时库。 - -2.0 标准各章节的实现情况: - -- [x] §3 -- [x] §4 -- [x] §5 -- [x] §6 -- [x] §7 -- [x] §8 -- [x] §9 -- [x] §10 -- [x] §11 -- [x] §12 -- [x] §13 -- [x] §14 -- [x] §15 -- [x] §16 diff --git a/third-party/vendor/sbi-rt/README_EN.md b/third-party/vendor/sbi-rt/README_EN.md deleted file mode 100644 index 4d1618fb..00000000 --- a/third-party/vendor/sbi-rt/README_EN.md +++ /dev/null @@ -1,21 +0,0 @@ -# sbi-rt - -- [中文自述文件](README.md) - -Runtime library for supervisors to call RISC-V Supervisor Binary Interface (RISC-V SBI). - -Chapters implementation in 2.0 specification: - -- [x] §3 -- [x] §4 -- [x] §5 -- [x] §6 -- [x] §7 -- [x] §8 -- [x] §9 -- [x] §10 -- [x] §11 -- [x] §13 -- [x] §14 -- [x] §15 -- [x] §16 diff --git a/third-party/vendor/sbi-rt/src/base.rs b/third-party/vendor/sbi-rt/src/base.rs deleted file mode 100644 index 5a26875f..00000000 --- a/third-party/vendor/sbi-rt/src/base.rs +++ /dev/null @@ -1,198 +0,0 @@ -//! Chapter 4. Base Extension (EID #0x10) - -use crate::binary::{sbi_call_0, sbi_call_1}; - -use sbi_spec::base::{ - Version, EID_BASE, GET_MARCHID, GET_MIMPID, GET_MVENDORID, GET_SBI_IMPL_ID, - GET_SBI_IMPL_VERSION, GET_SBI_SPEC_VERSION, PROBE_EXTENSION, -}; - -/// Return the current SBI specification version. -/// -/// The minor number of the SBI specification is encoded in the low 24 bits, -/// with the major number encoded in the next 7 bits. -/// Bit 31 must be zero and is reserved for future expansion. -/// -/// This function is defined in RISC-V SBI Specification chapter 4.1. -/// According to the introduction of chapter 4, all base extension functions -/// must success and return no error code. -#[inline] -pub fn get_spec_version() -> Version { - Version::from_raw(sbi_call_0(EID_BASE, GET_SBI_SPEC_VERSION).value) -} - -/// Return the current SBI implementation ID. -/// -/// Implementation ID is different for every SBI implementation. -/// It is intended that this implementation ID allows software to probe -/// for SBI implementation quirks. -/// -/// This function is defined in RISC-V SBI Specification chapter 4.2. -/// According to the introduction of chapter 4, all base extension functions -/// must success and return no error code. -#[inline] -pub fn get_sbi_impl_id() -> usize { - sbi_call_0(EID_BASE, GET_SBI_IMPL_ID).value -} - -/// Return the current SBI implementation version. -/// -/// The encoding of this version number is specific to the SBI implementation. -/// -/// This function is defined in RISC-V SBI Specification chapter 4.3. -/// According to the introduction of chapter 4, all base extension functions -/// must success and return no error code. -#[inline] -pub fn get_sbi_impl_version() -> usize { - sbi_call_0(EID_BASE, GET_SBI_IMPL_VERSION).value -} - -/// Probe information about one SBI extension from the current environment. -/// -/// Returns 0 if given SBI `extension_id` is not available, or typically -/// 1 if it's available. Implementation would define further non-zero -/// return values for information about this extension if it is available. -/// -/// This function is defined in RISC-V SBI Specification chapter 4.4. -/// According to the introduction of chapter 4, all base extension functions -/// must success and return no error code. -#[inline] -pub fn probe_extension(extension: E) -> ExtensionInfo -where - E: Extension, -{ - let ans = sbi_call_1(EID_BASE, PROBE_EXTENSION, extension.extension_id()); - ExtensionInfo { raw: ans.value } -} - -/// Return the value of `mvendorid` register in the current environment. -/// -/// This function returns a value that is legal for the `mvendorid` register, -/// and 0 is always a legal value for this register. -/// -/// This function is defined in RISC-V SBI Specification chapter 4.5. -/// According to the introduction of chapter 4, all base extension functions -/// must success and return no error code. -#[inline] -pub fn get_mvendorid() -> usize { - sbi_call_0(EID_BASE, GET_MVENDORID).value -} - -/// Return value of `marchid` register in the current environment. -/// -/// This function returns a value that is legal for the `marchid` register, -/// and 0 is always a legal value for this register. -/// -/// This function is defined in RISC-V SBI Specification chapter 4.6. -/// According to the introduction of chapter 4, all base extension functions -/// must success and return no error code. -#[inline] -pub fn get_marchid() -> usize { - sbi_call_0(EID_BASE, GET_MARCHID).value -} - -/// Return value of `mimpid` register in the current environment. -/// -/// This function returns a value that is legal for the `mimpid` register, -/// and 0 is always a legal value for this register. -/// -/// This function is defined in RISC-V SBI Specification chapter 4.7. -/// According to the introduction of chapter 4, all base extension functions -/// must success and return no error code. -#[inline] -pub fn get_mimpid() -> usize { - sbi_call_0(EID_BASE, GET_MIMPID).value -} - -/// An SBI extension. -pub trait Extension { - /// Get a raw `extension_id` value to pass to SBI environment. - fn extension_id(&self) -> usize; -} - -macro_rules! define_extension { - ($($struct:ident($value:expr) #[$doc:meta])*) => { - $( - #[derive(Clone, Copy, Debug)] - #[$doc] - pub struct $struct; - impl Extension for $struct { - #[inline] - fn extension_id(&self) -> usize { - $value - } - } - )* - }; -} - -define_extension! { - Base(sbi_spec::base::EID_BASE) /// RISC-V SBI Base extension. - Timer(sbi_spec::time::EID_TIME) /// Timer programmer extension. - Ipi(sbi_spec::spi::EID_SPI) /// Inter-processor Interrupt extension. - Fence(sbi_spec::rfnc::EID_RFNC) /// Remote Fence extension. - Hsm(sbi_spec::hsm::EID_HSM) /// Hart State Monitor extension. - Reset(sbi_spec::srst::EID_SRST) /// System Reset extension. - Pmu(sbi_spec::pmu::EID_PMU) /// Performance Monitoring Unit extension. - Console(sbi_spec::dbcn::EID_DBCN) /// Debug Console extension. - Suspend(sbi_spec::susp::SUSPEND) /// System Suspend extension. - Cppc(sbi_spec::cppc::EID_CPPC) /// SBI CPPC extension. - Nacl(sbi_spec::nacl::EID_NACL) /// Nested Acceleration extension. - Sta(sbi_spec::sta::EID_STA) /// Steal-time Accounting extension. -} - -#[cfg(feature = "integer-impls")] -impl Extension for usize { - #[inline] - fn extension_id(&self) -> usize { - *self - } -} - -#[cfg(feature = "integer-impls")] -impl Extension for isize { - #[inline] - fn extension_id(&self) -> usize { - usize::from_ne_bytes(isize::to_ne_bytes(*self)) - } -} - -/// Information about an SBI extension. -#[derive(Clone, Copy, Debug)] -pub struct ExtensionInfo { - pub raw: usize, -} - -impl ExtensionInfo { - /// Is this extension available? - #[inline] - pub const fn is_available(&self) -> bool { - self.raw != 0 - } - - /// Is this extension not available? - #[inline] - pub const fn is_unavailable(&self) -> bool { - self.raw == 0 - } -} - -#[cfg(test)] -mod tests { - #[test] - fn extension_id_defined() { - use crate::Extension; - assert_eq!(crate::Base.extension_id(), 0x10); - assert_eq!(crate::Timer.extension_id(), 0x54494D45); - assert_eq!(crate::Ipi.extension_id(), 0x735049); - assert_eq!(crate::Fence.extension_id(), 0x52464E43); - assert_eq!(crate::Hsm.extension_id(), 0x48534D); - assert_eq!(crate::Reset.extension_id(), 0x53525354); - assert_eq!(crate::Pmu.extension_id(), 0x504D55); - assert_eq!(crate::Console.extension_id(), 0x4442434E); - assert_eq!(crate::Suspend.extension_id(), 0x53555350); - assert_eq!(crate::Cppc.extension_id(), 0x43505043); - assert_eq!(crate::Nacl.extension_id(), 0x4E41434C); - assert_eq!(crate::Sta.extension_id(), 0x535441); - } -} diff --git a/third-party/vendor/sbi-rt/src/binary.rs b/third-party/vendor/sbi-rt/src/binary.rs deleted file mode 100644 index bf432a8f..00000000 --- a/third-party/vendor/sbi-rt/src/binary.rs +++ /dev/null @@ -1,143 +0,0 @@ -//! Chapter 3. Binary Encoding - -use sbi_spec::binary::SbiRet; - -#[inline(always)] -pub(crate) fn sbi_call_0(eid: usize, fid: usize) -> SbiRet { - let (error, value); - unsafe { - core::arch::asm!( - "ecall", - in("a7") eid, - in("a6") fid, - lateout("a0") error, - lateout("a1") value, - ); - } - SbiRet { error, value } -} - -#[inline(always)] -pub(crate) fn sbi_call_1(eid: usize, fid: usize, arg0: usize) -> SbiRet { - let (error, value); - unsafe { - core::arch::asm!( - "ecall", - in("a7") eid, - in("a6") fid, - inlateout("a0") arg0 => error, - lateout("a1") value, - ); - } - SbiRet { error, value } -} - -#[inline(always)] -pub(crate) fn sbi_call_2(eid: usize, fid: usize, arg0: usize, arg1: usize) -> SbiRet { - let (error, value); - unsafe { - core::arch::asm!( - "ecall", - in("a7") eid, - in("a6") fid, - inlateout("a0") arg0 => error, - inlateout("a1") arg1 => value, - ); - } - SbiRet { error, value } -} - -#[inline(always)] -pub(crate) fn sbi_call_3(eid: usize, fid: usize, arg0: usize, arg1: usize, arg2: usize) -> SbiRet { - let (error, value); - unsafe { - core::arch::asm!( - "ecall", - in("a7") eid, - in("a6") fid, - inlateout("a0") arg0 => error, - inlateout("a1") arg1 => value, - in("a2") arg2, - ); - } - SbiRet { error, value } -} - -#[inline(always)] -pub(crate) fn sbi_call_4( - eid: usize, - fid: usize, - arg0: usize, - arg1: usize, - arg2: usize, - arg3: usize, -) -> SbiRet { - let (error, value); - unsafe { - core::arch::asm!( - "ecall", - in("a7") eid, - in("a6") fid, - inlateout("a0") arg0 => error, - inlateout("a1") arg1 => value, - in("a2") arg2, - in("a3") arg3, - ); - } - SbiRet { error, value } -} - -#[inline(always)] -pub(crate) fn sbi_call_5( - eid: usize, - fid: usize, - arg0: usize, - arg1: usize, - arg2: usize, - arg3: usize, - arg4: usize, -) -> SbiRet { - let (error, value); - unsafe { - core::arch::asm!( - "ecall", - in("a7") eid, - in("a6") fid, - inlateout("a0") arg0 => error, - inlateout("a1") arg1 => value, - in("a2") arg2, - in("a3") arg3, - in("a4") arg4, - ); - } - SbiRet { error, value } -} - -#[cfg(target_pointer_width = "32")] -#[inline(always)] -pub(crate) fn sbi_call_6( - eid: usize, - fid: usize, - arg0: usize, - arg1: usize, - arg2: usize, - arg3: usize, - arg4: usize, - arg5: usize, -) -> SbiRet { - let (error, value); - unsafe { - core::arch::asm!( - "ecall", - in("a7") eid, - in("a6") fid, - inlateout("a0") arg0 => error, - inlateout("a1") arg1 => value, - in("a2") arg2, - in("a3") arg3, - in("a4") arg4, - in("a5") arg5, - ); - } - SbiRet { error, value } -} diff --git a/third-party/vendor/sbi-rt/src/cppc.rs b/third-party/vendor/sbi-rt/src/cppc.rs deleted file mode 100644 index e6383a81..00000000 --- a/third-party/vendor/sbi-rt/src/cppc.rs +++ /dev/null @@ -1,127 +0,0 @@ -//! Chapter 14. CPPC Extension (EID #0x43505043 "CPPC") - -use crate::binary::sbi_call_1; -#[cfg(target_pointer_width = "64")] -use crate::binary::sbi_call_2; -#[cfg(target_pointer_width = "32")] -use crate::binary::sbi_call_3; -use sbi_spec::{ - binary::SbiRet, - cppc::{EID_CPPC, PROBE, READ, READ_HI, WRITE}, -}; - -/// Probe whether the CPPC register is implemented or not by the platform. -/// -/// # Parameters -/// -/// The `cppc_reg_id` parameter specifies the CPPC register ID. -/// -/// # Return value -/// -/// If the register is implemented, `SbiRet.value` will contain the register width. -/// If the register is not implemented, `SbiRet.value` will be set to 0. -/// -/// The possible error codes returned in `SbiRet.error` are shown in the table below: -/// -/// | Return code | Description -/// |:--------------------------|:---------------------------------------------- -/// | `SbiRet::success()` | Probe completed successfully. -/// | `SbiRet::invalid_param()` | `cppc_reg_id` is reserved. -/// | `SbiRet::failed()` | The probe request failed for unspecified or unknown other reasons. -/// -/// This function is defined in RISC-V SBI Specification chapter 14.1. -#[inline] -pub fn cppc_probe(cppc_reg_id: u32) -> SbiRet { - sbi_call_1(EID_CPPC, PROBE, cppc_reg_id as _) -} - -/// Read the CPPC register identified by given `cppc_reg_id`. -/// -/// # Parameters -/// -/// The `cppc_reg_id` parameter specifies the CPPC register ID. -/// -/// # Return value -/// -/// `SbiRet.value` will contain the register value. When supervisor mode XLEN is 32, the `SbiRet.value` -/// will only contain the lower 32 bits of the CPPC register value. -/// -/// The possible error codes returned in `SbiRet.error` are shown in the table below: -/// -/// | Return code | Description -/// |:--------------------------|:---------------------------------------------- -/// | `SbiRet::success()` | Read completed successfully. -/// | `SbiRet::invalid_param()` | `cppc_reg_id` is reserved. -/// | `SbiRet::not_supported()` | `cppc_reg_id` is not implemented by the platform. -/// | `SbiRet::denied()` | `cppc_reg_id` is a write-only register. -/// | `SbiRet::failed()` | The read request failed for unspecified or unknown other reasons. -/// -/// This function is defined in RISC-V SBI Specification chapter 14.2. -#[inline] -pub fn cppc_read(cppc_reg_id: u32) -> SbiRet { - sbi_call_1(EID_CPPC, READ, cppc_reg_id as _) -} - -/// Read the upper 32-bit value of the CPPC register identified by `cppc_reg_id`. -/// -/// # Parameters -/// -/// The `cppc_reg_id` parameter specifies the CPPC register ID. -/// -/// # Return value -/// -/// `SbiRet.value` will contain the upper 32 bits of the register value. This function always -/// returns zero in `SbiRet.value` when supervisor mode XLEN is 64 or higher. -/// -/// The possible error codes returned in `SbiRet.error` are shown in the table below: -/// -/// | Return code | Description -/// |:--------------------------|:---------------------------------------------- -/// | `SbiRet::success()` | Read completed successfully. -/// | `SbiRet::invalid_param()` | `cppc_reg_id` is reserved. -/// | `SbiRet::not_supported()` | `cppc_reg_id` is not implemented by the platform. -/// | `SbiRet::denied()` | `cppc_reg_id` is a write-only register. -/// | `SbiRet::failed()` | The read operation request failed for unspecified or unknown other reasons. -/// -/// This function is defined in RISC-V SBI Specification chapter 14.3. -#[inline] -pub fn cppc_read_hi(cppc_reg_id: u32) -> SbiRet { - sbi_call_1(EID_CPPC, READ_HI, cppc_reg_id as _) -} - -/// Write 64-bit value to the CPPC register identified by given `cppc_reg_id`. -/// -/// # Parameters -/// -/// The `cppc_reg_id` parameter specifies the CPPC register ID. -/// -/// The `value` parameter specifies the value to be written to the register. -/// -/// # Return value -/// -/// The possible error codes returned in `SbiRet.error` are shown in the table below: -/// -/// | Return code | Description -/// |:--------------------------|:---------------------------------------------- -/// | `SbiRet::success()` | Write completed successfully. -/// | `SbiRet::invalid_param()` | `cppc_reg_id` is reserved. -/// | `SbiRet::not_supported()` | `cppc_reg_id` is not implemented by the platform. -/// | `SbiRet::denied()` | `cppc_reg_id` is a read-only register. -/// | `SbiRet::failed()` | The write operation request failed for unspecified or unknown other reasons. -/// -/// This function is defined in RISC-V SBI Specification chapter 14.4. -#[inline] -pub fn cppc_write(cppc_reg_id: u32, value: u64) -> SbiRet { - match () { - #[cfg(target_pointer_width = "32")] - () => sbi_call_3( - EID_CPPC, - WRITE, - cppc_reg_id as _, - value as _, - (value >> 32) as _, - ), - #[cfg(target_pointer_width = "64")] - () => sbi_call_2(EID_CPPC, WRITE, cppc_reg_id as _, value as _), - } -} diff --git a/third-party/vendor/sbi-rt/src/dbcn.rs b/third-party/vendor/sbi-rt/src/dbcn.rs deleted file mode 100644 index 005f8bdd..00000000 --- a/third-party/vendor/sbi-rt/src/dbcn.rs +++ /dev/null @@ -1,102 +0,0 @@ -//! Chapter 12. Debug Console Extension (EID #0x4442434E "DBCN") -use crate::binary::{sbi_call_1, sbi_call_3}; -use sbi_spec::{ - binary::{Physical, SbiRet}, - dbcn::{CONSOLE_READ, CONSOLE_WRITE, CONSOLE_WRITE_BYTE, EID_DBCN}, -}; - -/// Write bytes to the debug console from input memory. -/// -/// # Parameters -/// -/// The `bytes` parameter specifies the input memory, including its length -/// and memory physical base address (both lower and upper bits). -/// -/// # Non-blocking function -/// -/// This is a non-blocking SBI call, and it may do partial or no write operations if -/// the debug console is not able to accept more bytes. -/// -/// # Return value -/// -/// The number of bytes written is returned in `SbiRet.value` and the -/// possible return error codes returned in `SbiRet.error` are shown in -/// the table below: -/// -/// | Return code | Description -/// |:--------------------------|:---------------------------------------------- -/// | `SbiRet::success()` | Bytes written successfully. -/// | `SbiRet::invalid_param()` | The memory pointed to by `bytes` does not satisfy the requirements described in shared memory physical address range. -/// | `SbiRet::failed()` | Failed to write due to I/O errors. -/// -/// This function is defined in RISC-V SBI Specification chapter 12.1. -#[inline] -pub fn console_write(bytes: Physical<&[u8]>) -> SbiRet { - sbi_call_3( - EID_DBCN, - CONSOLE_WRITE, - bytes.num_bytes(), - bytes.phys_addr_lo(), - bytes.phys_addr_hi(), - ) -} - -/// Read bytes from the debug console into an output memory. -/// -/// # Parameters -/// -/// The `bytes` parameter specifies the output memory, including the maximum -/// bytes which can be written, and its memory physical base address -/// (both lower and upper bits). -/// -/// # Non-blocking function -/// -/// This is a non-blocking SBI call, and it will not write anything -/// into the output memory if there are no bytes to be read in the -/// debug console. -/// -/// # Return value -/// -/// The number of bytes read is returned in `SbiRet.value` and the -/// possible return error codes returned in `SbiRet.error` are shown in -/// the table below: -/// -/// | Return code | Description -/// |:--------------------------|:---------------------------------------------- -/// | `SbiRet::success()` | Bytes read successfully. -/// | `SbiRet::invalid_param()` | The memory pointed to by `bytes` does not satisfy the requirements described in shared memory physical address range. -/// | `SbiRet::failed()` | Failed to read due to I/O errors. -/// -/// This function is defined in RISC-V SBI Specification chapter 12.2. -pub fn console_read(bytes: Physical<&mut [u8]>) -> SbiRet { - sbi_call_3( - EID_DBCN, - CONSOLE_READ, - bytes.num_bytes(), - bytes.phys_addr_lo(), - bytes.phys_addr_hi(), - ) -} - -/// Write a single byte to the debug console. -/// -/// # Blocking function -/// -/// This is a blocking SBI call, and it will only return after writing -/// the specified byte to the debug console. It will also return with -/// `SbiRet::failed()` if there are I/O errors. -/// # Return value -/// -/// The `SbiRet.value` is set to zero, and the possible return error -/// codes returned in `SbiRet.error` are shown in the table below: -/// -/// | Return code | Description -/// |:--------------------------|:---------------------------------------------- -/// | `SbiRet::success()` | Byte written successfully. -/// | `SbiRet::failed()` | Failed to write the byte due to I/O errors. -/// -/// This function is defined in RISC-V SBI Specification chapter 12.3. -#[inline] -pub fn console_write_byte(byte: u8) -> SbiRet { - sbi_call_1(EID_DBCN, CONSOLE_WRITE_BYTE, byte as usize) -} diff --git a/third-party/vendor/sbi-rt/src/hsm.rs b/third-party/vendor/sbi-rt/src/hsm.rs deleted file mode 100644 index 7fcb26d9..00000000 --- a/third-party/vendor/sbi-rt/src/hsm.rs +++ /dev/null @@ -1,238 +0,0 @@ -//! Chapter 9. Hart State Management Extension (EID #0x48534D "HSM") - -use crate::binary::{sbi_call_0, sbi_call_1, sbi_call_3}; - -use sbi_spec::{ - binary::SbiRet, - hsm::{EID_HSM, HART_GET_STATUS, HART_START, HART_STOP, HART_SUSPEND}, -}; - -/// Start executing the given hart at specified address in supervisor-mode. -/// -/// This call is asynchronous - more specifically, the `hart_start()` may return before target hart starts -/// executing as long as the SBI implementation is capable of ensuring the return code is accurate. -/// -/// It is recommended that if the SBI implementation is a platform runtime firmware executing in -/// machine-mode (M-mode), then it MUST configure PMP and other the M-mode state before executing -/// in supervisor-mode. -/// -/// # Parameters -/// -/// - The `hartid` parameter specifies the target hart, which is to be started. -/// - The `start_addr` parameter points to a runtime-specified physical address, -/// where the hart can start executing in supervisor-mode. -/// - The `opaque` parameter is a `usize` value that will be set in the `a1` -/// register when the hart starts executing at `start_addr`. -/// -/// *NOTE:* A single `usize` parameter is sufficient as `start_addr`, -/// because the hart will start execution in the supervisor-mode with MMU off, -/// hence the `start_addr` must be less than XLEN bits wide. -/// -/// # Behavior -/// -/// The target hart jumps to supervisor mode at the address specified by `start_addr` -/// with the following values in specific registers. -/// -/// | Register Name | Register Value -/// |:--------------|:-------------- -/// | `satp` | 0 -/// | `sstatus.SIE` | 0 -/// | a0 | hartid -/// | a1 | `opaque` parameter -/// -/// # Return value -/// -/// The possible return error codes returned in `SbiRet.error` are shown in the table below: -/// -/// | Return code | Description -/// |:------------------------------|:---------------------------------------------- -/// | `SbiRet::success()` | Hart was previously in stopped state. -/// It will start executing from `start_addr`. -/// | `SbiRet::invalid_address()` | `start_addr` is not valid, possibly due to the following reasons: -/// it is not a valid physical address, -/// or the address is prohibited by PMP or H-extension G-stage to run in supervisor-mode. -/// | `SbiRet::invalid_param()` | `hartid` -/// is not a valid hartid as corresponding hart cannot be started in supervisor mode. -/// | `SbiRet::already_available()` | The given hartid is already started. -/// | `SbiRet::failed()` | The start request failed for unknown reasons. -/// -/// This function is defined in RISC-V SBI Specification chapter 9.1. -#[inline] -pub fn hart_start(hartid: usize, start_addr: usize, opaque: usize) -> SbiRet { - sbi_call_3(EID_HSM, HART_START, hartid, start_addr, opaque) -} - -/// Stop executing the calling hart in supervisor-mode. -/// -/// This function requests the SBI implementation to stop executing the calling hart in -/// supervisor-mode and return its ownership to the SBI implementation. -/// -/// This call is not expected to return under normal conditions. -/// The `sbi_hart_stop()` must be called with the supervisor-mode interrupts disabled. -/// -/// # Return value -/// -/// The possible return error codes returned in `SbiRet.error` are shown in the table below: -/// -/// | Error code | Description -/// |:------------|:------------ -/// | `SbiRet::failed()` | Failed to stop execution of the current hart -/// -/// This function is defined in RISC-V SBI Specification chapter 9.2. -#[inline] -pub fn hart_stop() -> SbiRet { - sbi_call_0(EID_HSM, HART_STOP) -} - -/// Get the current status (or HSM state id) of the given hart. -/// -/// The harts may transition HSM states at any time due to any concurrent `hart_start()` -/// or `hart_stop()` calls, the return value from this function may not represent the actual state -/// of the hart at the time of return value verification. -/// -/// # Parameters -/// -/// The `hartid` parameter specifies the target hart which status is required. -/// -/// # Return value -/// -/// The possible status values returned in `SbiRet.value` are shown in the table below: -/// -/// | Name | Value | Description -/// |:--------------|:------|:------------------------- -/// | STARTED | 0 | Hart Started -/// | STOPPED | 1 | Hart Stopped -/// | START_PENDING | 2 | Hart start request pending -/// | STOP_PENDING | 3 | Hart stop request pending -/// -/// The possible return error codes returned in `SbiRet.error` are shown in the table below: -/// -/// | Error code | Description -/// |:--------------------------|:------------ -/// | `SbiRet::invalid_param()` | The given `hartid` is not valid -/// -/// This function is defined in RISC-V SBI Specification chapter 9.3. -#[inline] -pub fn hart_get_status(hartid: usize) -> SbiRet { - sbi_call_1(EID_HSM, HART_GET_STATUS, hartid) -} - -/// Put the calling hart into suspend or platform specific lower power states. -/// -/// This function requests the SBI implementation to put the calling hart in a platform specfic suspend -/// (or low power) state specified by the `suspend_type` parameter. -/// -/// The hart will automatically come out of suspended state and resume normal execution -/// when it receives an interrupt or platform specific hardware event. -/// -/// # Suspend behavior -/// -/// The platform-specific suspend states for a hart can be either retentive or non-retentive in nature. -/// -/// A retentive suspend state will preserve hart register and CSR values for all privilege modes, -/// whereas a non-retentive suspend state will not preserve hart register and CSR values. -/// -/// # Resuming -/// -/// Resuming from a retentive suspend state is straight forward, and the supervisor-mode software -/// will see SBI suspend call return without any failures. -/// -/// Resuming from a non-retentive suspend state is relatively more involved, and it requires software -/// to restore various hart registers and CSRs for all privilege modes. -/// Upon resuming from non-retentive suspend state, the hart will jump to supervisor-mode at address -/// specified by `resume_addr` with specific registers values described in the table below: -/// -/// | Register Name | Register Value -/// |:--------------|:-------------- -/// | `satp` | 0 -/// | `sstatus.SIE` | 0 -/// | a0 | hartid -/// | a1 | `opaque` parameter -/// -/// # Parameters -/// -/// The `suspend_type` parameter is 32 bits wide, and the possible values are shown in the table below: -/// -/// | Value | Description -/// |:------------------------|:-------------- -/// | 0x00000000 | Default retentive suspend -/// | 0x00000001 - 0x0FFFFFFF | _Reserved for future use_ -/// | 0x10000000 - 0x7FFFFFFF | Platform specific retentive suspend -/// | 0x80000000 | Default non-retentive suspend -/// | 0x80000001 - 0x8FFFFFFF | _Reserved for future use_ -/// | 0x90000000 - 0xFFFFFFFF | Platform specific non-retentive suspend -/// | > 0xFFFFFFFF | _Reserved_ -/// -/// The `resume_addr` parameter points to a runtime-specified physical address, -/// where the hart can resume execution in supervisor-mode after a non-retentive -/// suspend. -/// -/// *NOTE:* A single `usize` parameter is sufficient as `resume_addr`, -/// because the hart will resume execution in the supervisor-mode with MMU off, -/// hence the `resume_addr` must be less than XLEN bits wide. -/// -/// The `opaque` parameter is an XLEN-bit value that will be set in the `a1` -/// register when the hart resumes execution at `resume_addr` after a -/// non-retentive suspend. -/// -/// # Return value -/// -/// The possible return error codes returned in `SbiRet.error` are shown in the table below: -/// -/// | Error code | Description -/// |:----------------------------|:------------ -/// | `SbiRet::success()` | Hart has been suspended and resumed back successfully from a retentive suspend state. -/// | `SbiRet::invalid_param()` | `suspend_type` is not valid. -/// | `SbiRet::not_supported()` | `suspend_type` is valid but not implemented. -/// | `SbiRet::invalid_address()` | `resume_addr` is not valid, possibly due to the following reasons: it is not a valid physical address, or the address is prohibited by PMP or H-extension G-stage to run in supervisor-mode. -/// | `SbiRet::failed()` | The suspend request failed for unknown reasons. -/// -/// This function is defined in RISC-V SBI Specification chapter 9.4. -#[inline] -pub fn hart_suspend(suspend_type: T, resume_addr: usize, opaque: usize) -> SbiRet -where - T: SuspendType, -{ - sbi_call_3( - EID_HSM, - HART_SUSPEND, - suspend_type.raw() as _, - resume_addr, - opaque, - ) -} - -/// A valid suspend type for hart state monitor. -pub trait SuspendType { - /// Get a raw value to pass to SBI environment. - fn raw(&self) -> u32; -} - -#[cfg(feature = "integer-impls")] -impl SuspendType for u32 { - #[inline] - fn raw(&self) -> u32 { - *self - } -} - -macro_rules! define_suspend_type { - ($($struct:ident($value:expr) #[$doc:meta])*) => { - $( - #[derive(Clone, Copy, Debug)] - #[$doc] - pub struct $struct; - impl SuspendType for $struct { - #[inline] - fn raw(&self) -> u32 { - $value - } - } - )* - }; -} - -define_suspend_type! { - Retentive(sbi_spec::hsm::suspend_type::RETENTIVE) /// Default retentive hart suspension. - NonRetentive(sbi_spec::hsm::suspend_type::NON_RETENTIVE) /// Default non-retentive hart suspension. -} diff --git a/third-party/vendor/sbi-rt/src/legacy.rs b/third-party/vendor/sbi-rt/src/legacy.rs deleted file mode 100644 index 656263ac..00000000 --- a/third-party/vendor/sbi-rt/src/legacy.rs +++ /dev/null @@ -1,160 +0,0 @@ -//! Chapter 5. Legacy Extensions (EIDs #0x00 - #0x0F) - -pub use sbi_spec::legacy::*; - -/// §5.1 -#[deprecated = "replaced by `set_timer` from Timer extension"] -#[inline] -pub fn set_timer(stime_value: u64) -> usize { - match () { - #[cfg(target_pointer_width = "32")] - () => sbi_call_legacy_2(LEGACY_SET_TIMER, stime_value as _, (stime_value >> 32) as _), - #[cfg(target_pointer_width = "64")] - () => sbi_call_legacy_1(LEGACY_SET_TIMER, stime_value as _), - } -} - -/// §5.2 -/// -/// No replacement. -#[deprecated = "no replacement"] -#[inline] -pub fn console_putchar(c: usize) -> usize { - sbi_call_legacy_1(LEGACY_CONSOLE_PUTCHAR, c) -} - -/// §5.3 -/// -/// No replacement. -#[deprecated = "no replacement"] -#[inline] -pub fn console_getchar() -> usize { - sbi_call_legacy_0(LEGACY_CONSOLE_GETCHAR) -} - -/// §5.4 -/// -/// No replacement. Just clear `sip.SSIP` directly. -#[deprecated = "you can clear `sip.SSIP` CSR bit directly"] -#[inline] -pub fn clear_ipi() -> usize { - sbi_call_legacy_0(LEGACY_CLEAR_IPI) -} - -/// §5.5 -/// -/// Replaced by [`send_ipi`](super::send_ipi) from [`sPI`](super::EID_SPI) extension. -#[deprecated = "replaced by `send_ipi` from `sPI` extension"] -#[inline] -pub fn send_ipi(hart_mask: usize) -> usize { - sbi_call_legacy_1(LEGACY_SEND_IPI, hart_mask) -} - -/// §5.6 -/// -/// Replaced by [`remote_fence_i`](super::remote_fence_i) from [`RFNC`](super::EID_RFNC) extension. -#[deprecated = "replaced by `remote_fence_i` from `RFNC` extension"] -#[inline] -pub fn remote_fence_i(hart_mask: usize) -> usize { - sbi_call_legacy_1(LEGACY_REMOTE_FENCE_I, hart_mask) -} - -/// §5.7 -/// -/// Replaced by [`remote_sfence_vma`](super::remote_sfence_vma) from [`RFNC`](super::EID_RFNC) extension. -#[deprecated = "replaced by `remote_sfence_vma` from `RFNC` extension"] -#[inline] -pub fn remote_fence_vma(hart_mask: usize, start: usize, size: usize) -> usize { - sbi_call_legacy_3(LEGACY_REMOTE_SFENCE_VMA, hart_mask, start, size) -} - -/// §5.8 -/// -/// Replaced by [`remote_sfence_vma_asid`](super::remote_sfence_vma_asid) from [`RFNC`](super::EID_RFNC) extension. -#[deprecated = "replaced by `remote_sfence_vma_asid` from `RFNC` extension"] -#[inline] -pub fn remote_fence_vma_asid(hart_mask: usize, start: usize, size: usize, asid: usize) -> usize { - sbi_call_legacy_4(LEGACY_REMOTE_SFENCE_VMA_ASID, hart_mask, start, size, asid) -} - -/// §5.9 -/// -/// Replaced by [`system_reset`](super::system_reset) in the [`SRST`](super::EID_SRST) extension. -#[deprecated = "replaced by `system_reset` from System `SRST` extension"] -#[inline] -pub fn shutdown() -> ! { - sbi_call_legacy_0(LEGACY_SHUTDOWN); - unreachable!() -} - -#[inline(always)] -fn sbi_call_legacy_0(eid: usize) -> usize { - let error; - unsafe { - core::arch::asm!( - "ecall", - in("a7") eid, - lateout("a0") error, - ); - } - error -} - -#[inline(always)] -fn sbi_call_legacy_1(eid: usize, arg0: usize) -> usize { - let error; - unsafe { - core::arch::asm!( - "ecall", - in("a7") eid, - inlateout("a0") arg0 => error, - ); - } - error -} - -#[cfg(target_pointer_width = "32")] -#[inline(always)] -fn sbi_call_legacy_2(eid: usize, arg0: usize, arg1: usize) -> usize { - let error; - unsafe { - core::arch::asm!( - "ecall", - in("a7") eid, - inlateout("a0") arg0 => error, - in("a1") arg1, - ); - } - error -} - -#[inline(always)] -fn sbi_call_legacy_3(eid: usize, arg0: usize, arg1: usize, arg2: usize) -> usize { - let error; - unsafe { - core::arch::asm!( - "ecall", - in("a7") eid, - inlateout("a0") arg0 => error, - in("a1") arg1, - in("a2") arg2, - ); - } - error -} - -#[inline(always)] -fn sbi_call_legacy_4(eid: usize, arg0: usize, arg1: usize, arg2: usize, arg3: usize) -> usize { - let error; - unsafe { - core::arch::asm!( - "ecall", - in("a7") eid, - inlateout("a0") arg0 => error, - in("a1") arg1, - in("a2") arg2, - in("a3") arg3, - ); - } - error -} diff --git a/third-party/vendor/sbi-rt/src/lib.rs b/third-party/vendor/sbi-rt/src/lib.rs deleted file mode 100644 index e8851de8..00000000 --- a/third-party/vendor/sbi-rt/src/lib.rs +++ /dev/null @@ -1,53 +0,0 @@ -//! Simple RISC-V SBI runtime primitives. -#![no_std] -#[cfg_attr(not(feature = "legacy"), deny(missing_docs))] -// §3 -mod binary; -// §4 -mod base; -// §5 -#[cfg(feature = "legacy")] -pub mod legacy; -// §6 -mod time; -// §7 -mod spi; -// §8 -mod rfnc; -// §9 -mod hsm; -// §10 -mod srst; -// §11 -mod pmu; -// §12 -mod dbcn; -// §13 -mod susp; -// §14 -mod cppc; -// §15 -mod nacl; -// §16 -mod sta; - -pub use sbi_spec::{ - base::Version, - binary::{HartMask, Physical, SbiRet, SharedPtr}, -}; - -// module `binary` includes crate-local `sbi_call_*` functions and is thus not re-exported -// into the library root. - -pub use base::*; -pub use cppc::*; -pub use dbcn::*; -pub use hsm::*; -pub use nacl::*; -pub use pmu::*; -pub use rfnc::*; -pub use spi::*; -pub use srst::*; -pub use sta::*; -pub use susp::*; -pub use time::*; diff --git a/third-party/vendor/sbi-rt/src/nacl.rs b/third-party/vendor/sbi-rt/src/nacl.rs deleted file mode 100644 index b2a3faec..00000000 --- a/third-party/vendor/sbi-rt/src/nacl.rs +++ /dev/null @@ -1,146 +0,0 @@ -//! Chapter 15. Nested Acceleration Extension (EID #0x4E41434C "NACL") - -use crate::binary::{sbi_call_0, sbi_call_1, sbi_call_3}; - -use sbi_spec::{ - binary::{SbiRet, SharedPtr}, - nacl::{shmem_size, EID_NACL, PROBE_FEATURE, SET_SHMEM, SYNC_CSR, SYNC_HFENCE, SYNC_SRET}, -}; - -/// Probe a nested acceleration feature. -/// -/// This is a mandatory function of the SBI nested acceleration extension. -/// -/// # Parameters -/// -/// The `feature_id` parameter specifies the nested acceleration feature to probe. -/// Possible feature IDs are defined in the table below: -/// -/// # Return value -/// -/// This function always returns `SbiRet::success()` in `SbiRet.error`. -/// It returns 0 in `SbiRet.value` if the given `feature_id` is not available, -/// or 1 in `SbiRet.value` if it is available. -/// -/// This function is defined in RISC-V SBI Specification chapter 15.5. -#[inline] -pub fn nacl_probe_feature(feature_id: u32) -> SbiRet { - sbi_call_1(EID_NACL, PROBE_FEATURE, feature_id as _) -} - -/// Set and enable the shared memory for nested acceleration on the calling hart. -/// -/// This is a mandatory function of the SBI nested acceleration extension. -/// -/// # Parameters -/// -/// If `shmem` parameter is not all-ones bitwise, then `shmem` specifies the shared -/// memory physical base address. `shmem` MUST be 4096 bytes (i.e., page) aligned, and -/// the size of the shared memory must be `4096 + (XLEN * 128)` bytes. -/// -/// If `shmem` parameter is all-ones bitwise, then the nested acceleration features -/// are disabled. -/// -/// The `flags` parameter is reserved for future use and must be zero. -/// -/// The possible error codes returned in `SbiRet.error` are shown in the table below: -/// -/// | Error code | Description -/// |:----------------------------|:--------------------------------- -/// | `SbiRet::success()` | Shared memory was set or cleared successfully. -/// | `SbiRet::invalid_param()` | The `flags` parameter is not zero or or the `shmem` parameter is not 4096 bytes aligned. -/// | `SbiRet::invalid_address()` | The shared memory pointed to by the `shmem` parameters does not satisfy the requirements. -/// -/// This function is defined in RISC-V SBI Specification chapter 15.6. -#[inline] -pub fn nacl_set_shmem(shmem: SharedPtr<[u8; shmem_size::NATIVE]>, flags: usize) -> SbiRet { - sbi_call_3( - EID_NACL, - SET_SHMEM, - shmem.phys_addr_lo(), - shmem.phys_addr_hi(), - flags, - ) -} - -/// Synchronize CSRs in the nested acceleration shared memory. -/// -/// This is an optional function that is only available if the SBI_NACL_FEAT_SYNC_CSR feature is available. -/// -/// # Parameters -/// -/// The parameter `csr_num` specifies the set of RISC-V H-extension CSRs to be synchronized. -/// -/// If `csr_num` is all-ones bitwise, then all RISC-V H-extension CSRs implemented by the SBI implementation (or L0 hypervisor) are synchronized. -/// -/// If `(csr_num & 0x300) == 0x200` and `csr_num < 0x1000` then only a single -/// RISC-V H-extension CSR specified by the csr_num parameter is synchronized. -/// -/// # Return value -/// -/// The possible error codes returned in `SbiRet.error` are shown in the table below: -/// -/// | Error code | Description -/// |:--------------------------|:--------------------------------- -/// | `SbiRet::success()` | CSRs synchronized successfully. -/// | `SbiRet::not_supported()` | SBI_NACL_FEAT_SYNC_CSR feature is not available. -/// | `SbiRet::invalid_param()` | `csr_num` is not all-ones bitwise and either:
* `(csr_num & 0x300) != 0x200` or
* `csr_num >= 0x1000` or
* `csr_num` is not implemented by the SBI implementation -/// | `SbiRet::no_shmem()` | Nested acceleration shared memory not available. -/// -/// This function is defined in RISC-V SBI Specification chapter 15.7. -#[inline] -pub fn nacl_sync_csr(csr_num: usize) -> SbiRet { - sbi_call_1(EID_NACL, SYNC_CSR, csr_num) -} - -/// Synchronize HFENCEs in the nested acceleration shared memory. -/// -/// This is an optional function that is only available if the SBI_NACL_FEAT_SYNC_HFENCE feature is available. -/// -/// # Parameters -/// -/// The parameter `entry_index` specifies the set of nested HFENCE entries to be synchronized. -/// -/// If `entry_index` is all-ones bitwise, then all nested HFENCE entries are synchronized. -/// -/// If `entry_index < (3840 / XLEN)` then only a single nested HFENCE entry specified by the `entry_index` parameter is synchronized -/// -/// # Return value -/// -/// The possible error codes returned in `SbiRet.error` are shown in the table below: -/// -/// | Error code | Description -/// |:--------------------------|:--------------------------------- -/// | `SbiRet::success()` | HFENCEs synchronized successfully. -/// | `SbiRet::not_supported()` | SBI_NACL_FEAT_SYNC_HFENCE feature is not available. -/// | `SbiRet::invalid_param()` | `entry_index` is not all-ones bitwise and `entry_index >= (3840 / XLEN)`. -/// | `SbiRet::no_shmem()` | Nested acceleration shared memory not available. -/// -/// This function is defined in RISC-V SBI Specification chapter 15.8. -#[inline] -pub fn nacl_sync_hfence(entry_index: usize) -> SbiRet { - sbi_call_1(EID_NACL, SYNC_HFENCE, entry_index) -} - -/// Synchronize CSRs and HFENCEs in the NACL shared memory and emulate the SRET instruction. -/// -/// This is an optional function that is only available if the SBI_NACL_FEAT_SYNC_SRET feature is available. -/// -/// This function is used by supervisor software (or L1 hypervisor) to do a synchronizing SRET request, -/// and the SBI implementation (or L0 hypervisor) MUST handle it. -/// -/// # Return value -/// -/// This function does not return upon success, and the possible error codes -/// returned in `SbiRet.error` upon failure are shown in the table below: -/// -/// | Error code | Description -/// |:--------------------------|:------------ -/// | `SbiRet::no_shmem()` | Nested acceleration shared memory not available. -/// | `SbiRet::not_supported()` | SBI_NACL_FEAT_SYNC_SRET feature is not available. -/// -/// This function is defined in RISC-V SBI Specification chapter 15.9. -#[inline] -pub fn nacl_sync_sret() -> SbiRet { - sbi_call_0(EID_NACL, SYNC_SRET) -} diff --git a/third-party/vendor/sbi-rt/src/pmu.rs b/third-party/vendor/sbi-rt/src/pmu.rs deleted file mode 100644 index 43de2911..00000000 --- a/third-party/vendor/sbi-rt/src/pmu.rs +++ /dev/null @@ -1,329 +0,0 @@ -//! Chapter 11. Performance Monitoring Unit Extension (EID #0x504D55 "PMU") - -use crate::binary::{sbi_call_0, sbi_call_1, sbi_call_3}; - -use sbi_spec::{ - binary::SbiRet, - pmu::{ - COUNTER_CONFIG_MATCHING, COUNTER_FW_READ, COUNTER_FW_READ_HI, COUNTER_GET_INFO, - COUNTER_START, COUNTER_STOP, EID_PMU, NUM_COUNTERS, - }, -}; - -/// Returns the number of counters, both hardware and firmware. -/// -/// This call would always succeed without returning any error. -/// -/// This function is defined in RISC-V SBI Specification chapter 11.5. -#[inline] -pub fn pmu_num_counters() -> usize { - sbi_call_0(EID_PMU, NUM_COUNTERS).value -} - -/// Get details about the specified counter. -/// -/// The value returned includes details such as underlying CSR number, width of the counter, -/// type of counter (hardware or firmware), etc. -/// -/// The `counter_info` returned by this SBI call is encoded as follows: -/// -/// ```text -/// counter_info[11:0] = CSR; // (12bit CSR number) -/// counter_info[17:12] = Width; // (One less than number of bits in CSR) -/// counter_info[XLEN-2:18] = Reserved; // Reserved for future use -/// counter_info[XLEN-1] = Type; // (0 = hardware and 1 = firmware) -/// ``` -/// If `counter_info.type` == `1` then `counter_info.csr` and `counter_info.width` should be ignored. -/// -/// This function is defined in RISC-V SBI Specification chapter 11.6. -/// -/// # Return value -/// -/// Returns the `counter_info` described above in `SbiRet.value`. -/// -/// The possible return error codes returned in `SbiRet.error` are shown in the table below: -/// -/// | Return code | Description -/// |:--------------------------|:---------------------------------------------- -/// | `SbiRet::success()` | `counter_info` read successfully. -/// | `SbiRet::invalid_param()` | `counter_idx` points to an invalid counter. -/// -/// This function is defined in RISC-V SBI Specification chapter 11.6. -#[inline] -pub fn pmu_counter_get_info(counter_idx: usize) -> SbiRet { - sbi_call_1(EID_PMU, COUNTER_GET_INFO, counter_idx) -} - -/// Find and configure a counter from a set of counters. -/// -/// The counters to be found and configured should not be started (or enabled) -/// and should be able to monitor the specified event. -/// -/// # Parameters -/// -/// The `counter_idx_base` and `counter_idx_mask` parameters represent the set of counters, -/// whereas the `event_idx` represent the event to be monitored -/// and `event_data` represents any additional event configuration. -/// -/// The `config_flags` parameter represents additional configuration and filter flags of the counter. -/// The bit definitions of the `config_flags` parameter are shown in the table below: -/// -/// | Flag Name | Bits | Description -/// |:-----------------------------|:-----------|:------------ -/// | SBI_PMU_CFG_FLAG_SKIP_MATCH | 0:0 | Skip the counter matching -/// | SBI_PMU_CFG_FLAG_CLEAR_VALUE | 1:1 | Clear (or zero) the counter value in counter configuration -/// | SBI_PMU_CFG_FLAG_AUTO_START | 2:2 | Start the counter after configuring a matching counter -/// | SBI_PMU_CFG_FLAG_SET_VUINH | 3:3 | Event counting inhibited in VU-mode -/// | SBI_PMU_CFG_FLAG_SET_VSINH | 4:4 | Event counting inhibited in VS-mode -/// | SBI_PMU_CFG_FLAG_SET_UINH | 5:5 | Event counting inhibited in U-mode -/// | SBI_PMU_CFG_FLAG_SET_SINH | 6:6 | Event counting inhibited in S-mode -/// | SBI_PMU_CFG_FLAG_SET_MINH | 7:7 | Event counting inhibited in M-mode -/// | _RESERVED_ | 8:(XLEN-1) | _All non-zero values are reserved for future use._ -/// -/// *NOTE:* When *SBI_PMU_CFG_FLAG_SKIP_MATCH* is set in `config_flags`, the -/// SBI implementation will unconditionally select the first counter from the -/// set of counters specified by the `counter_idx_base` and `counter_idx_mask`. -/// -/// *NOTE:* The *SBI_PMU_CFG_FLAG_AUTO_START* flag in `config_flags` has no -/// impact on the value of the counter. -/// -/// *NOTE:* The `config_flags[3:7]` bits are event filtering hints so these -/// can be ignored or overridden by the SBI implementation for security concerns -/// or due to lack of event filtering support in the underlying RISC-V platform. -/// -/// # Return value -/// -/// Returns the `counter_idx` in `sbiret.value` upon success. -/// -/// In case of failure, the possible error codes returned in `sbiret.error` are shown in the table below: -/// -/// | Return code | Description -/// |:--------------------------|:---------------------------------------------- -/// | `SbiRet::success()` | counter found and configured successfully. -/// | `SbiRet::invalid_param()` | set of counters has an invalid counter. -/// | `SbiRet::not_supported()` | none of the counters can monitor specified event. -/// -/// This function is defined in RISC-V SBI Specification chapter 11.7. -#[inline] -pub fn pmu_counter_config_matching( - counter_idx_base: usize, - counter_idx_mask: usize, - config_flags: T, - event_idx: usize, - event_data: u64, -) -> SbiRet -where - T: ConfigFlags, -{ - match () { - #[cfg(target_pointer_width = "32")] - () => crate::binary::sbi_call_6( - EID_PMU, - COUNTER_CONFIG_MATCHING, - counter_idx_base, - counter_idx_mask, - config_flags.raw(), - event_idx, - event_data as _, - (event_data >> 32) as _, - ), - #[cfg(target_pointer_width = "64")] - () => crate::binary::sbi_call_5( - EID_PMU, - COUNTER_CONFIG_MATCHING, - counter_idx_base, - counter_idx_mask, - config_flags.raw(), - event_idx, - event_data as _, - ), - } -} - -/// Start or enable a set of counters on the calling hart with the specified initial value. -/// -/// # Parameters -/// -/// The `counter_idx_base` and `counter_idx_mask` parameters represent the set of counters. -/// whereas the `initial_value` parameter specifies the initial value of the counter. -/// -/// The bit definitions of the `start_flags` parameter are shown in the table below: -/// -/// | Flag Name | Bits | Description -/// |:-----------------------------|:-----------|:------------ -/// | SBI_PMU_START_SET_INIT_VALUE | 0:0 | Set the value of counters based on the `initial_value` parameter. -/// | _RESERVED_ | 1:(XLEN-1) | _All non-zero values are reserved for future use._ -/// -/// *NOTE*: When `SBI_PMU_START_SET_INIT_VALUE` is not set in `start_flags`, the value of counter will -/// not be modified, and event counting will start from the current value of counter. -/// -/// # Return value -/// -/// The possible return error codes returned in `SbiRet.error` are shown in the table below: -/// -/// | Return code | Description -/// |:----------------------------|:---------------------------------------------- -/// | `SbiRet::success()` | counter started successfully. -/// | `SbiRet::invalid_param()` | some of the counters specified in parameters are invalid. -/// | `SbiRet::already_started()` | some of the counters specified in parameters are already started. -/// -/// This function is defined in RISC-V SBI Specification chapter 11.8. -#[inline] -pub fn pmu_counter_start( - counter_idx_base: usize, - counter_idx_mask: usize, - start_flags: T, - initial_value: u64, -) -> SbiRet -where - T: StartFlags, -{ - match () { - #[cfg(target_pointer_width = "32")] - () => crate::binary::sbi_call_5( - EID_PMU, - COUNTER_START, - counter_idx_base, - counter_idx_mask, - start_flags.raw(), - initial_value as _, - (initial_value >> 32) as _, - ), - #[cfg(target_pointer_width = "64")] - () => crate::binary::sbi_call_4( - EID_PMU, - COUNTER_START, - counter_idx_base, - counter_idx_mask, - start_flags.raw(), - initial_value as _, - ), - } -} - -/// Stop or disable a set of counters on the calling hart. -/// -/// # Parameters -/// -/// The `counter_idx_base` and `counter_idx_mask` parameters represent the set of counters. -/// The bit definitions of the `stop_flags` parameter are shown in the table below: -/// -/// | Flag Name | Bits | Description -/// |:------------------------|:-----------|:------------ -/// | SBI_PMU_STOP_FLAG_RESET | 0:0 | Reset the counter to event mapping. -/// | _RESERVED_ | 1:(XLEN-1) | *All non-zero values are reserved for future use.* -/// -/// # Return value -/// -/// The possible return error codes returned in `SbiRet.error` are shown in the table below: -/// -/// | Return code | Description -/// |:----------------------------|:---------------------------------------------- -/// | `SbiRet::success()` | counter stopped successfully. -/// | `SbiRet::invalid_param()` | some of the counters specified in parameters are invalid. -/// | `SbiRet::already_stopped()` | some of the counters specified in parameters are already stopped. -/// -/// This function is defined in RISC-V SBI Specification chapter 11.9. -#[inline] -pub fn pmu_counter_stop( - counter_idx_base: usize, - counter_idx_mask: usize, - stop_flags: T, -) -> SbiRet -where - T: StopFlags, -{ - sbi_call_3( - EID_PMU, - COUNTER_STOP, - counter_idx_base, - counter_idx_mask, - stop_flags.raw(), - ) -} - -/// Provide the current value of a firmware counter. -/// -/// On RV32 systems, the `SbiRet.value` will only contain the lower 32 bits from the current -/// value of the firmware counter. -/// -/// # Parameters -/// -/// This function should be only used to read a firmware counter. It will return an error -/// when a user provides a hardware counter in `counter_idx` parameter. -/// -/// # Return value -/// -/// The possible return error codes returned in `SbiRet.error` are shown in the table below: -/// -/// | Return code | Description -/// |:--------------------------|:---------------------------------------------- -/// | `SbiRet::success()` | firmware counter read successfully. -/// | `SbiRet::invalid_param()` | `counter_idx` points to a hardware counter or an invalid counter. -/// -/// This function is defined in RISC-V SBI Specification chapter 11.10. -#[inline] -pub fn pmu_counter_fw_read(counter_idx: usize) -> SbiRet { - sbi_call_1(EID_PMU, COUNTER_FW_READ, counter_idx) -} - -/// Provide the upper 32 bits from the value of a firmware counter. -/// -/// This function always returns zero in `SbiRet.value` for RV64 (or higher) systems. -/// -/// # Return value -/// -/// The possible return error codes returned in `SbiRet.error` are shown in the table below: -/// -/// | Return code | Description -/// |:--------------------------|:---------------------------------------------- -/// | `SbiRet::success()` | firmware counter read successfully. -/// | `SbiRet::invalid_param()` | `counter_idx` points to a hardware counter or an invalid counter. -/// -/// This function is defined in RISC-V SBI Specification chapter 11.11. -#[inline] -pub fn pmu_counter_fw_read_hi(counter_idx: usize) -> SbiRet { - sbi_call_1(EID_PMU, COUNTER_FW_READ_HI, counter_idx) -} - -/// Flags to configure performance counter. -pub trait ConfigFlags { - /// Get a raw value to pass to SBI environment. - fn raw(&self) -> usize; -} - -#[cfg(feature = "integer-impls")] -impl ConfigFlags for usize { - #[inline] - fn raw(&self) -> usize { - *self - } -} - -/// Flags to start performance counter. -pub trait StartFlags { - /// Get a raw value to pass to SBI environment. - fn raw(&self) -> usize; -} - -#[cfg(feature = "integer-impls")] -impl StartFlags for usize { - #[inline] - fn raw(&self) -> usize { - *self - } -} - -/// Flags to stop performance counter. -pub trait StopFlags { - /// Get a raw value to pass to SBI environment. - fn raw(&self) -> usize; -} - -#[cfg(feature = "integer-impls")] -impl StopFlags for usize { - #[inline] - fn raw(&self) -> usize { - *self - } -} diff --git a/third-party/vendor/sbi-rt/src/rfnc.rs b/third-party/vendor/sbi-rt/src/rfnc.rs deleted file mode 100644 index 19d8ce4e..00000000 --- a/third-party/vendor/sbi-rt/src/rfnc.rs +++ /dev/null @@ -1,228 +0,0 @@ -//! Chapter 8. RFENCE Extension (EID #0x52464E43 "RFNC") - -use crate::binary::{sbi_call_2, sbi_call_4, sbi_call_5}; - -use sbi_spec::{ - binary::{HartMask, SbiRet}, - rfnc::{ - EID_RFNC, REMOTE_FENCE_I, REMOTE_HFENCE_GVMA, REMOTE_HFENCE_GVMA_VMID, REMOTE_HFENCE_VVMA, - REMOTE_HFENCE_VVMA_ASID, REMOTE_SFENCE_VMA, REMOTE_SFENCE_VMA_ASID, - }, -}; - -/// Execute `FENCE.I` instruction on remote harts. -/// -/// # Return value -/// -/// Returns `SbiRet::success()` when a remote fence was sent to all the targeted harts successfully. -/// -/// This function is defined in RISC-V SBI Specification chapter 8.1. -#[inline] -pub fn remote_fence_i(hart_mask: HartMask) -> SbiRet { - let (hart_mask, hart_mask_base) = hart_mask.into_inner(); - sbi_call_2(EID_RFNC, REMOTE_FENCE_I, hart_mask, hart_mask_base) -} - -/// Execute `SFENCE.VMA` instructions for all address spaces on remote harts. -/// -/// This function instructs the remote harts to execute one or more `SFENCE.VMA` instructions, -/// covering the range of virtual addresses between `start_addr` and `size`. -/// -/// # Return value -/// -/// The possible return error codes returned in `SbiRet.error` are shown in the table below: -/// -/// | Return code | Description -/// |:----------------------------|:---------------------------------------------- -/// | `SbiRet::success()` | A remote fence was sent to all the targeted harts successfully. -/// | `SbiRet::invalid_address()` | `start_addr` or `size` is not valid. -/// -/// This function is defined in RISC-V SBI Specification chapter 8.2. -#[inline] -pub fn remote_sfence_vma(hart_mask: HartMask, start_addr: usize, size: usize) -> SbiRet { - let (hart_mask, hart_mask_base) = hart_mask.into_inner(); - sbi_call_4( - EID_RFNC, - REMOTE_SFENCE_VMA, - hart_mask, - hart_mask_base, - start_addr, - size, - ) -} - -/// Execute address-space-based `SFENCE.VMA` instructions on remote harts. -/// -/// This function instructs the remote harts to execute one or more `SFENCE.VMA` instructions, -/// covering the range of virtual addresses between `start_addr` and `size`. -/// This covers only the given address space by `asid`. -/// -/// # Return value -/// -/// The possible return error codes returned in `SbiRet.error` are shown in the table below: -/// -/// | Return code | Description -/// |:----------------------------|:---------------------------------------------- -/// | `SbiRet::success()` | A remote fence was sent to all the targeted harts successfully. -/// | `SbiRet::invalid_address()` | `start_addr` or `size` is not valid. -/// -/// This function is defined in RISC-V SBI Specification chapter 8.3. -#[inline] -pub fn remote_sfence_vma_asid( - hart_mask: HartMask, - start_addr: usize, - size: usize, - asid: usize, -) -> SbiRet { - let (hart_mask, hart_mask_base) = hart_mask.into_inner(); - sbi_call_5( - EID_RFNC, - REMOTE_SFENCE_VMA_ASID, - hart_mask, - hart_mask_base, - start_addr, - size, - asid, - ) -} - -/// Execute virtual machine id based `HFENCE.GVMA` instructions on remote harts. -/// -/// This function instructs the remote harts to execute one or more `HFENCE.GVMA` -/// instructions, covering the range of guest physical addresses between `start_addr` -/// and `size` only for the given virtual machine by `vmid`. -/// -/// This function call is only valid on harts implementing the RISC-V hypervisor extension. -/// -/// # Return value -/// -/// The possible return error codes returned in `SbiRet.error` are shown in the table below: -/// -/// | Return code | Description -/// |:----------------------------|:---------------------------------------------- -/// | `SbiRet::success()` | A remote fence was sent to all the targeted harts successfully. -/// | `SbiRet::not_supported()` | This function is not supported as it is not implemented or one of the target hart doesn’t support hypervisor extension. -/// | `SbiRet::invalid_address()` | `start_addr` or `size` is not valid. -/// -/// This function is defined in RISC-V SBI Specification chapter 8.4. -#[inline] -pub fn remote_hfence_gvma_vmid( - hart_mask: HartMask, - start_addr: usize, - size: usize, - vmid: usize, -) -> SbiRet { - let (hart_mask, hart_mask_base) = hart_mask.into_inner(); - sbi_call_5( - EID_RFNC, - REMOTE_HFENCE_GVMA_VMID, - hart_mask, - hart_mask_base, - start_addr, - size, - vmid, - ) -} - -/// Execute `HFENCE.GVMA` instructions for all virtual machines on remote harts. -/// -/// This function instructs the remote harts to execute one or more `HFENCE.GVMA` instructions, -/// covering the range of guest physical addresses between `start_addr` and `size` -/// for all the guests. -/// -/// This function call is only valid on harts implementing the RISC-V hypervisor extension. -/// -/// # Return value -/// -/// The possible return error codes returned in `SbiRet.error` are shown in the table below: -/// -/// | Return code | Description -/// |:----------------------------|:---------------------------------------------- -/// | `SbiRet::success()` | A remote fence was sent to all the targeted harts successfully. -/// | `SbiRet::not_supported()` | This function is not supported as it is not implemented or one of the target hart does not support hypervisor extension. -/// | `SbiRet::invalid_address()` | `start_addr` or `size` is not valid. -/// -/// This function is defined in RISC-V SBI Specification chapter 8.5. -#[inline] -pub fn remote_hfence_gvma(hart_mask: HartMask, start_addr: usize, size: usize) -> SbiRet { - let (hart_mask, hart_mask_base) = hart_mask.into_inner(); - sbi_call_4( - EID_RFNC, - REMOTE_HFENCE_GVMA, - hart_mask, - hart_mask_base, - start_addr, - size, - ) -} - -/// Execute address space based `HFENCE.VVMA` for current virtual machine on remote harts. -/// -/// This function instructs the remote harts to execute one or more `HFENCE.VVMA` instructions, -/// covering the range of guest virtual addresses between `start_addr` and `size` for the given -/// address space by `asid` and current virtual machine (by `vmid` in `hgatp` CSR) -/// of calling hart. -/// -/// This function call is only valid on harts implementing the RISC-V hypervisor extension. -/// -/// # Return value -/// -/// The possible return error codes returned in `SbiRet.error` are shown in the table below: -/// -/// | Return code | Description -/// |:----------------------------|:---------------------------------------------- -/// | `SbiRet::success()` | A remote fence was sent to all the targeted harts successfully. -/// | `SbiRet::not_supported()` | This function is not supported as it is not implemented or one of the target hart does not support hypervisor extension. -/// | `SbiRet::invalid_address()` | `start_addr` or `size` is not valid. -/// -/// This function is defined in RISC-V SBI Specification chapter 8.6. -#[inline] -pub fn remote_hfence_vvma_asid( - hart_mask: HartMask, - start_addr: usize, - size: usize, - asid: usize, -) -> SbiRet { - let (hart_mask, hart_mask_base) = hart_mask.into_inner(); - sbi_call_5( - EID_RFNC, - REMOTE_HFENCE_VVMA_ASID, - hart_mask, - hart_mask_base, - start_addr, - size, - asid, - ) -} - -/// Execute `HFENCE.VVMA` for all address spaces in the current virtual machine on remote harts. -/// -/// This function instructs the remote harts to execute one or more `HFENCE.VVMA` instructions, -/// covering the range of guest virtual addresses between `start_addr` and `size` -/// for current virtual machine (by `vmid` in `hgatp` CSR) of calling hart. -/// -/// This function call is only valid on harts implementing the RISC-V hypervisor extension. -/// -/// # Return value -/// -/// The possible return error codes returned in `SbiRet.error` are shown in the table below: -/// -/// | Return code | Description -/// |:----------------------------|:---------------------------------------------- -/// | `SbiRet::success()` | A remote fence was sent to all the targeted harts successfully. -/// | `SbiRet::not_supported()` | This function is not supported as it is not implemented or one of the target hart doesn’t support hypervisor extension. -/// | `SbiRet::invalid_address()` | `start_addr` or `size` is not valid. -/// -/// This function is defined in RISC-V SBI Specification chapter 8.7. -#[inline] -pub fn remote_hfence_vvma(hart_mask: HartMask, start_addr: usize, size: usize) -> SbiRet { - let (hart_mask, hart_mask_base) = hart_mask.into_inner(); - sbi_call_4( - EID_RFNC, - REMOTE_HFENCE_VVMA, - hart_mask, - hart_mask_base, - start_addr, - size, - ) -} diff --git a/third-party/vendor/sbi-rt/src/spi.rs b/third-party/vendor/sbi-rt/src/spi.rs deleted file mode 100644 index 7ade1155..00000000 --- a/third-party/vendor/sbi-rt/src/spi.rs +++ /dev/null @@ -1,23 +0,0 @@ -//! Chapter 7. IPI Extension (EID #0x735049 "sPI: s-mode IPI") - -use crate::binary::sbi_call_2; - -use sbi_spec::{ - binary::{HartMask, SbiRet}, - spi::{EID_SPI, SEND_IPI}, -}; - -/// Send an inter-processor interrupt to all harts defined in hart mask. -/// -/// Inter-processor interrupts manifest at the receiving harts as the supervisor software interrupts. -/// -/// # Return value -/// -/// Should return `SbiRet::success()` if IPI was sent to all the targeted harts successfully. -/// -/// This function is defined in RISC-V SBI Specification chapter 7.1. -#[inline] -pub fn send_ipi(hart_mask: HartMask) -> SbiRet { - let (hart_mask, hart_mask_base) = hart_mask.into_inner(); - sbi_call_2(EID_SPI, SEND_IPI, hart_mask, hart_mask_base) -} diff --git a/third-party/vendor/sbi-rt/src/srst.rs b/third-party/vendor/sbi-rt/src/srst.rs deleted file mode 100644 index bdeca2f3..00000000 --- a/third-party/vendor/sbi-rt/src/srst.rs +++ /dev/null @@ -1,113 +0,0 @@ -//! Chapter 10. System Reset Extension (EID #0x53525354 "SRST") - -use crate::binary::sbi_call_2; - -use sbi_spec::{ - binary::SbiRet, - srst::{ - EID_SRST, RESET_REASON_NO_REASON, RESET_REASON_SYSTEM_FAILURE, RESET_TYPE_COLD_REBOOT, - RESET_TYPE_SHUTDOWN, RESET_TYPE_WARM_REBOOT, SYSTEM_RESET, - }, -}; - -/// Reset the system based on provided `reset_type` and `reset_reason`. -/// -/// This is a synchronous call and does not return if it succeeds. -/// -/// # Warm reboot and cold reboot -/// -/// When supervisor software is running natively, the SBI implementation is machine mode firmware. -/// In this case, shutdown is equivalent to physical power down of the entire system, and -/// cold reboot is equivalent to a physical power cycle of the entire system. -/// Further, warm reboot is equivalent to a power cycle of the main processor and parts of the system -/// but not the entire system. -/// -/// For example, on a server class system with a BMC (board management controller), -/// a warm reboot will not power cycle the BMC whereas a cold reboot will definitely power cycle the BMC. -/// -/// When supervisor software is running inside a virtual machine, the SBI implementation is a hypervisor. -/// The shutdown, cold reboot and warm reboot will behave functionally the same as the native case but might -/// not result in any physical power changes. -/// -/// This function is defined in RISC-V SBI Specification chapter 10.1. -#[inline] -pub fn system_reset(reset_type: T, reset_reason: R) -> SbiRet -where - T: ResetType, - R: ResetReason, -{ - sbi_call_2( - EID_SRST, - SYSTEM_RESET, - reset_type.raw() as _, - reset_reason.raw() as _, - ) -} - -/// A valid type for system reset. -pub trait ResetType { - /// Get a raw value to pass to SBI environment. - fn raw(&self) -> u32; -} - -#[cfg(feature = "integer-impls")] -impl ResetType for u32 { - #[inline] - fn raw(&self) -> u32 { - *self - } -} - -#[cfg(feature = "integer-impls")] -impl ResetType for i32 { - #[inline] - fn raw(&self) -> u32 { - u32::from_ne_bytes(i32::to_ne_bytes(*self)) - } -} - -/// A valid reason for system reset. -pub trait ResetReason { - /// Get a raw value to pass to SBI environment. - fn raw(&self) -> u32; -} - -#[cfg(feature = "integer-impls")] -impl ResetReason for u32 { - #[inline] - fn raw(&self) -> u32 { - *self - } -} - -#[cfg(feature = "integer-impls")] -impl ResetReason for i32 { - #[inline] - fn raw(&self) -> u32 { - u32::from_ne_bytes(i32::to_ne_bytes(*self)) - } -} - -macro_rules! define_reset_param { - ($($struct:ident($value:expr): $trait:ident #[$doc:meta])*) => { - $( - #[derive(Clone, Copy, Debug)] - #[$doc] - pub struct $struct; - impl $trait for $struct { - #[inline] - fn raw(&self) -> u32 { - $value - } - } - )* - }; -} - -define_reset_param! { - Shutdown(RESET_TYPE_SHUTDOWN): ResetType /// Shutdown as a reset type. - ColdReboot(RESET_TYPE_COLD_REBOOT): ResetType /// Cold reboot as a reset type. - WarmReboot(RESET_TYPE_WARM_REBOOT): ResetType /// Warm reboot as a reset type. - NoReason(RESET_REASON_NO_REASON): ResetReason /// No reason as a reset reason. - SystemFailure(RESET_REASON_SYSTEM_FAILURE): ResetReason /// System failure as a reset reason. -} diff --git a/third-party/vendor/sbi-rt/src/sta.rs b/third-party/vendor/sbi-rt/src/sta.rs deleted file mode 100644 index 4f962fa1..00000000 --- a/third-party/vendor/sbi-rt/src/sta.rs +++ /dev/null @@ -1,67 +0,0 @@ -//! Chapter 16. Steal-time Accounting Extension (EID #0x535441 "STA") - -use crate::binary::sbi_call_3; - -use sbi_spec::{ - binary::{SbiRet, SharedPtr}, - sta::{EID_STA, SET_SHMEM}, -}; - -/// Prepare shared memory for steal-time accounting feature. -/// -/// Set the shared memory physical base address for steal-time accounting of the calling virtual hart and -/// enable the SBI implementation’s steal-time information reporting. -/// -/// It is not expected for the shared memory to be written by the supervisor-mode software -/// while it is in use for steal-time accounting. However, the SBI implementation MUST not misbehave -/// if a write operation from supervisor-mode software occurs, however, in that case, -/// it MAY leave the shared memory filled with inconsistent data. -/// -/// *NOTE:* Not writing to the shared memory when the supervisor-mode software is not runnable -/// avoids unnecessary work and supports repeatable capture of a system image -/// while the supervisor-mode software is suspended. -/// -/// # STA Shared Memory Structure -/// -/// | Name | Offset | Size | Description -/// |:----------|:-------|:-----|:------------ -/// | `sequence` | 0 | 4 | The SBI implementation MUST increment this field to an odd value before writing the `steal` field, and increment it again to an even value after writing `steal` (i.e. an odd sequence number indicates an in-progress update). The SBI implementation SHOULD ensure that the sequence field remains odd for only very short periods of time.

The supervisor-mode software MUST check this field before and after reading the `steal` field, and repeat the read if it is different or odd.

This sequence field enables the value of the steal field to be read by supervisor-mode software executed in a 32-bit environment. -/// | `flags` | 4 | 4 | Always zero.

Future extensions of the SBI call might allow the supervisor-mode software to write to some fields of the shared memory. Such extensions will not be enabled as long as a zero value is used for the flags argument to the SBI call. -/// | `steal` | 8 | 8 | The amount of time in which this virtual hart was not idle and scheduled out, in nanoseconds. The time during which the virtual hart is idle will not be reported as steal-time. -/// | `preempted` | 16 | 1 | An advisory flag indicating whether the virtual hart which registered this structure is running or not. A non-zero value MAY be written by the SBI implementation if the virtual hart has been preempted (i.e., while the `steal` field is increasing), while a zero value MUST be written before the virtual hart starts to run again.

This preempted field can, for example, be used by the supervisor-mode software to check if a lock holder has been preempted, and, in that case, disable optimistic spinning. -/// | `pad` | 17 | 47 | Pad with zeros to a 64-byte boundary. -/// -/// # Parameters -/// -/// If `shmem` address is not all-ones bitwise, then `shmem` specifies the shared memory -/// physical base address. `shmem` MUST be 64-byte aligned. The size of the shared memory -/// must be 64 bytes. All bytes MUST be set to zero by the SBI implementation before returning -/// from the SBI call. -/// -/// If `shmem` address is all-ones bitwise, the SBI implementation will stop reporting -/// steal-time information for the virtual hart. -/// -/// The `flags` parameter is reserved for future use and MUST be zero. -/// -/// # Return value -/// -/// `SbiRet.value` is set to zero, and the possible error codes returned in `SbiRet.error` are shown in the table below: -/// -/// | Error code | Description -/// |:----------------------------|:--------------------------------- -/// | `SbiRet::success()` | The steal-time shared memory physical base address was set or cleared successfully. -/// | `SbiRet::invalid_param()` | The `flags` parameter is not zero or the shmem_phys_lo is not 64-byte aligned. -/// | `SbiRet::invalid_address()` | The shared memory pointed to by the `shmem` parameter is not writable or does not satisfy other requirements of STA Shared Memory Structure. -/// | `SbiRet::failed()` | The request failed for unspecified or unknown other reasons. -/// -/// This function is defined in RISC-V SBI Specification chapter 16.1. -#[inline] -pub fn sta_set_shmem(shmem: SharedPtr<[u8; 64]>, flags: usize) -> SbiRet { - sbi_call_3( - EID_STA, - SET_SHMEM, - shmem.phys_addr_lo(), - shmem.phys_addr_hi(), - flags, - ) -} diff --git a/third-party/vendor/sbi-rt/src/susp.rs b/third-party/vendor/sbi-rt/src/susp.rs deleted file mode 100644 index 0a0f0647..00000000 --- a/third-party/vendor/sbi-rt/src/susp.rs +++ /dev/null @@ -1,88 +0,0 @@ -//! Chapter 13. System Suspend Extension (EID #0x53555350 "SUSP") - -use crate::binary::sbi_call_3; -use sbi_spec::{ - binary::SbiRet, - susp::{EID_SUSP, SUSPEND}, -}; - -/// Suspend the system based on provided `sleep_type`. -/// -/// # Parameters -/// -/// The `sleep_type` parameter specifies the sleep type. -/// -/// | Type | Name | Description -/// |:------------------------|:---------------|:---------------------------------------------- -/// | 0 | SUSPEND_TO_RAM | This is a "suspend to RAM" sleep type, similar to ACPI's S2 or S3. Entry requires all but the calling hart be in the HSM `STOPPED` state and all hart registers and CSRs saved to RAM. -/// | 0x00000001 - 0x7fffffff | | Reserved for future use -/// | 0x80000000 - 0xffffffff | | Platform-specific system sleep types -/// -/// The `resume_addr` parameter points to a runtime-specified physical address, -/// where the hart can resume execution in supervisor-mode after a system suspend. -/// -/// The `opaque` parameter is an XLEN-bit value that will be set in the `a1` -/// register when the hart resumes execution at `resume_addr` after a system -/// suspend. -/// -/// # Return value -/// -/// The possible return error codes returned in `SbiRet.error` are shown in -/// the table below: -/// -/// | Return code | Description -/// |:--------------------------|:---------------------------------------------- -/// | `SbiRet::success()` | The suspend request is accepted, and the system is suspended. The system will resume execution at `resume_addr` after the sleep period. -/// | `SbiRet::invalid_param()` | `sleep_type` is reserved or is platform-specific and unimplemented. -/// | `SbiRet::not_supported()` | `sleep_type` is not reserved and is implemented, but the platform does not support it due to one or more missing dependencies. -/// | `SbiRet::invalid_address()` | `resume_addr` is not valid, possibly due to the following reasons: + * It is not a valid physical address. + * Executable access to the address is prohibited by a physical memory protection mechanism or H-extension G-stage for supervisor mode. -/// | `SbiRet::denied()` | The suspend request failed due to unsatisfied entry criteria. -/// | `SbiRet::failed()` | The suspend request failed for unspecified or unknown other reasons. -/// -/// This function is defined in RISC-V SBI Specification chapter 13.1. -#[inline] -pub fn system_suspend(sleep_type: T, resume_addr: usize, opaque: usize) -> SbiRet -where - T: SleepType, -{ - sbi_call_3( - EID_SUSP, - SUSPEND, - sleep_type.raw() as _, - resume_addr, - opaque, - ) -} - -/// A valid sleep type for system suspend. -pub trait SleepType { - /// Get a raw value to pass to SBI environment. - fn raw(&self) -> u32; -} - -#[cfg(feature = "integer-impls")] -impl SleepType for u32 { - #[inline] - fn raw(&self) -> u32 { - *self - } -} - -#[cfg(feature = "integer-impls")] -impl SleepType for i32 { - #[inline] - fn raw(&self) -> u32 { - u32::from_ne_bytes(i32::to_ne_bytes(*self)) - } -} - -/// Suspend to RAM as sleep type. -#[derive(Clone, Copy, Debug)] -pub struct SuspendToRam; - -impl SleepType for SuspendToRam { - #[inline] - fn raw(&self) -> u32 { - 0 - } -} diff --git a/third-party/vendor/sbi-rt/src/time.rs b/third-party/vendor/sbi-rt/src/time.rs deleted file mode 100644 index 8c36b4a8..00000000 --- a/third-party/vendor/sbi-rt/src/time.rs +++ /dev/null @@ -1,31 +0,0 @@ -//! Chapter 6. Timer Extension (EID #0x54494D45 "TIME") - -use sbi_spec::{ - binary::SbiRet, - time::{EID_TIME, SET_TIMER}, -}; - -/// Programs the clock for the next event after an absolute time. -/// -/// Parameter `stime_value` is in absolute time. -/// This function must clear the pending timer-interrupt bit as well. -/// -/// If the supervisor wishes to clear the timer interrupt without scheduling the next timer event, -/// it can either request a timer interrupt infinitely far into the future (i.e., `u64::MAX`), -/// or it can instead mask the timer interrupt by clearing `sie.STIE` CSR bit. -/// -/// This function is defined in RISC-V SBI Specification chapter 6.1. -#[inline] -pub fn set_timer(stime_value: u64) -> SbiRet { - match () { - #[cfg(target_pointer_width = "32")] - () => crate::binary::sbi_call_2( - EID_TIME, - SET_TIMER, - stime_value as _, - (stime_value >> 32) as _, - ), - #[cfg(target_pointer_width = "64")] - () => crate::binary::sbi_call_1(EID_TIME, SET_TIMER, stime_value as _), - } -} diff --git a/third-party/vendor/sbi-spec/.cargo-checksum.json b/third-party/vendor/sbi-spec/.cargo-checksum.json deleted file mode 100644 index 4fb69648..00000000 --- a/third-party/vendor/sbi-spec/.cargo-checksum.json +++ /dev/null @@ -1 +0,0 @@ -{"files":{"CHANGELOG.md":"f9eb48271745fdf33bef22a4913bd2709398d483a2a1dd7f096ac3ec3871f2ae","Cargo.toml":"e35db58ea257dedfd49d481a41671ae8fe47ddc9eab9892234afc13acf3c87cf","LICENSE-MIT":"4af1c00d7ba6c13e37055a90960431e08c55c041acd3660d358699465e5059f5","LICENSE-MULAN":"86fec511f349365f8db0c46b2e0f78ac4d3e750e7386418586670425478aaaa5","README.md":"697042fab5db23591ee36b206d245d8e204a89c661cb821a0cd4785121eb1d7d","src/base.rs":"b50ac153f0571c59cca689243eec63d9fe0a0f3272f94e369b43848e829805ab","src/binary.rs":"3929f0c20808a28b3c25d186bbd7c51711a04d53595d3b4b371e59f01d29003d","src/cppc.rs":"bed2064a56c93c386f62ea960975602bbe924e9e5577c95bb60a5f94264e41c4","src/dbcn.rs":"decb977f1d3b31c358a676310dce3c09498617b4c743069fd29a5c04d2215fe3","src/hsm.rs":"0f868945c43dbbc87850944d66c8b2a5ba3de1af629e1283353d64e23970ceee","src/legacy.rs":"08e0c16ff9737bd063e96b95ada152546f95fce2295411af87f3f53abeb7ab20","src/lib.rs":"9db07db63869d05fc635abbfcae7c38fc3d23e34cc45855193af668d6bee4ee1","src/nacl.rs":"b4ff718cdf1ed74b5b0dda0dcdcf7649ce7efbdb51e71af72950ae5175aaeb2e","src/pmu.rs":"39560280b2d013b5a9938d9a73d1b0ca1c545dd25b27a8c6084c95ff104a5502","src/rfnc.rs":"9a5289fa8ae3ece4e0822b92f649d947dab5bf87c039633f6e5d6fdb0b317c23","src/spi.rs":"92d0ec15ad8b47d99b7636a9e6efbce55466bef21d868427e58a49d039372a92","src/srst.rs":"026e25fc0d7bb6ca4abe41cc6e816e48dacaf1b9d0c659155968f415806a1c1f","src/sta.rs":"922e083bb2ec7be5a77b173aa74b82d0dc232dc4b57a65074837e71e89188647","src/susp.rs":"66444fb9794a6384778022e51a5931500be42c1f28e0f6aedbb97d8fc52b15cd","src/time.rs":"cebdcf0ab2e528f9f66dda3c1aeb000eab7e1c8bb816193dad36179a2255a84d"},"package":"e6e36312fb5ddc10d08ecdc65187402baba4ac34585cb9d1b78522ae2358d890"} \ No newline at end of file diff --git a/third-party/vendor/sbi-spec/CHANGELOG.md b/third-party/vendor/sbi-spec/CHANGELOG.md deleted file mode 100644 index e6c7d9c3..00000000 --- a/third-party/vendor/sbi-spec/CHANGELOG.md +++ /dev/null @@ -1,117 +0,0 @@ -# Changelog - -All notable changes to this project will be documented in this file. - -The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). - -## [Unreleased] - -### Added - -### Modified - -### Fixed - -## [0.0.7] - 2024-02-05 - -`sbi-spec` crate now supports RISC-V SBI version 2.0 ratified. - -### Added - -- Support to PMU events in Chapter 11 -- Support `NACL` extension in Chapter 15 -- Support `STA` extension in Chapter 16 -- Add new SBI error `NoShmem` -- binary: add `SharedPtr` struct to represent shared memory range feature. -- nacl: add `shmem_size` module -- Move `HartMask` structure to `sbi-spec` crate from `rustsbi` crate. - -### Modified - -- Rearrange `HSM` constants into modules. - -### Fixed - -- Remove redundant prefixes in `PMU` -- Add new function id `SNAPSHOT_SET_SHMEM` in `PMU` -- Grammar fixes on documents - -## [0.0.6] - 2023-04-04 - -### Added - -- `Physical` shared memory physical address range with type annotation in Chapter 3 -- Support to RISC-V SBI System Suspend extension -- Support to CPPC extension - -## [0.0.5] - 2023-02-16 - -### Added - -- Adapt to RISC-V SBI specification version 2.0-rc1 -- `PMU_COUNTER_FW_READ_HI` function in `pmu` module for RV32 systems -- SBI DBCN extension support -- `Result`-like documents to `SbiRet` - -### Modified - -- style: add period to docs - -## [0.0.4] - 2022-10-10 - -### Added - -- Various convenient functions to `SbiRet` structure -- Add documents on whole `sbi-rt` crate to coply with `deny(missing_docs)` -- Feature `legacy` to gate legacy SBI extension - -### Modified - -- Rename `SbiRet::ok` to `SbiRet::success` -- Rename `SbiSpecVersion` to struct `Version` - -## [0.0.3] - 2022-10-06 - -### Added - -- deps: static_assertions - check implementations during compilation, and provide an item list for developers -- denied: warnings and unsafe code -- a github workflow to check building -- `SbiSpecVersion` type defination for sbi base - -### Modified - -- rename `GET_SPEC_VERSION` to `GET_SBI_SPEC_VERSION` -- rename `impl_id::IMPL_XXX` to `impl_id::XXX` - -### Removed - -- default target to RISC-V - -## [0.0.2] - 2022-07-21 - -### Added - -- A changelog to this project - -### Modified - -- Lift build target limit; now this crate would build on targets other than RISC-V - -## [0.0.1] - 2022-07-11 - -This is the first release of sbi-spec crate. This crate includes definition of RISC-V Supervisor Binary Interface (SBI) including structures and constants. - -### Added - -- Adapt to SBI specification version 1.0.0 ratified - -[Unreleased]: https://github.com/rustsbi/sbi-spec/compare/v0.0.7...HEAD -[0.0.7]: https://github.com/rustsbi/sbi-spec/compare/v0.0.6...v0.0.7 -[0.0.6]: https://github.com/rustsbi/sbi-spec/compare/v0.0.5...v0.0.6 -[0.0.5]: https://github.com/rustsbi/sbi-spec/compare/v0.0.4...v0.0.5 -[0.0.4]: https://github.com/rustsbi/sbi-spec/compare/v0.0.3...v0.0.4 -[0.0.3]: https://github.com/rustsbi/sbi-spec/compare/v0.0.2...v0.0.3 -[0.0.2]: https://github.com/rustsbi/sbi-spec/compare/v0.0.1...v0.0.2 -[0.0.1]: https://github.com/rustsbi/sbi-spec/releases/tag/v0.0.1 diff --git a/third-party/vendor/sbi-spec/Cargo.toml b/third-party/vendor/sbi-spec/Cargo.toml deleted file mode 100644 index e49d5df3..00000000 --- a/third-party/vendor/sbi-spec/Cargo.toml +++ /dev/null @@ -1,42 +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 are reading this file be aware that the original Cargo.toml -# will likely look very different (and much more reasonable). -# See Cargo.toml.orig for the original contents. - -[package] -edition = "2021" -name = "sbi-spec" -version = "0.0.7" -authors = [ - "YdrMaster ", - "Luo Jia ", -] -description = "Definitions and constants in RISC-V Supervisor Binary Interface (RISC-V SBI)" -documentation = "https://docs.rs/sbi-spec" -readme = "README.md" -keywords = [ - "riscv", - "sbi", - "rustsbi", -] -categories = [ - "os", - "embedded", - "hardware-support", - "no-std", -] -license = "MulanPSL-2.0 OR MIT" -repository = "https://github.com/rustsbi/rustsbi" - -[dev-dependencies.static_assertions] -version = "1.1.0" - -[features] -default = [] -legacy = [] diff --git a/third-party/vendor/sbi-spec/LICENSE-MIT b/third-party/vendor/sbi-spec/LICENSE-MIT deleted file mode 100644 index 0067cfbe..00000000 --- a/third-party/vendor/sbi-spec/LICENSE-MIT +++ /dev/null @@ -1,8 +0,0 @@ -Copyright 2020 Luo Jia - -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. - diff --git a/third-party/vendor/sbi-spec/LICENSE-MULAN b/third-party/vendor/sbi-spec/LICENSE-MULAN deleted file mode 100644 index 6da88a49..00000000 --- a/third-party/vendor/sbi-spec/LICENSE-MULAN +++ /dev/null @@ -1,101 +0,0 @@ -木兰宽松许可证, 第2版 - -2020年1月 http://license.coscl.org.cn/MulanPSL2 - -您对“软件”的复制、使用、修改及分发受木兰宽松许可证,第2版(“本许可证”)的如下条款的约束: - -0. 定义 - -“软件”是指由“贡献”构成的许可在“本许可证”下的程序和相关文档的集合。 - -“贡献”是指由任一“贡献者”许可在“本许可证”下的受版权法保护的作品。 - -“贡献者”是指将受版权法保护的作品许可在“本许可证”下的自然人或“法人实体”。 - -“法人实体”是指提交贡献的机构及其“关联实体”。 - -“关联实体”是指,对“本许可证”下的行为方而言,控制、受控制或与其共同受控制的机构,此处的控制是指有受控方或共同受控方至少50%直接或间接的投票权、资金或其他有价证券。 - -1. 授予版权许可 - -每个“贡献者”根据“本许可证”授予您永久性的、全球性的、免费的、非独占的、不可撤销的版权许可,您可以复制、使用、修改、分发其“贡献”,不论修改与否。 - -2. 授予专利许可 - -每个“贡献者”根据“本许可证”授予您永久性的、全球性的、免费的、非独占的、不可撤销的(根据本条规定撤销除外)专利许可,供您制造、委托制造、使用、许诺销售、销售、进口其“贡献”或以其他方式转移其“贡献”。前述专利许可仅限于“贡献者”现在或将来拥有或控制的其“贡献”本身或其“贡献”与许可“贡献”时的“软件”结合而将必然会侵犯的专利权利要求,不包括对“贡献”的修改或包含“贡献”的其他结合。如果您或您的“关联实体”直接或间接地,就“软件”或其中的“贡献”对任何人发起专利侵权诉讼(包括反诉或交叉诉讼)或其他专利维权行动,指控其侵犯专利权,则“本许可证”授予您对“软件”的专利许可自您提起诉讼或发起维权行动之日终止。 - -3. 无商标许可 - -“本许可证”不提供对“贡献者”的商品名称、商标、服务标志或产品名称的商标许可,但您为满足第4条规定的声明义务而必须使用除外。 - -4. 分发限制 - -您可以在任何媒介中将“软件”以源程序形式或可执行形式重新分发,不论修改与否,但您必须向接收者提供“本许可证”的副本,并保留“软件”中的版权、商标、专利及免责声明。 - -5. 免责声明与责任限制 - -“软件”及其中的“贡献”在提供时不带任何明示或默示的担保。在任何情况下,“贡献者”或版权所有者不对任何人因使用“软件”或其中的“贡献”而引发的任何直接或间接损失承担责任,不论因何种原因导致或者基于何种法律理论,即使其曾被建议有此种损失的可能性。 - -6. 语言 - -“本许可证”以中英文双语表述,中英文版本具有同等法律效力。如果中英文版本存在任何冲突不一致,以中文版为准。 - -条款结束 - -如何将木兰宽松许可证,第2版,应用到您的软件 - -如果您希望将木兰宽松许可证,第2版,应用到您的新软件,为了方便接收者查阅,建议您完成如下三步: - -1,请您补充如下声明中的空白,包括软件名、软件的首次发表年份以及您作为版权人的名字; - -2,请您在软件包的一级目录下创建以“LICENSE”为名的文件,将整个许可证文本放入该文件中; - -3,请将如下声明文本放入每个源文件的头部注释中。 - -Copyright (c) 2020 Luo Jia - -RustSBI is licensed under Mulan PSL v2. You can use this software according to the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at: http://license.coscl.org.cn/MulanPSL2 - -THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. See the Mulan PSL v2 for more details. - -January 2020 http://license.coscl.org.cn/MulanPSL2 - -Your reproduction, use, modification and distribution of the Software shall be subject to Mulan PSL v2 (this License) with the following terms and conditions: - -0. Definition - -Software means the program and related documents which are licensed under this License and comprise all Contribution(s). - -Contribution means the copyrightable work licensed by a particular Contributor under this License. - -Contributor means the Individual or Legal Entity who licenses its copyrightable work under this License. - -Legal Entity means the entity making a Contribution and all its Affiliates. - -Affiliates means entities that control, are controlled by, or are under common control with the acting entity under this License, ‘control’ means direct or indirect ownership of at least fifty percent (50%) of the voting power, capital or other securities of controlled or commonly controlled entity. - -1. Grant of Copyright License - -Subject to the terms and conditions of this License, each Contributor hereby grants to you a perpetual, worldwide, royalty-free, non-exclusive, irrevocable copyright license to reproduce, use, modify, or distribute its Contribution, with modification or not. - -2. Grant of Patent License - -Subject to the terms and conditions of this License, each Contributor hereby grants to you a perpetual, worldwide, royalty-free, non-exclusive, irrevocable (except for revocation under this Section) patent license to make, have made, use, offer for sale, sell, import or otherwise transfer its Contribution, where such patent license is only limited to the patent claims owned or controlled by such Contributor now or in future which will be necessarily infringed by its Contribution alone, or by combination of the Contribution with the Software to which the Contribution was contributed. The patent license shall not apply to any modification of the Contribution, and any other combination which includes the Contribution. If you or your Affiliates directly or indirectly institute patent litigation (including a cross claim or counterclaim in a litigation) or other patent enforcement activities against any individual or entity by alleging that the Software or any Contribution in it infringes patents, then any patent license granted to you under this License for the Software shall terminate as of the date such litigation or activity is filed or taken. - -3. No Trademark License - -No trademark license is granted to use the trade names, trademarks, service marks, or product names of Contributor, except as required to fulfill notice requirements in Section 4. - -4. Distribution Restriction - -You may distribute the Software in any medium with or without modification, whether in source or executable forms, provided that you provide recipients with a copy of this License and retain copyright, patent, trademark and disclaimer statements in the Software. - -5. Disclaimer of Warranty and Limitation of Liability - -THE SOFTWARE AND CONTRIBUTION IN IT ARE PROVIDED WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED. IN NO EVENT SHALL ANY CONTRIBUTOR OR COPYRIGHT HOLDER BE LIABLE TO YOU FOR ANY DAMAGES, INCLUDING, BUT NOT LIMITED TO ANY DIRECT, OR INDIRECT, SPECIAL OR CONSEQUENTIAL DAMAGES ARISING FROM YOUR USE OR INABILITY TO USE THE SOFTWARE OR THE CONTRIBUTION IN IT, NO MATTER HOW IT’S CAUSED OR BASED ON WHICH LEGAL THEORY, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. - -6. Language - -THIS LICENSE IS WRITTEN IN BOTH CHINESE AND ENGLISH, AND THE CHINESE VERSION AND ENGLISH VERSION SHALL HAVE THE SAME LEGAL EFFECT. IN THE CASE OF DIVERGENCE BETWEEN THE CHINESE AND ENGLISH VERSIONS, THE CHINESE VERSION SHALL PREVAIL. - -END OF THE TERMS AND CONDITIONS diff --git a/third-party/vendor/sbi-spec/README.md b/third-party/vendor/sbi-spec/README.md deleted file mode 100644 index 52a960a7..00000000 --- a/third-party/vendor/sbi-spec/README.md +++ /dev/null @@ -1,41 +0,0 @@ -# SBI 标准的 Rust 实现 - -[![CI](https://github.com/rustsbi/sbi-spec/actions/workflows/build.yml/badge.svg?branch=main)](https://github.com/rustsbi/sbi-spec/actions) -[![Latest version](https://img.shields.io/crates/v/sbi-spec.svg)](https://crates.io/crates/sbi-spec) -[![issue](https://img.shields.io/github/issues/rustsbi/sbi-spec)](https://github.com/rustsbi/sbi-spec/issues) -[![Documentation](https://docs.rs/sbi-spec/badge.svg)](https://docs.rs/sbi-spec) -![license](https://img.shields.io/github/license/rustsbi/sbi-spec) - -这个库用 Rust 实现了 [SBI 标准](https://github.com/riscv-non-isa/riscv-sbi-doc) 定义的常量和结构。 - -2.0 标准各章节的实现情况: - -- §3 - - [x] 常量 - - [x] 结构 -- §4 - - [x] 常量 -- §5 - - [x] 常量 -- §6 - - [x] 常量 -- §7 - - [x] 常量 -- §8 - - [x] 常量 -- §9 - - [x] 常量 -- §10 - - [x] 常量 -- §11 - - [x] 常量 -- §12 - - [x] 常量 -- §13 - - [x] 常量 -- §14 - - [x] 常量 -- §15 - - [x] 常量 -- §16 - - [x] 常量 diff --git a/third-party/vendor/sbi-spec/src/base.rs b/third-party/vendor/sbi-spec/src/base.rs deleted file mode 100644 index a1f151e0..00000000 --- a/third-party/vendor/sbi-spec/src/base.rs +++ /dev/null @@ -1,98 +0,0 @@ -//! Chapter 4. Base Extension (EID #0x10). - -/// Extension ID for RISC-V SBI Base extension. -pub const EID_BASE: usize = 0x10; -pub use fid::*; - -/// Default probe value for the target SBI extension is unavailable. -pub const UNAVAILABLE_EXTENSION: usize = 0; - -/// SBI specification version. -/// -/// Not to be confused with 'implementation version'. -/// -/// Declared in §4.1. -#[derive(Clone, Copy, Debug)] -#[repr(transparent)] -pub struct Version { - raw: usize, -} - -impl Version { - /// Converts raw extension value into Version structure. - #[inline] - pub const fn from_raw(raw: usize) -> Self { - Self { raw } - } - - /// Reads the major version of RISC-V SBI specification. - #[inline] - pub const fn major(self) -> usize { - (self.raw >> 24) & ((1 << 7) - 1) - } - - /// Reads the minor version of RISC-V SBI specification. - #[inline] - pub const fn minor(self) -> usize { - self.raw & ((1 << 24) - 1) - } -} - -impl core::fmt::Display for Version { - #[inline] - fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { - write!(f, "{}.{}", self.major(), self.minor()) - } -} - -/// Declared in §4.8 -mod fid { - /// Function ID to get the current SBI specification version. - /// - /// Declared in §4.1. - pub const GET_SBI_SPEC_VERSION: usize = 0x0; - /// Function ID to get the current SBI implementation ID. - /// - /// Declared in §4.2. - pub const GET_SBI_IMPL_ID: usize = 0x1; - /// Function ID to get the current SBI implementation version. - /// - /// Declared in §4.3. - pub const GET_SBI_IMPL_VERSION: usize = 0x2; - /// Function ID to probe information about one SBI extension from the current environment. - /// - /// Declared in §4.4. - pub const PROBE_EXTENSION: usize = 0x3; - /// Function ID to get the value of `mvendorid` register in the current environment. - /// - /// Declared in §4.5. - pub const GET_MVENDORID: usize = 0x4; - /// Function ID to get the value of `marchid` register in the current environment. - /// - /// Declared in §4.6. - pub const GET_MARCHID: usize = 0x5; - /// Function ID to get the value of `mimpid` register in the current environment. - /// - /// Declared in §4.7. - pub const GET_MIMPID: usize = 0x6; -} - -/// SBI Implementation IDs. -/// -/// Declared in §4.9. -pub mod impl_id { - /// Berkley Bootloader. - pub const BBL: usize = 0; - /// OpenSBI. - pub const OPEN_SBI: usize = 1; - /// Xvisor. - pub const XVISOR: usize = 2; - /// KVM. - pub const KVM: usize = 3; - /// RustSBI. - pub const RUST_SBI: usize = 4; - /// Diosix. - pub const DIOSIX: usize = 5; - /// Coffer. - pub const COFFER: usize = 6; -} diff --git a/third-party/vendor/sbi-spec/src/binary.rs b/third-party/vendor/sbi-spec/src/binary.rs deleted file mode 100644 index d2ad70d4..00000000 --- a/third-party/vendor/sbi-spec/src/binary.rs +++ /dev/null @@ -1,907 +0,0 @@ -//! Chapter 3. Binary Encoding. - -use core::marker::PhantomData; - -/// SBI functions return type. -/// -/// > SBI functions must return a pair of values in a0 and a1, -/// > with a0 returning an error code. -/// > This is analogous to returning the C structure `SbiRet`. -/// -/// Note: if this structure is used in function return on conventional -/// Rust code, it would not require pinning memory representation as -/// extern C. The `repr(C)` is set in case that some users want to use -/// this structure in FFI code. -#[derive(Clone, Copy, PartialEq, Eq)] -#[repr(C)] -pub struct SbiRet { - /// Error number. - pub error: usize, - /// Result value. - pub value: usize, -} - -/// SBI success state return value. -pub const RET_SUCCESS: usize = 0; -/// Error for SBI call failed for unknown reasons. -pub const RET_ERR_FAILED: usize = -1isize as _; -/// Error for target operation not supported. -pub const RET_ERR_NOT_SUPPORTED: usize = -2isize as _; -/// Error for invalid parameter. -pub const RET_ERR_INVALID_PARAM: usize = -3isize as _; -/// Error for denied (unused in standard extensions). -pub const RET_ERR_DENIED: usize = -4isize as _; -/// Error for invalid address. -pub const RET_ERR_INVALID_ADDRESS: usize = -5isize as _; -/// Error for resource already available. -pub const RET_ERR_ALREADY_AVAILABLE: usize = -6isize as _; -/// Error for resource already started. -pub const RET_ERR_ALREADY_STARTED: usize = -7isize as _; -/// Error for resource already stopped. -pub const RET_ERR_ALREADY_STOPPED: usize = -8isize as _; -/// Error for shared memory not available. -pub const RET_ERR_NO_SHMEM: usize = -9isize as _; - -impl core::fmt::Debug for SbiRet { - fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { - match self.error { - RET_SUCCESS => self.value.fmt(f), - RET_ERR_FAILED => write!(f, ""), - RET_ERR_NOT_SUPPORTED => write!(f, ""), - RET_ERR_INVALID_PARAM => write!(f, ""), - RET_ERR_DENIED => write!(f, ""), - RET_ERR_INVALID_ADDRESS => write!(f, ""), - RET_ERR_ALREADY_AVAILABLE => write!(f, ""), - RET_ERR_ALREADY_STARTED => write!(f, ""), - RET_ERR_ALREADY_STOPPED => write!(f, ""), - RET_ERR_NO_SHMEM => write!(f, ""), - unknown => write!(f, "[SBI Unknown error: {unknown:#x}]"), - } - } -} - -/// RISC-V SBI error in enumeration. -#[derive(Debug, Clone, Copy, PartialEq, Eq)] -pub enum Error { - /// Error for SBI call failed for unknown reasons. - Failed, - /// Error for target operation not supported. - NotSupported, - /// Error for invalid parameter. - InvalidParam, - /// Error for denied (unused in standard extensions). - Denied, - /// Error for invalid address. - InvalidAddress, - /// Error for resource already available. - AlreadyAvailable, - /// Error for resource already started. - AlreadyStarted, - /// Error for resource already stopped. - AlreadyStopped, - /// Error for shared memory not available. - NoShmem, - /// Custom error code. - Custom(isize), -} - -impl SbiRet { - /// Returns success SBI state with given `value`. - #[inline] - pub const fn success(value: usize) -> Self { - Self { - error: RET_SUCCESS, - value, - } - } - - /// The SBI call request failed for unknown reasons. - #[inline] - pub const fn failed() -> Self { - Self { - error: RET_ERR_FAILED, - value: 0, - } - } - - /// SBI call failed due to not supported by target ISA, - /// operation type not supported, - /// or target operation type not implemented on purpose. - #[inline] - pub const fn not_supported() -> Self { - Self { - error: RET_ERR_NOT_SUPPORTED, - value: 0, - } - } - - /// SBI call failed due to invalid hart mask parameter, - /// invalid target hart id, - /// invalid operation type, - /// or invalid resource index. - #[inline] - pub const fn invalid_param() -> Self { - Self { - error: RET_ERR_INVALID_PARAM, - value: 0, - } - } - /// SBI call denied. - /// - /// As the time this document was written, - /// there is currently no function in SBI standard that returns this error. - /// However, custom extensions or future standard functions may return this - /// error if appropriate. - #[inline] - pub const fn denied() -> Self { - Self { - error: RET_ERR_DENIED, - value: 0, - } - } - - /// SBI call failed for invalid mask start address, - /// not a valid physical address parameter, - /// or the target address is prohibited by PMP to run in supervisor mode. - #[inline] - pub const fn invalid_address() -> Self { - Self { - error: RET_ERR_INVALID_ADDRESS, - value: 0, - } - } - - /// SBI call failed for the target resource is already available, - /// e.g., the target hart is already started when caller still requests it to start. - #[inline] - pub const fn already_available() -> Self { - Self { - error: RET_ERR_ALREADY_AVAILABLE, - value: 0, - } - } - - /// SBI call failed for the target resource is already started, - /// e.g., target performance counter is started. - #[inline] - pub const fn already_started() -> Self { - Self { - error: RET_ERR_ALREADY_STARTED, - value: 0, - } - } - - /// SBI call failed for the target resource is already stopped, - /// e.g., target performance counter is stopped. - #[inline] - pub const fn already_stopped() -> Self { - Self { - error: RET_ERR_ALREADY_STOPPED, - value: 0, - } - } - - /// SBI call failed for shared memory is not available, - /// e.g. nested acceleration shared memory is not available. - #[inline] - pub const fn no_shmem() -> Self { - Self { - error: RET_ERR_NO_SHMEM, - value: 0, - } - } -} - -impl SbiRet { - /// Converts to a [`Result`] of value and error. - #[inline] - pub const fn into_result(self) -> Result { - match self.error { - RET_SUCCESS => Ok(self.value), - RET_ERR_FAILED => Err(Error::Failed), - RET_ERR_NOT_SUPPORTED => Err(Error::NotSupported), - RET_ERR_INVALID_PARAM => Err(Error::InvalidParam), - RET_ERR_DENIED => Err(Error::Denied), - RET_ERR_INVALID_ADDRESS => Err(Error::InvalidAddress), - RET_ERR_ALREADY_AVAILABLE => Err(Error::AlreadyAvailable), - RET_ERR_ALREADY_STARTED => Err(Error::AlreadyStarted), - RET_ERR_ALREADY_STOPPED => Err(Error::AlreadyStopped), - RET_ERR_NO_SHMEM => Err(Error::NoShmem), - unknown => Err(Error::Custom(unknown as _)), - } - } - - /// Returns `true` if current SBI return succeeded. - /// - /// # Examples - /// - /// Basic usage: - /// - /// ``` - /// # use sbi_spec::binary::SbiRet; - /// let x = SbiRet::success(0); - /// assert_eq!(x.is_ok(), true); - /// - /// let x = SbiRet::failed(); - /// assert_eq!(x.is_ok(), false); - /// ``` - #[must_use = "if you intended to assert that this is ok, consider `.unwrap()` instead"] - #[inline] - pub const fn is_ok(&self) -> bool { - matches!(self.error, RET_SUCCESS) - } - - /// Returns `true` if current SBI return is an error. - /// - /// # Examples - /// - /// Basic usage: - /// - /// ``` - /// # use sbi_spec::binary::SbiRet; - /// let x = SbiRet::success(0); - /// assert_eq!(x.is_err(), false); - /// - /// let x = SbiRet::not_supported(); - /// assert_eq!(x.is_err(), true); - /// ``` - #[must_use = "if you intended to assert that this is err, consider `.unwrap_err()` instead"] - #[inline] - pub const fn is_err(&self) -> bool { - !self.is_ok() - } - - /// Converts from `SbiRet` to [`Option`]. - /// - /// Converts `self` into an [`Option`], consuming `self`, - /// and discarding the error, if any. - /// - /// # Examples - /// - /// Basic usage: - /// - /// ``` - /// # use sbi_spec::binary::SbiRet; - /// let x = SbiRet::success(2); - /// assert_eq!(x.ok(), Some(2)); - /// - /// let x = SbiRet::invalid_param(); - /// assert_eq!(x.ok(), None); - /// ``` - // fixme: should be pub const fn once this function in Result is stablized in constant - #[inline] - pub fn ok(self) -> Option { - self.into_result().ok() - } - - /// Converts from `SbiRet` to [`Option`]. - /// - /// Converts `self` into an [`Option`], consuming `self`, - /// and discarding the success value, if any. - /// - /// # Examples - /// - /// Basic usage: - /// - /// ``` - /// # use sbi_spec::binary::{SbiRet, Error}; - /// let x = SbiRet::success(2); - /// assert_eq!(x.err(), None); - /// - /// let x = SbiRet::denied(); - /// assert_eq!(x.err(), Some(Error::Denied)); - /// ``` - // fixme: should be pub const fn once this function in Result is stablized in constant - #[inline] - pub fn err(self) -> Option { - self.into_result().err() - } - - /// Maps a `SbiRet` to `Result` by applying a function to a - /// contained success value, leaving an error value untouched. - /// - /// This function can be used to compose the results of two functions. - /// - /// # Examples - /// - /// Gets detail of a PMU counter and judge if it is a firmware counter. - /// - /// ``` - /// # use sbi_spec::binary::SbiRet; - /// # use core::mem::size_of; - /// # mod sbi_rt { - /// # use sbi_spec::binary::SbiRet; - /// # const TYPE_MASK: usize = 1 << (core::mem::size_of::() - 1); - /// # pub fn pmu_counter_get_info(_: usize) -> SbiRet { SbiRet::success(TYPE_MASK) } - /// # } - /// // We assume that counter index 42 is a firmware counter. - /// let counter_idx = 42; - /// // Masks PMU counter type by setting highest bit in `usize`. - /// const TYPE_MASK: usize = 1 << (size_of::() - 1); - /// // Highest bit of returned `counter_info` represents whether it's - /// // a firmware counter or a hardware counter. - /// let is_firmware_counter = sbi_rt::pmu_counter_get_info(counter_idx) - /// .map(|counter_info| counter_info & TYPE_MASK != 0); - /// // If that bit is set, it is a firmware counter. - /// assert_eq!(is_firmware_counter, Ok(true)); - /// ``` - #[inline] - pub fn map U>(self, op: F) -> Result { - self.into_result().map(op) - } - - /// Returns the provided default (if error), - /// or applies a function to the contained value (if success). - /// - /// Arguments passed to `map_or` are eagerly evaluated; - /// if you are passing the result of a function call, - /// it is recommended to use [`map_or_else`], - /// which is lazily evaluated. - /// - /// [`map_or_else`]: SbiRet::map_or_else - /// - /// # Examples - /// - /// ``` - /// # use sbi_spec::binary::SbiRet; - /// let x = SbiRet::success(3); - /// assert_eq!(x.map_or(42, |v| v & 0b1), 1); - /// - /// let x = SbiRet::invalid_address(); - /// assert_eq!(x.map_or(42, |v| v & 0b1), 42); - /// ``` - #[inline] - pub fn map_or U>(self, default: U, f: F) -> U { - self.into_result().map_or(default, f) - } - - /// Maps a `SbiRet` to `usize` value by applying fallback function `default` to - /// a contained error, or function `f` to a contained success value. - /// - /// This function can be used to unpack a successful result - /// while handling an error. - /// - /// # Examples - /// - /// Basic usage: - /// - /// ``` - /// # use sbi_spec::binary::SbiRet; - /// let k = 21; - /// - /// let x = SbiRet::success(3); - /// assert_eq!(x.map_or_else(|e| k * 2, |v| v & 0b1), 1); - /// - /// let x = SbiRet::already_available(); - /// assert_eq!(x.map_or_else(|e| k * 2, |v| v & 0b1), 42); - /// ``` - #[inline] - pub fn map_or_else U, F: FnOnce(usize) -> U>( - self, - default: D, - f: F, - ) -> U { - self.into_result().map_or_else(default, f) - } - - /// Maps a `SbiRet` to `Result` by applying a function to a - /// contained error as [`Error`] struct, leaving success value untouched. - /// - /// This function can be used to pass through a successful result while handling - /// an error. - /// - /// # Examples - /// - /// Basic usage: - /// - /// ``` - /// # use sbi_spec::binary::{SbiRet, Error}; - /// fn stringify(x: Error) -> String { - /// if x == Error::AlreadyStarted { - /// "error: already started!".to_string() - /// } else { - /// "error: other error!".to_string() - /// } - /// } - /// - /// let x = SbiRet::success(2); - /// assert_eq!(x.map_err(stringify), Ok(2)); - /// - /// let x = SbiRet::already_started(); - /// assert_eq!(x.map_err(stringify), Err("error: already started!".to_string())); - /// ``` - #[inline] - pub fn map_err F>(self, op: O) -> Result { - self.into_result().map_err(op) - } - - /// Returns the contained success value, consuming the `self` value. - /// - /// # Panics - /// - /// Panics if self is an SBI error with a panic message including the - /// passed message, and the content of the SBI state. - /// - /// # Examples - /// - /// Basic usage: - /// - /// ```should_panic - /// # use sbi_spec::binary::SbiRet; - /// let x = SbiRet::already_stopped(); - /// x.expect("Testing expect"); // panics with `Testing expect` - /// ``` - #[inline] - pub fn expect(self, msg: &str) -> usize { - self.into_result().expect(msg) - } - - /// Returns the contained success value, consuming the `self` value. - /// - /// # Panics - /// - /// Panics if self is an SBI error, with a panic message provided by the - /// SBI error converted into [`Error`] struct. - /// - /// # Examples - /// - /// Basic usage: - /// - /// ``` - /// # use sbi_spec::binary::SbiRet; - /// let x = SbiRet::success(2); - /// assert_eq!(x.unwrap(), 2); - /// ``` - /// - /// ```should_panic - /// # use sbi_spec::binary::SbiRet; - /// let x = SbiRet::failed(); - /// x.unwrap(); // panics - /// ``` - #[inline] - pub fn unwrap(self) -> usize { - self.into_result().unwrap() - } - - /// Returns the contained error as [`Error`] struct, consuming the `self` value. - /// - /// # Panics - /// - /// Panics if the self is SBI success value, with a panic message - /// including the passed message, and the content of the success value. - /// - /// # Examples - /// - /// Basic usage: - /// - /// ```should_panic - /// # use sbi_spec::binary::SbiRet; - /// let x = SbiRet::success(10); - /// x.expect_err("Testing expect_err"); // panics with `Testing expect_err` - /// ``` - #[inline] - pub fn expect_err(self, msg: &str) -> Error { - self.into_result().expect_err(msg) - } - - /// Returns the contained error as [`Error`] struct, consuming the `self` value. - /// - /// # Panics - /// - /// Panics if the self is SBI success value, with a custom panic message provided - /// by the success value. - /// - /// # Examples - /// - /// ```should_panic - /// # use sbi_spec::binary::SbiRet; - /// let x = SbiRet::success(2); - /// x.unwrap_err(); // panics with `2` - /// ``` - /// - /// ``` - /// # use sbi_spec::binary::{SbiRet, Error}; - /// let x = SbiRet::not_supported(); - /// assert_eq!(x.unwrap_err(), Error::NotSupported); - /// ``` - #[inline] - pub fn unwrap_err(self) -> Error { - self.into_result().unwrap_err() - } - - /// Returns `res` if self is success value, otherwise otherwise returns the contained error - /// of `self` as [`Error`] struct. - /// - /// Arguments passed to `and` are eagerly evaluated; if you are passing the - /// result of a function call, it is recommended to use [`and_then`], which is - /// lazily evaluated. - /// - /// [`and_then`]: SbiRet::and_then - /// - /// # Examples - /// - /// Basic usage: - /// - /// ``` - /// # use sbi_spec::binary::{SbiRet, Error}; - /// let x = SbiRet::success(2); - /// let y = SbiRet::invalid_param().into_result(); - /// assert_eq!(x.and(y), Err(Error::InvalidParam)); - /// - /// let x = SbiRet::denied(); - /// let y = SbiRet::success(3).into_result(); - /// assert_eq!(x.and(y), Err(Error::Denied)); - /// - /// let x = SbiRet::invalid_address(); - /// let y = SbiRet::already_available().into_result(); - /// assert_eq!(x.and(y), Err(Error::InvalidAddress)); - /// - /// let x = SbiRet::success(4); - /// let y = SbiRet::success(5).into_result(); - /// assert_eq!(x.and(y), Ok(5)); - /// ``` - // fixme: should be pub const fn once this function in Result is stablized in constant - // fixme: should parameter be `res: SbiRet`? - #[inline] - pub fn and(self, res: Result) -> Result { - self.into_result().and(res) - } - - /// Calls `op` if self is success value, otherwise returns the contained error - /// as [`Error`] struct. - /// - /// This function can be used for control flow based on `SbiRet` values. - /// - /// # Examples - /// - /// ``` - /// # use sbi_spec::binary::{SbiRet, Error}; - /// fn sq_then_to_string(x: usize) -> Result { - /// x.checked_mul(x).map(|sq| sq.to_string()).ok_or(Error::Failed) - /// } - /// - /// assert_eq!(SbiRet::success(2).and_then(sq_then_to_string), Ok(4.to_string())); - /// assert_eq!(SbiRet::success(1_000_000_000_000).and_then(sq_then_to_string), Err(Error::Failed)); - /// assert_eq!(SbiRet::invalid_param().and_then(sq_then_to_string), Err(Error::InvalidParam)); - /// ``` - #[inline] - pub fn and_then Result>(self, op: F) -> Result { - self.into_result().and_then(op) - } - - /// Returns `res` if self is SBI error, otherwise returns the success value of `self`. - /// - /// Arguments passed to `or` are eagerly evaluated; if you are passing the - /// result of a function call, it is recommended to use [`or_else`], which is - /// lazily evaluated. - /// - /// [`or_else`]: Result::or_else - /// - /// # Examples - /// - /// Basic usage: - /// - /// ``` - /// # use sbi_spec::binary::{SbiRet, Error}; - /// let x = SbiRet::success(2); - /// let y = SbiRet::invalid_param().into_result(); - /// assert_eq!(x.or(y), Ok(2)); - /// - /// let x = SbiRet::denied(); - /// let y = SbiRet::success(3).into_result(); - /// assert_eq!(x.or(y), Ok(3)); - /// - /// let x = SbiRet::invalid_address(); - /// let y = SbiRet::already_available().into_result(); - /// assert_eq!(x.or(y), Err(Error::AlreadyAvailable)); - /// - /// let x = SbiRet::success(4); - /// let y = SbiRet::success(100).into_result(); - /// assert_eq!(x.or(y), Ok(4)); - /// ``` - // fixme: should be pub const fn once this function in Result is stablized in constant - // fixme: should parameter be `res: SbiRet`? - #[inline] - pub fn or(self, res: Result) -> Result { - self.into_result().or(res) - } - - /// Calls `op` if self is SBI error, otherwise returns the success value of `self`. - /// - /// This function can be used for control flow based on result values. - /// - /// - /// # Examples - /// - /// Basic usage: - /// - /// ``` - /// # use sbi_spec::binary::{SbiRet, Error}; - /// fn is_failed(x: Error) -> Result { Err(x == Error::Failed) } - /// - /// assert_eq!(SbiRet::success(2).or_else(is_failed), Ok(2)); - /// assert_eq!(SbiRet::failed().or_else(is_failed), Err(true)); - /// ``` - #[inline] - pub fn or_else Result>(self, op: O) -> Result { - self.into_result().or_else(op) - } - - /// Returns the contained success value or a provided default. - /// - /// Arguments passed to `unwrap_or` are eagerly evaluated; if you are passing - /// the result of a function call, it is recommended to use [`unwrap_or_else`], - /// which is lazily evaluated. - /// - /// [`unwrap_or_else`]: SbiRet::unwrap_or_else - /// - /// # Examples - /// - /// Basic usage: - /// - /// ``` - /// # use sbi_spec::binary::SbiRet; - /// let default = 2; - /// let x = SbiRet::success(9); - /// assert_eq!(x.unwrap_or(default), 9); - /// - /// let x = SbiRet::invalid_param(); - /// assert_eq!(x.unwrap_or(default), default); - /// ``` - // fixme: should be pub const fn once this function in Result is stablized in constant - #[inline] - pub fn unwrap_or(self, default: usize) -> usize { - self.into_result().unwrap_or(default) - } - - /// Returns the contained success value or computes it from a closure. - /// - /// # Examples - /// - /// Basic usage: - /// - /// ``` - /// # use sbi_spec::binary::{SbiRet, Error}; - /// fn invalid_use_zero(x: Error) -> usize { if x == Error::InvalidParam { 0 } else { 3 } } - /// - /// assert_eq!(SbiRet::success(2).unwrap_or_else(invalid_use_zero), 2); - /// assert_eq!(SbiRet::invalid_param().unwrap_or_else(invalid_use_zero), 0); - /// ``` - #[inline] - pub fn unwrap_or_else usize>(self, op: F) -> usize { - self.into_result().unwrap_or_else(op) - } -} - -/// Hart mask structure in SBI function calls. -#[derive(Debug, Copy, Clone)] -pub struct HartMask { - inner: BitVector, -} - -impl HartMask { - /// Construct a hart mask from mask value and base hart id. - #[inline] - pub const fn from_mask_base(hart_mask: usize, hart_mask_base: usize) -> HartMask { - HartMask { - inner: BitVector { - hart_mask, - hart_mask_base, - }, - } - } - - /// Returns `hart_mask` and `hart_mask_base` parameters from the hart mask structure. - #[inline] - pub const fn into_inner(self) -> (usize, usize) { - (self.inner.hart_mask, self.inner.hart_mask_base) - } - - /// Check if the `hart_id` is included in this hart mask structure. - #[inline] - pub const fn has_bit(&self, hart_id: usize) -> bool { - let BitVector { - hart_mask, - hart_mask_base, - } = self.inner; - if hart_mask_base == usize::MAX { - // If `hart_mask_base` equals `usize::MAX`, that means `hart_mask` is ignored - // and all available harts must be considered. - return true; - } - let Some(idx) = hart_id.checked_sub(hart_mask_base) else { - // hart_id < hart_mask_base, not in current mask range - return false; - }; - if idx >= usize::BITS as usize { - // hart_idx >= hart_mask_base + XLEN, not in current mask range - return false; - } - hart_mask & (1 << idx) != 0 - } -} - -#[derive(Debug, Copy, Clone)] -struct BitVector { - hart_mask: usize, - hart_mask_base: usize, -} - -/// Physical slice wrapper with type annotation. -/// -/// This struct wraps slices in RISC-V physical memory by low and high part of the -/// physical base address as well as its length. It is usually used by SBI extensions -/// as parameter types to pass base address and length parameters on physical memory -/// other than a virtual one. -/// -/// Generic parameter `P` represents a hint of how this physical slice would be used. -/// For example, `Physical<&[u8]>` represents an immutable reference to physical byte slice, -/// while `Physical<&mut [u8]>` represents a mutable one. -/// -/// An SBI implementation should load or store memory using both `phys_addr_lo` and -/// `phys_addr_hi` combined as base address. A supervisor program (kernels etc.) -/// should provide continuous physical memory, wrapping its reference using this structure -/// before passing into SBI runtime. -#[derive(Clone, Copy)] -pub struct Physical

{ - num_bytes: usize, - phys_addr_lo: usize, - phys_addr_hi: usize, - _marker: PhantomData

, -} - -impl

Physical

{ - /// Create a physical memory slice by length and physical address. - #[inline] - pub const fn new(num_bytes: usize, phys_addr_lo: usize, phys_addr_hi: usize) -> Self { - Self { - num_bytes, - phys_addr_lo, - phys_addr_hi, - _marker: core::marker::PhantomData, - } - } - - /// Returns length of the physical memory slice. - #[inline] - pub const fn num_bytes(&self) -> usize { - self.num_bytes - } - - /// Returns low-part base address of physical memory slice. - #[inline] - pub const fn phys_addr_lo(&self) -> usize { - self.phys_addr_lo - } - - /// Returns high-part base address of physical memory slice. - #[inline] - pub const fn phys_addr_hi(&self) -> usize { - self.phys_addr_hi - } -} - -/// Shared memory physical address raw pointer with type annotation. -/// -/// This is a structure wrapping a raw pointer to the value of the type `T` without -/// a pointer metadata. `SharedPtr`'s are _thin_; they won't include metadata -/// as RISC-V SBI does not provide an approach to pass them via SBI calls, -/// thus the length of type `T` should be decided independently of raw -/// pointer structure. -/// -/// `SharedPtr` can be used as a parameter to pass the shared memory physical pointer -/// with a given base address in RISC-V SBI calls. For example, a `SharedPtr<[u8; 64]>` -/// would represent a fixed-size 64 byte array on a RISC-V SBI function argument -/// type. -/// -/// This structure cannot be dereferenced directly with physical addresses, -/// because on RISC-V systems the physical address space could be larger than the -/// virtual ones. Hence, this structure describes the physical memory range by -/// two `usize` values: the upper `phys_addr_hi` and lower `phys_addr_lo`. -/// -/// RISC-V SBI extensions may declare special pointer values for shared memory -/// raw pointers. For example, SBI STA declares that steal-time information -/// should stop from reporting when the SBI call is invoked using all-ones -/// bitwise shared pointer, i.e. `phys_addr_hi` and `phys_addr_lo` both equals -/// `usize::MAX`. `SharedPtr` can be constructed using such special values -/// by providing them to the `SharedPtr::new` function. -/// -/// # Requirements -/// -/// If an SBI function needs to pass a shared memory physical address range to -/// the SBI implementation (or higher privilege mode), then this physical memory -/// address range MUST satisfy the following requirements: -/// -/// * The SBI implementation MUST check that the supervisor-mode software is -/// allowed to access the specified physical memory range with the access -/// type requested (read and/or write). -/// * The SBI implementation MUST access the specified physical memory range -/// using the PMA attributes. -/// * The data in the shared memory MUST follow little-endian byte ordering. -/// -/// *NOTE:* If the supervisor-mode software accesses the same physical memory -/// range using a memory type different from the PMA, then a loss of coherence -/// or unexpected memory ordering may occur. The invoking software should -/// follow the rules and sequences defined in the RISC-V Svpbmt specification -/// to prevent the loss of coherence and memory ordering. -/// -/// It is recommended that a memory physical address passed to an SBI function -/// should use at least two `usize` parameters to support platforms -/// which have memory physical addresses wider than `XLEN` bits. -// FIXME: should constrain with `T: Thin` once ptr_metadata feature is stabled; -// RISC-V SBI does not provide an approach to pass pointer metadata by SBI calls. -pub struct SharedPtr { - phys_addr_lo: usize, - phys_addr_hi: usize, - _marker: PhantomData<*mut T>, -} - -// FIXME: we should consider strict provenance rules for this pointer-like structure -// once feature strict_provenance is stabled. -impl SharedPtr { - /// Create a shared physical memory pointer by physical address. - #[inline] - pub const fn new(phys_addr_lo: usize, phys_addr_hi: usize) -> Self { - Self { - phys_addr_lo, - phys_addr_hi, - _marker: PhantomData, - } - } - - /// Returns low-part physical address of the shared physical memory pointer. - #[inline] - pub const fn phys_addr_lo(self) -> usize { - self.phys_addr_lo - } - - /// Returns high-part physical address of the shared physical memory pointer. - #[inline] - pub const fn phys_addr_hi(self) -> usize { - self.phys_addr_hi - } -} - -impl Clone for SharedPtr { - #[inline(always)] - fn clone(&self) -> Self { - *self - } -} - -impl Copy for SharedPtr {} - -#[cfg(test)] -mod tests { - use super::HartMask; - - #[test] - fn rustsbi_hart_mask() { - let mask = HartMask::from_mask_base(0b1, 400); - assert!(!mask.has_bit(0)); - assert!(mask.has_bit(400)); - assert!(!mask.has_bit(401)); - let mask = HartMask::from_mask_base(0b110, 500); - assert!(!mask.has_bit(0)); - assert!(!mask.has_bit(500)); - assert!(mask.has_bit(501)); - assert!(mask.has_bit(502)); - assert!(!mask.has_bit(500 + (usize::BITS as usize))); - let max_bit = 1 << (usize::BITS - 1); - let mask = HartMask::from_mask_base(max_bit, 600); - assert!(mask.has_bit(600 + (usize::BITS as usize) - 1)); - assert!(!mask.has_bit(600 + (usize::BITS as usize))); - let mask = HartMask::from_mask_base(0b11, usize::MAX - 1); - assert!(!mask.has_bit(usize::MAX - 2)); - assert!(mask.has_bit(usize::MAX - 1)); - assert!(mask.has_bit(usize::MAX)); - assert!(!mask.has_bit(0)); - // hart_mask_base == usize::MAX is special, it means hart_mask should be ignored - // and this hart mask contains all harts available - let mask = HartMask::from_mask_base(0, usize::MAX); - for i in 0..5 { - assert!(mask.has_bit(i)); - } - assert!(mask.has_bit(usize::MAX)); - } -} diff --git a/third-party/vendor/sbi-spec/src/cppc.rs b/third-party/vendor/sbi-spec/src/cppc.rs deleted file mode 100644 index dd56a55f..00000000 --- a/third-party/vendor/sbi-spec/src/cppc.rs +++ /dev/null @@ -1,25 +0,0 @@ -//! Chapter 14. CPPC Extension (EID #0x43505043 "CPPC"). - -/// Extension ID for CPPC Extension. -pub const EID_CPPC: usize = crate::eid_from_str("CPPC") as _; -pub use fid::*; - -/// Declared in §14. -mod fid { - /// Function ID to probe a CPPC register. - /// - /// Declared in §14.1. - pub const PROBE: usize = 0; - /// Function ID to read CPPC register bits. - /// - /// Declared in §14.2. - pub const READ: usize = 1; - /// Function ID to read high bits of a CPPC register. - /// - /// Declared in §14.3. - pub const READ_HI: usize = 2; - /// Function ID to write to a CPPC register. - /// - /// Declared in §14.4. - pub const WRITE: usize = 3; -} diff --git a/third-party/vendor/sbi-spec/src/dbcn.rs b/third-party/vendor/sbi-spec/src/dbcn.rs deleted file mode 100644 index 180c2a75..00000000 --- a/third-party/vendor/sbi-spec/src/dbcn.rs +++ /dev/null @@ -1,21 +0,0 @@ -//! Chapter 12. Debug Console Extension (EID #0x4442434E "DBCN"). - -/// Extension ID for Debug Console Extension. -pub const EID_DBCN: usize = crate::eid_from_str("DBCN") as _; -pub use fid::*; - -/// Declared in §12. -mod fid { - /// Function ID to write bytes to the debug console from input memory. - /// - /// Declared in §12.1. - pub const CONSOLE_WRITE: usize = 0; - /// Function ID to read bytes from the debug console into an output memory. - /// - /// Declared in §12.2. - pub const CONSOLE_READ: usize = 1; - /// Function ID to write a single byte to the debug console. - /// - /// Declared in §12.3. - pub const CONSOLE_WRITE_BYTE: usize = 2; -} diff --git a/third-party/vendor/sbi-spec/src/hsm.rs b/third-party/vendor/sbi-spec/src/hsm.rs deleted file mode 100644 index 68f55ff6..00000000 --- a/third-party/vendor/sbi-spec/src/hsm.rs +++ /dev/null @@ -1,70 +0,0 @@ -//! Chapter 9. Hart State Management Extension (EID #0x48534D "HSM"). - -/// Extension ID for Hart State Management extension. -pub const EID_HSM: usize = crate::eid_from_str("HSM") as _; -pub use fid::*; - -/// Hart states. -/// -/// Declared in Table 1 at §9. -pub mod hart_state { - /// The hart is physically powered-up and executing normally. - pub const STARTED: usize = 0; - /// The hart is not executing in supervisor-mode or any lower privilege mode. - /// - /// It is probably powered-down by the SBI implementation if the underlying platform - /// has a mechanism to physically power-down harts. - pub const STOPPED: usize = 1; - /// The hart is pending before being started - /// - /// Some other hart has requested to start (or power-up) the hart from the STOPPED state, - /// and the SBI implementation is still working to get the hart in the STARTED state. - pub const START_PENDING: usize = 2; - /// The hart is pending before being stopped. - /// - /// The hart has requested to stop (or power-down) itself from the STARTED state, - /// and the SBI implementation is still working to get the hart in the STOPPED state. - pub const STOP_PENDING: usize = 3; - /// The hart is in a platform-specific suspend (or low-power) state. - pub const SUSPENDED: usize = 4; - /// The hart is pending before being suspended. - /// - /// The hart has requested to put itself in a platform-specific low-power state - /// from the STARTED state, and the SBI implementation is still working to get - /// the hart in the platform-specific SUSPENDED state. - pub const SUSPEND_PENDING: usize = 5; - /// The hart is pending before being resumed. - /// - /// An interrupt or platform specific hardware event has caused the hart to resume - /// normal execution from the SUSPENDED state, and the SBI implementation is still - /// working to get the hart in the STARTED state. - pub const RESUME_PENDING: usize = 6; -} - -/// Hart suspend types. -pub mod suspend_type { - /// Default retentive hart suspend type. - pub const RETENTIVE: u32 = 0; - /// Default non-retentive hart suspend type. - pub const NON_RETENTIVE: u32 = 0x8000_0000; -} - -/// Declared in §9.5. -mod fid { - /// Function ID to start executing the given hart at specified address in supervisor-mode. - /// - /// Declared in §9.1. - pub const HART_START: usize = 0; - /// Function ID to stop executing the calling hart in supervisor-mode. - /// - /// Declared in §9.2. - pub const HART_STOP: usize = 1; - /// Function ID to get the current status (or HSM state id) of the given hart. - /// - /// Declared in §9.3. - pub const HART_GET_STATUS: usize = 2; - /// Function ID to put the calling hart into suspend or platform-specific lower power states. - /// - /// Declared in §9.4. - pub const HART_SUSPEND: usize = 3; -} diff --git a/third-party/vendor/sbi-spec/src/legacy.rs b/third-party/vendor/sbi-spec/src/legacy.rs deleted file mode 100644 index ec8e4275..00000000 --- a/third-party/vendor/sbi-spec/src/legacy.rs +++ /dev/null @@ -1,25 +0,0 @@ -//! Chapter 5. Legacy Extensions (EIDs #0x00 - #0x0F). - -pub use id::*; - -/// §5.10 -mod id { - /// §5.1 - pub const LEGACY_SET_TIMER: usize = 0; - /// §5.2 - pub const LEGACY_CONSOLE_PUTCHAR: usize = 1; - /// §5.3 - pub const LEGACY_CONSOLE_GETCHAR: usize = 2; - /// §5.4 - pub const LEGACY_CLEAR_IPI: usize = 3; - /// §5.5 - pub const LEGACY_SEND_IPI: usize = 4; - /// §5.6 - pub const LEGACY_REMOTE_FENCE_I: usize = 5; - /// §5.7 - pub const LEGACY_REMOTE_SFENCE_VMA: usize = 6; - /// §5.8 - pub const LEGACY_REMOTE_SFENCE_VMA_ASID: usize = 7; - /// §5.9 - pub const LEGACY_SHUTDOWN: usize = 8; -} diff --git a/third-party/vendor/sbi-spec/src/lib.rs b/third-party/vendor/sbi-spec/src/lib.rs deleted file mode 100644 index fb569075..00000000 --- a/third-party/vendor/sbi-spec/src/lib.rs +++ /dev/null @@ -1,318 +0,0 @@ -//! RISC-V SBI Specification structure and constant definitions. -//! -//! This crate adapts to RISC-V SBI Specification version 2.0 ratified. -//! It provides structures in Rust semantics and best practices to simplify -//! designs of RISC-V SBI ecosystem, both implementation and applications. -//! -//! You may find it convenient to use this library in a vast range of packages, -//! from operating system kernels, hypervisors, to SBI bare metal implementations. -//! This crate is `no_std` compatible and does not need dynamic memory allocation, -//! which makes it suitable for embedded development. -//! -//! Although this library is dedicated to RISC-V architecture, it does not limit -//! which build target the dependents should compile into. -//! For example, when developing a RISC-V emulator on platforms other than RISC-V, -//! the emulator designed on other platforms can still make use of `sbi-spec` structures, -//! to provide the necessary features where the emulated RISC-V environment would make use of. -#![no_std] -#![deny(missing_docs, unsafe_code, unstable_features)] - -// §3 -pub mod binary; -// §4 -pub mod base; -// §5 -#[cfg(feature = "legacy")] -pub mod legacy; -// §6 -pub mod time; -// §7 -pub mod spi; -// §8 -pub mod rfnc; -// §9 -pub mod hsm; -// §10 -pub mod srst; -// §11 -pub mod pmu; -// §12 -pub mod dbcn; -// §13 -pub mod susp; -// §14 -pub mod cppc; -// §15 -pub mod nacl; -// §16 -pub mod sta; - -/// Converts SBI EID from str. -const fn eid_from_str(name: &str) -> i32 { - match *name.as_bytes() { - [a] => i32::from_be_bytes([0, 0, 0, a]), - [a, b] => i32::from_be_bytes([0, 0, a, b]), - [a, b, c] => i32::from_be_bytes([0, a, b, c]), - [a, b, c, d] => i32::from_be_bytes([a, b, c, d]), - _ => unreachable!(), - } -} - -/// Checks during compilation, and provides an item list for developers. -#[cfg(test)] -mod tests { - use static_assertions::{ - assert_eq_align, assert_eq_size, assert_fields, assert_impl_all, const_assert_eq, - }; - // §3 - #[test] - fn test_binary() { - use crate::binary::*; - assert_eq_align!(SbiRet, usize); - assert_eq_size!(SbiRet, [usize; 2]); - assert_fields!(SbiRet: error); - assert_fields!(SbiRet: value); - assert_impl_all!(SbiRet: Copy, Clone, PartialEq, Eq, core::fmt::Debug); - - const_assert_eq!(0, RET_SUCCESS as isize); - const_assert_eq!(-1, RET_ERR_FAILED as isize); - const_assert_eq!(-2, RET_ERR_NOT_SUPPORTED as isize); - const_assert_eq!(-3, RET_ERR_INVALID_PARAM as isize); - const_assert_eq!(-4, RET_ERR_DENIED as isize); - const_assert_eq!(-5, RET_ERR_INVALID_ADDRESS as isize); - const_assert_eq!(-6, RET_ERR_ALREADY_AVAILABLE as isize); - const_assert_eq!(-7, RET_ERR_ALREADY_STARTED as isize); - const_assert_eq!(-8, RET_ERR_ALREADY_STOPPED as isize); - const_assert_eq!(-9, RET_ERR_NO_SHMEM as isize); - } - // §4 - #[test] - fn test_base() { - use crate::base::*; - const_assert_eq!(0x10, EID_BASE); - const_assert_eq!(0, GET_SBI_SPEC_VERSION); - const_assert_eq!(1, GET_SBI_IMPL_ID); - const_assert_eq!(2, GET_SBI_IMPL_VERSION); - const_assert_eq!(3, PROBE_EXTENSION); - const_assert_eq!(4, GET_MVENDORID); - const_assert_eq!(5, GET_MARCHID); - const_assert_eq!(6, GET_MIMPID); - const_assert_eq!(0, impl_id::BBL); - const_assert_eq!(1, impl_id::OPEN_SBI); - const_assert_eq!(2, impl_id::XVISOR); - const_assert_eq!(3, impl_id::KVM); - const_assert_eq!(4, impl_id::RUST_SBI); - const_assert_eq!(5, impl_id::DIOSIX); - const_assert_eq!(6, impl_id::COFFER); - } - // §5 - #[cfg(feature = "legacy")] - #[test] - fn test_legacy() { - use crate::legacy::*; - const_assert_eq!(0, LEGACY_SET_TIMER); - const_assert_eq!(1, LEGACY_CONSOLE_PUTCHAR); - const_assert_eq!(2, LEGACY_CONSOLE_GETCHAR); - const_assert_eq!(3, LEGACY_CLEAR_IPI); - const_assert_eq!(4, LEGACY_SEND_IPI); - const_assert_eq!(5, LEGACY_REMOTE_FENCE_I); - const_assert_eq!(6, LEGACY_REMOTE_SFENCE_VMA); - const_assert_eq!(7, LEGACY_REMOTE_SFENCE_VMA_ASID); - const_assert_eq!(8, LEGACY_SHUTDOWN); - } - // §6 - #[test] - fn test_time() { - use crate::time::*; - const_assert_eq!(0x54494D45, EID_TIME); - const_assert_eq!(0, SET_TIMER); - } - // §7 - #[test] - fn test_spi() { - use crate::spi::*; - const_assert_eq!(0x735049, EID_SPI); - const_assert_eq!(0, SEND_IPI); - } - // §8 - #[test] - fn test_rfnc() { - use crate::rfnc::*; - const_assert_eq!(0x52464E43, EID_RFNC); - const_assert_eq!(0, REMOTE_FENCE_I); - const_assert_eq!(1, REMOTE_SFENCE_VMA); - const_assert_eq!(2, REMOTE_SFENCE_VMA_ASID); - const_assert_eq!(3, REMOTE_HFENCE_GVMA_VMID); - const_assert_eq!(4, REMOTE_HFENCE_GVMA); - const_assert_eq!(5, REMOTE_HFENCE_VVMA_ASID); - const_assert_eq!(6, REMOTE_HFENCE_VVMA); - } - // §9 - #[test] - fn test_hsm() { - use crate::hsm::*; - const_assert_eq!(0x48534D, EID_HSM); - const_assert_eq!(0, hart_state::STARTED); - const_assert_eq!(1, hart_state::STOPPED); - const_assert_eq!(2, hart_state::START_PENDING); - const_assert_eq!(3, hart_state::STOP_PENDING); - const_assert_eq!(4, hart_state::SUSPENDED); - const_assert_eq!(5, hart_state::SUSPEND_PENDING); - const_assert_eq!(6, hart_state::RESUME_PENDING); - const_assert_eq!(0x0000_0000, suspend_type::RETENTIVE); - const_assert_eq!(0x8000_0000, suspend_type::NON_RETENTIVE); - const_assert_eq!(0, HART_START); - const_assert_eq!(1, HART_STOP); - const_assert_eq!(2, HART_GET_STATUS); - const_assert_eq!(3, HART_SUSPEND); - } - // §10 - #[test] - fn test_srst() { - use crate::srst::*; - const_assert_eq!(0x53525354, EID_SRST); - const_assert_eq!(0, RESET_TYPE_SHUTDOWN); - const_assert_eq!(1, RESET_TYPE_COLD_REBOOT); - const_assert_eq!(2, RESET_TYPE_WARM_REBOOT); - const_assert_eq!(0, RESET_REASON_NO_REASON); - const_assert_eq!(1, RESET_REASON_SYSTEM_FAILURE); - const_assert_eq!(0, SYSTEM_RESET); - } - // §11 - #[test] - fn test_pmu() { - use crate::pmu::*; - const_assert_eq!(0x504D55, EID_PMU); - const_assert_eq!(0, NUM_COUNTERS); - const_assert_eq!(1, COUNTER_GET_INFO); - const_assert_eq!(2, COUNTER_CONFIG_MATCHING); - const_assert_eq!(3, COUNTER_START); - const_assert_eq!(4, COUNTER_STOP); - const_assert_eq!(5, COUNTER_FW_READ); - const_assert_eq!(6, COUNTER_FW_READ_HI); - const_assert_eq!(7, SNAPSHOT_SET_SHMEM); - - const_assert_eq!(0, event_type::HARDWARE_GENERAL); - const_assert_eq!(1, event_type::HARDWARE_CACHE); - const_assert_eq!(2, event_type::HARDWARE_RAW); - const_assert_eq!(15, event_type::FIRMWARE); - - const_assert_eq!(0, hardware_event::NO_EVENT); - const_assert_eq!(1, hardware_event::CPU_CYCLES); - const_assert_eq!(2, hardware_event::INSTRUCTIONS); - const_assert_eq!(3, hardware_event::CACHE_REFERENCES); - const_assert_eq!(4, hardware_event::CACHE_MISSES); - const_assert_eq!(5, hardware_event::BRANCH_INSTRUCTIONS); - const_assert_eq!(6, hardware_event::BRANCH_MISSES); - const_assert_eq!(7, hardware_event::BUS_CYCLES); - const_assert_eq!(8, hardware_event::STALLED_CYCLES_FRONTEND); - const_assert_eq!(9, hardware_event::STALLED_CYCLES_BACKEND); - const_assert_eq!(10, hardware_event::REF_CPU_CYCLES); - - const_assert_eq!(0, cache_event::L1D); - const_assert_eq!(1, cache_event::L1I); - const_assert_eq!(2, cache_event::LL); - const_assert_eq!(3, cache_event::DTLB); - const_assert_eq!(4, cache_event::ITLB); - const_assert_eq!(5, cache_event::BPU); - const_assert_eq!(6, cache_event::NODE); - - const_assert_eq!(0, cache_operation::READ); - const_assert_eq!(1, cache_operation::WRITE); - const_assert_eq!(2, cache_operation::PREFETCH); - - const_assert_eq!(0, cache_result::ACCESS); - const_assert_eq!(1, cache_result::MISS); - - const_assert_eq!(0, firmware_event::MISALIGNED_LOAD); - const_assert_eq!(1, firmware_event::MISALIGNED_STORE); - const_assert_eq!(2, firmware_event::ACCESS_LOAD); - const_assert_eq!(3, firmware_event::ACCESS_STORE); - const_assert_eq!(4, firmware_event::ILLEGAL_INSN); - const_assert_eq!(5, firmware_event::SET_TIMER); - const_assert_eq!(6, firmware_event::IPI_SENT); - const_assert_eq!(7, firmware_event::IPI_RECEIVED); - const_assert_eq!(8, firmware_event::FENCE_I_SENT); - const_assert_eq!(9, firmware_event::FENCE_I_RECEIVED); - const_assert_eq!(10, firmware_event::SFENCE_VMA_SENT); - const_assert_eq!(11, firmware_event::SFENCE_VMA_RECEIVED); - const_assert_eq!(12, firmware_event::SFENCE_VMA_ASID_SENT); - const_assert_eq!(13, firmware_event::SFENCE_VMA_ASID_RECEIVED); - const_assert_eq!(14, firmware_event::HFENCE_GVMA_SENT); - const_assert_eq!(15, firmware_event::HFENCE_GVMA_RECEIVED); - const_assert_eq!(16, firmware_event::HFENCE_GVMA_VMID_SENT); - const_assert_eq!(17, firmware_event::HFENCE_GVMA_VMID_RECEIVED); - const_assert_eq!(18, firmware_event::HFENCE_VVMA_SENT); - const_assert_eq!(19, firmware_event::HFENCE_VVMA_RECEIVED); - const_assert_eq!(20, firmware_event::HFENCE_VVMA_ASID_SENT); - const_assert_eq!(21, firmware_event::HFENCE_VVMA_ASID_RECEIVED); - const_assert_eq!(65535, firmware_event::PLATFORM); - } - // §12 - #[test] - fn test_dbcn() { - use crate::dbcn::*; - const_assert_eq!(0x4442434E, EID_DBCN); - const_assert_eq!(0, CONSOLE_WRITE); - const_assert_eq!(1, CONSOLE_READ); - const_assert_eq!(2, CONSOLE_WRITE_BYTE); - } - // §13 - #[test] - fn test_susp() { - use crate::susp::*; - const_assert_eq!(0x53555350, EID_SUSP); - const_assert_eq!(0, SUSPEND); - } - // §14 - #[test] - fn test_cppc() { - use crate::cppc::*; - const_assert_eq!(0x43505043, EID_CPPC); - const_assert_eq!(0, PROBE); - const_assert_eq!(1, READ); - const_assert_eq!(2, READ_HI); - const_assert_eq!(3, WRITE); - } - // §15 - #[test] - fn test_nacl() { - use crate::nacl::*; - const_assert_eq!(0x4E41434C, EID_NACL); - const_assert_eq!(0, PROBE_FEATURE); - const_assert_eq!(1, SET_SHMEM); - const_assert_eq!(2, SYNC_CSR); - const_assert_eq!(3, SYNC_HFENCE); - const_assert_eq!(4, SYNC_SRET); - - const_assert_eq!(0, feature_id::SYNC_CSR); - const_assert_eq!(1, feature_id::SYNC_HFENCE); - const_assert_eq!(2, feature_id::SYNC_SRET); - const_assert_eq!(3, feature_id::AUTOSWAP_CSR); - - const_assert_eq!(8192, shmem_size::RV32); - const_assert_eq!(12288, shmem_size::RV64); - const_assert_eq!(20480, shmem_size::RV128); - match () { - #[cfg(target_pointer_width = "32")] - () => { - const_assert_eq!(shmem_size::NATIVE, shmem_size::RV32); - } - #[cfg(target_pointer_width = "64")] - () => { - const_assert_eq!(shmem_size::NATIVE, shmem_size::RV64); - } - #[cfg(target_pointer_width = "128")] - () => { - const_assert_eq!(shmem_size::NATIVE, shmem_size::RV128); - } - } - } - // §16 - #[test] - fn test_sta() { - use crate::sta::*; - const_assert_eq!(0x535441, EID_STA); - const_assert_eq!(0, SET_SHMEM); - } -} diff --git a/third-party/vendor/sbi-spec/src/nacl.rs b/third-party/vendor/sbi-spec/src/nacl.rs deleted file mode 100644 index bb39fd95..00000000 --- a/third-party/vendor/sbi-spec/src/nacl.rs +++ /dev/null @@ -1,75 +0,0 @@ -//! Chapter 15. Nested Acceleration Extension (EID #0x4E41434C "NACL"). - -/// Extension ID for Nested Acceleration Extension. -pub const EID_NACL: usize = crate::eid_from_str("NACL") as _; - -pub use fid::*; - -/// Declared in § 15.15. -mod fid { - /// Function ID to probe a nested acceleration feature. - /// - /// Declared in §15.5. - pub const PROBE_FEATURE: usize = 0; - /// Function ID to set and enable the shared memory for nested acceleration on the calling hart. - /// - /// Declared in §15.6. - pub const SET_SHMEM: usize = 1; - /// Function ID to synchronize CSRs in the nested acceleration shared memory. - /// - /// Declared in §15.7. - pub const SYNC_CSR: usize = 2; - /// Function ID to synchronize HFENCEs in the nested acceleration shared memory. - /// - /// Declared in §15.8. - pub const SYNC_HFENCE: usize = 3; - /// Function ID to synchronize CSRs and HFENCEs in the nested acceleration shared memory and emulate the SRET instruction. - /// - /// Declared in §15.9. - pub const SYNC_SRET: usize = 4; -} - -/// Nested Acceleration Feature ID. -/// -/// Declared in §15. -pub mod feature_id { - /// Feature ID for the CSR synchronizing feature. - /// - /// Declared in §15.1. - pub const SYNC_CSR: usize = 0; - /// Feature ID for the HFENCE synchronizing feature. - /// - /// Declared in §15.2. - pub const SYNC_HFENCE: usize = 1; - /// Feature ID for the SRET synchronizing feature. - /// - /// Declared in §15.3. - pub const SYNC_SRET: usize = 2; - /// Feature ID for the auto-swap CSR feature. - /// - /// Declared in §15.4. - pub const AUTOSWAP_CSR: usize = 3; -} - -/// Size of shared memory set by supervisor software for current hart. -/// -/// NACL shared memory includes scratch space and CSR space. Due to the difference -/// of CSR width, this size varies between different `XLEN` values. `NATIVE` -/// constant here only matches the integer width for the target this crate is compiled. -/// If you are writing an SEE with different `XLEN` from the host platform, you should -/// choose other correct constant value from `RV32`, `RV64` or `RV128` in module `shmem_size` -/// instead. -pub mod shmem_size { - use core::mem::size_of; - /// Size of NACL shared memory on platforms with `XLEN` of the same width as the current platform. - pub const NATIVE: usize = 4096 + 1024 * size_of::(); - - /// Size of NACL shared memory on RV32 platforms. - pub const RV32: usize = 4096 + 1024 * size_of::(); - - /// Size of NACL shared memory on RV64 platforms. - pub const RV64: usize = 4096 + 1024 * size_of::(); - - /// Size of NACL shared memory on RV128 platforms. - pub const RV128: usize = 4096 + 1024 * size_of::(); -} diff --git a/third-party/vendor/sbi-spec/src/pmu.rs b/third-party/vendor/sbi-spec/src/pmu.rs deleted file mode 100644 index a231f984..00000000 --- a/third-party/vendor/sbi-spec/src/pmu.rs +++ /dev/null @@ -1,187 +0,0 @@ -//! Chapter 11. Performance Monitoring Unit Extension (EID #0x504D55 "PMU"). - -/// Extension ID for Performance Monitoring Unit extension. -pub const EID_PMU: usize = crate::eid_from_str("PMU") as _; -pub use fid::*; - -/// Declared in §11.11. -mod fid { - /// Function ID to get the number of counters, both hardware and firmware. - /// - /// Declared in §11.5. - pub const NUM_COUNTERS: usize = 0; - /// Function ID to get details about the specified counter. - /// - /// Declared in §11.6. - pub const COUNTER_GET_INFO: usize = 1; - /// Function ID to find and configure a counter from a set of counters. - /// - /// Declared in §11.7. - pub const COUNTER_CONFIG_MATCHING: usize = 2; - /// Function ID to start or enable a set of counters on the calling hart with the specified initial value. - /// - /// Declared in §11.8. - pub const COUNTER_START: usize = 3; - /// Function ID to stop or disable a set of counters on the calling hart. - /// - /// Declared in §11.9. - pub const COUNTER_STOP: usize = 4; - /// Function ID to provide the current value of a firmware counter. - /// - /// Declared in §11.10. - pub const COUNTER_FW_READ: usize = 5; - /// Function ID to provide the upper 32 bits from the value of the current firmware counter. - /// - /// Declared in §11.11. - pub const COUNTER_FW_READ_HI: usize = 6; - /// Function ID to set and enable the PMU snapshot shared memory. - /// - /// Declared in §11.12. - pub const SNAPSHOT_SET_SHMEM: usize = 7; -} - -/// PMU Event Types. -/// -/// Declared in §11. -pub mod event_type { - /// Type for all hardware general events. - /// - /// Declared in §11.1. - pub const HARDWARE_GENERAL: usize = 0; - /// Type for all hardware cache events. - /// - /// Declared in §11.2. - pub const HARDWARE_CACHE: usize = 1; - /// Type for all hardware raw events. - /// - /// Declared in §11.3. - pub const HARDWARE_RAW: usize = 2; - /// Type for all firmware events. - /// - /// Declared in §11.4. - pub const FIRMWARE: usize = 15; -} - -/// Hardware General Event Codes. -/// -/// Declared in §11.1. -pub mod hardware_event { - /// Unused event because event_idx cannot be zero. - pub const NO_EVENT: usize = 0; - /// Event for each CPU cycle. - pub const CPU_CYCLES: usize = 1; - /// Event for each completed instruction. - pub const INSTRUCTIONS: usize = 2; - /// Event for cache hit. - pub const CACHE_REFERENCES: usize = 3; - /// Event for cache miss. - pub const CACHE_MISSES: usize = 4; - /// Event for a branch instruction. - pub const BRANCH_INSTRUCTIONS: usize = 5; - /// Event for a branch mis-prediction. - pub const BRANCH_MISSES: usize = 6; - /// Event for each BUS cycle. - pub const BUS_CYCLES: usize = 7; - /// Event for a stalled cycle in micro-architecture frontend. - pub const STALLED_CYCLES_FRONTEND: usize = 8; - /// Event for a stalled cycle in micro-architecture backend. - pub const STALLED_CYCLES_BACKEND: usize = 9; - /// Event for each reference CPU cycle. - pub const REF_CPU_CYCLES: usize = 10; -} - -/// Hardware Cache Event ID. -/// -/// Declared in §11.2. -pub mod cache_event { - /// Level 1 data cache event. - pub const L1D: usize = 0; - /// Level 1 instruction cache event. - pub const L1I: usize = 1; - /// Last level cache event. - pub const LL: usize = 2; - /// Data TLB event. - pub const DTLB: usize = 3; - /// Instruction TLB event. - pub const ITLB: usize = 4; - /// Branch predictor unit event. - pub const BPU: usize = 5; - /// NUMA node cache event. - pub const NODE: usize = 6; -} - -/// Hardware Cache Operation ID. -/// -/// Declared in §11.2. -pub mod cache_operation { - /// Read cache line. - pub const READ: usize = 0; - /// Write cache line. - pub const WRITE: usize = 1; - /// Prefetch cache line. - pub const PREFETCH: usize = 2; -} - -/// Hardware Cache Operation Result ID. -/// -/// Declared in §11.2. -pub mod cache_result { - /// Cache access. - pub const ACCESS: usize = 0; - /// Cache miss. - pub const MISS: usize = 1; -} - -/// Firmware Event Codes. -/// -/// Declared in §11.4. -pub mod firmware_event { - /// Misaligned load trap event. - pub const MISALIGNED_LOAD: usize = 0; - /// Misaligned store trap event. - pub const MISALIGNED_STORE: usize = 1; - /// Load access trap event. - pub const ACCESS_LOAD: usize = 2; - /// Store access trap event. - pub const ACCESS_STORE: usize = 3; - /// Illegal instruction trap event. - pub const ILLEGAL_INSN: usize = 4; - /// Set timer event. - pub const SET_TIMER: usize = 5; - /// Sent IPI to other HART event. - pub const IPI_SENT: usize = 6; - /// Received IPI from other HART event. - pub const IPI_RECEIVED: usize = 7; - /// Sent FENCE.I request to other HART event. - pub const FENCE_I_SENT: usize = 8; - /// Received FENCE.I request from other HART event. - pub const FENCE_I_RECEIVED: usize = 9; - /// Sent SFENCE.VMA request to other HART event. - pub const SFENCE_VMA_SENT: usize = 10; - /// Received SFENCE.VMA request from other HART event. - pub const SFENCE_VMA_RECEIVED: usize = 11; - /// Sent SFENCE.VMA with ASID request to other HART event. - pub const SFENCE_VMA_ASID_SENT: usize = 12; - /// Received SFENCE.VMA with ASID request from other HART event. - pub const SFENCE_VMA_ASID_RECEIVED: usize = 13; - /// Sent HFENCE.GVMA request to other HART event. - pub const HFENCE_GVMA_SENT: usize = 14; - /// Received HFENCE.GVMA request from other HART event. - pub const HFENCE_GVMA_RECEIVED: usize = 15; - /// Sent HFENCE.GVMA with VMID request to other HART event. - pub const HFENCE_GVMA_VMID_SENT: usize = 16; - /// Received HFENCE.GVMA with VMID request from other HART event. - pub const HFENCE_GVMA_VMID_RECEIVED: usize = 17; - /// Sent HFENCE.VVMA request to other HART event. - pub const HFENCE_VVMA_SENT: usize = 18; - /// Received HFENCE.VVMA request from other HART event. - pub const HFENCE_VVMA_RECEIVED: usize = 19; - /// Sent HFENCE.VVMA with ASID request to other HART event. - pub const HFENCE_VVMA_ASID_SENT: usize = 20; - /// Received HFENCE.VVMA with ASID request from other HART event. - pub const HFENCE_VVMA_ASID_RECEIVED: usize = 21; - /// RISC-V platform specific firmware events. - /// - /// The `event_data` configuration (or parameter) contains the event encoding. - pub const PLATFORM: usize = 65535; -} diff --git a/third-party/vendor/sbi-spec/src/rfnc.rs b/third-party/vendor/sbi-spec/src/rfnc.rs deleted file mode 100644 index 7b57f7f9..00000000 --- a/third-party/vendor/sbi-spec/src/rfnc.rs +++ /dev/null @@ -1,37 +0,0 @@ -//! Chapter 8. RFENCE Extension (EID #0x52464E43 "RFNC"). - -/// Extension ID for Remote Fence extension. -pub const EID_RFNC: usize = crate::eid_from_str("RFNC") as _; -pub use fid::*; - -/// Declared in §8.8. -mod fid { - /// Function ID to `FENCE.I` instruction on remote harts. - /// - /// Declared in §8.1. - pub const REMOTE_FENCE_I: usize = 0; - /// Function ID to `SFENCE.VMA` for all address spaces on remote harts. - /// - /// Declared in §8.2. - pub const REMOTE_SFENCE_VMA: usize = 1; - /// Function ID to address space based `SFENCE.VMA` on remote harts. - /// - /// Declared in §8.3. - pub const REMOTE_SFENCE_VMA_ASID: usize = 2; - /// Function ID to virtual machine id based `HFENCE.GVMA` on remote harts. - /// - /// Declared in §8.4. - pub const REMOTE_HFENCE_GVMA_VMID: usize = 3; - /// Function ID to `HFENCE.GVMA` for all virtual machines on remote harts. - /// - /// Declared in §8.5. - pub const REMOTE_HFENCE_GVMA: usize = 4; - /// Function ID to address space based `HFENCE.VVMA` for current virtual machine on remote harts. - /// - /// Declared in §8.6. - pub const REMOTE_HFENCE_VVMA_ASID: usize = 5; - /// Function ID to `HFENCE.VVMA` for all address spaces in the current virtual machine on remote harts. - /// - /// Declared in §8.7. - pub const REMOTE_HFENCE_VVMA: usize = 6; -} diff --git a/third-party/vendor/sbi-spec/src/spi.rs b/third-party/vendor/sbi-spec/src/spi.rs deleted file mode 100644 index 29a82097..00000000 --- a/third-party/vendor/sbi-spec/src/spi.rs +++ /dev/null @@ -1,13 +0,0 @@ -//! Chapter 7. IPI Extension (EID #0x735049 "sPI: s-mode IPI"). - -/// Extension ID for Inter-processor Interrupt extension. -pub const EID_SPI: usize = crate::eid_from_str("sPI") as _; -pub use fid::*; - -/// Declared in §7.2. -mod fid { - /// Function ID to send an inter-processor interrupt to all harts defined in hart mask. - /// - /// Declared in §7.1. - pub const SEND_IPI: usize = 0; -} diff --git a/third-party/vendor/sbi-spec/src/srst.rs b/third-party/vendor/sbi-spec/src/srst.rs deleted file mode 100644 index 7377a201..00000000 --- a/third-party/vendor/sbi-spec/src/srst.rs +++ /dev/null @@ -1,25 +0,0 @@ -//! Chapter 10. System Reset Extension (EID #0x53525354 "SRST"). - -/// Extension ID for System Reset extension. -pub const EID_SRST: usize = crate::eid_from_str("SRST") as _; -pub use fid::*; - -/// Shutdown as a reset type. -pub const RESET_TYPE_SHUTDOWN: u32 = 0; -/// Cold Reboot as a reset type. -pub const RESET_TYPE_COLD_REBOOT: u32 = 1; -/// Warm Reboot as a reset type. -pub const RESET_TYPE_WARM_REBOOT: u32 = 2; - -/// No Reason as reset reason. -pub const RESET_REASON_NO_REASON: u32 = 0; -/// System Failure as reset reason. -pub const RESET_REASON_SYSTEM_FAILURE: u32 = 1; - -/// Declared in §10.2. -mod fid { - /// Function ID to reset the system based on provided reset type and reason. - /// - /// Declared in §10.1. - pub const SYSTEM_RESET: usize = 0; -} diff --git a/third-party/vendor/sbi-spec/src/sta.rs b/third-party/vendor/sbi-spec/src/sta.rs deleted file mode 100644 index a38cccd7..00000000 --- a/third-party/vendor/sbi-spec/src/sta.rs +++ /dev/null @@ -1,13 +0,0 @@ -//! Chapter 16. Steal-time Accounting Extension (EID #0x535441 "STA"). - -/// Extension ID for Steal-time Accounting Extension. -pub const EID_STA: usize = crate::eid_from_str("STA") as _; -pub use fid::*; - -/// Declared in §16.2. -mod fid { - /// Function ID to set the shared memory physical base address for steal-time accounting of the calling virtual hart and enable the SBI implementation’s steal-time information reporting. - /// - /// Declared in §16.1. - pub const SET_SHMEM: usize = 0; -} diff --git a/third-party/vendor/sbi-spec/src/susp.rs b/third-party/vendor/sbi-spec/src/susp.rs deleted file mode 100644 index 68374faf..00000000 --- a/third-party/vendor/sbi-spec/src/susp.rs +++ /dev/null @@ -1,13 +0,0 @@ -//! Chapter 13. System Suspend Extension (EID #0x53555350 "SUSP"). - -/// Extension ID for System Suspend Extension. -pub const EID_SUSP: usize = crate::eid_from_str("SUSP") as _; -pub use fid::*; - -/// Declared in §13. -mod fid { - /// Function ID to suspend under system-level sleep states. - /// - /// Declared in §13.1. - pub const SUSPEND: usize = 0; -} diff --git a/third-party/vendor/sbi-spec/src/time.rs b/third-party/vendor/sbi-spec/src/time.rs deleted file mode 100644 index 6dbbcac2..00000000 --- a/third-party/vendor/sbi-spec/src/time.rs +++ /dev/null @@ -1,13 +0,0 @@ -//! Chapter 6. Timer Extension (EID #0x54494D45 "TIME"). - -/// Extension ID for Timer extension. -pub const EID_TIME: usize = crate::eid_from_str("TIME") as _; -pub use fid::*; - -/// Declared in §6.2. -mod fid { - /// Function ID to program the clock for the next event after an absolute time. - /// - /// Declared in §6.1. - pub const SET_TIMER: usize = 0; -} diff --git a/third-party/vendor/scopeguard/.cargo-checksum.json b/third-party/vendor/scopeguard/.cargo-checksum.json deleted file mode 100644 index 5afe7357..00000000 --- a/third-party/vendor/scopeguard/.cargo-checksum.json +++ /dev/null @@ -1 +0,0 @@ -{"files":{"Cargo.lock":"684e99cc5938e7e51e1c5808214f9125ccfe66efa6ca5392303a7ee5337e1294","Cargo.toml":"68899251551903e2e1ba03c927f12e4c19fc8a15e8bd3756610f53f5ec075b48","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"fb77f0a9c53e473abe5103c8632ef9f0f2874d4fb3f17cb2d8c661aab9cee9d7","README.md":"68d5a7beebf814cffaaf6fe5758984fd06554b3bb5a49b2e13fc101522909b91","examples/readme.rs":"c6b1b458a130e091b1465040184759f1cc7d4e8de8d9cb893def0107238c2964","src/lib.rs":"3fb8bba1227724954c01cf98ec984bcf49ee74624faa74eb1bcea9018682751c"},"package":"94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"} \ No newline at end of file diff --git a/third-party/vendor/scopeguard/Cargo.lock b/third-party/vendor/scopeguard/Cargo.lock deleted file mode 100644 index ebfce518..00000000 --- a/third-party/vendor/scopeguard/Cargo.lock +++ /dev/null @@ -1,7 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -version = 3 - -[[package]] -name = "scopeguard" -version = "1.2.0" diff --git a/third-party/vendor/scopeguard/Cargo.toml b/third-party/vendor/scopeguard/Cargo.toml deleted file mode 100644 index acf5dce3..00000000 --- a/third-party/vendor/scopeguard/Cargo.toml +++ /dev/null @@ -1,43 +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 are reading this file be aware that the original Cargo.toml -# will likely look very different (and much more reasonable). -# See Cargo.toml.orig for the original contents. - -[package] -name = "scopeguard" -version = "1.2.0" -authors = ["bluss"] -description = """ -A RAII scope guard that will run a given closure when it goes out of scope, -even if the code between panics (assuming unwinding panic). - -Defines the macros `defer!`, `defer_on_unwind!`, `defer_on_success!` as -shorthands for guards with one of the implemented strategies. -""" -documentation = "https://docs.rs/scopeguard/" -readme = "README.md" -keywords = [ - "scope-guard", - "defer", - "panic", - "unwind", -] -categories = [ - "rust-patterns", - "no-std", -] -license = "MIT OR Apache-2.0" -repository = "https://github.com/bluss/scopeguard" - -[package.metadata.release] -no-dev-version = true - -[features] -default = ["use_std"] -use_std = [] diff --git a/third-party/vendor/scopeguard/LICENSE-APACHE b/third-party/vendor/scopeguard/LICENSE-APACHE deleted file mode 100644 index 16fe87b0..00000000 --- a/third-party/vendor/scopeguard/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. diff --git a/third-party/vendor/scopeguard/LICENSE-MIT b/third-party/vendor/scopeguard/LICENSE-MIT deleted file mode 100644 index 85144713..00000000 --- a/third-party/vendor/scopeguard/LICENSE-MIT +++ /dev/null @@ -1,25 +0,0 @@ -Copyright (c) 2016-2019 Ulrik Sverdrup "bluss" and scopeguard 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. diff --git a/third-party/vendor/scopeguard/README.md b/third-party/vendor/scopeguard/README.md deleted file mode 100644 index 01fa68c5..00000000 --- a/third-party/vendor/scopeguard/README.md +++ /dev/null @@ -1,102 +0,0 @@ -# scopeguard - -Rust crate for a convenient RAII scope guard that will run a given closure when -it goes out of scope, even if the code between panics (assuming unwinding panic). - -The `defer!` macro and `guard` are `no_std` compatible (require only `core`), -but the on unwinding / not on unwinding strategies require linking to `std`. -By default, the `use_std` crate feature is enabled. Disable the default features -for `no_std` support. - -Please read the [API documentation here](https://docs.rs/scopeguard/). - -Minimum supported Rust version: 1.20 - -[![build_status](https://github.com/bluss/scopeguard/actions/workflows/ci.yaml/badge.svg)](https://github.com/bluss/scopeguard/actions/workflows/ci.yaml) -[![crates](https://img.shields.io/crates/v/scopeguard.svg)](https://crates.io/crates/scopeguard) - -## How to use - -```rs -#[macro_use(defer)] -extern crate scopeguard; - -use scopeguard::guard; - -fn f() { - defer! { - println!("Called at return or panic"); - } - panic!(); -} - -use std::fs::File; -use std::io::Write; - -fn g() { - let f = File::create("newfile.txt").unwrap(); - let mut file = guard(f, |f| { - // write file at return or panic - let _ = f.sync_all(); - }); - // access the file through the scope guard itself - file.write_all(b"test me\n").unwrap(); -} -``` - -## Recent Changes - -- 1.2.0 - - - Use ManuallyDrop instead of mem::forget in into_inner. (by @willtunnels) - - Warn if the guard is not assigned to a variable and is dropped immediately - instead of at the scope's end. (by @sergey-v-galtsev) - -- 1.1.0 - - - Change macros (`defer!`, `defer_on_success!` and `defer_on_unwind!`) - to accept statements. (by @konsumlamm) - -- 1.0.0 - - - Change the closure type from `FnMut(&mut T)` to `FnOnce(T)`: - Passing the inner value by value instead of a mutable reference is a - breaking change, but allows the guard closure to consume it. (by @tormol) - - - Add `defer_on_success!`, `guard_on_success()` and `OnSuccess` - strategy, which triggers when scope is exited *without* panic. It's the - opposite to `defer_on_unwind!` / `guard_on_unwind()` / `OnUnwind`. - - - Add `ScopeGuard::into_inner()`, which "defuses" the guard and returns the - guarded value. (by @tormol) - - - Implement `Sync` for guards with non-`Sync` closures. - - - Require Rust 1.20 - -- 0.3.3 - - - Use `#[inline]` on a few more functions by @stjepang (#14) - - Add examples to crate documentation - -- 0.3.2 - - - Add crate categories - -- 0.3.1 - - - Add `defer_on_unwind!`, `Strategy` trait - - Rename `Guard` → `ScopeGuard` - - Add `ScopeGuard::with_strategy`. - - `ScopeGuard` now implements `Debug`. - - Require Rust 1.11 - -- 0.2.0 - - - Require Rust 1.6 - - Use `no_std` unconditionally - - No other changes - -- 0.1.2 - - - Add macro `defer!` diff --git a/third-party/vendor/scopeguard/examples/readme.rs b/third-party/vendor/scopeguard/examples/readme.rs deleted file mode 100644 index c4567e57..00000000 --- a/third-party/vendor/scopeguard/examples/readme.rs +++ /dev/null @@ -1,29 +0,0 @@ -#[macro_use(defer)] -extern crate scopeguard; - -use scopeguard::guard; - -fn f() { - defer! { - println!("Called at return or panic"); - } - panic!(); -} - -use std::fs::File; -use std::io::Write; - -fn g() { - let f = File::create("newfile.txt").unwrap(); - let mut file = guard(f, |f| { - // write file at return or panic - let _ = f.sync_all(); - }); - // access the file through the scope guard itself - file.write_all(b"test me\n").unwrap(); -} - -fn main() { - f(); - g(); -} diff --git a/third-party/vendor/scopeguard/src/lib.rs b/third-party/vendor/scopeguard/src/lib.rs deleted file mode 100644 index b5522c7b..00000000 --- a/third-party/vendor/scopeguard/src/lib.rs +++ /dev/null @@ -1,595 +0,0 @@ -#![cfg_attr(not(any(test, feature = "use_std")), no_std)] -#![doc(html_root_url = "https://docs.rs/scopeguard/1/")] - -//! A scope guard will run a given closure when it goes out of scope, -//! even if the code between panics. -//! (as long as panic doesn't abort) -//! -//! # Examples -//! -//! ## Hello World -//! -//! This example creates a scope guard with an example function: -//! -//! ``` -//! extern crate scopeguard; -//! -//! fn f() { -//! let _guard = scopeguard::guard((), |_| { -//! println!("Hello Scope Exit!"); -//! }); -//! -//! // rest of the code here. -//! -//! // Here, at the end of `_guard`'s scope, the guard's closure is called. -//! // It is also called if we exit this scope through unwinding instead. -//! } -//! # fn main() { -//! # f(); -//! # } -//! ``` -//! -//! ## `defer!` -//! -//! Use the `defer` macro to run an operation at scope exit, -//! either regular scope exit or during unwinding from a panic. -//! -//! ``` -//! #[macro_use(defer)] extern crate scopeguard; -//! -//! use std::cell::Cell; -//! -//! fn main() { -//! // use a cell to observe drops during and after the scope guard is active -//! let drop_counter = Cell::new(0); -//! { -//! // Create a scope guard using `defer!` for the current scope -//! defer! { -//! drop_counter.set(1 + drop_counter.get()); -//! } -//! -//! // Do regular operations here in the meantime. -//! -//! // Just before scope exit: it hasn't run yet. -//! assert_eq!(drop_counter.get(), 0); -//! -//! // The following scope end is where the defer closure is called -//! } -//! assert_eq!(drop_counter.get(), 1); -//! } -//! ``` -//! -//! ## Scope Guard with Value -//! -//! If the scope guard closure needs to access an outer value that is also -//! mutated outside of the scope guard, then you may want to use the scope guard -//! with a value. The guard works like a smart pointer, so the inner value can -//! be accessed by reference or by mutable reference. -//! -//! ### 1. The guard owns a file -//! -//! In this example, the scope guard owns a file and ensures pending writes are -//! synced at scope exit. -//! -//! ``` -//! extern crate scopeguard; -//! -//! use std::fs::*; -//! use std::io::{self, Write}; -//! # // Mock file so that we don't actually write a file -//! # struct MockFile; -//! # impl MockFile { -//! # fn create(_s: &str) -> io::Result { Ok(MockFile) } -//! # fn write_all(&self, _b: &[u8]) -> io::Result<()> { Ok(()) } -//! # fn sync_all(&self) -> io::Result<()> { Ok(()) } -//! # } -//! # use self::MockFile as File; -//! -//! fn try_main() -> io::Result<()> { -//! let f = File::create("newfile.txt")?; -//! let mut file = scopeguard::guard(f, |f| { -//! // ensure we flush file at return or panic -//! let _ = f.sync_all(); -//! }); -//! // Access the file through the scope guard itself -//! file.write_all(b"test me\n").map(|_| ()) -//! } -//! -//! fn main() { -//! try_main().unwrap(); -//! } -//! -//! ``` -//! -//! ### 2. The guard restores an invariant on scope exit -//! -//! ``` -//! extern crate scopeguard; -//! -//! use std::mem::ManuallyDrop; -//! use std::ptr; -//! -//! // This function, just for this example, takes the first element -//! // and inserts it into the assumed sorted tail of the vector. -//! // -//! // For optimization purposes we temporarily violate an invariant of the -//! // Vec, that it owns all of its elements. -//! // -//! // The safe approach is to use swap, which means two writes to memory, -//! // the optimization is to use a “hole” which uses only one write of memory -//! // for each position it moves. -//! // -//! // We *must* use a scope guard to run this code safely. We -//! // are running arbitrary user code (comparison operators) that may panic. -//! // The scope guard ensures we restore the invariant after successful -//! // exit or during unwinding from panic. -//! fn insertion_sort_first(v: &mut Vec) -//! where T: PartialOrd -//! { -//! struct Hole<'a, T: 'a> { -//! v: &'a mut Vec, -//! index: usize, -//! value: ManuallyDrop, -//! } -//! -//! unsafe { -//! // Create a moved-from location in the vector, a “hole”. -//! let value = ptr::read(&v[0]); -//! let mut hole = Hole { v: v, index: 0, value: ManuallyDrop::new(value) }; -//! -//! // Use a scope guard with a value. -//! // At scope exit, plug the hole so that the vector is fully -//! // initialized again. -//! // The scope guard owns the hole, but we can access it through the guard. -//! let mut hole_guard = scopeguard::guard(hole, |hole| { -//! // plug the hole in the vector with the value that was // taken out -//! let index = hole.index; -//! ptr::copy_nonoverlapping(&*hole.value, &mut hole.v[index], 1); -//! }); -//! -//! // run algorithm that moves the hole in the vector here -//! // move the hole until it's in a sorted position -//! for i in 1..hole_guard.v.len() { -//! if *hole_guard.value >= hole_guard.v[i] { -//! // move the element back and the hole forward -//! let index = hole_guard.index; -//! hole_guard.v.swap(index, index + 1); -//! hole_guard.index += 1; -//! } else { -//! break; -//! } -//! } -//! -//! // When the scope exits here, the Vec becomes whole again! -//! } -//! } -//! -//! fn main() { -//! let string = String::from; -//! let mut data = vec![string("c"), string("a"), string("b"), string("d")]; -//! insertion_sort_first(&mut data); -//! assert_eq!(data, vec!["a", "b", "c", "d"]); -//! } -//! -//! ``` -//! -//! -//! # Crate Features -//! -//! - `use_std` -//! + Enabled by default. Enables the `OnUnwind` and `OnSuccess` strategies. -//! + Disable to use `no_std`. -//! -//! # Rust Version -//! -//! This version of the crate requires Rust 1.20 or later. -//! -//! The scopeguard 1.x release series will use a carefully considered version -//! upgrade policy, where in a later 1.x version, we will raise the minimum -//! required Rust version. - -#[cfg(not(any(test, feature = "use_std")))] -extern crate core as std; - -use std::fmt; -use std::marker::PhantomData; -use std::mem::ManuallyDrop; -use std::ops::{Deref, DerefMut}; -use std::ptr; - -/// Controls in which cases the associated code should be run -pub trait Strategy { - /// Return `true` if the guard’s associated code should run - /// (in the context where this method is called). - fn should_run() -> bool; -} - -/// Always run on scope exit. -/// -/// “Always” run: on regular exit from a scope or on unwinding from a panic. -/// Can not run on abort, process exit, and other catastrophic events where -/// destructors don’t run. -#[derive(Debug)] -pub enum Always {} - -/// Run on scope exit through unwinding. -/// -/// Requires crate feature `use_std`. -#[cfg(feature = "use_std")] -#[derive(Debug)] -pub enum OnUnwind {} - -/// Run on regular scope exit, when not unwinding. -/// -/// Requires crate feature `use_std`. -#[cfg(feature = "use_std")] -#[derive(Debug)] -pub enum OnSuccess {} - -impl Strategy for Always { - #[inline(always)] - fn should_run() -> bool { - true - } -} - -#[cfg(feature = "use_std")] -impl Strategy for OnUnwind { - #[inline] - fn should_run() -> bool { - std::thread::panicking() - } -} - -#[cfg(feature = "use_std")] -impl Strategy for OnSuccess { - #[inline] - fn should_run() -> bool { - !std::thread::panicking() - } -} - -/// Macro to create a `ScopeGuard` (always run). -/// -/// The macro takes statements, which are the body of a closure -/// that will run when the scope is exited. -#[macro_export] -macro_rules! defer { - ($($t:tt)*) => { - let _guard = $crate::guard((), |()| { $($t)* }); - }; -} - -/// Macro to create a `ScopeGuard` (run on successful scope exit). -/// -/// The macro takes statements, which are the body of a closure -/// that will run when the scope is exited. -/// -/// Requires crate feature `use_std`. -#[cfg(feature = "use_std")] -#[macro_export] -macro_rules! defer_on_success { - ($($t:tt)*) => { - let _guard = $crate::guard_on_success((), |()| { $($t)* }); - }; -} - -/// Macro to create a `ScopeGuard` (run on unwinding from panic). -/// -/// The macro takes statements, which are the body of a closure -/// that will run when the scope is exited. -/// -/// Requires crate feature `use_std`. -#[cfg(feature = "use_std")] -#[macro_export] -macro_rules! defer_on_unwind { - ($($t:tt)*) => { - let _guard = $crate::guard_on_unwind((), |()| { $($t)* }); - }; -} - -/// `ScopeGuard` is a scope guard that may own a protected value. -/// -/// If you place a guard in a local variable, the closure can -/// run regardless how you leave the scope — through regular return or panic -/// (except if panic or other code aborts; so as long as destructors run). -/// It is run only once. -/// -/// The `S` parameter for [`Strategy`](trait.Strategy.html) determines if -/// the closure actually runs. -/// -/// The guard's closure will be called with the held value in the destructor. -/// -/// The `ScopeGuard` implements `Deref` so that you can access the inner value. -pub struct ScopeGuard -where - F: FnOnce(T), - S: Strategy, -{ - value: ManuallyDrop, - dropfn: ManuallyDrop, - // fn(S) -> S is used, so that the S is not taken into account for auto traits. - strategy: PhantomData S>, -} - -impl ScopeGuard -where - F: FnOnce(T), - S: Strategy, -{ - /// Create a `ScopeGuard` that owns `v` (accessible through deref) and calls - /// `dropfn` when its destructor runs. - /// - /// The `Strategy` decides whether the scope guard's closure should run. - #[inline] - #[must_use] - pub fn with_strategy(v: T, dropfn: F) -> ScopeGuard { - ScopeGuard { - value: ManuallyDrop::new(v), - dropfn: ManuallyDrop::new(dropfn), - strategy: PhantomData, - } - } - - /// “Defuse” the guard and extract the value without calling the closure. - /// - /// ``` - /// extern crate scopeguard; - /// - /// use scopeguard::{guard, ScopeGuard}; - /// - /// fn conditional() -> bool { true } - /// - /// fn main() { - /// let mut guard = guard(Vec::new(), |mut v| v.clear()); - /// guard.push(1); - /// - /// if conditional() { - /// // a condition maybe makes us decide to - /// // “defuse” the guard and get back its inner parts - /// let value = ScopeGuard::into_inner(guard); - /// } else { - /// // guard still exists in this branch - /// } - /// } - /// ``` - #[inline] - pub fn into_inner(guard: Self) -> T { - // Cannot move out of `Drop`-implementing types, - // so `ptr::read` the value and forget the guard. - let mut guard = ManuallyDrop::new(guard); - unsafe { - let value = ptr::read(&*guard.value); - // Drop the closure after `value` has been read, so that if the - // closure's `drop` function panics, unwinding still tries to drop - // `value`. - ManuallyDrop::drop(&mut guard.dropfn); - value - } - } -} - -/// Create a new `ScopeGuard` owning `v` and with deferred closure `dropfn`. -#[inline] -#[must_use] -pub fn guard(v: T, dropfn: F) -> ScopeGuard -where - F: FnOnce(T), -{ - ScopeGuard::with_strategy(v, dropfn) -} - -/// Create a new `ScopeGuard` owning `v` and with deferred closure `dropfn`. -/// -/// Requires crate feature `use_std`. -#[cfg(feature = "use_std")] -#[inline] -#[must_use] -pub fn guard_on_success(v: T, dropfn: F) -> ScopeGuard -where - F: FnOnce(T), -{ - ScopeGuard::with_strategy(v, dropfn) -} - -/// Create a new `ScopeGuard` owning `v` and with deferred closure `dropfn`. -/// -/// Requires crate feature `use_std`. -/// -/// ## Examples -/// -/// For performance reasons, or to emulate “only run guard on unwind” in -/// no-std environments, we can also use the default guard and simply manually -/// defuse it at the end of scope like the following example. (The performance -/// reason would be if the [`OnUnwind`]'s call to [std::thread::panicking()] is -/// an issue.) -/// -/// ``` -/// extern crate scopeguard; -/// -/// use scopeguard::ScopeGuard; -/// # fn main() { -/// { -/// let guard = scopeguard::guard((), |_| {}); -/// -/// // rest of the code here -/// -/// // we reached the end of scope without unwinding - defuse it -/// ScopeGuard::into_inner(guard); -/// } -/// # } -/// ``` -#[cfg(feature = "use_std")] -#[inline] -#[must_use] -pub fn guard_on_unwind(v: T, dropfn: F) -> ScopeGuard -where - F: FnOnce(T), -{ - ScopeGuard::with_strategy(v, dropfn) -} - -// ScopeGuard can be Sync even if F isn't because the closure is -// not accessible from references. -// The guard does not store any instance of S, so it is also irrelevant. -unsafe impl Sync for ScopeGuard -where - T: Sync, - F: FnOnce(T), - S: Strategy, -{ -} - -impl Deref for ScopeGuard -where - F: FnOnce(T), - S: Strategy, -{ - type Target = T; - - fn deref(&self) -> &T { - &*self.value - } -} - -impl DerefMut for ScopeGuard -where - F: FnOnce(T), - S: Strategy, -{ - fn deref_mut(&mut self) -> &mut T { - &mut *self.value - } -} - -impl Drop for ScopeGuard -where - F: FnOnce(T), - S: Strategy, -{ - fn drop(&mut self) { - // This is OK because the fields are `ManuallyDrop`s - // which will not be dropped by the compiler. - let (value, dropfn) = unsafe { (ptr::read(&*self.value), ptr::read(&*self.dropfn)) }; - if S::should_run() { - dropfn(value); - } - } -} - -impl fmt::Debug for ScopeGuard -where - T: fmt::Debug, - F: FnOnce(T), - S: Strategy, -{ - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - f.debug_struct(stringify!(ScopeGuard)) - .field("value", &*self.value) - .finish() - } -} - -#[cfg(test)] -mod tests { - use super::*; - use std::cell::Cell; - use std::panic::catch_unwind; - use std::panic::AssertUnwindSafe; - - #[test] - fn test_defer() { - let drops = Cell::new(0); - defer!(drops.set(1000)); - assert_eq!(drops.get(), 0); - } - - #[cfg(feature = "use_std")] - #[test] - fn test_defer_success_1() { - let drops = Cell::new(0); - { - defer_on_success!(drops.set(1)); - assert_eq!(drops.get(), 0); - } - assert_eq!(drops.get(), 1); - } - - #[cfg(feature = "use_std")] - #[test] - fn test_defer_success_2() { - let drops = Cell::new(0); - let _ = catch_unwind(AssertUnwindSafe(|| { - defer_on_success!(drops.set(1)); - panic!("failure") - })); - assert_eq!(drops.get(), 0); - } - - #[cfg(feature = "use_std")] - #[test] - fn test_defer_unwind_1() { - let drops = Cell::new(0); - let _ = catch_unwind(AssertUnwindSafe(|| { - defer_on_unwind!(drops.set(1)); - assert_eq!(drops.get(), 0); - panic!("failure") - })); - assert_eq!(drops.get(), 1); - } - - #[cfg(feature = "use_std")] - #[test] - fn test_defer_unwind_2() { - let drops = Cell::new(0); - { - defer_on_unwind!(drops.set(1)); - } - assert_eq!(drops.get(), 0); - } - - #[test] - fn test_only_dropped_by_closure_when_run() { - let value_drops = Cell::new(0); - let value = guard((), |()| value_drops.set(1 + value_drops.get())); - let closure_drops = Cell::new(0); - let guard = guard(value, |_| closure_drops.set(1 + closure_drops.get())); - assert_eq!(value_drops.get(), 0); - assert_eq!(closure_drops.get(), 0); - drop(guard); - assert_eq!(value_drops.get(), 1); - assert_eq!(closure_drops.get(), 1); - } - - #[cfg(feature = "use_std")] - #[test] - fn test_dropped_once_when_not_run() { - let value_drops = Cell::new(0); - let value = guard((), |()| value_drops.set(1 + value_drops.get())); - let captured_drops = Cell::new(0); - let captured = guard((), |()| captured_drops.set(1 + captured_drops.get())); - let closure_drops = Cell::new(0); - let guard = guard_on_unwind(value, |value| { - drop(value); - drop(captured); - closure_drops.set(1 + closure_drops.get()) - }); - assert_eq!(value_drops.get(), 0); - assert_eq!(captured_drops.get(), 0); - assert_eq!(closure_drops.get(), 0); - drop(guard); - assert_eq!(value_drops.get(), 1); - assert_eq!(captured_drops.get(), 1); - assert_eq!(closure_drops.get(), 0); - } - - #[test] - fn test_into_inner() { - let dropped = Cell::new(false); - let value = guard(42, |_| dropped.set(true)); - let guard = guard(value, |_| dropped.set(true)); - let inner = ScopeGuard::into_inner(guard); - assert_eq!(dropped.get(), false); - assert_eq!(*inner, 42); - } -} diff --git a/third-party/vendor/spin/.cargo-checksum.json b/third-party/vendor/spin/.cargo-checksum.json deleted file mode 100644 index 05961f16..00000000 --- a/third-party/vendor/spin/.cargo-checksum.json +++ /dev/null @@ -1 +0,0 @@ -{"files":{"CHANGELOG.md":"34b35704b01c68214b27cb20f0c4325b3ce6e40ce8fd5aa3d2b884697a27307b","Cargo.lock":"9d6481d9ffe412e6c4d9445d89c0fa3e33a14b61c56aa5c121d9f28656cacfe4","Cargo.toml":"d2a17df2fa85736364744ea8279c6aed7276cabcc63bca2d25667198504e4be7","LICENSE":"6ac8711fb340c62ce0a4ecd463342d3fa0e8e70de697c863a2e1c0c53006003c","README.md":"78f0456ba0f3fa490d2bf38d79c42b293d551a9951da5bef0e1e5043143abf78","benches/mutex.rs":"2fd79239798e88cab0fd982e04f91a44c7c63282f8703d85fbdd81a8a1e71917","examples/debug.rs":"0074651d78f8ed6d6c0274ae832c0d78de6c5c59423936f58e79cb3c98baea2c","script/doc-upload.cfg":"7383ee022197c1dade9a2e6888261def4a80df08ecb72b1b4db47d1e8a6ff8e0","src/barrier.rs":"f8569a601d870a713344747eb355e6d840db510a599709173ebd0ccba5fc4028","src/lazy.rs":"45cf9174ee607e8a9acfa652b95c9b0ac71d98e89e73b9850041c79c5f3a726e","src/lib.rs":"85fa19874da6518e7ccd0d8bd3a0549fba52afd820789797e0221af1ac62196a","src/mutex.rs":"530039838850a0e71f4af42b9a7cffa0f922874e8f00001d36d67876842ed68f","src/mutex/fair.rs":"74cf2a0b8ab8e7a95564d97e8a66fc5d3d2641dd655de56a94ae4a93458f82c3","src/mutex/spin.rs":"a11e42d58e87a195e5e2110b46bda766f5a62a0c0b75a2b163f1ce37745bf337","src/mutex/ticket.rs":"1711bb02de48cf92f950b8f31946d5003225542ab6521333be1f525b76710f26","src/once.rs":"e4289220d505b7a15e8f9fb3f0d032ee57df6a5ee1d50123d4187e1afc6fb98b","src/relax.rs":"919c345bf55c3b2f9a7d9cd4aec2b2b3db68b6dc40ee2e4de4f6f32027abc290","src/rwlock.rs":"ba3b3dd20cdcd97691f042bcdd6d352e52601db7dc0cc7053c01a5873754b196"},"package":"6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67"} \ No newline at end of file diff --git a/third-party/vendor/spin/CHANGELOG.md b/third-party/vendor/spin/CHANGELOG.md deleted file mode 100644 index 09f1f68b..00000000 --- a/third-party/vendor/spin/CHANGELOG.md +++ /dev/null @@ -1,146 +0,0 @@ -# Changelog - -All notable changes to this project will be documented in this file. - -The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), -and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). - -# Unreleased - -### Added - -### Changed - -### Fixed - -# [0.9.8] - 2023-04-03 - -### Fixed - -- Unsoundness in `Once::try_call_once` caused by an `Err(_)` result - -# [0.9.7] - 2023-03-27 - -### Fixed - -- Relaxed accidentally restricted `Send`/`Sync` bounds for `Mutex` guards - -# [0.9.6] - 2023-03-13 - -### Fixed - -- Relaxed accidentally restricted `Send`/`Sync` bounds for `RwLock` guards - -# [0.9.5] - 2023-02-07 - -### Added - -- `FairMutex`, a new mutex implementation that reduces writer starvation. -- A MSRV policy: Rust 1.38 is currently required - -### Changed - -- The crate's CI now has full MIRI integration, further improving the confidence you can have in the implementation. - -### Fixed - -- Ensured that the crate's abstractions comply with stacked borrows rules. -- Unsoundness in the `RwLock` that could be triggered via a reader overflow -- Relaxed various `Send`/`Sync` bound requirements to make the crate more flexible - -# [0.9.4] - 2022-07-14 - -### Fixed - -- Fixed unsoundness in `RwLock` on reader overflow -- Relaxed `Send`/`Sync` bounds for `SpinMutex` and `TicketMutex` (doesn't affect `Mutex` itself) - -# [0.9.3] - 2022-04-17 - -### Added - -- Implemented `Default` for `Once` -- `Once::try_call_once` - -### Fixed - -- Fixed bug that caused `Once::call_once` to incorrectly fail - -# [0.9.2] - 2021-07-09 - -### Changed - -- Improved `Once` performance by reducing the memory footprint of internal state to one byte - -### Fixed - -- Improved performance of `Once` by relaxing ordering guarantees and removing redundant checks - -# [0.9.1] - 2021-06-21 - -### Added - -- Default type parameter on `Once` for better ergonomics - -# [0.9.0] - 2021-03-18 - -### Changed - -- Placed all major API features behind feature flags - -### Fixed - -- A compilation bug with the `lock_api` feature - -# [0.8.0] - 2021-03-15 - -### Added - -- `Once::get_unchecked` -- `RelaxStrategy` trait with type parameter on all locks to support switching between relax strategies - -### Changed - -- `lock_api1` feature is now named `lock_api` - -# [0.7.1] - 2021-01-12 - -### Fixed - -- Prevented `Once` leaking the inner value upon drop - -# [0.7.0] - 2020-10-18 - -### Added - -- `Once::initialized` -- `Once::get_mut` -- `Once::try_into_inner` -- `Once::poll` -- `RwLock`, `Mutex` and `Once` now implement `From` -- `Lazy` type for lazy initialization -- `TicketMutex`, an alternative mutex implementation -- `std` feature flag to enable thread yielding instead of spinning -- `Mutex::is_locked`/`SpinMutex::is_locked`/`TicketMutex::is_locked` -- `Barrier` - -### Changed - -- `Once::wait` now spins even if initialization has not yet started -- `Guard::leak` is now an associated function instead of a method -- Improved the performance of `SpinMutex` by relaxing unnecessarily conservative - ordering requirements - -# [0.6.0] - 2020-10-08 - -### Added - -- More dynamic `Send`/`Sync` bounds for lock guards -- `lock_api` compatibility -- `Guard::leak` methods -- `RwLock::reader_count` and `RwLock::writer_count` -- `Display` implementation for guard types - -### Changed - -- Made `Debug` impls of lock guards just show the inner type like `std` diff --git a/third-party/vendor/spin/Cargo.lock b/third-party/vendor/spin/Cargo.lock deleted file mode 100644 index d8bb6cbd..00000000 --- a/third-party/vendor/spin/Cargo.lock +++ /dev/null @@ -1,623 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -version = 3 - -[[package]] -name = "anes" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b46cbb362ab8752921c97e041f5e366ee6297bd428a31275b9fcf1e380f7299" - -[[package]] -name = "atty" -version = "0.2.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" -dependencies = [ - "hermit-abi 0.1.19", - "libc", - "winapi", -] - -[[package]] -name = "autocfg" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" - -[[package]] -name = "bitflags" -version = "1.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" - -[[package]] -name = "bumpalo" -version = "3.12.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d261e256854913907f67ed06efbc3338dfe6179796deefc1ff763fc1aee5535" - -[[package]] -name = "cast" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37b2a672a2cb129a2e41c10b1224bb368f9f37a2b16b612598138befd7b37eb5" - -[[package]] -name = "cfg-if" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" - -[[package]] -name = "ciborium" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0c137568cc60b904a7724001b35ce2630fd00d5d84805fbb608ab89509d788f" -dependencies = [ - "ciborium-io", - "ciborium-ll", - "serde", -] - -[[package]] -name = "ciborium-io" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "346de753af073cc87b52b2083a506b38ac176a44cfb05497b622e27be899b369" - -[[package]] -name = "ciborium-ll" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "213030a2b5a4e0c0892b6652260cf6ccac84827b83a85a534e178e3906c4cf1b" -dependencies = [ - "ciborium-io", - "half", -] - -[[package]] -name = "clap" -version = "3.2.23" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "71655c45cb9845d3270c9d6df84ebe72b4dad3c2ba3f7023ad47c144e4e473a5" -dependencies = [ - "bitflags", - "clap_lex", - "indexmap", - "textwrap", -] - -[[package]] -name = "clap_lex" -version = "0.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2850f2f5a82cbf437dd5af4d49848fbdfc27c157c3d010345776f952765261c5" -dependencies = [ - "os_str_bytes", -] - -[[package]] -name = "criterion" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7c76e09c1aae2bc52b3d2f29e13c6572553b30c4aa1b8a49fd70de6412654cb" -dependencies = [ - "anes", - "atty", - "cast", - "ciborium", - "clap", - "criterion-plot", - "itertools", - "lazy_static", - "num-traits", - "oorandom", - "plotters", - "rayon", - "regex", - "serde", - "serde_derive", - "serde_json", - "tinytemplate", - "walkdir", -] - -[[package]] -name = "criterion-plot" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b50826342786a51a89e2da3a28f1c32b06e387201bc2d19791f622c673706b1" -dependencies = [ - "cast", - "itertools", -] - -[[package]] -name = "crossbeam-channel" -version = "0.5.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf2b3e8478797446514c91ef04bafcb59faba183e621ad488df88983cc14128c" -dependencies = [ - "cfg-if", - "crossbeam-utils", -] - -[[package]] -name = "crossbeam-deque" -version = "0.8.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce6fd6f855243022dcecf8702fef0c297d4338e226845fe067f6341ad9fa0cef" -dependencies = [ - "cfg-if", - "crossbeam-epoch", - "crossbeam-utils", -] - -[[package]] -name = "crossbeam-epoch" -version = "0.9.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46bd5f3f85273295a9d14aedfb86f6aadbff6d8f5295c4a9edb08e819dcf5695" -dependencies = [ - "autocfg", - "cfg-if", - "crossbeam-utils", - "memoffset", - "scopeguard", -] - -[[package]] -name = "crossbeam-utils" -version = "0.8.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c063cd8cc95f5c377ed0d4b49a4b21f632396ff690e8470c29b3359b346984b" -dependencies = [ - "cfg-if", -] - -[[package]] -name = "either" -version = "1.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fcaabb2fef8c910e7f4c7ce9f67a1283a1715879a7c230ca9d6d1ae31f16d91" - -[[package]] -name = "half" -version = "1.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eabb4a44450da02c90444cf74558da904edde8fb4e9035a9a6a4e15445af0bd7" - -[[package]] -name = "hashbrown" -version = "0.12.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" - -[[package]] -name = "hermit-abi" -version = "0.1.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" -dependencies = [ - "libc", -] - -[[package]] -name = "hermit-abi" -version = "0.2.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee512640fe35acbfb4bb779db6f0d80704c2cacfa2e39b601ef3e3f47d1ae4c7" -dependencies = [ - "libc", -] - -[[package]] -name = "indexmap" -version = "1.9.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" -dependencies = [ - "autocfg", - "hashbrown", -] - -[[package]] -name = "itertools" -version = "0.10.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473" -dependencies = [ - "either", -] - -[[package]] -name = "itoa" -version = "1.0.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "453ad9f582a441959e5f0d088b02ce04cfe8d51a8eaf077f12ac6d3e94164ca6" - -[[package]] -name = "js-sys" -version = "0.3.61" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "445dde2150c55e483f3d8416706b97ec8e8237c307e5b7b4b8dd15e6af2a0730" -dependencies = [ - "wasm-bindgen", -] - -[[package]] -name = "lazy_static" -version = "1.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" - -[[package]] -name = "libc" -version = "0.2.140" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "99227334921fae1a979cf0bfdfcc6b3e5ce376ef57e16fb6fb3ea2ed6095f80c" - -[[package]] -name = "lock_api" -version = "0.4.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "435011366fe56583b16cf956f9df0095b405b82d76425bc8981c0e22e60ec4df" -dependencies = [ - "autocfg", - "scopeguard", -] - -[[package]] -name = "log" -version = "0.4.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e" -dependencies = [ - "cfg-if", -] - -[[package]] -name = "memoffset" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d61c719bcfbcf5d62b3a09efa6088de8c54bc0bfcd3ea7ae39fcc186108b8de1" -dependencies = [ - "autocfg", -] - -[[package]] -name = "num-traits" -version = "0.2.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "578ede34cf02f8924ab9447f50c28075b4d3e5b269972345e7e0372b38c6cdcd" -dependencies = [ - "autocfg", -] - -[[package]] -name = "num_cpus" -version = "1.15.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fac9e2da13b5eb447a6ce3d392f23a29d8694bff781bf03a16cd9ac8697593b" -dependencies = [ - "hermit-abi 0.2.6", - "libc", -] - -[[package]] -name = "once_cell" -version = "1.17.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b7e5500299e16ebb147ae15a00a942af264cf3688f47923b8fc2cd5858f23ad3" - -[[package]] -name = "oorandom" -version = "11.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ab1bc2a289d34bd04a330323ac98a1b4bc82c9d9fcb1e66b63caa84da26b575" - -[[package]] -name = "os_str_bytes" -version = "6.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ceedf44fb00f2d1984b0bc98102627ce622e083e49a5bacdb3e514fa4238e267" - -[[package]] -name = "plotters" -version = "0.3.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2538b639e642295546c50fcd545198c9d64ee2a38620a628724a3b266d5fbf97" -dependencies = [ - "num-traits", - "plotters-backend", - "plotters-svg", - "wasm-bindgen", - "web-sys", -] - -[[package]] -name = "plotters-backend" -version = "0.3.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "193228616381fecdc1224c62e96946dfbc73ff4384fba576e052ff8c1bea8142" - -[[package]] -name = "plotters-svg" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f9a81d2759aae1dae668f783c308bc5c8ebd191ff4184aaa1b37f65a6ae5a56f" -dependencies = [ - "plotters-backend", -] - -[[package]] -name = "portable-atomic" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f602a0d1e09a48e4f8e8b4d4042e32807c3676da31f2ecabeac9f96226ec6c45" - -[[package]] -name = "proc-macro2" -version = "1.0.56" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b63bdb0cd06f1f4dedf69b254734f9b45af66e4a031e42a7480257d9898b435" -dependencies = [ - "unicode-ident", -] - -[[package]] -name = "quote" -version = "1.0.26" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4424af4bf778aae2051a77b60283332f386554255d722233d09fbfc7e30da2fc" -dependencies = [ - "proc-macro2", -] - -[[package]] -name = "rayon" -version = "1.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d2df5196e37bcc87abebc0053e20787d73847bb33134a69841207dd0a47f03b" -dependencies = [ - "either", - "rayon-core", -] - -[[package]] -name = "rayon-core" -version = "1.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b8f95bd6966f5c87776639160a66bd8ab9895d9d4ab01ddba9fc60661aebe8d" -dependencies = [ - "crossbeam-channel", - "crossbeam-deque", - "crossbeam-utils", - "num_cpus", -] - -[[package]] -name = "regex" -version = "1.7.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b1f693b24f6ac912f4893ef08244d70b6067480d2f1a46e950c9691e6749d1d" -dependencies = [ - "regex-syntax", -] - -[[package]] -name = "regex-syntax" -version = "0.6.29" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" - -[[package]] -name = "ryu" -version = "1.0.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f91339c0467de62360649f8d3e185ca8de4224ff281f66000de5eb2a77a79041" - -[[package]] -name = "same-file" -version = "1.0.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" -dependencies = [ - "winapi-util", -] - -[[package]] -name = "scopeguard" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" - -[[package]] -name = "serde" -version = "1.0.159" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c04e8343c3daeec41f58990b9d77068df31209f2af111e059e9fe9646693065" -dependencies = [ - "serde_derive", -] - -[[package]] -name = "serde_derive" -version = "1.0.159" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c614d17805b093df4b147b51339e7e44bf05ef59fba1e45d83500bcfb4d8585" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.13", -] - -[[package]] -name = "serde_json" -version = "1.0.95" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d721eca97ac802aa7777b701877c8004d950fc142651367300d21c1cc0194744" -dependencies = [ - "itoa", - "ryu", - "serde", -] - -[[package]] -name = "spin" -version = "0.9.8" -dependencies = [ - "criterion", - "lock_api", - "portable-atomic", -] - -[[package]] -name = "syn" -version = "1.0.109" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "syn" -version = "2.0.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c9da457c5285ac1f936ebd076af6dac17a61cfe7826f2076b4d015cf47bc8ec" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "textwrap" -version = "0.16.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "222a222a5bfe1bba4a77b45ec488a741b3cb8872e5e499451fd7d0129c9c7c3d" - -[[package]] -name = "tinytemplate" -version = "1.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be4d6b5f19ff7664e8c98d03e2139cb510db9b0a60b55f8e8709b689d939b6bc" -dependencies = [ - "serde", - "serde_json", -] - -[[package]] -name = "unicode-ident" -version = "1.0.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5464a87b239f13a63a501f2701565754bae92d243d4bb7eb12f6d57d2269bf4" - -[[package]] -name = "walkdir" -version = "2.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "36df944cda56c7d8d8b7496af378e6b16de9284591917d307c9b4d313c44e698" -dependencies = [ - "same-file", - "winapi-util", -] - -[[package]] -name = "wasm-bindgen" -version = "0.2.84" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "31f8dcbc21f30d9b8f2ea926ecb58f6b91192c17e9d33594b3df58b2007ca53b" -dependencies = [ - "cfg-if", - "wasm-bindgen-macro", -] - -[[package]] -name = "wasm-bindgen-backend" -version = "0.2.84" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95ce90fd5bcc06af55a641a86428ee4229e44e07033963a2290a8e241607ccb9" -dependencies = [ - "bumpalo", - "log", - "once_cell", - "proc-macro2", - "quote", - "syn 1.0.109", - "wasm-bindgen-shared", -] - -[[package]] -name = "wasm-bindgen-macro" -version = "0.2.84" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c21f77c0bedc37fd5dc21f897894a5ca01e7bb159884559461862ae90c0b4c5" -dependencies = [ - "quote", - "wasm-bindgen-macro-support", -] - -[[package]] -name = "wasm-bindgen-macro-support" -version = "0.2.84" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2aff81306fcac3c7515ad4e177f521b5c9a15f2b08f4e32d823066102f35a5f6" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.109", - "wasm-bindgen-backend", - "wasm-bindgen-shared", -] - -[[package]] -name = "wasm-bindgen-shared" -version = "0.2.84" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0046fef7e28c3804e5e38bfa31ea2a0f73905319b677e57ebe37e49358989b5d" - -[[package]] -name = "web-sys" -version = "0.3.61" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e33b99f4b23ba3eec1a53ac264e35a755f00e966e0065077d6027c0f575b0b97" -dependencies = [ - "js-sys", - "wasm-bindgen", -] - -[[package]] -name = "winapi" -version = "0.3.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" -dependencies = [ - "winapi-i686-pc-windows-gnu", - "winapi-x86_64-pc-windows-gnu", -] - -[[package]] -name = "winapi-i686-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" - -[[package]] -name = "winapi-util" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" -dependencies = [ - "winapi", -] - -[[package]] -name = "winapi-x86_64-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" diff --git a/third-party/vendor/spin/Cargo.toml b/third-party/vendor/spin/Cargo.toml deleted file mode 100644 index ff0d151c..00000000 --- a/third-party/vendor/spin/Cargo.toml +++ /dev/null @@ -1,80 +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 are reading this file be aware that the original Cargo.toml -# will likely look very different (and much more reasonable). -# See Cargo.toml.orig for the original contents. - -[package] -rust-version = "1.38" -name = "spin" -version = "0.9.8" -authors = [ - "Mathijs van de Nes ", - "John Ericson ", - "Joshua Barretto ", -] -description = "Spin-based synchronization primitives" -readme = "README.md" -keywords = [ - "spinlock", - "mutex", - "rwlock", -] -license = "MIT" -repository = "https://github.com/mvdnes/spin-rs.git" - -[package.metadata.docs.rs] -all-features = true -rustdoc-args = [ - "--cfg", - "docsrs", -] - -[[bench]] -name = "mutex" -harness = false -required-features = ["ticket_mutex"] - -[dependencies.lock_api_crate] -version = "0.4" -optional = true -package = "lock_api" - -[dependencies.portable-atomic] -version = "1" -optional = true -default-features = false - -[dev-dependencies.criterion] -version = "0.4" - -[features] -barrier = ["mutex"] -default = [ - "lock_api", - "mutex", - "spin_mutex", - "rwlock", - "once", - "lazy", - "barrier", -] -fair_mutex = ["mutex"] -lazy = ["once"] -lock_api = ["lock_api_crate"] -mutex = [] -once = [] -portable_atomic = ["portable-atomic"] -rwlock = [] -spin_mutex = ["mutex"] -std = [] -ticket_mutex = ["mutex"] -use_ticket_mutex = [ - "mutex", - "ticket_mutex", -] diff --git a/third-party/vendor/spin/LICENSE b/third-party/vendor/spin/LICENSE deleted file mode 100644 index b2d7f7bb..00000000 --- a/third-party/vendor/spin/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2014 Mathijs van de Nes - -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. \ No newline at end of file diff --git a/third-party/vendor/spin/README.md b/third-party/vendor/spin/README.md deleted file mode 100644 index 7fd37800..00000000 --- a/third-party/vendor/spin/README.md +++ /dev/null @@ -1,143 +0,0 @@ -# spin-rs - -[![Crates.io version](https://img.shields.io/crates/v/spin.svg)](https://crates.io/crates/spin) -[![docs.rs](https://docs.rs/spin/badge.svg)](https://docs.rs/spin/) -[![Build Status](https://travis-ci.org/mvdnes/spin-rs.svg)](https://travis-ci.org/mvdnes/spin-rs) - -Spin-based synchronization primitives. - -This crate provides [spin-based](https://en.wikipedia.org/wiki/Spinlock) -versions of the primitives in `std::sync`. Because synchronization is done -through spinning, the primitives are suitable for use in `no_std` environments. - -Before deciding to use `spin`, we recommend reading -[this superb blog post](https://matklad.github.io/2020/01/02/spinlocks-considered-harmful.html) -by [@matklad](https://github.com/matklad/) that discusses the pros and cons of -spinlocks. If you have access to `std`, it's likely that the primitives in -`std::sync` will serve you better except in very specific circumstances. - -## Features - -- `Mutex`, `RwLock`, `Once`, `Lazy` and `Barrier` equivalents -- Support for `no_std` environments -- [`lock_api`](https://crates.io/crates/lock_api) compatibility -- Upgradeable `RwLock` guards -- Guards can be sent and shared between threads -- Guard leaking -- Ticket locks -- Different strategies for dealing with contention - -## Usage - -Include the following under the `[dependencies]` section in your `Cargo.toml` file. - -```toml -spin = "x.y" -``` - -## Example - -When calling `lock` on a `Mutex` you will get a guard value that provides access -to the data. When this guard is dropped, the mutex will become available again. - -```rust -extern crate spin; -use std::{sync::Arc, thread}; - -fn main() { - let counter = Arc::new(spin::Mutex::new(0)); - - let thread = thread::spawn({ - let counter = counter.clone(); - move || { - for _ in 0..100 { - *counter.lock() += 1; - } - } - }); - - for _ in 0..100 { - *counter.lock() += 1; - } - - thread.join().unwrap(); - - assert_eq!(*counter.lock(), 200); -} -``` - -## Feature flags - -The crate comes with a few feature flags that you may wish to use. - -- `mutex` enables the `Mutex` type. - -- `spin_mutex` enables the `SpinMutex` type. - -- `ticket_mutex` enables the `TicketMutex` type. - -- `use_ticket_mutex` switches to a ticket lock for the implementation of `Mutex`. This - is recommended only on targets for which ordinary spinning locks perform very badly - because it will change the implementation used by other crates that depend on `spin`. - -- `rwlock` enables the `RwLock` type. - -- `once` enables the `Once` type. - -- `lazy` enables the `Lazy` type. - -- `barrier` enables the `Barrier` type. - -- `lock_api` enables support for [`lock_api`](https://crates.io/crates/lock_api) - -- `std` enables support for thread yielding instead of spinning. - -- `portable_atomic` enables usage of the `portable-atomic` crate - to support platforms without native atomic operations (Cortex-M0, etc.). - The `portable_atomic_unsafe_assume_single_core` cfg or `critical-section` feature - of `portable-atomic` crate must also be set by the final binary crate. - - When using the cfg, this can be done by adapting the following snippet to the `.cargo/config` file: - ``` - [target.] - rustflags = [ "--cfg", "portable_atomic_unsafe_assume_single_core" ] - ``` - Note that this cfg is unsafe by nature, and enabling it for multicore systems is unsound. - - When using the `critical-section` feature, you need to implement the critical-section - implementation that sound for your system by implementing an unsafe trait. - See [the documentation for the `portable-atomic` crate](https://docs.rs/portable-atomic/latest/portable_atomic/#optional-cfg) - for more information. - -## Remarks - -It is often desirable to have a lock shared between threads. Wrapping the lock in an -`std::sync::Arc` is route through which this might be achieved. - -Locks provide zero-overhead access to their data when accessed through a mutable -reference by using their `get_mut` methods. - -The behaviour of these lock is similar to their namesakes in `std::sync`. they -differ on the following: - -- Locks will not be poisoned in case of failure. -- Threads will not yield to the OS scheduler when encounter a lock that cannot be - accessed. Instead, they will 'spin' in a busy loop until the lock becomes available. - -Many of the feature flags listed above are enabled by default. If you're writing a -library, we recommend disabling those that you don't use to avoid increasing compilation -time for your crate's users. You can do this like so: - -``` -[dependencies] -spin = { version = "x.y", default-features = false, features = [...] } -``` - -## Minimum Safe Rust Version (MSRV) - -This crate is guaranteed to compile on a Minimum Safe Rust Version (MSRV) of 1.38.0 and above. -This version will not be changed without a minor version bump. - -## License - -`spin` is distributed under the MIT License, (See `LICENSE`). diff --git a/third-party/vendor/spin/benches/mutex.rs b/third-party/vendor/spin/benches/mutex.rs deleted file mode 100644 index 83897bb0..00000000 --- a/third-party/vendor/spin/benches/mutex.rs +++ /dev/null @@ -1,126 +0,0 @@ -#[macro_use] -extern crate criterion; - -use criterion::{Criterion, Bencher, black_box}; -use std::{ - ops::DerefMut, - sync::Arc, -}; - -trait Mutex: Send + Sync + 'static { - type Guard<'a>: DerefMut where Self: 'a; - fn new(x: T) -> Self; - fn lock(&self) -> Self::Guard<'_>; -} - -impl Mutex for spin::mutex::SpinMutex { - type Guard<'a> = spin::mutex::SpinMutexGuard<'a, T> where Self: 'a; - fn new(x: T) -> Self { spin::mutex::SpinMutex::new(x) } - fn lock(&self) -> Self::Guard<'_> { self.lock() } -} - -impl Mutex for spin::mutex::TicketMutex { - type Guard<'a> = spin::mutex::TicketMutexGuard<'a, T> where Self: 'a; - fn new(x: T) -> Self { spin::mutex::TicketMutex::new(x) } - fn lock(&self) -> Self::Guard<'_> { self.lock() } -} - -impl Mutex for std::sync::Mutex { - type Guard<'a> = std::sync::MutexGuard<'a, T> where Self: 'a; - fn new(x: T) -> Self { std::sync::Mutex::new(x) } - fn lock(&self) -> Self::Guard<'_> { self.lock().unwrap() } -} - -fn gen_create>(b: &mut Bencher) { - b.iter(|| { - let n = black_box(42); - M::new(n) - }); -} - -fn gen_lock_unlock>(b: &mut Bencher) { - let m = M::new(0); - b.iter(|| { - let mut m = m.lock(); - *m = m.wrapping_add(1); - drop(m); - }); -} - -fn gen_lock_unlock_read_contention>(b: &mut Bencher) { - let m = Arc::new(M::new(0)); - let thread = std::thread::spawn({ - let m = m.clone(); - move || { - while Arc::strong_count(&m) > 1 { - for _ in 0..1000 { - black_box(*m.lock()); - } - } - } - }); - b.iter(|| { - let mut m = m.lock(); - *m = m.wrapping_add(1); - drop(m); - }); - drop(m); - thread.join().unwrap(); -} - -fn gen_lock_unlock_write_contention>(b: &mut Bencher) { - let m = Arc::new(M::new(0)); - let thread = std::thread::spawn({ - let m = m.clone(); - move || { - while Arc::strong_count(&m) > 1 { - for _ in 0..1000 { - let mut m = m.lock(); - *m = m.wrapping_add(1); - drop(m); - } - } - } - }); - b.iter(|| { - let mut m = m.lock(); - *m = m.wrapping_add(1); - drop(m); - }); - drop(m); - thread.join().unwrap(); -} - -fn create(b: &mut Criterion) { - b.bench_function("create-spin-spinmutex", |b| gen_create::>(b)); - b.bench_function("create-spin-ticketmutex", |b| gen_create::>(b)); - b.bench_function("create-std", |b| gen_create::>(b)); -} - -fn lock_unlock(b: &mut Criterion) { - b.bench_function("lock_unlock-spin-spinmutex", |b| gen_lock_unlock::>(b)); - b.bench_function("lock_unlock-spin-ticketmutex", |b| gen_lock_unlock::>(b)); - b.bench_function("lock_unlock-std", |b| gen_lock_unlock::>(b)); -} - -fn lock_unlock_read_contention(b: &mut Criterion) { - b.bench_function("lock_unlock_read_contention-spin-spinmutex", |b| gen_lock_unlock_read_contention::>(b)); - b.bench_function("lock_unlock_read_contention-spin-ticketmutex", |b| gen_lock_unlock_read_contention::>(b)); - b.bench_function("lock_unlock_read_contention-std", |b| gen_lock_unlock_read_contention::>(b)); -} - -fn lock_unlock_write_contention(b: &mut Criterion) { - b.bench_function("lock_unlock_write_contention-spin-spinmutex", |b| gen_lock_unlock_write_contention::>(b)); - b.bench_function("lock_unlock_write_contention-spin-ticketmutex", |b| gen_lock_unlock_write_contention::>(b)); - b.bench_function("lock_unlock_write_contention-std", |b| gen_lock_unlock_write_contention::>(b)); -} - -criterion_group!( - mutex, - create, - lock_unlock, - lock_unlock_read_contention, - lock_unlock_write_contention, -); - -criterion_main!(mutex); diff --git a/third-party/vendor/spin/examples/debug.rs b/third-party/vendor/spin/examples/debug.rs deleted file mode 100644 index 64654f6c..00000000 --- a/third-party/vendor/spin/examples/debug.rs +++ /dev/null @@ -1,21 +0,0 @@ -extern crate spin; - -fn main() { - let mutex = spin::Mutex::new(42); - println!("{:?}", mutex); - { - let x = mutex.lock(); - println!("{:?}, {:?}", mutex, *x); - } - - let rwlock = spin::RwLock::new(42); - println!("{:?}", rwlock); - { - let x = rwlock.read(); - println!("{:?}, {:?}", rwlock, *x); - } - { - let x = rwlock.write(); - println!("{:?}, {:?}", rwlock, *x); - } -} diff --git a/third-party/vendor/spin/script/doc-upload.cfg b/third-party/vendor/spin/script/doc-upload.cfg deleted file mode 100644 index c6dfbdc1..00000000 --- a/third-party/vendor/spin/script/doc-upload.cfg +++ /dev/null @@ -1,3 +0,0 @@ -PROJECT_NAME=spin-rs -DOCS_REPO=mvdnes/rust-docs.git -DOC_RUST_VERSION=stable diff --git a/third-party/vendor/spin/src/barrier.rs b/third-party/vendor/spin/src/barrier.rs deleted file mode 100644 index c3a1c925..00000000 --- a/third-party/vendor/spin/src/barrier.rs +++ /dev/null @@ -1,239 +0,0 @@ -//! Synchronization primitive allowing multiple threads to synchronize the -//! beginning of some computation. -//! -//! Implementation adapted from the 'Barrier' type of the standard library. See: -//! -//! -//! Copyright 2014 The Rust Project Developers. See the COPYRIGHT -//! file at the top-level directory of this distribution and at -//! . -//! -//! Licensed under the Apache License, Version 2.0 > or the MIT license -//! >, at your -//! option. This file may not be copied, modified, or distributed -//! except according to those terms. - -use crate::{mutex::Mutex, RelaxStrategy, Spin}; - -/// A primitive that synchronizes the execution of multiple threads. -/// -/// # Example -/// -/// ``` -/// use spin; -/// use std::sync::Arc; -/// use std::thread; -/// -/// let mut handles = Vec::with_capacity(10); -/// let barrier = Arc::new(spin::Barrier::new(10)); -/// for _ in 0..10 { -/// let c = barrier.clone(); -/// // The same messages will be printed together. -/// // You will NOT see any interleaving. -/// handles.push(thread::spawn(move|| { -/// println!("before wait"); -/// c.wait(); -/// println!("after wait"); -/// })); -/// } -/// // Wait for other threads to finish. -/// for handle in handles { -/// handle.join().unwrap(); -/// } -/// ``` -pub struct Barrier { - lock: Mutex, - num_threads: usize, -} - -// The inner state of a double barrier -struct BarrierState { - count: usize, - generation_id: usize, -} - -/// A `BarrierWaitResult` is returned by [`wait`] when all threads in the [`Barrier`] -/// have rendezvoused. -/// -/// [`wait`]: struct.Barrier.html#method.wait -/// [`Barrier`]: struct.Barrier.html -/// -/// # Examples -/// -/// ``` -/// use spin; -/// -/// let barrier = spin::Barrier::new(1); -/// let barrier_wait_result = barrier.wait(); -/// ``` -pub struct BarrierWaitResult(bool); - -impl Barrier { - /// Blocks the current thread until all threads have rendezvoused here. - /// - /// Barriers are re-usable after all threads have rendezvoused once, and can - /// be used continuously. - /// - /// A single (arbitrary) thread will receive a [`BarrierWaitResult`] that - /// returns `true` from [`is_leader`] when returning from this function, and - /// all other threads will receive a result that will return `false` from - /// [`is_leader`]. - /// - /// [`BarrierWaitResult`]: struct.BarrierWaitResult.html - /// [`is_leader`]: struct.BarrierWaitResult.html#method.is_leader - /// - /// # Examples - /// - /// ``` - /// use spin; - /// use std::sync::Arc; - /// use std::thread; - /// - /// let mut handles = Vec::with_capacity(10); - /// let barrier = Arc::new(spin::Barrier::new(10)); - /// for _ in 0..10 { - /// let c = barrier.clone(); - /// // The same messages will be printed together. - /// // You will NOT see any interleaving. - /// handles.push(thread::spawn(move|| { - /// println!("before wait"); - /// c.wait(); - /// println!("after wait"); - /// })); - /// } - /// // Wait for other threads to finish. - /// for handle in handles { - /// handle.join().unwrap(); - /// } - /// ``` - pub fn wait(&self) -> BarrierWaitResult { - let mut lock = self.lock.lock(); - lock.count += 1; - - if lock.count < self.num_threads { - // not the leader - let local_gen = lock.generation_id; - - while local_gen == lock.generation_id && lock.count < self.num_threads { - drop(lock); - R::relax(); - lock = self.lock.lock(); - } - BarrierWaitResult(false) - } else { - // this thread is the leader, - // and is responsible for incrementing the generation - lock.count = 0; - lock.generation_id = lock.generation_id.wrapping_add(1); - BarrierWaitResult(true) - } - } -} - -impl Barrier { - /// Creates a new barrier that can block a given number of threads. - /// - /// A barrier will block `n`-1 threads which call [`wait`] and then wake up - /// all threads at once when the `n`th thread calls [`wait`]. A Barrier created - /// with n = 0 will behave identically to one created with n = 1. - /// - /// [`wait`]: #method.wait - /// - /// # Examples - /// - /// ``` - /// use spin; - /// - /// let barrier = spin::Barrier::new(10); - /// ``` - pub const fn new(n: usize) -> Self { - Self { - lock: Mutex::new(BarrierState { - count: 0, - generation_id: 0, - }), - num_threads: n, - } - } -} - -impl BarrierWaitResult { - /// Returns whether this thread from [`wait`] is the "leader thread". - /// - /// Only one thread will have `true` returned from their result, all other - /// threads will have `false` returned. - /// - /// [`wait`]: struct.Barrier.html#method.wait - /// - /// # Examples - /// - /// ``` - /// use spin; - /// - /// let barrier = spin::Barrier::new(1); - /// let barrier_wait_result = barrier.wait(); - /// println!("{:?}", barrier_wait_result.is_leader()); - /// ``` - pub fn is_leader(&self) -> bool { - self.0 - } -} - -#[cfg(test)] -mod tests { - use std::prelude::v1::*; - - use std::sync::mpsc::{channel, TryRecvError}; - use std::sync::Arc; - use std::thread; - - type Barrier = super::Barrier; - - fn use_barrier(n: usize, barrier: Arc) { - let (tx, rx) = channel(); - - let mut ts = Vec::new(); - for _ in 0..n - 1 { - let c = barrier.clone(); - let tx = tx.clone(); - ts.push(thread::spawn(move || { - tx.send(c.wait().is_leader()).unwrap(); - })); - } - - // At this point, all spawned threads should be blocked, - // so we shouldn't get anything from the port - assert!(match rx.try_recv() { - Err(TryRecvError::Empty) => true, - _ => false, - }); - - let mut leader_found = barrier.wait().is_leader(); - - // Now, the barrier is cleared and we should get data. - for _ in 0..n - 1 { - if rx.recv().unwrap() { - assert!(!leader_found); - leader_found = true; - } - } - assert!(leader_found); - - for t in ts { - t.join().unwrap(); - } - } - - #[test] - fn test_barrier() { - const N: usize = 10; - - let barrier = Arc::new(Barrier::new(N)); - - use_barrier(N, barrier.clone()); - - // use barrier twice to ensure it is reusable - use_barrier(N, barrier.clone()); - } -} diff --git a/third-party/vendor/spin/src/lazy.rs b/third-party/vendor/spin/src/lazy.rs deleted file mode 100644 index 6e5efe42..00000000 --- a/third-party/vendor/spin/src/lazy.rs +++ /dev/null @@ -1,118 +0,0 @@ -//! Synchronization primitives for lazy evaluation. -//! -//! Implementation adapted from the `SyncLazy` type of the standard library. See: -//! - -use crate::{once::Once, RelaxStrategy, Spin}; -use core::{cell::Cell, fmt, ops::Deref}; - -/// A value which is initialized on the first access. -/// -/// This type is a thread-safe `Lazy`, and can be used in statics. -/// -/// # Examples -/// -/// ``` -/// use std::collections::HashMap; -/// use spin::Lazy; -/// -/// static HASHMAP: Lazy> = Lazy::new(|| { -/// println!("initializing"); -/// let mut m = HashMap::new(); -/// m.insert(13, "Spica".to_string()); -/// m.insert(74, "Hoyten".to_string()); -/// m -/// }); -/// -/// fn main() { -/// println!("ready"); -/// std::thread::spawn(|| { -/// println!("{:?}", HASHMAP.get(&13)); -/// }).join().unwrap(); -/// println!("{:?}", HASHMAP.get(&74)); -/// -/// // Prints: -/// // ready -/// // initializing -/// // Some("Spica") -/// // Some("Hoyten") -/// } -/// ``` -pub struct Lazy T, R = Spin> { - cell: Once, - init: Cell>, -} - -impl fmt::Debug for Lazy { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.debug_struct("Lazy") - .field("cell", &self.cell) - .field("init", &"..") - .finish() - } -} - -// We never create a `&F` from a `&Lazy` so it is fine -// to not impl `Sync` for `F` -// we do create a `&mut Option` in `force`, but this is -// properly synchronized, so it only happens once -// so it also does not contribute to this impl. -unsafe impl Sync for Lazy where Once: Sync {} -// auto-derived `Send` impl is OK. - -impl Lazy { - /// Creates a new lazy value with the given initializing - /// function. - pub const fn new(f: F) -> Self { - Self { - cell: Once::new(), - init: Cell::new(Some(f)), - } - } - /// Retrieves a mutable pointer to the inner data. - /// - /// This is especially useful when interfacing with low level code or FFI where the caller - /// explicitly knows that it has exclusive access to the inner data. Note that reading from - /// this pointer is UB until initialized or directly written to. - pub fn as_mut_ptr(&self) -> *mut T { - self.cell.as_mut_ptr() - } -} - -impl T, R: RelaxStrategy> Lazy { - /// Forces the evaluation of this lazy value and - /// returns a reference to result. This is equivalent - /// to the `Deref` impl, but is explicit. - /// - /// # Examples - /// - /// ``` - /// use spin::Lazy; - /// - /// let lazy = Lazy::new(|| 92); - /// - /// assert_eq!(Lazy::force(&lazy), &92); - /// assert_eq!(&*lazy, &92); - /// ``` - pub fn force(this: &Self) -> &T { - this.cell.call_once(|| match this.init.take() { - Some(f) => f(), - None => panic!("Lazy instance has previously been poisoned"), - }) - } -} - -impl T, R: RelaxStrategy> Deref for Lazy { - type Target = T; - - fn deref(&self) -> &T { - Self::force(self) - } -} - -impl Default for Lazy T, R> { - /// Creates a new lazy value using `Default` as the initializing function. - fn default() -> Self { - Self::new(T::default) - } -} diff --git a/third-party/vendor/spin/src/lib.rs b/third-party/vendor/spin/src/lib.rs deleted file mode 100644 index 50768bc0..00000000 --- a/third-party/vendor/spin/src/lib.rs +++ /dev/null @@ -1,221 +0,0 @@ -#![cfg_attr(all(not(feature = "std"), not(test)), no_std)] -#![cfg_attr(docsrs, feature(doc_cfg))] -#![deny(missing_docs)] - -//! This crate provides [spin-based](https://en.wikipedia.org/wiki/Spinlock) versions of the -//! primitives in `std::sync` and `std::lazy`. Because synchronization is done through spinning, -//! the primitives are suitable for use in `no_std` environments. -//! -//! # Features -//! -//! - `Mutex`, `RwLock`, `Once`/`SyncOnceCell`, and `SyncLazy` equivalents -//! -//! - Support for `no_std` environments -//! -//! - [`lock_api`](https://crates.io/crates/lock_api) compatibility -//! -//! - Upgradeable `RwLock` guards -//! -//! - Guards can be sent and shared between threads -//! -//! - Guard leaking -//! -//! - Ticket locks -//! -//! - Different strategies for dealing with contention -//! -//! # Relationship with `std::sync` -//! -//! While `spin` is not a drop-in replacement for `std::sync` (and -//! [should not be considered as such](https://matklad.github.io/2020/01/02/spinlocks-considered-harmful.html)) -//! an effort is made to keep this crate reasonably consistent with `std::sync`. -//! -//! Many of the types defined in this crate have 'additional capabilities' when compared to `std::sync`: -//! -//! - Because spinning does not depend on the thread-driven model of `std::sync`, guards ([`MutexGuard`], -//! [`RwLockReadGuard`], [`RwLockWriteGuard`], etc.) may be sent and shared between threads. -//! -//! - [`RwLockUpgradableGuard`] supports being upgraded into a [`RwLockWriteGuard`]. -//! -//! - Guards support [leaking](https://doc.rust-lang.org/nomicon/leaking.html). -//! -//! - [`Once`] owns the value returned by its `call_once` initializer. -//! -//! - [`RwLock`] supports counting readers and writers. -//! -//! Conversely, the types in this crate do not have some of the features `std::sync` has: -//! -//! - Locks do not track [panic poisoning](https://doc.rust-lang.org/nomicon/poisoning.html). -//! -//! ## Feature flags -//! -//! The crate comes with a few feature flags that you may wish to use. -//! -//! - `lock_api` enables support for [`lock_api`](https://crates.io/crates/lock_api) -//! -//! - `ticket_mutex` uses a ticket lock for the implementation of `Mutex` -//! -//! - `fair_mutex` enables a fairer implementation of `Mutex` that uses eventual fairness to avoid -//! starvation -//! -//! - `std` enables support for thread yielding instead of spinning - -#[cfg(any(test, feature = "std"))] -extern crate core; - -#[cfg(feature = "portable_atomic")] -extern crate portable_atomic; - -#[cfg(not(feature = "portable_atomic"))] -use core::sync::atomic; -#[cfg(feature = "portable_atomic")] -use portable_atomic as atomic; - -#[cfg(feature = "barrier")] -#[cfg_attr(docsrs, doc(cfg(feature = "barrier")))] -pub mod barrier; -#[cfg(feature = "lazy")] -#[cfg_attr(docsrs, doc(cfg(feature = "lazy")))] -pub mod lazy; -#[cfg(feature = "mutex")] -#[cfg_attr(docsrs, doc(cfg(feature = "mutex")))] -pub mod mutex; -#[cfg(feature = "once")] -#[cfg_attr(docsrs, doc(cfg(feature = "once")))] -pub mod once; -pub mod relax; -#[cfg(feature = "rwlock")] -#[cfg_attr(docsrs, doc(cfg(feature = "rwlock")))] -pub mod rwlock; - -#[cfg(feature = "mutex")] -#[cfg_attr(docsrs, doc(cfg(feature = "mutex")))] -pub use mutex::MutexGuard; -#[cfg(feature = "std")] -#[cfg_attr(docsrs, doc(cfg(feature = "std")))] -pub use relax::Yield; -pub use relax::{RelaxStrategy, Spin}; -#[cfg(feature = "rwlock")] -#[cfg_attr(docsrs, doc(cfg(feature = "rwlock")))] -pub use rwlock::RwLockReadGuard; - -// Avoid confusing inference errors by aliasing away the relax strategy parameter. Users that need to use a different -// relax strategy can do so by accessing the types through their fully-qualified path. This is a little bit horrible -// but sadly adding a default type parameter is *still* a breaking change in Rust (for understandable reasons). - -/// A primitive that synchronizes the execution of multiple threads. See [`barrier::Barrier`] for documentation. -/// -/// A note for advanced users: this alias exists to avoid subtle type inference errors due to the default relax -/// strategy type parameter. If you need a non-default relax strategy, use the fully-qualified path. -#[cfg(feature = "barrier")] -#[cfg_attr(docsrs, doc(cfg(feature = "barrier")))] -pub type Barrier = crate::barrier::Barrier; - -/// A value which is initialized on the first access. See [`lazy::Lazy`] for documentation. -/// -/// A note for advanced users: this alias exists to avoid subtle type inference errors due to the default relax -/// strategy type parameter. If you need a non-default relax strategy, use the fully-qualified path. -#[cfg(feature = "lazy")] -#[cfg_attr(docsrs, doc(cfg(feature = "lazy")))] -pub type Lazy T> = crate::lazy::Lazy; - -/// A primitive that synchronizes the execution of multiple threads. See [`mutex::Mutex`] for documentation. -/// -/// A note for advanced users: this alias exists to avoid subtle type inference errors due to the default relax -/// strategy type parameter. If you need a non-default relax strategy, use the fully-qualified path. -#[cfg(feature = "mutex")] -#[cfg_attr(docsrs, doc(cfg(feature = "mutex")))] -pub type Mutex = crate::mutex::Mutex; - -/// A primitive that provides lazy one-time initialization. See [`once::Once`] for documentation. -/// -/// A note for advanced users: this alias exists to avoid subtle type inference errors due to the default relax -/// strategy type parameter. If you need a non-default relax strategy, use the fully-qualified path. -#[cfg(feature = "once")] -#[cfg_attr(docsrs, doc(cfg(feature = "once")))] -pub type Once = crate::once::Once; - -/// A lock that provides data access to either one writer or many readers. See [`rwlock::RwLock`] for documentation. -/// -/// A note for advanced users: this alias exists to avoid subtle type inference errors due to the default relax -/// strategy type parameter. If you need a non-default relax strategy, use the fully-qualified path. -#[cfg(feature = "rwlock")] -#[cfg_attr(docsrs, doc(cfg(feature = "rwlock")))] -pub type RwLock = crate::rwlock::RwLock; - -/// A guard that provides immutable data access but can be upgraded to [`RwLockWriteGuard`]. See -/// [`rwlock::RwLockUpgradableGuard`] for documentation. -/// -/// A note for advanced users: this alias exists to avoid subtle type inference errors due to the default relax -/// strategy type parameter. If you need a non-default relax strategy, use the fully-qualified path. -#[cfg(feature = "rwlock")] -#[cfg_attr(docsrs, doc(cfg(feature = "rwlock")))] -pub type RwLockUpgradableGuard<'a, T> = crate::rwlock::RwLockUpgradableGuard<'a, T>; - -/// A guard that provides mutable data access. See [`rwlock::RwLockWriteGuard`] for documentation. -/// -/// A note for advanced users: this alias exists to avoid subtle type inference errors due to the default relax -/// strategy type parameter. If you need a non-default relax strategy, use the fully-qualified path. -#[cfg(feature = "rwlock")] -#[cfg_attr(docsrs, doc(cfg(feature = "rwlock")))] -pub type RwLockWriteGuard<'a, T> = crate::rwlock::RwLockWriteGuard<'a, T>; - -/// Spin synchronisation primitives, but compatible with [`lock_api`](https://crates.io/crates/lock_api). -#[cfg(feature = "lock_api")] -#[cfg_attr(docsrs, doc(cfg(feature = "lock_api")))] -pub mod lock_api { - /// A lock that provides mutually exclusive data access (compatible with [`lock_api`](https://crates.io/crates/lock_api)). - #[cfg(feature = "mutex")] - #[cfg_attr(docsrs, doc(cfg(feature = "mutex")))] - pub type Mutex = lock_api_crate::Mutex, T>; - - /// A guard that provides mutable data access (compatible with [`lock_api`](https://crates.io/crates/lock_api)). - #[cfg(feature = "mutex")] - #[cfg_attr(docsrs, doc(cfg(feature = "mutex")))] - pub type MutexGuard<'a, T> = lock_api_crate::MutexGuard<'a, crate::Mutex<()>, T>; - - /// A lock that provides data access to either one writer or many readers (compatible with [`lock_api`](https://crates.io/crates/lock_api)). - #[cfg(feature = "rwlock")] - #[cfg_attr(docsrs, doc(cfg(feature = "rwlock")))] - pub type RwLock = lock_api_crate::RwLock, T>; - - /// A guard that provides immutable data access (compatible with [`lock_api`](https://crates.io/crates/lock_api)). - #[cfg(feature = "rwlock")] - #[cfg_attr(docsrs, doc(cfg(feature = "rwlock")))] - pub type RwLockReadGuard<'a, T> = lock_api_crate::RwLockReadGuard<'a, crate::RwLock<()>, T>; - - /// A guard that provides mutable data access (compatible with [`lock_api`](https://crates.io/crates/lock_api)). - #[cfg(feature = "rwlock")] - #[cfg_attr(docsrs, doc(cfg(feature = "rwlock")))] - pub type RwLockWriteGuard<'a, T> = lock_api_crate::RwLockWriteGuard<'a, crate::RwLock<()>, T>; - - /// A guard that provides immutable data access but can be upgraded to [`RwLockWriteGuard`] (compatible with [`lock_api`](https://crates.io/crates/lock_api)). - #[cfg(feature = "rwlock")] - #[cfg_attr(docsrs, doc(cfg(feature = "rwlock")))] - pub type RwLockUpgradableReadGuard<'a, T> = - lock_api_crate::RwLockUpgradableReadGuard<'a, crate::RwLock<()>, T>; -} - -/// In the event of an invalid operation, it's best to abort the current process. -#[cfg(feature = "fair_mutex")] -fn abort() -> ! { - #[cfg(not(feature = "std"))] - { - // Panicking while panicking is defined by Rust to result in an abort. - struct Panic; - - impl Drop for Panic { - fn drop(&mut self) { - panic!("aborting due to invalid operation"); - } - } - - let _panic = Panic; - panic!("aborting due to invalid operation"); - } - - #[cfg(feature = "std")] - { - std::process::abort(); - } -} diff --git a/third-party/vendor/spin/src/mutex.rs b/third-party/vendor/spin/src/mutex.rs deleted file mode 100644 index e333d8ad..00000000 --- a/third-party/vendor/spin/src/mutex.rs +++ /dev/null @@ -1,340 +0,0 @@ -//! Locks that have the same behaviour as a mutex. -//! -//! The [`Mutex`] in the root of the crate, can be configured using the `ticket_mutex` feature. -//! If it's enabled, [`TicketMutex`] and [`TicketMutexGuard`] will be re-exported as [`Mutex`] -//! and [`MutexGuard`], otherwise the [`SpinMutex`] and guard will be re-exported. -//! -//! `ticket_mutex` is disabled by default. -//! -//! [`Mutex`]: ../struct.Mutex.html -//! [`MutexGuard`]: ../struct.MutexGuard.html -//! [`TicketMutex`]: ./struct.TicketMutex.html -//! [`TicketMutexGuard`]: ./struct.TicketMutexGuard.html -//! [`SpinMutex`]: ./struct.SpinMutex.html -//! [`SpinMutexGuard`]: ./struct.SpinMutexGuard.html - -#[cfg(feature = "spin_mutex")] -#[cfg_attr(docsrs, doc(cfg(feature = "spin_mutex")))] -pub mod spin; -#[cfg(feature = "spin_mutex")] -#[cfg_attr(docsrs, doc(cfg(feature = "spin_mutex")))] -pub use self::spin::{SpinMutex, SpinMutexGuard}; - -#[cfg(feature = "ticket_mutex")] -#[cfg_attr(docsrs, doc(cfg(feature = "ticket_mutex")))] -pub mod ticket; -#[cfg(feature = "ticket_mutex")] -#[cfg_attr(docsrs, doc(cfg(feature = "ticket_mutex")))] -pub use self::ticket::{TicketMutex, TicketMutexGuard}; - -#[cfg(feature = "fair_mutex")] -#[cfg_attr(docsrs, doc(cfg(feature = "fair_mutex")))] -pub mod fair; -#[cfg(feature = "fair_mutex")] -#[cfg_attr(docsrs, doc(cfg(feature = "fair_mutex")))] -pub use self::fair::{FairMutex, FairMutexGuard, Starvation}; - -use crate::{RelaxStrategy, Spin}; -use core::{ - fmt, - ops::{Deref, DerefMut}, -}; - -#[cfg(all(not(feature = "spin_mutex"), not(feature = "use_ticket_mutex")))] -compile_error!("The `mutex` feature flag was used (perhaps through another feature?) without either `spin_mutex` or `use_ticket_mutex`. One of these is required."); - -#[cfg(all(not(feature = "use_ticket_mutex"), feature = "spin_mutex"))] -type InnerMutex = self::spin::SpinMutex; -#[cfg(all(not(feature = "use_ticket_mutex"), feature = "spin_mutex"))] -type InnerMutexGuard<'a, T> = self::spin::SpinMutexGuard<'a, T>; - -#[cfg(feature = "use_ticket_mutex")] -type InnerMutex = self::ticket::TicketMutex; -#[cfg(feature = "use_ticket_mutex")] -type InnerMutexGuard<'a, T> = self::ticket::TicketMutexGuard<'a, T>; - -/// A spin-based lock providing mutually exclusive access to data. -/// -/// The implementation uses either a ticket mutex or a regular spin mutex depending on whether the `spin_mutex` or -/// `ticket_mutex` feature flag is enabled. -/// -/// # Example -/// -/// ``` -/// use spin; -/// -/// let lock = spin::Mutex::new(0); -/// -/// // Modify the data -/// *lock.lock() = 2; -/// -/// // Read the data -/// let answer = *lock.lock(); -/// assert_eq!(answer, 2); -/// ``` -/// -/// # Thread safety example -/// -/// ``` -/// use spin; -/// use std::sync::{Arc, Barrier}; -/// -/// let thread_count = 1000; -/// let spin_mutex = Arc::new(spin::Mutex::new(0)); -/// -/// // We use a barrier to ensure the readout happens after all writing -/// let barrier = Arc::new(Barrier::new(thread_count + 1)); -/// -/// # let mut ts = Vec::new(); -/// for _ in (0..thread_count) { -/// let my_barrier = barrier.clone(); -/// let my_lock = spin_mutex.clone(); -/// # let t = -/// std::thread::spawn(move || { -/// let mut guard = my_lock.lock(); -/// *guard += 1; -/// -/// // Release the lock to prevent a deadlock -/// drop(guard); -/// my_barrier.wait(); -/// }); -/// # ts.push(t); -/// } -/// -/// barrier.wait(); -/// -/// let answer = { *spin_mutex.lock() }; -/// assert_eq!(answer, thread_count); -/// -/// # for t in ts { -/// # t.join().unwrap(); -/// # } -/// ``` -pub struct Mutex { - inner: InnerMutex, -} - -unsafe impl Sync for Mutex {} -unsafe impl Send for Mutex {} - -/// A generic guard that will protect some data access and -/// uses either a ticket lock or a normal spin mutex. -/// -/// For more info see [`TicketMutexGuard`] or [`SpinMutexGuard`]. -/// -/// [`TicketMutexGuard`]: ./struct.TicketMutexGuard.html -/// [`SpinMutexGuard`]: ./struct.SpinMutexGuard.html -pub struct MutexGuard<'a, T: 'a + ?Sized> { - inner: InnerMutexGuard<'a, T>, -} - -impl Mutex { - /// Creates a new [`Mutex`] wrapping the supplied data. - /// - /// # Example - /// - /// ``` - /// use spin::Mutex; - /// - /// static MUTEX: Mutex<()> = Mutex::new(()); - /// - /// fn demo() { - /// let lock = MUTEX.lock(); - /// // do something with lock - /// drop(lock); - /// } - /// ``` - #[inline(always)] - pub const fn new(value: T) -> Self { - Self { - inner: InnerMutex::new(value), - } - } - - /// Consumes this [`Mutex`] and unwraps the underlying data. - /// - /// # Example - /// - /// ``` - /// let lock = spin::Mutex::new(42); - /// assert_eq!(42, lock.into_inner()); - /// ``` - #[inline(always)] - pub fn into_inner(self) -> T { - self.inner.into_inner() - } -} - -impl Mutex { - /// Locks the [`Mutex`] and returns a guard that permits access to the inner data. - /// - /// The returned value may be dereferenced for data access - /// and the lock will be dropped when the guard falls out of scope. - /// - /// ``` - /// let lock = spin::Mutex::new(0); - /// { - /// let mut data = lock.lock(); - /// // The lock is now locked and the data can be accessed - /// *data += 1; - /// // The lock is implicitly dropped at the end of the scope - /// } - /// ``` - #[inline(always)] - pub fn lock(&self) -> MutexGuard { - MutexGuard { - inner: self.inner.lock(), - } - } -} - -impl Mutex { - /// Returns `true` if the lock is currently held. - /// - /// # Safety - /// - /// This function provides no synchronization guarantees and so its result should be considered 'out of date' - /// the instant it is called. Do not use it for synchronization purposes. However, it may be useful as a heuristic. - #[inline(always)] - pub fn is_locked(&self) -> bool { - self.inner.is_locked() - } - - /// Force unlock this [`Mutex`]. - /// - /// # Safety - /// - /// This is *extremely* unsafe if the lock is not held by the current - /// thread. However, this can be useful in some instances for exposing the - /// lock to FFI that doesn't know how to deal with RAII. - #[inline(always)] - pub unsafe fn force_unlock(&self) { - self.inner.force_unlock() - } - - /// Try to lock this [`Mutex`], returning a lock guard if successful. - /// - /// # Example - /// - /// ``` - /// let lock = spin::Mutex::new(42); - /// - /// let maybe_guard = lock.try_lock(); - /// assert!(maybe_guard.is_some()); - /// - /// // `maybe_guard` is still held, so the second call fails - /// let maybe_guard2 = lock.try_lock(); - /// assert!(maybe_guard2.is_none()); - /// ``` - #[inline(always)] - pub fn try_lock(&self) -> Option> { - self.inner - .try_lock() - .map(|guard| MutexGuard { inner: guard }) - } - - /// Returns a mutable reference to the underlying data. - /// - /// Since this call borrows the [`Mutex`] mutably, and a mutable reference is guaranteed to be exclusive in Rust, - /// no actual locking needs to take place -- the mutable borrow statically guarantees no locks exist. As such, - /// this is a 'zero-cost' operation. - /// - /// # Example - /// - /// ``` - /// let mut lock = spin::Mutex::new(0); - /// *lock.get_mut() = 10; - /// assert_eq!(*lock.lock(), 10); - /// ``` - #[inline(always)] - pub fn get_mut(&mut self) -> &mut T { - self.inner.get_mut() - } -} - -impl fmt::Debug for Mutex { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - fmt::Debug::fmt(&self.inner, f) - } -} - -impl Default for Mutex { - fn default() -> Self { - Self::new(Default::default()) - } -} - -impl From for Mutex { - fn from(data: T) -> Self { - Self::new(data) - } -} - -impl<'a, T: ?Sized> MutexGuard<'a, T> { - /// Leak the lock guard, yielding a mutable reference to the underlying data. - /// - /// Note that this function will permanently lock the original [`Mutex`]. - /// - /// ``` - /// let mylock = spin::Mutex::new(0); - /// - /// let data: &mut i32 = spin::MutexGuard::leak(mylock.lock()); - /// - /// *data = 1; - /// assert_eq!(*data, 1); - /// ``` - #[inline(always)] - pub fn leak(this: Self) -> &'a mut T { - InnerMutexGuard::leak(this.inner) - } -} - -impl<'a, T: ?Sized + fmt::Debug> fmt::Debug for MutexGuard<'a, T> { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - fmt::Debug::fmt(&**self, f) - } -} - -impl<'a, T: ?Sized + fmt::Display> fmt::Display for MutexGuard<'a, T> { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - fmt::Display::fmt(&**self, f) - } -} - -impl<'a, T: ?Sized> Deref for MutexGuard<'a, T> { - type Target = T; - fn deref(&self) -> &T { - &*self.inner - } -} - -impl<'a, T: ?Sized> DerefMut for MutexGuard<'a, T> { - fn deref_mut(&mut self) -> &mut T { - &mut *self.inner - } -} - -#[cfg(feature = "lock_api")] -unsafe impl lock_api_crate::RawMutex for Mutex<(), R> { - type GuardMarker = lock_api_crate::GuardSend; - - const INIT: Self = Self::new(()); - - fn lock(&self) { - // Prevent guard destructor running - core::mem::forget(Self::lock(self)); - } - - fn try_lock(&self) -> bool { - // Prevent guard destructor running - Self::try_lock(self).map(core::mem::forget).is_some() - } - - unsafe fn unlock(&self) { - self.force_unlock(); - } - - fn is_locked(&self) -> bool { - self.inner.is_locked() - } -} diff --git a/third-party/vendor/spin/src/mutex/fair.rs b/third-party/vendor/spin/src/mutex/fair.rs deleted file mode 100644 index db07ad6f..00000000 --- a/third-party/vendor/spin/src/mutex/fair.rs +++ /dev/null @@ -1,735 +0,0 @@ -//! A spinning mutex with a fairer unlock algorithm. -//! -//! This mutex is similar to the `SpinMutex` in that it uses spinning to avoid -//! context switches. However, it uses a fairer unlock algorithm that avoids -//! starvation of threads that are waiting for the lock. - -use crate::{ - atomic::{AtomicUsize, Ordering}, - RelaxStrategy, Spin, -}; -use core::{ - cell::UnsafeCell, - fmt, - marker::PhantomData, - mem::ManuallyDrop, - ops::{Deref, DerefMut}, -}; - -// The lowest bit of `lock` is used to indicate whether the mutex is locked or not. The rest of the bits are used to -// store the number of starving threads. -const LOCKED: usize = 1; -const STARVED: usize = 2; - -/// Number chosen by fair roll of the dice, adjust as needed. -const STARVATION_SPINS: usize = 1024; - -/// A [spin lock](https://en.m.wikipedia.org/wiki/Spinlock) providing mutually exclusive access to data, but with a fairer -/// algorithm. -/// -/// # Example -/// -/// ``` -/// use spin; -/// -/// let lock = spin::mutex::FairMutex::<_>::new(0); -/// -/// // Modify the data -/// *lock.lock() = 2; -/// -/// // Read the data -/// let answer = *lock.lock(); -/// assert_eq!(answer, 2); -/// ``` -/// -/// # Thread safety example -/// -/// ``` -/// use spin; -/// use std::sync::{Arc, Barrier}; -/// -/// let thread_count = 1000; -/// let spin_mutex = Arc::new(spin::mutex::FairMutex::<_>::new(0)); -/// -/// // We use a barrier to ensure the readout happens after all writing -/// let barrier = Arc::new(Barrier::new(thread_count + 1)); -/// -/// for _ in (0..thread_count) { -/// let my_barrier = barrier.clone(); -/// let my_lock = spin_mutex.clone(); -/// std::thread::spawn(move || { -/// let mut guard = my_lock.lock(); -/// *guard += 1; -/// -/// // Release the lock to prevent a deadlock -/// drop(guard); -/// my_barrier.wait(); -/// }); -/// } -/// -/// barrier.wait(); -/// -/// let answer = { *spin_mutex.lock() }; -/// assert_eq!(answer, thread_count); -/// ``` -pub struct FairMutex { - phantom: PhantomData, - pub(crate) lock: AtomicUsize, - data: UnsafeCell, -} - -/// A guard that provides mutable data access. -/// -/// When the guard falls out of scope it will release the lock. -pub struct FairMutexGuard<'a, T: ?Sized + 'a> { - lock: &'a AtomicUsize, - data: *mut T, -} - -/// A handle that indicates that we have been trying to acquire the lock for a while. -/// -/// This handle is used to prevent starvation. -pub struct Starvation<'a, T: ?Sized + 'a, R> { - lock: &'a FairMutex, -} - -/// Indicates whether a lock was rejected due to the lock being held by another thread or due to starvation. -#[derive(Debug)] -pub enum LockRejectReason { - /// The lock was rejected due to the lock being held by another thread. - Locked, - - /// The lock was rejected due to starvation. - Starved, -} - -// Same unsafe impls as `std::sync::Mutex` -unsafe impl Sync for FairMutex {} -unsafe impl Send for FairMutex {} - -unsafe impl Sync for FairMutexGuard<'_, T> {} -unsafe impl Send for FairMutexGuard<'_, T> {} - -impl FairMutex { - /// Creates a new [`FairMutex`] wrapping the supplied data. - /// - /// # Example - /// - /// ``` - /// use spin::mutex::FairMutex; - /// - /// static MUTEX: FairMutex<()> = FairMutex::<_>::new(()); - /// - /// fn demo() { - /// let lock = MUTEX.lock(); - /// // do something with lock - /// drop(lock); - /// } - /// ``` - #[inline(always)] - pub const fn new(data: T) -> Self { - FairMutex { - lock: AtomicUsize::new(0), - data: UnsafeCell::new(data), - phantom: PhantomData, - } - } - - /// Consumes this [`FairMutex`] and unwraps the underlying data. - /// - /// # Example - /// - /// ``` - /// let lock = spin::mutex::FairMutex::<_>::new(42); - /// assert_eq!(42, lock.into_inner()); - /// ``` - #[inline(always)] - pub fn into_inner(self) -> T { - // We know statically that there are no outstanding references to - // `self` so there's no need to lock. - let FairMutex { data, .. } = self; - data.into_inner() - } - - /// Returns a mutable pointer to the underlying data. - /// - /// This is mostly meant to be used for applications which require manual unlocking, but where - /// storing both the lock and the pointer to the inner data gets inefficient. - /// - /// # Example - /// ``` - /// let lock = spin::mutex::FairMutex::<_>::new(42); - /// - /// unsafe { - /// core::mem::forget(lock.lock()); - /// - /// assert_eq!(lock.as_mut_ptr().read(), 42); - /// lock.as_mut_ptr().write(58); - /// - /// lock.force_unlock(); - /// } - /// - /// assert_eq!(*lock.lock(), 58); - /// - /// ``` - #[inline(always)] - pub fn as_mut_ptr(&self) -> *mut T { - self.data.get() - } -} - -impl FairMutex { - /// Locks the [`FairMutex`] and returns a guard that permits access to the inner data. - /// - /// The returned value may be dereferenced for data access - /// and the lock will be dropped when the guard falls out of scope. - /// - /// ``` - /// let lock = spin::mutex::FairMutex::<_>::new(0); - /// { - /// let mut data = lock.lock(); - /// // The lock is now locked and the data can be accessed - /// *data += 1; - /// // The lock is implicitly dropped at the end of the scope - /// } - /// ``` - #[inline(always)] - pub fn lock(&self) -> FairMutexGuard { - // Can fail to lock even if the spinlock is not locked. May be more efficient than `try_lock` - // when called in a loop. - let mut spins = 0; - while self - .lock - .compare_exchange_weak(0, 1, Ordering::Acquire, Ordering::Relaxed) - .is_err() - { - // Wait until the lock looks unlocked before retrying - while self.is_locked() { - R::relax(); - - // If we've been spinning for a while, switch to a fairer strategy that will prevent - // newer users from stealing our lock from us. - if spins > STARVATION_SPINS { - return self.starve().lock(); - } - spins += 1; - } - } - - FairMutexGuard { - lock: &self.lock, - data: unsafe { &mut *self.data.get() }, - } - } -} - -impl FairMutex { - /// Returns `true` if the lock is currently held. - /// - /// # Safety - /// - /// This function provides no synchronization guarantees and so its result should be considered 'out of date' - /// the instant it is called. Do not use it for synchronization purposes. However, it may be useful as a heuristic. - #[inline(always)] - pub fn is_locked(&self) -> bool { - self.lock.load(Ordering::Relaxed) & LOCKED != 0 - } - - /// Force unlock this [`FairMutex`]. - /// - /// # Safety - /// - /// This is *extremely* unsafe if the lock is not held by the current - /// thread. However, this can be useful in some instances for exposing the - /// lock to FFI that doesn't know how to deal with RAII. - #[inline(always)] - pub unsafe fn force_unlock(&self) { - self.lock.fetch_and(!LOCKED, Ordering::Release); - } - - /// Try to lock this [`FairMutex`], returning a lock guard if successful. - /// - /// # Example - /// - /// ``` - /// let lock = spin::mutex::FairMutex::<_>::new(42); - /// - /// let maybe_guard = lock.try_lock(); - /// assert!(maybe_guard.is_some()); - /// - /// // `maybe_guard` is still held, so the second call fails - /// let maybe_guard2 = lock.try_lock(); - /// assert!(maybe_guard2.is_none()); - /// ``` - #[inline(always)] - pub fn try_lock(&self) -> Option> { - self.try_lock_starver().ok() - } - - /// Tries to lock this [`FairMutex`] and returns a result that indicates whether the lock was - /// rejected due to a starver or not. - #[inline(always)] - pub fn try_lock_starver(&self) -> Result, LockRejectReason> { - match self - .lock - .compare_exchange(0, LOCKED, Ordering::Acquire, Ordering::Relaxed) - .unwrap_or_else(|x| x) - { - 0 => Ok(FairMutexGuard { - lock: &self.lock, - data: unsafe { &mut *self.data.get() }, - }), - LOCKED => Err(LockRejectReason::Locked), - _ => Err(LockRejectReason::Starved), - } - } - - /// Indicates that the current user has been waiting for the lock for a while - /// and that the lock should yield to this thread over a newly arriving thread. - /// - /// # Example - /// - /// ``` - /// let lock = spin::mutex::FairMutex::<_>::new(42); - /// - /// // Lock the mutex to simulate it being used by another user. - /// let guard1 = lock.lock(); - /// - /// // Try to lock the mutex. - /// let guard2 = lock.try_lock(); - /// assert!(guard2.is_none()); - /// - /// // Wait for a while. - /// wait_for_a_while(); - /// - /// // We are now starved, indicate as such. - /// let starve = lock.starve(); - /// - /// // Once the lock is released, another user trying to lock it will - /// // fail. - /// drop(guard1); - /// let guard3 = lock.try_lock(); - /// assert!(guard3.is_none()); - /// - /// // However, we will be able to lock it. - /// let guard4 = starve.try_lock(); - /// assert!(guard4.is_ok()); - /// - /// # fn wait_for_a_while() {} - /// ``` - pub fn starve(&self) -> Starvation<'_, T, R> { - // Add a new starver to the state. - if self.lock.fetch_add(STARVED, Ordering::Relaxed) > (core::isize::MAX - 1) as usize { - // In the event of a potential lock overflow, abort. - crate::abort(); - } - - Starvation { lock: self } - } - - /// Returns a mutable reference to the underlying data. - /// - /// Since this call borrows the [`FairMutex`] mutably, and a mutable reference is guaranteed to be exclusive in - /// Rust, no actual locking needs to take place -- the mutable borrow statically guarantees no locks exist. As - /// such, this is a 'zero-cost' operation. - /// - /// # Example - /// - /// ``` - /// let mut lock = spin::mutex::FairMutex::<_>::new(0); - /// *lock.get_mut() = 10; - /// assert_eq!(*lock.lock(), 10); - /// ``` - #[inline(always)] - pub fn get_mut(&mut self) -> &mut T { - // We know statically that there are no other references to `self`, so - // there's no need to lock the inner mutex. - unsafe { &mut *self.data.get() } - } -} - -impl fmt::Debug for FairMutex { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - struct LockWrapper<'a, T: ?Sized + fmt::Debug>(Option>); - - impl fmt::Debug for LockWrapper<'_, T> { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - match &self.0 { - Some(guard) => fmt::Debug::fmt(guard, f), - None => f.write_str(""), - } - } - } - - f.debug_struct("FairMutex") - .field("data", &LockWrapper(self.try_lock())) - .finish() - } -} - -impl Default for FairMutex { - fn default() -> Self { - Self::new(Default::default()) - } -} - -impl From for FairMutex { - fn from(data: T) -> Self { - Self::new(data) - } -} - -impl<'a, T: ?Sized> FairMutexGuard<'a, T> { - /// Leak the lock guard, yielding a mutable reference to the underlying data. - /// - /// Note that this function will permanently lock the original [`FairMutex`]. - /// - /// ``` - /// let mylock = spin::mutex::FairMutex::<_>::new(0); - /// - /// let data: &mut i32 = spin::mutex::FairMutexGuard::leak(mylock.lock()); - /// - /// *data = 1; - /// assert_eq!(*data, 1); - /// ``` - #[inline(always)] - pub fn leak(this: Self) -> &'a mut T { - // Use ManuallyDrop to avoid stacked-borrow invalidation - let mut this = ManuallyDrop::new(this); - // We know statically that only we are referencing data - unsafe { &mut *this.data } - } -} - -impl<'a, T: ?Sized + fmt::Debug> fmt::Debug for FairMutexGuard<'a, T> { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - fmt::Debug::fmt(&**self, f) - } -} - -impl<'a, T: ?Sized + fmt::Display> fmt::Display for FairMutexGuard<'a, T> { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - fmt::Display::fmt(&**self, f) - } -} - -impl<'a, T: ?Sized> Deref for FairMutexGuard<'a, T> { - type Target = T; - fn deref(&self) -> &T { - // We know statically that only we are referencing data - unsafe { &*self.data } - } -} - -impl<'a, T: ?Sized> DerefMut for FairMutexGuard<'a, T> { - fn deref_mut(&mut self) -> &mut T { - // We know statically that only we are referencing data - unsafe { &mut *self.data } - } -} - -impl<'a, T: ?Sized> Drop for FairMutexGuard<'a, T> { - /// The dropping of the MutexGuard will release the lock it was created from. - fn drop(&mut self) { - self.lock.fetch_and(!LOCKED, Ordering::Release); - } -} - -impl<'a, T: ?Sized, R> Starvation<'a, T, R> { - /// Attempts the lock the mutex if we are the only starving user. - /// - /// This allows another user to lock the mutex if they are starving as well. - pub fn try_lock_fair(self) -> Result, Self> { - // Try to lock the mutex. - if self - .lock - .lock - .compare_exchange( - STARVED, - STARVED | LOCKED, - Ordering::Acquire, - Ordering::Relaxed, - ) - .is_ok() - { - // We are the only starving user, lock the mutex. - Ok(FairMutexGuard { - lock: &self.lock.lock, - data: self.lock.data.get(), - }) - } else { - // Another user is starving, fail. - Err(self) - } - } - - /// Attempts to lock the mutex. - /// - /// If the lock is currently held by another thread, this will return `None`. - /// - /// # Example - /// - /// ``` - /// let lock = spin::mutex::FairMutex::<_>::new(42); - /// - /// // Lock the mutex to simulate it being used by another user. - /// let guard1 = lock.lock(); - /// - /// // Try to lock the mutex. - /// let guard2 = lock.try_lock(); - /// assert!(guard2.is_none()); - /// - /// // Wait for a while. - /// wait_for_a_while(); - /// - /// // We are now starved, indicate as such. - /// let starve = lock.starve(); - /// - /// // Once the lock is released, another user trying to lock it will - /// // fail. - /// drop(guard1); - /// let guard3 = lock.try_lock(); - /// assert!(guard3.is_none()); - /// - /// // However, we will be able to lock it. - /// let guard4 = starve.try_lock(); - /// assert!(guard4.is_ok()); - /// - /// # fn wait_for_a_while() {} - /// ``` - pub fn try_lock(self) -> Result, Self> { - // Try to lock the mutex. - if self.lock.lock.fetch_or(LOCKED, Ordering::Acquire) & LOCKED == 0 { - // We have successfully locked the mutex. - // By dropping `self` here, we decrement the starvation count. - Ok(FairMutexGuard { - lock: &self.lock.lock, - data: self.lock.data.get(), - }) - } else { - Err(self) - } - } -} - -impl<'a, T: ?Sized, R: RelaxStrategy> Starvation<'a, T, R> { - /// Locks the mutex. - pub fn lock(mut self) -> FairMutexGuard<'a, T> { - // Try to lock the mutex. - loop { - match self.try_lock() { - Ok(lock) => return lock, - Err(starve) => self = starve, - } - - // Relax until the lock is released. - while self.lock.is_locked() { - R::relax(); - } - } - } -} - -impl<'a, T: ?Sized, R> Drop for Starvation<'a, T, R> { - fn drop(&mut self) { - // As there is no longer a user being starved, we decrement the starver count. - self.lock.lock.fetch_sub(STARVED, Ordering::Release); - } -} - -impl fmt::Display for LockRejectReason { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - match self { - LockRejectReason::Locked => write!(f, "locked"), - LockRejectReason::Starved => write!(f, "starved"), - } - } -} - -#[cfg(feature = "std")] -impl std::error::Error for LockRejectReason {} - -#[cfg(feature = "lock_api")] -unsafe impl lock_api_crate::RawMutex for FairMutex<(), R> { - type GuardMarker = lock_api_crate::GuardSend; - - const INIT: Self = Self::new(()); - - fn lock(&self) { - // Prevent guard destructor running - core::mem::forget(Self::lock(self)); - } - - fn try_lock(&self) -> bool { - // Prevent guard destructor running - Self::try_lock(self).map(core::mem::forget).is_some() - } - - unsafe fn unlock(&self) { - self.force_unlock(); - } - - fn is_locked(&self) -> bool { - Self::is_locked(self) - } -} - -#[cfg(test)] -mod tests { - use std::prelude::v1::*; - - use std::sync::atomic::{AtomicUsize, Ordering}; - use std::sync::mpsc::channel; - use std::sync::Arc; - use std::thread; - - type FairMutex = super::FairMutex; - - #[derive(Eq, PartialEq, Debug)] - struct NonCopy(i32); - - #[test] - fn smoke() { - let m = FairMutex::<_>::new(()); - drop(m.lock()); - drop(m.lock()); - } - - #[test] - fn lots_and_lots() { - static M: FairMutex<()> = FairMutex::<_>::new(()); - static mut CNT: u32 = 0; - const J: u32 = 1000; - const K: u32 = 3; - - fn inc() { - for _ in 0..J { - unsafe { - let _g = M.lock(); - CNT += 1; - } - } - } - - let (tx, rx) = channel(); - for _ in 0..K { - let tx2 = tx.clone(); - thread::spawn(move || { - inc(); - tx2.send(()).unwrap(); - }); - let tx2 = tx.clone(); - thread::spawn(move || { - inc(); - tx2.send(()).unwrap(); - }); - } - - drop(tx); - for _ in 0..2 * K { - rx.recv().unwrap(); - } - assert_eq!(unsafe { CNT }, J * K * 2); - } - - #[test] - fn try_lock() { - let mutex = FairMutex::<_>::new(42); - - // First lock succeeds - let a = mutex.try_lock(); - assert_eq!(a.as_ref().map(|r| **r), Some(42)); - - // Additional lock fails - let b = mutex.try_lock(); - assert!(b.is_none()); - - // After dropping lock, it succeeds again - ::core::mem::drop(a); - let c = mutex.try_lock(); - assert_eq!(c.as_ref().map(|r| **r), Some(42)); - } - - #[test] - fn test_into_inner() { - let m = FairMutex::<_>::new(NonCopy(10)); - assert_eq!(m.into_inner(), NonCopy(10)); - } - - #[test] - fn test_into_inner_drop() { - struct Foo(Arc); - impl Drop for Foo { - fn drop(&mut self) { - self.0.fetch_add(1, Ordering::SeqCst); - } - } - let num_drops = Arc::new(AtomicUsize::new(0)); - let m = FairMutex::<_>::new(Foo(num_drops.clone())); - assert_eq!(num_drops.load(Ordering::SeqCst), 0); - { - let _inner = m.into_inner(); - assert_eq!(num_drops.load(Ordering::SeqCst), 0); - } - assert_eq!(num_drops.load(Ordering::SeqCst), 1); - } - - #[test] - fn test_mutex_arc_nested() { - // Tests nested mutexes and access - // to underlying data. - let arc = Arc::new(FairMutex::<_>::new(1)); - let arc2 = Arc::new(FairMutex::<_>::new(arc)); - let (tx, rx) = channel(); - let _t = thread::spawn(move || { - let lock = arc2.lock(); - let lock2 = lock.lock(); - assert_eq!(*lock2, 1); - tx.send(()).unwrap(); - }); - rx.recv().unwrap(); - } - - #[test] - fn test_mutex_arc_access_in_unwind() { - let arc = Arc::new(FairMutex::<_>::new(1)); - let arc2 = arc.clone(); - let _ = thread::spawn(move || -> () { - struct Unwinder { - i: Arc>, - } - impl Drop for Unwinder { - fn drop(&mut self) { - *self.i.lock() += 1; - } - } - let _u = Unwinder { i: arc2 }; - panic!(); - }) - .join(); - let lock = arc.lock(); - assert_eq!(*lock, 2); - } - - #[test] - fn test_mutex_unsized() { - let mutex: &FairMutex<[i32]> = &FairMutex::<_>::new([1, 2, 3]); - { - let b = &mut *mutex.lock(); - b[0] = 4; - b[2] = 5; - } - let comp: &[i32] = &[4, 2, 5]; - assert_eq!(&*mutex.lock(), comp); - } - - #[test] - fn test_mutex_force_lock() { - let lock = FairMutex::<_>::new(()); - ::std::mem::forget(lock.lock()); - unsafe { - lock.force_unlock(); - } - assert!(lock.try_lock().is_some()); - } -} diff --git a/third-party/vendor/spin/src/mutex/spin.rs b/third-party/vendor/spin/src/mutex/spin.rs deleted file mode 100644 index fc974727..00000000 --- a/third-party/vendor/spin/src/mutex/spin.rs +++ /dev/null @@ -1,543 +0,0 @@ -//! A naïve spinning mutex. -//! -//! Waiting threads hammer an atomic variable until it becomes available. Best-case latency is low, but worst-case -//! latency is theoretically infinite. - -use crate::{ - atomic::{AtomicBool, Ordering}, - RelaxStrategy, Spin, -}; -use core::{ - cell::UnsafeCell, - fmt, - marker::PhantomData, - mem::ManuallyDrop, - ops::{Deref, DerefMut}, -}; - -/// A [spin lock](https://en.m.wikipedia.org/wiki/Spinlock) providing mutually exclusive access to data. -/// -/// # Example -/// -/// ``` -/// use spin; -/// -/// let lock = spin::mutex::SpinMutex::<_>::new(0); -/// -/// // Modify the data -/// *lock.lock() = 2; -/// -/// // Read the data -/// let answer = *lock.lock(); -/// assert_eq!(answer, 2); -/// ``` -/// -/// # Thread safety example -/// -/// ``` -/// use spin; -/// use std::sync::{Arc, Barrier}; -/// -/// let thread_count = 1000; -/// let spin_mutex = Arc::new(spin::mutex::SpinMutex::<_>::new(0)); -/// -/// // We use a barrier to ensure the readout happens after all writing -/// let barrier = Arc::new(Barrier::new(thread_count + 1)); -/// -/// # let mut ts = Vec::new(); -/// for _ in (0..thread_count) { -/// let my_barrier = barrier.clone(); -/// let my_lock = spin_mutex.clone(); -/// # let t = -/// std::thread::spawn(move || { -/// let mut guard = my_lock.lock(); -/// *guard += 1; -/// -/// // Release the lock to prevent a deadlock -/// drop(guard); -/// my_barrier.wait(); -/// }); -/// # ts.push(t); -/// } -/// -/// barrier.wait(); -/// -/// let answer = { *spin_mutex.lock() }; -/// assert_eq!(answer, thread_count); -/// -/// # for t in ts { -/// # t.join().unwrap(); -/// # } -/// ``` -pub struct SpinMutex { - phantom: PhantomData, - pub(crate) lock: AtomicBool, - data: UnsafeCell, -} - -/// A guard that provides mutable data access. -/// -/// When the guard falls out of scope it will release the lock. -pub struct SpinMutexGuard<'a, T: ?Sized + 'a> { - lock: &'a AtomicBool, - data: *mut T, -} - -// Same unsafe impls as `std::sync::Mutex` -unsafe impl Sync for SpinMutex {} -unsafe impl Send for SpinMutex {} - -unsafe impl Sync for SpinMutexGuard<'_, T> {} -unsafe impl Send for SpinMutexGuard<'_, T> {} - -impl SpinMutex { - /// Creates a new [`SpinMutex`] wrapping the supplied data. - /// - /// # Example - /// - /// ``` - /// use spin::mutex::SpinMutex; - /// - /// static MUTEX: SpinMutex<()> = SpinMutex::<_>::new(()); - /// - /// fn demo() { - /// let lock = MUTEX.lock(); - /// // do something with lock - /// drop(lock); - /// } - /// ``` - #[inline(always)] - pub const fn new(data: T) -> Self { - SpinMutex { - lock: AtomicBool::new(false), - data: UnsafeCell::new(data), - phantom: PhantomData, - } - } - - /// Consumes this [`SpinMutex`] and unwraps the underlying data. - /// - /// # Example - /// - /// ``` - /// let lock = spin::mutex::SpinMutex::<_>::new(42); - /// assert_eq!(42, lock.into_inner()); - /// ``` - #[inline(always)] - pub fn into_inner(self) -> T { - // We know statically that there are no outstanding references to - // `self` so there's no need to lock. - let SpinMutex { data, .. } = self; - data.into_inner() - } - - /// Returns a mutable pointer to the underlying data. - /// - /// This is mostly meant to be used for applications which require manual unlocking, but where - /// storing both the lock and the pointer to the inner data gets inefficient. - /// - /// # Example - /// ``` - /// let lock = spin::mutex::SpinMutex::<_>::new(42); - /// - /// unsafe { - /// core::mem::forget(lock.lock()); - /// - /// assert_eq!(lock.as_mut_ptr().read(), 42); - /// lock.as_mut_ptr().write(58); - /// - /// lock.force_unlock(); - /// } - /// - /// assert_eq!(*lock.lock(), 58); - /// - /// ``` - #[inline(always)] - pub fn as_mut_ptr(&self) -> *mut T { - self.data.get() - } -} - -impl SpinMutex { - /// Locks the [`SpinMutex`] and returns a guard that permits access to the inner data. - /// - /// The returned value may be dereferenced for data access - /// and the lock will be dropped when the guard falls out of scope. - /// - /// ``` - /// let lock = spin::mutex::SpinMutex::<_>::new(0); - /// { - /// let mut data = lock.lock(); - /// // The lock is now locked and the data can be accessed - /// *data += 1; - /// // The lock is implicitly dropped at the end of the scope - /// } - /// ``` - #[inline(always)] - pub fn lock(&self) -> SpinMutexGuard { - // Can fail to lock even if the spinlock is not locked. May be more efficient than `try_lock` - // when called in a loop. - while self - .lock - .compare_exchange_weak(false, true, Ordering::Acquire, Ordering::Relaxed) - .is_err() - { - // Wait until the lock looks unlocked before retrying - while self.is_locked() { - R::relax(); - } - } - - SpinMutexGuard { - lock: &self.lock, - data: unsafe { &mut *self.data.get() }, - } - } -} - -impl SpinMutex { - /// Returns `true` if the lock is currently held. - /// - /// # Safety - /// - /// This function provides no synchronization guarantees and so its result should be considered 'out of date' - /// the instant it is called. Do not use it for synchronization purposes. However, it may be useful as a heuristic. - #[inline(always)] - pub fn is_locked(&self) -> bool { - self.lock.load(Ordering::Relaxed) - } - - /// Force unlock this [`SpinMutex`]. - /// - /// # Safety - /// - /// This is *extremely* unsafe if the lock is not held by the current - /// thread. However, this can be useful in some instances for exposing the - /// lock to FFI that doesn't know how to deal with RAII. - #[inline(always)] - pub unsafe fn force_unlock(&self) { - self.lock.store(false, Ordering::Release); - } - - /// Try to lock this [`SpinMutex`], returning a lock guard if successful. - /// - /// # Example - /// - /// ``` - /// let lock = spin::mutex::SpinMutex::<_>::new(42); - /// - /// let maybe_guard = lock.try_lock(); - /// assert!(maybe_guard.is_some()); - /// - /// // `maybe_guard` is still held, so the second call fails - /// let maybe_guard2 = lock.try_lock(); - /// assert!(maybe_guard2.is_none()); - /// ``` - #[inline(always)] - pub fn try_lock(&self) -> Option> { - // The reason for using a strong compare_exchange is explained here: - // https://github.com/Amanieu/parking_lot/pull/207#issuecomment-575869107 - if self - .lock - .compare_exchange(false, true, Ordering::Acquire, Ordering::Relaxed) - .is_ok() - { - Some(SpinMutexGuard { - lock: &self.lock, - data: unsafe { &mut *self.data.get() }, - }) - } else { - None - } - } - - /// Returns a mutable reference to the underlying data. - /// - /// Since this call borrows the [`SpinMutex`] mutably, and a mutable reference is guaranteed to be exclusive in - /// Rust, no actual locking needs to take place -- the mutable borrow statically guarantees no locks exist. As - /// such, this is a 'zero-cost' operation. - /// - /// # Example - /// - /// ``` - /// let mut lock = spin::mutex::SpinMutex::<_>::new(0); - /// *lock.get_mut() = 10; - /// assert_eq!(*lock.lock(), 10); - /// ``` - #[inline(always)] - pub fn get_mut(&mut self) -> &mut T { - // We know statically that there are no other references to `self`, so - // there's no need to lock the inner mutex. - unsafe { &mut *self.data.get() } - } -} - -impl fmt::Debug for SpinMutex { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - match self.try_lock() { - Some(guard) => write!(f, "Mutex {{ data: ") - .and_then(|()| (&*guard).fmt(f)) - .and_then(|()| write!(f, "}}")), - None => write!(f, "Mutex {{ }}"), - } - } -} - -impl Default for SpinMutex { - fn default() -> Self { - Self::new(Default::default()) - } -} - -impl From for SpinMutex { - fn from(data: T) -> Self { - Self::new(data) - } -} - -impl<'a, T: ?Sized> SpinMutexGuard<'a, T> { - /// Leak the lock guard, yielding a mutable reference to the underlying data. - /// - /// Note that this function will permanently lock the original [`SpinMutex`]. - /// - /// ``` - /// let mylock = spin::mutex::SpinMutex::<_>::new(0); - /// - /// let data: &mut i32 = spin::mutex::SpinMutexGuard::leak(mylock.lock()); - /// - /// *data = 1; - /// assert_eq!(*data, 1); - /// ``` - #[inline(always)] - pub fn leak(this: Self) -> &'a mut T { - // Use ManuallyDrop to avoid stacked-borrow invalidation - let mut this = ManuallyDrop::new(this); - // We know statically that only we are referencing data - unsafe { &mut *this.data } - } -} - -impl<'a, T: ?Sized + fmt::Debug> fmt::Debug for SpinMutexGuard<'a, T> { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - fmt::Debug::fmt(&**self, f) - } -} - -impl<'a, T: ?Sized + fmt::Display> fmt::Display for SpinMutexGuard<'a, T> { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - fmt::Display::fmt(&**self, f) - } -} - -impl<'a, T: ?Sized> Deref for SpinMutexGuard<'a, T> { - type Target = T; - fn deref(&self) -> &T { - // We know statically that only we are referencing data - unsafe { &*self.data } - } -} - -impl<'a, T: ?Sized> DerefMut for SpinMutexGuard<'a, T> { - fn deref_mut(&mut self) -> &mut T { - // We know statically that only we are referencing data - unsafe { &mut *self.data } - } -} - -impl<'a, T: ?Sized> Drop for SpinMutexGuard<'a, T> { - /// The dropping of the MutexGuard will release the lock it was created from. - fn drop(&mut self) { - self.lock.store(false, Ordering::Release); - } -} - -#[cfg(feature = "lock_api")] -unsafe impl lock_api_crate::RawMutex for SpinMutex<(), R> { - type GuardMarker = lock_api_crate::GuardSend; - - const INIT: Self = Self::new(()); - - fn lock(&self) { - // Prevent guard destructor running - core::mem::forget(Self::lock(self)); - } - - fn try_lock(&self) -> bool { - // Prevent guard destructor running - Self::try_lock(self).map(core::mem::forget).is_some() - } - - unsafe fn unlock(&self) { - self.force_unlock(); - } - - fn is_locked(&self) -> bool { - Self::is_locked(self) - } -} - -#[cfg(test)] -mod tests { - use std::prelude::v1::*; - - use std::sync::atomic::{AtomicUsize, Ordering}; - use std::sync::mpsc::channel; - use std::sync::Arc; - use std::thread; - - type SpinMutex = super::SpinMutex; - - #[derive(Eq, PartialEq, Debug)] - struct NonCopy(i32); - - #[test] - fn smoke() { - let m = SpinMutex::<_>::new(()); - drop(m.lock()); - drop(m.lock()); - } - - #[test] - fn lots_and_lots() { - static M: SpinMutex<()> = SpinMutex::<_>::new(()); - static mut CNT: u32 = 0; - const J: u32 = 1000; - const K: u32 = 3; - - fn inc() { - for _ in 0..J { - unsafe { - let _g = M.lock(); - CNT += 1; - } - } - } - - let (tx, rx) = channel(); - let mut ts = Vec::new(); - for _ in 0..K { - let tx2 = tx.clone(); - ts.push(thread::spawn(move || { - inc(); - tx2.send(()).unwrap(); - })); - let tx2 = tx.clone(); - ts.push(thread::spawn(move || { - inc(); - tx2.send(()).unwrap(); - })); - } - - drop(tx); - for _ in 0..2 * K { - rx.recv().unwrap(); - } - assert_eq!(unsafe { CNT }, J * K * 2); - - for t in ts { - t.join().unwrap(); - } - } - - #[test] - fn try_lock() { - let mutex = SpinMutex::<_>::new(42); - - // First lock succeeds - let a = mutex.try_lock(); - assert_eq!(a.as_ref().map(|r| **r), Some(42)); - - // Additional lock fails - let b = mutex.try_lock(); - assert!(b.is_none()); - - // After dropping lock, it succeeds again - ::core::mem::drop(a); - let c = mutex.try_lock(); - assert_eq!(c.as_ref().map(|r| **r), Some(42)); - } - - #[test] - fn test_into_inner() { - let m = SpinMutex::<_>::new(NonCopy(10)); - assert_eq!(m.into_inner(), NonCopy(10)); - } - - #[test] - fn test_into_inner_drop() { - struct Foo(Arc); - impl Drop for Foo { - fn drop(&mut self) { - self.0.fetch_add(1, Ordering::SeqCst); - } - } - let num_drops = Arc::new(AtomicUsize::new(0)); - let m = SpinMutex::<_>::new(Foo(num_drops.clone())); - assert_eq!(num_drops.load(Ordering::SeqCst), 0); - { - let _inner = m.into_inner(); - assert_eq!(num_drops.load(Ordering::SeqCst), 0); - } - assert_eq!(num_drops.load(Ordering::SeqCst), 1); - } - - #[test] - fn test_mutex_arc_nested() { - // Tests nested mutexes and access - // to underlying data. - let arc = Arc::new(SpinMutex::<_>::new(1)); - let arc2 = Arc::new(SpinMutex::<_>::new(arc)); - let (tx, rx) = channel(); - let t = thread::spawn(move || { - let lock = arc2.lock(); - let lock2 = lock.lock(); - assert_eq!(*lock2, 1); - tx.send(()).unwrap(); - }); - rx.recv().unwrap(); - t.join().unwrap(); - } - - #[test] - fn test_mutex_arc_access_in_unwind() { - let arc = Arc::new(SpinMutex::<_>::new(1)); - let arc2 = arc.clone(); - let _ = thread::spawn(move || -> () { - struct Unwinder { - i: Arc>, - } - impl Drop for Unwinder { - fn drop(&mut self) { - *self.i.lock() += 1; - } - } - let _u = Unwinder { i: arc2 }; - panic!(); - }) - .join(); - let lock = arc.lock(); - assert_eq!(*lock, 2); - } - - #[test] - fn test_mutex_unsized() { - let mutex: &SpinMutex<[i32]> = &SpinMutex::<_>::new([1, 2, 3]); - { - let b = &mut *mutex.lock(); - b[0] = 4; - b[2] = 5; - } - let comp: &[i32] = &[4, 2, 5]; - assert_eq!(&*mutex.lock(), comp); - } - - #[test] - fn test_mutex_force_lock() { - let lock = SpinMutex::<_>::new(()); - ::std::mem::forget(lock.lock()); - unsafe { - lock.force_unlock(); - } - assert!(lock.try_lock().is_some()); - } -} diff --git a/third-party/vendor/spin/src/mutex/ticket.rs b/third-party/vendor/spin/src/mutex/ticket.rs deleted file mode 100644 index c14869ef..00000000 --- a/third-party/vendor/spin/src/mutex/ticket.rs +++ /dev/null @@ -1,537 +0,0 @@ -//! A ticket-based mutex. -//! -//! Waiting threads take a 'ticket' from the lock in the order they arrive and gain access to the lock when their -//! ticket is next in the queue. Best-case latency is slightly worse than a regular spinning mutex, but worse-case -//! latency is infinitely better. Waiting threads simply need to wait for all threads that come before them in the -//! queue to finish. - -use crate::{ - atomic::{AtomicUsize, Ordering}, - RelaxStrategy, Spin, -}; -use core::{ - cell::UnsafeCell, - fmt, - marker::PhantomData, - ops::{Deref, DerefMut}, -}; - -/// A spin-based [ticket lock](https://en.wikipedia.org/wiki/Ticket_lock) providing mutually exclusive access to data. -/// -/// A ticket lock is analogous to a queue management system for lock requests. When a thread tries to take a lock, it -/// is assigned a 'ticket'. It then spins until its ticket becomes next in line. When the lock guard is released, the -/// next ticket will be processed. -/// -/// Ticket locks significantly reduce the worse-case performance of locking at the cost of slightly higher average-time -/// overhead. -/// -/// # Example -/// -/// ``` -/// use spin; -/// -/// let lock = spin::mutex::TicketMutex::<_>::new(0); -/// -/// // Modify the data -/// *lock.lock() = 2; -/// -/// // Read the data -/// let answer = *lock.lock(); -/// assert_eq!(answer, 2); -/// ``` -/// -/// # Thread safety example -/// -/// ``` -/// use spin; -/// use std::sync::{Arc, Barrier}; -/// -/// let thread_count = 1000; -/// let spin_mutex = Arc::new(spin::mutex::TicketMutex::<_>::new(0)); -/// -/// // We use a barrier to ensure the readout happens after all writing -/// let barrier = Arc::new(Barrier::new(thread_count + 1)); -/// -/// for _ in (0..thread_count) { -/// let my_barrier = barrier.clone(); -/// let my_lock = spin_mutex.clone(); -/// std::thread::spawn(move || { -/// let mut guard = my_lock.lock(); -/// *guard += 1; -/// -/// // Release the lock to prevent a deadlock -/// drop(guard); -/// my_barrier.wait(); -/// }); -/// } -/// -/// barrier.wait(); -/// -/// let answer = { *spin_mutex.lock() }; -/// assert_eq!(answer, thread_count); -/// ``` -pub struct TicketMutex { - phantom: PhantomData, - next_ticket: AtomicUsize, - next_serving: AtomicUsize, - data: UnsafeCell, -} - -/// A guard that protects some data. -/// -/// When the guard is dropped, the next ticket will be processed. -pub struct TicketMutexGuard<'a, T: ?Sized + 'a> { - next_serving: &'a AtomicUsize, - ticket: usize, - data: &'a mut T, -} - -unsafe impl Sync for TicketMutex {} -unsafe impl Send for TicketMutex {} - -impl TicketMutex { - /// Creates a new [`TicketMutex`] wrapping the supplied data. - /// - /// # Example - /// - /// ``` - /// use spin::mutex::TicketMutex; - /// - /// static MUTEX: TicketMutex<()> = TicketMutex::<_>::new(()); - /// - /// fn demo() { - /// let lock = MUTEX.lock(); - /// // do something with lock - /// drop(lock); - /// } - /// ``` - #[inline(always)] - pub const fn new(data: T) -> Self { - Self { - phantom: PhantomData, - next_ticket: AtomicUsize::new(0), - next_serving: AtomicUsize::new(0), - data: UnsafeCell::new(data), - } - } - - /// Consumes this [`TicketMutex`] and unwraps the underlying data. - /// - /// # Example - /// - /// ``` - /// let lock = spin::mutex::TicketMutex::<_>::new(42); - /// assert_eq!(42, lock.into_inner()); - /// ``` - #[inline(always)] - pub fn into_inner(self) -> T { - self.data.into_inner() - } - /// Returns a mutable pointer to the underying data. - /// - /// This is mostly meant to be used for applications which require manual unlocking, but where - /// storing both the lock and the pointer to the inner data gets inefficient. - /// - /// # Example - /// ``` - /// let lock = spin::mutex::SpinMutex::<_>::new(42); - /// - /// unsafe { - /// core::mem::forget(lock.lock()); - /// - /// assert_eq!(lock.as_mut_ptr().read(), 42); - /// lock.as_mut_ptr().write(58); - /// - /// lock.force_unlock(); - /// } - /// - /// assert_eq!(*lock.lock(), 58); - /// - /// ``` - #[inline(always)] - pub fn as_mut_ptr(&self) -> *mut T { - self.data.get() - } -} - -impl fmt::Debug for TicketMutex { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - match self.try_lock() { - Some(guard) => write!(f, "Mutex {{ data: ") - .and_then(|()| (&*guard).fmt(f)) - .and_then(|()| write!(f, "}}")), - None => write!(f, "Mutex {{ }}"), - } - } -} - -impl TicketMutex { - /// Locks the [`TicketMutex`] and returns a guard that permits access to the inner data. - /// - /// The returned data may be dereferenced for data access - /// and the lock will be dropped when the guard falls out of scope. - /// - /// ``` - /// let lock = spin::mutex::TicketMutex::<_>::new(0); - /// { - /// let mut data = lock.lock(); - /// // The lock is now locked and the data can be accessed - /// *data += 1; - /// // The lock is implicitly dropped at the end of the scope - /// } - /// ``` - #[inline(always)] - pub fn lock(&self) -> TicketMutexGuard { - let ticket = self.next_ticket.fetch_add(1, Ordering::Relaxed); - - while self.next_serving.load(Ordering::Acquire) != ticket { - R::relax(); - } - - TicketMutexGuard { - next_serving: &self.next_serving, - ticket, - // Safety - // We know that we are the next ticket to be served, - // so there's no other thread accessing the data. - // - // Every other thread has another ticket number so it's - // definitely stuck in the spin loop above. - data: unsafe { &mut *self.data.get() }, - } - } -} - -impl TicketMutex { - /// Returns `true` if the lock is currently held. - /// - /// # Safety - /// - /// This function provides no synchronization guarantees and so its result should be considered 'out of date' - /// the instant it is called. Do not use it for synchronization purposes. However, it may be useful as a heuristic. - #[inline(always)] - pub fn is_locked(&self) -> bool { - let ticket = self.next_ticket.load(Ordering::Relaxed); - self.next_serving.load(Ordering::Relaxed) != ticket - } - - /// Force unlock this [`TicketMutex`], by serving the next ticket. - /// - /// # Safety - /// - /// This is *extremely* unsafe if the lock is not held by the current - /// thread. However, this can be useful in some instances for exposing the - /// lock to FFI that doesn't know how to deal with RAII. - #[inline(always)] - pub unsafe fn force_unlock(&self) { - self.next_serving.fetch_add(1, Ordering::Release); - } - - /// Try to lock this [`TicketMutex`], returning a lock guard if successful. - /// - /// # Example - /// - /// ``` - /// let lock = spin::mutex::TicketMutex::<_>::new(42); - /// - /// let maybe_guard = lock.try_lock(); - /// assert!(maybe_guard.is_some()); - /// - /// // `maybe_guard` is still held, so the second call fails - /// let maybe_guard2 = lock.try_lock(); - /// assert!(maybe_guard2.is_none()); - /// ``` - #[inline(always)] - pub fn try_lock(&self) -> Option> { - let ticket = self - .next_ticket - .fetch_update(Ordering::SeqCst, Ordering::SeqCst, |ticket| { - if self.next_serving.load(Ordering::Acquire) == ticket { - Some(ticket + 1) - } else { - None - } - }); - - ticket.ok().map(|ticket| TicketMutexGuard { - next_serving: &self.next_serving, - ticket, - // Safety - // We have a ticket that is equal to the next_serving ticket, so we know: - // - that no other thread can have the same ticket id as this thread - // - that we are the next one to be served so we have exclusive access to the data - data: unsafe { &mut *self.data.get() }, - }) - } - - /// Returns a mutable reference to the underlying data. - /// - /// Since this call borrows the [`TicketMutex`] mutably, and a mutable reference is guaranteed to be exclusive in - /// Rust, no actual locking needs to take place -- the mutable borrow statically guarantees no locks exist. As - /// such, this is a 'zero-cost' operation. - /// - /// # Example - /// - /// ``` - /// let mut lock = spin::mutex::TicketMutex::<_>::new(0); - /// *lock.get_mut() = 10; - /// assert_eq!(*lock.lock(), 10); - /// ``` - #[inline(always)] - pub fn get_mut(&mut self) -> &mut T { - // Safety: - // We know that there are no other references to `self`, - // so it's safe to return a exclusive reference to the data. - unsafe { &mut *self.data.get() } - } -} - -impl Default for TicketMutex { - fn default() -> Self { - Self::new(Default::default()) - } -} - -impl From for TicketMutex { - fn from(data: T) -> Self { - Self::new(data) - } -} - -impl<'a, T: ?Sized> TicketMutexGuard<'a, T> { - /// Leak the lock guard, yielding a mutable reference to the underlying data. - /// - /// Note that this function will permanently lock the original [`TicketMutex`]. - /// - /// ``` - /// let mylock = spin::mutex::TicketMutex::<_>::new(0); - /// - /// let data: &mut i32 = spin::mutex::TicketMutexGuard::leak(mylock.lock()); - /// - /// *data = 1; - /// assert_eq!(*data, 1); - /// ``` - #[inline(always)] - pub fn leak(this: Self) -> &'a mut T { - let data = this.data as *mut _; // Keep it in pointer form temporarily to avoid double-aliasing - core::mem::forget(this); - unsafe { &mut *data } - } -} - -impl<'a, T: ?Sized + fmt::Debug> fmt::Debug for TicketMutexGuard<'a, T> { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - fmt::Debug::fmt(&**self, f) - } -} - -impl<'a, T: ?Sized + fmt::Display> fmt::Display for TicketMutexGuard<'a, T> { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - fmt::Display::fmt(&**self, f) - } -} - -impl<'a, T: ?Sized> Deref for TicketMutexGuard<'a, T> { - type Target = T; - fn deref(&self) -> &T { - self.data - } -} - -impl<'a, T: ?Sized> DerefMut for TicketMutexGuard<'a, T> { - fn deref_mut(&mut self) -> &mut T { - self.data - } -} - -impl<'a, T: ?Sized> Drop for TicketMutexGuard<'a, T> { - fn drop(&mut self) { - let new_ticket = self.ticket + 1; - self.next_serving.store(new_ticket, Ordering::Release); - } -} - -#[cfg(feature = "lock_api")] -unsafe impl lock_api_crate::RawMutex for TicketMutex<(), R> { - type GuardMarker = lock_api_crate::GuardSend; - - const INIT: Self = Self::new(()); - - fn lock(&self) { - // Prevent guard destructor running - core::mem::forget(Self::lock(self)); - } - - fn try_lock(&self) -> bool { - // Prevent guard destructor running - Self::try_lock(self).map(core::mem::forget).is_some() - } - - unsafe fn unlock(&self) { - self.force_unlock(); - } - - fn is_locked(&self) -> bool { - Self::is_locked(self) - } -} - -#[cfg(test)] -mod tests { - use std::prelude::v1::*; - - use std::sync::atomic::{AtomicUsize, Ordering}; - use std::sync::mpsc::channel; - use std::sync::Arc; - use std::thread; - - type TicketMutex = super::TicketMutex; - - #[derive(Eq, PartialEq, Debug)] - struct NonCopy(i32); - - #[test] - fn smoke() { - let m = TicketMutex::<_>::new(()); - drop(m.lock()); - drop(m.lock()); - } - - #[test] - fn lots_and_lots() { - static M: TicketMutex<()> = TicketMutex::<_>::new(()); - static mut CNT: u32 = 0; - const J: u32 = 1000; - const K: u32 = 3; - - fn inc() { - for _ in 0..J { - unsafe { - let _g = M.lock(); - CNT += 1; - } - } - } - - let (tx, rx) = channel(); - for _ in 0..K { - let tx2 = tx.clone(); - thread::spawn(move || { - inc(); - tx2.send(()).unwrap(); - }); - let tx2 = tx.clone(); - thread::spawn(move || { - inc(); - tx2.send(()).unwrap(); - }); - } - - drop(tx); - for _ in 0..2 * K { - rx.recv().unwrap(); - } - assert_eq!(unsafe { CNT }, J * K * 2); - } - - #[test] - fn try_lock() { - let mutex = TicketMutex::<_>::new(42); - - // First lock succeeds - let a = mutex.try_lock(); - assert_eq!(a.as_ref().map(|r| **r), Some(42)); - - // Additional lock fails - let b = mutex.try_lock(); - assert!(b.is_none()); - - // After dropping lock, it succeeds again - ::core::mem::drop(a); - let c = mutex.try_lock(); - assert_eq!(c.as_ref().map(|r| **r), Some(42)); - } - - #[test] - fn test_into_inner() { - let m = TicketMutex::<_>::new(NonCopy(10)); - assert_eq!(m.into_inner(), NonCopy(10)); - } - - #[test] - fn test_into_inner_drop() { - struct Foo(Arc); - impl Drop for Foo { - fn drop(&mut self) { - self.0.fetch_add(1, Ordering::SeqCst); - } - } - let num_drops = Arc::new(AtomicUsize::new(0)); - let m = TicketMutex::<_>::new(Foo(num_drops.clone())); - assert_eq!(num_drops.load(Ordering::SeqCst), 0); - { - let _inner = m.into_inner(); - assert_eq!(num_drops.load(Ordering::SeqCst), 0); - } - assert_eq!(num_drops.load(Ordering::SeqCst), 1); - } - - #[test] - fn test_mutex_arc_nested() { - // Tests nested mutexes and access - // to underlying data. - let arc = Arc::new(TicketMutex::<_>::new(1)); - let arc2 = Arc::new(TicketMutex::<_>::new(arc)); - let (tx, rx) = channel(); - let _t = thread::spawn(move || { - let lock = arc2.lock(); - let lock2 = lock.lock(); - assert_eq!(*lock2, 1); - tx.send(()).unwrap(); - }); - rx.recv().unwrap(); - } - - #[test] - fn test_mutex_arc_access_in_unwind() { - let arc = Arc::new(TicketMutex::<_>::new(1)); - let arc2 = arc.clone(); - let _ = thread::spawn(move || -> () { - struct Unwinder { - i: Arc>, - } - impl Drop for Unwinder { - fn drop(&mut self) { - *self.i.lock() += 1; - } - } - let _u = Unwinder { i: arc2 }; - panic!(); - }) - .join(); - let lock = arc.lock(); - assert_eq!(*lock, 2); - } - - #[test] - fn test_mutex_unsized() { - let mutex: &TicketMutex<[i32]> = &TicketMutex::<_>::new([1, 2, 3]); - { - let b = &mut *mutex.lock(); - b[0] = 4; - b[2] = 5; - } - let comp: &[i32] = &[4, 2, 5]; - assert_eq!(&*mutex.lock(), comp); - } - - #[test] - fn is_locked() { - let mutex = TicketMutex::<_>::new(()); - assert!(!mutex.is_locked()); - let lock = mutex.lock(); - assert!(mutex.is_locked()); - drop(lock); - assert!(!mutex.is_locked()); - } -} diff --git a/third-party/vendor/spin/src/once.rs b/third-party/vendor/spin/src/once.rs deleted file mode 100644 index 31700dce..00000000 --- a/third-party/vendor/spin/src/once.rs +++ /dev/null @@ -1,789 +0,0 @@ -//! Synchronization primitives for one-time evaluation. - -use crate::{ - atomic::{AtomicU8, Ordering}, - RelaxStrategy, Spin, -}; -use core::{cell::UnsafeCell, fmt, marker::PhantomData, mem::MaybeUninit}; - -/// A primitive that provides lazy one-time initialization. -/// -/// Unlike its `std::sync` equivalent, this is generalized such that the closure returns a -/// value to be stored by the [`Once`] (`std::sync::Once` can be trivially emulated with -/// `Once`). -/// -/// Because [`Once::new`] is `const`, this primitive may be used to safely initialize statics. -/// -/// # Examples -/// -/// ``` -/// use spin; -/// -/// static START: spin::Once = spin::Once::new(); -/// -/// START.call_once(|| { -/// // run initialization here -/// }); -/// ``` -pub struct Once { - phantom: PhantomData, - status: AtomicStatus, - data: UnsafeCell>, -} - -impl Default for Once { - fn default() -> Self { - Self::new() - } -} - -impl fmt::Debug for Once { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - match self.get() { - Some(s) => write!(f, "Once {{ data: ") - .and_then(|()| s.fmt(f)) - .and_then(|()| write!(f, "}}")), - None => write!(f, "Once {{ }}"), - } - } -} - -// Same unsafe impls as `std::sync::RwLock`, because this also allows for -// concurrent reads. -unsafe impl Sync for Once {} -unsafe impl Send for Once {} - -mod status { - use super::*; - - // SAFETY: This structure has an invariant, namely that the inner atomic u8 must *always* have - // a value for which there exists a valid Status. This means that users of this API must only - // be allowed to load and store `Status`es. - #[repr(transparent)] - pub struct AtomicStatus(AtomicU8); - - // Four states that a Once can be in, encoded into the lower bits of `status` in - // the Once structure. - #[repr(u8)] - #[derive(Clone, Copy, Debug, PartialEq)] - pub enum Status { - Incomplete = 0x00, - Running = 0x01, - Complete = 0x02, - Panicked = 0x03, - } - impl Status { - // Construct a status from an inner u8 integer. - // - // # Safety - // - // For this to be safe, the inner number must have a valid corresponding enum variant. - unsafe fn new_unchecked(inner: u8) -> Self { - core::mem::transmute(inner) - } - } - - impl AtomicStatus { - #[inline(always)] - pub const fn new(status: Status) -> Self { - // SAFETY: We got the value directly from status, so transmuting back is fine. - Self(AtomicU8::new(status as u8)) - } - #[inline(always)] - pub fn load(&self, ordering: Ordering) -> Status { - // SAFETY: We know that the inner integer must have been constructed from a Status in - // the first place. - unsafe { Status::new_unchecked(self.0.load(ordering)) } - } - #[inline(always)] - pub fn store(&self, status: Status, ordering: Ordering) { - // SAFETY: While not directly unsafe, this is safe because the value was retrieved from - // a status, thus making transmutation safe. - self.0.store(status as u8, ordering); - } - #[inline(always)] - pub fn compare_exchange( - &self, - old: Status, - new: Status, - success: Ordering, - failure: Ordering, - ) -> Result { - match self - .0 - .compare_exchange(old as u8, new as u8, success, failure) - { - // SAFETY: A compare exchange will always return a value that was later stored into - // the atomic u8, but due to the invariant that it must be a valid Status, we know - // that both Ok(_) and Err(_) will be safely transmutable. - Ok(ok) => Ok(unsafe { Status::new_unchecked(ok) }), - Err(err) => Err(unsafe { Status::new_unchecked(err) }), - } - } - #[inline(always)] - pub fn get_mut(&mut self) -> &mut Status { - // SAFETY: Since we know that the u8 inside must be a valid Status, we can safely cast - // it to a &mut Status. - unsafe { &mut *((self.0.get_mut() as *mut u8).cast::()) } - } - } -} -use self::status::{AtomicStatus, Status}; - -impl Once { - /// Performs an initialization routine once and only once. The given closure - /// will be executed if this is the first time `call_once` has been called, - /// and otherwise the routine will *not* be invoked. - /// - /// This method will block the calling thread if another initialization - /// routine is currently running. - /// - /// When this function returns, it is guaranteed that some initialization - /// has run and completed (it may not be the closure specified). The - /// returned pointer will point to the result from the closure that was - /// run. - /// - /// # Panics - /// - /// This function will panic if the [`Once`] previously panicked while attempting - /// to initialize. This is similar to the poisoning behaviour of `std::sync`'s - /// primitives. - /// - /// # Examples - /// - /// ``` - /// use spin; - /// - /// static INIT: spin::Once = spin::Once::new(); - /// - /// fn get_cached_val() -> usize { - /// *INIT.call_once(expensive_computation) - /// } - /// - /// fn expensive_computation() -> usize { - /// // ... - /// # 2 - /// } - /// ``` - pub fn call_once T>(&self, f: F) -> &T { - match self.try_call_once(|| Ok::(f())) { - Ok(x) => x, - Err(void) => match void {}, - } - } - - /// This method is similar to `call_once`, but allows the given closure to - /// fail, and lets the `Once` in a uninitialized state if it does. - /// - /// This method will block the calling thread if another initialization - /// routine is currently running. - /// - /// When this function returns without error, it is guaranteed that some - /// initialization has run and completed (it may not be the closure - /// specified). The returned reference will point to the result from the - /// closure that was run. - /// - /// # Panics - /// - /// This function will panic if the [`Once`] previously panicked while attempting - /// to initialize. This is similar to the poisoning behaviour of `std::sync`'s - /// primitives. - /// - /// # Examples - /// - /// ``` - /// use spin; - /// - /// static INIT: spin::Once = spin::Once::new(); - /// - /// fn get_cached_val() -> Result { - /// INIT.try_call_once(expensive_fallible_computation).map(|x| *x) - /// } - /// - /// fn expensive_fallible_computation() -> Result { - /// // ... - /// # Ok(2) - /// } - /// ``` - pub fn try_call_once Result, E>(&self, f: F) -> Result<&T, E> { - if let Some(value) = self.get() { - Ok(value) - } else { - self.try_call_once_slow(f) - } - } - - #[cold] - fn try_call_once_slow Result, E>(&self, f: F) -> Result<&T, E> { - loop { - let xchg = self.status.compare_exchange( - Status::Incomplete, - Status::Running, - Ordering::Acquire, - Ordering::Acquire, - ); - - match xchg { - Ok(_must_be_state_incomplete) => { - // Impl is defined after the match for readability - } - Err(Status::Panicked) => panic!("Once panicked"), - Err(Status::Running) => match self.poll() { - Some(v) => return Ok(v), - None => continue, - }, - Err(Status::Complete) => { - return Ok(unsafe { - // SAFETY: The status is Complete - self.force_get() - }); - } - Err(Status::Incomplete) => { - // The compare_exchange failed, so this shouldn't ever be reached, - // however if we decide to switch to compare_exchange_weak it will - // be safer to leave this here than hit an unreachable - continue; - } - } - - // The compare-exchange succeeded, so we shall initialize it. - - // We use a guard (Finish) to catch panics caused by builder - let finish = Finish { - status: &self.status, - }; - let val = match f() { - Ok(val) => val, - Err(err) => { - // If an error occurs, clean up everything and leave. - core::mem::forget(finish); - self.status.store(Status::Incomplete, Ordering::Release); - return Err(err); - } - }; - unsafe { - // SAFETY: - // `UnsafeCell`/deref: currently the only accessor, mutably - // and immutably by cas exclusion. - // `write`: pointer comes from `MaybeUninit`. - (*self.data.get()).as_mut_ptr().write(val); - }; - // If there were to be a panic with unwind enabled, the code would - // short-circuit and never reach the point where it writes the inner data. - // The destructor for Finish will run, and poison the Once to ensure that other - // threads accessing it do not exhibit unwanted behavior, if there were to be - // any inconsistency in data structures caused by the panicking thread. - // - // However, f() is expected in the general case not to panic. In that case, we - // simply forget the guard, bypassing its destructor. We could theoretically - // clear a flag instead, but this eliminates the call to the destructor at - // compile time, and unconditionally poisons during an eventual panic, if - // unwinding is enabled. - core::mem::forget(finish); - - // SAFETY: Release is required here, so that all memory accesses done in the - // closure when initializing, become visible to other threads that perform Acquire - // loads. - // - // And, we also know that the changes this thread has done will not magically - // disappear from our cache, so it does not need to be AcqRel. - self.status.store(Status::Complete, Ordering::Release); - - // This next line is mainly an optimization. - return unsafe { Ok(self.force_get()) }; - } - } - - /// Spins until the [`Once`] contains a value. - /// - /// Note that in releases prior to `0.7`, this function had the behaviour of [`Once::poll`]. - /// - /// # Panics - /// - /// This function will panic if the [`Once`] previously panicked while attempting - /// to initialize. This is similar to the poisoning behaviour of `std::sync`'s - /// primitives. - pub fn wait(&self) -> &T { - loop { - match self.poll() { - Some(x) => break x, - None => R::relax(), - } - } - } - - /// Like [`Once::get`], but will spin if the [`Once`] is in the process of being - /// initialized. If initialization has not even begun, `None` will be returned. - /// - /// Note that in releases prior to `0.7`, this function was named `wait`. - /// - /// # Panics - /// - /// This function will panic if the [`Once`] previously panicked while attempting - /// to initialize. This is similar to the poisoning behaviour of `std::sync`'s - /// primitives. - pub fn poll(&self) -> Option<&T> { - loop { - // SAFETY: Acquire is safe here, because if the status is COMPLETE, then we want to make - // sure that all memory accessed done while initializing that value, are visible when - // we return a reference to the inner data after this load. - match self.status.load(Ordering::Acquire) { - Status::Incomplete => return None, - Status::Running => R::relax(), // We spin - Status::Complete => return Some(unsafe { self.force_get() }), - Status::Panicked => panic!("Once previously poisoned by a panicked"), - } - } - } -} - -impl Once { - /// Initialization constant of [`Once`]. - #[allow(clippy::declare_interior_mutable_const)] - pub const INIT: Self = Self { - phantom: PhantomData, - status: AtomicStatus::new(Status::Incomplete), - data: UnsafeCell::new(MaybeUninit::uninit()), - }; - - /// Creates a new [`Once`]. - pub const fn new() -> Self { - Self::INIT - } - - /// Creates a new initialized [`Once`]. - pub const fn initialized(data: T) -> Self { - Self { - phantom: PhantomData, - status: AtomicStatus::new(Status::Complete), - data: UnsafeCell::new(MaybeUninit::new(data)), - } - } - - /// Retrieve a pointer to the inner data. - /// - /// While this method itself is safe, accessing the pointer before the [`Once`] has been - /// initialized is UB, unless this method has already been written to from a pointer coming - /// from this method. - pub fn as_mut_ptr(&self) -> *mut T { - // SAFETY: - // * MaybeUninit always has exactly the same layout as T - self.data.get().cast::() - } - - /// Get a reference to the initialized instance. Must only be called once COMPLETE. - unsafe fn force_get(&self) -> &T { - // SAFETY: - // * `UnsafeCell`/inner deref: data never changes again - // * `MaybeUninit`/outer deref: data was initialized - &*(*self.data.get()).as_ptr() - } - - /// Get a reference to the initialized instance. Must only be called once COMPLETE. - unsafe fn force_get_mut(&mut self) -> &mut T { - // SAFETY: - // * `UnsafeCell`/inner deref: data never changes again - // * `MaybeUninit`/outer deref: data was initialized - &mut *(*self.data.get()).as_mut_ptr() - } - - /// Get a reference to the initialized instance. Must only be called once COMPLETE. - unsafe fn force_into_inner(self) -> T { - // SAFETY: - // * `UnsafeCell`/inner deref: data never changes again - // * `MaybeUninit`/outer deref: data was initialized - (*self.data.get()).as_ptr().read() - } - - /// Returns a reference to the inner value if the [`Once`] has been initialized. - pub fn get(&self) -> Option<&T> { - // SAFETY: Just as with `poll`, Acquire is safe here because we want to be able to see the - // nonatomic stores done when initializing, once we have loaded and checked the status. - match self.status.load(Ordering::Acquire) { - Status::Complete => Some(unsafe { self.force_get() }), - _ => None, - } - } - - /// Returns a reference to the inner value on the unchecked assumption that the [`Once`] has been initialized. - /// - /// # Safety - /// - /// This is *extremely* unsafe if the `Once` has not already been initialized because a reference to uninitialized - /// memory will be returned, immediately triggering undefined behaviour (even if the reference goes unused). - /// However, this can be useful in some instances for exposing the `Once` to FFI or when the overhead of atomically - /// checking initialization is unacceptable and the `Once` has already been initialized. - pub unsafe fn get_unchecked(&self) -> &T { - debug_assert_eq!( - self.status.load(Ordering::SeqCst), - Status::Complete, - "Attempted to access an uninitialized Once. If this was run without debug checks, this would be undefined behaviour. This is a serious bug and you must fix it.", - ); - self.force_get() - } - - /// Returns a mutable reference to the inner value if the [`Once`] has been initialized. - /// - /// Because this method requires a mutable reference to the [`Once`], no synchronization - /// overhead is required to access the inner value. In effect, it is zero-cost. - pub fn get_mut(&mut self) -> Option<&mut T> { - match *self.status.get_mut() { - Status::Complete => Some(unsafe { self.force_get_mut() }), - _ => None, - } - } - - /// Returns a mutable reference to the inner value - /// - /// # Safety - /// - /// This is *extremely* unsafe if the `Once` has not already been initialized because a reference to uninitialized - /// memory will be returned, immediately triggering undefined behaviour (even if the reference goes unused). - /// However, this can be useful in some instances for exposing the `Once` to FFI or when the overhead of atomically - /// checking initialization is unacceptable and the `Once` has already been initialized. - pub unsafe fn get_mut_unchecked(&mut self) -> &mut T { - debug_assert_eq!( - self.status.load(Ordering::SeqCst), - Status::Complete, - "Attempted to access an unintialized Once. If this was to run without debug checks, this would be undefined behavior. This is a serious bug and you must fix it.", - ); - self.force_get_mut() - } - - /// Returns a the inner value if the [`Once`] has been initialized. - /// - /// Because this method requires ownership of the [`Once`], no synchronization overhead - /// is required to access the inner value. In effect, it is zero-cost. - pub fn try_into_inner(mut self) -> Option { - match *self.status.get_mut() { - Status::Complete => Some(unsafe { self.force_into_inner() }), - _ => None, - } - } - - /// Returns a the inner value if the [`Once`] has been initialized. - /// # Safety - /// - /// This is *extremely* unsafe if the `Once` has not already been initialized because a reference to uninitialized - /// memory will be returned, immediately triggering undefined behaviour (even if the reference goes unused) - /// This can be useful, if `Once` has already been initialized, and you want to bypass an - /// option check. - pub unsafe fn into_inner_unchecked(self) -> T { - debug_assert_eq!( - self.status.load(Ordering::SeqCst), - Status::Complete, - "Attempted to access an unintialized Once. If this was to run without debug checks, this would be undefined behavior. This is a serious bug and you must fix it.", - ); - self.force_into_inner() - } - - /// Checks whether the value has been initialized. - /// - /// This is done using [`Acquire`](core::sync::atomic::Ordering::Acquire) ordering, and - /// therefore it is safe to access the value directly via - /// [`get_unchecked`](Self::get_unchecked) if this returns true. - pub fn is_completed(&self) -> bool { - // TODO: Add a similar variant for Relaxed? - self.status.load(Ordering::Acquire) == Status::Complete - } -} - -impl From for Once { - fn from(data: T) -> Self { - Self::initialized(data) - } -} - -impl Drop for Once { - fn drop(&mut self) { - // No need to do any atomic access here, we have &mut! - if *self.status.get_mut() == Status::Complete { - unsafe { - //TODO: Use MaybeUninit::assume_init_drop once stabilised - core::ptr::drop_in_place((*self.data.get()).as_mut_ptr()); - } - } - } -} - -struct Finish<'a> { - status: &'a AtomicStatus, -} - -impl<'a> Drop for Finish<'a> { - fn drop(&mut self) { - // While using Relaxed here would most likely not be an issue, we use SeqCst anyway. - // This is mainly because panics are not meant to be fast at all, but also because if - // there were to be a compiler bug which reorders accesses within the same thread, - // where it should not, we want to be sure that the panic really is handled, and does - // not cause additional problems. SeqCst will therefore help guarding against such - // bugs. - self.status.store(Status::Panicked, Ordering::SeqCst); - } -} - -#[cfg(test)] -mod tests { - use std::prelude::v1::*; - - use std::sync::atomic::AtomicU32; - use std::sync::mpsc::channel; - use std::sync::Arc; - use std::thread; - - use super::*; - - #[test] - fn smoke_once() { - static O: Once = Once::new(); - let mut a = 0; - O.call_once(|| a += 1); - assert_eq!(a, 1); - O.call_once(|| a += 1); - assert_eq!(a, 1); - } - - #[test] - fn smoke_once_value() { - static O: Once = Once::new(); - let a = O.call_once(|| 1); - assert_eq!(*a, 1); - let b = O.call_once(|| 2); - assert_eq!(*b, 1); - } - - #[test] - fn stampede_once() { - static O: Once = Once::new(); - static mut RUN: bool = false; - - let (tx, rx) = channel(); - let mut ts = Vec::new(); - for _ in 0..10 { - let tx = tx.clone(); - ts.push(thread::spawn(move || { - for _ in 0..4 { - thread::yield_now() - } - unsafe { - O.call_once(|| { - assert!(!RUN); - RUN = true; - }); - assert!(RUN); - } - tx.send(()).unwrap(); - })); - } - - unsafe { - O.call_once(|| { - assert!(!RUN); - RUN = true; - }); - assert!(RUN); - } - - for _ in 0..10 { - rx.recv().unwrap(); - } - - for t in ts { - t.join().unwrap(); - } - } - - #[test] - fn get() { - static INIT: Once = Once::new(); - - assert!(INIT.get().is_none()); - INIT.call_once(|| 2); - assert_eq!(INIT.get().map(|r| *r), Some(2)); - } - - #[test] - fn get_no_wait() { - static INIT: Once = Once::new(); - - assert!(INIT.get().is_none()); - let t = thread::spawn(move || { - INIT.call_once(|| { - thread::sleep(std::time::Duration::from_secs(3)); - 42 - }); - }); - assert!(INIT.get().is_none()); - - t.join().unwrap(); - } - - #[test] - fn poll() { - static INIT: Once = Once::new(); - - assert!(INIT.poll().is_none()); - INIT.call_once(|| 3); - assert_eq!(INIT.poll().map(|r| *r), Some(3)); - } - - #[test] - fn wait() { - static INIT: Once = Once::new(); - - let t = std::thread::spawn(|| { - assert_eq!(*INIT.wait(), 3); - assert!(INIT.is_completed()); - }); - - for _ in 0..4 { - thread::yield_now() - } - - assert!(INIT.poll().is_none()); - INIT.call_once(|| 3); - - t.join().unwrap(); - } - - #[test] - fn panic() { - use std::panic; - - static INIT: Once = Once::new(); - - // poison the once - let t = panic::catch_unwind(|| { - INIT.call_once(|| panic!()); - }); - assert!(t.is_err()); - - // poisoning propagates - let t = panic::catch_unwind(|| { - INIT.call_once(|| {}); - }); - assert!(t.is_err()); - } - - #[test] - fn init_constant() { - static O: Once = Once::INIT; - let mut a = 0; - O.call_once(|| a += 1); - assert_eq!(a, 1); - O.call_once(|| a += 1); - assert_eq!(a, 1); - } - - static mut CALLED: bool = false; - - struct DropTest {} - - impl Drop for DropTest { - fn drop(&mut self) { - unsafe { - CALLED = true; - } - } - } - - #[test] - fn try_call_once_err() { - let once = Once::<_, Spin>::new(); - let shared = Arc::new((once, AtomicU32::new(0))); - - let (tx, rx) = channel(); - - let t0 = { - let shared = shared.clone(); - thread::spawn(move || { - let (once, called) = &*shared; - - once.try_call_once(|| { - called.fetch_add(1, Ordering::AcqRel); - tx.send(()).unwrap(); - thread::sleep(std::time::Duration::from_millis(50)); - Err(()) - }) - .ok(); - }) - }; - - let t1 = { - let shared = shared.clone(); - thread::spawn(move || { - rx.recv().unwrap(); - let (once, called) = &*shared; - assert_eq!( - called.load(Ordering::Acquire), - 1, - "leader thread did not run first" - ); - - once.call_once(|| { - called.fetch_add(1, Ordering::AcqRel); - }); - }) - }; - - t0.join().unwrap(); - t1.join().unwrap(); - - assert_eq!(shared.1.load(Ordering::Acquire), 2); - } - - // This is sort of two test cases, but if we write them as separate test methods - // they can be executed concurrently and then fail some small fraction of the - // time. - #[test] - fn drop_occurs_and_skip_uninit_drop() { - unsafe { - CALLED = false; - } - - { - let once = Once::<_>::new(); - once.call_once(|| DropTest {}); - } - - assert!(unsafe { CALLED }); - // Now test that we skip drops for the uninitialized case. - unsafe { - CALLED = false; - } - - let once = Once::::new(); - drop(once); - - assert!(unsafe { !CALLED }); - } - - #[test] - fn call_once_test() { - for _ in 0..20 { - use std::sync::atomic::AtomicUsize; - use std::sync::Arc; - use std::time::Duration; - let share = Arc::new(AtomicUsize::new(0)); - let once = Arc::new(Once::<_, Spin>::new()); - let mut hs = Vec::new(); - for _ in 0..8 { - let h = thread::spawn({ - let share = share.clone(); - let once = once.clone(); - move || { - thread::sleep(Duration::from_millis(10)); - once.call_once(|| { - share.fetch_add(1, Ordering::SeqCst); - }); - } - }); - hs.push(h); - } - for h in hs { - h.join().unwrap(); - } - assert_eq!(1, share.load(Ordering::SeqCst)); - } - } -} diff --git a/third-party/vendor/spin/src/relax.rs b/third-party/vendor/spin/src/relax.rs deleted file mode 100644 index 8842f80b..00000000 --- a/third-party/vendor/spin/src/relax.rs +++ /dev/null @@ -1,61 +0,0 @@ -//! Strategies that determine the behaviour of locks when encountering contention. - -/// A trait implemented by spinning relax strategies. -pub trait RelaxStrategy { - /// Perform the relaxing operation during a period of contention. - fn relax(); -} - -/// A strategy that rapidly spins while informing the CPU that it should power down non-essential components via -/// [`core::hint::spin_loop`]. -/// -/// Note that spinning is a 'dumb' strategy and most schedulers cannot correctly differentiate it from useful work, -/// thereby misallocating even more CPU time to the spinning process. This is known as -/// ['priority inversion'](https://matklad.github.io/2020/01/02/spinlocks-considered-harmful.html). -/// -/// If you see signs that priority inversion is occurring, consider switching to [`Yield`] or, even better, not using a -/// spinlock at all and opting for a proper scheduler-aware lock. Remember also that different targets, operating -/// systems, schedulers, and even the same scheduler with different workloads will exhibit different behaviour. Just -/// because priority inversion isn't occurring in your tests does not mean that it will not occur. Use a scheduler- -/// aware lock if at all possible. -pub struct Spin; - -impl RelaxStrategy for Spin { - #[inline(always)] - fn relax() { - // Use the deprecated spin_loop_hint() to ensure that we don't get - // a higher MSRV than we need to. - #[allow(deprecated)] - core::sync::atomic::spin_loop_hint(); - } -} - -/// A strategy that yields the current time slice to the scheduler in favour of other threads or processes. -/// -/// This is generally used as a strategy for minimising power consumption and priority inversion on targets that have a -/// standard library available. Note that such targets have scheduler-integrated concurrency primitives available, and -/// you should generally use these instead, except in rare circumstances. -#[cfg(feature = "std")] -#[cfg_attr(docsrs, doc(cfg(feature = "std")))] -pub struct Yield; - -#[cfg(feature = "std")] -#[cfg_attr(docsrs, doc(cfg(feature = "std")))] -impl RelaxStrategy for Yield { - #[inline(always)] - fn relax() { - std::thread::yield_now(); - } -} - -/// A strategy that rapidly spins, without telling the CPU to do any powering down. -/// -/// You almost certainly do not want to use this. Use [`Spin`] instead. It exists for completeness and for targets -/// that, for some reason, miscompile or do not support spin hint intrinsics despite attempting to generate code for -/// them (i.e: this is a workaround for possible compiler bugs). -pub struct Loop; - -impl RelaxStrategy for Loop { - #[inline(always)] - fn relax() {} -} diff --git a/third-party/vendor/spin/src/rwlock.rs b/third-party/vendor/spin/src/rwlock.rs deleted file mode 100644 index 5dd35441..00000000 --- a/third-party/vendor/spin/src/rwlock.rs +++ /dev/null @@ -1,1165 +0,0 @@ -//! A lock that provides data access to either one writer or many readers. - -use crate::{ - atomic::{AtomicUsize, Ordering}, - RelaxStrategy, Spin, -}; -use core::{ - cell::UnsafeCell, - fmt, - marker::PhantomData, - mem, - mem::ManuallyDrop, - ops::{Deref, DerefMut}, -}; - -/// A lock that provides data access to either one writer or many readers. -/// -/// This lock behaves in a similar manner to its namesake `std::sync::RwLock` but uses -/// spinning for synchronisation instead. Unlike its namespace, this lock does not -/// track lock poisoning. -/// -/// This type of lock allows a number of readers or at most one writer at any -/// point in time. The write portion of this lock typically allows modification -/// of the underlying data (exclusive access) and the read portion of this lock -/// typically allows for read-only access (shared access). -/// -/// The type parameter `T` represents the data that this lock protects. It is -/// required that `T` satisfies `Send` to be shared across tasks and `Sync` to -/// allow concurrent access through readers. The RAII guards returned from the -/// locking methods implement `Deref` (and `DerefMut` for the `write` methods) -/// to allow access to the contained of the lock. -/// -/// An [`RwLockUpgradableGuard`](RwLockUpgradableGuard) can be upgraded to a -/// writable guard through the [`RwLockUpgradableGuard::upgrade`](RwLockUpgradableGuard::upgrade) -/// [`RwLockUpgradableGuard::try_upgrade`](RwLockUpgradableGuard::try_upgrade) functions. -/// Writable or upgradeable guards can be downgraded through their respective `downgrade` -/// functions. -/// -/// Based on Facebook's -/// [`folly/RWSpinLock.h`](https://github.com/facebook/folly/blob/a0394d84f2d5c3e50ebfd0566f9d3acb52cfab5a/folly/synchronization/RWSpinLock.h). -/// This implementation is unfair to writers - if the lock always has readers, then no writers will -/// ever get a chance. Using an upgradeable lock guard can *somewhat* alleviate this issue as no -/// new readers are allowed when an upgradeable guard is held, but upgradeable guards can be taken -/// when there are existing readers. However if the lock is that highly contended and writes are -/// crucial then this implementation may be a poor choice. -/// -/// # Examples -/// -/// ``` -/// use spin; -/// -/// let lock = spin::RwLock::new(5); -/// -/// // many reader locks can be held at once -/// { -/// let r1 = lock.read(); -/// let r2 = lock.read(); -/// assert_eq!(*r1, 5); -/// assert_eq!(*r2, 5); -/// } // read locks are dropped at this point -/// -/// // only one write lock may be held, however -/// { -/// let mut w = lock.write(); -/// *w += 1; -/// assert_eq!(*w, 6); -/// } // write lock is dropped here -/// ``` -pub struct RwLock { - phantom: PhantomData, - lock: AtomicUsize, - data: UnsafeCell, -} - -const READER: usize = 1 << 2; -const UPGRADED: usize = 1 << 1; -const WRITER: usize = 1; - -/// A guard that provides immutable data access. -/// -/// When the guard falls out of scope it will decrement the read count, -/// potentially releasing the lock. -pub struct RwLockReadGuard<'a, T: 'a + ?Sized> { - lock: &'a AtomicUsize, - data: *const T, -} - -/// A guard that provides mutable data access. -/// -/// When the guard falls out of scope it will release the lock. -pub struct RwLockWriteGuard<'a, T: 'a + ?Sized, R = Spin> { - phantom: PhantomData, - inner: &'a RwLock, - data: *mut T, -} - -/// A guard that provides immutable data access but can be upgraded to [`RwLockWriteGuard`]. -/// -/// No writers or other upgradeable guards can exist while this is in scope. New reader -/// creation is prevented (to alleviate writer starvation) but there may be existing readers -/// when the lock is acquired. -/// -/// When the guard falls out of scope it will release the lock. -pub struct RwLockUpgradableGuard<'a, T: 'a + ?Sized, R = Spin> { - phantom: PhantomData, - inner: &'a RwLock, - data: *const T, -} - -// Same unsafe impls as `std::sync::RwLock` -unsafe impl Send for RwLock {} -unsafe impl Sync for RwLock {} - -unsafe impl Send for RwLockWriteGuard<'_, T, R> {} -unsafe impl Sync for RwLockWriteGuard<'_, T, R> {} - -unsafe impl Send for RwLockReadGuard<'_, T> {} -unsafe impl Sync for RwLockReadGuard<'_, T> {} - -unsafe impl Send for RwLockUpgradableGuard<'_, T, R> {} -unsafe impl Sync for RwLockUpgradableGuard<'_, T, R> {} - -impl RwLock { - /// Creates a new spinlock wrapping the supplied data. - /// - /// May be used statically: - /// - /// ``` - /// use spin; - /// - /// static RW_LOCK: spin::RwLock<()> = spin::RwLock::new(()); - /// - /// fn demo() { - /// let lock = RW_LOCK.read(); - /// // do something with lock - /// drop(lock); - /// } - /// ``` - #[inline] - pub const fn new(data: T) -> Self { - RwLock { - phantom: PhantomData, - lock: AtomicUsize::new(0), - data: UnsafeCell::new(data), - } - } - - /// Consumes this `RwLock`, returning the underlying data. - #[inline] - pub fn into_inner(self) -> T { - // We know statically that there are no outstanding references to - // `self` so there's no need to lock. - let RwLock { data, .. } = self; - data.into_inner() - } - /// Returns a mutable pointer to the underying data. - /// - /// This is mostly meant to be used for applications which require manual unlocking, but where - /// storing both the lock and the pointer to the inner data gets inefficient. - /// - /// While this is safe, writing to the data is undefined behavior unless the current thread has - /// acquired a write lock, and reading requires either a read or write lock. - /// - /// # Example - /// ``` - /// let lock = spin::RwLock::new(42); - /// - /// unsafe { - /// core::mem::forget(lock.write()); - /// - /// assert_eq!(lock.as_mut_ptr().read(), 42); - /// lock.as_mut_ptr().write(58); - /// - /// lock.force_write_unlock(); - /// } - /// - /// assert_eq!(*lock.read(), 58); - /// - /// ``` - #[inline(always)] - pub fn as_mut_ptr(&self) -> *mut T { - self.data.get() - } -} - -impl RwLock { - /// Locks this rwlock with shared read access, blocking the current thread - /// until it can be acquired. - /// - /// The calling thread will be blocked until there are no more writers which - /// hold the lock. There may be other readers currently inside the lock when - /// this method returns. This method does not provide any guarantees with - /// respect to the ordering of whether contentious readers or writers will - /// acquire the lock first. - /// - /// Returns an RAII guard which will release this thread's shared access - /// once it is dropped. - /// - /// ``` - /// let mylock = spin::RwLock::new(0); - /// { - /// let mut data = mylock.read(); - /// // The lock is now locked and the data can be read - /// println!("{}", *data); - /// // The lock is dropped - /// } - /// ``` - #[inline] - pub fn read(&self) -> RwLockReadGuard { - loop { - match self.try_read() { - Some(guard) => return guard, - None => R::relax(), - } - } - } - - /// Lock this rwlock with exclusive write access, blocking the current - /// thread until it can be acquired. - /// - /// This function will not return while other writers or other readers - /// currently have access to the lock. - /// - /// Returns an RAII guard which will drop the write access of this rwlock - /// when dropped. - /// - /// ``` - /// let mylock = spin::RwLock::new(0); - /// { - /// let mut data = mylock.write(); - /// // The lock is now locked and the data can be written - /// *data += 1; - /// // The lock is dropped - /// } - /// ``` - #[inline] - pub fn write(&self) -> RwLockWriteGuard { - loop { - match self.try_write_internal(false) { - Some(guard) => return guard, - None => R::relax(), - } - } - } - - /// Obtain a readable lock guard that can later be upgraded to a writable lock guard. - /// Upgrades can be done through the [`RwLockUpgradableGuard::upgrade`](RwLockUpgradableGuard::upgrade) method. - #[inline] - pub fn upgradeable_read(&self) -> RwLockUpgradableGuard { - loop { - match self.try_upgradeable_read() { - Some(guard) => return guard, - None => R::relax(), - } - } - } -} - -impl RwLock { - // Acquire a read lock, returning the new lock value. - fn acquire_reader(&self) -> usize { - // An arbitrary cap that allows us to catch overflows long before they happen - const MAX_READERS: usize = core::usize::MAX / READER / 2; - - let value = self.lock.fetch_add(READER, Ordering::Acquire); - - if value > MAX_READERS * READER { - self.lock.fetch_sub(READER, Ordering::Relaxed); - panic!("Too many lock readers, cannot safely proceed"); - } else { - value - } - } - - /// Attempt to acquire this lock with shared read access. - /// - /// This function will never block and will return immediately if `read` - /// would otherwise succeed. Returns `Some` of an RAII guard which will - /// release the shared access of this thread when dropped, or `None` if the - /// access could not be granted. This method does not provide any - /// guarantees with respect to the ordering of whether contentious readers - /// or writers will acquire the lock first. - /// - /// ``` - /// let mylock = spin::RwLock::new(0); - /// { - /// match mylock.try_read() { - /// Some(data) => { - /// // The lock is now locked and the data can be read - /// println!("{}", *data); - /// // The lock is dropped - /// }, - /// None => (), // no cigar - /// }; - /// } - /// ``` - #[inline] - pub fn try_read(&self) -> Option> { - let value = self.acquire_reader(); - - // We check the UPGRADED bit here so that new readers are prevented when an UPGRADED lock is held. - // This helps reduce writer starvation. - if value & (WRITER | UPGRADED) != 0 { - // Lock is taken, undo. - self.lock.fetch_sub(READER, Ordering::Release); - None - } else { - Some(RwLockReadGuard { - lock: &self.lock, - data: unsafe { &*self.data.get() }, - }) - } - } - - /// Return the number of readers that currently hold the lock (including upgradable readers). - /// - /// # Safety - /// - /// This function provides no synchronization guarantees and so its result should be considered 'out of date' - /// the instant it is called. Do not use it for synchronization purposes. However, it may be useful as a heuristic. - pub fn reader_count(&self) -> usize { - let state = self.lock.load(Ordering::Relaxed); - state / READER + (state & UPGRADED) / UPGRADED - } - - /// Return the number of writers that currently hold the lock. - /// - /// Because [`RwLock`] guarantees exclusive mutable access, this function may only return either `0` or `1`. - /// - /// # Safety - /// - /// This function provides no synchronization guarantees and so its result should be considered 'out of date' - /// the instant it is called. Do not use it for synchronization purposes. However, it may be useful as a heuristic. - pub fn writer_count(&self) -> usize { - (self.lock.load(Ordering::Relaxed) & WRITER) / WRITER - } - - /// Force decrement the reader count. - /// - /// # Safety - /// - /// This is *extremely* unsafe if there are outstanding `RwLockReadGuard`s - /// live, or if called more times than `read` has been called, but can be - /// useful in FFI contexts where the caller doesn't know how to deal with - /// RAII. The underlying atomic operation uses `Ordering::Release`. - #[inline] - pub unsafe fn force_read_decrement(&self) { - debug_assert!(self.lock.load(Ordering::Relaxed) & !WRITER > 0); - self.lock.fetch_sub(READER, Ordering::Release); - } - - /// Force unlock exclusive write access. - /// - /// # Safety - /// - /// This is *extremely* unsafe if there are outstanding `RwLockWriteGuard`s - /// live, or if called when there are current readers, but can be useful in - /// FFI contexts where the caller doesn't know how to deal with RAII. The - /// underlying atomic operation uses `Ordering::Release`. - #[inline] - pub unsafe fn force_write_unlock(&self) { - debug_assert_eq!(self.lock.load(Ordering::Relaxed) & !(WRITER | UPGRADED), 0); - self.lock.fetch_and(!(WRITER | UPGRADED), Ordering::Release); - } - - #[inline(always)] - fn try_write_internal(&self, strong: bool) -> Option> { - if compare_exchange( - &self.lock, - 0, - WRITER, - Ordering::Acquire, - Ordering::Relaxed, - strong, - ) - .is_ok() - { - Some(RwLockWriteGuard { - phantom: PhantomData, - inner: self, - data: unsafe { &mut *self.data.get() }, - }) - } else { - None - } - } - - /// Attempt to lock this rwlock with exclusive write access. - /// - /// This function does not ever block, and it will return `None` if a call - /// to `write` would otherwise block. If successful, an RAII guard is - /// returned. - /// - /// ``` - /// let mylock = spin::RwLock::new(0); - /// { - /// match mylock.try_write() { - /// Some(mut data) => { - /// // The lock is now locked and the data can be written - /// *data += 1; - /// // The lock is implicitly dropped - /// }, - /// None => (), // no cigar - /// }; - /// } - /// ``` - #[inline] - pub fn try_write(&self) -> Option> { - self.try_write_internal(true) - } - - /// Tries to obtain an upgradeable lock guard. - #[inline] - pub fn try_upgradeable_read(&self) -> Option> { - if self.lock.fetch_or(UPGRADED, Ordering::Acquire) & (WRITER | UPGRADED) == 0 { - Some(RwLockUpgradableGuard { - phantom: PhantomData, - inner: self, - data: unsafe { &*self.data.get() }, - }) - } else { - // We can't unflip the UPGRADED bit back just yet as there is another upgradeable or write lock. - // When they unlock, they will clear the bit. - None - } - } - - /// Returns a mutable reference to the underlying data. - /// - /// Since this call borrows the `RwLock` mutably, no actual locking needs to - /// take place -- the mutable borrow statically guarantees no locks exist. - /// - /// # Examples - /// - /// ``` - /// let mut lock = spin::RwLock::new(0); - /// *lock.get_mut() = 10; - /// assert_eq!(*lock.read(), 10); - /// ``` - pub fn get_mut(&mut self) -> &mut T { - // We know statically that there are no other references to `self`, so - // there's no need to lock the inner lock. - unsafe { &mut *self.data.get() } - } -} - -impl fmt::Debug for RwLock { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - match self.try_read() { - Some(guard) => write!(f, "RwLock {{ data: ") - .and_then(|()| (&*guard).fmt(f)) - .and_then(|()| write!(f, "}}")), - None => write!(f, "RwLock {{ }}"), - } - } -} - -impl Default for RwLock { - fn default() -> Self { - Self::new(Default::default()) - } -} - -impl From for RwLock { - fn from(data: T) -> Self { - Self::new(data) - } -} - -impl<'rwlock, T: ?Sized> RwLockReadGuard<'rwlock, T> { - /// Leak the lock guard, yielding a reference to the underlying data. - /// - /// Note that this function will permanently lock the original lock for all but reading locks. - /// - /// ``` - /// let mylock = spin::RwLock::new(0); - /// - /// let data: &i32 = spin::RwLockReadGuard::leak(mylock.read()); - /// - /// assert_eq!(*data, 0); - /// ``` - #[inline] - pub fn leak(this: Self) -> &'rwlock T { - let this = ManuallyDrop::new(this); - // Safety: We know statically that only we are referencing data - unsafe { &*this.data } - } -} - -impl<'rwlock, T: ?Sized + fmt::Debug> fmt::Debug for RwLockReadGuard<'rwlock, T> { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - fmt::Debug::fmt(&**self, f) - } -} - -impl<'rwlock, T: ?Sized + fmt::Display> fmt::Display for RwLockReadGuard<'rwlock, T> { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - fmt::Display::fmt(&**self, f) - } -} - -impl<'rwlock, T: ?Sized, R: RelaxStrategy> RwLockUpgradableGuard<'rwlock, T, R> { - /// Upgrades an upgradeable lock guard to a writable lock guard. - /// - /// ``` - /// let mylock = spin::RwLock::new(0); - /// - /// let upgradeable = mylock.upgradeable_read(); // Readable, but not yet writable - /// let writable = upgradeable.upgrade(); - /// ``` - #[inline] - pub fn upgrade(mut self) -> RwLockWriteGuard<'rwlock, T, R> { - loop { - self = match self.try_upgrade_internal(false) { - Ok(guard) => return guard, - Err(e) => e, - }; - - R::relax(); - } - } -} - -impl<'rwlock, T: ?Sized, R> RwLockUpgradableGuard<'rwlock, T, R> { - #[inline(always)] - fn try_upgrade_internal(self, strong: bool) -> Result, Self> { - if compare_exchange( - &self.inner.lock, - UPGRADED, - WRITER, - Ordering::Acquire, - Ordering::Relaxed, - strong, - ) - .is_ok() - { - let inner = self.inner; - - // Forget the old guard so its destructor doesn't run (before mutably aliasing data below) - mem::forget(self); - - // Upgrade successful - Ok(RwLockWriteGuard { - phantom: PhantomData, - inner, - data: unsafe { &mut *inner.data.get() }, - }) - } else { - Err(self) - } - } - - /// Tries to upgrade an upgradeable lock guard to a writable lock guard. - /// - /// ``` - /// let mylock = spin::RwLock::new(0); - /// let upgradeable = mylock.upgradeable_read(); // Readable, but not yet writable - /// - /// match upgradeable.try_upgrade() { - /// Ok(writable) => /* upgrade successful - use writable lock guard */ (), - /// Err(upgradeable) => /* upgrade unsuccessful */ (), - /// }; - /// ``` - #[inline] - pub fn try_upgrade(self) -> Result, Self> { - self.try_upgrade_internal(true) - } - - #[inline] - /// Downgrades the upgradeable lock guard to a readable, shared lock guard. Cannot fail and is guaranteed not to spin. - /// - /// ``` - /// let mylock = spin::RwLock::new(1); - /// - /// let upgradeable = mylock.upgradeable_read(); - /// assert!(mylock.try_read().is_none()); - /// assert_eq!(*upgradeable, 1); - /// - /// let readable = upgradeable.downgrade(); // This is guaranteed not to spin - /// assert!(mylock.try_read().is_some()); - /// assert_eq!(*readable, 1); - /// ``` - pub fn downgrade(self) -> RwLockReadGuard<'rwlock, T> { - // Reserve the read guard for ourselves - self.inner.acquire_reader(); - - let inner = self.inner; - - // Dropping self removes the UPGRADED bit - mem::drop(self); - - RwLockReadGuard { - lock: &inner.lock, - data: unsafe { &*inner.data.get() }, - } - } - - /// Leak the lock guard, yielding a reference to the underlying data. - /// - /// Note that this function will permanently lock the original lock. - /// - /// ``` - /// let mylock = spin::RwLock::new(0); - /// - /// let data: &i32 = spin::RwLockUpgradableGuard::leak(mylock.upgradeable_read()); - /// - /// assert_eq!(*data, 0); - /// ``` - #[inline] - pub fn leak(this: Self) -> &'rwlock T { - let this = ManuallyDrop::new(this); - // Safety: We know statically that only we are referencing data - unsafe { &*this.data } - } -} - -impl<'rwlock, T: ?Sized + fmt::Debug, R> fmt::Debug for RwLockUpgradableGuard<'rwlock, T, R> { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - fmt::Debug::fmt(&**self, f) - } -} - -impl<'rwlock, T: ?Sized + fmt::Display, R> fmt::Display for RwLockUpgradableGuard<'rwlock, T, R> { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - fmt::Display::fmt(&**self, f) - } -} - -impl<'rwlock, T: ?Sized, R> RwLockWriteGuard<'rwlock, T, R> { - /// Downgrades the writable lock guard to a readable, shared lock guard. Cannot fail and is guaranteed not to spin. - /// - /// ``` - /// let mylock = spin::RwLock::new(0); - /// - /// let mut writable = mylock.write(); - /// *writable = 1; - /// - /// let readable = writable.downgrade(); // This is guaranteed not to spin - /// # let readable_2 = mylock.try_read().unwrap(); - /// assert_eq!(*readable, 1); - /// ``` - #[inline] - pub fn downgrade(self) -> RwLockReadGuard<'rwlock, T> { - // Reserve the read guard for ourselves - self.inner.acquire_reader(); - - let inner = self.inner; - - // Dropping self removes the UPGRADED bit - mem::drop(self); - - RwLockReadGuard { - lock: &inner.lock, - data: unsafe { &*inner.data.get() }, - } - } - - /// Downgrades the writable lock guard to an upgradable, shared lock guard. Cannot fail and is guaranteed not to spin. - /// - /// ``` - /// let mylock = spin::RwLock::new(0); - /// - /// let mut writable = mylock.write(); - /// *writable = 1; - /// - /// let readable = writable.downgrade_to_upgradeable(); // This is guaranteed not to spin - /// assert_eq!(*readable, 1); - /// ``` - #[inline] - pub fn downgrade_to_upgradeable(self) -> RwLockUpgradableGuard<'rwlock, T, R> { - debug_assert_eq!( - self.inner.lock.load(Ordering::Acquire) & (WRITER | UPGRADED), - WRITER - ); - - // Reserve the read guard for ourselves - self.inner.lock.store(UPGRADED, Ordering::Release); - - let inner = self.inner; - - // Dropping self removes the UPGRADED bit - mem::forget(self); - - RwLockUpgradableGuard { - phantom: PhantomData, - inner, - data: unsafe { &*inner.data.get() }, - } - } - - /// Leak the lock guard, yielding a mutable reference to the underlying data. - /// - /// Note that this function will permanently lock the original lock. - /// - /// ``` - /// let mylock = spin::RwLock::new(0); - /// - /// let data: &mut i32 = spin::RwLockWriteGuard::leak(mylock.write()); - /// - /// *data = 1; - /// assert_eq!(*data, 1); - /// ``` - #[inline] - pub fn leak(this: Self) -> &'rwlock mut T { - let mut this = ManuallyDrop::new(this); - // Safety: We know statically that only we are referencing data - unsafe { &mut *this.data } - } -} - -impl<'rwlock, T: ?Sized + fmt::Debug, R> fmt::Debug for RwLockWriteGuard<'rwlock, T, R> { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - fmt::Debug::fmt(&**self, f) - } -} - -impl<'rwlock, T: ?Sized + fmt::Display, R> fmt::Display for RwLockWriteGuard<'rwlock, T, R> { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - fmt::Display::fmt(&**self, f) - } -} - -impl<'rwlock, T: ?Sized> Deref for RwLockReadGuard<'rwlock, T> { - type Target = T; - - fn deref(&self) -> &T { - // Safety: We know statically that only we are referencing data - unsafe { &*self.data } - } -} - -impl<'rwlock, T: ?Sized, R> Deref for RwLockUpgradableGuard<'rwlock, T, R> { - type Target = T; - - fn deref(&self) -> &T { - // Safety: We know statically that only we are referencing data - unsafe { &*self.data } - } -} - -impl<'rwlock, T: ?Sized, R> Deref for RwLockWriteGuard<'rwlock, T, R> { - type Target = T; - - fn deref(&self) -> &T { - // Safety: We know statically that only we are referencing data - unsafe { &*self.data } - } -} - -impl<'rwlock, T: ?Sized, R> DerefMut for RwLockWriteGuard<'rwlock, T, R> { - fn deref_mut(&mut self) -> &mut T { - // Safety: We know statically that only we are referencing data - unsafe { &mut *self.data } - } -} - -impl<'rwlock, T: ?Sized> Drop for RwLockReadGuard<'rwlock, T> { - fn drop(&mut self) { - debug_assert!(self.lock.load(Ordering::Relaxed) & !(WRITER | UPGRADED) > 0); - self.lock.fetch_sub(READER, Ordering::Release); - } -} - -impl<'rwlock, T: ?Sized, R> Drop for RwLockUpgradableGuard<'rwlock, T, R> { - fn drop(&mut self) { - debug_assert_eq!( - self.inner.lock.load(Ordering::Relaxed) & (WRITER | UPGRADED), - UPGRADED - ); - self.inner.lock.fetch_sub(UPGRADED, Ordering::AcqRel); - } -} - -impl<'rwlock, T: ?Sized, R> Drop for RwLockWriteGuard<'rwlock, T, R> { - fn drop(&mut self) { - debug_assert_eq!(self.inner.lock.load(Ordering::Relaxed) & WRITER, WRITER); - - // Writer is responsible for clearing both WRITER and UPGRADED bits. - // The UPGRADED bit may be set if an upgradeable lock attempts an upgrade while this lock is held. - self.inner - .lock - .fetch_and(!(WRITER | UPGRADED), Ordering::Release); - } -} - -#[inline(always)] -fn compare_exchange( - atomic: &AtomicUsize, - current: usize, - new: usize, - success: Ordering, - failure: Ordering, - strong: bool, -) -> Result { - if strong { - atomic.compare_exchange(current, new, success, failure) - } else { - atomic.compare_exchange_weak(current, new, success, failure) - } -} - -#[cfg(feature = "lock_api")] -unsafe impl lock_api_crate::RawRwLock for RwLock<(), R> { - type GuardMarker = lock_api_crate::GuardSend; - - const INIT: Self = Self::new(()); - - #[inline(always)] - fn lock_exclusive(&self) { - // Prevent guard destructor running - core::mem::forget(self.write()); - } - - #[inline(always)] - fn try_lock_exclusive(&self) -> bool { - // Prevent guard destructor running - self.try_write().map(|g| core::mem::forget(g)).is_some() - } - - #[inline(always)] - unsafe fn unlock_exclusive(&self) { - drop(RwLockWriteGuard { - inner: self, - data: &mut (), - phantom: PhantomData, - }); - } - - #[inline(always)] - fn lock_shared(&self) { - // Prevent guard destructor running - core::mem::forget(self.read()); - } - - #[inline(always)] - fn try_lock_shared(&self) -> bool { - // Prevent guard destructor running - self.try_read().map(|g| core::mem::forget(g)).is_some() - } - - #[inline(always)] - unsafe fn unlock_shared(&self) { - drop(RwLockReadGuard { - lock: &self.lock, - data: &(), - }); - } - - #[inline(always)] - fn is_locked(&self) -> bool { - self.lock.load(Ordering::Relaxed) != 0 - } -} - -#[cfg(feature = "lock_api")] -unsafe impl lock_api_crate::RawRwLockUpgrade for RwLock<(), R> { - #[inline(always)] - fn lock_upgradable(&self) { - // Prevent guard destructor running - core::mem::forget(self.upgradeable_read()); - } - - #[inline(always)] - fn try_lock_upgradable(&self) -> bool { - // Prevent guard destructor running - self.try_upgradeable_read() - .map(|g| core::mem::forget(g)) - .is_some() - } - - #[inline(always)] - unsafe fn unlock_upgradable(&self) { - drop(RwLockUpgradableGuard { - inner: self, - data: &(), - phantom: PhantomData, - }); - } - - #[inline(always)] - unsafe fn upgrade(&self) { - let tmp_guard = RwLockUpgradableGuard { - inner: self, - data: &(), - phantom: PhantomData, - }; - core::mem::forget(tmp_guard.upgrade()); - } - - #[inline(always)] - unsafe fn try_upgrade(&self) -> bool { - let tmp_guard = RwLockUpgradableGuard { - inner: self, - data: &(), - phantom: PhantomData, - }; - tmp_guard - .try_upgrade() - .map(|g| core::mem::forget(g)) - .is_ok() - } -} - -#[cfg(feature = "lock_api")] -unsafe impl lock_api_crate::RawRwLockDowngrade for RwLock<(), R> { - unsafe fn downgrade(&self) { - let tmp_guard = RwLockWriteGuard { - inner: self, - data: &mut (), - phantom: PhantomData, - }; - core::mem::forget(tmp_guard.downgrade()); - } -} - -#[cfg(feature = "lock_api1")] -unsafe impl lock_api::RawRwLockUpgradeDowngrade for RwLock<()> { - unsafe fn downgrade_upgradable(&self) { - let tmp_guard = RwLockUpgradableGuard { - inner: self, - data: &(), - phantom: PhantomData, - }; - core::mem::forget(tmp_guard.downgrade()); - } - - unsafe fn downgrade_to_upgradable(&self) { - let tmp_guard = RwLockWriteGuard { - inner: self, - data: &mut (), - phantom: PhantomData, - }; - core::mem::forget(tmp_guard.downgrade_to_upgradeable()); - } -} - -#[cfg(test)] -mod tests { - use std::prelude::v1::*; - - use std::sync::atomic::{AtomicUsize, Ordering}; - use std::sync::mpsc::channel; - use std::sync::Arc; - use std::thread; - - type RwLock = super::RwLock; - - #[derive(Eq, PartialEq, Debug)] - struct NonCopy(i32); - - #[test] - fn smoke() { - let l = RwLock::new(()); - drop(l.read()); - drop(l.write()); - drop((l.read(), l.read())); - drop(l.write()); - } - - // TODO: needs RNG - //#[test] - //fn frob() { - // static R: RwLock = RwLock::new(); - // const N: usize = 10; - // const M: usize = 1000; - // - // let (tx, rx) = channel::<()>(); - // for _ in 0..N { - // let tx = tx.clone(); - // thread::spawn(move|| { - // let mut rng = rand::thread_rng(); - // for _ in 0..M { - // if rng.gen_weighted_bool(N) { - // drop(R.write()); - // } else { - // drop(R.read()); - // } - // } - // drop(tx); - // }); - // } - // drop(tx); - // let _ = rx.recv(); - // unsafe { R.destroy(); } - //} - - #[test] - fn test_rw_arc() { - let arc = Arc::new(RwLock::new(0)); - let arc2 = arc.clone(); - let (tx, rx) = channel(); - - let t = thread::spawn(move || { - let mut lock = arc2.write(); - for _ in 0..10 { - let tmp = *lock; - *lock = -1; - thread::yield_now(); - *lock = tmp + 1; - } - tx.send(()).unwrap(); - }); - - // Readers try to catch the writer in the act - let mut children = Vec::new(); - for _ in 0..5 { - let arc3 = arc.clone(); - children.push(thread::spawn(move || { - let lock = arc3.read(); - assert!(*lock >= 0); - })); - } - - // Wait for children to pass their asserts - for r in children { - assert!(r.join().is_ok()); - } - - // Wait for writer to finish - rx.recv().unwrap(); - let lock = arc.read(); - assert_eq!(*lock, 10); - - assert!(t.join().is_ok()); - } - - #[test] - fn test_rw_access_in_unwind() { - let arc = Arc::new(RwLock::new(1)); - let arc2 = arc.clone(); - let _ = thread::spawn(move || -> () { - struct Unwinder { - i: Arc>, - } - impl Drop for Unwinder { - fn drop(&mut self) { - let mut lock = self.i.write(); - *lock += 1; - } - } - let _u = Unwinder { i: arc2 }; - panic!(); - }) - .join(); - let lock = arc.read(); - assert_eq!(*lock, 2); - } - - #[test] - fn test_rwlock_unsized() { - let rw: &RwLock<[i32]> = &RwLock::new([1, 2, 3]); - { - let b = &mut *rw.write(); - b[0] = 4; - b[2] = 5; - } - let comp: &[i32] = &[4, 2, 5]; - assert_eq!(&*rw.read(), comp); - } - - #[test] - fn test_rwlock_try_write() { - use std::mem::drop; - - let lock = RwLock::new(0isize); - let read_guard = lock.read(); - - let write_result = lock.try_write(); - match write_result { - None => (), - Some(_) => assert!( - false, - "try_write should not succeed while read_guard is in scope" - ), - } - - drop(read_guard); - } - - #[test] - fn test_rw_try_read() { - let m = RwLock::new(0); - ::std::mem::forget(m.write()); - assert!(m.try_read().is_none()); - } - - #[test] - fn test_into_inner() { - let m = RwLock::new(NonCopy(10)); - assert_eq!(m.into_inner(), NonCopy(10)); - } - - #[test] - fn test_into_inner_drop() { - struct Foo(Arc); - impl Drop for Foo { - fn drop(&mut self) { - self.0.fetch_add(1, Ordering::SeqCst); - } - } - let num_drops = Arc::new(AtomicUsize::new(0)); - let m = RwLock::new(Foo(num_drops.clone())); - assert_eq!(num_drops.load(Ordering::SeqCst), 0); - { - let _inner = m.into_inner(); - assert_eq!(num_drops.load(Ordering::SeqCst), 0); - } - assert_eq!(num_drops.load(Ordering::SeqCst), 1); - } - - #[test] - fn test_force_read_decrement() { - let m = RwLock::new(()); - ::std::mem::forget(m.read()); - ::std::mem::forget(m.read()); - ::std::mem::forget(m.read()); - assert!(m.try_write().is_none()); - unsafe { - m.force_read_decrement(); - m.force_read_decrement(); - } - assert!(m.try_write().is_none()); - unsafe { - m.force_read_decrement(); - } - assert!(m.try_write().is_some()); - } - - #[test] - fn test_force_write_unlock() { - let m = RwLock::new(()); - ::std::mem::forget(m.write()); - assert!(m.try_read().is_none()); - unsafe { - m.force_write_unlock(); - } - assert!(m.try_read().is_some()); - } - - #[test] - fn test_upgrade_downgrade() { - let m = RwLock::new(()); - { - let _r = m.read(); - let upg = m.try_upgradeable_read().unwrap(); - assert!(m.try_read().is_none()); - assert!(m.try_write().is_none()); - assert!(upg.try_upgrade().is_err()); - } - { - let w = m.write(); - assert!(m.try_upgradeable_read().is_none()); - let _r = w.downgrade(); - assert!(m.try_upgradeable_read().is_some()); - assert!(m.try_read().is_some()); - assert!(m.try_write().is_none()); - } - { - let _u = m.upgradeable_read(); - assert!(m.try_upgradeable_read().is_none()); - } - - assert!(m.try_upgradeable_read().unwrap().try_upgrade().is_ok()); - } -} diff --git a/third-party/vendor/syn/.cargo-checksum.json b/third-party/vendor/syn/.cargo-checksum.json deleted file mode 100644 index 27e4b5ca..00000000 --- a/third-party/vendor/syn/.cargo-checksum.json +++ /dev/null @@ -1 +0,0 @@ -{"files":{"Cargo.toml":"139a7e42e4c95f9730d4dfe05dd5e09ee59f713eacc310921a61d9fdfc0bdce0","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"23f18e03dc49df91622fe2a76176497404e46ced8a715d9d2b67a7446571cca3","README.md":"ea9f2b6340b302b5608d2bedcda7e2d707f3eaebf4cc983c02d55071ead7096f","benches/file.rs":"3d737ef3878f6e242b003af9bd539e565f98439a12ee44d9548d84e3fdd7af0c","benches/rust.rs":"11ac9fe898a7bf1bd63e8a8cc9c08bd795b01f0248215cff99afaaf28ce87fab","build.rs":"b815649fd2929d3debd93a58f5da2fb8eba506047a6a5ba538347305828a87b0","src/attr.rs":"234d9cebe2c5e92cd0f5e1117bf5755037e2e905788a337000a65d4bd82b63aa","src/await.rs":"8aa22e3c201cb2bdb6b4817fa00901f308ab06817607aa7b884c58c957705969","src/bigint.rs":"efc7f64959980653d73fe4f8bc2a3a2904dc05f45b02c6dc15cd316fa3d7c338","src/buffer.rs":"4d15f35273d485261be4f1a765ae03abc1daee9fc9dac5fb4f9b624d6b22cb58","src/custom_keyword.rs":"5c706fc3611e73d16b8c019d7ecb848a86b1ccfcd9e556f80bb6e6a4abe058a8","src/custom_punctuation.rs":"8a666298e774b0d326642f0f73284f6677d0d0a7c9e4a712c9c98d010b4d8a2c","src/data.rs":"75d2c2b5d6a01bf8a6fa2845e41663d8045a78b4b191f1a1bd7c93619d20017a","src/derive.rs":"ee24a202be2d36ccdff576dd9cd765e94b33ef2286946e6725d75b08e777d462","src/discouraged.rs":"6c6a9298f8d24f578da119557bc588f3bd928f7b79fca27d6bdfe3e786dd005f","src/drops.rs":"013385f1dd95663f1afab41abc1e2eea04181998644828935ca564c74d6462ae","src/error.rs":"b30e738fdab7d10e126350e09f7ad907bf4dc14e684b9ed9eeea001c7ee356e0","src/export.rs":"0cf50d70c32d5fddba8b1193032df62e560237c113df3e86ba26b565cc82838e","src/expr.rs":"5eea3828f3291b0ce5463ed5f0c23fc8a39aeceae68a3247ae02ae467dd35a98","src/ext.rs":"1f648cff1d705a1cea64b32b77482b97a82d2fe0aaf63b40cade91e5c02dc969","src/file.rs":"f86697655222ae294215114f4eae8e6b0b5e2a935d6c479ff8f8f889c4efd2e2","src/gen/clone.rs":"76e89fe155fedf43bc4a252af7e35319b82ce455f584bad8698fdc3f9b7f5d4e","src/gen/debug.rs":"4b05e474e864ce6bf1a5a6ab48ee6c0ecdf41a0d750237990cf2e31963bc1208","src/gen/eq.rs":"79f84836fdcd5cfa352f38055dab7c3246c7757650946c1c701234b11021652a","src/gen/fold.rs":"fcd6a05c8c8e0c36e7ede8593002528b553c8b648fbed452106fd6a8a8c9212a","src/gen/hash.rs":"575e8beae303c1eabda12bf76cbd82672268c502a8ebb8517aab18b40fdbc44e","src/gen/visit.rs":"ced9f6c17d2b3eb3553faab710cb2b3d44d6bca7d1862c8c5da09c3d45debecb","src/gen/visit_mut.rs":"966ea340c53461bf8a1c6bed3c882e4ab8b8907fd18ac35531266f7891ae5f46","src/gen_helper.rs":"ea6c66388365971db6a2fc86cbb208f7eacde77e245bc8623f27a3642a3d7741","src/generics.rs":"b81ce0d3ea0f7accef4590d5181cecc4589395865abaea60b0470da727f17340","src/group.rs":"166f0fbb365471ffa3e4f554b72c2b460cbf7e3a1f9bec6c01ef6bbbcd751041","src/ident.rs":"2443e43561abea7eea577b141422258237a663499c839923d8a5ca6fea2470db","src/item.rs":"419c4d6135a7ca7b8f94b5ba038b6af8fcb3939ae807153a19e3c82e9b01e0b7","src/lib.rs":"de155fed49dffb1756ca8b76d82209fe8bc80c4dda6684f669e98835147869a5","src/lifetime.rs":"b18862ef1e690037a4f308ea897debad7bc5038584e3b26c6d8809752ea0e3c2","src/lit.rs":"667d90787fefac4d25e88509799e8423b9f87125027740c30644dd28adfab95d","src/lookahead.rs":"e2c2b6d55906421e83dab51463b58bc6dcb582f1bff9303c8b62afefb8d71e5f","src/mac.rs":"004cb89f9697564f6c9ee837e08ead68463ef946fb4c13c6c105adf2ba364b2b","src/macros.rs":"936f503c2fcde602f05220954ecaf87625c6138d0af13d33d56c7b6530110084","src/op.rs":"9d499022902743a6a0a19223b356449a979b90e60552d0446497d72750e646a4","src/parse.rs":"7b2f8caddf25a5734cbcdf7cbf043cbf9afbc07b484966cd59ddfcec9f970fb3","src/parse_macro_input.rs":"a5d16859b782bb6a2754c1066468a2f1ea05b57390caa32175bb84064973be7b","src/parse_quote.rs":"d7d996f1382c68b5fbfd4b7327ce1d389cd43c3bb3c4f382a35994d0bb79d8ab","src/pat.rs":"b2de04ae6c01df50eab9d1c3908287aca8424adc2007b926c7bcf74d1f64d40a","src/path.rs":"58a4fb3b1ff76d32cfd84a3914f8cadbf55b363c1929222b362b7465385520ac","src/print.rs":"da6529c1d9d21aaf6c835f66b4e67eacb7cf91a10eb5e9a2143b49bf99b3b5e1","src/punctuated.rs":"44c29523dee76605be2531674fe21ed2f1bbd02559aac8b7a49c70af23129ca1","src/reserved.rs":"e70e028bd55cfa43e23cab4ba29e4dc53a3d91eff685ef2b6e57efc2b87a3428","src/sealed.rs":"896a495a5340eec898527f18bd4ddca408ea03ea0ee3af30074ff48deace778d","src/span.rs":"748c51c6feb223c26d3b1701f5bb98aee823666c775c98106cfa24fe29d8cec1","src/spanned.rs":"3ca016a943637653ab98e373dfb826a120f3c159867346fa38a844439944eb39","src/stmt.rs":"601a6914f1e0bf97ae0d31d474a531d195b8c251a4ded11aa8746ac0018d367b","src/thread.rs":"815eca6bd64f4eef7c447f0809e84108f5428ff50225224b373efd8fbb696874","src/token.rs":"5e423a696f80e281c322f37c87577f9fdc28607e9c007e24896a2b12da62d5ad","src/tt.rs":"32402645b6e82ef1e882945721b59b5fb7b0ee337d1972876362ecacef643d0f","src/ty.rs":"9befd22f8c8ac731b7f68008552a1335797a3ef19184190eec0e103e4ebe18a7","src/verbatim.rs":"96d4280e4556a1841b8dcb306bc35a94d18f71dceb63f3c27a4fe7f776191760","src/whitespace.rs":"e63dd0aa3d34029f17766a8b09c1a6e4479e36c552c8b7023d710a399333aace","tests/common/eq.rs":"e930fb0bdcec3e787986b56785b1db580e5a26a5131df2f2b91a6da37069de15","tests/common/mod.rs":"432ad35577f836a20b517d8c26ed994ac25fe73ef2f461c67688b61b99762015","tests/common/parse.rs":"81580f23583723f7a2a337c4d13ebc021057cd825562fb4e474caa7cc641fed9","tests/debug/gen.rs":"1b7f875344cb04a7dd3df62deac2f410a9d107c097986e68006d87465f5f5306","tests/debug/mod.rs":"3a6bb799f478101f71c84c6f1a854a58afe2f9db43c39017909346ca20262d94","tests/macros/mod.rs":"aff805b35cfd55aef6a1359ff747e4023afcb08d69d86aff4c19465d29dda088","tests/regression.rs":"86731134bfb9bb693d9a4fc62393027de80a8bf031109ea6c7ea475b1ebdde8d","tests/regression/issue1108.rs":"adcc55a42239d344da74216ed85fc14153ddd6ca4dec4872d8339604ba78c185","tests/regression/issue1235.rs":"a2266b10c3f7c7af5734817ab0a3e8b309b51e7d177b63f26e67e6b744d280b0","tests/repo/mod.rs":"159c2c4b6416d26ac42ffc35f6cb587c4c1e2b0f24de9aa42b0337a534d7d86d","tests/repo/progress.rs":"c08d0314a7f3ecf760d471f27da3cd2a500aeb9f1c8331bffb2aa648f9fabf3f","tests/test_asyncness.rs":"cff01db49d28ab23b0b258bc6c0a5cc4071be4fe7248eef344a5d79d2fb649b7","tests/test_attribute.rs":"0ffd99384e1a52ae17d9fed5c4053e411e8f9018decef07ffa621d1faa7329d8","tests/test_derive_input.rs":"62bb86aaaaf730187a46ff700a8e3b2d1a163039b109b6a483aa44ed2b6806fe","tests/test_expr.rs":"41eb343829ad36cdea40cd06d45a90765e7fe6f1e47dd550daf1b6096c3a7b44","tests/test_generics.rs":"54b7d2afc19aa6e9049585f4c8f7d3f0c29ac3bd11a2c769e9df76f18a4f5ecb","tests/test_grouping.rs":"6276c3c73bba649dec5c97904ad2492879f918bc887a2c425d095c654ca0d925","tests/test_ident.rs":"9eb53d1e21edf23e7c9e14dc74dcc2b2538e9221e19dbcc0a44e3acc2e90f3f6","tests/test_item.rs":"a3642c80066f1e7787becfd0278af90a6b7968d6c1249e25e81663aa454cfb2a","tests/test_iterators.rs":"9cf6fde17853ce7d5617e1de9ef901c47ca35c0f1c2dd668c0d0604d7b48598c","tests/test_lit.rs":"137cc9f882cca58f0f2c109535b7ad03c5a35a0aee0cbb9e98ad94710d64e265","tests/test_meta.rs":"65d4586d131f6cac66694ca5e936748ec4e7f7423af6d8da509240e6be14800b","tests/test_parse_buffer.rs":"68d857f776396d064fcc0023c37093c2fbf75ee68e8241d4014d00d1423c18e9","tests/test_parse_stream.rs":"bf1db6fab7ac396fa61012faccbe6ffbc9c3d795ed2900be75e91c5b09b0c62f","tests/test_pat.rs":"d4465f4fc3fd5d6e534ba8efabe1e0ed6da89de4ac7c96effa6bfb880c4287cf","tests/test_path.rs":"71092a5ae2c9143b92a8fe15a92d39958b3c28bd4d4275cfb2d22cbdd53ada07","tests/test_precedence.rs":"736eee861c4c7a3d7d4387d2fb1b5eced1541790d34974f72b0a5532797e73c3","tests/test_receiver.rs":"084eca59984b9a18651da52f2c4407355da3de1335916a12477652999e2d01cc","tests/test_round_trip.rs":"c3c415413d5177a728c7cbbfb7ef44aebbc6a2c821dd56695156e9e33636fd57","tests/test_shebang.rs":"f5772cadad5b56e3112cb16308b779f92bce1c3a48091fc9933deb2276a69331","tests/test_should_parse.rs":"1d3535698a446e2755bfc360676bdb161841a1f454cdef6e7556c6d06a95c89d","tests/test_size.rs":"6720d55569808244ab011364c39931f06aa509cd05f98ab908b0670e8501b3c8","tests/test_stmt.rs":"0601fc32131b5501dfcdc4b4248d46bf21e0a98a49eb19439e1a46869dfb30b7","tests/test_token_trees.rs":"43e56a701817e3c3bfd0cae54a457dd7a38ccb3ca19da41e2b995fdf20e6ed18","tests/test_ty.rs":"f71d7f7f1c038aaabea8dd4c03c0d5752c76d570f8b4885a81659825bbb4d576","tests/test_visibility.rs":"7456fcb3a6634db509748aededff9c2d8b242d511a3e5ee3022e40b232892704","tests/zzz_stable.rs":"2a862e59cb446235ed99aec0e6ada8e16d3ecc30229b29d825b7c0bbc2602989"},"package":"72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237"} \ No newline at end of file diff --git a/third-party/vendor/syn/Cargo.toml b/third-party/vendor/syn/Cargo.toml deleted file mode 100644 index cd26cef0..00000000 --- a/third-party/vendor/syn/Cargo.toml +++ /dev/null @@ -1,147 +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 are reading this file be aware that the original Cargo.toml -# will likely look very different (and much more reasonable). -# See Cargo.toml.orig for the original contents. - -[package] -edition = "2018" -rust-version = "1.31" -name = "syn" -version = "1.0.109" -authors = ["David Tolnay "] -include = [ - "/benches/**", - "/build.rs", - "/Cargo.toml", - "/LICENSE-APACHE", - "/LICENSE-MIT", - "/README.md", - "/src/**", - "/tests/**", -] -description = "Parser for Rust source code" -documentation = "https://docs.rs/syn" -readme = "README.md" -keywords = [ - "macros", - "syn", -] -categories = [ - "development-tools::procedural-macro-helpers", - "parser-implementations", -] -license = "MIT OR Apache-2.0" -repository = "https://github.com/dtolnay/syn" - -[package.metadata.docs.rs] -all-features = true -rustdoc-args = [ - "--cfg", - "doc_cfg", -] -targets = ["x86_64-unknown-linux-gnu"] - -[package.metadata.playground] -features = [ - "full", - "visit", - "visit-mut", - "fold", - "extra-traits", -] - -[lib] -doc-scrape-examples = false - -[[bench]] -name = "rust" -harness = false -required-features = [ - "full", - "parsing", -] - -[[bench]] -name = "file" -required-features = [ - "full", - "parsing", -] - -[dependencies.proc-macro2] -version = "1.0.46" -default-features = false - -[dependencies.quote] -version = "1.0" -optional = true -default-features = false - -[dependencies.unicode-ident] -version = "1.0" - -[dev-dependencies.anyhow] -version = "1.0" - -[dev-dependencies.automod] -version = "1.0" - -[dev-dependencies.flate2] -version = "1.0" - -[dev-dependencies.insta] -version = "1.0" - -[dev-dependencies.rayon] -version = "1.0" - -[dev-dependencies.ref-cast] -version = "1.0" - -[dev-dependencies.regex] -version = "1.0" - -[dev-dependencies.reqwest] -version = "0.11" -features = ["blocking"] - -[dev-dependencies.syn-test-suite] -version = "0" - -[dev-dependencies.tar] -version = "0.4.16" - -[dev-dependencies.termcolor] -version = "1.0" - -[dev-dependencies.walkdir] -version = "2.1" - -[features] -clone-impls = [] -default = [ - "derive", - "parsing", - "printing", - "clone-impls", - "proc-macro", -] -derive = [] -extra-traits = [] -fold = [] -full = [] -parsing = [] -printing = ["quote"] -proc-macro = [ - "proc-macro2/proc-macro", - "quote/proc-macro", -] -test = ["syn-test-suite/all-features"] -visit = [] -visit-mut = [] diff --git a/third-party/vendor/syn/LICENSE-APACHE b/third-party/vendor/syn/LICENSE-APACHE deleted file mode 100644 index 16fe87b0..00000000 --- a/third-party/vendor/syn/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. diff --git a/third-party/vendor/syn/LICENSE-MIT b/third-party/vendor/syn/LICENSE-MIT deleted file mode 100644 index 31aa7938..00000000 --- a/third-party/vendor/syn/LICENSE-MIT +++ /dev/null @@ -1,23 +0,0 @@ -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. diff --git a/third-party/vendor/syn/README.md b/third-party/vendor/syn/README.md deleted file mode 100644 index eeef83dd..00000000 --- a/third-party/vendor/syn/README.md +++ /dev/null @@ -1,285 +0,0 @@ -Parser for Rust source code -=========================== - -[github](https://github.com/dtolnay/syn) -[crates.io](https://crates.io/crates/syn) -[docs.rs](https://docs.rs/syn) -[build status](https://github.com/dtolnay/syn/actions?query=branch%3Amaster) - -Syn is a parsing library for parsing a stream of Rust tokens into a syntax tree -of Rust source code. - -Currently this library is geared toward use in Rust procedural macros, but -contains some APIs that may be useful more generally. - -- **Data structures** — Syn provides a complete syntax tree that can represent - any valid Rust source code. The syntax tree is rooted at [`syn::File`] which - represents a full source file, but there are other entry points that may be - useful to procedural macros including [`syn::Item`], [`syn::Expr`] and - [`syn::Type`]. - -- **Derives** — Of particular interest to derive macros is [`syn::DeriveInput`] - which is any of the three legal input items to a derive macro. An example - below shows using this type in a library that can derive implementations of a - user-defined trait. - -- **Parsing** — Parsing in Syn is built around [parser functions] with the - signature `fn(ParseStream) -> Result`. Every syntax tree node defined by - Syn is individually parsable and may be used as a building block for custom - syntaxes, or you may dream up your own brand new syntax without involving any - of our syntax tree types. - -- **Location information** — Every token parsed by Syn is associated with a - `Span` that tracks line and column information back to the source of that - token. These spans allow a procedural macro to display detailed error messages - pointing to all the right places in the user's code. There is an example of - this below. - -- **Feature flags** — Functionality is aggressively feature gated so your - procedural macros enable only what they need, and do not pay in compile time - for all the rest. - -[`syn::File`]: https://docs.rs/syn/1.0/syn/struct.File.html -[`syn::Item`]: https://docs.rs/syn/1.0/syn/enum.Item.html -[`syn::Expr`]: https://docs.rs/syn/1.0/syn/enum.Expr.html -[`syn::Type`]: https://docs.rs/syn/1.0/syn/enum.Type.html -[`syn::DeriveInput`]: https://docs.rs/syn/1.0/syn/struct.DeriveInput.html -[parser functions]: https://docs.rs/syn/1.0/syn/parse/index.html - -*Version requirement: Syn supports rustc 1.31 and up.* - -[*Release notes*](https://github.com/dtolnay/syn/releases) - -
- -## Resources - -The best way to learn about procedural macros is by writing some. Consider -working through [this procedural macro workshop][workshop] to get familiar with -the different types of procedural macros. The workshop contains relevant links -into the Syn documentation as you work through each project. - -[workshop]: https://github.com/dtolnay/proc-macro-workshop - -
- -## Example of a derive macro - -The canonical derive macro using Syn looks like this. We write an ordinary Rust -function tagged with a `proc_macro_derive` attribute and the name of the trait -we are deriving. Any time that derive appears in the user's code, the Rust -compiler passes their data structure as tokens into our macro. We get to execute -arbitrary Rust code to figure out what to do with those tokens, then hand some -tokens back to the compiler to compile into the user's crate. - -[`TokenStream`]: https://doc.rust-lang.org/proc_macro/struct.TokenStream.html - -```toml -[dependencies] -syn = "1.0" -quote = "1.0" - -[lib] -proc-macro = true -``` - -```rust -use proc_macro::TokenStream; -use quote::quote; -use syn::{parse_macro_input, DeriveInput}; - -#[proc_macro_derive(MyMacro)] -pub fn my_macro(input: TokenStream) -> TokenStream { - // Parse the input tokens into a syntax tree - let input = parse_macro_input!(input as DeriveInput); - - // Build the output, possibly using quasi-quotation - let expanded = quote! { - // ... - }; - - // Hand the output tokens back to the compiler - TokenStream::from(expanded) -} -``` - -The [`heapsize`] example directory shows a complete working implementation of a -derive macro. It works on any Rust compiler 1.31+. The example derives a -`HeapSize` trait which computes an estimate of the amount of heap memory owned -by a value. - -[`heapsize`]: examples/heapsize - -```rust -pub trait HeapSize { - /// Total number of bytes of heap memory owned by `self`. - fn heap_size_of_children(&self) -> usize; -} -``` - -The derive macro allows users to write `#[derive(HeapSize)]` on data structures -in their program. - -```rust -#[derive(HeapSize)] -struct Demo<'a, T: ?Sized> { - a: Box, - b: u8, - c: &'a str, - d: String, -} -``` - -
- -## Spans and error reporting - -The token-based procedural macro API provides great control over where the -compiler's error messages are displayed in user code. Consider the error the -user sees if one of their field types does not implement `HeapSize`. - -```rust -#[derive(HeapSize)] -struct Broken { - ok: String, - bad: std::thread::Thread, -} -``` - -By tracking span information all the way through the expansion of a procedural -macro as shown in the `heapsize` example, token-based macros in Syn are able to -trigger errors that directly pinpoint the source of the problem. - -```console -error[E0277]: the trait bound `std::thread::Thread: HeapSize` is not satisfied - --> src/main.rs:7:5 - | -7 | bad: std::thread::Thread, - | ^^^^^^^^^^^^^^^^^^^^^^^^ the trait `HeapSize` is not implemented for `std::thread::Thread` -``` - -
- -## Parsing a custom syntax - -The [`lazy-static`] example directory shows the implementation of a -`functionlike!(...)` procedural macro in which the input tokens are parsed using -Syn's parsing API. - -[`lazy-static`]: examples/lazy-static - -The example reimplements the popular `lazy_static` crate from crates.io as a -procedural macro. - -```rust -lazy_static! { - static ref USERNAME: Regex = Regex::new("^[a-z0-9_-]{3,16}$").unwrap(); -} -``` - -The implementation shows how to trigger custom warnings and error messages on -the macro input. - -```console -warning: come on, pick a more creative name - --> src/main.rs:10:16 - | -10 | static ref FOO: String = "lazy_static".to_owned(); - | ^^^ -``` - -
- -## Testing - -When testing macros, we often care not just that the macro can be used -successfully but also that when the macro is provided with invalid input it -produces maximally helpful error messages. Consider using the [`trybuild`] crate -to write tests for errors that are emitted by your macro or errors detected by -the Rust compiler in the expanded code following misuse of the macro. Such tests -help avoid regressions from later refactors that mistakenly make an error no -longer trigger or be less helpful than it used to be. - -[`trybuild`]: https://github.com/dtolnay/trybuild - -
- -## Debugging - -When developing a procedural macro it can be helpful to look at what the -generated code looks like. Use `cargo rustc -- -Zunstable-options ---pretty=expanded` or the [`cargo expand`] subcommand. - -[`cargo expand`]: https://github.com/dtolnay/cargo-expand - -To show the expanded code for some crate that uses your procedural macro, run -`cargo expand` from that crate. To show the expanded code for one of your own -test cases, run `cargo expand --test the_test_case` where the last argument is -the name of the test file without the `.rs` extension. - -This write-up by Brandon W Maister discusses debugging in more detail: -[Debugging Rust's new Custom Derive system][debugging]. - -[debugging]: https://quodlibetor.github.io/posts/debugging-rusts-new-custom-derive-system/ - -
- -## Optional features - -Syn puts a lot of functionality behind optional features in order to optimize -compile time for the most common use cases. The following features are -available. - -- **`derive`** *(enabled by default)* — Data structures for representing the - possible input to a derive macro, including structs and enums and types. -- **`full`** — Data structures for representing the syntax tree of all valid - Rust source code, including items and expressions. -- **`parsing`** *(enabled by default)* — Ability to parse input tokens into a - syntax tree node of a chosen type. -- **`printing`** *(enabled by default)* — Ability to print a syntax tree node as - tokens of Rust source code. -- **`visit`** — Trait for traversing a syntax tree. -- **`visit-mut`** — Trait for traversing and mutating in place a syntax tree. -- **`fold`** — Trait for transforming an owned syntax tree. -- **`clone-impls`** *(enabled by default)* — Clone impls for all syntax tree - types. -- **`extra-traits`** — Debug, Eq, PartialEq, Hash impls for all syntax tree - types. -- **`proc-macro`** *(enabled by default)* — Runtime dependency on the dynamic - library libproc_macro from rustc toolchain. - -
- -## Proc macro shim - -Syn operates on the token representation provided by the [proc-macro2] crate -from crates.io rather than using the compiler's built in proc-macro crate -directly. This enables code using Syn to execute outside of the context of a -procedural macro, such as in unit tests or build.rs, and we avoid needing -incompatible ecosystems for proc macros vs non-macro use cases. - -In general all of your code should be written against proc-macro2 rather than -proc-macro. The one exception is in the signatures of procedural macro entry -points, which are required by the language to use `proc_macro::TokenStream`. - -The proc-macro2 crate will automatically detect and use the compiler's data -structures when a procedural macro is active. - -[proc-macro2]: https://docs.rs/proc-macro2/1.0/proc_macro2/ - -
- -#### License - - -Licensed under either of Apache License, Version -2.0 or MIT license at your option. - - -
- - -Unless you explicitly state otherwise, any contribution intentionally submitted -for inclusion in this crate by you, as defined in the Apache-2.0 license, shall -be dual licensed as above, without any additional terms or conditions. - diff --git a/third-party/vendor/syn/benches/file.rs b/third-party/vendor/syn/benches/file.rs deleted file mode 100644 index bd4a247d..00000000 --- a/third-party/vendor/syn/benches/file.rs +++ /dev/null @@ -1,55 +0,0 @@ -// $ cargo bench --features full,test --bench file - -#![feature(rustc_private, test)] -#![recursion_limit = "1024"] -#![allow( - clippy::items_after_statements, - clippy::missing_panics_doc, - clippy::must_use_candidate -)] - -extern crate test; - -#[macro_use] -#[path = "../tests/macros/mod.rs"] -mod macros; - -#[path = "../tests/common/mod.rs"] -mod common; -#[path = "../tests/repo/mod.rs"] -pub mod repo; - -use proc_macro2::{Span, TokenStream}; -use std::fs; -use std::str::FromStr; -use syn::parse::{ParseStream, Parser}; -use test::Bencher; - -const FILE: &str = "tests/rust/library/core/src/str/mod.rs"; - -fn get_tokens() -> TokenStream { - repo::clone_rust(); - let content = fs::read_to_string(FILE).unwrap(); - TokenStream::from_str(&content).unwrap() -} - -#[bench] -fn baseline(b: &mut Bencher) { - let tokens = get_tokens(); - b.iter(|| drop(tokens.clone())); -} - -#[bench] -fn create_token_buffer(b: &mut Bencher) { - let tokens = get_tokens(); - fn immediate_fail(_input: ParseStream) -> syn::Result<()> { - Err(syn::Error::new(Span::call_site(), "")) - } - b.iter(|| immediate_fail.parse2(tokens.clone())); -} - -#[bench] -fn parse_file(b: &mut Bencher) { - let tokens = get_tokens(); - b.iter(|| syn::parse2::(tokens.clone())); -} diff --git a/third-party/vendor/syn/benches/rust.rs b/third-party/vendor/syn/benches/rust.rs deleted file mode 100644 index e3f8f550..00000000 --- a/third-party/vendor/syn/benches/rust.rs +++ /dev/null @@ -1,170 +0,0 @@ -// $ cargo bench --features full,test --bench rust -// -// Syn only, useful for profiling: -// $ RUSTFLAGS='--cfg syn_only' cargo build --release --features full,test --bench rust - -#![cfg_attr(not(syn_only), feature(rustc_private))] -#![recursion_limit = "1024"] -#![allow(clippy::cast_lossless, clippy::unnecessary_wraps)] - -#[macro_use] -#[path = "../tests/macros/mod.rs"] -mod macros; - -#[path = "../tests/common/mod.rs"] -mod common; -#[path = "../tests/repo/mod.rs"] -mod repo; - -use std::fs; -use std::time::{Duration, Instant}; - -#[cfg(not(syn_only))] -mod tokenstream_parse { - use proc_macro2::TokenStream; - use std::str::FromStr; - - pub fn bench(content: &str) -> Result<(), ()> { - TokenStream::from_str(content).map(drop).map_err(drop) - } -} - -mod syn_parse { - pub fn bench(content: &str) -> Result<(), ()> { - syn::parse_file(content).map(drop).map_err(drop) - } -} - -#[cfg(not(syn_only))] -mod librustc_parse { - extern crate rustc_data_structures; - extern crate rustc_error_messages; - extern crate rustc_errors; - extern crate rustc_parse; - extern crate rustc_session; - extern crate rustc_span; - - use rustc_data_structures::sync::Lrc; - use rustc_error_messages::FluentBundle; - use rustc_errors::{emitter::Emitter, translation::Translate, Diagnostic, Handler}; - use rustc_session::parse::ParseSess; - use rustc_span::source_map::{FilePathMapping, SourceMap}; - use rustc_span::{edition::Edition, FileName}; - - pub fn bench(content: &str) -> Result<(), ()> { - struct SilentEmitter; - - impl Emitter for SilentEmitter { - fn emit_diagnostic(&mut self, _diag: &Diagnostic) {} - fn source_map(&self) -> Option<&Lrc> { - None - } - } - - impl Translate for SilentEmitter { - fn fluent_bundle(&self) -> Option<&Lrc> { - None - } - fn fallback_fluent_bundle(&self) -> &FluentBundle { - panic!("silent emitter attempted to translate a diagnostic"); - } - } - - rustc_span::create_session_if_not_set_then(Edition::Edition2018, |_| { - let cm = Lrc::new(SourceMap::new(FilePathMapping::empty())); - let emitter = Box::new(SilentEmitter); - let handler = Handler::with_emitter(false, None, emitter); - let sess = ParseSess::with_span_handler(handler, cm); - if let Err(diagnostic) = rustc_parse::parse_crate_from_source_str( - FileName::Custom("bench".to_owned()), - content.to_owned(), - &sess, - ) { - diagnostic.cancel(); - return Err(()); - }; - Ok(()) - }) - } -} - -#[cfg(not(syn_only))] -mod read_from_disk { - pub fn bench(content: &str) -> Result<(), ()> { - _ = content; - Ok(()) - } -} - -fn exec(mut codepath: impl FnMut(&str) -> Result<(), ()>) -> Duration { - let begin = Instant::now(); - let mut success = 0; - let mut total = 0; - - walkdir::WalkDir::new("tests/rust/src") - .into_iter() - .filter_entry(repo::base_dir_filter) - .for_each(|entry| { - let entry = entry.unwrap(); - let path = entry.path(); - if path.is_dir() { - return; - } - let content = fs::read_to_string(path).unwrap(); - let ok = codepath(&content).is_ok(); - success += ok as usize; - total += 1; - if !ok { - eprintln!("FAIL {}", path.display()); - } - }); - - assert_eq!(success, total); - begin.elapsed() -} - -fn main() { - repo::clone_rust(); - - macro_rules! testcases { - ($($(#[$cfg:meta])* $name:ident,)*) => { - [ - $( - $(#[$cfg])* - (stringify!($name), $name::bench as fn(&str) -> Result<(), ()>), - )* - ] - }; - } - - #[cfg(not(syn_only))] - { - let mut lines = 0; - let mut files = 0; - exec(|content| { - lines += content.lines().count(); - files += 1; - Ok(()) - }); - eprintln!("\n{} lines in {} files", lines, files); - } - - for (name, f) in testcases!( - #[cfg(not(syn_only))] - read_from_disk, - #[cfg(not(syn_only))] - tokenstream_parse, - syn_parse, - #[cfg(not(syn_only))] - librustc_parse, - ) { - eprint!("{:20}", format!("{}:", name)); - let elapsed = exec(f); - eprintln!( - "elapsed={}.{:03}s", - elapsed.as_secs(), - elapsed.subsec_millis(), - ); - } - eprintln!(); -} diff --git a/third-party/vendor/syn/build.rs b/third-party/vendor/syn/build.rs deleted file mode 100644 index 1a2c077b..00000000 --- a/third-party/vendor/syn/build.rs +++ /dev/null @@ -1,51 +0,0 @@ -use std::env; -use std::process::Command; -use std::str; - -// The rustc-cfg strings below are *not* public API. Please let us know by -// opening a GitHub issue if your build environment requires some way to enable -// these cfgs other than by executing our build script. -fn main() { - let compiler = match rustc_version() { - Some(compiler) => compiler, - None => return, - }; - - if compiler.minor < 36 { - println!("cargo:rustc-cfg=syn_omit_await_from_token_macro"); - } - - if compiler.minor < 39 { - println!("cargo:rustc-cfg=syn_no_const_vec_new"); - } - - if compiler.minor < 40 { - println!("cargo:rustc-cfg=syn_no_non_exhaustive"); - } - - if compiler.minor < 56 { - println!("cargo:rustc-cfg=syn_no_negative_literal_parse"); - } - - if !compiler.nightly { - println!("cargo:rustc-cfg=syn_disable_nightly_tests"); - } -} - -struct Compiler { - minor: u32, - nightly: bool, -} - -fn rustc_version() -> Option { - let rustc = env::var_os("RUSTC")?; - let output = Command::new(rustc).arg("--version").output().ok()?; - let version = str::from_utf8(&output.stdout).ok()?; - let mut pieces = version.split('.'); - if pieces.next() != Some("rustc 1") { - return None; - } - let minor = pieces.next()?.parse().ok()?; - let nightly = version.contains("nightly") || version.ends_with("-dev"); - Some(Compiler { minor, nightly }) -} diff --git a/third-party/vendor/syn/src/attr.rs b/third-party/vendor/syn/src/attr.rs deleted file mode 100644 index bace94f4..00000000 --- a/third-party/vendor/syn/src/attr.rs +++ /dev/null @@ -1,662 +0,0 @@ -use super::*; -use crate::punctuated::Punctuated; -use proc_macro2::TokenStream; -use std::iter; -use std::slice; - -#[cfg(feature = "parsing")] -use crate::parse::{Parse, ParseBuffer, ParseStream, Parser, Result}; -#[cfg(feature = "parsing")] -use crate::punctuated::Pair; - -ast_struct! { - /// An attribute like `#[repr(transparent)]`. - /// - /// *This type is available only if Syn is built with the `"derive"` or `"full"` - /// feature.* - /// - ///
- /// - /// # Syntax - /// - /// Rust has six types of attributes. - /// - /// - Outer attributes like `#[repr(transparent)]`. These appear outside or - /// in front of the item they describe. - /// - Inner attributes like `#![feature(proc_macro)]`. These appear inside - /// of the item they describe, usually a module. - /// - Outer doc comments like `/// # Example`. - /// - Inner doc comments like `//! Please file an issue`. - /// - Outer block comments `/** # Example */`. - /// - Inner block comments `/*! Please file an issue */`. - /// - /// The `style` field of type `AttrStyle` distinguishes whether an attribute - /// is outer or inner. Doc comments and block comments are promoted to - /// attributes, as this is how they are processed by the compiler and by - /// `macro_rules!` macros. - /// - /// The `path` field gives the possibly colon-delimited path against which - /// the attribute is resolved. It is equal to `"doc"` for desugared doc - /// comments. The `tokens` field contains the rest of the attribute body as - /// tokens. - /// - /// ```text - /// #[derive(Copy)] #[crate::precondition x < 5] - /// ^^^^^^~~~~~~ ^^^^^^^^^^^^^^^^^^^ ~~~~~ - /// path tokens path tokens - /// ``` - /// - ///
- /// - /// # Parsing from tokens to Attribute - /// - /// This type does not implement the [`Parse`] trait and thus cannot be - /// parsed directly by [`ParseStream::parse`]. Instead use - /// [`ParseStream::call`] with one of the two parser functions - /// [`Attribute::parse_outer`] or [`Attribute::parse_inner`] depending on - /// which you intend to parse. - /// - /// [`Parse`]: parse::Parse - /// [`ParseStream::parse`]: parse::ParseBuffer::parse - /// [`ParseStream::call`]: parse::ParseBuffer::call - /// - /// ``` - /// use syn::{Attribute, Ident, Result, Token}; - /// use syn::parse::{Parse, ParseStream}; - /// - /// // Parses a unit struct with attributes. - /// // - /// // #[path = "s.tmpl"] - /// // struct S; - /// struct UnitStruct { - /// attrs: Vec, - /// struct_token: Token![struct], - /// name: Ident, - /// semi_token: Token![;], - /// } - /// - /// impl Parse for UnitStruct { - /// fn parse(input: ParseStream) -> Result { - /// Ok(UnitStruct { - /// attrs: input.call(Attribute::parse_outer)?, - /// struct_token: input.parse()?, - /// name: input.parse()?, - /// semi_token: input.parse()?, - /// }) - /// } - /// } - /// ``` - /// - ///


- /// - /// # Parsing from Attribute to structured arguments - /// - /// The grammar of attributes in Rust is very flexible, which makes the - /// syntax tree not that useful on its own. In particular, arguments of the - /// attribute are held in an arbitrary `tokens: TokenStream`. Macros are - /// expected to check the `path` of the attribute, decide whether they - /// recognize it, and then parse the remaining tokens according to whatever - /// grammar they wish to require for that kind of attribute. - /// - /// If the attribute you are parsing is expected to conform to the - /// conventional structured form of attribute, use [`parse_meta()`] to - /// obtain that structured representation. If the attribute follows some - /// other grammar of its own, use [`parse_args()`] to parse that into the - /// expected data structure. - /// - /// [`parse_meta()`]: Attribute::parse_meta - /// [`parse_args()`]: Attribute::parse_args - /// - ///


- /// - /// # Doc comments - /// - /// The compiler transforms doc comments, such as `/// comment` and `/*! - /// comment */`, into attributes before macros are expanded. Each comment is - /// expanded into an attribute of the form `#[doc = r"comment"]`. - /// - /// As an example, the following `mod` items are expanded identically: - /// - /// ``` - /// # use syn::{ItemMod, parse_quote}; - /// let doc: ItemMod = parse_quote! { - /// /// Single line doc comments - /// /// We write so many! - /// /** - /// * Multi-line comments... - /// * May span many lines - /// */ - /// mod example { - /// //! Of course, they can be inner too - /// /*! And fit in a single line */ - /// } - /// }; - /// let attr: ItemMod = parse_quote! { - /// #[doc = r" Single line doc comments"] - /// #[doc = r" We write so many!"] - /// #[doc = r" - /// * Multi-line comments... - /// * May span many lines - /// "] - /// mod example { - /// #![doc = r" Of course, they can be inner too"] - /// #![doc = r" And fit in a single line "] - /// } - /// }; - /// assert_eq!(doc, attr); - /// ``` - #[cfg_attr(doc_cfg, doc(cfg(any(feature = "full", feature = "derive"))))] - pub struct Attribute { - pub pound_token: Token![#], - pub style: AttrStyle, - pub bracket_token: token::Bracket, - pub path: Path, - pub tokens: TokenStream, - } -} - -impl Attribute { - /// Parses the content of the attribute, consisting of the path and tokens, - /// as a [`Meta`] if possible. - /// - /// *This function is available only if Syn is built with the `"parsing"` - /// feature.* - #[cfg(feature = "parsing")] - #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))] - pub fn parse_meta(&self) -> Result { - fn clone_ident_segment(segment: &PathSegment) -> PathSegment { - PathSegment { - ident: segment.ident.clone(), - arguments: PathArguments::None, - } - } - - let path = Path { - leading_colon: self - .path - .leading_colon - .as_ref() - .map(|colon| Token![::](colon.spans)), - segments: self - .path - .segments - .pairs() - .map(|pair| match pair { - Pair::Punctuated(seg, punct) => { - Pair::Punctuated(clone_ident_segment(seg), Token![::](punct.spans)) - } - Pair::End(seg) => Pair::End(clone_ident_segment(seg)), - }) - .collect(), - }; - - let parser = |input: ParseStream| parsing::parse_meta_after_path(path, input); - parse::Parser::parse2(parser, self.tokens.clone()) - } - - /// Parse the arguments to the attribute as a syntax tree. - /// - /// This is similar to `syn::parse2::(attr.tokens)` except that: - /// - /// - the surrounding delimiters are *not* included in the input to the - /// parser; and - /// - the error message has a more useful span when `tokens` is empty. - /// - /// ```text - /// #[my_attr(value < 5)] - /// ^^^^^^^^^ what gets parsed - /// ``` - /// - /// *This function is available only if Syn is built with the `"parsing"` - /// feature.* - #[cfg(feature = "parsing")] - #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))] - pub fn parse_args(&self) -> Result { - self.parse_args_with(T::parse) - } - - /// Parse the arguments to the attribute using the given parser. - /// - /// *This function is available only if Syn is built with the `"parsing"` - /// feature.* - #[cfg(feature = "parsing")] - #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))] - pub fn parse_args_with(&self, parser: F) -> Result { - let parser = |input: ParseStream| { - let args = enter_args(self, input)?; - parse::parse_stream(parser, &args) - }; - parser.parse2(self.tokens.clone()) - } - - /// Parses zero or more outer attributes from the stream. - /// - /// *This function is available only if Syn is built with the `"parsing"` - /// feature.* - #[cfg(feature = "parsing")] - #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))] - pub fn parse_outer(input: ParseStream) -> Result> { - let mut attrs = Vec::new(); - while input.peek(Token![#]) { - attrs.push(input.call(parsing::single_parse_outer)?); - } - Ok(attrs) - } - - /// Parses zero or more inner attributes from the stream. - /// - /// *This function is available only if Syn is built with the `"parsing"` - /// feature.* - #[cfg(feature = "parsing")] - #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))] - pub fn parse_inner(input: ParseStream) -> Result> { - let mut attrs = Vec::new(); - parsing::parse_inner(input, &mut attrs)?; - Ok(attrs) - } -} - -#[cfg(feature = "parsing")] -fn expected_parentheses(attr: &Attribute) -> String { - let style = match attr.style { - AttrStyle::Outer => "#", - AttrStyle::Inner(_) => "#!", - }; - - let mut path = String::new(); - for segment in &attr.path.segments { - if !path.is_empty() || attr.path.leading_colon.is_some() { - path += "::"; - } - path += &segment.ident.to_string(); - } - - format!("{}[{}(...)]", style, path) -} - -#[cfg(feature = "parsing")] -fn enter_args<'a>(attr: &Attribute, input: ParseStream<'a>) -> Result> { - if input.is_empty() { - let expected = expected_parentheses(attr); - let msg = format!("expected attribute arguments in parentheses: {}", expected); - return Err(crate::error::new2( - attr.pound_token.span, - attr.bracket_token.span, - msg, - )); - } else if input.peek(Token![=]) { - let expected = expected_parentheses(attr); - let msg = format!("expected parentheses: {}", expected); - return Err(input.error(msg)); - }; - - let content; - if input.peek(token::Paren) { - parenthesized!(content in input); - } else if input.peek(token::Bracket) { - bracketed!(content in input); - } else if input.peek(token::Brace) { - braced!(content in input); - } else { - return Err(input.error("unexpected token in attribute arguments")); - } - - if input.is_empty() { - Ok(content) - } else { - Err(input.error("unexpected token in attribute arguments")) - } -} - -ast_enum! { - /// Distinguishes between attributes that decorate an item and attributes - /// that are contained within an item. - /// - /// *This type is available only if Syn is built with the `"derive"` or `"full"` - /// feature.* - /// - /// # Outer attributes - /// - /// - `#[repr(transparent)]` - /// - `/// # Example` - /// - `/** Please file an issue */` - /// - /// # Inner attributes - /// - /// - `#![feature(proc_macro)]` - /// - `//! # Example` - /// - `/*! Please file an issue */` - #[cfg_attr(doc_cfg, doc(cfg(any(feature = "full", feature = "derive"))))] - pub enum AttrStyle { - Outer, - Inner(Token![!]), - } -} - -ast_enum_of_structs! { - /// Content of a compile-time structured attribute. - /// - /// *This type is available only if Syn is built with the `"derive"` or `"full"` - /// feature.* - /// - /// ## Path - /// - /// A meta path is like the `test` in `#[test]`. - /// - /// ## List - /// - /// A meta list is like the `derive(Copy)` in `#[derive(Copy)]`. - /// - /// ## NameValue - /// - /// A name-value meta is like the `path = "..."` in `#[path = - /// "sys/windows.rs"]`. - /// - /// # Syntax tree enum - /// - /// This type is a [syntax tree enum]. - /// - /// [syntax tree enum]: Expr#syntax-tree-enums - #[cfg_attr(doc_cfg, doc(cfg(any(feature = "full", feature = "derive"))))] - pub enum Meta { - Path(Path), - - /// A structured list within an attribute, like `derive(Copy, Clone)`. - List(MetaList), - - /// A name-value pair within an attribute, like `feature = "nightly"`. - NameValue(MetaNameValue), - } -} - -ast_struct! { - /// A structured list within an attribute, like `derive(Copy, Clone)`. - /// - /// *This type is available only if Syn is built with the `"derive"` or - /// `"full"` feature.* - #[cfg_attr(doc_cfg, doc(cfg(any(feature = "full", feature = "derive"))))] - pub struct MetaList { - pub path: Path, - pub paren_token: token::Paren, - pub nested: Punctuated, - } -} - -ast_struct! { - /// A name-value pair within an attribute, like `feature = "nightly"`. - /// - /// *This type is available only if Syn is built with the `"derive"` or - /// `"full"` feature.* - #[cfg_attr(doc_cfg, doc(cfg(any(feature = "full", feature = "derive"))))] - pub struct MetaNameValue { - pub path: Path, - pub eq_token: Token![=], - pub lit: Lit, - } -} - -impl Meta { - /// Returns the identifier that begins this structured meta item. - /// - /// For example this would return the `test` in `#[test]`, the `derive` in - /// `#[derive(Copy)]`, and the `path` in `#[path = "sys/windows.rs"]`. - pub fn path(&self) -> &Path { - match self { - Meta::Path(path) => path, - Meta::List(meta) => &meta.path, - Meta::NameValue(meta) => &meta.path, - } - } -} - -ast_enum_of_structs! { - /// Element of a compile-time attribute list. - /// - /// *This type is available only if Syn is built with the `"derive"` or `"full"` - /// feature.* - #[cfg_attr(doc_cfg, doc(cfg(any(feature = "full", feature = "derive"))))] - pub enum NestedMeta { - /// A structured meta item, like the `Copy` in `#[derive(Copy)]` which - /// would be a nested `Meta::Path`. - Meta(Meta), - - /// A Rust literal, like the `"new_name"` in `#[rename("new_name")]`. - Lit(Lit), - } -} - -/// Conventional argument type associated with an invocation of an attribute -/// macro. -/// -/// For example if we are developing an attribute macro that is intended to be -/// invoked on function items as follows: -/// -/// ``` -/// # const IGNORE: &str = stringify! { -/// #[my_attribute(path = "/v1/refresh")] -/// # }; -/// pub fn refresh() { -/// /* ... */ -/// } -/// ``` -/// -/// The implementation of this macro would want to parse its attribute arguments -/// as type `AttributeArgs`. -/// -/// ``` -/// # extern crate proc_macro; -/// # -/// use proc_macro::TokenStream; -/// use syn::{parse_macro_input, AttributeArgs, ItemFn}; -/// -/// # const IGNORE: &str = stringify! { -/// #[proc_macro_attribute] -/// # }; -/// pub fn my_attribute(args: TokenStream, input: TokenStream) -> TokenStream { -/// let args = parse_macro_input!(args as AttributeArgs); -/// let input = parse_macro_input!(input as ItemFn); -/// -/// /* ... */ -/// # "".parse().unwrap() -/// } -/// ``` -#[cfg_attr(doc_cfg, doc(cfg(any(feature = "full", feature = "derive"))))] -pub type AttributeArgs = Vec; - -pub trait FilterAttrs<'a> { - type Ret: Iterator; - - fn outer(self) -> Self::Ret; - fn inner(self) -> Self::Ret; -} - -impl<'a> FilterAttrs<'a> for &'a [Attribute] { - type Ret = iter::Filter, fn(&&Attribute) -> bool>; - - fn outer(self) -> Self::Ret { - fn is_outer(attr: &&Attribute) -> bool { - match attr.style { - AttrStyle::Outer => true, - AttrStyle::Inner(_) => false, - } - } - self.iter().filter(is_outer) - } - - fn inner(self) -> Self::Ret { - fn is_inner(attr: &&Attribute) -> bool { - match attr.style { - AttrStyle::Inner(_) => true, - AttrStyle::Outer => false, - } - } - self.iter().filter(is_inner) - } -} - -#[cfg(feature = "parsing")] -pub mod parsing { - use super::*; - use crate::ext::IdentExt; - use crate::parse::{Parse, ParseStream, Result}; - - pub fn parse_inner(input: ParseStream, attrs: &mut Vec) -> Result<()> { - while input.peek(Token![#]) && input.peek2(Token![!]) { - attrs.push(input.call(parsing::single_parse_inner)?); - } - Ok(()) - } - - pub fn single_parse_inner(input: ParseStream) -> Result { - let content; - Ok(Attribute { - pound_token: input.parse()?, - style: AttrStyle::Inner(input.parse()?), - bracket_token: bracketed!(content in input), - path: content.call(Path::parse_mod_style)?, - tokens: content.parse()?, - }) - } - - pub fn single_parse_outer(input: ParseStream) -> Result { - let content; - Ok(Attribute { - pound_token: input.parse()?, - style: AttrStyle::Outer, - bracket_token: bracketed!(content in input), - path: content.call(Path::parse_mod_style)?, - tokens: content.parse()?, - }) - } - - // Like Path::parse_mod_style but accepts keywords in the path. - fn parse_meta_path(input: ParseStream) -> Result { - Ok(Path { - leading_colon: input.parse()?, - segments: { - let mut segments = Punctuated::new(); - while input.peek(Ident::peek_any) { - let ident = Ident::parse_any(input)?; - segments.push_value(PathSegment::from(ident)); - if !input.peek(Token![::]) { - break; - } - let punct = input.parse()?; - segments.push_punct(punct); - } - if segments.is_empty() { - return Err(input.error("expected path")); - } else if segments.trailing_punct() { - return Err(input.error("expected path segment")); - } - segments - }, - }) - } - - #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))] - impl Parse for Meta { - fn parse(input: ParseStream) -> Result { - let path = input.call(parse_meta_path)?; - parse_meta_after_path(path, input) - } - } - - #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))] - impl Parse for MetaList { - fn parse(input: ParseStream) -> Result { - let path = input.call(parse_meta_path)?; - parse_meta_list_after_path(path, input) - } - } - - #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))] - impl Parse for MetaNameValue { - fn parse(input: ParseStream) -> Result { - let path = input.call(parse_meta_path)?; - parse_meta_name_value_after_path(path, input) - } - } - - #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))] - impl Parse for NestedMeta { - fn parse(input: ParseStream) -> Result { - if input.peek(Lit) && !(input.peek(LitBool) && input.peek2(Token![=])) { - input.parse().map(NestedMeta::Lit) - } else if input.peek(Ident::peek_any) - || input.peek(Token![::]) && input.peek3(Ident::peek_any) - { - input.parse().map(NestedMeta::Meta) - } else { - Err(input.error("expected identifier or literal")) - } - } - } - - pub fn parse_meta_after_path(path: Path, input: ParseStream) -> Result { - if input.peek(token::Paren) { - parse_meta_list_after_path(path, input).map(Meta::List) - } else if input.peek(Token![=]) { - parse_meta_name_value_after_path(path, input).map(Meta::NameValue) - } else { - Ok(Meta::Path(path)) - } - } - - fn parse_meta_list_after_path(path: Path, input: ParseStream) -> Result { - let content; - Ok(MetaList { - path, - paren_token: parenthesized!(content in input), - nested: content.parse_terminated(NestedMeta::parse)?, - }) - } - - fn parse_meta_name_value_after_path(path: Path, input: ParseStream) -> Result { - Ok(MetaNameValue { - path, - eq_token: input.parse()?, - lit: input.parse()?, - }) - } -} - -#[cfg(feature = "printing")] -mod printing { - use super::*; - use proc_macro2::TokenStream; - use quote::ToTokens; - - #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))] - impl ToTokens for Attribute { - fn to_tokens(&self, tokens: &mut TokenStream) { - self.pound_token.to_tokens(tokens); - if let AttrStyle::Inner(b) = &self.style { - b.to_tokens(tokens); - } - self.bracket_token.surround(tokens, |tokens| { - self.path.to_tokens(tokens); - self.tokens.to_tokens(tokens); - }); - } - } - - #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))] - impl ToTokens for MetaList { - fn to_tokens(&self, tokens: &mut TokenStream) { - self.path.to_tokens(tokens); - self.paren_token.surround(tokens, |tokens| { - self.nested.to_tokens(tokens); - }); - } - } - - #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))] - impl ToTokens for MetaNameValue { - fn to_tokens(&self, tokens: &mut TokenStream) { - self.path.to_tokens(tokens); - self.eq_token.to_tokens(tokens); - self.lit.to_tokens(tokens); - } - } -} diff --git a/third-party/vendor/syn/src/await.rs b/third-party/vendor/syn/src/await.rs deleted file mode 100644 index 038c6a5d..00000000 --- a/third-party/vendor/syn/src/await.rs +++ /dev/null @@ -1,2 +0,0 @@ -// See include!("await.rs") in token.rs. -export_token_macro! {[await]} diff --git a/third-party/vendor/syn/src/bigint.rs b/third-party/vendor/syn/src/bigint.rs deleted file mode 100644 index 5397d6be..00000000 --- a/third-party/vendor/syn/src/bigint.rs +++ /dev/null @@ -1,66 +0,0 @@ -use std::ops::{AddAssign, MulAssign}; - -// For implementing base10_digits() accessor on LitInt. -pub struct BigInt { - digits: Vec, -} - -impl BigInt { - pub fn new() -> Self { - BigInt { digits: Vec::new() } - } - - pub fn to_string(&self) -> String { - let mut repr = String::with_capacity(self.digits.len()); - - let mut has_nonzero = false; - for digit in self.digits.iter().rev() { - has_nonzero |= *digit != 0; - if has_nonzero { - repr.push((*digit + b'0') as char); - } - } - - if repr.is_empty() { - repr.push('0'); - } - - repr - } - - fn reserve_two_digits(&mut self) { - let len = self.digits.len(); - let desired = - len + !self.digits.ends_with(&[0, 0]) as usize + !self.digits.ends_with(&[0]) as usize; - self.digits.resize(desired, 0); - } -} - -impl AddAssign for BigInt { - // Assumes increment <16. - fn add_assign(&mut self, mut increment: u8) { - self.reserve_two_digits(); - - let mut i = 0; - while increment > 0 { - let sum = self.digits[i] + increment; - self.digits[i] = sum % 10; - increment = sum / 10; - i += 1; - } - } -} - -impl MulAssign for BigInt { - // Assumes base <=16. - fn mul_assign(&mut self, base: u8) { - self.reserve_two_digits(); - - let mut carry = 0; - for digit in &mut self.digits { - let prod = *digit * base + carry; - *digit = prod % 10; - carry = prod / 10; - } - } -} diff --git a/third-party/vendor/syn/src/buffer.rs b/third-party/vendor/syn/src/buffer.rs deleted file mode 100644 index 0d5cf30d..00000000 --- a/third-party/vendor/syn/src/buffer.rs +++ /dev/null @@ -1,398 +0,0 @@ -//! A stably addressed token buffer supporting efficient traversal based on a -//! cheaply copyable cursor. -//! -//! *This module is available only if Syn is built with the `"parsing"` feature.* - -// This module is heavily commented as it contains most of the unsafe code in -// Syn, and caution should be used when editing it. The public-facing interface -// is 100% safe but the implementation is fragile internally. - -#[cfg(all( - not(all(target_arch = "wasm32", any(target_os = "unknown", target_os = "wasi"))), - feature = "proc-macro" -))] -use crate::proc_macro as pm; -use crate::Lifetime; -use proc_macro2::{Delimiter, Group, Ident, Literal, Punct, Spacing, Span, TokenStream, TokenTree}; -use std::cmp::Ordering; -use std::marker::PhantomData; - -/// Internal type which is used instead of `TokenTree` to represent a token tree -/// within a `TokenBuffer`. -enum Entry { - // Mimicking types from proc-macro. - // Group entries contain the offset to the matching End entry. - Group(Group, usize), - Ident(Ident), - Punct(Punct), - Literal(Literal), - // End entries contain the offset (negative) to the start of the buffer. - End(isize), -} - -/// A buffer that can be efficiently traversed multiple times, unlike -/// `TokenStream` which requires a deep copy in order to traverse more than -/// once. -/// -/// *This type is available only if Syn is built with the `"parsing"` feature.* -pub struct TokenBuffer { - // NOTE: Do not implement clone on this - while the current design could be - // cloned, other designs which could be desirable may not be cloneable. - entries: Box<[Entry]>, -} - -impl TokenBuffer { - fn recursive_new(entries: &mut Vec, stream: TokenStream) { - for tt in stream { - match tt { - TokenTree::Ident(ident) => entries.push(Entry::Ident(ident)), - TokenTree::Punct(punct) => entries.push(Entry::Punct(punct)), - TokenTree::Literal(literal) => entries.push(Entry::Literal(literal)), - TokenTree::Group(group) => { - let group_start_index = entries.len(); - entries.push(Entry::End(0)); // we replace this below - Self::recursive_new(entries, group.stream()); - let group_end_index = entries.len(); - entries.push(Entry::End(-(group_end_index as isize))); - let group_end_offset = group_end_index - group_start_index; - entries[group_start_index] = Entry::Group(group, group_end_offset); - } - } - } - } - - /// Creates a `TokenBuffer` containing all the tokens from the input - /// `proc_macro::TokenStream`. - /// - /// *This method is available only if Syn is built with both the `"parsing"` and - /// `"proc-macro"` features.* - #[cfg(all( - not(all(target_arch = "wasm32", any(target_os = "unknown", target_os = "wasi"))), - feature = "proc-macro" - ))] - pub fn new(stream: pm::TokenStream) -> Self { - Self::new2(stream.into()) - } - - /// Creates a `TokenBuffer` containing all the tokens from the input - /// `proc_macro2::TokenStream`. - pub fn new2(stream: TokenStream) -> Self { - let mut entries = Vec::new(); - Self::recursive_new(&mut entries, stream); - entries.push(Entry::End(-(entries.len() as isize))); - Self { - entries: entries.into_boxed_slice(), - } - } - - /// Creates a cursor referencing the first token in the buffer and able to - /// traverse until the end of the buffer. - pub fn begin(&self) -> Cursor { - let ptr = self.entries.as_ptr(); - unsafe { Cursor::create(ptr, ptr.add(self.entries.len() - 1)) } - } -} - -/// A cheaply copyable cursor into a `TokenBuffer`. -/// -/// This cursor holds a shared reference into the immutable data which is used -/// internally to represent a `TokenStream`, and can be efficiently manipulated -/// and copied around. -/// -/// An empty `Cursor` can be created directly, or one may create a `TokenBuffer` -/// object and get a cursor to its first token with `begin()`. -/// -/// Two cursors are equal if they have the same location in the same input -/// stream, and have the same scope. -/// -/// *This type is available only if Syn is built with the `"parsing"` feature.* -pub struct Cursor<'a> { - // The current entry which the `Cursor` is pointing at. - ptr: *const Entry, - // This is the only `Entry::End` object which this cursor is allowed to - // point at. All other `End` objects are skipped over in `Cursor::create`. - scope: *const Entry, - // Cursor is covariant in 'a. This field ensures that our pointers are still - // valid. - marker: PhantomData<&'a Entry>, -} - -impl<'a> Cursor<'a> { - /// Creates a cursor referencing a static empty TokenStream. - pub fn empty() -> Self { - // It's safe in this situation for us to put an `Entry` object in global - // storage, despite it not actually being safe to send across threads - // (`Ident` is a reference into a thread-local table). This is because - // this entry never includes a `Ident` object. - // - // This wrapper struct allows us to break the rules and put a `Sync` - // object in global storage. - struct UnsafeSyncEntry(Entry); - unsafe impl Sync for UnsafeSyncEntry {} - static EMPTY_ENTRY: UnsafeSyncEntry = UnsafeSyncEntry(Entry::End(0)); - - Cursor { - ptr: &EMPTY_ENTRY.0, - scope: &EMPTY_ENTRY.0, - marker: PhantomData, - } - } - - /// This create method intelligently exits non-explicitly-entered - /// `None`-delimited scopes when the cursor reaches the end of them, - /// allowing for them to be treated transparently. - unsafe fn create(mut ptr: *const Entry, scope: *const Entry) -> Self { - // NOTE: If we're looking at a `End`, we want to advance the cursor - // past it, unless `ptr == scope`, which means that we're at the edge of - // our cursor's scope. We should only have `ptr != scope` at the exit - // from None-delimited groups entered with `ignore_none`. - while let Entry::End(_) = *ptr { - if ptr == scope { - break; - } - ptr = ptr.add(1); - } - - Cursor { - ptr, - scope, - marker: PhantomData, - } - } - - /// Get the current entry. - fn entry(self) -> &'a Entry { - unsafe { &*self.ptr } - } - - /// Bump the cursor to point at the next token after the current one. This - /// is undefined behavior if the cursor is currently looking at an - /// `Entry::End`. - /// - /// If the cursor is looking at an `Entry::Group`, the bumped cursor will - /// point at the first token in the group (with the same scope end). - unsafe fn bump_ignore_group(self) -> Cursor<'a> { - Cursor::create(self.ptr.offset(1), self.scope) - } - - /// While the cursor is looking at a `None`-delimited group, move it to look - /// at the first token inside instead. If the group is empty, this will move - /// the cursor past the `None`-delimited group. - /// - /// WARNING: This mutates its argument. - fn ignore_none(&mut self) { - while let Entry::Group(group, _) = self.entry() { - if group.delimiter() == Delimiter::None { - unsafe { *self = self.bump_ignore_group() }; - } else { - break; - } - } - } - - /// Checks whether the cursor is currently pointing at the end of its valid - /// scope. - pub fn eof(self) -> bool { - // We're at eof if we're at the end of our scope. - self.ptr == self.scope - } - - /// If the cursor is pointing at a `Group` with the given delimiter, returns - /// a cursor into that group and one pointing to the next `TokenTree`. - pub fn group(mut self, delim: Delimiter) -> Option<(Cursor<'a>, Span, Cursor<'a>)> { - // If we're not trying to enter a none-delimited group, we want to - // ignore them. We have to make sure to _not_ ignore them when we want - // to enter them, of course. For obvious reasons. - if delim != Delimiter::None { - self.ignore_none(); - } - - if let Entry::Group(group, end_offset) = self.entry() { - if group.delimiter() == delim { - let end_of_group = unsafe { self.ptr.add(*end_offset) }; - let inside_of_group = unsafe { Cursor::create(self.ptr.add(1), end_of_group) }; - let after_group = unsafe { Cursor::create(end_of_group, self.scope) }; - return Some((inside_of_group, group.span(), after_group)); - } - } - - None - } - - /// If the cursor is pointing at a `Ident`, returns it along with a cursor - /// pointing at the next `TokenTree`. - pub fn ident(mut self) -> Option<(Ident, Cursor<'a>)> { - self.ignore_none(); - match self.entry() { - Entry::Ident(ident) => Some((ident.clone(), unsafe { self.bump_ignore_group() })), - _ => None, - } - } - - /// If the cursor is pointing at a `Punct`, returns it along with a cursor - /// pointing at the next `TokenTree`. - pub fn punct(mut self) -> Option<(Punct, Cursor<'a>)> { - self.ignore_none(); - match self.entry() { - Entry::Punct(punct) if punct.as_char() != '\'' => { - Some((punct.clone(), unsafe { self.bump_ignore_group() })) - } - _ => None, - } - } - - /// If the cursor is pointing at a `Literal`, return it along with a cursor - /// pointing at the next `TokenTree`. - pub fn literal(mut self) -> Option<(Literal, Cursor<'a>)> { - self.ignore_none(); - match self.entry() { - Entry::Literal(literal) => Some((literal.clone(), unsafe { self.bump_ignore_group() })), - _ => None, - } - } - - /// If the cursor is pointing at a `Lifetime`, returns it along with a - /// cursor pointing at the next `TokenTree`. - pub fn lifetime(mut self) -> Option<(Lifetime, Cursor<'a>)> { - self.ignore_none(); - match self.entry() { - Entry::Punct(punct) if punct.as_char() == '\'' && punct.spacing() == Spacing::Joint => { - let next = unsafe { self.bump_ignore_group() }; - let (ident, rest) = next.ident()?; - let lifetime = Lifetime { - apostrophe: punct.span(), - ident, - }; - Some((lifetime, rest)) - } - _ => None, - } - } - - /// Copies all remaining tokens visible from this cursor into a - /// `TokenStream`. - pub fn token_stream(self) -> TokenStream { - let mut tts = Vec::new(); - let mut cursor = self; - while let Some((tt, rest)) = cursor.token_tree() { - tts.push(tt); - cursor = rest; - } - tts.into_iter().collect() - } - - /// If the cursor is pointing at a `TokenTree`, returns it along with a - /// cursor pointing at the next `TokenTree`. - /// - /// Returns `None` if the cursor has reached the end of its stream. - /// - /// This method does not treat `None`-delimited groups as transparent, and - /// will return a `Group(None, ..)` if the cursor is looking at one. - pub fn token_tree(self) -> Option<(TokenTree, Cursor<'a>)> { - let (tree, len) = match self.entry() { - Entry::Group(group, end_offset) => (group.clone().into(), *end_offset), - Entry::Literal(literal) => (literal.clone().into(), 1), - Entry::Ident(ident) => (ident.clone().into(), 1), - Entry::Punct(punct) => (punct.clone().into(), 1), - Entry::End(_) => return None, - }; - - let rest = unsafe { Cursor::create(self.ptr.add(len), self.scope) }; - Some((tree, rest)) - } - - /// Returns the `Span` of the current token, or `Span::call_site()` if this - /// cursor points to eof. - pub fn span(self) -> Span { - match self.entry() { - Entry::Group(group, _) => group.span(), - Entry::Literal(literal) => literal.span(), - Entry::Ident(ident) => ident.span(), - Entry::Punct(punct) => punct.span(), - Entry::End(_) => Span::call_site(), - } - } - - /// Skip over the next token without cloning it. Returns `None` if this - /// cursor points to eof. - /// - /// This method treats `'lifetimes` as a single token. - pub(crate) fn skip(self) -> Option> { - let len = match self.entry() { - Entry::End(_) => return None, - - // Treat lifetimes as a single tt for the purposes of 'skip'. - Entry::Punct(punct) if punct.as_char() == '\'' && punct.spacing() == Spacing::Joint => { - match unsafe { &*self.ptr.add(1) } { - Entry::Ident(_) => 2, - _ => 1, - } - } - - Entry::Group(_, end_offset) => *end_offset, - _ => 1, - }; - - Some(unsafe { Cursor::create(self.ptr.add(len), self.scope) }) - } -} - -impl<'a> Copy for Cursor<'a> {} - -impl<'a> Clone for Cursor<'a> { - fn clone(&self) -> Self { - *self - } -} - -impl<'a> Eq for Cursor<'a> {} - -impl<'a> PartialEq for Cursor<'a> { - fn eq(&self, other: &Self) -> bool { - self.ptr == other.ptr - } -} - -impl<'a> PartialOrd for Cursor<'a> { - fn partial_cmp(&self, other: &Self) -> Option { - if same_buffer(*self, *other) { - Some(self.ptr.cmp(&other.ptr)) - } else { - None - } - } -} - -pub(crate) fn same_scope(a: Cursor, b: Cursor) -> bool { - a.scope == b.scope -} - -pub(crate) fn same_buffer(a: Cursor, b: Cursor) -> bool { - unsafe { - match (&*a.scope, &*b.scope) { - (Entry::End(a_offset), Entry::End(b_offset)) => { - a.scope.offset(*a_offset) == b.scope.offset(*b_offset) - } - _ => unreachable!(), - } - } -} - -#[cfg(any(feature = "full", feature = "derive"))] -pub(crate) fn cmp_assuming_same_buffer(a: Cursor, b: Cursor) -> Ordering { - a.ptr.cmp(&b.ptr) -} - -pub(crate) fn open_span_of_group(cursor: Cursor) -> Span { - match cursor.entry() { - Entry::Group(group, _) => group.span_open(), - _ => cursor.span(), - } -} - -pub(crate) fn close_span_of_group(cursor: Cursor) -> Span { - match cursor.entry() { - Entry::Group(group, _) => group.span_close(), - _ => cursor.span(), - } -} diff --git a/third-party/vendor/syn/src/custom_keyword.rs b/third-party/vendor/syn/src/custom_keyword.rs deleted file mode 100644 index a3ec9d4c..00000000 --- a/third-party/vendor/syn/src/custom_keyword.rs +++ /dev/null @@ -1,253 +0,0 @@ -/// Define a type that supports parsing and printing a given identifier as if it -/// were a keyword. -/// -/// # Usage -/// -/// As a convention, it is recommended that this macro be invoked within a -/// module called `kw` or `keyword` and that the resulting parser be invoked -/// with a `kw::` or `keyword::` prefix. -/// -/// ``` -/// mod kw { -/// syn::custom_keyword!(whatever); -/// } -/// ``` -/// -/// The generated syntax tree node supports the following operations just like -/// any built-in keyword token. -/// -/// - [Peeking] — `input.peek(kw::whatever)` -/// -/// - [Parsing] — `input.parse::()?` -/// -/// - [Printing] — `quote!( ... #whatever_token ... )` -/// -/// - Construction from a [`Span`] — `let whatever_token = kw::whatever(sp)` -/// -/// - Field access to its span — `let sp = whatever_token.span` -/// -/// [Peeking]: crate::parse::ParseBuffer::peek -/// [Parsing]: crate::parse::ParseBuffer::parse -/// [Printing]: quote::ToTokens -/// [`Span`]: proc_macro2::Span -/// -/// # Example -/// -/// This example parses input that looks like `bool = true` or `str = "value"`. -/// The key must be either the identifier `bool` or the identifier `str`. If -/// `bool`, the value may be either `true` or `false`. If `str`, the value may -/// be any string literal. -/// -/// The symbols `bool` and `str` are not reserved keywords in Rust so these are -/// not considered keywords in the `syn::token` module. Like any other -/// identifier that is not a keyword, these can be declared as custom keywords -/// by crates that need to use them as such. -/// -/// ``` -/// use syn::{LitBool, LitStr, Result, Token}; -/// use syn::parse::{Parse, ParseStream}; -/// -/// mod kw { -/// syn::custom_keyword!(bool); -/// syn::custom_keyword!(str); -/// } -/// -/// enum Argument { -/// Bool { -/// bool_token: kw::bool, -/// eq_token: Token![=], -/// value: LitBool, -/// }, -/// Str { -/// str_token: kw::str, -/// eq_token: Token![=], -/// value: LitStr, -/// }, -/// } -/// -/// impl Parse for Argument { -/// fn parse(input: ParseStream) -> Result { -/// let lookahead = input.lookahead1(); -/// if lookahead.peek(kw::bool) { -/// Ok(Argument::Bool { -/// bool_token: input.parse::()?, -/// eq_token: input.parse()?, -/// value: input.parse()?, -/// }) -/// } else if lookahead.peek(kw::str) { -/// Ok(Argument::Str { -/// str_token: input.parse::()?, -/// eq_token: input.parse()?, -/// value: input.parse()?, -/// }) -/// } else { -/// Err(lookahead.error()) -/// } -/// } -/// } -/// ``` -#[macro_export] -macro_rules! custom_keyword { - ($ident:ident) => { - #[allow(non_camel_case_types)] - pub struct $ident { - pub span: $crate::__private::Span, - } - - #[doc(hidden)] - #[allow(dead_code, non_snake_case)] - pub fn $ident<__S: $crate::__private::IntoSpans<[$crate::__private::Span; 1]>>( - span: __S, - ) -> $ident { - $ident { - span: $crate::__private::IntoSpans::into_spans(span)[0], - } - } - - impl $crate::__private::Default for $ident { - fn default() -> Self { - $ident { - span: $crate::__private::Span::call_site(), - } - } - } - - $crate::impl_parse_for_custom_keyword!($ident); - $crate::impl_to_tokens_for_custom_keyword!($ident); - $crate::impl_clone_for_custom_keyword!($ident); - $crate::impl_extra_traits_for_custom_keyword!($ident); - }; -} - -// Not public API. -#[cfg(feature = "parsing")] -#[doc(hidden)] -#[macro_export] -macro_rules! impl_parse_for_custom_keyword { - ($ident:ident) => { - // For peek. - impl $crate::token::CustomToken for $ident { - fn peek(cursor: $crate::buffer::Cursor) -> $crate::__private::bool { - if let $crate::__private::Some((ident, _rest)) = cursor.ident() { - ident == stringify!($ident) - } else { - false - } - } - - fn display() -> &'static $crate::__private::str { - concat!("`", stringify!($ident), "`") - } - } - - impl $crate::parse::Parse for $ident { - fn parse(input: $crate::parse::ParseStream) -> $crate::parse::Result<$ident> { - input.step(|cursor| { - if let $crate::__private::Some((ident, rest)) = cursor.ident() { - if ident == stringify!($ident) { - return $crate::__private::Ok(($ident { span: ident.span() }, rest)); - } - } - $crate::__private::Err(cursor.error(concat!( - "expected `", - stringify!($ident), - "`" - ))) - }) - } - } - }; -} - -// Not public API. -#[cfg(not(feature = "parsing"))] -#[doc(hidden)] -#[macro_export] -macro_rules! impl_parse_for_custom_keyword { - ($ident:ident) => {}; -} - -// Not public API. -#[cfg(feature = "printing")] -#[doc(hidden)] -#[macro_export] -macro_rules! impl_to_tokens_for_custom_keyword { - ($ident:ident) => { - impl $crate::__private::ToTokens for $ident { - fn to_tokens(&self, tokens: &mut $crate::__private::TokenStream2) { - let ident = $crate::Ident::new(stringify!($ident), self.span); - $crate::__private::TokenStreamExt::append(tokens, ident); - } - } - }; -} - -// Not public API. -#[cfg(not(feature = "printing"))] -#[doc(hidden)] -#[macro_export] -macro_rules! impl_to_tokens_for_custom_keyword { - ($ident:ident) => {}; -} - -// Not public API. -#[cfg(feature = "clone-impls")] -#[doc(hidden)] -#[macro_export] -macro_rules! impl_clone_for_custom_keyword { - ($ident:ident) => { - impl $crate::__private::Copy for $ident {} - - #[allow(clippy::expl_impl_clone_on_copy)] - impl $crate::__private::Clone for $ident { - fn clone(&self) -> Self { - *self - } - } - }; -} - -// Not public API. -#[cfg(not(feature = "clone-impls"))] -#[doc(hidden)] -#[macro_export] -macro_rules! impl_clone_for_custom_keyword { - ($ident:ident) => {}; -} - -// Not public API. -#[cfg(feature = "extra-traits")] -#[doc(hidden)] -#[macro_export] -macro_rules! impl_extra_traits_for_custom_keyword { - ($ident:ident) => { - impl $crate::__private::Debug for $ident { - fn fmt(&self, f: &mut $crate::__private::Formatter) -> $crate::__private::fmt::Result { - $crate::__private::Formatter::write_str( - f, - concat!("Keyword [", stringify!($ident), "]"), - ) - } - } - - impl $crate::__private::Eq for $ident {} - - impl $crate::__private::PartialEq for $ident { - fn eq(&self, _other: &Self) -> $crate::__private::bool { - true - } - } - - impl $crate::__private::Hash for $ident { - fn hash<__H: $crate::__private::Hasher>(&self, _state: &mut __H) {} - } - }; -} - -// Not public API. -#[cfg(not(feature = "extra-traits"))] -#[doc(hidden)] -#[macro_export] -macro_rules! impl_extra_traits_for_custom_keyword { - ($ident:ident) => {}; -} diff --git a/third-party/vendor/syn/src/custom_punctuation.rs b/third-party/vendor/syn/src/custom_punctuation.rs deleted file mode 100644 index 118a8453..00000000 --- a/third-party/vendor/syn/src/custom_punctuation.rs +++ /dev/null @@ -1,300 +0,0 @@ -/// Define a type that supports parsing and printing a multi-character symbol -/// as if it were a punctuation token. -/// -/// # Usage -/// -/// ``` -/// syn::custom_punctuation!(LeftRightArrow, <=>); -/// ``` -/// -/// The generated syntax tree node supports the following operations just like -/// any built-in punctuation token. -/// -/// - [Peeking] — `input.peek(LeftRightArrow)` -/// -/// - [Parsing] — `input.parse::()?` -/// -/// - [Printing] — `quote!( ... #lrarrow ... )` -/// -/// - Construction from a [`Span`] — `let lrarrow = LeftRightArrow(sp)` -/// -/// - Construction from multiple [`Span`] — `let lrarrow = LeftRightArrow([sp, sp, sp])` -/// -/// - Field access to its spans — `let spans = lrarrow.spans` -/// -/// [Peeking]: crate::parse::ParseBuffer::peek -/// [Parsing]: crate::parse::ParseBuffer::parse -/// [Printing]: quote::ToTokens -/// [`Span`]: proc_macro2::Span -/// -/// # Example -/// -/// ``` -/// use proc_macro2::{TokenStream, TokenTree}; -/// use syn::parse::{Parse, ParseStream, Peek, Result}; -/// use syn::punctuated::Punctuated; -/// use syn::Expr; -/// -/// syn::custom_punctuation!(PathSeparator, ); -/// -/// // expr expr expr ... -/// struct PathSegments { -/// segments: Punctuated, -/// } -/// -/// impl Parse for PathSegments { -/// fn parse(input: ParseStream) -> Result { -/// let mut segments = Punctuated::new(); -/// -/// let first = parse_until(input, PathSeparator)?; -/// segments.push_value(syn::parse2(first)?); -/// -/// while input.peek(PathSeparator) { -/// segments.push_punct(input.parse()?); -/// -/// let next = parse_until(input, PathSeparator)?; -/// segments.push_value(syn::parse2(next)?); -/// } -/// -/// Ok(PathSegments { segments }) -/// } -/// } -/// -/// fn parse_until(input: ParseStream, end: E) -> Result { -/// let mut tokens = TokenStream::new(); -/// while !input.is_empty() && !input.peek(end) { -/// let next: TokenTree = input.parse()?; -/// tokens.extend(Some(next)); -/// } -/// Ok(tokens) -/// } -/// -/// fn main() { -/// let input = r#" a::b c::d::e "#; -/// let _: PathSegments = syn::parse_str(input).unwrap(); -/// } -/// ``` -#[macro_export] -macro_rules! custom_punctuation { - ($ident:ident, $($tt:tt)+) => { - pub struct $ident { - pub spans: $crate::custom_punctuation_repr!($($tt)+), - } - - #[doc(hidden)] - #[allow(dead_code, non_snake_case)] - pub fn $ident<__S: $crate::__private::IntoSpans<$crate::custom_punctuation_repr!($($tt)+)>>( - spans: __S, - ) -> $ident { - let _validate_len = 0 $(+ $crate::custom_punctuation_len!(strict, $tt))*; - $ident { - spans: $crate::__private::IntoSpans::into_spans(spans) - } - } - - impl $crate::__private::Default for $ident { - fn default() -> Self { - $ident($crate::__private::Span::call_site()) - } - } - - $crate::impl_parse_for_custom_punctuation!($ident, $($tt)+); - $crate::impl_to_tokens_for_custom_punctuation!($ident, $($tt)+); - $crate::impl_clone_for_custom_punctuation!($ident, $($tt)+); - $crate::impl_extra_traits_for_custom_punctuation!($ident, $($tt)+); - }; -} - -// Not public API. -#[cfg(feature = "parsing")] -#[doc(hidden)] -#[macro_export] -macro_rules! impl_parse_for_custom_punctuation { - ($ident:ident, $($tt:tt)+) => { - impl $crate::token::CustomToken for $ident { - fn peek(cursor: $crate::buffer::Cursor) -> bool { - $crate::token::parsing::peek_punct(cursor, $crate::stringify_punct!($($tt)+)) - } - - fn display() -> &'static $crate::__private::str { - concat!("`", $crate::stringify_punct!($($tt)+), "`") - } - } - - impl $crate::parse::Parse for $ident { - fn parse(input: $crate::parse::ParseStream) -> $crate::parse::Result<$ident> { - let spans: $crate::custom_punctuation_repr!($($tt)+) = - $crate::token::parsing::punct(input, $crate::stringify_punct!($($tt)+))?; - Ok($ident(spans)) - } - } - }; -} - -// Not public API. -#[cfg(not(feature = "parsing"))] -#[doc(hidden)] -#[macro_export] -macro_rules! impl_parse_for_custom_punctuation { - ($ident:ident, $($tt:tt)+) => {}; -} - -// Not public API. -#[cfg(feature = "printing")] -#[doc(hidden)] -#[macro_export] -macro_rules! impl_to_tokens_for_custom_punctuation { - ($ident:ident, $($tt:tt)+) => { - impl $crate::__private::ToTokens for $ident { - fn to_tokens(&self, tokens: &mut $crate::__private::TokenStream2) { - $crate::token::printing::punct($crate::stringify_punct!($($tt)+), &self.spans, tokens) - } - } - }; -} - -// Not public API. -#[cfg(not(feature = "printing"))] -#[doc(hidden)] -#[macro_export] -macro_rules! impl_to_tokens_for_custom_punctuation { - ($ident:ident, $($tt:tt)+) => {}; -} - -// Not public API. -#[cfg(feature = "clone-impls")] -#[doc(hidden)] -#[macro_export] -macro_rules! impl_clone_for_custom_punctuation { - ($ident:ident, $($tt:tt)+) => { - impl $crate::__private::Copy for $ident {} - - #[allow(clippy::expl_impl_clone_on_copy)] - impl $crate::__private::Clone for $ident { - fn clone(&self) -> Self { - *self - } - } - }; -} - -// Not public API. -#[cfg(not(feature = "clone-impls"))] -#[doc(hidden)] -#[macro_export] -macro_rules! impl_clone_for_custom_punctuation { - ($ident:ident, $($tt:tt)+) => {}; -} - -// Not public API. -#[cfg(feature = "extra-traits")] -#[doc(hidden)] -#[macro_export] -macro_rules! impl_extra_traits_for_custom_punctuation { - ($ident:ident, $($tt:tt)+) => { - impl $crate::__private::Debug for $ident { - fn fmt(&self, f: &mut $crate::__private::Formatter) -> $crate::__private::fmt::Result { - $crate::__private::Formatter::write_str(f, stringify!($ident)) - } - } - - impl $crate::__private::Eq for $ident {} - - impl $crate::__private::PartialEq for $ident { - fn eq(&self, _other: &Self) -> $crate::__private::bool { - true - } - } - - impl $crate::__private::Hash for $ident { - fn hash<__H: $crate::__private::Hasher>(&self, _state: &mut __H) {} - } - }; -} - -// Not public API. -#[cfg(not(feature = "extra-traits"))] -#[doc(hidden)] -#[macro_export] -macro_rules! impl_extra_traits_for_custom_punctuation { - ($ident:ident, $($tt:tt)+) => {}; -} - -// Not public API. -#[doc(hidden)] -#[macro_export] -macro_rules! custom_punctuation_repr { - ($($tt:tt)+) => { - [$crate::__private::Span; 0 $(+ $crate::custom_punctuation_len!(lenient, $tt))+] - }; -} - -// Not public API. -#[doc(hidden)] -#[macro_export] -#[rustfmt::skip] -macro_rules! custom_punctuation_len { - ($mode:ident, +) => { 1 }; - ($mode:ident, +=) => { 2 }; - ($mode:ident, &) => { 1 }; - ($mode:ident, &&) => { 2 }; - ($mode:ident, &=) => { 2 }; - ($mode:ident, @) => { 1 }; - ($mode:ident, !) => { 1 }; - ($mode:ident, ^) => { 1 }; - ($mode:ident, ^=) => { 2 }; - ($mode:ident, :) => { 1 }; - ($mode:ident, ::) => { 2 }; - ($mode:ident, ,) => { 1 }; - ($mode:ident, /) => { 1 }; - ($mode:ident, /=) => { 2 }; - ($mode:ident, .) => { 1 }; - ($mode:ident, ..) => { 2 }; - ($mode:ident, ...) => { 3 }; - ($mode:ident, ..=) => { 3 }; - ($mode:ident, =) => { 1 }; - ($mode:ident, ==) => { 2 }; - ($mode:ident, >=) => { 2 }; - ($mode:ident, >) => { 1 }; - ($mode:ident, <=) => { 2 }; - ($mode:ident, <) => { 1 }; - ($mode:ident, *=) => { 2 }; - ($mode:ident, !=) => { 2 }; - ($mode:ident, |) => { 1 }; - ($mode:ident, |=) => { 2 }; - ($mode:ident, ||) => { 2 }; - ($mode:ident, #) => { 1 }; - ($mode:ident, ?) => { 1 }; - ($mode:ident, ->) => { 2 }; - ($mode:ident, <-) => { 2 }; - ($mode:ident, %) => { 1 }; - ($mode:ident, %=) => { 2 }; - ($mode:ident, =>) => { 2 }; - ($mode:ident, ;) => { 1 }; - ($mode:ident, <<) => { 2 }; - ($mode:ident, <<=) => { 3 }; - ($mode:ident, >>) => { 2 }; - ($mode:ident, >>=) => { 3 }; - ($mode:ident, *) => { 1 }; - ($mode:ident, -) => { 1 }; - ($mode:ident, -=) => { 2 }; - ($mode:ident, ~) => { 1 }; - (lenient, $tt:tt) => { 0 }; - (strict, $tt:tt) => {{ $crate::custom_punctuation_unexpected!($tt); 0 }}; -} - -// Not public API. -#[doc(hidden)] -#[macro_export] -macro_rules! custom_punctuation_unexpected { - () => {}; -} - -// Not public API. -#[doc(hidden)] -#[macro_export] -macro_rules! stringify_punct { - ($($tt:tt)+) => { - concat!($(stringify!($tt)),+) - }; -} diff --git a/third-party/vendor/syn/src/data.rs b/third-party/vendor/syn/src/data.rs deleted file mode 100644 index 3b466618..00000000 --- a/third-party/vendor/syn/src/data.rs +++ /dev/null @@ -1,493 +0,0 @@ -use super::*; -use crate::punctuated::Punctuated; - -ast_struct! { - /// An enum variant. - /// - /// *This type is available only if Syn is built with the `"derive"` or `"full"` - /// feature.* - #[cfg_attr(doc_cfg, doc(cfg(any(feature = "full", feature = "derive"))))] - pub struct Variant { - /// Attributes tagged on the variant. - pub attrs: Vec, - - /// Name of the variant. - pub ident: Ident, - - /// Content stored in the variant. - pub fields: Fields, - - /// Explicit discriminant: `Variant = 1` - pub discriminant: Option<(Token![=], Expr)>, - } -} - -ast_enum_of_structs! { - /// Data stored within an enum variant or struct. - /// - /// *This type is available only if Syn is built with the `"derive"` or `"full"` - /// feature.* - /// - /// # Syntax tree enum - /// - /// This type is a [syntax tree enum]. - /// - /// [syntax tree enum]: Expr#syntax-tree-enums - #[cfg_attr(doc_cfg, doc(cfg(any(feature = "full", feature = "derive"))))] - pub enum Fields { - /// Named fields of a struct or struct variant such as `Point { x: f64, - /// y: f64 }`. - Named(FieldsNamed), - - /// Unnamed fields of a tuple struct or tuple variant such as `Some(T)`. - Unnamed(FieldsUnnamed), - - /// Unit struct or unit variant such as `None`. - Unit, - } -} - -ast_struct! { - /// Named fields of a struct or struct variant such as `Point { x: f64, - /// y: f64 }`. - /// - /// *This type is available only if Syn is built with the `"derive"` or - /// `"full"` feature.* - #[cfg_attr(doc_cfg, doc(cfg(any(feature = "full", feature = "derive"))))] - pub struct FieldsNamed { - pub brace_token: token::Brace, - pub named: Punctuated, - } -} - -ast_struct! { - /// Unnamed fields of a tuple struct or tuple variant such as `Some(T)`. - /// - /// *This type is available only if Syn is built with the `"derive"` or - /// `"full"` feature.* - #[cfg_attr(doc_cfg, doc(cfg(any(feature = "full", feature = "derive"))))] - pub struct FieldsUnnamed { - pub paren_token: token::Paren, - pub unnamed: Punctuated, - } -} - -impl Fields { - /// Get an iterator over the borrowed [`Field`] items in this object. This - /// iterator can be used to iterate over a named or unnamed struct or - /// variant's fields uniformly. - pub fn iter(&self) -> punctuated::Iter { - match self { - Fields::Unit => crate::punctuated::empty_punctuated_iter(), - Fields::Named(f) => f.named.iter(), - Fields::Unnamed(f) => f.unnamed.iter(), - } - } - - /// Get an iterator over the mutably borrowed [`Field`] items in this - /// object. This iterator can be used to iterate over a named or unnamed - /// struct or variant's fields uniformly. - pub fn iter_mut(&mut self) -> punctuated::IterMut { - match self { - Fields::Unit => crate::punctuated::empty_punctuated_iter_mut(), - Fields::Named(f) => f.named.iter_mut(), - Fields::Unnamed(f) => f.unnamed.iter_mut(), - } - } - - /// Returns the number of fields. - pub fn len(&self) -> usize { - match self { - Fields::Unit => 0, - Fields::Named(f) => f.named.len(), - Fields::Unnamed(f) => f.unnamed.len(), - } - } - - /// Returns `true` if there are zero fields. - pub fn is_empty(&self) -> bool { - match self { - Fields::Unit => true, - Fields::Named(f) => f.named.is_empty(), - Fields::Unnamed(f) => f.unnamed.is_empty(), - } - } -} - -impl IntoIterator for Fields { - type Item = Field; - type IntoIter = punctuated::IntoIter; - - fn into_iter(self) -> Self::IntoIter { - match self { - Fields::Unit => Punctuated::::new().into_iter(), - Fields::Named(f) => f.named.into_iter(), - Fields::Unnamed(f) => f.unnamed.into_iter(), - } - } -} - -impl<'a> IntoIterator for &'a Fields { - type Item = &'a Field; - type IntoIter = punctuated::Iter<'a, Field>; - - fn into_iter(self) -> Self::IntoIter { - self.iter() - } -} - -impl<'a> IntoIterator for &'a mut Fields { - type Item = &'a mut Field; - type IntoIter = punctuated::IterMut<'a, Field>; - - fn into_iter(self) -> Self::IntoIter { - self.iter_mut() - } -} - -ast_struct! { - /// A field of a struct or enum variant. - /// - /// *This type is available only if Syn is built with the `"derive"` or `"full"` - /// feature.* - #[cfg_attr(doc_cfg, doc(cfg(any(feature = "full", feature = "derive"))))] - pub struct Field { - /// Attributes tagged on the field. - pub attrs: Vec, - - /// Visibility of the field. - pub vis: Visibility, - - /// Name of the field, if any. - /// - /// Fields of tuple structs have no names. - pub ident: Option, - - pub colon_token: Option, - - /// Type of the field. - pub ty: Type, - } -} - -ast_enum_of_structs! { - /// The visibility level of an item: inherited or `pub` or - /// `pub(restricted)`. - /// - /// *This type is available only if Syn is built with the `"derive"` or `"full"` - /// feature.* - /// - /// # Syntax tree enum - /// - /// This type is a [syntax tree enum]. - /// - /// [syntax tree enum]: Expr#syntax-tree-enums - #[cfg_attr(doc_cfg, doc(cfg(any(feature = "full", feature = "derive"))))] - pub enum Visibility { - /// A public visibility level: `pub`. - Public(VisPublic), - - /// A crate-level visibility: `crate`. - Crate(VisCrate), - - /// A visibility level restricted to some path: `pub(self)` or - /// `pub(super)` or `pub(crate)` or `pub(in some::module)`. - Restricted(VisRestricted), - - /// An inherited visibility, which usually means private. - Inherited, - } -} - -ast_struct! { - /// A public visibility level: `pub`. - /// - /// *This type is available only if Syn is built with the `"derive"` or - /// `"full"` feature.* - #[cfg_attr(doc_cfg, doc(cfg(any(feature = "full", feature = "derive"))))] - pub struct VisPublic { - pub pub_token: Token![pub], - } -} - -ast_struct! { - /// A crate-level visibility: `crate`. - /// - /// *This type is available only if Syn is built with the `"derive"` or - /// `"full"` feature.* - #[cfg_attr(doc_cfg, doc(cfg(any(feature = "full", feature = "derive"))))] - pub struct VisCrate { - pub crate_token: Token![crate], - } -} - -ast_struct! { - /// A visibility level restricted to some path: `pub(self)` or - /// `pub(super)` or `pub(crate)` or `pub(in some::module)`. - /// - /// *This type is available only if Syn is built with the `"derive"` or - /// `"full"` feature.* - #[cfg_attr(doc_cfg, doc(cfg(any(feature = "full", feature = "derive"))))] - pub struct VisRestricted { - pub pub_token: Token![pub], - pub paren_token: token::Paren, - pub in_token: Option, - pub path: Box, - } -} - -#[cfg(feature = "parsing")] -pub mod parsing { - use super::*; - use crate::ext::IdentExt; - use crate::parse::discouraged::Speculative; - use crate::parse::{Parse, ParseStream, Result}; - - #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))] - impl Parse for Variant { - fn parse(input: ParseStream) -> Result { - let attrs = input.call(Attribute::parse_outer)?; - let _visibility: Visibility = input.parse()?; - let ident: Ident = input.parse()?; - let fields = if input.peek(token::Brace) { - Fields::Named(input.parse()?) - } else if input.peek(token::Paren) { - Fields::Unnamed(input.parse()?) - } else { - Fields::Unit - }; - let discriminant = if input.peek(Token![=]) { - let eq_token: Token![=] = input.parse()?; - let discriminant: Expr = input.parse()?; - Some((eq_token, discriminant)) - } else { - None - }; - Ok(Variant { - attrs, - ident, - fields, - discriminant, - }) - } - } - - #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))] - impl Parse for FieldsNamed { - fn parse(input: ParseStream) -> Result { - let content; - Ok(FieldsNamed { - brace_token: braced!(content in input), - named: content.parse_terminated(Field::parse_named)?, - }) - } - } - - #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))] - impl Parse for FieldsUnnamed { - fn parse(input: ParseStream) -> Result { - let content; - Ok(FieldsUnnamed { - paren_token: parenthesized!(content in input), - unnamed: content.parse_terminated(Field::parse_unnamed)?, - }) - } - } - - impl Field { - /// Parses a named (braced struct) field. - #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))] - pub fn parse_named(input: ParseStream) -> Result { - Ok(Field { - attrs: input.call(Attribute::parse_outer)?, - vis: input.parse()?, - ident: Some(if input.peek(Token![_]) { - input.call(Ident::parse_any) - } else { - input.parse() - }?), - colon_token: Some(input.parse()?), - ty: input.parse()?, - }) - } - - /// Parses an unnamed (tuple struct) field. - #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))] - pub fn parse_unnamed(input: ParseStream) -> Result { - Ok(Field { - attrs: input.call(Attribute::parse_outer)?, - vis: input.parse()?, - ident: None, - colon_token: None, - ty: input.parse()?, - }) - } - } - - #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))] - impl Parse for Visibility { - fn parse(input: ParseStream) -> Result { - // Recognize an empty None-delimited group, as produced by a $:vis - // matcher that matched no tokens. - if input.peek(token::Group) { - let ahead = input.fork(); - let group = crate::group::parse_group(&ahead)?; - if group.content.is_empty() { - input.advance_to(&ahead); - return Ok(Visibility::Inherited); - } - } - - if input.peek(Token![pub]) { - Self::parse_pub(input) - } else if input.peek(Token![crate]) { - Self::parse_crate(input) - } else { - Ok(Visibility::Inherited) - } - } - } - - impl Visibility { - fn parse_pub(input: ParseStream) -> Result { - let pub_token = input.parse::()?; - - if input.peek(token::Paren) { - let ahead = input.fork(); - - let content; - let paren_token = parenthesized!(content in ahead); - if content.peek(Token![crate]) - || content.peek(Token![self]) - || content.peek(Token![super]) - { - let path = content.call(Ident::parse_any)?; - - // Ensure there are no additional tokens within `content`. - // Without explicitly checking, we may misinterpret a tuple - // field as a restricted visibility, causing a parse error. - // e.g. `pub (crate::A, crate::B)` (Issue #720). - if content.is_empty() { - input.advance_to(&ahead); - return Ok(Visibility::Restricted(VisRestricted { - pub_token, - paren_token, - in_token: None, - path: Box::new(Path::from(path)), - })); - } - } else if content.peek(Token![in]) { - let in_token: Token![in] = content.parse()?; - let path = content.call(Path::parse_mod_style)?; - - input.advance_to(&ahead); - return Ok(Visibility::Restricted(VisRestricted { - pub_token, - paren_token, - in_token: Some(in_token), - path: Box::new(path), - })); - } - } - - Ok(Visibility::Public(VisPublic { pub_token })) - } - - fn parse_crate(input: ParseStream) -> Result { - if input.peek2(Token![::]) { - Ok(Visibility::Inherited) - } else { - Ok(Visibility::Crate(VisCrate { - crate_token: input.parse()?, - })) - } - } - - #[cfg(feature = "full")] - pub(crate) fn is_some(&self) -> bool { - match self { - Visibility::Inherited => false, - _ => true, - } - } - } -} - -#[cfg(feature = "printing")] -mod printing { - use super::*; - use crate::print::TokensOrDefault; - use proc_macro2::TokenStream; - use quote::{ToTokens, TokenStreamExt}; - - #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))] - impl ToTokens for Variant { - fn to_tokens(&self, tokens: &mut TokenStream) { - tokens.append_all(&self.attrs); - self.ident.to_tokens(tokens); - self.fields.to_tokens(tokens); - if let Some((eq_token, disc)) = &self.discriminant { - eq_token.to_tokens(tokens); - disc.to_tokens(tokens); - } - } - } - - #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))] - impl ToTokens for FieldsNamed { - fn to_tokens(&self, tokens: &mut TokenStream) { - self.brace_token.surround(tokens, |tokens| { - self.named.to_tokens(tokens); - }); - } - } - - #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))] - impl ToTokens for FieldsUnnamed { - fn to_tokens(&self, tokens: &mut TokenStream) { - self.paren_token.surround(tokens, |tokens| { - self.unnamed.to_tokens(tokens); - }); - } - } - - #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))] - impl ToTokens for Field { - fn to_tokens(&self, tokens: &mut TokenStream) { - tokens.append_all(&self.attrs); - self.vis.to_tokens(tokens); - if let Some(ident) = &self.ident { - ident.to_tokens(tokens); - TokensOrDefault(&self.colon_token).to_tokens(tokens); - } - self.ty.to_tokens(tokens); - } - } - - #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))] - impl ToTokens for VisPublic { - fn to_tokens(&self, tokens: &mut TokenStream) { - self.pub_token.to_tokens(tokens); - } - } - - #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))] - impl ToTokens for VisCrate { - fn to_tokens(&self, tokens: &mut TokenStream) { - self.crate_token.to_tokens(tokens); - } - } - - #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))] - impl ToTokens for VisRestricted { - fn to_tokens(&self, tokens: &mut TokenStream) { - self.pub_token.to_tokens(tokens); - self.paren_token.surround(tokens, |tokens| { - // TODO: If we have a path which is not "self" or "super" or - // "crate", automatically add the "in" token. - self.in_token.to_tokens(tokens); - self.path.to_tokens(tokens); - }); - } - } -} diff --git a/third-party/vendor/syn/src/derive.rs b/third-party/vendor/syn/src/derive.rs deleted file mode 100644 index af9bb91b..00000000 --- a/third-party/vendor/syn/src/derive.rs +++ /dev/null @@ -1,274 +0,0 @@ -use super::*; -use crate::punctuated::Punctuated; - -ast_struct! { - /// Data structure sent to a `proc_macro_derive` macro. - /// - /// *This type is available only if Syn is built with the `"derive"` feature.* - #[cfg_attr(doc_cfg, doc(cfg(feature = "derive")))] - pub struct DeriveInput { - /// Attributes tagged on the whole struct or enum. - pub attrs: Vec, - - /// Visibility of the struct or enum. - pub vis: Visibility, - - /// Name of the struct or enum. - pub ident: Ident, - - /// Generics required to complete the definition. - pub generics: Generics, - - /// Data within the struct or enum. - pub data: Data, - } -} - -ast_enum_of_structs! { - /// The storage of a struct, enum or union data structure. - /// - /// *This type is available only if Syn is built with the `"derive"` feature.* - /// - /// # Syntax tree enum - /// - /// This type is a [syntax tree enum]. - /// - /// [syntax tree enum]: Expr#syntax-tree-enums - #[cfg_attr(doc_cfg, doc(cfg(feature = "derive")))] - pub enum Data { - /// A struct input to a `proc_macro_derive` macro. - Struct(DataStruct), - - /// An enum input to a `proc_macro_derive` macro. - Enum(DataEnum), - - /// An untagged union input to a `proc_macro_derive` macro. - Union(DataUnion), - } - - do_not_generate_to_tokens -} - -ast_struct! { - /// A struct input to a `proc_macro_derive` macro. - /// - /// *This type is available only if Syn is built with the `"derive"` - /// feature.* - #[cfg_attr(doc_cfg, doc(cfg(feature = "derive")))] - pub struct DataStruct { - pub struct_token: Token![struct], - pub fields: Fields, - pub semi_token: Option, - } -} - -ast_struct! { - /// An enum input to a `proc_macro_derive` macro. - /// - /// *This type is available only if Syn is built with the `"derive"` - /// feature.* - #[cfg_attr(doc_cfg, doc(cfg(feature = "derive")))] - pub struct DataEnum { - pub enum_token: Token![enum], - pub brace_token: token::Brace, - pub variants: Punctuated, - } -} - -ast_struct! { - /// An untagged union input to a `proc_macro_derive` macro. - /// - /// *This type is available only if Syn is built with the `"derive"` - /// feature.* - #[cfg_attr(doc_cfg, doc(cfg(feature = "derive")))] - pub struct DataUnion { - pub union_token: Token![union], - pub fields: FieldsNamed, - } -} - -#[cfg(feature = "parsing")] -pub mod parsing { - use super::*; - use crate::parse::{Parse, ParseStream, Result}; - - #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))] - impl Parse for DeriveInput { - fn parse(input: ParseStream) -> Result { - let attrs = input.call(Attribute::parse_outer)?; - let vis = input.parse::()?; - - let lookahead = input.lookahead1(); - if lookahead.peek(Token![struct]) { - let struct_token = input.parse::()?; - let ident = input.parse::()?; - let generics = input.parse::()?; - let (where_clause, fields, semi) = data_struct(input)?; - Ok(DeriveInput { - attrs, - vis, - ident, - generics: Generics { - where_clause, - ..generics - }, - data: Data::Struct(DataStruct { - struct_token, - fields, - semi_token: semi, - }), - }) - } else if lookahead.peek(Token![enum]) { - let enum_token = input.parse::()?; - let ident = input.parse::()?; - let generics = input.parse::()?; - let (where_clause, brace, variants) = data_enum(input)?; - Ok(DeriveInput { - attrs, - vis, - ident, - generics: Generics { - where_clause, - ..generics - }, - data: Data::Enum(DataEnum { - enum_token, - brace_token: brace, - variants, - }), - }) - } else if lookahead.peek(Token![union]) { - let union_token = input.parse::()?; - let ident = input.parse::()?; - let generics = input.parse::()?; - let (where_clause, fields) = data_union(input)?; - Ok(DeriveInput { - attrs, - vis, - ident, - generics: Generics { - where_clause, - ..generics - }, - data: Data::Union(DataUnion { - union_token, - fields, - }), - }) - } else { - Err(lookahead.error()) - } - } - } - - pub fn data_struct( - input: ParseStream, - ) -> Result<(Option, Fields, Option)> { - let mut lookahead = input.lookahead1(); - let mut where_clause = None; - if lookahead.peek(Token![where]) { - where_clause = Some(input.parse()?); - lookahead = input.lookahead1(); - } - - if where_clause.is_none() && lookahead.peek(token::Paren) { - let fields = input.parse()?; - - lookahead = input.lookahead1(); - if lookahead.peek(Token![where]) { - where_clause = Some(input.parse()?); - lookahead = input.lookahead1(); - } - - if lookahead.peek(Token![;]) { - let semi = input.parse()?; - Ok((where_clause, Fields::Unnamed(fields), Some(semi))) - } else { - Err(lookahead.error()) - } - } else if lookahead.peek(token::Brace) { - let fields = input.parse()?; - Ok((where_clause, Fields::Named(fields), None)) - } else if lookahead.peek(Token![;]) { - let semi = input.parse()?; - Ok((where_clause, Fields::Unit, Some(semi))) - } else { - Err(lookahead.error()) - } - } - - pub fn data_enum( - input: ParseStream, - ) -> Result<( - Option, - token::Brace, - Punctuated, - )> { - let where_clause = input.parse()?; - - let content; - let brace = braced!(content in input); - let variants = content.parse_terminated(Variant::parse)?; - - Ok((where_clause, brace, variants)) - } - - pub fn data_union(input: ParseStream) -> Result<(Option, FieldsNamed)> { - let where_clause = input.parse()?; - let fields = input.parse()?; - Ok((where_clause, fields)) - } -} - -#[cfg(feature = "printing")] -mod printing { - use super::*; - use crate::attr::FilterAttrs; - use crate::print::TokensOrDefault; - use proc_macro2::TokenStream; - use quote::ToTokens; - - #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))] - impl ToTokens for DeriveInput { - fn to_tokens(&self, tokens: &mut TokenStream) { - for attr in self.attrs.outer() { - attr.to_tokens(tokens); - } - self.vis.to_tokens(tokens); - match &self.data { - Data::Struct(d) => d.struct_token.to_tokens(tokens), - Data::Enum(d) => d.enum_token.to_tokens(tokens), - Data::Union(d) => d.union_token.to_tokens(tokens), - } - self.ident.to_tokens(tokens); - self.generics.to_tokens(tokens); - match &self.data { - Data::Struct(data) => match &data.fields { - Fields::Named(fields) => { - self.generics.where_clause.to_tokens(tokens); - fields.to_tokens(tokens); - } - Fields::Unnamed(fields) => { - fields.to_tokens(tokens); - self.generics.where_clause.to_tokens(tokens); - TokensOrDefault(&data.semi_token).to_tokens(tokens); - } - Fields::Unit => { - self.generics.where_clause.to_tokens(tokens); - TokensOrDefault(&data.semi_token).to_tokens(tokens); - } - }, - Data::Enum(data) => { - self.generics.where_clause.to_tokens(tokens); - data.brace_token.surround(tokens, |tokens| { - data.variants.to_tokens(tokens); - }); - } - Data::Union(data) => { - self.generics.where_clause.to_tokens(tokens); - data.fields.to_tokens(tokens); - } - } - } - } -} diff --git a/third-party/vendor/syn/src/discouraged.rs b/third-party/vendor/syn/src/discouraged.rs deleted file mode 100644 index a46129b6..00000000 --- a/third-party/vendor/syn/src/discouraged.rs +++ /dev/null @@ -1,194 +0,0 @@ -//! Extensions to the parsing API with niche applicability. - -use super::*; - -/// Extensions to the `ParseStream` API to support speculative parsing. -pub trait Speculative { - /// Advance this parse stream to the position of a forked parse stream. - /// - /// This is the opposite operation to [`ParseStream::fork`]. You can fork a - /// parse stream, perform some speculative parsing, then join the original - /// stream to the fork to "commit" the parsing from the fork to the main - /// stream. - /// - /// If you can avoid doing this, you should, as it limits the ability to - /// generate useful errors. That said, it is often the only way to parse - /// syntax of the form `A* B*` for arbitrary syntax `A` and `B`. The problem - /// is that when the fork fails to parse an `A`, it's impossible to tell - /// whether that was because of a syntax error and the user meant to provide - /// an `A`, or that the `A`s are finished and it's time to start parsing - /// `B`s. Use with care. - /// - /// Also note that if `A` is a subset of `B`, `A* B*` can be parsed by - /// parsing `B*` and removing the leading members of `A` from the - /// repetition, bypassing the need to involve the downsides associated with - /// speculative parsing. - /// - /// [`ParseStream::fork`]: ParseBuffer::fork - /// - /// # Example - /// - /// There has been chatter about the possibility of making the colons in the - /// turbofish syntax like `path::to::` no longer required by accepting - /// `path::to` in expression position. Specifically, according to [RFC - /// 2544], [`PathSegment`] parsing should always try to consume a following - /// `<` token as the start of generic arguments, and reset to the `<` if - /// that fails (e.g. the token is acting as a less-than operator). - /// - /// This is the exact kind of parsing behavior which requires the "fork, - /// try, commit" behavior that [`ParseStream::fork`] discourages. With - /// `advance_to`, we can avoid having to parse the speculatively parsed - /// content a second time. - /// - /// This change in behavior can be implemented in syn by replacing just the - /// `Parse` implementation for `PathSegment`: - /// - /// ``` - /// # use syn::ext::IdentExt; - /// use syn::parse::discouraged::Speculative; - /// # use syn::parse::{Parse, ParseStream}; - /// # use syn::{Ident, PathArguments, Result, Token}; - /// - /// pub struct PathSegment { - /// pub ident: Ident, - /// pub arguments: PathArguments, - /// } - /// # - /// # impl From for PathSegment - /// # where - /// # T: Into, - /// # { - /// # fn from(ident: T) -> Self { - /// # PathSegment { - /// # ident: ident.into(), - /// # arguments: PathArguments::None, - /// # } - /// # } - /// # } - /// - /// impl Parse for PathSegment { - /// fn parse(input: ParseStream) -> Result { - /// if input.peek(Token![super]) - /// || input.peek(Token![self]) - /// || input.peek(Token![Self]) - /// || input.peek(Token![crate]) - /// { - /// let ident = input.call(Ident::parse_any)?; - /// return Ok(PathSegment::from(ident)); - /// } - /// - /// let ident = input.parse()?; - /// if input.peek(Token![::]) && input.peek3(Token![<]) { - /// return Ok(PathSegment { - /// ident, - /// arguments: PathArguments::AngleBracketed(input.parse()?), - /// }); - /// } - /// if input.peek(Token![<]) && !input.peek(Token![<=]) { - /// let fork = input.fork(); - /// if let Ok(arguments) = fork.parse() { - /// input.advance_to(&fork); - /// return Ok(PathSegment { - /// ident, - /// arguments: PathArguments::AngleBracketed(arguments), - /// }); - /// } - /// } - /// Ok(PathSegment::from(ident)) - /// } - /// } - /// - /// # syn::parse_str::("a").unwrap(); - /// ``` - /// - /// # Drawbacks - /// - /// The main drawback of this style of speculative parsing is in error - /// presentation. Even if the lookahead is the "correct" parse, the error - /// that is shown is that of the "fallback" parse. To use the same example - /// as the turbofish above, take the following unfinished "turbofish": - /// - /// ```text - /// let _ = f<&'a fn(), for<'a> serde::>(); - /// ``` - /// - /// If this is parsed as generic arguments, we can provide the error message - /// - /// ```text - /// error: expected identifier - /// --> src.rs:L:C - /// | - /// L | let _ = f<&'a fn(), for<'a> serde::>(); - /// | ^ - /// ``` - /// - /// but if parsed using the above speculative parsing, it falls back to - /// assuming that the `<` is a less-than when it fails to parse the generic - /// arguments, and tries to interpret the `&'a` as the start of a labelled - /// loop, resulting in the much less helpful error - /// - /// ```text - /// error: expected `:` - /// --> src.rs:L:C - /// | - /// L | let _ = f<&'a fn(), for<'a> serde::>(); - /// | ^^ - /// ``` - /// - /// This can be mitigated with various heuristics (two examples: show both - /// forks' parse errors, or show the one that consumed more tokens), but - /// when you can control the grammar, sticking to something that can be - /// parsed LL(3) and without the LL(*) speculative parsing this makes - /// possible, displaying reasonable errors becomes much more simple. - /// - /// [RFC 2544]: https://github.com/rust-lang/rfcs/pull/2544 - /// [`PathSegment`]: crate::PathSegment - /// - /// # Performance - /// - /// This method performs a cheap fixed amount of work that does not depend - /// on how far apart the two streams are positioned. - /// - /// # Panics - /// - /// The forked stream in the argument of `advance_to` must have been - /// obtained by forking `self`. Attempting to advance to any other stream - /// will cause a panic. - fn advance_to(&self, fork: &Self); -} - -impl<'a> Speculative for ParseBuffer<'a> { - fn advance_to(&self, fork: &Self) { - if !crate::buffer::same_scope(self.cursor(), fork.cursor()) { - panic!("Fork was not derived from the advancing parse stream"); - } - - let (self_unexp, self_sp) = inner_unexpected(self); - let (fork_unexp, fork_sp) = inner_unexpected(fork); - if !Rc::ptr_eq(&self_unexp, &fork_unexp) { - match (fork_sp, self_sp) { - // Unexpected set on the fork, but not on `self`, copy it over. - (Some(span), None) => { - self_unexp.set(Unexpected::Some(span)); - } - // Unexpected unset. Use chain to propagate errors from fork. - (None, None) => { - fork_unexp.set(Unexpected::Chain(self_unexp)); - - // Ensure toplevel 'unexpected' tokens from the fork don't - // bubble up the chain by replacing the root `unexpected` - // pointer, only 'unexpected' tokens from existing group - // parsers should bubble. - fork.unexpected - .set(Some(Rc::new(Cell::new(Unexpected::None)))); - } - // Unexpected has been set on `self`. No changes needed. - (_, Some(_)) => {} - } - } - - // See comment on `cell` in the struct definition. - self.cell - .set(unsafe { mem::transmute::>(fork.cursor()) }); - } -} diff --git a/third-party/vendor/syn/src/drops.rs b/third-party/vendor/syn/src/drops.rs deleted file mode 100644 index 89b42d82..00000000 --- a/third-party/vendor/syn/src/drops.rs +++ /dev/null @@ -1,58 +0,0 @@ -use std::iter; -use std::mem::ManuallyDrop; -use std::ops::{Deref, DerefMut}; -use std::option; -use std::slice; - -#[repr(transparent)] -pub(crate) struct NoDrop(ManuallyDrop); - -impl NoDrop { - pub(crate) fn new(value: T) -> Self - where - T: TrivialDrop, - { - NoDrop(ManuallyDrop::new(value)) - } -} - -impl Deref for NoDrop { - type Target = T; - fn deref(&self) -> &Self::Target { - &self.0 - } -} - -impl DerefMut for NoDrop { - fn deref_mut(&mut self) -> &mut Self::Target { - &mut self.0 - } -} - -pub(crate) trait TrivialDrop {} - -impl TrivialDrop for iter::Empty {} -impl<'a, T> TrivialDrop for slice::Iter<'a, T> {} -impl<'a, T> TrivialDrop for slice::IterMut<'a, T> {} -impl<'a, T> TrivialDrop for option::IntoIter<&'a T> {} -impl<'a, T> TrivialDrop for option::IntoIter<&'a mut T> {} - -#[test] -fn test_needs_drop() { - use std::mem::needs_drop; - - struct NeedsDrop; - - impl Drop for NeedsDrop { - fn drop(&mut self) {} - } - - assert!(needs_drop::()); - - // Test each of the types with a handwritten TrivialDrop impl above. - assert!(!needs_drop::>()); - assert!(!needs_drop::>()); - assert!(!needs_drop::>()); - assert!(!needs_drop::>()); - assert!(!needs_drop::>()); -} diff --git a/third-party/vendor/syn/src/error.rs b/third-party/vendor/syn/src/error.rs deleted file mode 100644 index e301367d..00000000 --- a/third-party/vendor/syn/src/error.rs +++ /dev/null @@ -1,428 +0,0 @@ -#[cfg(feature = "parsing")] -use crate::buffer::Cursor; -use crate::thread::ThreadBound; -use proc_macro2::{ - Delimiter, Group, Ident, LexError, Literal, Punct, Spacing, Span, TokenStream, TokenTree, -}; -#[cfg(feature = "printing")] -use quote::ToTokens; -use std::fmt::{self, Debug, Display}; -use std::iter::FromIterator; -use std::slice; -use std::vec; - -/// The result of a Syn parser. -pub type Result = std::result::Result; - -/// Error returned when a Syn parser cannot parse the input tokens. -/// -/// # Error reporting in proc macros -/// -/// The correct way to report errors back to the compiler from a procedural -/// macro is by emitting an appropriately spanned invocation of -/// [`compile_error!`] in the generated code. This produces a better diagnostic -/// message than simply panicking the macro. -/// -/// [`compile_error!`]: std::compile_error! -/// -/// When parsing macro input, the [`parse_macro_input!`] macro handles the -/// conversion to `compile_error!` automatically. -/// -/// [`parse_macro_input!`]: crate::parse_macro_input! -/// -/// ``` -/// # extern crate proc_macro; -/// # -/// use proc_macro::TokenStream; -/// use syn::{parse_macro_input, AttributeArgs, ItemFn}; -/// -/// # const IGNORE: &str = stringify! { -/// #[proc_macro_attribute] -/// # }; -/// pub fn my_attr(args: TokenStream, input: TokenStream) -> TokenStream { -/// let args = parse_macro_input!(args as AttributeArgs); -/// let input = parse_macro_input!(input as ItemFn); -/// -/// /* ... */ -/// # TokenStream::new() -/// } -/// ``` -/// -/// For errors that arise later than the initial parsing stage, the -/// [`.to_compile_error()`] or [`.into_compile_error()`] methods can be used to -/// perform an explicit conversion to `compile_error!`. -/// -/// [`.to_compile_error()`]: Error::to_compile_error -/// [`.into_compile_error()`]: Error::into_compile_error -/// -/// ``` -/// # extern crate proc_macro; -/// # -/// # use proc_macro::TokenStream; -/// # use syn::{parse_macro_input, DeriveInput}; -/// # -/// # const IGNORE: &str = stringify! { -/// #[proc_macro_derive(MyDerive)] -/// # }; -/// pub fn my_derive(input: TokenStream) -> TokenStream { -/// let input = parse_macro_input!(input as DeriveInput); -/// -/// // fn(DeriveInput) -> syn::Result -/// expand::my_derive(input) -/// .unwrap_or_else(syn::Error::into_compile_error) -/// .into() -/// } -/// # -/// # mod expand { -/// # use proc_macro2::TokenStream; -/// # use syn::{DeriveInput, Result}; -/// # -/// # pub fn my_derive(input: DeriveInput) -> Result { -/// # unimplemented!() -/// # } -/// # } -/// ``` -pub struct Error { - messages: Vec, -} - -struct ErrorMessage { - // Span is implemented as an index into a thread-local interner to keep the - // size small. It is not safe to access from a different thread. We want - // errors to be Send and Sync to play nicely with the Failure crate, so pin - // the span we're given to its original thread and assume it is - // Span::call_site if accessed from any other thread. - start_span: ThreadBound, - end_span: ThreadBound, - message: String, -} - -#[cfg(test)] -struct _Test -where - Error: Send + Sync; - -impl Error { - /// Usually the [`ParseStream::error`] method will be used instead, which - /// automatically uses the correct span from the current position of the - /// parse stream. - /// - /// Use `Error::new` when the error needs to be triggered on some span other - /// than where the parse stream is currently positioned. - /// - /// [`ParseStream::error`]: crate::parse::ParseBuffer::error - /// - /// # Example - /// - /// ``` - /// use syn::{Error, Ident, LitStr, Result, Token}; - /// use syn::parse::ParseStream; - /// - /// // Parses input that looks like `name = "string"` where the key must be - /// // the identifier `name` and the value may be any string literal. - /// // Returns the string literal. - /// fn parse_name(input: ParseStream) -> Result { - /// let name_token: Ident = input.parse()?; - /// if name_token != "name" { - /// // Trigger an error not on the current position of the stream, - /// // but on the position of the unexpected identifier. - /// return Err(Error::new(name_token.span(), "expected `name`")); - /// } - /// input.parse::()?; - /// let s: LitStr = input.parse()?; - /// Ok(s) - /// } - /// ``` - pub fn new(span: Span, message: T) -> Self { - return new(span, message.to_string()); - - fn new(span: Span, message: String) -> Error { - Error { - messages: vec![ErrorMessage { - start_span: ThreadBound::new(span), - end_span: ThreadBound::new(span), - message, - }], - } - } - } - - /// Creates an error with the specified message spanning the given syntax - /// tree node. - /// - /// Unlike the `Error::new` constructor, this constructor takes an argument - /// `tokens` which is a syntax tree node. This allows the resulting `Error` - /// to attempt to span all tokens inside of `tokens`. While you would - /// typically be able to use the `Spanned` trait with the above `Error::new` - /// constructor, implementation limitations today mean that - /// `Error::new_spanned` may provide a higher-quality error message on - /// stable Rust. - /// - /// When in doubt it's recommended to stick to `Error::new` (or - /// `ParseStream::error`)! - #[cfg(feature = "printing")] - pub fn new_spanned(tokens: T, message: U) -> Self { - return new_spanned(tokens.into_token_stream(), message.to_string()); - - fn new_spanned(tokens: TokenStream, message: String) -> Error { - let mut iter = tokens.into_iter(); - let start = iter.next().map_or_else(Span::call_site, |t| t.span()); - let end = iter.last().map_or(start, |t| t.span()); - Error { - messages: vec![ErrorMessage { - start_span: ThreadBound::new(start), - end_span: ThreadBound::new(end), - message, - }], - } - } - } - - /// The source location of the error. - /// - /// Spans are not thread-safe so this function returns `Span::call_site()` - /// if called from a different thread than the one on which the `Error` was - /// originally created. - pub fn span(&self) -> Span { - let start = match self.messages[0].start_span.get() { - Some(span) => *span, - None => return Span::call_site(), - }; - let end = match self.messages[0].end_span.get() { - Some(span) => *span, - None => return Span::call_site(), - }; - start.join(end).unwrap_or(start) - } - - /// Render the error as an invocation of [`compile_error!`]. - /// - /// The [`parse_macro_input!`] macro provides a convenient way to invoke - /// this method correctly in a procedural macro. - /// - /// [`compile_error!`]: std::compile_error! - /// [`parse_macro_input!`]: crate::parse_macro_input! - pub fn to_compile_error(&self) -> TokenStream { - self.messages - .iter() - .map(ErrorMessage::to_compile_error) - .collect() - } - - /// Render the error as an invocation of [`compile_error!`]. - /// - /// [`compile_error!`]: std::compile_error! - /// - /// # Example - /// - /// ``` - /// # extern crate proc_macro; - /// # - /// use proc_macro::TokenStream; - /// use syn::{parse_macro_input, DeriveInput, Error}; - /// - /// # const _: &str = stringify! { - /// #[proc_macro_derive(MyTrait)] - /// # }; - /// pub fn derive_my_trait(input: TokenStream) -> TokenStream { - /// let input = parse_macro_input!(input as DeriveInput); - /// my_trait::expand(input) - /// .unwrap_or_else(Error::into_compile_error) - /// .into() - /// } - /// - /// mod my_trait { - /// use proc_macro2::TokenStream; - /// use syn::{DeriveInput, Result}; - /// - /// pub(crate) fn expand(input: DeriveInput) -> Result { - /// /* ... */ - /// # unimplemented!() - /// } - /// } - /// ``` - pub fn into_compile_error(self) -> TokenStream { - self.to_compile_error() - } - - /// Add another error message to self such that when `to_compile_error()` is - /// called, both errors will be emitted together. - pub fn combine(&mut self, another: Error) { - self.messages.extend(another.messages); - } -} - -impl ErrorMessage { - fn to_compile_error(&self) -> TokenStream { - let start = self - .start_span - .get() - .cloned() - .unwrap_or_else(Span::call_site); - let end = self.end_span.get().cloned().unwrap_or_else(Span::call_site); - - // compile_error!($message) - TokenStream::from_iter(vec![ - TokenTree::Ident(Ident::new("compile_error", start)), - TokenTree::Punct({ - let mut punct = Punct::new('!', Spacing::Alone); - punct.set_span(start); - punct - }), - TokenTree::Group({ - let mut group = Group::new(Delimiter::Brace, { - TokenStream::from_iter(vec![TokenTree::Literal({ - let mut string = Literal::string(&self.message); - string.set_span(end); - string - })]) - }); - group.set_span(end); - group - }), - ]) - } -} - -#[cfg(feature = "parsing")] -pub fn new_at(scope: Span, cursor: Cursor, message: T) -> Error { - if cursor.eof() { - Error::new(scope, format!("unexpected end of input, {}", message)) - } else { - let span = crate::buffer::open_span_of_group(cursor); - Error::new(span, message) - } -} - -#[cfg(all(feature = "parsing", any(feature = "full", feature = "derive")))] -pub fn new2(start: Span, end: Span, message: T) -> Error { - return new2(start, end, message.to_string()); - - fn new2(start: Span, end: Span, message: String) -> Error { - Error { - messages: vec![ErrorMessage { - start_span: ThreadBound::new(start), - end_span: ThreadBound::new(end), - message, - }], - } - } -} - -impl Debug for Error { - fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { - if self.messages.len() == 1 { - formatter - .debug_tuple("Error") - .field(&self.messages[0]) - .finish() - } else { - formatter - .debug_tuple("Error") - .field(&self.messages) - .finish() - } - } -} - -impl Debug for ErrorMessage { - fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { - Debug::fmt(&self.message, formatter) - } -} - -impl Display for Error { - fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { - formatter.write_str(&self.messages[0].message) - } -} - -impl Clone for Error { - fn clone(&self) -> Self { - Error { - messages: self.messages.clone(), - } - } -} - -impl Clone for ErrorMessage { - fn clone(&self) -> Self { - let start = self - .start_span - .get() - .cloned() - .unwrap_or_else(Span::call_site); - let end = self.end_span.get().cloned().unwrap_or_else(Span::call_site); - ErrorMessage { - start_span: ThreadBound::new(start), - end_span: ThreadBound::new(end), - message: self.message.clone(), - } - } -} - -impl std::error::Error for Error {} - -impl From for Error { - fn from(err: LexError) -> Self { - Error::new(err.span(), "lex error") - } -} - -impl IntoIterator for Error { - type Item = Error; - type IntoIter = IntoIter; - - fn into_iter(self) -> Self::IntoIter { - IntoIter { - messages: self.messages.into_iter(), - } - } -} - -pub struct IntoIter { - messages: vec::IntoIter, -} - -impl Iterator for IntoIter { - type Item = Error; - - fn next(&mut self) -> Option { - Some(Error { - messages: vec![self.messages.next()?], - }) - } -} - -impl<'a> IntoIterator for &'a Error { - type Item = Error; - type IntoIter = Iter<'a>; - - fn into_iter(self) -> Self::IntoIter { - Iter { - messages: self.messages.iter(), - } - } -} - -pub struct Iter<'a> { - messages: slice::Iter<'a, ErrorMessage>, -} - -impl<'a> Iterator for Iter<'a> { - type Item = Error; - - fn next(&mut self) -> Option { - Some(Error { - messages: vec![self.messages.next()?.clone()], - }) - } -} - -impl Extend for Error { - fn extend>(&mut self, iter: T) { - for err in iter { - self.combine(err); - } - } -} diff --git a/third-party/vendor/syn/src/export.rs b/third-party/vendor/syn/src/export.rs deleted file mode 100644 index f478d091..00000000 --- a/third-party/vendor/syn/src/export.rs +++ /dev/null @@ -1,39 +0,0 @@ -pub use std::clone::Clone; -pub use std::cmp::{Eq, PartialEq}; -pub use std::default::Default; -pub use std::fmt::{self, Debug, Formatter}; -pub use std::hash::{Hash, Hasher}; -pub use std::marker::Copy; -pub use std::option::Option::{None, Some}; -pub use std::result::Result::{Err, Ok}; - -#[cfg(feature = "printing")] -pub extern crate quote; - -pub use proc_macro2::{Span, TokenStream as TokenStream2}; - -#[cfg(feature = "parsing")] -pub use crate::group::{parse_braces, parse_brackets, parse_parens}; - -pub use crate::span::IntoSpans; - -#[cfg(all( - not(all(target_arch = "wasm32", any(target_os = "unknown", target_os = "wasi"))), - feature = "proc-macro" -))] -pub use proc_macro::TokenStream; - -#[cfg(feature = "printing")] -pub use quote::{ToTokens, TokenStreamExt}; - -#[allow(non_camel_case_types)] -pub type bool = help::Bool; -#[allow(non_camel_case_types)] -pub type str = help::Str; - -mod help { - pub type Bool = bool; - pub type Str = str; -} - -pub struct private(pub(crate) ()); diff --git a/third-party/vendor/syn/src/expr.rs b/third-party/vendor/syn/src/expr.rs deleted file mode 100644 index 93a59b0e..00000000 --- a/third-party/vendor/syn/src/expr.rs +++ /dev/null @@ -1,3558 +0,0 @@ -use super::*; -use crate::punctuated::Punctuated; -#[cfg(feature = "full")] -use crate::reserved::Reserved; -use proc_macro2::{Span, TokenStream}; -#[cfg(feature = "printing")] -use quote::IdentFragment; -#[cfg(feature = "printing")] -use std::fmt::{self, Display}; -use std::hash::{Hash, Hasher}; -#[cfg(feature = "parsing")] -use std::mem; - -ast_enum_of_structs! { - /// A Rust expression. - /// - /// *This type is available only if Syn is built with the `"derive"` or `"full"` - /// feature, but most of the variants are not available unless "full" is enabled.* - /// - /// # Syntax tree enums - /// - /// This type is a syntax tree enum. In Syn this and other syntax tree enums - /// are designed to be traversed using the following rebinding idiom. - /// - /// ``` - /// # use syn::Expr; - /// # - /// # fn example(expr: Expr) { - /// # const IGNORE: &str = stringify! { - /// let expr: Expr = /* ... */; - /// # }; - /// match expr { - /// Expr::MethodCall(expr) => { - /// /* ... */ - /// } - /// Expr::Cast(expr) => { - /// /* ... */ - /// } - /// Expr::If(expr) => { - /// /* ... */ - /// } - /// - /// /* ... */ - /// # _ => {} - /// # } - /// # } - /// ``` - /// - /// We begin with a variable `expr` of type `Expr` that has no fields - /// (because it is an enum), and by matching on it and rebinding a variable - /// with the same name `expr` we effectively imbue our variable with all of - /// the data fields provided by the variant that it turned out to be. So for - /// example above if we ended up in the `MethodCall` case then we get to use - /// `expr.receiver`, `expr.args` etc; if we ended up in the `If` case we get - /// to use `expr.cond`, `expr.then_branch`, `expr.else_branch`. - /// - /// This approach avoids repeating the variant names twice on every line. - /// - /// ``` - /// # use syn::{Expr, ExprMethodCall}; - /// # - /// # fn example(expr: Expr) { - /// // Repetitive; recommend not doing this. - /// match expr { - /// Expr::MethodCall(ExprMethodCall { method, args, .. }) => { - /// # } - /// # _ => {} - /// # } - /// # } - /// ``` - /// - /// In general, the name to which a syntax tree enum variant is bound should - /// be a suitable name for the complete syntax tree enum type. - /// - /// ``` - /// # use syn::{Expr, ExprField}; - /// # - /// # fn example(discriminant: ExprField) { - /// // Binding is called `base` which is the name I would use if I were - /// // assigning `*discriminant.base` without an `if let`. - /// if let Expr::Tuple(base) = *discriminant.base { - /// # } - /// # } - /// ``` - /// - /// A sign that you may not be choosing the right variable names is if you - /// see names getting repeated in your code, like accessing - /// `receiver.receiver` or `pat.pat` or `cond.cond`. - #[cfg_attr(doc_cfg, doc(cfg(any(feature = "full", feature = "derive"))))] - #[cfg_attr(not(syn_no_non_exhaustive), non_exhaustive)] - pub enum Expr { - /// A slice literal expression: `[a, b, c, d]`. - Array(ExprArray), - - /// An assignment expression: `a = compute()`. - Assign(ExprAssign), - - /// A compound assignment expression: `counter += 1`. - AssignOp(ExprAssignOp), - - /// An async block: `async { ... }`. - Async(ExprAsync), - - /// An await expression: `fut.await`. - Await(ExprAwait), - - /// A binary operation: `a + b`, `a * b`. - Binary(ExprBinary), - - /// A blocked scope: `{ ... }`. - Block(ExprBlock), - - /// A box expression: `box f`. - Box(ExprBox), - - /// A `break`, with an optional label to break and an optional - /// expression. - Break(ExprBreak), - - /// A function call expression: `invoke(a, b)`. - Call(ExprCall), - - /// A cast expression: `foo as f64`. - Cast(ExprCast), - - /// A closure expression: `|a, b| a + b`. - Closure(ExprClosure), - - /// A `continue`, with an optional label. - Continue(ExprContinue), - - /// Access of a named struct field (`obj.k`) or unnamed tuple struct - /// field (`obj.0`). - Field(ExprField), - - /// A for loop: `for pat in expr { ... }`. - ForLoop(ExprForLoop), - - /// An expression contained within invisible delimiters. - /// - /// This variant is important for faithfully representing the precedence - /// of expressions and is related to `None`-delimited spans in a - /// `TokenStream`. - Group(ExprGroup), - - /// An `if` expression with an optional `else` block: `if expr { ... } - /// else { ... }`. - /// - /// The `else` branch expression may only be an `If` or `Block` - /// expression, not any of the other types of expression. - If(ExprIf), - - /// A square bracketed indexing expression: `vector[2]`. - Index(ExprIndex), - - /// A `let` guard: `let Some(x) = opt`. - Let(ExprLet), - - /// A literal in place of an expression: `1`, `"foo"`. - Lit(ExprLit), - - /// Conditionless loop: `loop { ... }`. - Loop(ExprLoop), - - /// A macro invocation expression: `format!("{}", q)`. - Macro(ExprMacro), - - /// A `match` expression: `match n { Some(n) => {}, None => {} }`. - Match(ExprMatch), - - /// A method call expression: `x.foo::(a, b)`. - MethodCall(ExprMethodCall), - - /// A parenthesized expression: `(a + b)`. - Paren(ExprParen), - - /// A path like `std::mem::replace` possibly containing generic - /// parameters and a qualified self-type. - /// - /// A plain identifier like `x` is a path of length 1. - Path(ExprPath), - - /// A range expression: `1..2`, `1..`, `..2`, `1..=2`, `..=2`. - Range(ExprRange), - - /// A referencing operation: `&a` or `&mut a`. - Reference(ExprReference), - - /// An array literal constructed from one repeated element: `[0u8; N]`. - Repeat(ExprRepeat), - - /// A `return`, with an optional value to be returned. - Return(ExprReturn), - - /// A struct literal expression: `Point { x: 1, y: 1 }`. - /// - /// The `rest` provides the value of the remaining fields as in `S { a: - /// 1, b: 1, ..rest }`. - Struct(ExprStruct), - - /// A try-expression: `expr?`. - Try(ExprTry), - - /// A try block: `try { ... }`. - TryBlock(ExprTryBlock), - - /// A tuple expression: `(a, b, c, d)`. - Tuple(ExprTuple), - - /// A type ascription expression: `foo: f64`. - Type(ExprType), - - /// A unary operation: `!x`, `*x`. - Unary(ExprUnary), - - /// An unsafe block: `unsafe { ... }`. - Unsafe(ExprUnsafe), - - /// Tokens in expression position not interpreted by Syn. - Verbatim(TokenStream), - - /// A while loop: `while expr { ... }`. - While(ExprWhile), - - /// A yield expression: `yield expr`. - Yield(ExprYield), - - // Not public API. - // - // For testing exhaustiveness in downstream code, use the following idiom: - // - // match expr { - // Expr::Array(expr) => {...} - // Expr::Assign(expr) => {...} - // ... - // Expr::Yield(expr) => {...} - // - // #[cfg_attr(test, deny(non_exhaustive_omitted_patterns))] - // _ => { /* some sane fallback */ } - // } - // - // This way we fail your tests but don't break your library when adding - // a variant. You will be notified by a test failure when a variant is - // added, so that you can add code to handle it, but your library will - // continue to compile and work for downstream users in the interim. - #[cfg(syn_no_non_exhaustive)] - #[doc(hidden)] - __NonExhaustive, - } -} - -ast_struct! { - /// A slice literal expression: `[a, b, c, d]`. - /// - /// *This type is available only if Syn is built with the `"full"` feature.* - #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))] - pub struct ExprArray #full { - pub attrs: Vec, - pub bracket_token: token::Bracket, - pub elems: Punctuated, - } -} - -ast_struct! { - /// An assignment expression: `a = compute()`. - /// - /// *This type is available only if Syn is built with the `"full"` feature.* - #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))] - pub struct ExprAssign #full { - pub attrs: Vec, - pub left: Box, - pub eq_token: Token![=], - pub right: Box, - } -} - -ast_struct! { - /// A compound assignment expression: `counter += 1`. - /// - /// *This type is available only if Syn is built with the `"full"` feature.* - #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))] - pub struct ExprAssignOp #full { - pub attrs: Vec, - pub left: Box, - pub op: BinOp, - pub right: Box, - } -} - -ast_struct! { - /// An async block: `async { ... }`. - /// - /// *This type is available only if Syn is built with the `"full"` feature.* - #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))] - pub struct ExprAsync #full { - pub attrs: Vec, - pub async_token: Token![async], - pub capture: Option, - pub block: Block, - } -} - -ast_struct! { - /// An await expression: `fut.await`. - /// - /// *This type is available only if Syn is built with the `"full"` feature.* - #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))] - pub struct ExprAwait #full { - pub attrs: Vec, - pub base: Box, - pub dot_token: Token![.], - pub await_token: token::Await, - } -} - -ast_struct! { - /// A binary operation: `a + b`, `a * b`. - /// - /// *This type is available only if Syn is built with the `"derive"` or - /// `"full"` feature.* - #[cfg_attr(doc_cfg, doc(cfg(any(feature = "full", feature = "derive"))))] - pub struct ExprBinary { - pub attrs: Vec, - pub left: Box, - pub op: BinOp, - pub right: Box, - } -} - -ast_struct! { - /// A blocked scope: `{ ... }`. - /// - /// *This type is available only if Syn is built with the `"full"` feature.* - #[cfg_attr(doc_cfg, doc(cfg(feature = "full")))] - pub struct ExprBlock #full { - pub attrs: Vec, - pub label: Option