зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1744669 - Bulk update of rust crates. a. r=emilio
This updates all crates that can be updated with no addition of new crates, that start with letter a. Differential Revision: https://phabricator.services.mozilla.com/D133027
This commit is contained in:
Родитель
64905dd854
Коммит
48c99f617b
|
@ -49,9 +49,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "anyhow"
|
||||
version = "1.0.41"
|
||||
version = "1.0.51"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "15af2628f6890fe2609a3b91bef4c83450512802e59489f9c1cb1fa5df064a61"
|
||||
checksum = "8b26702f315f53b6071259e15dd9d64528213b44d61de1ec926eca7715d62203"
|
||||
|
||||
[[package]]
|
||||
name = "app_services_logger"
|
||||
|
@ -78,9 +78,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "arbitrary"
|
||||
version = "1.0.1"
|
||||
version = "1.0.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "237430fd6ed3740afe94eefcc278ae21e050285be882804e0d6e8695f0c94691"
|
||||
checksum = "510c76ecefdceada737ea728f4f9a84bd2e1ef29f1ba555e560940fe279954de"
|
||||
dependencies = [
|
||||
"derive_arbitrary",
|
||||
]
|
||||
|
@ -99,18 +99,18 @@ checksum = "23b62fc65de8e4e7f52534fb52b0f3ed04746ae267519eef2a83941e8085068b"
|
|||
|
||||
[[package]]
|
||||
name = "arrayvec"
|
||||
version = "0.7.1"
|
||||
version = "0.7.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "be4dc07131ffa69b8072d35f5007352af944213cde02545e2103680baed38fcd"
|
||||
checksum = "8da52d66c7071e2e3fa2a1e5c6d088fec47b593032b254f5e980de8ea54454d6"
|
||||
dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ash"
|
||||
version = "0.33.0+1.2.186"
|
||||
version = "0.33.3+1.2.191"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a2142f1fa77cc4d24ffd2f24dc84f88ce5b1e588d524f10fb473a04b93aef14f"
|
||||
checksum = "cc4f1d82f164f838ae413296d1131aa6fa79b917d25bebaa7033d25620c09219"
|
||||
dependencies = [
|
||||
"libloading 0.7.0",
|
||||
]
|
||||
|
@ -132,9 +132,9 @@ checksum = "e91831deabf0d6d7ec49552e489aed63b7456a7a3c46cff62adad428110b0af0"
|
|||
|
||||
[[package]]
|
||||
name = "async-trait"
|
||||
version = "0.1.42"
|
||||
version = "0.1.51"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8d3a45e77e34375a7923b1e8febb049bb011f064714a8e17a1a616fef01da13d"
|
||||
checksum = "44318e776df68115a881de9a8fd1b9e53368d7a4a5ce4cc48517da3393233a5e"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
|
@ -149,9 +149,9 @@ checksum = "64f46ca51dca4837f1520754d1c8c36636356b81553d928dc9c177025369a06e"
|
|||
|
||||
[[package]]
|
||||
name = "atomic_refcell"
|
||||
version = "0.1.7"
|
||||
version = "0.1.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "681b971236e0f76b20fcafca0236b8718c9186ee778d67cd78bd5f28fd85427f"
|
||||
checksum = "73b5e5f48b927f04e952dedc932f31995a65a0bf65ec971c74436e51bf6e970d"
|
||||
|
||||
[[package]]
|
||||
name = "atty"
|
||||
|
@ -5693,7 +5693,7 @@ name = "wgpu-core"
|
|||
version = "0.11.0"
|
||||
source = "git+https://github.com/gfx-rs/wgpu?rev=28ba9d8#28ba9d86ebb30173c910303b1ceb38e101a8a4a1"
|
||||
dependencies = [
|
||||
"arrayvec 0.7.1",
|
||||
"arrayvec 0.7.2",
|
||||
"bitflags",
|
||||
"cfg_aliases",
|
||||
"codespan-reporting",
|
||||
|
@ -5716,7 +5716,7 @@ name = "wgpu-hal"
|
|||
version = "0.11.2"
|
||||
source = "git+https://github.com/gfx-rs/wgpu?rev=28ba9d8#28ba9d86ebb30173c910303b1ceb38e101a8a4a1"
|
||||
dependencies = [
|
||||
"arrayvec 0.7.1",
|
||||
"arrayvec 0.7.2",
|
||||
"ash",
|
||||
"bit-set",
|
||||
"bitflags",
|
||||
|
|
|
@ -1 +1 @@
|
|||
{"files":{"Cargo.toml":"05c1bbd8a9f36fba15398f0dc3634198aca3c3f6887b085b9812d21f4f33c450","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"23f18e03dc49df91622fe2a76176497404e46ced8a715d9d2b67a7446571cca3","README.md":"4a58a26808c92aae6265a60e21745bb2891a60cf1d69985fc05d26b77c2b9a79","build.rs":"afa03584629443ec723ca4e99bd087d5f07602d8640772f6f57c8e3847f75ae6","src/backtrace.rs":"a1a52f9874f0aa1382fb404f029c6fa88e53afe38fb2417877d5711f1f2b90c9","src/chain.rs":"1627608ce95c3484d26e1742a1b8b533b74c6159916b717bacffae3ae53731f9","src/context.rs":"559478ae785ce913523aa21358cc1561ef4b0b95c5c87675a77890364c0162fe","src/error.rs":"2aa93ec95f16980037c244e94fa8ac75f8b20ac22530fe45a24550d1878eb0b5","src/fmt.rs":"c2d4aad6ce20625a70a7c091e3087b6a2c19a4a87c7a12edb4c98978307245ea","src/kind.rs":"ccf5d8075d44b03cc69c0478ee5e5b3a02d4f2e7cecb37588b30043d3fcdf65f","src/lib.rs":"c0a0f94d85f5cc4aed37048ca12d8652da85b50f0999d998903ccd3ebf043eec","src/macros.rs":"88daf58370b2fcc93c43ebd5b9c1659bf5460c972681b63d89d51132126e5560","src/ptr.rs":"f1ece995b5be064773ee3d516710b4948b0bee3c237786d9988c7d2acc52c95c","src/wrapper.rs":"1229beca67dbd95ca77c9ecce282272acc55276c267c58cb73a75388b4693dda","tests/common/mod.rs":"f9088c2d7afafa64ff730b629272045b776bfafc2f5957508242da630635f2e1","tests/compiletest.rs":"022a8e400ef813d7ea1875b944549cee5125f6a995dc33e93b48cba3e1b57bd1","tests/drop/mod.rs":"382956f4bd3dcd1f6036efb8f11193595a7c60e0a5dbf5f2da149f1f25183abf","tests/test_autotrait.rs":"981e792db353be2f14c7a1cabe43b5f1329c168cb7679077cc2be786a0920d48","tests/test_backtrace.rs":"0e50edbb33b6bd07ba89ff3db72fb7c688ba2a4371fccdbbb20309ab02948b6a","tests/test_boxed.rs":"98a45325b1e86d4c5d3094ab99cd1ada1f771c505d2d7322f0afcbe7bdb71cfa","tests/test_chain.rs":"f28efeae7395d1c395e6f1a647b4199c25a00410ade45248c145c6fcf2fb448a","tests/test_context.rs":"f82c915b182df1a604a4cd558a03b1a821414983d6f6af6822398104cea70676","tests/test_convert.rs":"cae1c941727f2371b2439ff95b2628f810cfb2f77431a0807de32db84c5844e1","tests/test_downcast.rs":"e9dc236dad1cbb8b7ad74a0d87d328f23a585fbb55670b8fe55a9a2644041c5c","tests/test_ffi.rs":"d0cb4c1d6d9154090982dee72ae3ebe05a5981f976058c3250f1c9da5a45edef","tests/test_fmt.rs":"17572596f257aac9aa2ec4620e292ca6a954128b94772bb948399fab53832e70","tests/test_macros.rs":"0288c879c4735a8d317560baa3d4a6efbf1435d8ec350c5cb12cc1ba7c484080","tests/test_repr.rs":"dbb9b04ddbe1ab31eb5331ea69f05bb3a147299da2275a3d4dcc92947b5591b9","tests/test_source.rs":"b80723cf635a4f8c4df21891b34bfab9ed2b2aa407e7a2f826d24e334cd5f88e","tests/ui/no-impl.rs":"fab6cbf2f6ea510b86f567dfb3b7c31250a9fd71ae5d110dbb9188be569ec593","tests/ui/no-impl.stderr":"7dd1b84a267c83121d9f85a9c1aadc072a863ec324e170af4d7d19516f0f526c","tests/ui/temporary-value.rs":"4dcc96271b2403e6372cf4cfc813445e5ce4365fc6e156b6bc38274098499a70","tests/ui/temporary-value.stderr":"4b0cceae9e9b27fe2594e6c02bb3e3fd9965ed04498738e5877934dab807b50f"},"package":"15af2628f6890fe2609a3b91bef4c83450512802e59489f9c1cb1fa5df064a61"}
|
||||
{"files":{"Cargo.toml":"5e3414ce23940106f95102f85e643cb5bed5e8ed9027557963c728d5f46d5586","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"23f18e03dc49df91622fe2a76176497404e46ced8a715d9d2b67a7446571cca3","README.md":"f6bffe3676b128afe14aaf91c972d69c37f2e5afe4e02b99a974f7b7393f4cda","build.rs":"b6ee548cb30aba0a4a7ff92379478fcf94ef246b892da8e2134ee2d9575bf08c","rust-toolchain.toml":"6bbb61302978c736b2da03e4fb40e3beab908f85d533ab46fd541e637b5f3e0f","src/backtrace.rs":"a1a52f9874f0aa1382fb404f029c6fa88e53afe38fb2417877d5711f1f2b90c9","src/chain.rs":"6edefc5f3c7d69683095862e54e3bb56faba5b3387bf2eeaed429da090007a0a","src/context.rs":"559478ae785ce913523aa21358cc1561ef4b0b95c5c87675a77890364c0162fe","src/ensure.rs":"98b2f4a7923e06cf6558b0a15f39a7c7ff3d36711e217475c6a93690cd58b7a1","src/error.rs":"33a0f6c49d2c5d08b8d027aa930be75ece822331d6e6b28db74520ea69587cbc","src/fmt.rs":"c2d4aad6ce20625a70a7c091e3087b6a2c19a4a87c7a12edb4c98978307245ea","src/kind.rs":"b21b15dbee77d50abe88684a9571b39659076465dd4b1956f366af8fdd26e95a","src/lib.rs":"f39d4684ce6ce473b585d2f9bc8b7a355cf28e5b5c936431d8072ac5c4fe94fd","src/macros.rs":"5a735a3fa919de58729be54976678c0a386e8e9af947987f17fd988c531974c7","src/ptr.rs":"f4e28bc9feba1e84160ca9d185008a51b5d72e168e6546f3e942f4258c361e19","src/wrapper.rs":"1229beca67dbd95ca77c9ecce282272acc55276c267c58cb73a75388b4693dda","tests/common/mod.rs":"f9088c2d7afafa64ff730b629272045b776bfafc2f5957508242da630635f2e1","tests/compiletest.rs":"022a8e400ef813d7ea1875b944549cee5125f6a995dc33e93b48cba3e1b57bd1","tests/drop/mod.rs":"382956f4bd3dcd1f6036efb8f11193595a7c60e0a5dbf5f2da149f1f25183abf","tests/test_autotrait.rs":"981e792db353be2f14c7a1cabe43b5f1329c168cb7679077cc2be786a0920d48","tests/test_backtrace.rs":"0e50edbb33b6bd07ba89ff3db72fb7c688ba2a4371fccdbbb20309ab02948b6a","tests/test_boxed.rs":"6b26db0e2eb72afe9af7352ea820837aab90f8d486294616dd5dc34c1b94038c","tests/test_chain.rs":"d5e90e3eba58abc60d241d3aade39e0b8d4006d9a14f3cf015d3d925160b5812","tests/test_context.rs":"8409c53b328562c11e822bd6c3cd17e0d4d50b9bbb8fc3617333fd77303a6a33","tests/test_convert.rs":"7e7a8b4772a427a911014ac4d1083f9519000e786177f898808980dd9bdfde61","tests/test_downcast.rs":"ce8438cb58a1b7f3599740c261f6ef05855127ccde20c83c82db15eaf51c57ad","tests/test_ensure.rs":"45331ef18c4c69acf4b80f5f55d2cefb55cc82f00e854b81d54c3df36a639003","tests/test_ffi.rs":"d0cb4c1d6d9154090982dee72ae3ebe05a5981f976058c3250f1c9da5a45edef","tests/test_fmt.rs":"17572596f257aac9aa2ec4620e292ca6a954128b94772bb948399fab53832e70","tests/test_macros.rs":"3f808b3050fc2b18c5b9058fe71b6b464d70e3658ff9b1daa379cd58c6874296","tests/test_repr.rs":"dbb9b04ddbe1ab31eb5331ea69f05bb3a147299da2275a3d4dcc92947b5591b9","tests/test_source.rs":"b80723cf635a4f8c4df21891b34bfab9ed2b2aa407e7a2f826d24e334cd5f88e","tests/ui/chained-comparison.rs":"6504b03d95b5acc232a7f4defc9f343b2be6733bf475fa0992e8e6545b912bd4","tests/ui/chained-comparison.stderr":"7f1d0a8c251b0ede2d30b3087ec157fc660945c97a642c4a5acf5a14ec58de34","tests/ui/empty-ensure.rs":"ab5bf37c846a0d689f26ce9257a27228411ed64154f9c950f1602d88a355d94b","tests/ui/empty-ensure.stderr":"0fa39de3edadb86382d8cd147c2640771e080338be2f4b067650258e3150f181","tests/ui/no-impl.rs":"fab6cbf2f6ea510b86f567dfb3b7c31250a9fd71ae5d110dbb9188be569ec593","tests/ui/no-impl.stderr":"9d2d9cdf441f1c4a0ccbc4a7433013166425b98cd8dd8738381e8fd070c1aed9","tests/ui/temporary-value.rs":"4dcc96271b2403e6372cf4cfc813445e5ce4365fc6e156b6bc38274098499a70","tests/ui/temporary-value.stderr":"64e448b6759cf51d41b1360307a638452bbe53ffa706f93e4a503b712d7b89a8","tests/ui/wrong-interpolation.rs":"9c44d4674c2dccd27b9dedd03341346ec02d993b41793ee89b5755202e7e367e","tests/ui/wrong-interpolation.stderr":"301e60e2eb9401782c7dc0b3580613a4cb2aafd4cc8065734a630a62e1161aa5"},"package":"8b26702f315f53b6071259e15dd9d64528213b44d61de1ec926eca7715d62203"}
|
|
@ -3,17 +3,17 @@
|
|||
# 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
|
||||
# to registry (e.g., crates.io) dependencies.
|
||||
#
|
||||
# If you believe there's an error in this file please file an
|
||||
# issue against the rust-lang/cargo repository. If you're
|
||||
# editing this file be aware that the upstream Cargo.toml
|
||||
# will likely look very different (and much more reasonable)
|
||||
# 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.38"
|
||||
name = "anyhow"
|
||||
version = "1.0.41"
|
||||
version = "1.0.51"
|
||||
authors = ["David Tolnay <dtolnay@gmail.com>"]
|
||||
description = "Flexible concrete Error type built on std::error::Error"
|
||||
documentation = "https://docs.rs/anyhow"
|
||||
|
@ -42,7 +42,7 @@ features = ["full"]
|
|||
version = "1.0"
|
||||
|
||||
[dev-dependencies.trybuild]
|
||||
version = "1.0.19"
|
||||
version = "1.0.49"
|
||||
features = ["diff"]
|
||||
|
||||
[features]
|
||||
|
|
|
@ -16,7 +16,7 @@ for easy idiomatic error handling in Rust applications.
|
|||
anyhow = "1.0"
|
||||
```
|
||||
|
||||
*Compiler support: requires rustc 1.34+*
|
||||
*Compiler support: requires rustc 1.38+*
|
||||
|
||||
<br>
|
||||
|
||||
|
@ -75,10 +75,10 @@ anyhow = "1.0"
|
|||
}
|
||||
```
|
||||
|
||||
- If using the nightly channel, a backtrace is captured and printed with the
|
||||
error if the underlying error type does not already provide its own. In order
|
||||
to see backtraces, they must be enabled through the environment variables
|
||||
described in [`std::backtrace`]:
|
||||
- If using the nightly channel, or stable with `features = ["backtrace"]`, a
|
||||
backtrace is captured and printed with the error if the underlying error type
|
||||
does not already provide its own. In order to see backtraces, they must be
|
||||
enabled through the environment variables described in [`std::backtrace`]:
|
||||
|
||||
- If you want panics and errors to both have backtraces, set
|
||||
`RUST_BACKTRACE=1`;
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
#![allow(clippy::option_if_let_else)]
|
||||
|
||||
use std::env;
|
||||
use std::fs;
|
||||
use std::path::Path;
|
||||
|
@ -53,13 +55,13 @@ fn main() {
|
|||
None => return,
|
||||
};
|
||||
|
||||
if rustc < 38 {
|
||||
println!("cargo:rustc-cfg=anyhow_no_macro_reexport");
|
||||
}
|
||||
|
||||
if rustc < 51 {
|
||||
println!("cargo:rustc-cfg=anyhow_no_ptr_addr_of");
|
||||
}
|
||||
|
||||
if rustc < 52 {
|
||||
println!("cargo:rustc-cfg=anyhow_no_fmt_arguments_as_str");
|
||||
}
|
||||
}
|
||||
|
||||
fn compile_probe() -> Option<ExitStatus> {
|
||||
|
@ -67,17 +69,36 @@ fn compile_probe() -> Option<ExitStatus> {
|
|||
let out_dir = env::var_os("OUT_DIR")?;
|
||||
let probefile = Path::new(&out_dir).join("probe.rs");
|
||||
fs::write(&probefile, PROBE).ok()?;
|
||||
Command::new(rustc)
|
||||
.stderr(Stdio::null())
|
||||
|
||||
// Make sure to pick up Cargo rustc configuration.
|
||||
let mut cmd = if let Some(wrapper) = env::var_os("CARGO_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)
|
||||
};
|
||||
|
||||
cmd.stderr(Stdio::null())
|
||||
.arg("--edition=2018")
|
||||
.arg("--crate-name=anyhow_build")
|
||||
.arg("--crate-type=lib")
|
||||
.arg("--emit=metadata")
|
||||
.arg("--out-dir")
|
||||
.arg(out_dir)
|
||||
.arg(probefile)
|
||||
.status()
|
||||
.ok()
|
||||
.arg(probefile);
|
||||
|
||||
// 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
cmd.status().ok()
|
||||
}
|
||||
|
||||
fn rustc_minor_version() -> Option<u32> {
|
||||
|
|
|
@ -0,0 +1,2 @@
|
|||
[toolchain]
|
||||
components = ["rust-src"]
|
|
@ -24,6 +24,7 @@ pub(crate) enum ChainState<'a> {
|
|||
}
|
||||
|
||||
impl<'a> Chain<'a> {
|
||||
#[cold]
|
||||
pub fn new(head: &'a (dyn StdError + 'static)) -> Self {
|
||||
Chain {
|
||||
state: ChainState::Linked { next: Some(head) },
|
||||
|
|
|
@ -0,0 +1,818 @@
|
|||
use crate::Error;
|
||||
use alloc::string::String;
|
||||
use core::fmt::{self, Debug, Write};
|
||||
use core::mem::MaybeUninit;
|
||||
use core::ptr;
|
||||
use core::slice;
|
||||
use core::str;
|
||||
|
||||
#[doc(hidden)]
|
||||
pub trait BothDebug {
|
||||
fn __dispatch_ensure(self, msg: &'static str) -> Error;
|
||||
}
|
||||
|
||||
impl<A, B> BothDebug for (A, B)
|
||||
where
|
||||
A: Debug,
|
||||
B: Debug,
|
||||
{
|
||||
fn __dispatch_ensure(self, msg: &'static str) -> Error {
|
||||
render(msg, &self.0, &self.1)
|
||||
}
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
pub trait NotBothDebug {
|
||||
fn __dispatch_ensure(self, msg: &'static str) -> Error;
|
||||
}
|
||||
|
||||
impl<A, B> NotBothDebug for &(A, B) {
|
||||
fn __dispatch_ensure(self, msg: &'static str) -> Error {
|
||||
Error::msg(msg)
|
||||
}
|
||||
}
|
||||
|
||||
struct Buf {
|
||||
bytes: [MaybeUninit<u8>; 40],
|
||||
written: usize,
|
||||
}
|
||||
|
||||
impl Buf {
|
||||
fn new() -> Self {
|
||||
Buf {
|
||||
bytes: [MaybeUninit::uninit(); 40],
|
||||
written: 0,
|
||||
}
|
||||
}
|
||||
|
||||
fn as_str(&self) -> &str {
|
||||
unsafe {
|
||||
str::from_utf8_unchecked(slice::from_raw_parts(
|
||||
self.bytes.as_ptr().cast::<u8>(),
|
||||
self.written,
|
||||
))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Write for Buf {
|
||||
fn write_str(&mut self, s: &str) -> fmt::Result {
|
||||
if s.bytes().any(|b| b == b' ' || b == b'\n') {
|
||||
return Err(fmt::Error);
|
||||
}
|
||||
|
||||
let remaining = self.bytes.len() - self.written;
|
||||
if s.len() > remaining {
|
||||
return Err(fmt::Error);
|
||||
}
|
||||
|
||||
unsafe {
|
||||
ptr::copy_nonoverlapping(
|
||||
s.as_ptr(),
|
||||
self.bytes.as_mut_ptr().add(self.written).cast::<u8>(),
|
||||
s.len(),
|
||||
);
|
||||
}
|
||||
self.written += s.len();
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
fn render(msg: &'static str, lhs: &dyn Debug, rhs: &dyn Debug) -> Error {
|
||||
let mut lhs_buf = Buf::new();
|
||||
if fmt::write(&mut lhs_buf, format_args!("{:?}", lhs)).is_ok() {
|
||||
let mut rhs_buf = Buf::new();
|
||||
if fmt::write(&mut rhs_buf, format_args!("{:?}", rhs)).is_ok() {
|
||||
let lhs_str = lhs_buf.as_str();
|
||||
let rhs_str = rhs_buf.as_str();
|
||||
// "{msg} ({lhs} vs {rhs})"
|
||||
let len = msg.len() + 2 + lhs_str.len() + 4 + rhs_str.len() + 1;
|
||||
let mut string = String::with_capacity(len);
|
||||
string.push_str(msg);
|
||||
string.push_str(" (");
|
||||
string.push_str(lhs_str);
|
||||
string.push_str(" vs ");
|
||||
string.push_str(rhs_str);
|
||||
string.push(')');
|
||||
return Error::msg(string);
|
||||
}
|
||||
}
|
||||
Error::msg(msg)
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
#[macro_export]
|
||||
macro_rules! __parse_ensure {
|
||||
(atom () $bail:tt $fuel:tt {($($rhs:tt)+) ($($lhs:tt)+) $op:tt} $dup:tt $(,)?) => {
|
||||
$crate::__fancy_ensure!($($lhs)+, $op, $($rhs)+)
|
||||
};
|
||||
|
||||
// low precedence control flow constructs
|
||||
|
||||
(0 $stack:tt ($($bail:tt)*) $fuel:tt $parse:tt $dup:tt return $($rest:tt)*) => {
|
||||
$crate::__fallback_ensure!($($bail)*)
|
||||
};
|
||||
|
||||
(0 $stack:tt ($($bail:tt)*) $fuel:tt $parse:tt $dup:tt break $($rest:tt)*) => {
|
||||
$crate::__fallback_ensure!($($bail)*)
|
||||
};
|
||||
|
||||
(0 $stack:tt ($($bail:tt)*) $fuel:tt $parse:tt $dup:tt continue $($rest:tt)*) => {
|
||||
$crate::__fallback_ensure!($($bail)*)
|
||||
};
|
||||
|
||||
(0 $stack:tt ($($bail:tt)*) $fuel:tt $parse:tt $dup:tt yield $($rest:tt)*) => {
|
||||
$crate::__fallback_ensure!($($bail)*)
|
||||
};
|
||||
|
||||
(0 $stack:tt ($($bail:tt)*) $fuel:tt $parse:tt $dup:tt move $($rest:tt)*) => {
|
||||
$crate::__fallback_ensure!($($bail)*)
|
||||
};
|
||||
|
||||
// unary operators
|
||||
|
||||
(0 $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($deref:tt $($dup:tt)*) * $($rest:tt)*) => {
|
||||
$crate::__parse_ensure!(0 $stack $bail ($($fuel)*) {($($buf)* $deref) $($parse)*} ($($rest)*) $($rest)*)
|
||||
};
|
||||
|
||||
(0 $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($not:tt $($dup:tt)*) ! $($rest:tt)*) => {
|
||||
$crate::__parse_ensure!(0 $stack $bail ($($fuel)*) {($($buf)* $not) $($parse)*} ($($rest)*) $($rest)*)
|
||||
};
|
||||
|
||||
(0 $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($neg:tt $($dup:tt)*) - $($rest:tt)*) => {
|
||||
$crate::__parse_ensure!(0 $stack $bail ($($fuel)*) {($($buf)* $neg) $($parse)*} ($($rest)*) $($rest)*)
|
||||
};
|
||||
|
||||
(0 $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($let:tt $($dup:tt)*) let $($rest:tt)*) => {
|
||||
$crate::__parse_ensure!(pat $stack $bail ($($fuel)*) {($($buf)* $let) $($parse)*} ($($rest)*) $($rest)*)
|
||||
};
|
||||
|
||||
(0 $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($life:tt $colon:tt $($dup:tt)*) $label:lifetime : $($rest:tt)*) => {
|
||||
$crate::__parse_ensure!(0 $stack $bail ($($fuel)*) {($($buf)* $life $colon) $($parse)*} ($($rest)*) $($rest)*)
|
||||
};
|
||||
|
||||
(0 $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($and:tt $mut:tt $($dup:tt)*) &mut $($rest:tt)*) => {
|
||||
$crate::__parse_ensure!(0 $stack $bail ($($fuel)*) {($($buf)* $and $mut) $($parse)*} ($($rest)*) $($rest)*)
|
||||
};
|
||||
|
||||
(0 $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($and:tt $($dup:tt)*) & $($rest:tt)*) => {
|
||||
$crate::__parse_ensure!(0 $stack $bail ($($fuel)*) {($($buf)* $and) $($parse)*} ($($rest)*) $($rest)*)
|
||||
};
|
||||
|
||||
(0 $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($andand:tt $mut:tt $($dup:tt)*) &&mut $($rest:tt)*) => {
|
||||
$crate::__parse_ensure!(0 $stack $bail ($($fuel)*) {($($buf)* $andand $mut) $($parse)*} ($($rest)*) $($rest)*)
|
||||
};
|
||||
|
||||
(0 $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($andand:tt $($dup:tt)*) && $($rest:tt)*) => {
|
||||
$crate::__parse_ensure!(0 $stack $bail ($($fuel)*) {($($buf)* $andand) $($parse)*} ($($rest)*) $($rest)*)
|
||||
};
|
||||
|
||||
// control flow constructs
|
||||
|
||||
(0 $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($if:tt $($dup:tt)*) if $($rest:tt)*) => {
|
||||
$crate::__parse_ensure!(0 (cond $stack) $bail ($($fuel)*) {($($buf)* $if) $($parse)*} ($($rest)*) $($rest)*)
|
||||
};
|
||||
|
||||
(0 $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($match:tt $($dup:tt)*) match $($rest:tt)*) => {
|
||||
$crate::__parse_ensure!(0 (cond $stack) $bail ($($fuel)*) {($($buf)* $match) $($parse)*} ($($rest)*) $($rest)*)
|
||||
};
|
||||
|
||||
(0 $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($while:tt $($dup:tt)*) while $($rest:tt)*) => {
|
||||
$crate::__parse_ensure!(0 (cond $stack) $bail ($($fuel)*) {($($buf)* $while) $($parse)*} ($($rest)*) $($rest)*)
|
||||
};
|
||||
|
||||
(0 $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($for:tt $($dup:tt)*) for $($rest:tt)*) => {
|
||||
$crate::__parse_ensure!(pat (cond $stack) $bail ($($fuel)*) {($($buf)* $for) $($parse)*} ($($rest)*) $($rest)*)
|
||||
};
|
||||
|
||||
(atom (cond $stack:tt) $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($brace:tt $($dup:tt)*) {$($block:tt)*} $($rest:tt)*) => {
|
||||
$crate::__parse_ensure!(cond $stack $bail ($($fuel)*) {($($buf)* $brace) $($parse)*} ($($rest)*) $($rest)*)
|
||||
};
|
||||
|
||||
(cond $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($else:tt $if:tt $($dup:tt)*) else if $($rest:tt)*) => {
|
||||
$crate::__parse_ensure!(0 (cond $stack) $bail ($($fuel)*) {($($buf)* $else $if) $($parse)*} ($($rest)*) $($rest)*)
|
||||
};
|
||||
|
||||
(cond $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($else:tt $brace:tt $($dup:tt)*) else {$($block:tt)*} $($rest:tt)*) => {
|
||||
$crate::__parse_ensure!(atom $stack $bail ($($fuel)*) {($($buf)* $else $brace) $($parse)*} ($($rest)*) $($rest)*)
|
||||
};
|
||||
|
||||
(cond $stack:tt $bail:tt (~$($fuel:tt)*) $parse:tt $dup:tt $($rest:tt)*) => {
|
||||
$crate::__parse_ensure!(atom $stack $bail ($($fuel)*) $parse $dup $($rest)*)
|
||||
};
|
||||
|
||||
// atomic expressions
|
||||
|
||||
(0 $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($paren:tt $($dup:tt)*) ($($content:tt)*) $($rest:tt)*) => {
|
||||
$crate::__parse_ensure!(atom $stack $bail ($($fuel)*) {($($buf)* $paren) $($parse)*} ($($rest)*) $($rest)*)
|
||||
};
|
||||
|
||||
(0 $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($bracket:tt $($dup:tt)*) [$($array:tt)*] $($rest:tt)*) => {
|
||||
$crate::__parse_ensure!(atom $stack $bail ($($fuel)*) {($($buf)* $bracket) $($parse)*} ($($rest)*) $($rest)*)
|
||||
};
|
||||
|
||||
(0 $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($brace:tt $($dup:tt)*) {$($block:tt)*} $($rest:tt)*) => {
|
||||
$crate::__parse_ensure!(atom $stack $bail ($($fuel)*) {($($buf)* $brace) $($parse)*} ($($rest)*) $($rest)*)
|
||||
};
|
||||
|
||||
(0 $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($loop:tt $block:tt $($dup:tt)*) loop {$($body:tt)*} $($rest:tt)*) => {
|
||||
$crate::__parse_ensure!(atom $stack $bail ($($fuel)*) {($($buf)* $loop $block) $($parse)*} ($($rest)*) $($rest)*)
|
||||
};
|
||||
|
||||
(0 $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($async:tt $block:tt $($dup:tt)*) async {$($body:tt)*} $($rest:tt)*) => {
|
||||
$crate::__parse_ensure!(atom $stack $bail ($($fuel)*) {($($buf)* $async $block) $($parse)*} ($($rest)*) $($rest)*)
|
||||
};
|
||||
|
||||
(0 $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($async:tt $move:tt $block:tt $($dup:tt)*) async move {$($body:tt)*} $($rest:tt)*) => {
|
||||
$crate::__parse_ensure!(atom $stack $bail ($($fuel)*) {($($buf)* $async $move $block) $($parse)*} ($($rest)*) $($rest)*)
|
||||
};
|
||||
|
||||
(0 $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($unsafe:tt $block:tt $($dup:tt)*) unsafe {$($body:tt)*} $($rest:tt)*) => {
|
||||
$crate::__parse_ensure!(atom $stack $bail ($($fuel)*) {($($buf)* $unsafe $block) $($parse)*} ($($rest)*) $($rest)*)
|
||||
};
|
||||
|
||||
(0 $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} $dup:tt $lit:literal $($rest:tt)*) => {
|
||||
$crate::__parse_ensure!(atom $stack $bail ($($fuel)*) {($($buf)* $lit) $($parse)*} ($($rest)*) $($rest)*)
|
||||
};
|
||||
|
||||
// path expressions
|
||||
|
||||
(0 $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($colons:tt $($dup:tt)*) :: $ident:ident $($rest:tt)*) => {
|
||||
$crate::__parse_ensure!(epath (atom $stack) $bail ($($fuel)*) {($($buf)* $colons $ident) $($parse)*} ($($rest)*) $($rest)*)
|
||||
};
|
||||
|
||||
(0 $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} $dup:tt $ident:ident $($rest:tt)*) => {
|
||||
$crate::__parse_ensure!(epath (atom $stack) $bail ($($fuel)*) {($($buf)* $ident) $($parse)*} ($($rest)*) $($rest)*)
|
||||
};
|
||||
|
||||
(0 $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($langle:tt $($dup:tt)*) < $($rest:tt)*) => {
|
||||
$crate::__parse_ensure!(type (qpath (epath (atom $stack))) $bail ($($fuel)*) {($($buf)* $langle) $($parse)*} ($($rest)*) $($rest)*)
|
||||
};
|
||||
|
||||
(epath $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($colons:tt $langle:tt $($dup:tt)*) :: < $($rest:tt)*) => {
|
||||
$crate::__parse_ensure!(generic (epath $stack) $bail ($($fuel)*) {($($buf)* $colons $langle) $($parse)*} ($($rest)*) $($rest)*)
|
||||
};
|
||||
|
||||
(epath $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($colons:tt $($dup:tt)*) :: << $($rest:tt)*) => {
|
||||
$crate::__parse_ensure!(generic (epath $stack) $bail ($($fuel)*) {($($buf)* $colons <) $($parse)*} (< $($rest)*) < $($rest)*)
|
||||
};
|
||||
|
||||
(epath $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($colons:tt $($dup:tt)*) :: $ident:ident $($rest:tt)*) => {
|
||||
$crate::__parse_ensure!(epath $stack $bail ($($fuel)*) {($($buf)* $colons $ident) $($parse)*} ($($rest)*) $($rest)*)
|
||||
};
|
||||
|
||||
(epath ($pop:ident $stack:tt) $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($bang:tt $args:tt $($dup:tt)*) ! ($($mac:tt)*) $($rest:tt)*) => {
|
||||
$crate::__parse_ensure!($pop $stack $bail ($($fuel)*) {($($buf)* $bang $args) $($parse)*} ($($rest)*) $($rest)*)
|
||||
};
|
||||
|
||||
(epath ($pop:ident $stack:tt) $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($bang:tt $args:tt $($dup:tt)*) ! [$($mac:tt)*] $($rest:tt)*) => {
|
||||
$crate::__parse_ensure!($pop $stack $bail ($($fuel)*) {($($buf)* $bang $args) $($parse)*} ($($rest)*) $($rest)*)
|
||||
};
|
||||
|
||||
(epath ($pop:ident $stack:tt) $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($bang:tt $args:tt $($dup:tt)*) ! {$($mac:tt)*} $($rest:tt)*) => {
|
||||
$crate::__parse_ensure!($pop $stack $bail ($($fuel)*) {($($buf)* $bang $args) $($parse)*} ($($rest)*) $($rest)*)
|
||||
};
|
||||
|
||||
(epath ($pop:ident $stack:tt) $bail:tt (~$($fuel:tt)*) $parse:tt $dup:tt $($rest:tt)*) => {
|
||||
$crate::__parse_ensure!($pop $stack $bail ($($fuel)*) $parse $dup $($rest)*)
|
||||
};
|
||||
|
||||
// trailer expressions
|
||||
|
||||
(atom $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($paren:tt $($dup:tt)*) ($($call:tt)*) $($rest:tt)*) => {
|
||||
$crate::__parse_ensure!(atom $stack $bail ($($fuel)*) {($($buf)* $paren) $($parse)*} ($($rest)*) $($rest)*)
|
||||
};
|
||||
|
||||
(atom $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($bracket:tt $($dup:tt)*) [$($index:tt)*] $($rest:tt)*) => {
|
||||
$crate::__parse_ensure!(atom $stack $bail ($($fuel)*) {($($buf)* $bracket) $($parse)*} ($($rest)*) $($rest)*)
|
||||
};
|
||||
|
||||
(atom $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($brace:tt $($dup:tt)*) {$($init:tt)*} $($rest:tt)*) => {
|
||||
$crate::__parse_ensure!(atom $stack $bail ($($fuel)*) {($($buf)* $brace) $($parse)*} ($($rest)*) $($rest)*)
|
||||
};
|
||||
|
||||
(atom $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($question:tt $($dup:tt)*) ? $($rest:tt)*) => {
|
||||
$crate::__parse_ensure!(atom $stack $bail ($($fuel)*) {($($buf)* $question) $($parse)*} ($($rest)*) $($rest)*)
|
||||
};
|
||||
|
||||
(atom $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($dot:tt $ident:tt $colons:tt $langle:tt $($dup:tt)*) . $i:ident :: < $($rest:tt)*) => {
|
||||
$crate::__parse_ensure!(generic (atom $stack) $bail ($($fuel)*) {($($buf)* $dot $ident $colons $langle) $($parse)*} ($($rest)*) $($rest)*)
|
||||
};
|
||||
|
||||
(atom $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($dot:tt $ident:tt $colons:tt $($dup:tt)*) . $i:ident :: << $($rest:tt)*) => {
|
||||
$crate::__parse_ensure!(generic (atom $stack) $bail ($($fuel)*) {($($buf)* $dot $ident $colons <) $($parse)*} (< $($rest)*) < $($rest)*)
|
||||
};
|
||||
|
||||
(atom $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($dot:tt $($dup:tt)*) . $field:ident $($rest:tt)*) => {
|
||||
$crate::__parse_ensure!(atom $stack $bail ($($fuel)*) {($($buf)* $dot $field) $($parse)*} ($($rest)*) $($rest)*)
|
||||
};
|
||||
|
||||
(atom $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($dot:tt $index:tt $($dup:tt)*) . $lit:literal $($rest:tt)*) => {
|
||||
$crate::__parse_ensure!(atom $stack $bail ($($fuel)*) {($($buf)* $dot $index) $($parse)*} ($($rest)*) $($rest)*)
|
||||
};
|
||||
|
||||
(atom $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($as:tt $($dup:tt)*) as $($rest:tt)*) => {
|
||||
$crate::__parse_ensure!(type (atom $stack) $bail ($($fuel)*) {($($buf)* $as) $($parse)*} ($($rest)*) $($rest)*)
|
||||
};
|
||||
|
||||
// types
|
||||
|
||||
(type ($pop:ident $stack:tt) $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($bracket:tt $($dup:tt)*) [$($content:tt)*] $($rest:tt)*) => {
|
||||
$crate::__parse_ensure!($pop $stack $bail ($($fuel)*) {($($buf)* $bracket) $($parse)*} ($($rest)*) $($rest)*)
|
||||
};
|
||||
|
||||
(type ($pop:ident $stack:tt) $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($paren:tt $($dup:tt)*) ($($content:tt)*) $($rest:tt)*) => {
|
||||
$crate::__parse_ensure!($pop $stack $bail ($($fuel)*) {($($buf)* $paren) $($parse)*} ($($rest)*) $($rest)*)
|
||||
};
|
||||
|
||||
(type $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($star:tt $const:tt $($dup:tt)*) *const $($rest:tt)*) => {
|
||||
$crate::__parse_ensure!(type $stack $bail ($($fuel)*) {($($buf)* $star $const) $($parse)*} ($($rest)*) $($rest)*)
|
||||
};
|
||||
|
||||
(type $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($star:tt $mut:tt $($dup:tt)*) *mut $($rest:tt)*) => {
|
||||
$crate::__parse_ensure!(type $stack $bail ($($fuel)*) {($($buf)* $star $mut) $($parse)*} ($($rest)*) $($rest)*)
|
||||
};
|
||||
|
||||
(type $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($and:tt $life:lifetime $mut:tt $($dup:tt)*) & $l:lifetime mut $($rest:tt)*) => {
|
||||
$crate::__parse_ensure!(type $stack $bail ($($fuel)*) {($($buf)* $and $life $mut) $($parse)*} ($($rest)*) $($rest)*)
|
||||
};
|
||||
|
||||
(type $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($and:tt $mut:tt $($dup:tt)*) & mut $($rest:tt)*) => {
|
||||
$crate::__parse_ensure!(type $stack $bail ($($fuel)*) {($($buf)* $and $mut) $($parse)*} ($($rest)*) $($rest)*)
|
||||
};
|
||||
|
||||
(type $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($and:tt $life:lifetime $($dup:tt)*) & $l:lifetime $($rest:tt)*) => {
|
||||
$crate::__parse_ensure!(type $stack $bail ($($fuel)*) {($($buf)* $and $life) $($parse)*} ($($rest)*) $($rest)*)
|
||||
};
|
||||
|
||||
(type $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($and:tt $($dup:tt)*) & $($rest:tt)*) => {
|
||||
$crate::__parse_ensure!(type $stack $bail ($($fuel)*) {($($buf)* $and) $($parse)*} ($($rest)*) $($rest)*)
|
||||
};
|
||||
|
||||
(type $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($and:tt $life:lifetime $mut:tt $($dup:tt)*) && $l:lifetime mut $($rest:tt)*) => {
|
||||
$crate::__parse_ensure!(type $stack $bail ($($fuel)*) {($($buf)* $and $life $mut) $($parse)*} ($($rest)*) $($rest)*)
|
||||
};
|
||||
|
||||
(type $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($and:tt $mut:tt $($dup:tt)*) && mut $($rest:tt)*) => {
|
||||
$crate::__parse_ensure!(type $stack $bail ($($fuel)*) {($($buf)* $and $mut) $($parse)*} ($($rest)*) $($rest)*)
|
||||
};
|
||||
|
||||
(type $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($and:tt $life:lifetime $($dup:tt)*) && $l:lifetime $($rest:tt)*) => {
|
||||
$crate::__parse_ensure!(type $stack $bail ($($fuel)*) {($($buf)* $and $life) $($parse)*} ($($rest)*) $($rest)*)
|
||||
};
|
||||
|
||||
(type $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($and:tt $($dup:tt)*) && $($rest:tt)*) => {
|
||||
$crate::__parse_ensure!(type $stack $bail ($($fuel)*) {($($buf)* $and) $($parse)*} ($($rest)*) $($rest)*)
|
||||
};
|
||||
|
||||
(type $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($unsafe:tt $(extern $($abi:literal)?)? fn $($dup:tt)*) unsafe $($rest:tt)*) => {
|
||||
$crate::__parse_ensure!(type $stack $bail ($($fuel)*) {($($buf)* $unsafe) $($parse)*} ($($rest)*) $($rest)*)
|
||||
};
|
||||
|
||||
(type $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($extern:tt $abi:literal fn $($dup:tt)*) extern $lit:literal $($rest:tt)*) => {
|
||||
$crate::__parse_ensure!(type $stack $bail ($($fuel)*) {($($buf)* $extern $abi) $($parse)*} ($($rest)*) $($rest)*)
|
||||
};
|
||||
|
||||
(type $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($extern:tt fn $($dup:tt)*) extern $($rest:tt)*) => {
|
||||
$crate::__parse_ensure!(type $stack $bail ($($fuel)*) {($($buf)* $extern) $($parse)*} ($($rest)*) $($rest)*)
|
||||
};
|
||||
|
||||
(type $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($fn:tt $paren:tt $arrow:tt $($dup:tt)*) fn ($($args:tt)*) -> $($rest:tt)*) => {
|
||||
$crate::__parse_ensure!(type $stack $bail ($($fuel)*) {($($buf)* $fn $paren $arrow) $($parse)*} ($($rest)*) $($rest)*)
|
||||
};
|
||||
|
||||
(type ($pop:ident $stack:tt) $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($fn:tt $paren:tt $($dup:tt)*) fn ($($args:tt)*) $($rest:tt)*) => {
|
||||
$crate::__parse_ensure!($pop $stack $bail ($($fuel)*) {($($buf)* $fn $paren) $($parse)*} ($($rest)*) $($rest)*)
|
||||
};
|
||||
|
||||
(type $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($impl:tt $($dup:tt)*) impl $($rest:tt)*) => {
|
||||
$crate::__parse_ensure!(type $stack $bail ($($fuel)*) {($($buf)* $impl) $($parse)*} ($($rest)*) $($rest)*)
|
||||
};
|
||||
|
||||
(type $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($dyn:tt $($dup:tt)*) dyn $($rest:tt)*) => {
|
||||
$crate::__parse_ensure!(type $stack $bail ($($fuel)*) {($($buf)* $dyn) $($parse)*} ($($rest)*) $($rest)*)
|
||||
};
|
||||
|
||||
(type ($pop:ident $stack:tt) $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($wild:tt $($dup:tt)*) _ $($rest:tt)*) => {
|
||||
$crate::__parse_ensure!($pop $stack $bail ($($fuel)*) {($($buf)* $wild) $($parse)*} ($($rest)*) $($rest)*)
|
||||
};
|
||||
|
||||
(type ($pop:ident $stack:tt) $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($never:tt $($dup:tt)*) ! $($rest:tt)*) => {
|
||||
$crate::__parse_ensure!($pop $stack $bail ($($fuel)*) {($($buf)* $never) $($parse)*} ($($rest)*) $($rest)*)
|
||||
};
|
||||
|
||||
(type $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($for:tt $langle:tt $($dup:tt)*) for < $($rest:tt)*) => {
|
||||
$crate::__parse_ensure!(generic (type $stack) $bail ($($fuel)*) {($($buf)* $for $langle) $($parse)*} ($($rest)*) $($rest)*)
|
||||
};
|
||||
|
||||
// path types
|
||||
|
||||
(type $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($colons:tt $($dup:tt)*) :: $ident:ident $($rest:tt)*) => {
|
||||
$crate::__parse_ensure!(tpath $stack $bail ($($fuel)*) {($($buf)* $colons $ident) $($parse)*} ($($rest)*) $($rest)*)
|
||||
};
|
||||
|
||||
(type $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} $dup:tt $ident:ident $($rest:tt)*) => {
|
||||
$crate::__parse_ensure!(tpath $stack $bail ($($fuel)*) {($($buf)* $ident) $($parse)*} ($($rest)*) $($rest)*)
|
||||
};
|
||||
|
||||
(type $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($langle:tt $($dup:tt)*) < $($rest:tt)*) => {
|
||||
$crate::__parse_ensure!(type (qpath (tpath $stack)) $bail ($($fuel)*) {($($buf)* $langle) $($parse)*} ($($rest)*) $($rest)*)
|
||||
};
|
||||
|
||||
(tpath $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($langle:tt $($dup:tt)*) < $($rest:tt)*) => {
|
||||
$crate::__parse_ensure!(generic (tpath $stack) $bail ($($fuel)*) {($($buf)* $langle) $($parse)*} ($($rest)*) $($rest)*)
|
||||
};
|
||||
|
||||
(tpath $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} $dup:tt << $($rest:tt)*) => {
|
||||
$crate::__parse_ensure!(generic (tpath $stack) $bail ($($fuel)*) {($($buf)* <) $($parse)*} (< $($rest)*) < $($rest)*)
|
||||
};
|
||||
|
||||
(tpath $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($colons:tt $langle:tt $($dup:tt)*) :: < $($rest:tt)*) => {
|
||||
$crate::__parse_ensure!(generic (tpath $stack) $bail ($($fuel)*) {($($buf)* $colons $langle) $($parse)*} ($($rest)*) $($rest)*)
|
||||
};
|
||||
|
||||
(tpath $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($colons:tt $($dup:tt)*) :: << $($rest:tt)*) => {
|
||||
$crate::__parse_ensure!(generic (tpath $stack) $bail ($($fuel)*) {($($buf)* $colons <) $($parse)*} (< $($rest)*) < $($rest)*)
|
||||
};
|
||||
|
||||
(tpath $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($colons:tt $($dup:tt)*) :: $ident:ident $($rest:tt)*) => {
|
||||
$crate::__parse_ensure!(tpath $stack $bail ($($fuel)*) {($($buf)* $colons $ident) $($parse)*} ($($rest)*) $($rest)*)
|
||||
};
|
||||
|
||||
(tpath $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($paren:tt $arrow:tt $($dup:tt)*) ($($args:tt)*) -> $($rest:tt)*) => {
|
||||
$crate::__parse_ensure!(type $stack $bail ($($fuel)*) {($($buf)* $paren $arrow) $($parse)*} ($($rest)*) $($rest)*)
|
||||
};
|
||||
|
||||
(tpath $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($paren:tt $($dup:tt)*) ($($args:tt)*) $($rest:tt)*) => {
|
||||
$crate::__parse_ensure!(object $stack $bail ($($fuel)*) {($($buf)* $paren) $($parse)*} ($($rest)*) $($rest)*)
|
||||
};
|
||||
|
||||
(tpath $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($colons:tt $paren:tt $arrow:tt $($dup:tt)*) :: ($($args:tt)*) -> $($rest:tt)*) => {
|
||||
$crate::__parse_ensure!(type $stack $bail ($($fuel)*) {($($buf)* $colons $paren $arrow) $($parse)*} ($($rest)*) $($rest)*)
|
||||
};
|
||||
|
||||
(tpath $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($colons:tt $paren:tt $($dup:tt)*) :: ($($args:tt)*) $($rest:tt)*) => {
|
||||
$crate::__parse_ensure!(object $stack $bail ($($fuel)*) {($($buf)* $colons $paren) $($parse)*} ($($rest)*) $($rest)*)
|
||||
};
|
||||
|
||||
(tpath ($pop:ident $stack:tt) $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($bang:tt $args:tt $($dup:tt)*) ! ($($mac:tt)*) $($rest:tt)*) => {
|
||||
$crate::__parse_ensure!($pop $stack $bail ($($fuel)*) {($($buf)* $bang $args) $($parse)*} ($($rest)*) $($rest)*)
|
||||
};
|
||||
|
||||
(tpath ($pop:ident $stack:tt) $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($bang:tt $args:tt $($dup:tt)*) ! [$($mac:tt)*] $($rest:tt)*) => {
|
||||
$crate::__parse_ensure!($pop $stack $bail ($($fuel)*) {($($buf)* $bang $args) $($parse)*} ($($rest)*) $($rest)*)
|
||||
};
|
||||
|
||||
(tpath ($pop:ident $stack:tt) $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($bang:tt $args:tt $($dup:tt)*) ! {$($mac:tt)*} $($rest:tt)*) => {
|
||||
$crate::__parse_ensure!($pop $stack $bail ($($fuel)*) {($($buf)* $bang $args) $($parse)*} ($($rest)*) $($rest)*)
|
||||
};
|
||||
|
||||
(tpath $stack:tt $bail:tt (~$($fuel:tt)*) $parse:tt $dup:tt $($rest:tt)*) => {
|
||||
$crate::__parse_ensure!(object $stack $bail ($($fuel)*) $parse $dup $($rest)*)
|
||||
};
|
||||
|
||||
// qualified paths
|
||||
|
||||
(qpath ($pop:ident $stack:tt) $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($rangle:tt $colons:tt $($dup:tt)*) > :: $ident:ident $($rest:tt)*) => {
|
||||
$crate::__parse_ensure!($pop $stack $bail ($($fuel)*) {($($buf)* $rangle $colons $ident) $($parse)*} ($($rest)*) $($rest)*)
|
||||
};
|
||||
|
||||
(qpath $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($as:tt $($dup:tt)*) as $($rest:tt)*) => {
|
||||
$crate::__parse_ensure!(type (qpath $stack) $bail ($($fuel)*) {($($buf)* $as) $($parse)*} ($($rest)*) $($rest)*)
|
||||
};
|
||||
|
||||
// trait objects
|
||||
|
||||
(object (arglist $stack:tt) $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($plus:tt $colons:tt $($dup:tt)*) + :: $ident:ident $($rest:tt)*) => {
|
||||
$crate::__parse_ensure!(tpath (arglist $stack) $bail ($($fuel)*) {($($buf)* $plus $colons $ident) $($parse)*} ($($rest)*) $($rest)*)
|
||||
};
|
||||
|
||||
(object (arglist $stack:tt) $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($plus:tt $($dup:tt)*) + $ident:ident $($rest:tt)*) => {
|
||||
$crate::__parse_ensure!(tpath (arglist $stack) $bail ($($fuel)*) {($($buf)* $plus $ident) $($parse)*} ($($rest)*) $($rest)*)
|
||||
};
|
||||
|
||||
(object ($pop:ident $stack:tt) $bail:tt (~$($fuel:tt)*) $parse:tt $dup:tt $($rest:tt)*) => {
|
||||
$crate::__parse_ensure!($pop $stack $bail ($($fuel)*) $parse $dup $($rest)*)
|
||||
};
|
||||
|
||||
// angle bracketed generic arguments
|
||||
|
||||
(generic ($pop:ident $stack:tt) $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($rangle:tt $($dup:tt)*) > $($rest:tt)*) => {
|
||||
$crate::__parse_ensure!($pop $stack $bail ($($fuel)*) {($($buf)* $rangle) $($parse)*} ($($rest)*) $($rest)*)
|
||||
};
|
||||
|
||||
(generic ($pop:ident $stack:tt) $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} $dup:tt >> $($rest:tt)*) => {
|
||||
$crate::__parse_ensure!($pop $stack $bail ($($fuel)*) {($($buf)* >) $($parse)*} (> $($rest)*) > $($rest)*)
|
||||
};
|
||||
|
||||
(generic $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} $dup:tt $lit:literal $($rest:tt)*) => {
|
||||
$crate::__parse_ensure!(arglist $stack $bail ($($fuel)*) {($($buf)* $lit) $($parse)*} ($($rest)*) $($rest)*)
|
||||
};
|
||||
|
||||
(generic $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($brace:tt $($dup:tt)*) {$($block:tt)*} $($rest:tt)*) => {
|
||||
$crate::__parse_ensure!(arglist $stack $bail ($($fuel)*) {($($buf)* $brace) $($parse)*} ($($rest)*) $($rest)*)
|
||||
};
|
||||
|
||||
(generic $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} $dup:tt $life:lifetime $($rest:tt)*) => {
|
||||
$crate::__parse_ensure!(arglist $stack $bail ($($fuel)*) {($($buf)* $life) $($parse)*} ($($rest)*) $($rest)*)
|
||||
};
|
||||
|
||||
(generic $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($assoc:ident $eq:tt $($dup:tt)*) $ident:ident = $($rest:tt)*) => {
|
||||
$crate::__parse_ensure!(type (arglist $stack) $bail ($($fuel)*) {($($buf)* $assoc $eq) $($parse)*} ($($rest)*) $($rest)*)
|
||||
};
|
||||
|
||||
(generic $stack:tt $bail:tt (~$($fuel:tt)*) $parse:tt $dup:tt $($rest:tt)*) => {
|
||||
$crate::__parse_ensure!(type (arglist $stack) $bail ($($fuel)*) $parse $dup $($rest)*)
|
||||
};
|
||||
|
||||
(arglist $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($comma:tt $($dup:tt)*) , $($rest:tt)*) => {
|
||||
$crate::__parse_ensure!(generic $stack $bail ($($fuel)*) {($($buf)* $comma) $($parse)*} ($($rest)*) $($rest)*)
|
||||
};
|
||||
|
||||
(arglist ($pop:ident $stack:tt) $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($rangle:tt $($dup:tt)*) > $($rest:tt)*) => {
|
||||
$crate::__parse_ensure!($pop $stack $bail ($($fuel)*) {($($buf)* $rangle) $($parse)*} ($($rest)*) $($rest)*)
|
||||
};
|
||||
|
||||
(arglist ($pop:ident $stack:tt) $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} $dup:tt >> $($rest:tt)*) => {
|
||||
$crate::__parse_ensure!($pop $stack $bail ($($fuel)*) {($($buf)* >) $($parse)*} (> $($rest)*) > $($rest)*)
|
||||
};
|
||||
|
||||
// patterns
|
||||
|
||||
(pat $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($pipe:tt $($dup:tt)*) | $($rest:tt)*) => {
|
||||
$crate::__parse_ensure!(pat $stack $bail ($($fuel)*) {($($buf)* $pipe) $($parse)*} ($($rest)*) $($rest)*)
|
||||
};
|
||||
|
||||
(pat $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($eq:tt $($dup:tt)*) = $($rest:tt)*) => {
|
||||
$crate::__parse_ensure!(0 $stack $bail ($($fuel)*) {($($buf)* $eq) $($parse)*} ($($rest)*) $($rest)*)
|
||||
};
|
||||
|
||||
(pat $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($in:tt $($dup:tt)*) in $($rest:tt)*) => {
|
||||
$crate::__parse_ensure!(0 $stack $bail ($($fuel)*) {($($buf)* $in) $($parse)*} ($($rest)*) $($rest)*)
|
||||
};
|
||||
|
||||
(pat $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($ref:tt $($dup:tt)*) ref $($rest:tt)*) => {
|
||||
$crate::__parse_ensure!(pat $stack $bail ($($fuel)*) {($($buf)* $ref) $($parse)*} ($($rest)*) $($rest)*)
|
||||
};
|
||||
|
||||
(pat $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($mut:tt $($dup:tt)*) mut $($rest:tt)*) => {
|
||||
$crate::__parse_ensure!(pat $stack $bail ($($fuel)*) {($($buf)* $mut) $($parse)*} ($($rest)*) $($rest)*)
|
||||
};
|
||||
|
||||
(pat $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($at:tt $($dup:tt)*) @ $($rest:tt)*) => {
|
||||
$crate::__parse_ensure!(pat $stack $bail ($($fuel)*) {($($buf)* $at) $($parse)*} ($($rest)*) $($rest)*)
|
||||
};
|
||||
|
||||
(pat $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} $dup:tt $lit:literal $($rest:tt)*) => {
|
||||
$crate::__parse_ensure!(pat $stack $bail ($($fuel)*) {($($buf)* $lit) $($parse)*} ($($rest)*) $($rest)*)
|
||||
};
|
||||
|
||||
(pat $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($range:tt $($dup:tt)*) .. $($rest:tt)*) => {
|
||||
$crate::__parse_ensure!(pat $stack $bail ($($fuel)*) {($($buf)* $range) $($parse)*} ($($rest)*) $($rest)*)
|
||||
};
|
||||
|
||||
(pat $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($range:tt $($dup:tt)*) ..= $($rest:tt)*) => {
|
||||
$crate::__parse_ensure!(pat $stack $bail ($($fuel)*) {($($buf)* $range) $($parse)*} ($($rest)*) $($rest)*)
|
||||
};
|
||||
|
||||
(pat $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($and:tt $($dup:tt)*) & $($rest:tt)*) => {
|
||||
$crate::__parse_ensure!(pat $stack $bail ($($fuel)*) {($($buf)* $and) $($parse)*} ($($rest)*) $($rest)*)
|
||||
};
|
||||
|
||||
(pat $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($andand:tt $($dup:tt)*) && $($rest:tt)*) => {
|
||||
$crate::__parse_ensure!(pat $stack $bail ($($fuel)*) {($($buf)* $andand) $($parse)*} ($($rest)*) $($rest)*)
|
||||
};
|
||||
|
||||
(pat $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($paren:tt $($dup:tt)*) ($($content:tt)*) $($rest:tt)*) => {
|
||||
$crate::__parse_ensure!(pat $stack $bail ($($fuel)*) {($($buf)* $paren) $($parse)*} ($($rest)*) $($rest)*)
|
||||
};
|
||||
|
||||
(pat $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($bracket:tt $($dup:tt)*) [$($content:tt)*] $($rest:tt)*) => {
|
||||
$crate::__parse_ensure!(pat $stack $bail ($($fuel)*) {($($buf)* $bracket) $($parse)*} ($($rest)*) $($rest)*)
|
||||
};
|
||||
|
||||
(pat $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($brace:tt $($dup:tt)*) {$($content:tt)*} $($rest:tt)*) => {
|
||||
$crate::__parse_ensure!(pat $stack $bail ($($fuel)*) {($($buf)* $brace) $($parse)*} ($($rest)*) $($rest)*)
|
||||
};
|
||||
|
||||
(pat $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($wild:tt $($dup:tt)*) _ $($rest:tt)*) => {
|
||||
$crate::__parse_ensure!(pat $stack $bail ($($fuel)*) {($($buf)* $wild) $($parse)*} ($($rest)*) $($rest)*)
|
||||
};
|
||||
|
||||
(pat $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($colons:tt $($dup:tt)*) :: $ident:ident $($rest:tt)*) => {
|
||||
$crate::__parse_ensure!(epath (pat $stack) $bail ($($fuel)*) {($($buf)* $colons $ident) $($parse)*} ($($rest)*) $($rest)*)
|
||||
};
|
||||
|
||||
(pat $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} $dup:tt $ident:ident $($rest:tt)*) => {
|
||||
$crate::__parse_ensure!(epath (pat $stack) $bail ($($fuel)*) {($($buf)* $ident) $($parse)*} ($($rest)*) $($rest)*)
|
||||
};
|
||||
|
||||
(pat $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($langle:tt $($dup:tt)*) < $($rest:tt)*) => {
|
||||
$crate::__parse_ensure!(type (qpath (epath (pat $stack))) $bail ($($fuel)*) {($($buf)* $langle) $($parse)*} ($($rest)*) $($rest)*)
|
||||
};
|
||||
|
||||
// high precedence binary operators
|
||||
|
||||
(atom $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($add:tt $($dup:tt)*) + $($rest:tt)*) => {
|
||||
$crate::__parse_ensure!(0 $stack $bail ($($fuel)*) {($($buf)* $add) $($parse)*} ($($rest)*) $($rest)*)
|
||||
};
|
||||
|
||||
(atom $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($sub:tt $($dup:tt)*) - $($rest:tt)*) => {
|
||||
$crate::__parse_ensure!(0 $stack $bail ($($fuel)*) {($($buf)* $sub) $($parse)*} ($($rest)*) $($rest)*)
|
||||
};
|
||||
|
||||
(atom $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($mul:tt $($dup:tt)*) * $($rest:tt)*) => {
|
||||
$crate::__parse_ensure!(0 $stack $bail ($($fuel)*) {($($buf)* $mul) $($parse)*} ($($rest)*) $($rest)*)
|
||||
};
|
||||
|
||||
(atom $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($div:tt $($dup:tt)*) / $($rest:tt)*) => {
|
||||
$crate::__parse_ensure!(0 $stack $bail ($($fuel)*) {($($buf)* $div) $($parse)*} ($($rest)*) $($rest)*)
|
||||
};
|
||||
|
||||
(atom $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($rem:tt $($dup:tt)*) % $($rest:tt)*) => {
|
||||
$crate::__parse_ensure!(0 $stack $bail ($($fuel)*) {($($buf)* $rem) $($parse)*} ($($rest)*) $($rest)*)
|
||||
};
|
||||
|
||||
(atom $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($bitxor:tt $($dup:tt)*) ^ $($rest:tt)*) => {
|
||||
$crate::__parse_ensure!(0 $stack $bail ($($fuel)*) {($($buf)* $bitxor) $($parse)*} ($($rest)*) $($rest)*)
|
||||
};
|
||||
|
||||
(atom $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($bitand:tt $($dup:tt)*) & $($rest:tt)*) => {
|
||||
$crate::__parse_ensure!(0 $stack $bail ($($fuel)*) {($($buf)* $bitand) $($parse)*} ($($rest)*) $($rest)*)
|
||||
};
|
||||
|
||||
(atom $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($bitor:tt $($dup:tt)*) | $($rest:tt)*) => {
|
||||
$crate::__parse_ensure!(0 $stack $bail ($($fuel)*) {($($buf)* $bitor) $($parse)*} ($($rest)*) $($rest)*)
|
||||
};
|
||||
|
||||
(atom $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($shl:tt $($dup:tt)*) << $($rest:tt)*) => {
|
||||
$crate::__parse_ensure!(0 $stack $bail ($($fuel)*) {($($buf)* $shl) $($parse)*} ($($rest)*) $($rest)*)
|
||||
};
|
||||
|
||||
(atom $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($shr:tt $($dup:tt)*) >> $($rest:tt)*) => {
|
||||
$crate::__parse_ensure!(0 $stack $bail ($($fuel)*) {($($buf)* $shr) $($parse)*} ($($rest)*) $($rest)*)
|
||||
};
|
||||
|
||||
// comparison binary operators
|
||||
|
||||
(atom () $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($eq:tt $($dup:tt)*) == $($rest:tt)*) => {
|
||||
$crate::__parse_ensure!(0 () $bail ($($fuel)*) {() $($parse)* ($($buf)*) $eq} ($($rest)*) $($rest)*)
|
||||
};
|
||||
|
||||
(atom $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)+) $($parse:tt)*} ($eq:tt $($dup:tt)*) == $($rest:tt)*) => {
|
||||
$crate::__parse_ensure!(0 $stack $bail ($($fuel)*) {($($buf)* $eq) $($parse)*} ($($rest)*) $($rest)*)
|
||||
};
|
||||
|
||||
(atom () $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($le:tt $($dup:tt)*) <= $($rest:tt)*) => {
|
||||
$crate::__parse_ensure!(0 () $bail ($($fuel)*) {() $($parse)* ($($buf)*) $le} ($($rest)*) $($rest)*)
|
||||
};
|
||||
|
||||
(atom $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)+) $($parse:tt)*} ($le:tt $($dup:tt)*) <= $($rest:tt)*) => {
|
||||
$crate::__parse_ensure!(0 $stack $bail ($($fuel)*) {($($buf)* $le) $($parse)*} ($($rest)*) $($rest)*)
|
||||
};
|
||||
|
||||
(atom () $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($lt:tt $($dup:tt)*) < $($rest:tt)*) => {
|
||||
$crate::__parse_ensure!(0 () $bail ($($fuel)*) {() $($parse)* ($($buf)*) $lt} ($($rest)*) $($rest)*)
|
||||
};
|
||||
|
||||
(atom $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)+) $($parse:tt)*} ($lt:tt $($dup:tt)*) < $($rest:tt)*) => {
|
||||
$crate::__parse_ensure!(0 $stack $bail ($($fuel)*) {($($buf)* $lt) $($parse)*} ($($rest)*) $($rest)*)
|
||||
};
|
||||
|
||||
(atom () $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($ne:tt $($dup:tt)*) != $($rest:tt)*) => {
|
||||
$crate::__parse_ensure!(0 () $bail ($($fuel)*) {() $($parse)* ($($buf)*) $ne} ($($rest)*) $($rest)*)
|
||||
};
|
||||
|
||||
(atom $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)+) $($parse:tt)*} ($ne:tt $($dup:tt)*) != $($rest:tt)*) => {
|
||||
$crate::__parse_ensure!(0 $stack $bail ($($fuel)*) {($($buf)* $ne) $($parse)*} ($($rest)*) $($rest)*)
|
||||
};
|
||||
|
||||
(atom () $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($ge:tt $($dup:tt)*) >= $($rest:tt)*) => {
|
||||
$crate::__parse_ensure!(0 () $bail ($($fuel)*) {() $($parse)* ($($buf)*) $ge} ($($rest)*) $($rest)*)
|
||||
};
|
||||
|
||||
(atom $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)+) $($parse:tt)*} ($ge:tt $($dup:tt)*) >= $($rest:tt)*) => {
|
||||
$crate::__parse_ensure!(0 $stack $bail ($($fuel)*) {($($buf)* $ge) $($parse)*} ($($rest)*) $($rest)*)
|
||||
};
|
||||
|
||||
(atom () $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($gt:tt $($dup:tt)*) > $($rest:tt)*) => {
|
||||
$crate::__parse_ensure!(0 () $bail ($($fuel)*) {() $($parse)* ($($buf)*) $gt} ($($rest)*) $($rest)*)
|
||||
};
|
||||
|
||||
(atom $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)+) $($parse:tt)*} ($gt:tt $($dup:tt)*) > $($rest:tt)*) => {
|
||||
$crate::__parse_ensure!(0 $stack $bail ($($fuel)*) {($($buf)* $gt) $($parse)*} ($($rest)*) $($rest)*)
|
||||
};
|
||||
|
||||
// low precedence binary operators
|
||||
|
||||
(atom ($($stack:tt)+) $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($and:tt $($dup:tt)*) && $($rest:tt)*) => {
|
||||
$crate::__parse_ensure!(0 ($($stack)*) $bail ($($fuel)*) {($($buf)* $and) $($parse)*} ($($rest)*) $($rest)*)
|
||||
};
|
||||
|
||||
(atom ($($stack:tt)+) $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($or:tt $($dup:tt)*) || $($rest:tt)*) => {
|
||||
$crate::__parse_ensure!(0 ($($stack)*) $bail ($($fuel)*) {($($buf)* $or) $($parse)*} ($($rest)*) $($rest)*)
|
||||
};
|
||||
|
||||
(atom ($($stack:tt)+) $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($assign:tt $($dup:tt)*) = $($rest:tt)*) => {
|
||||
$crate::__parse_ensure!(0 ($($stack)*) $bail ($($fuel)*) {($($buf)* $assign) $($parse)*} ($($rest)*) $($rest)*)
|
||||
};
|
||||
|
||||
(atom ($($stack:tt)+) $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($addeq:tt $($dup:tt)*) += $($rest:tt)*) => {
|
||||
$crate::__parse_ensure!(0 ($($stack)*) $bail ($($fuel)*) {($($buf)* $addeq) $($parse)*} ($($rest)*) $($rest)*)
|
||||
};
|
||||
|
||||
(atom ($($stack:tt)+) $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($subeq:tt $($dup:tt)*) -= $($rest:tt)*) => {
|
||||
$crate::__parse_ensure!(0 ($($stack)*) $bail ($($fuel)*) {($($buf)* $subeq) $($parse)*} ($($rest)*) $($rest)*)
|
||||
};
|
||||
|
||||
(atom ($($stack:tt)+) $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($muleq:tt $($dup:tt)*) *= $($rest:tt)*) => {
|
||||
$crate::__parse_ensure!(0 ($($stack)*) $bail ($($fuel)*) {($($buf)* $muleq) $($parse)*} ($($rest)*) $($rest)*)
|
||||
};
|
||||
|
||||
(atom ($($stack:tt)+) $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($diveq:tt $($dup:tt)*) /= $($rest:tt)*) => {
|
||||
$crate::__parse_ensure!(0 ($($stack)*) $bail ($($fuel)*) {($($buf)* $diveq) $($parse)*} ($($rest)*) $($rest)*)
|
||||
};
|
||||
|
||||
(atom ($($stack:tt)+) $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($remeq:tt $($dup:tt)*) %= $($rest:tt)*) => {
|
||||
$crate::__parse_ensure!(0 ($($stack)*) $bail ($($fuel)*) {($($buf)* $remeq) $($parse)*} ($($rest)*) $($rest)*)
|
||||
};
|
||||
|
||||
(atom ($($stack:tt)+) $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($bitxoreq:tt $($dup:tt)*) ^= $($rest:tt)*) => {
|
||||
$crate::__parse_ensure!(0 ($($stack)*) $bail ($($fuel)*) {($($buf)* $bitxoreq) $($parse)*} ($($rest)*) $($rest)*)
|
||||
};
|
||||
|
||||
(atom ($($stack:tt)+) $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($bitandeq:tt $($dup:tt)*) &= $($rest:tt)*) => {
|
||||
$crate::__parse_ensure!(0 ($($stack)*) $bail ($($fuel)*) {($($buf)* $bitandeq) $($parse)*} ($($rest)*) $($rest)*)
|
||||
};
|
||||
|
||||
(atom ($($stack:tt)+) $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($bitoreq:tt $($dup:tt)*) |= $($rest:tt)*) => {
|
||||
$crate::__parse_ensure!(0 ($($stack)*) $bail ($($fuel)*) {($($buf)* $bitoreq) $($parse)*} ($($rest)*) $($rest)*)
|
||||
};
|
||||
|
||||
(atom ($($stack:tt)+) $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($shleq:tt $($dup:tt)*) <<= $($rest:tt)*) => {
|
||||
$crate::__parse_ensure!(0 ($($stack)*) $bail ($($fuel)*) {($($buf)* $shleq) $($parse)*} ($($rest)*) $($rest)*)
|
||||
};
|
||||
|
||||
(atom ($($stack:tt)+) $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($shreq:tt $($dup:tt)*) >>= $($rest:tt)*) => {
|
||||
$crate::__parse_ensure!(0 ($($stack)*) $bail ($($fuel)*) {($($buf)* $shreq) $($parse)*} ($($rest)*) $($rest)*)
|
||||
};
|
||||
|
||||
// unrecognized expression
|
||||
|
||||
($state:tt $stack:tt ($($bail:tt)*) $($rest:tt)*) => {
|
||||
$crate::__fallback_ensure!($($bail)*)
|
||||
};
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
#[macro_export]
|
||||
macro_rules! __fancy_ensure {
|
||||
($lhs:expr, $op:tt, $rhs:expr) => {
|
||||
match (&$lhs, &$rhs) {
|
||||
(lhs, rhs) => {
|
||||
if !(lhs $op rhs) {
|
||||
#[allow(unused_imports)]
|
||||
use $crate::private::{BothDebug, NotBothDebug};
|
||||
return Err((lhs, rhs).__dispatch_ensure(
|
||||
$crate::private::concat!(
|
||||
"Condition failed: `",
|
||||
$crate::private::stringify!($lhs),
|
||||
" ",
|
||||
$crate::private::stringify!($op),
|
||||
" ",
|
||||
$crate::private::stringify!($rhs),
|
||||
"`",
|
||||
),
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
#[macro_export]
|
||||
macro_rules! __fallback_ensure {
|
||||
($cond:expr $(,)?) => {
|
||||
if !$cond {
|
||||
return $crate::private::Err($crate::Error::msg(
|
||||
$crate::private::concat!("Condition failed: `", $crate::private::stringify!($cond), "`")
|
||||
));
|
||||
}
|
||||
};
|
||||
($cond:expr, $msg:literal $(,)?) => {
|
||||
if !$cond {
|
||||
return $crate::private::Err($crate::anyhow!($msg));
|
||||
}
|
||||
};
|
||||
($cond:expr, $err:expr $(,)?) => {
|
||||
if !$cond {
|
||||
return $crate::private::Err($crate::anyhow!($err));
|
||||
}
|
||||
};
|
||||
($cond:expr, $fmt:expr, $($arg:tt)*) => {
|
||||
if !$cond {
|
||||
return $crate::private::Err($crate::anyhow!($fmt, $($arg)*));
|
||||
}
|
||||
};
|
||||
}
|
|
@ -1,10 +1,10 @@
|
|||
use crate::alloc::Box;
|
||||
use crate::backtrace::Backtrace;
|
||||
use crate::chain::Chain;
|
||||
#[cfg(any(feature = "std", anyhow_no_ptr_addr_of))]
|
||||
use crate::ptr::Mut;
|
||||
use crate::ptr::{Own, Ref};
|
||||
use crate::{Error, StdError};
|
||||
use alloc::boxed::Box;
|
||||
use core::any::TypeId;
|
||||
use core::fmt::{self, Debug, Display};
|
||||
use core::mem::ManuallyDrop;
|
||||
|
@ -25,6 +25,7 @@ impl Error {
|
|||
/// created here to ensure that a backtrace exists.
|
||||
#[cfg(feature = "std")]
|
||||
#[cfg_attr(doc_cfg, doc(cfg(feature = "std")))]
|
||||
#[cold]
|
||||
pub fn new<E>(error: E) -> Self
|
||||
where
|
||||
E: StdError + Send + Sync + 'static,
|
||||
|
@ -70,6 +71,7 @@ impl Error {
|
|||
/// .await
|
||||
/// }
|
||||
/// ```
|
||||
#[cold]
|
||||
pub fn msg<M>(message: M) -> Self
|
||||
where
|
||||
M: Display + Debug + Send + Sync + 'static,
|
||||
|
@ -78,6 +80,7 @@ impl Error {
|
|||
}
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
#[cold]
|
||||
pub(crate) fn from_std<E>(error: E, backtrace: Option<Backtrace>) -> Self
|
||||
where
|
||||
E: StdError + Send + Sync + 'static,
|
||||
|
@ -100,6 +103,7 @@ impl Error {
|
|||
unsafe { Error::construct(error, vtable, backtrace) }
|
||||
}
|
||||
|
||||
#[cold]
|
||||
pub(crate) fn from_adhoc<M>(message: M, backtrace: Option<Backtrace>) -> Self
|
||||
where
|
||||
M: Display + Debug + Send + Sync + 'static,
|
||||
|
@ -125,6 +129,7 @@ impl Error {
|
|||
unsafe { Error::construct(error, vtable, backtrace) }
|
||||
}
|
||||
|
||||
#[cold]
|
||||
pub(crate) fn from_display<M>(message: M, backtrace: Option<Backtrace>) -> Self
|
||||
where
|
||||
M: Display + Send + Sync + 'static,
|
||||
|
@ -151,6 +156,7 @@ impl Error {
|
|||
}
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
#[cold]
|
||||
pub(crate) fn from_context<C, E>(context: C, error: E, backtrace: Option<Backtrace>) -> Self
|
||||
where
|
||||
C: Display + Send + Sync + 'static,
|
||||
|
@ -177,6 +183,7 @@ impl Error {
|
|||
}
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
#[cold]
|
||||
pub(crate) fn from_boxed(
|
||||
error: Box<dyn StdError + Send + Sync>,
|
||||
backtrace: Option<Backtrace>,
|
||||
|
@ -207,6 +214,7 @@ impl Error {
|
|||
//
|
||||
// Unsafe because the given vtable must have sensible behavior on the error
|
||||
// value of type E.
|
||||
#[cold]
|
||||
unsafe fn construct<E>(
|
||||
error: E,
|
||||
vtable: &'static ErrorVTable,
|
||||
|
@ -284,6 +292,7 @@ impl Error {
|
|||
/// })
|
||||
/// }
|
||||
/// ```
|
||||
#[cold]
|
||||
pub fn context<C>(self, context: C) -> Self
|
||||
where
|
||||
C: Display + Send + Sync + 'static,
|
||||
|
@ -373,6 +382,7 @@ impl Error {
|
|||
/// ```
|
||||
#[cfg(feature = "std")]
|
||||
#[cfg_attr(doc_cfg, doc(cfg(feature = "std")))]
|
||||
#[cold]
|
||||
pub fn chain(&self) -> Chain {
|
||||
unsafe { ErrorImpl::chain(self.inner.by_ref()) }
|
||||
}
|
||||
|
@ -515,6 +525,7 @@ impl<E> From<E> for Error
|
|||
where
|
||||
E: StdError + Send + Sync + 'static,
|
||||
{
|
||||
#[cold]
|
||||
fn from(error: E) -> Self {
|
||||
let backtrace = backtrace_if_absent!(error);
|
||||
Error::from_std(error, backtrace)
|
||||
|
@ -879,6 +890,7 @@ impl ErrorImpl {
|
|||
.expect("backtrace capture failed")
|
||||
}
|
||||
|
||||
#[cold]
|
||||
pub(crate) unsafe fn chain(this: Ref<Self>) -> Chain {
|
||||
Chain::new(Self::error(this))
|
||||
}
|
||||
|
@ -917,6 +929,7 @@ where
|
|||
}
|
||||
|
||||
impl From<Error> for Box<dyn StdError + Send + Sync + 'static> {
|
||||
#[cold]
|
||||
fn from(error: Error) -> Self {
|
||||
let outer = ManuallyDrop::new(error);
|
||||
unsafe {
|
||||
|
|
|
@ -62,6 +62,7 @@ pub trait AdhocKind: Sized {
|
|||
impl<T> AdhocKind for &T where T: ?Sized + Display + Debug + Send + Sync + 'static {}
|
||||
|
||||
impl Adhoc {
|
||||
#[cold]
|
||||
pub fn new<M>(self, message: M) -> Error
|
||||
where
|
||||
M: Display + Debug + Send + Sync + 'static,
|
||||
|
@ -82,6 +83,7 @@ pub trait TraitKind: Sized {
|
|||
impl<E> TraitKind for E where E: Into<Error> {}
|
||||
|
||||
impl Trait {
|
||||
#[cold]
|
||||
pub fn new<E>(self, error: E) -> Error
|
||||
where
|
||||
E: Into<Error>,
|
||||
|
@ -106,6 +108,7 @@ impl BoxedKind for Box<dyn StdError + Send + Sync> {}
|
|||
|
||||
#[cfg(feature = "std")]
|
||||
impl Boxed {
|
||||
#[cold]
|
||||
pub fn new(self, error: Box<dyn StdError + Send + Sync>) -> Error {
|
||||
let backtrace = backtrace_if_absent!(error);
|
||||
Error::from_boxed(error, backtrace)
|
||||
|
|
|
@ -128,10 +128,11 @@
|
|||
//! # ;
|
||||
//! ```
|
||||
//!
|
||||
//! - If using the nightly channel, a backtrace is captured and printed with the
|
||||
//! error if the underlying error type does not already provide its own. In
|
||||
//! order to see backtraces, they must be enabled through the environment
|
||||
//! variables described in [`std::backtrace`]:
|
||||
//! - If using the nightly channel, or stable with `features = ["backtrace"]`, a
|
||||
//! backtrace is captured and printed with the error if the underlying error
|
||||
//! type does not already provide its own. In order to see backtraces, they
|
||||
//! must be enabled through the environment variables described in
|
||||
//! [`std::backtrace`]:
|
||||
//!
|
||||
//! - If you want panics and errors to both have backtraces, set
|
||||
//! `RUST_BACKTRACE=1`;
|
||||
|
@ -209,7 +210,7 @@
|
|||
//! will require an explicit `.map_err(Error::msg)` when working with a
|
||||
//! non-Anyhow error type inside a function that returns Anyhow's error type.
|
||||
|
||||
#![doc(html_root_url = "https://docs.rs/anyhow/1.0.41")]
|
||||
#![doc(html_root_url = "https://docs.rs/anyhow/1.0.51")]
|
||||
#![cfg_attr(backtrace, feature(backtrace))]
|
||||
#![cfg_attr(doc_cfg, feature(doc_cfg))]
|
||||
#![cfg_attr(not(feature = "std"), no_std)]
|
||||
|
@ -230,21 +231,13 @@
|
|||
clippy::wrong_self_convention
|
||||
)]
|
||||
|
||||
mod alloc {
|
||||
#[cfg(not(feature = "std"))]
|
||||
extern crate alloc;
|
||||
|
||||
#[cfg(not(feature = "std"))]
|
||||
pub use alloc::boxed::Box;
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
pub use std::boxed::Box;
|
||||
}
|
||||
extern crate alloc;
|
||||
|
||||
#[macro_use]
|
||||
mod backtrace;
|
||||
mod chain;
|
||||
mod context;
|
||||
mod ensure;
|
||||
mod error;
|
||||
mod fmt;
|
||||
mod kind;
|
||||
|
@ -609,13 +602,40 @@ pub trait Context<T, E>: context::private::Sealed {
|
|||
F: FnOnce() -> C;
|
||||
}
|
||||
|
||||
/// Equivalent to Ok::<_, anyhow::Error>(value).
|
||||
///
|
||||
/// This simplifies creation of an anyhow::Result in places where type inference
|
||||
/// cannot deduce the `E` type of the result — without needing to write
|
||||
/// `Ok::<_, anyhow::Error>(value)`.
|
||||
///
|
||||
/// One might think that `anyhow::Result::Ok(value)` would work in such cases
|
||||
/// but it does not.
|
||||
///
|
||||
/// ```console
|
||||
/// error[E0282]: type annotations needed for `std::result::Result<i32, E>`
|
||||
/// --> src/main.rs:11:13
|
||||
/// |
|
||||
/// 11 | let _ = anyhow::Result::Ok(1);
|
||||
/// | - ^^^^^^^^^^^^^^^^^^ cannot infer type for type parameter `E` declared on the enum `Result`
|
||||
/// | |
|
||||
/// | consider giving this pattern the explicit type `std::result::Result<i32, E>`, where the type parameter `E` is specified
|
||||
/// ```
|
||||
#[allow(non_snake_case)]
|
||||
pub fn Ok<T>(t: T) -> Result<T> {
|
||||
Result::Ok(t)
|
||||
}
|
||||
|
||||
// Not public API. Referenced by macro-generated code.
|
||||
#[doc(hidden)]
|
||||
pub mod private {
|
||||
use crate::Error;
|
||||
use core::fmt::{Debug, Display};
|
||||
use alloc::fmt;
|
||||
use core::fmt::Arguments;
|
||||
|
||||
pub use crate::ensure::{BothDebug, NotBothDebug};
|
||||
pub use alloc::format;
|
||||
pub use core::result::Result::Err;
|
||||
pub use core::{concat, format_args, stringify};
|
||||
|
||||
#[doc(hidden)]
|
||||
pub mod kind {
|
||||
|
@ -625,33 +645,21 @@ pub mod private {
|
|||
pub use crate::kind::BoxedKind;
|
||||
}
|
||||
|
||||
pub fn new_adhoc<M>(message: M) -> Error
|
||||
where
|
||||
M: Display + Debug + Send + Sync + 'static,
|
||||
{
|
||||
Error::from_adhoc(message, backtrace!())
|
||||
}
|
||||
|
||||
#[cfg(anyhow_no_macro_reexport)]
|
||||
pub use crate::{__anyhow_concat as concat, __anyhow_stringify as stringify};
|
||||
#[cfg(not(anyhow_no_macro_reexport))]
|
||||
pub use core::{concat, stringify};
|
||||
|
||||
#[cfg(anyhow_no_macro_reexport)]
|
||||
#[doc(hidden)]
|
||||
#[macro_export]
|
||||
macro_rules! __anyhow_concat {
|
||||
($($tt:tt)*) => {
|
||||
concat!($($tt)*)
|
||||
};
|
||||
}
|
||||
#[inline]
|
||||
#[cold]
|
||||
pub fn format_err(args: Arguments) -> Error {
|
||||
#[cfg(anyhow_no_fmt_arguments_as_str)]
|
||||
let fmt_arguments_as_str = None::<&str>;
|
||||
#[cfg(not(anyhow_no_fmt_arguments_as_str))]
|
||||
let fmt_arguments_as_str = args.as_str();
|
||||
|
||||
#[cfg(anyhow_no_macro_reexport)]
|
||||
#[doc(hidden)]
|
||||
#[macro_export]
|
||||
macro_rules! __anyhow_stringify {
|
||||
($($tt:tt)*) => {
|
||||
stringify!($($tt)*)
|
||||
};
|
||||
if let Some(message) = fmt_arguments_as_str {
|
||||
// anyhow!("literal"), can downcast to &'static str
|
||||
Error::msg(message)
|
||||
} else {
|
||||
// anyhow!("interpolate {var}"), can downcast to String
|
||||
Error::msg(fmt::format(args))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -50,6 +50,7 @@
|
|||
/// # Ok(())
|
||||
/// # }
|
||||
/// ```
|
||||
#[cfg(doc)]
|
||||
#[macro_export]
|
||||
macro_rules! bail {
|
||||
($msg:literal $(,)?) => {
|
||||
|
@ -63,6 +64,27 @@ macro_rules! bail {
|
|||
};
|
||||
}
|
||||
|
||||
// Workaround for crates that intentionally contained `{}` in an error message
|
||||
// prior to https://github.com/dtolnay/anyhow/issues/55 catching the missing
|
||||
// format args.
|
||||
#[cfg(not(doc))]
|
||||
#[macro_export]
|
||||
macro_rules! bail {
|
||||
// https://github.com/estk/log4rs/blob/afa0351af56b3bfd1780389700051d7e4d8bbdc9/src/append/rolling_file/policy/compound/roll/fixed_window.rs#L261
|
||||
("pattern does not contain `{}`") => {
|
||||
return $crate::private::Err($crate::Error::msg("pattern does not contain `{}`"))
|
||||
};
|
||||
($msg:literal $(,)?) => {
|
||||
return $crate::private::Err($crate::anyhow!($msg))
|
||||
};
|
||||
($err:expr $(,)?) => {
|
||||
return $crate::private::Err($crate::anyhow!($err))
|
||||
};
|
||||
($fmt:expr, $($arg:tt)*) => {
|
||||
return $crate::private::Err($crate::anyhow!($fmt, $($arg)*))
|
||||
};
|
||||
}
|
||||
|
||||
/// Return early with an error if a condition is not satisfied.
|
||||
///
|
||||
/// This macro is equivalent to `if !$cond { return
|
||||
|
@ -111,13 +133,15 @@ macro_rules! bail {
|
|||
/// # Ok(())
|
||||
/// # }
|
||||
/// ```
|
||||
#[cfg(doc)]
|
||||
#[macro_export]
|
||||
macro_rules! ensure {
|
||||
($cond:expr $(,)?) => {
|
||||
$crate::ensure!(
|
||||
$cond,
|
||||
$crate::private::concat!("Condition failed: `", $crate::private::stringify!($cond), "`"),
|
||||
)
|
||||
if !$cond {
|
||||
return $crate::private::Err($crate::Error::msg(
|
||||
$crate::private::concat!("Condition failed: `", $crate::private::stringify!($cond), "`")
|
||||
));
|
||||
}
|
||||
};
|
||||
($cond:expr, $msg:literal $(,)?) => {
|
||||
if !$cond {
|
||||
|
@ -136,6 +160,22 @@ macro_rules! ensure {
|
|||
};
|
||||
}
|
||||
|
||||
#[cfg(not(doc))]
|
||||
#[macro_export]
|
||||
macro_rules! ensure {
|
||||
($($tt:tt)*) => {
|
||||
$crate::__parse_ensure!(
|
||||
/* state */ 0
|
||||
/* stack */ ()
|
||||
/* bail */ ($($tt)*)
|
||||
/* fuel */ (~~~~~~~~~~ ~~~~~~~~~~ ~~~~~~~~~~ ~~~~~~~~~~ ~~~~~~~~~~ ~~~~~~~~~~ ~~~~~~~~~~ ~~~~~~~~~~ ~~~~~~~~~~ ~~~~~~~~~~ ~~~~~~~~~~ ~~~~~~~~~~)
|
||||
/* parse */ {()}
|
||||
/* dup */ ($($tt)*)
|
||||
/* rest */ $($tt)*
|
||||
)
|
||||
};
|
||||
}
|
||||
|
||||
/// Construct an ad-hoc error from a string or existing non-`anyhow` error
|
||||
/// value.
|
||||
///
|
||||
|
@ -166,18 +206,18 @@ macro_rules! ensure {
|
|||
/// ```
|
||||
#[macro_export]
|
||||
macro_rules! anyhow {
|
||||
($msg:literal $(,)?) => {
|
||||
// Handle $:literal as a special case to make cargo-expanded code more
|
||||
// concise in the common case.
|
||||
$crate::private::new_adhoc($msg)
|
||||
};
|
||||
($msg:literal $(,)?) => ({
|
||||
let error = $crate::private::format_err($crate::private::format_args!($msg));
|
||||
error
|
||||
});
|
||||
($err:expr $(,)?) => ({
|
||||
use $crate::private::kind::*;
|
||||
match $err {
|
||||
let error = match $err {
|
||||
error => (&error).anyhow_kind().new(error),
|
||||
}
|
||||
};
|
||||
error
|
||||
});
|
||||
($fmt:expr, $($arg:tt)*) => {
|
||||
$crate::private::new_adhoc(format!($fmt, $($arg)*))
|
||||
$crate::Error::msg($crate::private::format!($fmt, $($arg)*))
|
||||
};
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use crate::alloc::Box;
|
||||
use alloc::boxed::Box;
|
||||
use core::marker::PhantomData;
|
||||
use core::ptr::NonNull;
|
||||
|
||||
|
|
|
@ -1,3 +1,8 @@
|
|||
#![allow(
|
||||
// Clippy bug: https://github.com/rust-lang/rust-clippy/issues/7422
|
||||
clippy::nonstandard_macro_braces,
|
||||
)]
|
||||
|
||||
use anyhow::anyhow;
|
||||
use std::error::Error as StdError;
|
||||
use std::io;
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
use anyhow::{anyhow, Error};
|
||||
use anyhow::{anyhow, Chain, Error};
|
||||
|
||||
fn error() -> Error {
|
||||
anyhow!(0).context(1).context(2).context(3)
|
||||
anyhow!({ 0 }).context(1).context(2).context(3)
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -33,13 +33,36 @@ fn test_len() {
|
|||
let e = error();
|
||||
let mut chain = e.chain();
|
||||
assert_eq!(4, chain.len());
|
||||
assert_eq!((4, Some(4)), chain.size_hint());
|
||||
assert_eq!("3", chain.next().unwrap().to_string());
|
||||
assert_eq!(3, chain.len());
|
||||
assert_eq!((3, Some(3)), chain.size_hint());
|
||||
assert_eq!("0", chain.next_back().unwrap().to_string());
|
||||
assert_eq!(2, chain.len());
|
||||
assert_eq!((2, Some(2)), chain.size_hint());
|
||||
assert_eq!("2", chain.next().unwrap().to_string());
|
||||
assert_eq!(1, chain.len());
|
||||
assert_eq!((1, Some(1)), chain.size_hint());
|
||||
assert_eq!("1", chain.next_back().unwrap().to_string());
|
||||
assert_eq!(0, chain.len());
|
||||
assert_eq!((0, Some(0)), chain.size_hint());
|
||||
assert!(chain.next().is_none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_default() {
|
||||
let mut c = Chain::default();
|
||||
assert!(c.next().is_none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_clone() {
|
||||
let e = error();
|
||||
let mut chain = e.chain().clone();
|
||||
assert_eq!("3", chain.next().unwrap().to_string());
|
||||
assert_eq!("2", chain.next().unwrap().to_string());
|
||||
assert_eq!("1", chain.next().unwrap().to_string());
|
||||
assert_eq!("0", chain.next().unwrap().to_string());
|
||||
assert!(chain.next().is_none());
|
||||
assert!(chain.next_back().is_none());
|
||||
}
|
||||
|
|
|
@ -1,3 +1,8 @@
|
|||
#![allow(
|
||||
// Clippy bug: https://github.com/rust-lang/rust-clippy/issues/7422
|
||||
clippy::nonstandard_macro_braces,
|
||||
)]
|
||||
|
||||
mod drop;
|
||||
|
||||
use crate::drop::{DetectDrop, Flag};
|
||||
|
@ -19,6 +24,7 @@ macro_rules! context_type {
|
|||
#[derive(Debug)]
|
||||
struct $name {
|
||||
message: &'static str,
|
||||
#[allow(dead_code)]
|
||||
drop: DetectDrop,
|
||||
}
|
||||
|
||||
|
@ -157,3 +163,10 @@ fn test_unsuccessful_downcast() {
|
|||
drop(err);
|
||||
assert!(dropped.all());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_root_cause() {
|
||||
let (err, _) = make_chain();
|
||||
|
||||
assert_eq!(err.root_cause().to_string(), "no such file or directory");
|
||||
}
|
||||
|
|
|
@ -8,6 +8,26 @@ use std::error::Error as StdError;
|
|||
|
||||
#[test]
|
||||
fn test_convert() {
|
||||
let has_dropped = Flag::new();
|
||||
let error = Error::new(DetectDrop::new(&has_dropped));
|
||||
let box_dyn = Box::<dyn StdError>::from(error);
|
||||
assert_eq!("oh no!", box_dyn.to_string());
|
||||
drop(box_dyn);
|
||||
assert!(has_dropped.get());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_convert_send() {
|
||||
let has_dropped = Flag::new();
|
||||
let error = Error::new(DetectDrop::new(&has_dropped));
|
||||
let box_dyn = Box::<dyn StdError + Send>::from(error);
|
||||
assert_eq!("oh no!", box_dyn.to_string());
|
||||
drop(box_dyn);
|
||||
assert!(has_dropped.get());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_convert_send_sync() {
|
||||
let has_dropped = Flag::new();
|
||||
let error = Error::new(DetectDrop::new(&has_dropped));
|
||||
let box_dyn = Box::<dyn StdError + Send + Sync>::from(error);
|
||||
|
|
|
@ -84,6 +84,15 @@ fn test_drop() {
|
|||
assert!(has_dropped.get());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_as_ref() {
|
||||
let error = bail_error().unwrap_err();
|
||||
let ref_dyn: &dyn StdError = error.as_ref();
|
||||
assert_eq!("oh no!", ref_dyn.to_string());
|
||||
let ref_dyn_send_sync: &(dyn StdError + Send + Sync) = error.as_ref();
|
||||
assert_eq!("oh no!", ref_dyn_send_sync.to_string());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_large_alignment() {
|
||||
#[repr(align(64))]
|
||||
|
|
|
@ -0,0 +1,686 @@
|
|||
#![allow(
|
||||
clippy::diverging_sub_expression,
|
||||
clippy::if_same_then_else,
|
||||
clippy::ifs_same_cond,
|
||||
clippy::items_after_statements,
|
||||
clippy::let_and_return,
|
||||
clippy::let_underscore_drop,
|
||||
clippy::match_bool,
|
||||
clippy::never_loop,
|
||||
clippy::redundant_closure_call,
|
||||
clippy::redundant_pattern_matching,
|
||||
clippy::too_many_lines,
|
||||
clippy::unit_arg,
|
||||
clippy::while_immutable_condition,
|
||||
clippy::zero_ptr
|
||||
)]
|
||||
|
||||
use anyhow::{anyhow, ensure, Chain, Error, Result};
|
||||
use std::fmt::Debug;
|
||||
use std::iter;
|
||||
use std::marker::{PhantomData, PhantomData as P};
|
||||
use std::ops::Add;
|
||||
use std::ptr;
|
||||
|
||||
struct S;
|
||||
|
||||
impl<T> Add<T> for S {
|
||||
type Output = bool;
|
||||
fn add(self, rhs: T) -> Self::Output {
|
||||
let _ = rhs;
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
trait Trait: Sized {
|
||||
const V: usize = 0;
|
||||
fn t(self, i: i32) -> i32 {
|
||||
i
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> Trait for T {}
|
||||
|
||||
#[track_caller]
|
||||
fn assert_err<T: Debug>(result: impl FnOnce() -> Result<T>, expected: &'static str) {
|
||||
let actual = result().unwrap_err().to_string();
|
||||
|
||||
let mut accepted_alternatives = expected.split('\n');
|
||||
let expected = accepted_alternatives.next_back().unwrap();
|
||||
if accepted_alternatives.any(|alternative| actual == alternative) {
|
||||
return;
|
||||
}
|
||||
|
||||
assert_eq!(actual, expected);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_recursion() {
|
||||
// Must not blow the default #[recursion_limit], which is 128.
|
||||
#[rustfmt::skip]
|
||||
let test = || Ok(ensure!(
|
||||
false | false | false | false | false | false | false | false | false |
|
||||
false | false | false | false | false | false | false | false | false |
|
||||
false | false | false | false | false | false | false | false | false |
|
||||
false | false | false | false | false | false | false | false | false |
|
||||
false | false | false | false | false | false | false | false | false |
|
||||
false | false | false | false | false | false | false | false | false |
|
||||
false | false | false | false | false | false | false | false | false
|
||||
));
|
||||
|
||||
test().unwrap_err();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_low_precedence_control_flow() {
|
||||
#[allow(unreachable_code)]
|
||||
let test = || {
|
||||
let val = loop {
|
||||
// Break has lower precedence than the comparison operators so the
|
||||
// expression here is `S + (break (1 == 1))`. It would be bad if the
|
||||
// ensure macro partitioned this input into `(S + break 1) == (1)`
|
||||
// because that means a different thing than what was written.
|
||||
ensure!(S + break 1 == 1);
|
||||
};
|
||||
Ok(val)
|
||||
};
|
||||
|
||||
assert!(test().unwrap());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_low_precedence_binary_operator() {
|
||||
// Must not partition as `false == (true && false)`.
|
||||
let test = || Ok(ensure!(false == true && false));
|
||||
assert_err(test, "Condition failed: `false == true && false`");
|
||||
|
||||
// But outside the root level, it is fine.
|
||||
let test = || Ok(ensure!(while false == true && false {} < ()));
|
||||
assert_err(
|
||||
test,
|
||||
"Condition failed: `while false == true && false { } < ()` (() vs ())",
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_closure() {
|
||||
// Must not partition as `(S + move) || (1 == 1)` by treating move as an
|
||||
// identifier, nor as `(S + move || 1) == (1)` by misinterpreting the
|
||||
// closure precedence.
|
||||
let test = || Ok(ensure!(S + move || 1 == 1));
|
||||
assert_err(test, "Condition failed: `S + (move || 1 == 1)`");
|
||||
|
||||
let test = || Ok(ensure!(S + || 1 == 1));
|
||||
assert_err(test, "Condition failed: `S + (|| 1 == 1)`");
|
||||
|
||||
// Must not partition as `S + ((move | ()) | 1) == 1` by treating those
|
||||
// pipes as bitwise-or.
|
||||
let test = || Ok(ensure!(S + move |()| 1 == 1));
|
||||
assert_err(test, "Condition failed: `S + (move |()| 1 == 1)`");
|
||||
|
||||
let test = || Ok(ensure!(S + |()| 1 == 1));
|
||||
assert_err(test, "Condition failed: `S + (|()| 1 == 1)`");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_unary() {
|
||||
let mut x = &1;
|
||||
let test = || Ok(ensure!(*x == 2));
|
||||
assert_err(test, "Condition failed: `*x == 2` (1 vs 2)");
|
||||
|
||||
let test = || Ok(ensure!(!x == 1));
|
||||
assert_err(test, "Condition failed: `!x == 1` (-2 vs 1)");
|
||||
|
||||
let test = || Ok(ensure!(-x == 1));
|
||||
assert_err(test, "Condition failed: `-x == 1` (-1 vs 1)");
|
||||
|
||||
let test = || Ok(ensure!(&x == &&2));
|
||||
assert_err(test, "Condition failed: `&x == &&2` (1 vs 2)");
|
||||
|
||||
let test = || Ok(ensure!(&mut x == *&&mut &2));
|
||||
assert_err(test, "Condition failed: `&mut x == *&&mut &2` (1 vs 2)");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_if() {
|
||||
#[rustfmt::skip]
|
||||
let test = || Ok(ensure!(if false {}.t(1) == 2));
|
||||
assert_err(test, "Condition failed: `if false { }.t(1) == 2` (1 vs 2)");
|
||||
|
||||
#[rustfmt::skip]
|
||||
let test = || Ok(ensure!(if false {} else {}.t(1) == 2));
|
||||
assert_err(
|
||||
test,
|
||||
"Condition failed: `if false { } else { }.t(1) == 2` (1 vs 2)",
|
||||
);
|
||||
|
||||
#[rustfmt::skip]
|
||||
let test = || Ok(ensure!(if false {} else if false {}.t(1) == 2));
|
||||
assert_err(
|
||||
test,
|
||||
"Condition failed: `if false { } else if false { }.t(1) == 2` (1 vs 2)",
|
||||
);
|
||||
|
||||
#[rustfmt::skip]
|
||||
let test = || Ok(ensure!(if let 1 = 2 {}.t(1) == 2));
|
||||
assert_err(
|
||||
test,
|
||||
"Condition failed: `if let 1 = 2 { }.t(1) == 2` (1 vs 2)",
|
||||
);
|
||||
|
||||
#[rustfmt::skip]
|
||||
let test = || Ok(ensure!(if let 1 | 2 = 2 {}.t(1) == 2));
|
||||
assert_err(
|
||||
test,
|
||||
"Condition failed: `if let 1 | 2 = 2 { }.t(1) == 2` (1 vs 2)",
|
||||
);
|
||||
|
||||
#[rustfmt::skip]
|
||||
let test = || Ok(ensure!(if let | 1 | 2 = 2 {}.t(1) == 2));
|
||||
assert_err(
|
||||
test,
|
||||
"Condition failed: `if let 1 | 2 = 2 { }.t(1) == 2` (1 vs 2)",
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_loop() {
|
||||
#[rustfmt::skip]
|
||||
let test = || Ok(ensure!(1 + loop { break 1 } == 1));
|
||||
assert_err(
|
||||
test,
|
||||
// 1.54 puts a double space after loop
|
||||
"Condition failed: `1 + loop { break 1 } == 1` (2 vs 1)\n\
|
||||
Condition failed: `1 + loop { break 1 } == 1` (2 vs 1)",
|
||||
);
|
||||
|
||||
#[rustfmt::skip]
|
||||
let test = || Ok(ensure!(1 + 'a: loop { break 'a 1 } == 1));
|
||||
assert_err(
|
||||
test,
|
||||
// 1.54 puts a double space after loop
|
||||
"Condition failed: `1 + 'a: loop { break 'a 1 } == 1` (2 vs 1)\n\
|
||||
Condition failed: `1 + 'a: loop { break 'a 1 } == 1` (2 vs 1)",
|
||||
);
|
||||
|
||||
#[rustfmt::skip]
|
||||
let test = || Ok(ensure!(while false {}.t(1) == 2));
|
||||
assert_err(
|
||||
test,
|
||||
"Condition failed: `while false { }.t(1) == 2` (1 vs 2)",
|
||||
);
|
||||
|
||||
#[rustfmt::skip]
|
||||
let test = || Ok(ensure!(while let None = Some(1) {}.t(1) == 2));
|
||||
assert_err(
|
||||
test,
|
||||
"Condition failed: `while let None = Some(1) { }.t(1) == 2` (1 vs 2)",
|
||||
);
|
||||
|
||||
#[rustfmt::skip]
|
||||
let test = || Ok(ensure!(for _x in iter::once(0) {}.t(1) == 2));
|
||||
assert_err(
|
||||
test,
|
||||
"Condition failed: `for _x in iter::once(0) { }.t(1) == 2` (1 vs 2)",
|
||||
);
|
||||
|
||||
#[rustfmt::skip]
|
||||
let test = || Ok(ensure!(for | _x in iter::once(0) {}.t(1) == 2));
|
||||
assert_err(
|
||||
test,
|
||||
"Condition failed: `for _x in iter::once(0) { }.t(1) == 2` (1 vs 2)",
|
||||
);
|
||||
|
||||
#[rustfmt::skip]
|
||||
let test = || Ok(ensure!(for true | false in iter::empty() {}.t(1) == 2));
|
||||
assert_err(
|
||||
test,
|
||||
"Condition failed: `for true | false in iter::empty() { }.t(1) == 2` (1 vs 2)",
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_match() {
|
||||
#[rustfmt::skip]
|
||||
let test = || Ok(ensure!(match 1 == 1 { true => 1, false => 0 } == 2));
|
||||
assert_err(
|
||||
test,
|
||||
"Condition failed: `match 1 == 1 { true => 1, false => 0, } == 2` (1 vs 2)",
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_atom() {
|
||||
let test = || Ok(ensure!([false, false].len() > 3));
|
||||
assert_err(
|
||||
test,
|
||||
"Condition failed: `[false, false].len() > 3` (2 vs 3)",
|
||||
);
|
||||
|
||||
#[rustfmt::skip]
|
||||
let test = || Ok(ensure!({ let x = 1; x } >= 3));
|
||||
assert_err(test, "Condition failed: `{ let x = 1; x } >= 3` (1 vs 3)");
|
||||
|
||||
let test = || Ok(ensure!(S + async { 1 } == true));
|
||||
assert_err(
|
||||
test,
|
||||
"Condition failed: `S + async { 1 } == true` (false vs true)",
|
||||
);
|
||||
|
||||
let test = || Ok(ensure!(S + async move { 1 } == true));
|
||||
assert_err(
|
||||
test,
|
||||
"Condition failed: `S + async move { 1 } == true` (false vs true)",
|
||||
);
|
||||
|
||||
let x = &1;
|
||||
let test = || Ok(ensure!(S + unsafe { ptr::read(x) } == true));
|
||||
assert_err(
|
||||
test,
|
||||
"Condition failed: `S + unsafe { ptr::read(x) } == true` (false vs true)",
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_path() {
|
||||
let test = || Ok(ensure!(crate::S.t(1) == 2));
|
||||
assert_err(test, "Condition failed: `crate::S.t(1) == 2` (1 vs 2)");
|
||||
|
||||
let test = || Ok(ensure!(::anyhow::Error::root_cause.t(1) == 2));
|
||||
assert_err(
|
||||
test,
|
||||
"Condition failed: `::anyhow::Error::root_cause.t(1) == 2` (1 vs 2)",
|
||||
);
|
||||
|
||||
let test = || Ok(ensure!(Error::msg::<&str>.t(1) == 2));
|
||||
assert_err(
|
||||
test,
|
||||
"Condition failed: `Error::msg::<&str>.t(1) == 2` (1 vs 2)",
|
||||
);
|
||||
|
||||
#[rustfmt::skip]
|
||||
let test = || Ok(ensure!(Error::msg::<&str,>.t(1) == 2));
|
||||
assert_err(
|
||||
test,
|
||||
"Condition failed: `Error::msg::<&str>.t(1) == 2` (1 vs 2)",
|
||||
);
|
||||
|
||||
let test = || Ok(ensure!(Error::msg::<<str as ToOwned>::Owned>.t(1) == 2));
|
||||
assert_err(
|
||||
test,
|
||||
"Condition failed: `Error::msg::<<str as ToOwned>::Owned>.t(1) == 2` (1 vs 2)",
|
||||
);
|
||||
|
||||
let test = || Ok(ensure!(Chain::<'static>::new.t(1) == 2));
|
||||
assert_err(
|
||||
test,
|
||||
"Condition failed: `Chain::<'static>::new.t(1) == 2` (1 vs 2)",
|
||||
);
|
||||
|
||||
#[rustfmt::skip]
|
||||
let test = || Ok(ensure!(Chain::<'static,>::new.t(1) == 2));
|
||||
assert_err(
|
||||
test,
|
||||
"Condition failed: `Chain::<'static>::new.t(1) == 2` (1 vs 2)",
|
||||
);
|
||||
|
||||
#[derive(PartialOrd, PartialEq, Debug)]
|
||||
enum E<'a, T> {
|
||||
#[allow(dead_code)]
|
||||
T(&'a T),
|
||||
U,
|
||||
}
|
||||
|
||||
#[rustfmt::skip]
|
||||
let test = || Ok(ensure!(E::U::<>>E::U::<u8>));
|
||||
assert_err(test, "Condition failed: `E::U::<> > E::U::<u8>` (U vs U)");
|
||||
|
||||
#[rustfmt::skip]
|
||||
let test = || Ok(ensure!(E::U::<u8>>E::U));
|
||||
assert_err(test, "Condition failed: `E::U::<u8> > E::U` (U vs U)");
|
||||
|
||||
#[rustfmt::skip]
|
||||
let test = || Ok(ensure!(E::U::<u8,>>E::U));
|
||||
assert_err(test, "Condition failed: `E::U::<u8> > E::U` (U vs U)");
|
||||
|
||||
let test = || Ok(ensure!(PhantomData::<dyn Debug + Sync> != PhantomData));
|
||||
assert_err(
|
||||
test,
|
||||
"Condition failed: `PhantomData::<dyn Debug + Sync> != PhantomData` (PhantomData vs PhantomData)",
|
||||
);
|
||||
|
||||
let test = || Ok(ensure!(PhantomData::<dyn Fn() + Sync> != PhantomData));
|
||||
assert_err(
|
||||
test,
|
||||
"Condition failed: `PhantomData::<dyn Fn() + Sync> != PhantomData` (PhantomData vs PhantomData)",
|
||||
);
|
||||
|
||||
#[rustfmt::skip]
|
||||
let test = || {
|
||||
Ok(ensure!(
|
||||
PhantomData::<dyn Fn::() + ::std::marker::Sync> != PhantomData
|
||||
))
|
||||
};
|
||||
assert_err(
|
||||
test,
|
||||
"Condition failed: `PhantomData::<dyn Fn() + ::std::marker::Sync> != PhantomData` (PhantomData vs PhantomData)",
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_macro() {
|
||||
let test = || Ok(ensure!(anyhow!("...").to_string().len() <= 1));
|
||||
assert_err(
|
||||
test,
|
||||
"Condition failed: `anyhow!(\"...\").to_string().len() <= 1` (3 vs 1)",
|
||||
);
|
||||
|
||||
let test = || Ok(ensure!(vec![1].len() < 1));
|
||||
assert_err(test, "Condition failed: `vec![1].len() < 1` (1 vs 1)");
|
||||
|
||||
let test = || Ok(ensure!(stringify! {} != ""));
|
||||
assert_err(
|
||||
test,
|
||||
"Condition failed: `stringify! { } != \"\"` (\"\" vs \"\")",
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_trailer() {
|
||||
let test = || Ok(ensure!((|| 1)() == 2));
|
||||
assert_err(test, "Condition failed: `(|| 1)() == 2` (1 vs 2)");
|
||||
|
||||
let test = || Ok(ensure!(b"hmm"[1] == b'c'));
|
||||
assert_err(test, "Condition failed: `b\"hmm\"[1] == b'c'` (109 vs 99)");
|
||||
|
||||
let test = || Ok(ensure!(PhantomData::<u8> {} != PhantomData));
|
||||
assert_err(
|
||||
test,
|
||||
"Condition failed: `PhantomData::<u8>{} != PhantomData` (PhantomData vs PhantomData)",
|
||||
);
|
||||
|
||||
let result = Ok::<_, Error>(1);
|
||||
let test = || Ok(ensure!(result? == 2));
|
||||
assert_err(test, "Condition failed: `result? == 2` (1 vs 2)");
|
||||
|
||||
let test = || Ok(ensure!((2, 3).1 == 2));
|
||||
assert_err(test, "Condition failed: `(2, 3).1 == 2` (3 vs 2)");
|
||||
|
||||
#[rustfmt::skip]
|
||||
let test = || Ok(ensure!((2, (3, 4)). 1.1 == 2));
|
||||
assert_err(test, "Condition failed: `(2, (3, 4)).1.1 == 2` (4 vs 2)");
|
||||
|
||||
let err = anyhow!("");
|
||||
let test = || Ok(ensure!(err.is::<&str>() == false));
|
||||
assert_err(
|
||||
test,
|
||||
"Condition failed: `err.is::<&str>() == false` (true vs false)",
|
||||
);
|
||||
|
||||
let test = || Ok(ensure!(err.is::<<str as ToOwned>::Owned>() == true));
|
||||
assert_err(
|
||||
test,
|
||||
"Condition failed: `err.is::<<str as ToOwned>::Owned>() == true` (false vs true)",
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_whitespace() {
|
||||
#[derive(Debug)]
|
||||
pub struct Point {
|
||||
pub x: i32,
|
||||
pub y: i32,
|
||||
}
|
||||
|
||||
let point = Point { x: 0, y: 0 };
|
||||
let test = || Ok(ensure!("" == format!("{:#?}", point)));
|
||||
assert_err(
|
||||
test,
|
||||
"Condition failed: `\"\" == format!(\"{:#?}\", point)`",
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_too_long() {
|
||||
let test = || Ok(ensure!("" == "x".repeat(10)));
|
||||
assert_err(
|
||||
test,
|
||||
"Condition failed: `\"\" == \"x\".repeat(10)` (\"\" vs \"xxxxxxxxxx\")",
|
||||
);
|
||||
|
||||
let test = || Ok(ensure!("" == "x".repeat(80)));
|
||||
assert_err(test, "Condition failed: `\"\" == \"x\".repeat(80)`");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_as() {
|
||||
let test = || Ok(ensure!('\0' as u8 > 1));
|
||||
assert_err(test, "Condition failed: `'\\0' as u8 > 1` (0 vs 1)");
|
||||
|
||||
let test = || Ok(ensure!('\0' as ::std::primitive::u8 > 1));
|
||||
assert_err(
|
||||
test,
|
||||
"Condition failed: `'\\0' as ::std::primitive::u8 > 1` (0 vs 1)",
|
||||
);
|
||||
|
||||
let test = || Ok(ensure!(&[0] as &[i32] == [1]));
|
||||
assert_err(
|
||||
test,
|
||||
"Condition failed: `&[0] as &[i32] == [1]` ([0] vs [1])",
|
||||
);
|
||||
|
||||
let test = || Ok(ensure!(0 as *const () as *mut _ == 1 as *mut ()));
|
||||
assert_err(
|
||||
test,
|
||||
"Condition failed: `0 as *const () as *mut _ == 1 as *mut ()` (0x0 vs 0x1)",
|
||||
);
|
||||
|
||||
let s = "";
|
||||
let test = || Ok(ensure!(s as &str != s));
|
||||
assert_err(test, "Condition failed: `s as &str != s` (\"\" vs \"\")");
|
||||
|
||||
let test = || Ok(ensure!(&s as &&str != &s));
|
||||
assert_err(test, "Condition failed: `&s as &&str != &s` (\"\" vs \"\")");
|
||||
|
||||
let test = || Ok(ensure!(s as &'static str != s));
|
||||
assert_err(
|
||||
test,
|
||||
"Condition failed: `s as &'static str != s` (\"\" vs \"\")",
|
||||
);
|
||||
|
||||
let test = || Ok(ensure!(&s as &&'static str != &s));
|
||||
assert_err(
|
||||
test,
|
||||
"Condition failed: `&s as &&'static str != &s` (\"\" vs \"\")",
|
||||
);
|
||||
|
||||
let m: &mut str = Default::default();
|
||||
let test = || Ok(ensure!(m as &mut str != s));
|
||||
assert_err(
|
||||
test,
|
||||
"Condition failed: `m as &mut str != s` (\"\" vs \"\")",
|
||||
);
|
||||
|
||||
let test = || Ok(ensure!(&m as &&mut str != &s));
|
||||
assert_err(
|
||||
test,
|
||||
"Condition failed: `&m as &&mut str != &s` (\"\" vs \"\")",
|
||||
);
|
||||
|
||||
let test = || Ok(ensure!(&m as &&'static mut str != &s));
|
||||
assert_err(
|
||||
test,
|
||||
"Condition failed: `&m as &&'static mut str != &s` (\"\" vs \"\")",
|
||||
);
|
||||
|
||||
let f = || {};
|
||||
let test = || Ok(ensure!(f as fn() as usize * 0 != 0));
|
||||
assert_err(
|
||||
test,
|
||||
"Condition failed: `f as fn() as usize * 0 != 0` (0 vs 0)",
|
||||
);
|
||||
|
||||
let test = || Ok(ensure!(f as fn() -> () as usize * 0 != 0));
|
||||
assert_err(
|
||||
test,
|
||||
"Condition failed: `f as fn() -> () as usize * 0 != 0` (0 vs 0)",
|
||||
);
|
||||
|
||||
let test = || Ok(ensure!(f as for<'a> fn() as usize * 0 != 0));
|
||||
assert_err(
|
||||
test,
|
||||
"Condition failed: `f as for<'a>fn() as usize * 0 != 0` (0 vs 0)",
|
||||
);
|
||||
|
||||
let test = || Ok(ensure!(f as unsafe fn() as usize * 0 != 0));
|
||||
assert_err(
|
||||
test,
|
||||
"Condition failed: `f as unsafe fn() as usize * 0 != 0` (0 vs 0)",
|
||||
);
|
||||
|
||||
#[rustfmt::skip]
|
||||
let test = || Ok(ensure!(f as extern "Rust" fn() as usize * 0 != 0));
|
||||
assert_err(
|
||||
test,
|
||||
"Condition failed: `f as extern \"Rust\" fn() as usize * 0 != 0` (0 vs 0)",
|
||||
);
|
||||
|
||||
extern "C" fn extern_fn() {}
|
||||
#[rustfmt::skip]
|
||||
let test = || Ok(ensure!(extern_fn as extern fn() as usize * 0 != 0));
|
||||
assert_err(
|
||||
test,
|
||||
"Condition failed: `extern_fn as extern fn() as usize * 0 != 0` (0 vs 0)",
|
||||
);
|
||||
|
||||
let f = || -> ! { panic!() };
|
||||
let test = || Ok(ensure!(f as fn() -> ! as usize * 0 != 0));
|
||||
assert_err(
|
||||
test,
|
||||
"Condition failed: `f as fn() -> ! as usize * 0 != 0` (0 vs 0)",
|
||||
);
|
||||
|
||||
trait EqDebug<T>: PartialEq<T> + Debug {
|
||||
type Assoc;
|
||||
}
|
||||
|
||||
impl<S, T> EqDebug<T> for S
|
||||
where
|
||||
S: PartialEq<T> + Debug,
|
||||
{
|
||||
type Assoc = bool;
|
||||
}
|
||||
|
||||
let test = || Ok(ensure!(&0 as &dyn EqDebug<i32, Assoc = bool> != &0));
|
||||
assert_err(
|
||||
test,
|
||||
"Condition failed: `&0 as &dyn EqDebug<i32, Assoc = bool> != &0` (0 vs 0)",
|
||||
);
|
||||
|
||||
let test = || {
|
||||
Ok(ensure!(
|
||||
PhantomData as PhantomData<<i32 as ToOwned>::Owned> != PhantomData
|
||||
))
|
||||
};
|
||||
assert_err(
|
||||
test,
|
||||
"Condition failed: `PhantomData as PhantomData<<i32 as ToOwned>::Owned> != PhantomData` (PhantomData vs PhantomData)",
|
||||
);
|
||||
|
||||
macro_rules! int {
|
||||
(...) => {
|
||||
u8
|
||||
};
|
||||
}
|
||||
|
||||
let test = || Ok(ensure!(0 as int!(...) != 0));
|
||||
assert_err(test, "Condition failed: `0 as int!(...) != 0` (0 vs 0)");
|
||||
|
||||
let test = || Ok(ensure!(0 as int![...] != 0));
|
||||
assert_err(test, "Condition failed: `0 as int![...] != 0` (0 vs 0)");
|
||||
|
||||
let test = || Ok(ensure!(0 as int! {...} != 0));
|
||||
assert_err(test, "Condition failed: `0 as int! { ... } != 0` (0 vs 0)");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_pat() {
|
||||
let test = || Ok(ensure!(if let ref mut _x @ 0 = 0 { 0 } else { 1 } == 1));
|
||||
assert_err(
|
||||
test,
|
||||
"Condition failed: `if let ref mut _x @ 0 = 0 { 0 } else { 1 } == 1` (0 vs 1)",
|
||||
);
|
||||
|
||||
let test = || Ok(ensure!(if let -1..=1 = 0 { 0 } else { 1 } == 1));
|
||||
assert_err(
|
||||
test,
|
||||
"Condition failed: `if let -1 ..=1 = 0 { 0 } else { 1 } == 1` (0 vs 1)",
|
||||
);
|
||||
|
||||
let test = || Ok(ensure!(if let &0 = &0 { 0 } else { 1 } == 1));
|
||||
assert_err(
|
||||
test,
|
||||
"Condition failed: `if let &0 = &0 { 0 } else { 1 } == 1` (0 vs 1)",
|
||||
);
|
||||
|
||||
let test = || Ok(ensure!(if let &&0 = &&0 { 0 } else { 1 } == 1));
|
||||
assert_err(
|
||||
test,
|
||||
"Condition failed: `if let &&0 = &&0 { 0 } else { 1 } == 1` (0 vs 1)",
|
||||
);
|
||||
|
||||
let test = || Ok(ensure!(if let &mut 0 = &mut 0 { 0 } else { 1 } == 1));
|
||||
assert_err(
|
||||
test,
|
||||
"Condition failed: `if let &mut 0 = &mut 0 { 0 } else { 1 } == 1` (0 vs 1)",
|
||||
);
|
||||
|
||||
let test = || Ok(ensure!(if let &&mut 0 = &&mut 0 { 0 } else { 1 } == 1));
|
||||
assert_err(
|
||||
test,
|
||||
"Condition failed: `if let &&mut 0 = &&mut 0 { 0 } else { 1 } == 1` (0 vs 1)",
|
||||
);
|
||||
|
||||
let test = || Ok(ensure!(if let (0, 1) = (0, 1) { 0 } else { 1 } == 1));
|
||||
assert_err(
|
||||
test,
|
||||
"Condition failed: `if let (0, 1) = (0, 1) { 0 } else { 1 } == 1` (0 vs 1)",
|
||||
);
|
||||
|
||||
let test = || Ok(ensure!(if let [0] = b"\0" { 0 } else { 1 } == 1));
|
||||
assert_err(
|
||||
test,
|
||||
"Condition failed: `if let [0] = b\"\\0\" { 0 } else { 1 } == 1` (0 vs 1)",
|
||||
);
|
||||
|
||||
let p = PhantomData::<u8>;
|
||||
let test = || Ok(ensure!(if let P::<u8> {} = p { 0 } else { 1 } == 1));
|
||||
assert_err(
|
||||
test,
|
||||
"Condition failed: `if let P::<u8> { } = p { 0 } else { 1 } == 1` (0 vs 1)",
|
||||
);
|
||||
|
||||
let test = || Ok(ensure!(if let ::std::marker::PhantomData = p {} != ()));
|
||||
assert_err(
|
||||
test,
|
||||
"Condition failed: `if let ::std::marker::PhantomData = p { } != ()` (() vs ())",
|
||||
);
|
||||
|
||||
let test = || Ok(ensure!(if let <S as Trait>::V = 0 { 0 } else { 1 } == 1));
|
||||
assert_err(
|
||||
test,
|
||||
"Condition failed: `if let <S as Trait>::V = 0 { 0 } else { 1 } == 1` (0 vs 1)",
|
||||
);
|
||||
|
||||
let test = || Ok(ensure!(for _ in iter::once(()) {} != ()));
|
||||
assert_err(
|
||||
test,
|
||||
"Condition failed: `for _ in iter::once(()) { } != ()` (() vs ())",
|
||||
);
|
||||
|
||||
let test = || Ok(ensure!(if let stringify!(x) = "x" { 0 } else { 1 } == 1));
|
||||
assert_err(
|
||||
test,
|
||||
"Condition failed: `if let stringify!(x) = \"x\" { 0 } else { 1 } == 1` (0 vs 1)",
|
||||
);
|
||||
}
|
|
@ -1,9 +1,17 @@
|
|||
#![allow(clippy::eq_op, clippy::shadow_unrelated, clippy::wildcard_imports)]
|
||||
#![allow(
|
||||
clippy::eq_op,
|
||||
clippy::items_after_statements,
|
||||
clippy::needless_pass_by_value,
|
||||
clippy::shadow_unrelated,
|
||||
clippy::wildcard_imports
|
||||
)]
|
||||
|
||||
mod common;
|
||||
|
||||
use self::common::*;
|
||||
use anyhow::ensure;
|
||||
use anyhow::{anyhow, ensure};
|
||||
use std::cell::Cell;
|
||||
use std::future;
|
||||
|
||||
#[test]
|
||||
fn test_messages() {
|
||||
|
@ -39,6 +47,33 @@ fn test_ensure() {
|
|||
};
|
||||
assert_eq!(
|
||||
f().unwrap_err().to_string(),
|
||||
"Condition failed: `v + v == 1`",
|
||||
"Condition failed: `v + v == 1` (2 vs 1)",
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_temporaries() {
|
||||
fn require_send_sync(_: impl Send + Sync) {}
|
||||
|
||||
require_send_sync(async {
|
||||
// If anyhow hasn't dropped any temporary format_args it creates by the
|
||||
// time it's done evaluating, those will stick around until the
|
||||
// semicolon, which is on the other side of the await point, making the
|
||||
// enclosing future non-Send.
|
||||
future::ready(anyhow!("...")).await;
|
||||
});
|
||||
|
||||
fn message(cell: Cell<&str>) -> &str {
|
||||
cell.get()
|
||||
}
|
||||
|
||||
require_send_sync(async {
|
||||
future::ready(anyhow!(message(Cell::new("...")))).await;
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_brace_escape() {
|
||||
let err = anyhow!("unterminated ${{..}} expression");
|
||||
assert_eq!("unterminated ${..} expression", err.to_string());
|
||||
}
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
use anyhow::{ensure, Result};
|
||||
|
||||
fn main() -> Result<()> {
|
||||
// `ensure!` must not partition this into `(false) == (false == true)`
|
||||
// because Rust doesn't ordinarily allow this form of expression.
|
||||
ensure!(false == false == true);
|
||||
Ok(())
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
error: comparison operators cannot be chained
|
||||
--> tests/ui/chained-comparison.rs:6:19
|
||||
|
|
||||
6 | ensure!(false == false == true);
|
||||
| ^^ ^^
|
||||
|
|
||||
help: split the comparison into two
|
||||
|
|
||||
6 | ensure!(false == false && false == true);
|
||||
| ++++++++
|
|
@ -0,0 +1,6 @@
|
|||
use anyhow::{ensure, Result};
|
||||
|
||||
fn main() -> Result<()> {
|
||||
ensure!();
|
||||
Ok(())
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
error: unexpected end of macro invocation
|
||||
--> tests/ui/empty-ensure.rs:4:5
|
||||
|
|
||||
4 | ensure!();
|
||||
| ^^^^^^^^^ missing tokens in macro arguments
|
||||
|
|
||||
= note: this error originates in the macro `$crate::__parse_ensure` (in Nightly builds, run with -Z macro-backtrace for more info)
|
|
@ -1,21 +1,42 @@
|
|||
error[E0599]: the method `anyhow_kind` exists for reference `&Error`, but its trait bounds were not satisfied
|
||||
--> $DIR/no-impl.rs:7:13
|
||||
|
|
||||
4 | struct Error;
|
||||
| -------------
|
||||
| |
|
||||
| doesn't satisfy `Error: Into<anyhow::Error>`
|
||||
| doesn't satisfy `Error: anyhow::private::kind::TraitKind`
|
||||
| doesn't satisfy `Error: std::fmt::Display`
|
||||
--> tests/ui/no-impl.rs:7:13
|
||||
|
|
||||
4 | struct Error;
|
||||
| -------------
|
||||
| |
|
||||
| doesn't satisfy `Error: Into<anyhow::Error>`
|
||||
| doesn't satisfy `Error: anyhow::private::kind::TraitKind`
|
||||
| doesn't satisfy `Error: std::fmt::Display`
|
||||
...
|
||||
7 | let _ = anyhow!(Error);
|
||||
| ^^^^^^^^^^^^^^ method cannot be called on `&Error` due to unsatisfied trait bounds
|
||||
|
|
||||
= note: the following trait bounds were not satisfied:
|
||||
`Error: Into<anyhow::Error>`
|
||||
which is required by `Error: anyhow::private::kind::TraitKind`
|
||||
`Error: std::fmt::Display`
|
||||
which is required by `&Error: anyhow::private::kind::AdhocKind`
|
||||
`&Error: Into<anyhow::Error>`
|
||||
which is required by `&Error: anyhow::private::kind::TraitKind`
|
||||
= note: this error originates in the macro `anyhow` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
7 | let _ = anyhow!(Error);
|
||||
| ^^^^^^^^^^^^^^ method cannot be called on `&Error` due to unsatisfied trait bounds
|
||||
|
|
||||
= note: the following trait bounds were not satisfied:
|
||||
`Error: Into<anyhow::Error>`
|
||||
which is required by `Error: anyhow::private::kind::TraitKind`
|
||||
`Error: std::fmt::Display`
|
||||
which is required by `&Error: anyhow::private::kind::AdhocKind`
|
||||
`&Error: Into<anyhow::Error>`
|
||||
which is required by `&Error: anyhow::private::kind::TraitKind`
|
||||
note: the following traits must be implemented
|
||||
--> $RUST/core/src/convert/mod.rs
|
||||
|
|
||||
| / pub trait Into<T>: Sized {
|
||||
| | /// Performs the conversion.
|
||||
| | #[must_use]
|
||||
| | #[stable(feature = "rust1", since = "1.0.0")]
|
||||
| | fn into(self) -> T;
|
||||
| | }
|
||||
| |_^
|
||||
|
|
||||
::: $RUST/core/src/fmt/mod.rs
|
||||
|
|
||||
| / pub trait Display {
|
||||
| | /// Formats the value using the given formatter.
|
||||
| | ///
|
||||
| | /// # Examples
|
||||
... |
|
||||
| | fn fmt(&self, f: &mut Formatter<'_>) -> Result;
|
||||
| | }
|
||||
| |_^
|
||||
= note: this error originates in the macro `anyhow` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
error[E0716]: temporary value dropped while borrowed
|
||||
--> $DIR/temporary-value.rs:4:22
|
||||
--> tests/ui/temporary-value.rs:4:22
|
||||
|
|
||||
4 | let _ = anyhow!(&String::new());
|
||||
| ---------^^^^^^^^^^^^^-- temporary value is freed at the end of this statement
|
||||
| ---------^^^^^^^^^^^^^-
|
||||
| | |
|
||||
| | creates a temporary which is freed while still in use
|
||||
| temporary value is freed at the end of this statement
|
||||
| argument requires that borrow lasts for `'static`
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
use anyhow::{bail, Result};
|
||||
|
||||
fn main() -> Result<()> {
|
||||
bail!("{} not found");
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
error: 1 positional argument in format string, but no arguments were given
|
||||
--> tests/ui/wrong-interpolation.rs:4:12
|
||||
|
|
||||
4 | bail!("{} not found");
|
||||
| ^^
|
|
@ -1 +1 @@
|
|||
{"files":{"CHANGELOG.md":"edf3c8b74500275d5c9136f23c82eadf5356d4e804ef629ac5d15842e6859897","Cargo.lock":"7c30080ec598ac111d312a1e1ace0df52e346dd70ebce305df876906324810bb","Cargo.toml":"1bc1fc9183477e937309eb3c3d25a4aea2973bb858cac84b119a243d0a787be3","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"15656cc11a8331f28c0986b8ab97220d3e76f98e60ed388b5ffad37dfac4710c","README.md":"950e645eba942c01ae12aaf835b23f2b70bcc75c561e663fe483e000d067a57e","examples/derive_enum.rs":"4d399f1805c48780443182aa141be4e3bf773649b118eab245280799e67742f6","publish.sh":"752e221bdd960666b127df15effddd3d789ff3f1762498961fc79ae99f9a27f1","src/error.rs":"88293a722e314bcc05e4836167b49e76520c9b3d7f64d1ae711f7bd29280f480","src/lib.rs":"78ad87737c6f5cdf38f1f2ed797587c6e258739397f21109d3a969f0ee33a140","src/size_hint.rs":"9762b183f8277ee4955fe5b22552961744b6237286758161a551f904ef43e3eb","src/unstructured.rs":"990a08e3037c9cecf7395deecc27fd8c99ec27c8d80c6b5f85c2aca75b629d6e","tests/derive.rs":"6a4aaa87ee08ea2b67e97e7f6fc7c6247ef9a11144b5465a802631ed0ee5465e","tests/path.rs":"a9706f00ce95d5a11652ae926830756d9111837b55073a0bc6a1eadd25033387"},"package":"237430fd6ed3740afe94eefcc278ae21e050285be882804e0d6e8695f0c94691"}
|
||||
{"files":{"CHANGELOG.md":"fd809eba6052a6f34ea7bcbad629dd27a09d1aace817269273bcd2c2dd10a36d","Cargo.lock":"1cc33e3427d1f564ec269b0222ff5b2372c082d01bbf3fd2d1b5e821a19f32a9","Cargo.toml":"6b2f8363fc6c07abdcc96cf7b4a7615720d9d7f958a8531e2b0d07e13efa682e","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"15656cc11a8331f28c0986b8ab97220d3e76f98e60ed388b5ffad37dfac4710c","README.md":"950e645eba942c01ae12aaf835b23f2b70bcc75c561e663fe483e000d067a57e","examples/derive_enum.rs":"4d399f1805c48780443182aa141be4e3bf773649b118eab245280799e67742f6","publish.sh":"752e221bdd960666b127df15effddd3d789ff3f1762498961fc79ae99f9a27f1","src/error.rs":"88293a722e314bcc05e4836167b49e76520c9b3d7f64d1ae711f7bd29280f480","src/lib.rs":"18ec8d74692260407ec6683a6f5ae0b9e65c9c258c4dc1510e3956b62b54169b","src/size_hint.rs":"9762b183f8277ee4955fe5b22552961744b6237286758161a551f904ef43e3eb","src/unstructured.rs":"ae7e2cbcd216bfd6cfe2a5e64fd405753da73546437ebf567f121f20f634c36e","tests/derive.rs":"6a4aaa87ee08ea2b67e97e7f6fc7c6247ef9a11144b5465a802631ed0ee5465e","tests/path.rs":"a9706f00ce95d5a11652ae926830756d9111837b55073a0bc6a1eadd25033387"},"package":"510c76ecefdceada737ea728f4f9a84bd2e1ef29f1ba555e560940fe279954de"}
|
|
@ -26,6 +26,31 @@ Released YYYY-MM-DD.
|
|||
|
||||
* TODO (or remove section if none)
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
## 1.0.3
|
||||
|
||||
Released 2021-11-20.
|
||||
|
||||
### Fixed
|
||||
|
||||
* Fixed documentation for `Unstructured::fill_bytes`. We forgot to update this
|
||||
way back in [#53](https://github.com/rust-fuzz/arbitrary/pull/53) when the
|
||||
behavior changed.
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
## 1.0.2
|
||||
|
||||
Released 2021-08-25.
|
||||
|
||||
### Added
|
||||
|
||||
* `Arbitrary` impls for `HashMap`s and `HashSet`s with custom `Hasher`s
|
||||
[#87](https://github.com/rust-fuzz/arbitrary/pull/87)
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
## 1.0.1
|
||||
|
||||
Released 2021-05-20.
|
||||
|
|
|
@ -4,16 +4,16 @@ version = 3
|
|||
|
||||
[[package]]
|
||||
name = "arbitrary"
|
||||
version = "1.0.1"
|
||||
version = "1.0.3"
|
||||
dependencies = [
|
||||
"derive_arbitrary",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "derive_arbitrary"
|
||||
version = "1.0.0"
|
||||
version = "1.0.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "df89dd0d075dea5cc5fdd6d5df6b8a61172a710b3efac1d6bdb9dd8b78f82c1a"
|
||||
checksum = "b24629208e87a2d8b396ff43b15c4afb0a69cea3fbbaa9ed9b92b7c02f0aed73"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
|
@ -22,27 +22,27 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.27"
|
||||
version = "1.0.24"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f0d8caf72986c1a598726adc988bb5984792ef84f5ee5aa50209145ee8077038"
|
||||
checksum = "1e0704ee1a7e00d7bb417d0770ea303c1bccbabf0ef1667dae92b5967f5f8a71"
|
||||
dependencies = [
|
||||
"unicode-xid",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.9"
|
||||
version = "1.0.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c3d0b9745dc2debf507c8422de05d7226cc1f0644216dfdfead988f9b1ab32a7"
|
||||
checksum = "991431c3519a3f36861882da93630ce66b52918dcf1b8e2fd66b397fc96f28df"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "1.0.72"
|
||||
version = "1.0.60"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a1e8cdbefb79a9a5a65e0db8b47b723ee907b7c7f8496c76a1770b5c310bab82"
|
||||
checksum = "c700597eca8a5a762beb35753ef6b94df201c81cca676604f547495a0d7f0081"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
|
@ -51,6 +51,6 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "unicode-xid"
|
||||
version = "0.2.2"
|
||||
version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3"
|
||||
checksum = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564"
|
||||
|
|
|
@ -3,24 +3,23 @@
|
|||
# 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
|
||||
# to registry (e.g., crates.io) dependencies.
|
||||
#
|
||||
# If you believe there's an error in this file please file an
|
||||
# issue against the rust-lang/cargo repository. If you're
|
||||
# editing this file be aware that the upstream Cargo.toml
|
||||
# will likely look very different (and much more reasonable)
|
||||
# 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 = "arbitrary"
|
||||
version = "1.0.1"
|
||||
version = "1.0.3"
|
||||
authors = ["The Rust-Fuzz Project Developers", "Nick Fitzgerald <fitzgen@gmail.com>", "Manish Goregaokar <manishsmail@gmail.com>", "Simonas Kazlauskas <arbitrary@kazlauskas.me>", "Brian L. Troutwine <brian@troutwine.us>", "Corey Farwell <coreyf@rwell.org>"]
|
||||
description = "The trait for generating structured data from unstructured data"
|
||||
documentation = "https://docs.rs/arbitrary/"
|
||||
readme = "README.md"
|
||||
keywords = ["arbitrary", "testing"]
|
||||
categories = ["development-tools::testing"]
|
||||
license = "MIT/Apache-2.0"
|
||||
license = "MIT OR Apache-2.0"
|
||||
repository = "https://github.com/rust-fuzz/arbitrary/"
|
||||
|
||||
[[example]]
|
||||
|
|
|
@ -45,6 +45,7 @@ use core::time::Duration;
|
|||
use std::borrow::{Cow, ToOwned};
|
||||
use std::collections::{BTreeMap, BTreeSet, BinaryHeap, HashMap, HashSet, LinkedList, VecDeque};
|
||||
use std::ffi::{CString, OsString};
|
||||
use std::hash::BuildHasher;
|
||||
use std::net::{Ipv4Addr, Ipv6Addr};
|
||||
use std::path::PathBuf;
|
||||
use std::rc::Rc;
|
||||
|
@ -98,7 +99,7 @@ use std::sync::{Arc, Mutex};
|
|||
/// Implementing `Arbitrary` mostly involves nested calls to other `Arbitrary`
|
||||
/// arbitrary implementations for each of your `struct` or `enum`'s members. But
|
||||
/// sometimes you need some amount of raw data, or you need to generate a
|
||||
/// variably-sized collection type, or you something of that sort. The
|
||||
/// variably-sized collection type, or something of that sort. The
|
||||
/// [`Unstructured`][crate::Unstructured] type helps you with these tasks.
|
||||
///
|
||||
/// ```
|
||||
|
@ -736,8 +737,8 @@ impl<'a, A: Arbitrary<'a> + Ord> Arbitrary<'a> for BinaryHeap<A> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'a, K: Arbitrary<'a> + Eq + ::std::hash::Hash, V: Arbitrary<'a>> Arbitrary<'a>
|
||||
for HashMap<K, V>
|
||||
impl<'a, K: Arbitrary<'a> + Eq + ::std::hash::Hash, V: Arbitrary<'a>, S: BuildHasher + Default>
|
||||
Arbitrary<'a> for HashMap<K, V, S>
|
||||
{
|
||||
fn arbitrary(u: &mut Unstructured<'a>) -> Result<Self> {
|
||||
u.arbitrary_iter()?.collect()
|
||||
|
@ -753,7 +754,9 @@ impl<'a, K: Arbitrary<'a> + Eq + ::std::hash::Hash, V: Arbitrary<'a>> Arbitrary<
|
|||
}
|
||||
}
|
||||
|
||||
impl<'a, A: Arbitrary<'a> + Eq + ::std::hash::Hash> Arbitrary<'a> for HashSet<A> {
|
||||
impl<'a, A: Arbitrary<'a> + Eq + ::std::hash::Hash, S: BuildHasher + Default> Arbitrary<'a>
|
||||
for HashSet<A, S>
|
||||
{
|
||||
fn arbitrary(u: &mut Unstructured<'a>) -> Result<Self> {
|
||||
u.arbitrary_iter()?.collect()
|
||||
}
|
||||
|
|
|
@ -389,8 +389,8 @@ impl<'a> Unstructured<'a> {
|
|||
/// `Arbitrary` implementations like `<Vec<u8>>::arbitrary` and
|
||||
/// `String::arbitrary` over using this method directly.
|
||||
///
|
||||
/// If this `Unstructured` does not have enough data to fill the whole
|
||||
/// `buffer`, an error is returned.
|
||||
/// If this `Unstructured` does not have enough underlying data to fill the
|
||||
/// whole `buffer`, it pads the buffer out with zeros.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
|
@ -400,8 +400,15 @@ impl<'a> Unstructured<'a> {
|
|||
/// let mut u = Unstructured::new(&[1, 2, 3, 4]);
|
||||
///
|
||||
/// let mut buf = [0; 2];
|
||||
///
|
||||
/// assert!(u.fill_buffer(&mut buf).is_ok());
|
||||
/// assert_eq!(buf, [1, 2]);
|
||||
///
|
||||
/// assert!(u.fill_buffer(&mut buf).is_ok());
|
||||
/// assert_eq!(buf, [3, 4]);
|
||||
///
|
||||
/// assert!(u.fill_buffer(&mut buf).is_ok());
|
||||
/// assert_eq!(buf, [0, 0]);
|
||||
/// ```
|
||||
pub fn fill_buffer(&mut self, buffer: &mut [u8]) -> Result<()> {
|
||||
let n = std::cmp::min(buffer.len(), self.data.len());
|
||||
|
|
|
@ -1 +1 @@
|
|||
{"files":{"CHANGELOG.md":"9608f4cde67279f69e80b85373f19c1dde90a075b51d930e25e26d7ddabbfa03","Cargo.toml":"f4001657c27de1386a449fc5035abc0016f4f70ad99161b16e263d1eb2892dd8","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"0245ee104228a100ce5fceecf43e25faae450494d9173f43fd94c27d69fdac13","README.md":"2264c34c62ea4c617d72047b00749b4786dfb9dff2fac24e0320170ee0cd19c8","benches/arraystring.rs":"fad1cecef71c290375befc77c75a868988b8d74135e8f8732bc5b58c85a8ab46","benches/extend.rs":"c38ecedbc88217a7e9fe1a73f916b168a96e48010a7ccd3dba5c3f8dea030d5d","ci/miri.sh":"6bad1d135e1bdd67a6b91c870a7cf5ee09a85f9515633592a6abfbba95fdaf52","src/array_string.rs":"cefc432a025d780e01113144cbd5c0856d4424ec7fba4e626ddea523fbc8bbaf","src/arrayvec.rs":"32da1d3202f621852a3b884491f7a1086b7d813fe64b5cd7cab858ad3e967560","src/arrayvec_impl.rs":"a5e3391dc350041651f0ba3816c863ff7f552ff553e4a88f801481dfad7e7613","src/char.rs":"1de50e1d6045af2b3496426492315ba774986f9bc8301ffa391de861a08cc9cb","src/errors.rs":"ca44c0987f59ae57623088d80013e75129101caea93c278c8ebb0df898bc6b1b","src/lib.rs":"29a4123616c0912ccae5d931d45f0ccc3746647da1ba077c34538824910dd0ca","src/utils.rs":"d1cdc508dfca385e63f1f57bc8b53ed4a7f515e4ac1ebaa97b1d543fc8369432","tests/serde.rs":"117eb2961b5954d13c577edf60bbb07cb7481685cc9d6c49760a981d71465849","tests/tests.rs":"c1cd94337f4dc9aa31a6c16e334319389c605a98ccc5792e5489167cb614b7cb"},"package":"be4dc07131ffa69b8072d35f5007352af944213cde02545e2103680baed38fcd"}
|
||||
{"files":{"CHANGELOG.md":"f684ba712e1546b4cc7de9637f484598cd3fa49b7e7b32c2d98562a8f78ce98c","Cargo.toml":"94a588809d4be252f0146b9e193abc1b22d8afcce0265af19f12905a3db37998","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"0245ee104228a100ce5fceecf43e25faae450494d9173f43fd94c27d69fdac13","README.md":"2264c34c62ea4c617d72047b00749b4786dfb9dff2fac24e0320170ee0cd19c8","benches/arraystring.rs":"fad1cecef71c290375befc77c75a868988b8d74135e8f8732bc5b58c85a8ab46","benches/extend.rs":"c38ecedbc88217a7e9fe1a73f916b168a96e48010a7ccd3dba5c3f8dea030d5d","ci/miri.sh":"6bad1d135e1bdd67a6b91c870a7cf5ee09a85f9515633592a6abfbba95fdaf52","src/array_string.rs":"4f0c2dab882e6df7d10a0b043220587626e64ff94dd53a80949667ed861490de","src/arrayvec.rs":"61fba79217f564e54761c25651c06ec3f6d23b9c6af4bfd621992ef2bb95a74b","src/arrayvec_impl.rs":"a5e3391dc350041651f0ba3816c863ff7f552ff553e4a88f801481dfad7e7613","src/char.rs":"1de50e1d6045af2b3496426492315ba774986f9bc8301ffa391de861a08cc9cb","src/errors.rs":"7fa2ff2350f811d52a210a7346c526d6715cacefd38a46e2d3b57ab7dc62b1ab","src/lib.rs":"29a4123616c0912ccae5d931d45f0ccc3746647da1ba077c34538824910dd0ca","src/utils.rs":"d1cdc508dfca385e63f1f57bc8b53ed4a7f515e4ac1ebaa97b1d543fc8369432","tests/serde.rs":"117eb2961b5954d13c577edf60bbb07cb7481685cc9d6c49760a981d71465849","tests/tests.rs":"f8a18ff5deadb167832964ca0fff4f280129dd4a1de024e9cc76ffb7efe1c12c"},"package":"8da52d66c7071e2e3fa2a1e5c6d088fec47b593032b254f5e980de8ea54454d6"}
|
|
@ -1,6 +1,20 @@
|
|||
Recent Changes (arrayvec)
|
||||
=========================
|
||||
|
||||
## 0.7.2
|
||||
|
||||
- Add `.as_mut_str()` to `ArrayString` by @clarfonthey
|
||||
- Add `remaining_capacity` to `ArrayString` by @bhgomes
|
||||
- Add `zero_filled` constructor by @c410-f3r
|
||||
- Optimize `retain` by @TennyZhuang and @niklasf
|
||||
- Make the following methods `const` by @bhgomes:
|
||||
- len
|
||||
- is_empty
|
||||
- capacity
|
||||
- is_full
|
||||
- remaining_capacity
|
||||
- CapacityError::new
|
||||
|
||||
## 0.7.1
|
||||
|
||||
- Add new ArrayVec methods `.take()` and `.into_inner_unchecked()` by @conradludgate
|
||||
|
|
|
@ -3,17 +3,16 @@
|
|||
# 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
|
||||
# to registry (e.g., crates.io) dependencies.
|
||||
#
|
||||
# If you believe there's an error in this file please file an
|
||||
# issue against the rust-lang/cargo repository. If you're
|
||||
# editing this file be aware that the upstream Cargo.toml
|
||||
# will likely look very different (and much more reasonable)
|
||||
# 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 = "arrayvec"
|
||||
version = "0.7.1"
|
||||
version = "0.7.2"
|
||||
authors = ["bluss"]
|
||||
description = "A vector with fixed capacity, backed by an array (it can be stored on the stack too). Implements fixed capacity ArrayVec and ArrayString."
|
||||
documentation = "https://docs.rs/arrayvec/"
|
||||
|
|
|
@ -82,11 +82,11 @@ impl<const CAP: usize> ArrayString<CAP>
|
|||
|
||||
/// Return the length of the string.
|
||||
#[inline]
|
||||
pub fn len(&self) -> usize { self.len as usize }
|
||||
pub const fn len(&self) -> usize { self.len as usize }
|
||||
|
||||
/// Returns whether the string is empty.
|
||||
#[inline]
|
||||
pub fn is_empty(&self) -> bool { self.len() == 0 }
|
||||
pub const fn is_empty(&self) -> bool { self.len() == 0 }
|
||||
|
||||
/// Create a new `ArrayString` from a `str`.
|
||||
///
|
||||
|
@ -129,6 +129,28 @@ impl<const CAP: usize> ArrayString<CAP>
|
|||
Ok(vec)
|
||||
}
|
||||
|
||||
/// Create a new `ArrayString` value fully filled with ASCII NULL characters (`\0`). Useful
|
||||
/// to be used as a buffer to collect external data or as a buffer for intermediate processing.
|
||||
///
|
||||
/// ```
|
||||
/// use arrayvec::ArrayString;
|
||||
///
|
||||
/// let string = ArrayString::<16>::zero_filled();
|
||||
/// assert_eq!(string.len(), 16);
|
||||
/// ```
|
||||
#[inline]
|
||||
pub fn zero_filled() -> Self {
|
||||
assert_capacity_limit!(CAP);
|
||||
// SAFETY: `assert_capacity_limit` asserts that `len` won't overflow and
|
||||
// `zeroed` fully fills the array with nulls.
|
||||
unsafe {
|
||||
ArrayString {
|
||||
xs: MaybeUninit::zeroed().assume_init(),
|
||||
len: CAP as _
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Return the capacity of the `ArrayString`.
|
||||
///
|
||||
/// ```
|
||||
|
@ -138,7 +160,7 @@ impl<const CAP: usize> ArrayString<CAP>
|
|||
/// assert_eq!(string.capacity(), 3);
|
||||
/// ```
|
||||
#[inline(always)]
|
||||
pub fn capacity(&self) -> usize { CAP }
|
||||
pub const fn capacity(&self) -> usize { CAP }
|
||||
|
||||
/// Return if the `ArrayString` is completely filled.
|
||||
///
|
||||
|
@ -150,7 +172,20 @@ impl<const CAP: usize> ArrayString<CAP>
|
|||
/// string.push_str("A");
|
||||
/// assert!(string.is_full());
|
||||
/// ```
|
||||
pub fn is_full(&self) -> bool { self.len() == self.capacity() }
|
||||
pub const fn is_full(&self) -> bool { self.len() == self.capacity() }
|
||||
|
||||
/// Returns the capacity left in the `ArrayString`.
|
||||
///
|
||||
/// ```
|
||||
/// use arrayvec::ArrayString;
|
||||
///
|
||||
/// let mut string = ArrayString::<3>::from("abc").unwrap();
|
||||
/// string.pop();
|
||||
/// assert_eq!(string.remaining_capacity(), 1);
|
||||
/// ```
|
||||
pub const fn remaining_capacity(&self) -> usize {
|
||||
self.capacity() - self.len()
|
||||
}
|
||||
|
||||
/// Adds the given char to the end of the string.
|
||||
///
|
||||
|
@ -370,6 +405,11 @@ impl<const CAP: usize> ArrayString<CAP>
|
|||
self
|
||||
}
|
||||
|
||||
/// Return a mutable string slice of the whole `ArrayString`.
|
||||
pub fn as_mut_str(&mut self) -> &mut str {
|
||||
self
|
||||
}
|
||||
|
||||
fn as_ptr(&self) -> *const u8 {
|
||||
self.xs.as_ptr() as *const u8
|
||||
}
|
||||
|
|
|
@ -108,7 +108,7 @@ impl<T, const CAP: usize> ArrayVec<T, CAP> {
|
|||
/// assert_eq!(array.len(), 2);
|
||||
/// ```
|
||||
#[inline(always)]
|
||||
pub fn len(&self) -> usize { self.len as usize }
|
||||
pub const fn len(&self) -> usize { self.len as usize }
|
||||
|
||||
/// Returns whether the `ArrayVec` is empty.
|
||||
///
|
||||
|
@ -120,7 +120,7 @@ impl<T, const CAP: usize> ArrayVec<T, CAP> {
|
|||
/// assert_eq!(array.is_empty(), true);
|
||||
/// ```
|
||||
#[inline]
|
||||
pub fn is_empty(&self) -> bool { self.len() == 0 }
|
||||
pub const fn is_empty(&self) -> bool { self.len() == 0 }
|
||||
|
||||
/// Return the capacity of the `ArrayVec`.
|
||||
///
|
||||
|
@ -131,7 +131,7 @@ impl<T, const CAP: usize> ArrayVec<T, CAP> {
|
|||
/// assert_eq!(array.capacity(), 3);
|
||||
/// ```
|
||||
#[inline(always)]
|
||||
pub fn capacity(&self) -> usize { CAP }
|
||||
pub const fn capacity(&self) -> usize { CAP }
|
||||
|
||||
/// Return true if the `ArrayVec` is completely filled to its capacity, false otherwise.
|
||||
///
|
||||
|
@ -143,7 +143,7 @@ impl<T, const CAP: usize> ArrayVec<T, CAP> {
|
|||
/// array.push(1);
|
||||
/// assert!(array.is_full());
|
||||
/// ```
|
||||
pub fn is_full(&self) -> bool { self.len() == self.capacity() }
|
||||
pub const fn is_full(&self) -> bool { self.len() == self.capacity() }
|
||||
|
||||
/// Returns the capacity left in the `ArrayVec`.
|
||||
///
|
||||
|
@ -154,7 +154,7 @@ impl<T, const CAP: usize> ArrayVec<T, CAP> {
|
|||
/// array.pop();
|
||||
/// assert_eq!(array.remaining_capacity(), 1);
|
||||
/// ```
|
||||
pub fn remaining_capacity(&self) -> usize {
|
||||
pub const fn remaining_capacity(&self) -> usize {
|
||||
self.capacity() - self.len()
|
||||
}
|
||||
|
||||
|
@ -493,21 +493,38 @@ impl<T, const CAP: usize> ArrayVec<T, CAP> {
|
|||
|
||||
let mut g = BackshiftOnDrop { v: self, processed_len: 0, deleted_cnt: 0, original_len };
|
||||
|
||||
while g.processed_len < original_len {
|
||||
#[inline(always)]
|
||||
fn process_one<F: FnMut(&mut T) -> bool, T, const CAP: usize, const DELETED: bool>(
|
||||
f: &mut F,
|
||||
g: &mut BackshiftOnDrop<'_, T, CAP>
|
||||
) -> bool {
|
||||
let cur = unsafe { g.v.as_mut_ptr().add(g.processed_len) };
|
||||
if !f(unsafe { &mut *cur }) {
|
||||
g.processed_len += 1;
|
||||
g.deleted_cnt += 1;
|
||||
unsafe { ptr::drop_in_place(cur) };
|
||||
continue;
|
||||
return false;
|
||||
}
|
||||
if g.deleted_cnt > 0 {
|
||||
if DELETED {
|
||||
unsafe {
|
||||
let hole_slot = g.v.as_mut_ptr().add(g.processed_len - g.deleted_cnt);
|
||||
ptr::copy_nonoverlapping(cur, hole_slot, 1);
|
||||
}
|
||||
}
|
||||
g.processed_len += 1;
|
||||
true
|
||||
}
|
||||
|
||||
// Stage 1: Nothing was deleted.
|
||||
while g.processed_len != original_len {
|
||||
if !process_one::<F, T, CAP, false>(&mut f, &mut g) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Stage 2: Some elements were deleted.
|
||||
while g.processed_len != original_len {
|
||||
process_one::<F, T, CAP, true>(&mut f, &mut g);
|
||||
}
|
||||
|
||||
drop(g);
|
||||
|
|
|
@ -12,7 +12,7 @@ pub struct CapacityError<T = ()> {
|
|||
|
||||
impl<T> CapacityError<T> {
|
||||
/// Create a new `CapacityError` from `element`.
|
||||
pub fn new(element: T) -> CapacityError<T> {
|
||||
pub const fn new(element: T) -> CapacityError<T> {
|
||||
CapacityError {
|
||||
element: element,
|
||||
}
|
||||
|
|
|
@ -773,7 +773,6 @@ fn test_arrayvec_const_constructible() {
|
|||
assert_eq!(var[..], [vec![3, 5, 8]]);
|
||||
}
|
||||
|
||||
|
||||
#[test]
|
||||
fn test_arraystring_const_constructible() {
|
||||
const AS: ArrayString<10> = ArrayString::new_const();
|
||||
|
@ -786,3 +785,9 @@ fn test_arraystring_const_constructible() {
|
|||
}
|
||||
|
||||
|
||||
#[test]
|
||||
fn test_arraystring_zero_filled_has_some_sanity_checks() {
|
||||
let string = ArrayString::<4>::zero_filled();
|
||||
assert_eq!(string.as_str(), "\0\0\0\0");
|
||||
assert_eq!(string.len(), 4);
|
||||
}
|
Различия файлов скрыты, потому что одна или несколько строк слишком длинны
|
@ -13,7 +13,7 @@
|
|||
[package]
|
||||
edition = "2018"
|
||||
name = "ash"
|
||||
version = "0.33.0+1.2.186"
|
||||
version = "0.33.3+1.2.191"
|
||||
authors = ["maik klein <maikklein@googlemail.com>"]
|
||||
description = "Vulkan bindings for Rust"
|
||||
documentation = "https://docs.rs/ash"
|
||||
|
|
|
@ -1638,24 +1638,14 @@ impl Device {
|
|||
&self,
|
||||
pipeline_cache: vk::PipelineCache,
|
||||
) -> VkResult<Vec<u8>> {
|
||||
let mut data_size: usize = 0;
|
||||
self.device_fn_1_0
|
||||
.get_pipeline_cache_data(
|
||||
read_into_uninitialized_vector(|count, data| {
|
||||
self.device_fn_1_0.get_pipeline_cache_data(
|
||||
self.handle(),
|
||||
pipeline_cache,
|
||||
&mut data_size,
|
||||
ptr::null_mut(),
|
||||
count,
|
||||
data as _,
|
||||
)
|
||||
.result()?;
|
||||
let mut data: Vec<u8> = Vec::with_capacity(data_size);
|
||||
let err_code = self.device_fn_1_0.get_pipeline_cache_data(
|
||||
self.handle(),
|
||||
pipeline_cache,
|
||||
&mut data_size,
|
||||
data.as_mut_ptr() as _,
|
||||
);
|
||||
data.set_len(data_size);
|
||||
err_code.result_with_success(data)
|
||||
})
|
||||
}
|
||||
|
||||
#[doc = "<https://www.khronos.org/registry/vulkan/specs/1.2-extensions/man/html/vkMergePipelineCaches.html>"]
|
||||
|
@ -2107,21 +2097,16 @@ impl Device {
|
|||
&self,
|
||||
image: vk::Image,
|
||||
) -> Vec<vk::SparseImageMemoryRequirements> {
|
||||
let mut count = 0;
|
||||
self.device_fn_1_0.get_image_sparse_memory_requirements(
|
||||
self.handle(),
|
||||
image,
|
||||
&mut count,
|
||||
ptr::null_mut(),
|
||||
);
|
||||
let mut data = Vec::with_capacity(count as usize);
|
||||
self.device_fn_1_0.get_image_sparse_memory_requirements(
|
||||
self.handle(),
|
||||
image,
|
||||
&mut count,
|
||||
data.as_mut_ptr(),
|
||||
);
|
||||
data.set_len(count as usize);
|
||||
data
|
||||
read_into_uninitialized_vector(|count, data| {
|
||||
self.device_fn_1_0.get_image_sparse_memory_requirements(
|
||||
self.handle(),
|
||||
image,
|
||||
count,
|
||||
data,
|
||||
);
|
||||
vk::Result::SUCCESS
|
||||
})
|
||||
// The closure always returns SUCCESS
|
||||
.unwrap()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -123,16 +123,10 @@ impl<L> EntryCustom<L> {
|
|||
#[doc = "<https://www.khronos.org/registry/vulkan/specs/1.2-extensions/man/html/vkEnumerateInstanceLayerProperties.html>"]
|
||||
pub fn enumerate_instance_layer_properties(&self) -> VkResult<Vec<vk::LayerProperties>> {
|
||||
unsafe {
|
||||
let mut count = 0;
|
||||
self.entry_fn_1_0
|
||||
.enumerate_instance_layer_properties(&mut count, ptr::null_mut())
|
||||
.result()?;
|
||||
let mut v = Vec::with_capacity(count as usize);
|
||||
let err_code = self
|
||||
.entry_fn_1_0
|
||||
.enumerate_instance_layer_properties(&mut count, v.as_mut_ptr());
|
||||
v.set_len(count as usize);
|
||||
err_code.result_with_success(v)
|
||||
read_into_uninitialized_vector(|count, data| {
|
||||
self.entry_fn_1_0
|
||||
.enumerate_instance_layer_properties(count, data)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -141,18 +135,10 @@ impl<L> EntryCustom<L> {
|
|||
&self,
|
||||
) -> VkResult<Vec<vk::ExtensionProperties>> {
|
||||
unsafe {
|
||||
let mut count = 0;
|
||||
self.entry_fn_1_0
|
||||
.enumerate_instance_extension_properties(ptr::null(), &mut count, ptr::null_mut())
|
||||
.result()?;
|
||||
let mut data = Vec::with_capacity(count as usize);
|
||||
let err_code = self.entry_fn_1_0.enumerate_instance_extension_properties(
|
||||
ptr::null(),
|
||||
&mut count,
|
||||
data.as_mut_ptr(),
|
||||
);
|
||||
data.set_len(count as usize);
|
||||
err_code.result_with_success(data)
|
||||
read_into_uninitialized_vector(|count, data| {
|
||||
self.entry_fn_1_0
|
||||
.enumerate_instance_extension_properties(ptr::null(), count, data)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -3,7 +3,6 @@ use crate::vk;
|
|||
use crate::{Device, Instance};
|
||||
use std::ffi::CStr;
|
||||
use std::mem;
|
||||
use std::ptr;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct FullScreenExclusive {
|
||||
|
@ -42,26 +41,15 @@ impl FullScreenExclusive {
|
|||
physical_device: vk::PhysicalDevice,
|
||||
surface_info: &vk::PhysicalDeviceSurfaceInfo2KHR,
|
||||
) -> VkResult<Vec<vk::PresentModeKHR>> {
|
||||
let mut count = 0;
|
||||
self.full_screen_exclusive_fn
|
||||
.get_physical_device_surface_present_modes2_ext(
|
||||
physical_device,
|
||||
surface_info,
|
||||
&mut count,
|
||||
ptr::null_mut(),
|
||||
)
|
||||
.result()?;
|
||||
let mut present_modes = Vec::<vk::PresentModeKHR>::with_capacity(count as usize);
|
||||
let err_code = self
|
||||
.full_screen_exclusive_fn
|
||||
.get_physical_device_surface_present_modes2_ext(
|
||||
physical_device,
|
||||
surface_info,
|
||||
&mut count,
|
||||
present_modes.as_mut_ptr(),
|
||||
);
|
||||
present_modes.set_len(count as usize);
|
||||
err_code.result_with_success(present_modes)
|
||||
read_into_uninitialized_vector(|count, data| {
|
||||
self.full_screen_exclusive_fn
|
||||
.get_physical_device_surface_present_modes2_ext(
|
||||
physical_device,
|
||||
surface_info,
|
||||
count,
|
||||
data,
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
#[doc = "<https://www.khronos.org/registry/vulkan/specs/1.2-extensions/man/html/vkReleaseFullScreenExclusiveModeEXT.html>"]
|
||||
|
|
|
@ -3,7 +3,6 @@ use crate::vk;
|
|||
use crate::{EntryCustom, Instance};
|
||||
use std::ffi::CStr;
|
||||
use std::mem;
|
||||
use std::ptr;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct ToolingInfo {
|
||||
|
@ -31,16 +30,10 @@ impl ToolingInfo {
|
|||
&self,
|
||||
physical_device: vk::PhysicalDevice,
|
||||
) -> VkResult<Vec<vk::PhysicalDeviceToolPropertiesEXT>> {
|
||||
let mut count = 0;
|
||||
self.tooling_info_fn
|
||||
.get_physical_device_tool_properties_ext(physical_device, &mut count, ptr::null_mut())
|
||||
.result()?;
|
||||
let mut v = Vec::with_capacity(count as usize);
|
||||
let err_code = self
|
||||
.tooling_info_fn
|
||||
.get_physical_device_tool_properties_ext(physical_device, &mut count, v.as_mut_ptr());
|
||||
v.set_len(count as usize);
|
||||
err_code.result_with_success(v)
|
||||
read_into_defaulted_vector(|count, data| {
|
||||
self.tooling_info_fn
|
||||
.get_physical_device_tool_properties_ext(physical_device, count, data)
|
||||
})
|
||||
}
|
||||
|
||||
pub fn fp(&self) -> &vk::ExtToolingInfoFn {
|
||||
|
|
|
@ -4,7 +4,6 @@ use crate::RawPtr;
|
|||
use crate::{EntryCustom, Instance};
|
||||
use std::ffi::CStr;
|
||||
use std::mem;
|
||||
use std::ptr;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct Display {
|
||||
|
@ -32,22 +31,10 @@ impl Display {
|
|||
&self,
|
||||
physical_device: vk::PhysicalDevice,
|
||||
) -> VkResult<Vec<vk::DisplayPropertiesKHR>> {
|
||||
let mut count = 0;
|
||||
self.display_fn
|
||||
.get_physical_device_display_properties_khr(
|
||||
physical_device,
|
||||
&mut count,
|
||||
ptr::null_mut(),
|
||||
)
|
||||
.result()?;
|
||||
let mut v = Vec::with_capacity(count as usize);
|
||||
let err_code = self.display_fn.get_physical_device_display_properties_khr(
|
||||
physical_device,
|
||||
&mut count,
|
||||
v.as_mut_ptr(),
|
||||
);
|
||||
v.set_len(count as usize);
|
||||
err_code.result_with_success(v)
|
||||
read_into_uninitialized_vector(|count, data| {
|
||||
self.display_fn
|
||||
.get_physical_device_display_properties_khr(physical_device, count, data)
|
||||
})
|
||||
}
|
||||
|
||||
#[doc = "<https://www.khronos.org/registry/vulkan/specs/1.2-extensions/man/html/vkGetPhysicalDeviceDisplayPlanePropertiesKHR.html>"]
|
||||
|
@ -55,27 +42,10 @@ impl Display {
|
|||
&self,
|
||||
physical_device: vk::PhysicalDevice,
|
||||
) -> VkResult<Vec<vk::DisplayPlanePropertiesKHR>> {
|
||||
let mut count = 0;
|
||||
let err_code = self
|
||||
.display_fn
|
||||
.get_physical_device_display_plane_properties_khr(
|
||||
physical_device,
|
||||
&mut count,
|
||||
ptr::null_mut(),
|
||||
);
|
||||
if err_code != vk::Result::SUCCESS {
|
||||
return Err(err_code);
|
||||
}
|
||||
let mut v = Vec::with_capacity(count as usize);
|
||||
let err_code = self
|
||||
.display_fn
|
||||
.get_physical_device_display_plane_properties_khr(
|
||||
physical_device,
|
||||
&mut count,
|
||||
v.as_mut_ptr(),
|
||||
);
|
||||
v.set_len(count as usize);
|
||||
err_code.result_with_success(v)
|
||||
read_into_uninitialized_vector(|count, data| {
|
||||
self.display_fn
|
||||
.get_physical_device_display_plane_properties_khr(physical_device, count, data)
|
||||
})
|
||||
}
|
||||
|
||||
#[doc = "<https://www.khronos.org/registry/vulkan/specs/1.2-extensions/man/html/vkGetDisplayPlaneSupportedDisplaysKHR.html>"]
|
||||
|
@ -84,24 +54,14 @@ impl Display {
|
|||
physical_device: vk::PhysicalDevice,
|
||||
plane_index: u32,
|
||||
) -> VkResult<Vec<vk::DisplayKHR>> {
|
||||
let mut count = 0;
|
||||
self.display_fn
|
||||
.get_display_plane_supported_displays_khr(
|
||||
read_into_uninitialized_vector(|count, data| {
|
||||
self.display_fn.get_display_plane_supported_displays_khr(
|
||||
physical_device,
|
||||
plane_index,
|
||||
&mut count,
|
||||
ptr::null_mut(),
|
||||
count,
|
||||
data,
|
||||
)
|
||||
.result()?;
|
||||
let mut v = Vec::with_capacity(count as usize);
|
||||
let err_code = self.display_fn.get_display_plane_supported_displays_khr(
|
||||
physical_device,
|
||||
plane_index,
|
||||
&mut count,
|
||||
v.as_mut_ptr(),
|
||||
);
|
||||
v.set_len(count as usize);
|
||||
err_code.result_with_success(v)
|
||||
})
|
||||
}
|
||||
|
||||
#[doc = "<https://www.khronos.org/registry/vulkan/specs/1.2-extensions/man/html/vkGetDisplayModePropertiesKHR.html>"]
|
||||
|
@ -110,19 +70,10 @@ impl Display {
|
|||
physical_device: vk::PhysicalDevice,
|
||||
display: vk::DisplayKHR,
|
||||
) -> VkResult<Vec<vk::DisplayModePropertiesKHR>> {
|
||||
let mut count = 0;
|
||||
self.display_fn
|
||||
.get_display_mode_properties_khr(physical_device, display, &mut count, ptr::null_mut())
|
||||
.result()?;
|
||||
let mut v = Vec::with_capacity(count as usize);
|
||||
let err_code = self.display_fn.get_display_mode_properties_khr(
|
||||
physical_device,
|
||||
display,
|
||||
&mut count,
|
||||
v.as_mut_ptr(),
|
||||
);
|
||||
v.set_len(count as usize);
|
||||
err_code.result_with_success(v)
|
||||
read_into_uninitialized_vector(|count, data| {
|
||||
self.display_fn
|
||||
.get_display_mode_properties_khr(physical_device, display, count, data)
|
||||
})
|
||||
}
|
||||
|
||||
#[doc = "<https://www.khronos.org/registry/vulkan/specs/1.2-extensions/man/html/vkCreateDisplayModeKHR.html>"]
|
||||
|
|
|
@ -3,7 +3,6 @@ use crate::vk;
|
|||
use crate::{EntryCustom, Instance};
|
||||
use std::ffi::CStr;
|
||||
use std::mem;
|
||||
use std::ptr;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct PipelineExecutableProperties {
|
||||
|
@ -33,27 +32,15 @@ impl PipelineExecutableProperties {
|
|||
device: vk::Device,
|
||||
executable_info: &vk::PipelineExecutableInfoKHR,
|
||||
) -> VkResult<Vec<vk::PipelineExecutableInternalRepresentationKHR>> {
|
||||
let mut count = 0;
|
||||
let err_code = self
|
||||
.pipeline_executable_properties_fn
|
||||
.get_pipeline_executable_internal_representations_khr(
|
||||
device,
|
||||
executable_info,
|
||||
&mut count,
|
||||
ptr::null_mut(),
|
||||
);
|
||||
if err_code != vk::Result::SUCCESS {
|
||||
return Err(err_code);
|
||||
}
|
||||
let mut v: Vec<_> = vec![Default::default(); count as usize];
|
||||
self.pipeline_executable_properties_fn
|
||||
.get_pipeline_executable_internal_representations_khr(
|
||||
device,
|
||||
executable_info,
|
||||
&mut count,
|
||||
v.as_mut_ptr(),
|
||||
)
|
||||
.result_with_success(v)
|
||||
read_into_defaulted_vector(|count, data| {
|
||||
self.pipeline_executable_properties_fn
|
||||
.get_pipeline_executable_internal_representations_khr(
|
||||
device,
|
||||
executable_info,
|
||||
count,
|
||||
data,
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
#[doc = "<https://www.khronos.org/registry/vulkan/specs/1.2-extensions/man/html/vkGetPipelineExecutablePropertiesKHR.html>"]
|
||||
|
@ -62,27 +49,10 @@ impl PipelineExecutableProperties {
|
|||
device: vk::Device,
|
||||
pipeline_info: &vk::PipelineInfoKHR,
|
||||
) -> VkResult<Vec<vk::PipelineExecutablePropertiesKHR>> {
|
||||
let mut count = 0;
|
||||
let err_code = self
|
||||
.pipeline_executable_properties_fn
|
||||
.get_pipeline_executable_properties_khr(
|
||||
device,
|
||||
pipeline_info,
|
||||
&mut count,
|
||||
ptr::null_mut(),
|
||||
);
|
||||
if err_code != vk::Result::SUCCESS {
|
||||
return Err(err_code);
|
||||
}
|
||||
let mut v: Vec<_> = vec![Default::default(); count as usize];
|
||||
self.pipeline_executable_properties_fn
|
||||
.get_pipeline_executable_properties_khr(
|
||||
device,
|
||||
pipeline_info,
|
||||
&mut count,
|
||||
v.as_mut_ptr(),
|
||||
)
|
||||
.result_with_success(v)
|
||||
read_into_defaulted_vector(|count, data| {
|
||||
self.pipeline_executable_properties_fn
|
||||
.get_pipeline_executable_properties_khr(device, pipeline_info, count, data)
|
||||
})
|
||||
}
|
||||
|
||||
#[doc = "<https://www.khronos.org/registry/vulkan/specs/1.2-extensions/man/html/vkGetPipelineExecutableStatisticsKHR.html>"]
|
||||
|
@ -91,27 +61,10 @@ impl PipelineExecutableProperties {
|
|||
device: vk::Device,
|
||||
executable_info: &vk::PipelineExecutableInfoKHR,
|
||||
) -> VkResult<Vec<vk::PipelineExecutableStatisticKHR>> {
|
||||
let mut count = 0;
|
||||
let err_code = self
|
||||
.pipeline_executable_properties_fn
|
||||
.get_pipeline_executable_statistics_khr(
|
||||
device,
|
||||
executable_info,
|
||||
&mut count,
|
||||
ptr::null_mut(),
|
||||
);
|
||||
if err_code != vk::Result::SUCCESS {
|
||||
return Err(err_code);
|
||||
}
|
||||
let mut v: Vec<_> = vec![Default::default(); count as usize];
|
||||
self.pipeline_executable_properties_fn
|
||||
.get_pipeline_executable_statistics_khr(
|
||||
device,
|
||||
executable_info,
|
||||
&mut count,
|
||||
v.as_mut_ptr(),
|
||||
)
|
||||
.result_with_success(v)
|
||||
read_into_defaulted_vector(|count, data| {
|
||||
self.pipeline_executable_properties_fn
|
||||
.get_pipeline_executable_statistics_khr(device, executable_info, count, data)
|
||||
})
|
||||
}
|
||||
|
||||
pub fn fp(&self) -> &vk::KhrPipelineExecutablePropertiesFn {
|
||||
|
|
|
@ -4,7 +4,6 @@ use crate::RawPtr;
|
|||
use crate::{EntryCustom, Instance};
|
||||
use std::ffi::CStr;
|
||||
use std::mem;
|
||||
use std::ptr;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct Surface {
|
||||
|
@ -51,26 +50,15 @@ impl Surface {
|
|||
physical_device: vk::PhysicalDevice,
|
||||
surface: vk::SurfaceKHR,
|
||||
) -> VkResult<Vec<vk::PresentModeKHR>> {
|
||||
let mut count = 0;
|
||||
self.surface_fn
|
||||
.get_physical_device_surface_present_modes_khr(
|
||||
physical_device,
|
||||
surface,
|
||||
&mut count,
|
||||
ptr::null_mut(),
|
||||
)
|
||||
.result()?;
|
||||
let mut v = Vec::with_capacity(count as usize);
|
||||
let err_code = self
|
||||
.surface_fn
|
||||
.get_physical_device_surface_present_modes_khr(
|
||||
physical_device,
|
||||
surface,
|
||||
&mut count,
|
||||
v.as_mut_ptr(),
|
||||
);
|
||||
v.set_len(count as usize);
|
||||
err_code.result_with_success(v)
|
||||
read_into_uninitialized_vector(|count, data| {
|
||||
self.surface_fn
|
||||
.get_physical_device_surface_present_modes_khr(
|
||||
physical_device,
|
||||
surface,
|
||||
count,
|
||||
data,
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
#[doc = "<https://www.khronos.org/registry/vulkan/specs/1.2-extensions/man/html/vkGetPhysicalDeviceSurfaceCapabilitiesKHR.html>"]
|
||||
|
@ -95,24 +83,14 @@ impl Surface {
|
|||
physical_device: vk::PhysicalDevice,
|
||||
surface: vk::SurfaceKHR,
|
||||
) -> VkResult<Vec<vk::SurfaceFormatKHR>> {
|
||||
let mut count = 0;
|
||||
self.surface_fn
|
||||
.get_physical_device_surface_formats_khr(
|
||||
read_into_uninitialized_vector(|count, data| {
|
||||
self.surface_fn.get_physical_device_surface_formats_khr(
|
||||
physical_device,
|
||||
surface,
|
||||
&mut count,
|
||||
ptr::null_mut(),
|
||||
count,
|
||||
data,
|
||||
)
|
||||
.result()?;
|
||||
let mut v = Vec::with_capacity(count as usize);
|
||||
let err_code = self.surface_fn.get_physical_device_surface_formats_khr(
|
||||
physical_device,
|
||||
surface,
|
||||
&mut count,
|
||||
v.as_mut_ptr(),
|
||||
);
|
||||
v.set_len(count as usize);
|
||||
err_code.result_with_success(v)
|
||||
})
|
||||
}
|
||||
|
||||
#[doc = "<https://www.khronos.org/registry/vulkan/specs/1.2-extensions/man/html/vkDestroySurfaceKHR.html>"]
|
||||
|
|
|
@ -4,7 +4,6 @@ use crate::RawPtr;
|
|||
use crate::{Device, Instance};
|
||||
use std::ffi::CStr;
|
||||
use std::mem;
|
||||
use std::ptr;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct Swapchain {
|
||||
|
@ -102,20 +101,10 @@ impl Swapchain {
|
|||
&self,
|
||||
swapchain: vk::SwapchainKHR,
|
||||
) -> VkResult<Vec<vk::Image>> {
|
||||
let mut count = 0;
|
||||
self.swapchain_fn
|
||||
.get_swapchain_images_khr(self.handle, swapchain, &mut count, ptr::null_mut())
|
||||
.result()?;
|
||||
|
||||
let mut v = Vec::with_capacity(count as usize);
|
||||
let err_code = self.swapchain_fn.get_swapchain_images_khr(
|
||||
self.handle,
|
||||
swapchain,
|
||||
&mut count,
|
||||
v.as_mut_ptr(),
|
||||
);
|
||||
v.set_len(count as usize);
|
||||
err_code.result_with_success(v)
|
||||
read_into_uninitialized_vector(|count, data| {
|
||||
self.swapchain_fn
|
||||
.get_swapchain_images_khr(self.handle, swapchain, count, data)
|
||||
})
|
||||
}
|
||||
|
||||
pub fn fp(&self) -> &vk::KhrSwapchainFn {
|
||||
|
|
|
@ -348,22 +348,13 @@ impl Instance {
|
|||
&self,
|
||||
physical_device: vk::PhysicalDevice,
|
||||
) -> Vec<vk::QueueFamilyProperties> {
|
||||
let mut queue_count = 0;
|
||||
self.instance_fn_1_0
|
||||
.get_physical_device_queue_family_properties(
|
||||
physical_device,
|
||||
&mut queue_count,
|
||||
ptr::null_mut(),
|
||||
);
|
||||
let mut queue_families_vec = Vec::with_capacity(queue_count as usize);
|
||||
self.instance_fn_1_0
|
||||
.get_physical_device_queue_family_properties(
|
||||
physical_device,
|
||||
&mut queue_count,
|
||||
queue_families_vec.as_mut_ptr(),
|
||||
);
|
||||
queue_families_vec.set_len(queue_count as usize);
|
||||
queue_families_vec
|
||||
read_into_uninitialized_vector(|count, data| {
|
||||
self.instance_fn_1_0
|
||||
.get_physical_device_queue_family_properties(physical_device, count, data);
|
||||
vk::Result::SUCCESS
|
||||
})
|
||||
// The closure always returns SUCCESS
|
||||
.unwrap()
|
||||
}
|
||||
|
||||
#[doc = "<https://www.khronos.org/registry/vulkan/specs/1.2-extensions/man/html/vkGetPhysicalDeviceFeatures.html>"]
|
||||
|
@ -379,18 +370,10 @@ impl Instance {
|
|||
|
||||
#[doc = "<https://www.khronos.org/registry/vulkan/specs/1.2-extensions/man/html/vkEnumeratePhysicalDevices.html>"]
|
||||
pub unsafe fn enumerate_physical_devices(&self) -> VkResult<Vec<vk::PhysicalDevice>> {
|
||||
let mut count = 0;
|
||||
self.instance_fn_1_0
|
||||
.enumerate_physical_devices(self.handle(), &mut count, ptr::null_mut())
|
||||
.result()?;
|
||||
let mut physical_devices = Vec::<vk::PhysicalDevice>::with_capacity(count as usize);
|
||||
let err_code = self.instance_fn_1_0.enumerate_physical_devices(
|
||||
self.handle(),
|
||||
&mut count,
|
||||
physical_devices.as_mut_ptr(),
|
||||
);
|
||||
physical_devices.set_len(count as usize);
|
||||
err_code.result_with_success(physical_devices)
|
||||
read_into_uninitialized_vector(|count, data| {
|
||||
self.instance_fn_1_0
|
||||
.enumerate_physical_devices(self.handle(), count, data)
|
||||
})
|
||||
}
|
||||
|
||||
#[doc = "<https://www.khronos.org/registry/vulkan/specs/1.2-extensions/man/html/vkEnumerateDeviceExtensionProperties.html>"]
|
||||
|
@ -398,19 +381,14 @@ impl Instance {
|
|||
&self,
|
||||
device: vk::PhysicalDevice,
|
||||
) -> VkResult<Vec<vk::ExtensionProperties>> {
|
||||
let mut count = 0;
|
||||
self.instance_fn_1_0
|
||||
.enumerate_device_extension_properties(device, ptr::null(), &mut count, ptr::null_mut())
|
||||
.result()?;
|
||||
let mut data = Vec::with_capacity(count as usize);
|
||||
let err_code = self.instance_fn_1_0.enumerate_device_extension_properties(
|
||||
device,
|
||||
ptr::null(),
|
||||
&mut count,
|
||||
data.as_mut_ptr(),
|
||||
);
|
||||
data.set_len(count as usize);
|
||||
err_code.result_with_success(data)
|
||||
read_into_uninitialized_vector(|count, data| {
|
||||
self.instance_fn_1_0.enumerate_device_extension_properties(
|
||||
device,
|
||||
ptr::null(),
|
||||
count,
|
||||
data,
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
#[doc = "<https://www.khronos.org/registry/vulkan/specs/1.2-extensions/man/html/vkEnumerateDeviceLayerProperties.html>"]
|
||||
|
@ -418,18 +396,10 @@ impl Instance {
|
|||
&self,
|
||||
device: vk::PhysicalDevice,
|
||||
) -> VkResult<Vec<vk::LayerProperties>> {
|
||||
let mut count = 0;
|
||||
self.instance_fn_1_0
|
||||
.enumerate_device_layer_properties(device, &mut count, ptr::null_mut())
|
||||
.result()?;
|
||||
let mut data = Vec::with_capacity(count as usize);
|
||||
let err_code = self.instance_fn_1_0.enumerate_device_layer_properties(
|
||||
device,
|
||||
&mut count,
|
||||
data.as_mut_ptr(),
|
||||
);
|
||||
data.set_len(count as usize);
|
||||
err_code.result_with_success(data)
|
||||
read_into_uninitialized_vector(|count, data| {
|
||||
self.instance_fn_1_0
|
||||
.enumerate_device_layer_properties(device, count, data)
|
||||
})
|
||||
}
|
||||
|
||||
#[doc = "<https://www.khronos.org/registry/vulkan/specs/1.2-extensions/man/html/vkGetPhysicalDeviceSparseImageFormatProperties.html>"]
|
||||
|
@ -442,31 +412,21 @@ impl Instance {
|
|||
usage: vk::ImageUsageFlags,
|
||||
tiling: vk::ImageTiling,
|
||||
) -> Vec<vk::SparseImageFormatProperties> {
|
||||
let mut count = 0;
|
||||
self.instance_fn_1_0
|
||||
.get_physical_device_sparse_image_format_properties(
|
||||
physical_device,
|
||||
format,
|
||||
typ,
|
||||
samples,
|
||||
usage,
|
||||
tiling,
|
||||
&mut count,
|
||||
ptr::null_mut(),
|
||||
);
|
||||
let mut data = Vec::with_capacity(count as usize);
|
||||
self.instance_fn_1_0
|
||||
.get_physical_device_sparse_image_format_properties(
|
||||
physical_device,
|
||||
format,
|
||||
typ,
|
||||
samples,
|
||||
usage,
|
||||
tiling,
|
||||
&mut count,
|
||||
data.as_mut_ptr(),
|
||||
);
|
||||
data.set_len(count as usize);
|
||||
data
|
||||
read_into_uninitialized_vector(|count, data| {
|
||||
self.instance_fn_1_0
|
||||
.get_physical_device_sparse_image_format_properties(
|
||||
physical_device,
|
||||
format,
|
||||
typ,
|
||||
samples,
|
||||
usage,
|
||||
tiling,
|
||||
count,
|
||||
data,
|
||||
);
|
||||
vk::Result::SUCCESS
|
||||
})
|
||||
// The closure always returns SUCCESS
|
||||
.unwrap()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
use std::convert::TryInto;
|
||||
|
||||
use crate::vk;
|
||||
pub type VkResult<T> = Result<T, vk::Result>;
|
||||
|
||||
|
@ -19,3 +21,69 @@ impl vk::Result {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Repeatedly calls `f` until it does not return [`vk::Result::INCOMPLETE`] anymore,
|
||||
/// ensuring all available data has been read into the vector.
|
||||
///
|
||||
/// See for example [`vkEnumerateInstanceExtensionProperties`]: the number of available
|
||||
/// items may change between calls; [`vk::Result::INCOMPLETE`] is returned when the count
|
||||
/// increased (and the vector is not large enough after querying the initial size),
|
||||
/// requiring Ash to try again.
|
||||
///
|
||||
/// [`vkEnumerateInstanceExtensionProperties`]: https://www.khronos.org/registry/vulkan/specs/1.2-extensions/man/html/vkEnumerateInstanceExtensionProperties.html
|
||||
pub(crate) unsafe fn read_into_uninitialized_vector<N: Copy + Default + TryInto<usize>, T>(
|
||||
f: impl Fn(&mut N, *mut T) -> vk::Result,
|
||||
) -> VkResult<Vec<T>>
|
||||
where
|
||||
<N as TryInto<usize>>::Error: std::fmt::Debug,
|
||||
{
|
||||
loop {
|
||||
let mut count = N::default();
|
||||
f(&mut count, std::ptr::null_mut()).result()?;
|
||||
let mut data =
|
||||
Vec::with_capacity(count.try_into().expect("`N` failed to convert to `usize`"));
|
||||
|
||||
let err_code = f(&mut count, data.as_mut_ptr());
|
||||
if err_code != vk::Result::INCOMPLETE {
|
||||
data.set_len(count.try_into().expect("`N` failed to convert to `usize`"));
|
||||
break err_code.result_with_success(data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Repeatedly calls `f` until it does not return [`vk::Result::INCOMPLETE`] anymore,
|
||||
/// ensuring all available data has been read into the vector.
|
||||
///
|
||||
/// Items in the target vector are [`default()`][`Default::default()`]-initialized which
|
||||
/// is required for [`vk::BaseOutStructure`]-like structs where [`vk::BaseOutStructure::s_type`]
|
||||
/// needs to be a valid type and [`vk::BaseOutStructure::p_next`] a valid or
|
||||
/// [`null`][`std::ptr::null_mut()`] pointer.
|
||||
///
|
||||
/// See for example [`vkEnumerateInstanceExtensionProperties`]: the number of available
|
||||
/// items may change between calls; [`vk::Result::INCOMPLETE`] is returned when the count
|
||||
/// increased (and the vector is not large enough after querying the initial size),
|
||||
/// requiring Ash to try again.
|
||||
///
|
||||
/// [`vkEnumerateInstanceExtensionProperties`]: https://www.khronos.org/registry/vulkan/specs/1.2-extensions/man/html/vkEnumerateInstanceExtensionProperties.html
|
||||
pub(crate) unsafe fn read_into_defaulted_vector<
|
||||
N: Copy + Default + TryInto<usize>,
|
||||
T: Default + Clone,
|
||||
>(
|
||||
f: impl Fn(&mut N, *mut T) -> vk::Result,
|
||||
) -> VkResult<Vec<T>>
|
||||
where
|
||||
<N as TryInto<usize>>::Error: std::fmt::Debug,
|
||||
{
|
||||
loop {
|
||||
let mut count = N::default();
|
||||
f(&mut count, std::ptr::null_mut()).result()?;
|
||||
let mut data =
|
||||
vec![Default::default(); count.try_into().expect("`N` failed to convert to `usize`")];
|
||||
|
||||
let err_code = f(&mut count, data.as_mut_ptr());
|
||||
if err_code != vk::Result::INCOMPLETE {
|
||||
data.set_len(count.try_into().expect("`N` failed to convert to `usize`"));
|
||||
break err_code.result_with_success(data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -113,15 +113,12 @@ pub fn read_spv<R: io::Read + io::Seek>(x: &mut R) -> io::Result<Vec<u32>> {
|
|||
return Err(io::Error::new(io::ErrorKind::InvalidData, "input too long"));
|
||||
}
|
||||
let words = (size / 4) as usize;
|
||||
let mut result = Vec::<u32>::with_capacity(words);
|
||||
// https://github.com/MaikKlein/ash/issues/354:
|
||||
// Zero-initialize the result to prevent read_exact from possibly
|
||||
// reading uninitialized memory.
|
||||
let mut result = vec![0u32; words];
|
||||
x.seek(io::SeekFrom::Start(0))?;
|
||||
unsafe {
|
||||
x.read_exact(slice::from_raw_parts_mut(
|
||||
result.as_mut_ptr() as *mut u8,
|
||||
words * 4,
|
||||
))?;
|
||||
result.set_len(words);
|
||||
}
|
||||
x.read_exact(unsafe { slice::from_raw_parts_mut(result.as_mut_ptr() as *mut u8, words * 4) })?;
|
||||
const MAGIC_NUMBER: u32 = 0x0723_0203;
|
||||
if !result.is_empty() && result[0] == MAGIC_NUMBER.swap_bytes() {
|
||||
for word in &mut result {
|
||||
|
|
|
@ -256,6 +256,12 @@ impl FenceCreateFlags {
|
|||
}
|
||||
#[repr(transparent)]
|
||||
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||
#[doc = "<https://www.khronos.org/registry/vulkan/specs/1.2-extensions/man/html/VkSemaphoreCreateFlagBits.html>"]
|
||||
pub struct SemaphoreCreateFlags(pub(crate) Flags);
|
||||
vk_bitflags_wrapped!(SemaphoreCreateFlags, 0b0, Flags);
|
||||
impl SemaphoreCreateFlags {}
|
||||
#[repr(transparent)]
|
||||
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||
#[doc = "<https://www.khronos.org/registry/vulkan/specs/1.2-extensions/man/html/VkFormatFeatureFlagBits.html>"]
|
||||
pub struct FormatFeatureFlags(pub(crate) Flags);
|
||||
vk_bitflags_wrapped!(FormatFeatureFlags, 0b1_1111_1111_1111, Flags);
|
||||
|
@ -857,9 +863,10 @@ pub struct GeometryInstanceFlagsKHR(pub(crate) Flags);
|
|||
vk_bitflags_wrapped!(GeometryInstanceFlagsKHR, 0b1111, Flags);
|
||||
impl GeometryInstanceFlagsKHR {
|
||||
pub const TRIANGLE_FACING_CULL_DISABLE: Self = Self(0b1);
|
||||
pub const TRIANGLE_FRONT_COUNTERCLOCKWISE: Self = Self(0b10);
|
||||
pub const TRIANGLE_FLIP_FACING: Self = Self(0b10);
|
||||
pub const FORCE_OPAQUE: Self = Self(0b100);
|
||||
pub const FORCE_NO_OPAQUE: Self = Self(0b1000);
|
||||
pub const TRIANGLE_FRONT_COUNTERCLOCKWISE: Self = Self::TRIANGLE_FLIP_FACING;
|
||||
}
|
||||
#[repr(transparent)]
|
||||
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||
|
@ -1085,10 +1092,10 @@ impl VideoComponentBitDepthFlagsKHR {
|
|||
}
|
||||
#[repr(transparent)]
|
||||
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||
#[doc = "<https://www.khronos.org/registry/vulkan/specs/1.2-extensions/man/html/VkVideoCapabilitiesFlagBitsKHR.html>"]
|
||||
pub struct VideoCapabilitiesFlagsKHR(pub(crate) Flags);
|
||||
vk_bitflags_wrapped!(VideoCapabilitiesFlagsKHR, 0b11, Flags);
|
||||
impl VideoCapabilitiesFlagsKHR {
|
||||
#[doc = "<https://www.khronos.org/registry/vulkan/specs/1.2-extensions/man/html/VkVideoCapabilityFlagBitsKHR.html>"]
|
||||
pub struct VideoCapabilityFlagsKHR(pub(crate) Flags);
|
||||
vk_bitflags_wrapped!(VideoCapabilityFlagsKHR, 0b11, Flags);
|
||||
impl VideoCapabilityFlagsKHR {
|
||||
pub const PROTECTED_CONTENT: Self = Self(0b1);
|
||||
pub const SEPARATE_REFERENCE_IMAGES: Self = Self(0b10);
|
||||
}
|
||||
|
@ -1107,20 +1114,19 @@ impl VideoSessionCreateFlagsKHR {
|
|||
pub struct VideoCodingQualityPresetFlagsKHR(pub(crate) Flags);
|
||||
vk_bitflags_wrapped!(VideoCodingQualityPresetFlagsKHR, 0b111, Flags);
|
||||
impl VideoCodingQualityPresetFlagsKHR {
|
||||
pub const DEFAULT: Self = Self(0);
|
||||
pub const NORMAL: Self = Self(0b1);
|
||||
pub const POWER: Self = Self(0b10);
|
||||
pub const QUALITY: Self = Self(0b100);
|
||||
}
|
||||
#[repr(transparent)]
|
||||
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||
#[doc = "<https://www.khronos.org/registry/vulkan/specs/1.2-extensions/man/html/VkVideoDecodeH264FieldLayoutFlagBitsEXT.html>"]
|
||||
pub struct VideoDecodeH264FieldLayoutFlagsEXT(pub(crate) Flags);
|
||||
vk_bitflags_wrapped!(VideoDecodeH264FieldLayoutFlagsEXT, 0b11, Flags);
|
||||
impl VideoDecodeH264FieldLayoutFlagsEXT {
|
||||
pub const PROGRESSIVE_PICTURES_ONLY: Self = Self(0);
|
||||
pub const LINE_INTERLACED_PLANE: Self = Self(0b1);
|
||||
pub const SEPARATE_INTERLACED_PLANE: Self = Self(0b10);
|
||||
#[doc = "<https://www.khronos.org/registry/vulkan/specs/1.2-extensions/man/html/VkVideoDecodeH264PictureLayoutFlagBitsEXT.html>"]
|
||||
pub struct VideoDecodeH264PictureLayoutFlagsEXT(pub(crate) Flags);
|
||||
vk_bitflags_wrapped!(VideoDecodeH264PictureLayoutFlagsEXT, 0b11, Flags);
|
||||
impl VideoDecodeH264PictureLayoutFlagsEXT {
|
||||
pub const PROGRESSIVE: Self = Self(0);
|
||||
pub const INTERLACED_INTERLEAVED_LINES: Self = Self(0b1);
|
||||
pub const INTERLACED_SEPARATE_PLANES: Self = Self(0b10);
|
||||
}
|
||||
#[repr(transparent)]
|
||||
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||
|
@ -1170,10 +1176,10 @@ impl VideoEncodeRateControlModeFlagsKHR {
|
|||
}
|
||||
#[repr(transparent)]
|
||||
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||
#[doc = "<https://www.khronos.org/registry/vulkan/specs/1.2-extensions/man/html/VkVideoEncodeH264CapabilitiesFlagBitsEXT.html>"]
|
||||
pub struct VideoEncodeH264CapabilitiesFlagsEXT(pub(crate) Flags);
|
||||
vk_bitflags_wrapped!(VideoEncodeH264CapabilitiesFlagsEXT, 0b111_1111_1111, Flags);
|
||||
impl VideoEncodeH264CapabilitiesFlagsEXT {
|
||||
#[doc = "<https://www.khronos.org/registry/vulkan/specs/1.2-extensions/man/html/VkVideoEncodeH264CapabilityFlagBitsEXT.html>"]
|
||||
pub struct VideoEncodeH264CapabilityFlagsEXT(pub(crate) Flags);
|
||||
vk_bitflags_wrapped!(VideoEncodeH264CapabilityFlagsEXT, 0b111_1111_1111, Flags);
|
||||
impl VideoEncodeH264CapabilityFlagsEXT {
|
||||
pub const CABAC: Self = Self(0b1);
|
||||
pub const CAVLC: Self = Self(0b10);
|
||||
pub const WEIGHTED_BI_PRED_IMPLICIT: Self = Self(0b100);
|
||||
|
|
|
@ -353,6 +353,7 @@ impl fmt::Debug for AttachmentLoadOp {
|
|||
Self::LOAD => Some("LOAD"),
|
||||
Self::CLEAR => Some("CLEAR"),
|
||||
Self::DONT_CARE => Some("DONT_CARE"),
|
||||
Self::NONE_EXT => Some("NONE_EXT"),
|
||||
_ => None,
|
||||
};
|
||||
if let Some(x) = name {
|
||||
|
@ -367,7 +368,7 @@ impl fmt::Debug for AttachmentStoreOp {
|
|||
let name = match *self {
|
||||
Self::STORE => Some("STORE"),
|
||||
Self::DONT_CARE => Some("DONT_CARE"),
|
||||
Self::NONE_QCOM => Some("NONE_QCOM"),
|
||||
Self::NONE_EXT => Some("NONE_EXT"),
|
||||
_ => None,
|
||||
};
|
||||
if let Some(x) = name {
|
||||
|
@ -1324,6 +1325,7 @@ impl fmt::Debug for DriverId {
|
|||
Self::MOLTENVK => Some("MOLTENVK"),
|
||||
Self::COREAVI_PROPRIETARY => Some("COREAVI_PROPRIETARY"),
|
||||
Self::JUICE_PROPRIETARY => Some("JUICE_PROPRIETARY"),
|
||||
Self::VERISILICON_PROPRIETARY => Some("VERISILICON_PROPRIETARY"),
|
||||
_ => None,
|
||||
};
|
||||
if let Some(x) = name {
|
||||
|
@ -2031,8 +2033,8 @@ impl fmt::Debug for GeometryInstanceFlagsKHR {
|
|||
"TRIANGLE_FACING_CULL_DISABLE",
|
||||
),
|
||||
(
|
||||
GeometryInstanceFlagsKHR::TRIANGLE_FRONT_COUNTERCLOCKWISE.0,
|
||||
"TRIANGLE_FRONT_COUNTERCLOCKWISE",
|
||||
GeometryInstanceFlagsKHR::TRIANGLE_FLIP_FACING.0,
|
||||
"TRIANGLE_FLIP_FACING",
|
||||
),
|
||||
(GeometryInstanceFlagsKHR::FORCE_OPAQUE.0, "FORCE_OPAQUE"),
|
||||
(
|
||||
|
@ -3572,6 +3574,7 @@ impl fmt::Debug for SamplerCreateFlags {
|
|||
SamplerCreateFlags::SUBSAMPLED_COARSE_RECONSTRUCTION_EXT.0,
|
||||
"SUBSAMPLED_COARSE_RECONSTRUCTION_EXT",
|
||||
),
|
||||
(SamplerCreateFlags::RESERVED_2_EXT.0, "RESERVED_2_EXT"),
|
||||
];
|
||||
debug_flags(f, KNOWN, self.0)
|
||||
}
|
||||
|
@ -4684,6 +4687,12 @@ impl fmt::Debug for StructureType {
|
|||
Self::COMMAND_BUFFER_INHERITANCE_VIEWPORT_SCISSOR_INFO_NV => {
|
||||
Some("COMMAND_BUFFER_INHERITANCE_VIEWPORT_SCISSOR_INFO_NV")
|
||||
}
|
||||
Self::PHYSICAL_DEVICE_SHADER_INTEGER_DOT_PRODUCT_FEATURES_KHR => {
|
||||
Some("PHYSICAL_DEVICE_SHADER_INTEGER_DOT_PRODUCT_FEATURES_KHR")
|
||||
}
|
||||
Self::PHYSICAL_DEVICE_SHADER_INTEGER_DOT_PRODUCT_PROPERTIES_KHR => {
|
||||
Some("PHYSICAL_DEVICE_SHADER_INTEGER_DOT_PRODUCT_PROPERTIES_KHR")
|
||||
}
|
||||
Self::PHYSICAL_DEVICE_TEXEL_BUFFER_ALIGNMENT_FEATURES_EXT => {
|
||||
Some("PHYSICAL_DEVICE_TEXEL_BUFFER_ALIGNMENT_FEATURES_EXT")
|
||||
}
|
||||
|
@ -4829,6 +4838,9 @@ impl fmt::Debug for StructureType {
|
|||
Some("VERTEX_INPUT_ATTRIBUTE_DESCRIPTION_2_EXT")
|
||||
}
|
||||
Self::PHYSICAL_DEVICE_DRM_PROPERTIES_EXT => Some("PHYSICAL_DEVICE_DRM_PROPERTIES_EXT"),
|
||||
Self::PHYSICAL_DEVICE_PRIMITIVE_TOPOLOGY_LIST_RESTART_FEATURES_EXT => {
|
||||
Some("PHYSICAL_DEVICE_PRIMITIVE_TOPOLOGY_LIST_RESTART_FEATURES_EXT")
|
||||
}
|
||||
Self::IMPORT_MEMORY_ZIRCON_HANDLE_INFO_FUCHSIA => {
|
||||
Some("IMPORT_MEMORY_ZIRCON_HANDLE_INFO_FUCHSIA")
|
||||
}
|
||||
|
@ -4882,6 +4894,9 @@ impl fmt::Debug for StructureType {
|
|||
Self::PHYSICAL_DEVICE_MULTI_DRAW_PROPERTIES_EXT => {
|
||||
Some("PHYSICAL_DEVICE_MULTI_DRAW_PROPERTIES_EXT")
|
||||
}
|
||||
Self::PHYSICAL_DEVICE_PAGEABLE_DEVICE_LOCAL_MEMORY_FEATURES_EXT => {
|
||||
Some("PHYSICAL_DEVICE_PAGEABLE_DEVICE_LOCAL_MEMORY_FEATURES_EXT")
|
||||
}
|
||||
Self::PHYSICAL_DEVICE_SUBGROUP_PROPERTIES => {
|
||||
Some("PHYSICAL_DEVICE_SUBGROUP_PROPERTIES")
|
||||
}
|
||||
|
@ -5419,15 +5434,15 @@ impl fmt::Debug for VideoBeginCodingFlagsKHR {
|
|||
debug_flags(f, KNOWN, self.0)
|
||||
}
|
||||
}
|
||||
impl fmt::Debug for VideoCapabilitiesFlagsKHR {
|
||||
impl fmt::Debug for VideoCapabilityFlagsKHR {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
const KNOWN: &[(Flags, &str)] = &[
|
||||
(
|
||||
VideoCapabilitiesFlagsKHR::PROTECTED_CONTENT.0,
|
||||
VideoCapabilityFlagsKHR::PROTECTED_CONTENT.0,
|
||||
"PROTECTED_CONTENT",
|
||||
),
|
||||
(
|
||||
VideoCapabilitiesFlagsKHR::SEPARATE_REFERENCE_IMAGES.0,
|
||||
VideoCapabilityFlagsKHR::SEPARATE_REFERENCE_IMAGES.0,
|
||||
"SEPARATE_REFERENCE_IMAGES",
|
||||
),
|
||||
];
|
||||
|
@ -5478,7 +5493,6 @@ impl fmt::Debug for VideoCodingControlFlagsKHR {
|
|||
impl fmt::Debug for VideoCodingQualityPresetFlagsKHR {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
const KNOWN: &[(Flags, &str)] = &[
|
||||
(VideoCodingQualityPresetFlagsKHR::DEFAULT.0, "DEFAULT"),
|
||||
(VideoCodingQualityPresetFlagsKHR::NORMAL.0, "NORMAL"),
|
||||
(VideoCodingQualityPresetFlagsKHR::POWER.0, "POWER"),
|
||||
(VideoCodingQualityPresetFlagsKHR::QUALITY.0, "QUALITY"),
|
||||
|
@ -5512,20 +5526,20 @@ impl fmt::Debug for VideoDecodeH264CreateFlagsEXT {
|
|||
debug_flags(f, KNOWN, self.0)
|
||||
}
|
||||
}
|
||||
impl fmt::Debug for VideoDecodeH264FieldLayoutFlagsEXT {
|
||||
impl fmt::Debug for VideoDecodeH264PictureLayoutFlagsEXT {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
const KNOWN: &[(Flags, &str)] = &[
|
||||
(
|
||||
VideoDecodeH264FieldLayoutFlagsEXT::PROGRESSIVE_PICTURES_ONLY.0,
|
||||
"PROGRESSIVE_PICTURES_ONLY",
|
||||
VideoDecodeH264PictureLayoutFlagsEXT::PROGRESSIVE.0,
|
||||
"PROGRESSIVE",
|
||||
),
|
||||
(
|
||||
VideoDecodeH264FieldLayoutFlagsEXT::LINE_INTERLACED_PLANE.0,
|
||||
"LINE_INTERLACED_PLANE",
|
||||
VideoDecodeH264PictureLayoutFlagsEXT::INTERLACED_INTERLEAVED_LINES.0,
|
||||
"INTERLACED_INTERLEAVED_LINES",
|
||||
),
|
||||
(
|
||||
VideoDecodeH264FieldLayoutFlagsEXT::SEPARATE_INTERLACED_PLANE.0,
|
||||
"SEPARATE_INTERLACED_PLANE",
|
||||
VideoDecodeH264PictureLayoutFlagsEXT::INTERLACED_SEPARATE_PLANES.0,
|
||||
"INTERLACED_SEPARATE_PLANES",
|
||||
),
|
||||
];
|
||||
debug_flags(f, KNOWN, self.0)
|
||||
|
@ -5546,45 +5560,45 @@ impl fmt::Debug for VideoEncodeFlagsKHR {
|
|||
debug_flags(f, KNOWN, self.0)
|
||||
}
|
||||
}
|
||||
impl fmt::Debug for VideoEncodeH264CapabilitiesFlagsEXT {
|
||||
impl fmt::Debug for VideoEncodeH264CapabilityFlagsEXT {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
const KNOWN: &[(Flags, &str)] = &[
|
||||
(VideoEncodeH264CapabilitiesFlagsEXT::CABAC.0, "CABAC"),
|
||||
(VideoEncodeH264CapabilitiesFlagsEXT::CAVLC.0, "CAVLC"),
|
||||
(VideoEncodeH264CapabilityFlagsEXT::CABAC.0, "CABAC"),
|
||||
(VideoEncodeH264CapabilityFlagsEXT::CAVLC.0, "CAVLC"),
|
||||
(
|
||||
VideoEncodeH264CapabilitiesFlagsEXT::WEIGHTED_BI_PRED_IMPLICIT.0,
|
||||
VideoEncodeH264CapabilityFlagsEXT::WEIGHTED_BI_PRED_IMPLICIT.0,
|
||||
"WEIGHTED_BI_PRED_IMPLICIT",
|
||||
),
|
||||
(
|
||||
VideoEncodeH264CapabilitiesFlagsEXT::TRANSFORM_8X8.0,
|
||||
VideoEncodeH264CapabilityFlagsEXT::TRANSFORM_8X8.0,
|
||||
"TRANSFORM_8X8",
|
||||
),
|
||||
(
|
||||
VideoEncodeH264CapabilitiesFlagsEXT::CHROMA_QP_OFFSET.0,
|
||||
VideoEncodeH264CapabilityFlagsEXT::CHROMA_QP_OFFSET.0,
|
||||
"CHROMA_QP_OFFSET",
|
||||
),
|
||||
(
|
||||
VideoEncodeH264CapabilitiesFlagsEXT::SECOND_CHROMA_QP_OFFSET.0,
|
||||
VideoEncodeH264CapabilityFlagsEXT::SECOND_CHROMA_QP_OFFSET.0,
|
||||
"SECOND_CHROMA_QP_OFFSET",
|
||||
),
|
||||
(
|
||||
VideoEncodeH264CapabilitiesFlagsEXT::DEBLOCKING_FILTER_DISABLED.0,
|
||||
VideoEncodeH264CapabilityFlagsEXT::DEBLOCKING_FILTER_DISABLED.0,
|
||||
"DEBLOCKING_FILTER_DISABLED",
|
||||
),
|
||||
(
|
||||
VideoEncodeH264CapabilitiesFlagsEXT::DEBLOCKING_FILTER_ENABLED.0,
|
||||
VideoEncodeH264CapabilityFlagsEXT::DEBLOCKING_FILTER_ENABLED.0,
|
||||
"DEBLOCKING_FILTER_ENABLED",
|
||||
),
|
||||
(
|
||||
VideoEncodeH264CapabilitiesFlagsEXT::DEBLOCKING_FILTER_PARTIAL.0,
|
||||
VideoEncodeH264CapabilityFlagsEXT::DEBLOCKING_FILTER_PARTIAL.0,
|
||||
"DEBLOCKING_FILTER_PARTIAL",
|
||||
),
|
||||
(
|
||||
VideoEncodeH264CapabilitiesFlagsEXT::MULTIPLE_SLICE_PER_FRAME.0,
|
||||
VideoEncodeH264CapabilityFlagsEXT::MULTIPLE_SLICE_PER_FRAME.0,
|
||||
"MULTIPLE_SLICE_PER_FRAME",
|
||||
),
|
||||
(
|
||||
VideoEncodeH264CapabilitiesFlagsEXT::EVENLY_DISTRIBUTED_SLICE_SIZE.0,
|
||||
VideoEncodeH264CapabilityFlagsEXT::EVENLY_DISTRIBUTED_SLICE_SIZE.0,
|
||||
"EVENLY_DISTRIBUTED_SLICE_SIZE",
|
||||
),
|
||||
];
|
||||
|
|
|
@ -53,7 +53,7 @@ pub const API_VERSION_1_0: u32 = make_api_version(0, 1, 0, 0);
|
|||
pub const API_VERSION_1_1: u32 = make_api_version(0, 1, 1, 0);
|
||||
#[doc = "<https://www.khronos.org/registry/vulkan/specs/1.2-extensions/man/html/VK_API_VERSION_1_2.html>"]
|
||||
pub const API_VERSION_1_2: u32 = make_api_version(0, 1, 2, 0);
|
||||
pub const HEADER_VERSION: u32 = 186u32;
|
||||
pub const HEADER_VERSION: u32 = 191u32;
|
||||
#[doc = "<https://www.khronos.org/registry/vulkan/specs/1.2-extensions/man/html/VK_HEADER_VERSION_COMPLETE.html>"]
|
||||
pub const HEADER_VERSION_COMPLETE: u32 = make_api_version(0, 1, 2, HEADER_VERSION);
|
||||
#[doc = "<https://www.khronos.org/registry/vulkan/specs/1.2-extensions/man/html/VkSampleMask.html>"]
|
||||
|
@ -135,11 +135,6 @@ pub struct DeviceCreateFlags(pub(crate) Flags);
|
|||
vk_bitflags_wrapped!(DeviceCreateFlags, 0b0, Flags);
|
||||
#[repr(transparent)]
|
||||
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||
#[doc = "<https://www.khronos.org/registry/vulkan/specs/1.2-extensions/man/html/VkSemaphoreCreateFlags.html>"]
|
||||
pub struct SemaphoreCreateFlags(pub(crate) Flags);
|
||||
vk_bitflags_wrapped!(SemaphoreCreateFlags, 0b0, Flags);
|
||||
#[repr(transparent)]
|
||||
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||
#[doc = "<https://www.khronos.org/registry/vulkan/specs/1.2-extensions/man/html/VkMemoryMapFlags.html>"]
|
||||
pub struct MemoryMapFlags(pub(crate) Flags);
|
||||
vk_bitflags_wrapped!(MemoryMapFlags, 0b0, Flags);
|
||||
|
@ -34259,6 +34254,69 @@ impl<'a> MemoryPriorityAllocateInfoEXTBuilder<'a> {
|
|||
}
|
||||
#[repr(C)]
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
#[doc = "<https://www.khronos.org/registry/vulkan/specs/1.2-extensions/man/html/VkPhysicalDevicePageableDeviceLocalMemoryFeaturesEXT.html>"]
|
||||
pub struct PhysicalDevicePageableDeviceLocalMemoryFeaturesEXT {
|
||||
pub s_type: StructureType,
|
||||
pub p_next: *mut c_void,
|
||||
pub pageable_device_local_memory: Bool32,
|
||||
}
|
||||
impl ::std::default::Default for PhysicalDevicePageableDeviceLocalMemoryFeaturesEXT {
|
||||
fn default() -> PhysicalDevicePageableDeviceLocalMemoryFeaturesEXT {
|
||||
PhysicalDevicePageableDeviceLocalMemoryFeaturesEXT {
|
||||
s_type: StructureType::PHYSICAL_DEVICE_PAGEABLE_DEVICE_LOCAL_MEMORY_FEATURES_EXT,
|
||||
p_next: ::std::ptr::null_mut(),
|
||||
pageable_device_local_memory: Bool32::default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
impl PhysicalDevicePageableDeviceLocalMemoryFeaturesEXT {
|
||||
pub fn builder<'a>() -> PhysicalDevicePageableDeviceLocalMemoryFeaturesEXTBuilder<'a> {
|
||||
PhysicalDevicePageableDeviceLocalMemoryFeaturesEXTBuilder {
|
||||
inner: PhysicalDevicePageableDeviceLocalMemoryFeaturesEXT::default(),
|
||||
marker: ::std::marker::PhantomData,
|
||||
}
|
||||
}
|
||||
}
|
||||
#[repr(transparent)]
|
||||
pub struct PhysicalDevicePageableDeviceLocalMemoryFeaturesEXTBuilder<'a> {
|
||||
inner: PhysicalDevicePageableDeviceLocalMemoryFeaturesEXT,
|
||||
marker: ::std::marker::PhantomData<&'a ()>,
|
||||
}
|
||||
unsafe impl ExtendsPhysicalDeviceFeatures2
|
||||
for PhysicalDevicePageableDeviceLocalMemoryFeaturesEXTBuilder<'_>
|
||||
{
|
||||
}
|
||||
unsafe impl ExtendsPhysicalDeviceFeatures2 for PhysicalDevicePageableDeviceLocalMemoryFeaturesEXT {}
|
||||
unsafe impl ExtendsDeviceCreateInfo
|
||||
for PhysicalDevicePageableDeviceLocalMemoryFeaturesEXTBuilder<'_>
|
||||
{
|
||||
}
|
||||
unsafe impl ExtendsDeviceCreateInfo for PhysicalDevicePageableDeviceLocalMemoryFeaturesEXT {}
|
||||
impl<'a> ::std::ops::Deref for PhysicalDevicePageableDeviceLocalMemoryFeaturesEXTBuilder<'a> {
|
||||
type Target = PhysicalDevicePageableDeviceLocalMemoryFeaturesEXT;
|
||||
fn deref(&self) -> &Self::Target {
|
||||
&self.inner
|
||||
}
|
||||
}
|
||||
impl<'a> ::std::ops::DerefMut for PhysicalDevicePageableDeviceLocalMemoryFeaturesEXTBuilder<'a> {
|
||||
fn deref_mut(&mut self) -> &mut Self::Target {
|
||||
&mut self.inner
|
||||
}
|
||||
}
|
||||
impl<'a> PhysicalDevicePageableDeviceLocalMemoryFeaturesEXTBuilder<'a> {
|
||||
pub fn pageable_device_local_memory(mut self, pageable_device_local_memory: bool) -> Self {
|
||||
self.inner.pageable_device_local_memory = pageable_device_local_memory.into();
|
||||
self
|
||||
}
|
||||
#[doc = r" Calling build will **discard** all the lifetime information. Only call this if"]
|
||||
#[doc = r" necessary! Builders implement `Deref` targeting their corresponding Vulkan struct,"]
|
||||
#[doc = r" so references to builders can be passed directly to Vulkan functions."]
|
||||
pub fn build(self) -> PhysicalDevicePageableDeviceLocalMemoryFeaturesEXT {
|
||||
self.inner
|
||||
}
|
||||
}
|
||||
#[repr(C)]
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
#[doc = "<https://www.khronos.org/registry/vulkan/specs/1.2-extensions/man/html/VkPhysicalDeviceBufferDeviceAddressFeatures.html>"]
|
||||
pub struct PhysicalDeviceBufferDeviceAddressFeatures {
|
||||
pub s_type: StructureType,
|
||||
|
@ -37463,6 +37521,85 @@ impl<'a> AttachmentReferenceStencilLayoutBuilder<'a> {
|
|||
}
|
||||
#[repr(C)]
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
#[doc = "<https://www.khronos.org/registry/vulkan/specs/1.2-extensions/man/html/VkPhysicalDevicePrimitiveTopologyListRestartFeaturesEXT.html>"]
|
||||
pub struct PhysicalDevicePrimitiveTopologyListRestartFeaturesEXT {
|
||||
pub s_type: StructureType,
|
||||
pub p_next: *mut c_void,
|
||||
pub primitive_topology_list_restart: Bool32,
|
||||
pub primitive_topology_patch_list_restart: Bool32,
|
||||
}
|
||||
impl ::std::default::Default for PhysicalDevicePrimitiveTopologyListRestartFeaturesEXT {
|
||||
fn default() -> PhysicalDevicePrimitiveTopologyListRestartFeaturesEXT {
|
||||
PhysicalDevicePrimitiveTopologyListRestartFeaturesEXT {
|
||||
s_type: StructureType::PHYSICAL_DEVICE_PRIMITIVE_TOPOLOGY_LIST_RESTART_FEATURES_EXT,
|
||||
p_next: ::std::ptr::null_mut(),
|
||||
primitive_topology_list_restart: Bool32::default(),
|
||||
primitive_topology_patch_list_restart: Bool32::default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
impl PhysicalDevicePrimitiveTopologyListRestartFeaturesEXT {
|
||||
pub fn builder<'a>() -> PhysicalDevicePrimitiveTopologyListRestartFeaturesEXTBuilder<'a> {
|
||||
PhysicalDevicePrimitiveTopologyListRestartFeaturesEXTBuilder {
|
||||
inner: PhysicalDevicePrimitiveTopologyListRestartFeaturesEXT::default(),
|
||||
marker: ::std::marker::PhantomData,
|
||||
}
|
||||
}
|
||||
}
|
||||
#[repr(transparent)]
|
||||
pub struct PhysicalDevicePrimitiveTopologyListRestartFeaturesEXTBuilder<'a> {
|
||||
inner: PhysicalDevicePrimitiveTopologyListRestartFeaturesEXT,
|
||||
marker: ::std::marker::PhantomData<&'a ()>,
|
||||
}
|
||||
unsafe impl ExtendsPhysicalDeviceFeatures2
|
||||
for PhysicalDevicePrimitiveTopologyListRestartFeaturesEXTBuilder<'_>
|
||||
{
|
||||
}
|
||||
unsafe impl ExtendsPhysicalDeviceFeatures2
|
||||
for PhysicalDevicePrimitiveTopologyListRestartFeaturesEXT
|
||||
{
|
||||
}
|
||||
unsafe impl ExtendsDeviceCreateInfo
|
||||
for PhysicalDevicePrimitiveTopologyListRestartFeaturesEXTBuilder<'_>
|
||||
{
|
||||
}
|
||||
unsafe impl ExtendsDeviceCreateInfo for PhysicalDevicePrimitiveTopologyListRestartFeaturesEXT {}
|
||||
impl<'a> ::std::ops::Deref for PhysicalDevicePrimitiveTopologyListRestartFeaturesEXTBuilder<'a> {
|
||||
type Target = PhysicalDevicePrimitiveTopologyListRestartFeaturesEXT;
|
||||
fn deref(&self) -> &Self::Target {
|
||||
&self.inner
|
||||
}
|
||||
}
|
||||
impl<'a> ::std::ops::DerefMut for PhysicalDevicePrimitiveTopologyListRestartFeaturesEXTBuilder<'a> {
|
||||
fn deref_mut(&mut self) -> &mut Self::Target {
|
||||
&mut self.inner
|
||||
}
|
||||
}
|
||||
impl<'a> PhysicalDevicePrimitiveTopologyListRestartFeaturesEXTBuilder<'a> {
|
||||
pub fn primitive_topology_list_restart(
|
||||
mut self,
|
||||
primitive_topology_list_restart: bool,
|
||||
) -> Self {
|
||||
self.inner.primitive_topology_list_restart = primitive_topology_list_restart.into();
|
||||
self
|
||||
}
|
||||
pub fn primitive_topology_patch_list_restart(
|
||||
mut self,
|
||||
primitive_topology_patch_list_restart: bool,
|
||||
) -> Self {
|
||||
self.inner.primitive_topology_patch_list_restart =
|
||||
primitive_topology_patch_list_restart.into();
|
||||
self
|
||||
}
|
||||
#[doc = r" Calling build will **discard** all the lifetime information. Only call this if"]
|
||||
#[doc = r" necessary! Builders implement `Deref` targeting their corresponding Vulkan struct,"]
|
||||
#[doc = r" so references to builders can be passed directly to Vulkan functions."]
|
||||
pub fn build(self) -> PhysicalDevicePrimitiveTopologyListRestartFeaturesEXT {
|
||||
self.inner
|
||||
}
|
||||
}
|
||||
#[repr(C)]
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
#[doc = "<https://www.khronos.org/registry/vulkan/specs/1.2-extensions/man/html/VkAttachmentDescriptionStencilLayout.html>"]
|
||||
pub struct AttachmentDescriptionStencilLayout {
|
||||
pub s_type: StructureType,
|
||||
|
@ -41623,7 +41760,7 @@ impl<'a> AccelerationStructureDeviceAddressInfoKHRBuilder<'a> {
|
|||
pub struct AccelerationStructureVersionInfoKHR {
|
||||
pub s_type: StructureType,
|
||||
pub p_next: *const c_void,
|
||||
pub p_version_data: *const u8,
|
||||
pub p_version_data: *const [u8; 2 * UUID_SIZE],
|
||||
}
|
||||
impl ::std::default::Default for AccelerationStructureVersionInfoKHR {
|
||||
fn default() -> AccelerationStructureVersionInfoKHR {
|
||||
|
@ -41660,7 +41797,7 @@ impl<'a> ::std::ops::DerefMut for AccelerationStructureVersionInfoKHRBuilder<'a>
|
|||
}
|
||||
impl<'a> AccelerationStructureVersionInfoKHRBuilder<'a> {
|
||||
pub fn version_data(mut self, version_data: &'a [u8; 2 * UUID_SIZE]) -> Self {
|
||||
self.inner.p_version_data = version_data.as_ptr();
|
||||
self.inner.p_version_data = version_data as *const [u8; 2 * UUID_SIZE];
|
||||
self
|
||||
}
|
||||
#[doc = r" Calling build will **discard** all the lifetime information. Only call this if"]
|
||||
|
@ -46693,7 +46830,7 @@ impl<'a> VideoProfileKHRBuilder<'a> {
|
|||
pub struct VideoCapabilitiesKHR {
|
||||
pub s_type: StructureType,
|
||||
pub p_next: *mut c_void,
|
||||
pub capability_flags: VideoCapabilitiesFlagsKHR,
|
||||
pub capability_flags: VideoCapabilityFlagsKHR,
|
||||
pub min_bitstream_buffer_offset_alignment: DeviceSize,
|
||||
pub min_bitstream_buffer_size_alignment: DeviceSize,
|
||||
pub video_picture_extent_granularity: Extent2D,
|
||||
|
@ -46707,7 +46844,7 @@ impl ::std::default::Default for VideoCapabilitiesKHR {
|
|||
VideoCapabilitiesKHR {
|
||||
s_type: StructureType::VIDEO_CAPABILITIES_KHR,
|
||||
p_next: ::std::ptr::null_mut(),
|
||||
capability_flags: VideoCapabilitiesFlagsKHR::default(),
|
||||
capability_flags: VideoCapabilityFlagsKHR::default(),
|
||||
min_bitstream_buffer_offset_alignment: DeviceSize::default(),
|
||||
min_bitstream_buffer_size_alignment: DeviceSize::default(),
|
||||
video_picture_extent_granularity: Extent2D::default(),
|
||||
|
@ -46744,7 +46881,7 @@ impl<'a> ::std::ops::DerefMut for VideoCapabilitiesKHRBuilder<'a> {
|
|||
}
|
||||
}
|
||||
impl<'a> VideoCapabilitiesKHRBuilder<'a> {
|
||||
pub fn capability_flags(mut self, capability_flags: VideoCapabilitiesFlagsKHR) -> Self {
|
||||
pub fn capability_flags(mut self, capability_flags: VideoCapabilityFlagsKHR) -> Self {
|
||||
self.inner.capability_flags = capability_flags;
|
||||
self
|
||||
}
|
||||
|
@ -47213,7 +47350,7 @@ pub struct VideoDecodeH264ProfileEXT {
|
|||
pub s_type: StructureType,
|
||||
pub p_next: *const c_void,
|
||||
pub std_profile_idc: StdVideoH264ProfileIdc,
|
||||
pub field_layout: VideoDecodeH264FieldLayoutFlagsEXT,
|
||||
pub picture_layout: VideoDecodeH264PictureLayoutFlagsEXT,
|
||||
}
|
||||
impl ::std::default::Default for VideoDecodeH264ProfileEXT {
|
||||
fn default() -> VideoDecodeH264ProfileEXT {
|
||||
|
@ -47221,7 +47358,7 @@ impl ::std::default::Default for VideoDecodeH264ProfileEXT {
|
|||
s_type: StructureType::VIDEO_DECODE_H264_PROFILE_EXT,
|
||||
p_next: ::std::ptr::null(),
|
||||
std_profile_idc: StdVideoH264ProfileIdc::default(),
|
||||
field_layout: VideoDecodeH264FieldLayoutFlagsEXT::default(),
|
||||
picture_layout: VideoDecodeH264PictureLayoutFlagsEXT::default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -47256,8 +47393,8 @@ impl<'a> VideoDecodeH264ProfileEXTBuilder<'a> {
|
|||
self.inner.std_profile_idc = std_profile_idc;
|
||||
self
|
||||
}
|
||||
pub fn field_layout(mut self, field_layout: VideoDecodeH264FieldLayoutFlagsEXT) -> Self {
|
||||
self.inner.field_layout = field_layout;
|
||||
pub fn picture_layout(mut self, picture_layout: VideoDecodeH264PictureLayoutFlagsEXT) -> Self {
|
||||
self.inner.picture_layout = picture_layout;
|
||||
self
|
||||
}
|
||||
#[doc = r" Calling build will **discard** all the lifetime information. Only call this if"]
|
||||
|
@ -48883,7 +49020,7 @@ impl<'a> VideoEncodeRateControlInfoKHRBuilder<'a> {
|
|||
pub struct VideoEncodeH264CapabilitiesEXT {
|
||||
pub s_type: StructureType,
|
||||
pub p_next: *const c_void,
|
||||
pub flags: VideoEncodeH264CapabilitiesFlagsEXT,
|
||||
pub flags: VideoEncodeH264CapabilityFlagsEXT,
|
||||
pub input_mode_flags: VideoEncodeH264InputModeFlagsEXT,
|
||||
pub output_mode_flags: VideoEncodeH264OutputModeFlagsEXT,
|
||||
pub min_picture_size_in_mbs: Extent2D,
|
||||
|
@ -48900,7 +49037,7 @@ impl ::std::default::Default for VideoEncodeH264CapabilitiesEXT {
|
|||
VideoEncodeH264CapabilitiesEXT {
|
||||
s_type: StructureType::VIDEO_ENCODE_H264_CAPABILITIES_EXT,
|
||||
p_next: ::std::ptr::null(),
|
||||
flags: VideoEncodeH264CapabilitiesFlagsEXT::default(),
|
||||
flags: VideoEncodeH264CapabilityFlagsEXT::default(),
|
||||
input_mode_flags: VideoEncodeH264InputModeFlagsEXT::default(),
|
||||
output_mode_flags: VideoEncodeH264OutputModeFlagsEXT::default(),
|
||||
min_picture_size_in_mbs: Extent2D::default(),
|
||||
|
@ -48941,7 +49078,7 @@ impl<'a> ::std::ops::DerefMut for VideoEncodeH264CapabilitiesEXTBuilder<'a> {
|
|||
}
|
||||
}
|
||||
impl<'a> VideoEncodeH264CapabilitiesEXTBuilder<'a> {
|
||||
pub fn flags(mut self, flags: VideoEncodeH264CapabilitiesFlagsEXT) -> Self {
|
||||
pub fn flags(mut self, flags: VideoEncodeH264CapabilityFlagsEXT) -> Self {
|
||||
self.inner.flags = flags;
|
||||
self
|
||||
}
|
||||
|
@ -50218,6 +50355,412 @@ impl<'a> CuLaunchInfoNVXBuilder<'a> {
|
|||
}
|
||||
#[repr(C)]
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
#[doc = "<https://www.khronos.org/registry/vulkan/specs/1.2-extensions/man/html/VkPhysicalDeviceShaderIntegerDotProductFeaturesKHR.html>"]
|
||||
pub struct PhysicalDeviceShaderIntegerDotProductFeaturesKHR {
|
||||
pub s_type: StructureType,
|
||||
pub p_next: *mut c_void,
|
||||
pub shader_integer_dot_product: Bool32,
|
||||
}
|
||||
impl ::std::default::Default for PhysicalDeviceShaderIntegerDotProductFeaturesKHR {
|
||||
fn default() -> PhysicalDeviceShaderIntegerDotProductFeaturesKHR {
|
||||
PhysicalDeviceShaderIntegerDotProductFeaturesKHR {
|
||||
s_type: StructureType::PHYSICAL_DEVICE_SHADER_INTEGER_DOT_PRODUCT_FEATURES_KHR,
|
||||
p_next: ::std::ptr::null_mut(),
|
||||
shader_integer_dot_product: Bool32::default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
impl PhysicalDeviceShaderIntegerDotProductFeaturesKHR {
|
||||
pub fn builder<'a>() -> PhysicalDeviceShaderIntegerDotProductFeaturesKHRBuilder<'a> {
|
||||
PhysicalDeviceShaderIntegerDotProductFeaturesKHRBuilder {
|
||||
inner: PhysicalDeviceShaderIntegerDotProductFeaturesKHR::default(),
|
||||
marker: ::std::marker::PhantomData,
|
||||
}
|
||||
}
|
||||
}
|
||||
#[repr(transparent)]
|
||||
pub struct PhysicalDeviceShaderIntegerDotProductFeaturesKHRBuilder<'a> {
|
||||
inner: PhysicalDeviceShaderIntegerDotProductFeaturesKHR,
|
||||
marker: ::std::marker::PhantomData<&'a ()>,
|
||||
}
|
||||
unsafe impl ExtendsPhysicalDeviceFeatures2
|
||||
for PhysicalDeviceShaderIntegerDotProductFeaturesKHRBuilder<'_>
|
||||
{
|
||||
}
|
||||
unsafe impl ExtendsPhysicalDeviceFeatures2 for PhysicalDeviceShaderIntegerDotProductFeaturesKHR {}
|
||||
unsafe impl ExtendsDeviceCreateInfo
|
||||
for PhysicalDeviceShaderIntegerDotProductFeaturesKHRBuilder<'_>
|
||||
{
|
||||
}
|
||||
unsafe impl ExtendsDeviceCreateInfo for PhysicalDeviceShaderIntegerDotProductFeaturesKHR {}
|
||||
impl<'a> ::std::ops::Deref for PhysicalDeviceShaderIntegerDotProductFeaturesKHRBuilder<'a> {
|
||||
type Target = PhysicalDeviceShaderIntegerDotProductFeaturesKHR;
|
||||
fn deref(&self) -> &Self::Target {
|
||||
&self.inner
|
||||
}
|
||||
}
|
||||
impl<'a> ::std::ops::DerefMut for PhysicalDeviceShaderIntegerDotProductFeaturesKHRBuilder<'a> {
|
||||
fn deref_mut(&mut self) -> &mut Self::Target {
|
||||
&mut self.inner
|
||||
}
|
||||
}
|
||||
impl<'a> PhysicalDeviceShaderIntegerDotProductFeaturesKHRBuilder<'a> {
|
||||
pub fn shader_integer_dot_product(mut self, shader_integer_dot_product: bool) -> Self {
|
||||
self.inner.shader_integer_dot_product = shader_integer_dot_product.into();
|
||||
self
|
||||
}
|
||||
#[doc = r" Calling build will **discard** all the lifetime information. Only call this if"]
|
||||
#[doc = r" necessary! Builders implement `Deref` targeting their corresponding Vulkan struct,"]
|
||||
#[doc = r" so references to builders can be passed directly to Vulkan functions."]
|
||||
pub fn build(self) -> PhysicalDeviceShaderIntegerDotProductFeaturesKHR {
|
||||
self.inner
|
||||
}
|
||||
}
|
||||
#[repr(C)]
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
#[doc = "<https://www.khronos.org/registry/vulkan/specs/1.2-extensions/man/html/VkPhysicalDeviceShaderIntegerDotProductPropertiesKHR.html>"]
|
||||
pub struct PhysicalDeviceShaderIntegerDotProductPropertiesKHR {
|
||||
pub s_type: StructureType,
|
||||
pub p_next: *mut c_void,
|
||||
pub integer_dot_product8_bit_unsigned_accelerated: Bool32,
|
||||
pub integer_dot_product8_bit_signed_accelerated: Bool32,
|
||||
pub integer_dot_product8_bit_mixed_signedness_accelerated: Bool32,
|
||||
pub integer_dot_product4x8_bit_packed_unsigned_accelerated: Bool32,
|
||||
pub integer_dot_product4x8_bit_packed_signed_accelerated: Bool32,
|
||||
pub integer_dot_product4x8_bit_packed_mixed_signedness_accelerated: Bool32,
|
||||
pub integer_dot_product16_bit_unsigned_accelerated: Bool32,
|
||||
pub integer_dot_product16_bit_signed_accelerated: Bool32,
|
||||
pub integer_dot_product16_bit_mixed_signedness_accelerated: Bool32,
|
||||
pub integer_dot_product32_bit_unsigned_accelerated: Bool32,
|
||||
pub integer_dot_product32_bit_signed_accelerated: Bool32,
|
||||
pub integer_dot_product32_bit_mixed_signedness_accelerated: Bool32,
|
||||
pub integer_dot_product64_bit_unsigned_accelerated: Bool32,
|
||||
pub integer_dot_product64_bit_signed_accelerated: Bool32,
|
||||
pub integer_dot_product64_bit_mixed_signedness_accelerated: Bool32,
|
||||
pub integer_dot_product_accumulating_saturating8_bit_unsigned_accelerated: Bool32,
|
||||
pub integer_dot_product_accumulating_saturating8_bit_signed_accelerated: Bool32,
|
||||
pub integer_dot_product_accumulating_saturating8_bit_mixed_signedness_accelerated: Bool32,
|
||||
pub integer_dot_product_accumulating_saturating4x8_bit_packed_unsigned_accelerated: Bool32,
|
||||
pub integer_dot_product_accumulating_saturating4x8_bit_packed_signed_accelerated: Bool32,
|
||||
pub integer_dot_product_accumulating_saturating4x8_bit_packed_mixed_signedness_accelerated:
|
||||
Bool32,
|
||||
pub integer_dot_product_accumulating_saturating16_bit_unsigned_accelerated: Bool32,
|
||||
pub integer_dot_product_accumulating_saturating16_bit_signed_accelerated: Bool32,
|
||||
pub integer_dot_product_accumulating_saturating16_bit_mixed_signedness_accelerated: Bool32,
|
||||
pub integer_dot_product_accumulating_saturating32_bit_unsigned_accelerated: Bool32,
|
||||
pub integer_dot_product_accumulating_saturating32_bit_signed_accelerated: Bool32,
|
||||
pub integer_dot_product_accumulating_saturating32_bit_mixed_signedness_accelerated: Bool32,
|
||||
pub integer_dot_product_accumulating_saturating64_bit_unsigned_accelerated: Bool32,
|
||||
pub integer_dot_product_accumulating_saturating64_bit_signed_accelerated: Bool32,
|
||||
pub integer_dot_product_accumulating_saturating64_bit_mixed_signedness_accelerated: Bool32,
|
||||
}
|
||||
impl ::std::default::Default for PhysicalDeviceShaderIntegerDotProductPropertiesKHR {
|
||||
fn default() -> PhysicalDeviceShaderIntegerDotProductPropertiesKHR {
|
||||
PhysicalDeviceShaderIntegerDotProductPropertiesKHR { s_type : StructureType :: PHYSICAL_DEVICE_SHADER_INTEGER_DOT_PRODUCT_PROPERTIES_KHR , p_next : :: std :: ptr :: null_mut () , integer_dot_product8_bit_unsigned_accelerated : Bool32 :: default () , integer_dot_product8_bit_signed_accelerated : Bool32 :: default () , integer_dot_product8_bit_mixed_signedness_accelerated : Bool32 :: default () , integer_dot_product4x8_bit_packed_unsigned_accelerated : Bool32 :: default () , integer_dot_product4x8_bit_packed_signed_accelerated : Bool32 :: default () , integer_dot_product4x8_bit_packed_mixed_signedness_accelerated : Bool32 :: default () , integer_dot_product16_bit_unsigned_accelerated : Bool32 :: default () , integer_dot_product16_bit_signed_accelerated : Bool32 :: default () , integer_dot_product16_bit_mixed_signedness_accelerated : Bool32 :: default () , integer_dot_product32_bit_unsigned_accelerated : Bool32 :: default () , integer_dot_product32_bit_signed_accelerated : Bool32 :: default () , integer_dot_product32_bit_mixed_signedness_accelerated : Bool32 :: default () , integer_dot_product64_bit_unsigned_accelerated : Bool32 :: default () , integer_dot_product64_bit_signed_accelerated : Bool32 :: default () , integer_dot_product64_bit_mixed_signedness_accelerated : Bool32 :: default () , integer_dot_product_accumulating_saturating8_bit_unsigned_accelerated : Bool32 :: default () , integer_dot_product_accumulating_saturating8_bit_signed_accelerated : Bool32 :: default () , integer_dot_product_accumulating_saturating8_bit_mixed_signedness_accelerated : Bool32 :: default () , integer_dot_product_accumulating_saturating4x8_bit_packed_unsigned_accelerated : Bool32 :: default () , integer_dot_product_accumulating_saturating4x8_bit_packed_signed_accelerated : Bool32 :: default () , integer_dot_product_accumulating_saturating4x8_bit_packed_mixed_signedness_accelerated : Bool32 :: default () , integer_dot_product_accumulating_saturating16_bit_unsigned_accelerated : Bool32 :: default () , integer_dot_product_accumulating_saturating16_bit_signed_accelerated : Bool32 :: default () , integer_dot_product_accumulating_saturating16_bit_mixed_signedness_accelerated : Bool32 :: default () , integer_dot_product_accumulating_saturating32_bit_unsigned_accelerated : Bool32 :: default () , integer_dot_product_accumulating_saturating32_bit_signed_accelerated : Bool32 :: default () , integer_dot_product_accumulating_saturating32_bit_mixed_signedness_accelerated : Bool32 :: default () , integer_dot_product_accumulating_saturating64_bit_unsigned_accelerated : Bool32 :: default () , integer_dot_product_accumulating_saturating64_bit_signed_accelerated : Bool32 :: default () , integer_dot_product_accumulating_saturating64_bit_mixed_signedness_accelerated : Bool32 :: default () }
|
||||
}
|
||||
}
|
||||
impl PhysicalDeviceShaderIntegerDotProductPropertiesKHR {
|
||||
pub fn builder<'a>() -> PhysicalDeviceShaderIntegerDotProductPropertiesKHRBuilder<'a> {
|
||||
PhysicalDeviceShaderIntegerDotProductPropertiesKHRBuilder {
|
||||
inner: PhysicalDeviceShaderIntegerDotProductPropertiesKHR::default(),
|
||||
marker: ::std::marker::PhantomData,
|
||||
}
|
||||
}
|
||||
}
|
||||
#[repr(transparent)]
|
||||
pub struct PhysicalDeviceShaderIntegerDotProductPropertiesKHRBuilder<'a> {
|
||||
inner: PhysicalDeviceShaderIntegerDotProductPropertiesKHR,
|
||||
marker: ::std::marker::PhantomData<&'a ()>,
|
||||
}
|
||||
unsafe impl ExtendsPhysicalDeviceProperties2
|
||||
for PhysicalDeviceShaderIntegerDotProductPropertiesKHRBuilder<'_>
|
||||
{
|
||||
}
|
||||
unsafe impl ExtendsPhysicalDeviceProperties2
|
||||
for PhysicalDeviceShaderIntegerDotProductPropertiesKHR
|
||||
{
|
||||
}
|
||||
impl<'a> ::std::ops::Deref for PhysicalDeviceShaderIntegerDotProductPropertiesKHRBuilder<'a> {
|
||||
type Target = PhysicalDeviceShaderIntegerDotProductPropertiesKHR;
|
||||
fn deref(&self) -> &Self::Target {
|
||||
&self.inner
|
||||
}
|
||||
}
|
||||
impl<'a> ::std::ops::DerefMut for PhysicalDeviceShaderIntegerDotProductPropertiesKHRBuilder<'a> {
|
||||
fn deref_mut(&mut self) -> &mut Self::Target {
|
||||
&mut self.inner
|
||||
}
|
||||
}
|
||||
impl<'a> PhysicalDeviceShaderIntegerDotProductPropertiesKHRBuilder<'a> {
|
||||
pub fn integer_dot_product8_bit_unsigned_accelerated(
|
||||
mut self,
|
||||
integer_dot_product8_bit_unsigned_accelerated: bool,
|
||||
) -> Self {
|
||||
self.inner.integer_dot_product8_bit_unsigned_accelerated =
|
||||
integer_dot_product8_bit_unsigned_accelerated.into();
|
||||
self
|
||||
}
|
||||
pub fn integer_dot_product8_bit_signed_accelerated(
|
||||
mut self,
|
||||
integer_dot_product8_bit_signed_accelerated: bool,
|
||||
) -> Self {
|
||||
self.inner.integer_dot_product8_bit_signed_accelerated =
|
||||
integer_dot_product8_bit_signed_accelerated.into();
|
||||
self
|
||||
}
|
||||
pub fn integer_dot_product8_bit_mixed_signedness_accelerated(
|
||||
mut self,
|
||||
integer_dot_product8_bit_mixed_signedness_accelerated: bool,
|
||||
) -> Self {
|
||||
self.inner
|
||||
.integer_dot_product8_bit_mixed_signedness_accelerated =
|
||||
integer_dot_product8_bit_mixed_signedness_accelerated.into();
|
||||
self
|
||||
}
|
||||
pub fn integer_dot_product4x8_bit_packed_unsigned_accelerated(
|
||||
mut self,
|
||||
integer_dot_product4x8_bit_packed_unsigned_accelerated: bool,
|
||||
) -> Self {
|
||||
self.inner
|
||||
.integer_dot_product4x8_bit_packed_unsigned_accelerated =
|
||||
integer_dot_product4x8_bit_packed_unsigned_accelerated.into();
|
||||
self
|
||||
}
|
||||
pub fn integer_dot_product4x8_bit_packed_signed_accelerated(
|
||||
mut self,
|
||||
integer_dot_product4x8_bit_packed_signed_accelerated: bool,
|
||||
) -> Self {
|
||||
self.inner
|
||||
.integer_dot_product4x8_bit_packed_signed_accelerated =
|
||||
integer_dot_product4x8_bit_packed_signed_accelerated.into();
|
||||
self
|
||||
}
|
||||
pub fn integer_dot_product4x8_bit_packed_mixed_signedness_accelerated(
|
||||
mut self,
|
||||
integer_dot_product4x8_bit_packed_mixed_signedness_accelerated: bool,
|
||||
) -> Self {
|
||||
self.inner
|
||||
.integer_dot_product4x8_bit_packed_mixed_signedness_accelerated =
|
||||
integer_dot_product4x8_bit_packed_mixed_signedness_accelerated.into();
|
||||
self
|
||||
}
|
||||
pub fn integer_dot_product16_bit_unsigned_accelerated(
|
||||
mut self,
|
||||
integer_dot_product16_bit_unsigned_accelerated: bool,
|
||||
) -> Self {
|
||||
self.inner.integer_dot_product16_bit_unsigned_accelerated =
|
||||
integer_dot_product16_bit_unsigned_accelerated.into();
|
||||
self
|
||||
}
|
||||
pub fn integer_dot_product16_bit_signed_accelerated(
|
||||
mut self,
|
||||
integer_dot_product16_bit_signed_accelerated: bool,
|
||||
) -> Self {
|
||||
self.inner.integer_dot_product16_bit_signed_accelerated =
|
||||
integer_dot_product16_bit_signed_accelerated.into();
|
||||
self
|
||||
}
|
||||
pub fn integer_dot_product16_bit_mixed_signedness_accelerated(
|
||||
mut self,
|
||||
integer_dot_product16_bit_mixed_signedness_accelerated: bool,
|
||||
) -> Self {
|
||||
self.inner
|
||||
.integer_dot_product16_bit_mixed_signedness_accelerated =
|
||||
integer_dot_product16_bit_mixed_signedness_accelerated.into();
|
||||
self
|
||||
}
|
||||
pub fn integer_dot_product32_bit_unsigned_accelerated(
|
||||
mut self,
|
||||
integer_dot_product32_bit_unsigned_accelerated: bool,
|
||||
) -> Self {
|
||||
self.inner.integer_dot_product32_bit_unsigned_accelerated =
|
||||
integer_dot_product32_bit_unsigned_accelerated.into();
|
||||
self
|
||||
}
|
||||
pub fn integer_dot_product32_bit_signed_accelerated(
|
||||
mut self,
|
||||
integer_dot_product32_bit_signed_accelerated: bool,
|
||||
) -> Self {
|
||||
self.inner.integer_dot_product32_bit_signed_accelerated =
|
||||
integer_dot_product32_bit_signed_accelerated.into();
|
||||
self
|
||||
}
|
||||
pub fn integer_dot_product32_bit_mixed_signedness_accelerated(
|
||||
mut self,
|
||||
integer_dot_product32_bit_mixed_signedness_accelerated: bool,
|
||||
) -> Self {
|
||||
self.inner
|
||||
.integer_dot_product32_bit_mixed_signedness_accelerated =
|
||||
integer_dot_product32_bit_mixed_signedness_accelerated.into();
|
||||
self
|
||||
}
|
||||
pub fn integer_dot_product64_bit_unsigned_accelerated(
|
||||
mut self,
|
||||
integer_dot_product64_bit_unsigned_accelerated: bool,
|
||||
) -> Self {
|
||||
self.inner.integer_dot_product64_bit_unsigned_accelerated =
|
||||
integer_dot_product64_bit_unsigned_accelerated.into();
|
||||
self
|
||||
}
|
||||
pub fn integer_dot_product64_bit_signed_accelerated(
|
||||
mut self,
|
||||
integer_dot_product64_bit_signed_accelerated: bool,
|
||||
) -> Self {
|
||||
self.inner.integer_dot_product64_bit_signed_accelerated =
|
||||
integer_dot_product64_bit_signed_accelerated.into();
|
||||
self
|
||||
}
|
||||
pub fn integer_dot_product64_bit_mixed_signedness_accelerated(
|
||||
mut self,
|
||||
integer_dot_product64_bit_mixed_signedness_accelerated: bool,
|
||||
) -> Self {
|
||||
self.inner
|
||||
.integer_dot_product64_bit_mixed_signedness_accelerated =
|
||||
integer_dot_product64_bit_mixed_signedness_accelerated.into();
|
||||
self
|
||||
}
|
||||
pub fn integer_dot_product_accumulating_saturating8_bit_unsigned_accelerated(
|
||||
mut self,
|
||||
integer_dot_product_accumulating_saturating8_bit_unsigned_accelerated: bool,
|
||||
) -> Self {
|
||||
self.inner
|
||||
.integer_dot_product_accumulating_saturating8_bit_unsigned_accelerated =
|
||||
integer_dot_product_accumulating_saturating8_bit_unsigned_accelerated.into();
|
||||
self
|
||||
}
|
||||
pub fn integer_dot_product_accumulating_saturating8_bit_signed_accelerated(
|
||||
mut self,
|
||||
integer_dot_product_accumulating_saturating8_bit_signed_accelerated: bool,
|
||||
) -> Self {
|
||||
self.inner
|
||||
.integer_dot_product_accumulating_saturating8_bit_signed_accelerated =
|
||||
integer_dot_product_accumulating_saturating8_bit_signed_accelerated.into();
|
||||
self
|
||||
}
|
||||
pub fn integer_dot_product_accumulating_saturating8_bit_mixed_signedness_accelerated(
|
||||
mut self,
|
||||
integer_dot_product_accumulating_saturating8_bit_mixed_signedness_accelerated: bool,
|
||||
) -> Self {
|
||||
self.inner
|
||||
.integer_dot_product_accumulating_saturating8_bit_mixed_signedness_accelerated =
|
||||
integer_dot_product_accumulating_saturating8_bit_mixed_signedness_accelerated.into();
|
||||
self
|
||||
}
|
||||
pub fn integer_dot_product_accumulating_saturating4x8_bit_packed_unsigned_accelerated(
|
||||
mut self,
|
||||
integer_dot_product_accumulating_saturating4x8_bit_packed_unsigned_accelerated: bool,
|
||||
) -> Self {
|
||||
self.inner
|
||||
.integer_dot_product_accumulating_saturating4x8_bit_packed_unsigned_accelerated =
|
||||
integer_dot_product_accumulating_saturating4x8_bit_packed_unsigned_accelerated.into();
|
||||
self
|
||||
}
|
||||
pub fn integer_dot_product_accumulating_saturating4x8_bit_packed_signed_accelerated(
|
||||
mut self,
|
||||
integer_dot_product_accumulating_saturating4x8_bit_packed_signed_accelerated: bool,
|
||||
) -> Self {
|
||||
self.inner
|
||||
.integer_dot_product_accumulating_saturating4x8_bit_packed_signed_accelerated =
|
||||
integer_dot_product_accumulating_saturating4x8_bit_packed_signed_accelerated.into();
|
||||
self
|
||||
}
|
||||
pub fn integer_dot_product_accumulating_saturating4x8_bit_packed_mixed_signedness_accelerated(
|
||||
mut self,
|
||||
integer_dot_product_accumulating_saturating4x8_bit_packed_mixed_signedness_accelerated : bool,
|
||||
) -> Self {
|
||||
self . inner . integer_dot_product_accumulating_saturating4x8_bit_packed_mixed_signedness_accelerated = integer_dot_product_accumulating_saturating4x8_bit_packed_mixed_signedness_accelerated . into () ;
|
||||
self
|
||||
}
|
||||
pub fn integer_dot_product_accumulating_saturating16_bit_unsigned_accelerated(
|
||||
mut self,
|
||||
integer_dot_product_accumulating_saturating16_bit_unsigned_accelerated: bool,
|
||||
) -> Self {
|
||||
self.inner
|
||||
.integer_dot_product_accumulating_saturating16_bit_unsigned_accelerated =
|
||||
integer_dot_product_accumulating_saturating16_bit_unsigned_accelerated.into();
|
||||
self
|
||||
}
|
||||
pub fn integer_dot_product_accumulating_saturating16_bit_signed_accelerated(
|
||||
mut self,
|
||||
integer_dot_product_accumulating_saturating16_bit_signed_accelerated: bool,
|
||||
) -> Self {
|
||||
self.inner
|
||||
.integer_dot_product_accumulating_saturating16_bit_signed_accelerated =
|
||||
integer_dot_product_accumulating_saturating16_bit_signed_accelerated.into();
|
||||
self
|
||||
}
|
||||
pub fn integer_dot_product_accumulating_saturating16_bit_mixed_signedness_accelerated(
|
||||
mut self,
|
||||
integer_dot_product_accumulating_saturating16_bit_mixed_signedness_accelerated: bool,
|
||||
) -> Self {
|
||||
self.inner
|
||||
.integer_dot_product_accumulating_saturating16_bit_mixed_signedness_accelerated =
|
||||
integer_dot_product_accumulating_saturating16_bit_mixed_signedness_accelerated.into();
|
||||
self
|
||||
}
|
||||
pub fn integer_dot_product_accumulating_saturating32_bit_unsigned_accelerated(
|
||||
mut self,
|
||||
integer_dot_product_accumulating_saturating32_bit_unsigned_accelerated: bool,
|
||||
) -> Self {
|
||||
self.inner
|
||||
.integer_dot_product_accumulating_saturating32_bit_unsigned_accelerated =
|
||||
integer_dot_product_accumulating_saturating32_bit_unsigned_accelerated.into();
|
||||
self
|
||||
}
|
||||
pub fn integer_dot_product_accumulating_saturating32_bit_signed_accelerated(
|
||||
mut self,
|
||||
integer_dot_product_accumulating_saturating32_bit_signed_accelerated: bool,
|
||||
) -> Self {
|
||||
self.inner
|
||||
.integer_dot_product_accumulating_saturating32_bit_signed_accelerated =
|
||||
integer_dot_product_accumulating_saturating32_bit_signed_accelerated.into();
|
||||
self
|
||||
}
|
||||
pub fn integer_dot_product_accumulating_saturating32_bit_mixed_signedness_accelerated(
|
||||
mut self,
|
||||
integer_dot_product_accumulating_saturating32_bit_mixed_signedness_accelerated: bool,
|
||||
) -> Self {
|
||||
self.inner
|
||||
.integer_dot_product_accumulating_saturating32_bit_mixed_signedness_accelerated =
|
||||
integer_dot_product_accumulating_saturating32_bit_mixed_signedness_accelerated.into();
|
||||
self
|
||||
}
|
||||
pub fn integer_dot_product_accumulating_saturating64_bit_unsigned_accelerated(
|
||||
mut self,
|
||||
integer_dot_product_accumulating_saturating64_bit_unsigned_accelerated: bool,
|
||||
) -> Self {
|
||||
self.inner
|
||||
.integer_dot_product_accumulating_saturating64_bit_unsigned_accelerated =
|
||||
integer_dot_product_accumulating_saturating64_bit_unsigned_accelerated.into();
|
||||
self
|
||||
}
|
||||
pub fn integer_dot_product_accumulating_saturating64_bit_signed_accelerated(
|
||||
mut self,
|
||||
integer_dot_product_accumulating_saturating64_bit_signed_accelerated: bool,
|
||||
) -> Self {
|
||||
self.inner
|
||||
.integer_dot_product_accumulating_saturating64_bit_signed_accelerated =
|
||||
integer_dot_product_accumulating_saturating64_bit_signed_accelerated.into();
|
||||
self
|
||||
}
|
||||
pub fn integer_dot_product_accumulating_saturating64_bit_mixed_signedness_accelerated(
|
||||
mut self,
|
||||
integer_dot_product_accumulating_saturating64_bit_mixed_signedness_accelerated: bool,
|
||||
) -> Self {
|
||||
self.inner
|
||||
.integer_dot_product_accumulating_saturating64_bit_mixed_signedness_accelerated =
|
||||
integer_dot_product_accumulating_saturating64_bit_mixed_signedness_accelerated.into();
|
||||
self
|
||||
}
|
||||
#[doc = r" Calling build will **discard** all the lifetime information. Only call this if"]
|
||||
#[doc = r" necessary! Builders implement `Deref` targeting their corresponding Vulkan struct,"]
|
||||
#[doc = r" so references to builders can be passed directly to Vulkan functions."]
|
||||
pub fn build(self) -> PhysicalDeviceShaderIntegerDotProductPropertiesKHR {
|
||||
self.inner
|
||||
}
|
||||
}
|
||||
#[repr(C)]
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
#[doc = "<https://www.khronos.org/registry/vulkan/specs/1.2-extensions/man/html/VkPhysicalDeviceDrmPropertiesEXT.html>"]
|
||||
pub struct PhysicalDeviceDrmPropertiesEXT {
|
||||
pub s_type: StructureType,
|
||||
|
|
|
@ -1655,6 +1655,8 @@ impl DriverId {
|
|||
pub const COREAVI_PROPRIETARY: Self = Self(15);
|
||||
#[doc = "Juice Technologies, Inc."]
|
||||
pub const JUICE_PROPRIETARY: Self = Self(16);
|
||||
#[doc = "Verisilicon, Inc."]
|
||||
pub const VERISILICON_PROPRIETARY: Self = Self(17);
|
||||
}
|
||||
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Default)]
|
||||
#[repr(transparent)]
|
||||
|
|
|
@ -2398,7 +2398,7 @@ impl KhrVideoQueueFn {
|
|||
::std::ffi::CStr::from_bytes_with_nul(b"VK_KHR_video_queue\0")
|
||||
.expect("Wrong extension string")
|
||||
}
|
||||
pub const SPEC_VERSION: u32 = 1u32;
|
||||
pub const SPEC_VERSION: u32 = 2u32;
|
||||
}
|
||||
#[allow(non_camel_case_types)]
|
||||
pub type PFN_vkGetPhysicalDeviceVideoCapabilitiesKHR = unsafe extern "system" fn(
|
||||
|
@ -4072,7 +4072,7 @@ impl ExtVideoEncodeH264Fn {
|
|||
::std::ffi::CStr::from_bytes_with_nul(b"VK_EXT_video_encode_h264\0")
|
||||
.expect("Wrong extension string")
|
||||
}
|
||||
pub const SPEC_VERSION: u32 = 1u32;
|
||||
pub const SPEC_VERSION: u32 = 2u32;
|
||||
}
|
||||
#[derive(Clone)]
|
||||
pub struct ExtVideoEncodeH264Fn {}
|
||||
|
@ -4150,7 +4150,7 @@ impl ExtVideoDecodeH264Fn {
|
|||
::std::ffi::CStr::from_bytes_with_nul(b"VK_EXT_video_decode_h264\0")
|
||||
.expect("Wrong extension string")
|
||||
}
|
||||
pub const SPEC_VERSION: u32 = 1u32;
|
||||
pub const SPEC_VERSION: u32 = 3u32;
|
||||
}
|
||||
#[derive(Clone)]
|
||||
pub struct ExtVideoDecodeH264Fn {}
|
||||
|
@ -11198,7 +11198,7 @@ impl KhrAccelerationStructureFn {
|
|||
::std::ffi::CStr::from_bytes_with_nul(b"VK_KHR_acceleration_structure\0")
|
||||
.expect("Wrong extension string")
|
||||
}
|
||||
pub const SPEC_VERSION: u32 = 11u32;
|
||||
pub const SPEC_VERSION: u32 = 12u32;
|
||||
}
|
||||
#[allow(non_camel_case_types)]
|
||||
pub type PFN_vkCreateAccelerationStructureKHR = unsafe extern "system" fn(
|
||||
|
@ -20415,25 +20415,33 @@ impl KhrExtension280Fn {
|
|||
KhrExtension280Fn {}
|
||||
}
|
||||
}
|
||||
impl ArmExtension281Fn {
|
||||
impl KhrShaderIntegerDotProductFn {
|
||||
pub fn name() -> &'static ::std::ffi::CStr {
|
||||
::std::ffi::CStr::from_bytes_with_nul(b"VK_ARM_extension_281\0")
|
||||
::std::ffi::CStr::from_bytes_with_nul(b"VK_KHR_shader_integer_dot_product\0")
|
||||
.expect("Wrong extension string")
|
||||
}
|
||||
pub const SPEC_VERSION: u32 = 0u32;
|
||||
pub const SPEC_VERSION: u32 = 1u32;
|
||||
}
|
||||
#[derive(Clone)]
|
||||
pub struct ArmExtension281Fn {}
|
||||
unsafe impl Send for ArmExtension281Fn {}
|
||||
unsafe impl Sync for ArmExtension281Fn {}
|
||||
impl ArmExtension281Fn {
|
||||
pub struct KhrShaderIntegerDotProductFn {}
|
||||
unsafe impl Send for KhrShaderIntegerDotProductFn {}
|
||||
unsafe impl Sync for KhrShaderIntegerDotProductFn {}
|
||||
impl KhrShaderIntegerDotProductFn {
|
||||
pub fn load<F>(mut _f: F) -> Self
|
||||
where
|
||||
F: FnMut(&::std::ffi::CStr) -> *const c_void,
|
||||
{
|
||||
ArmExtension281Fn {}
|
||||
KhrShaderIntegerDotProductFn {}
|
||||
}
|
||||
}
|
||||
#[doc = "Generated from 'VK_KHR_shader_integer_dot_product'"]
|
||||
impl StructureType {
|
||||
pub const PHYSICAL_DEVICE_SHADER_INTEGER_DOT_PRODUCT_FEATURES_KHR: Self = Self(1_000_280_000);
|
||||
}
|
||||
#[doc = "Generated from 'VK_KHR_shader_integer_dot_product'"]
|
||||
impl StructureType {
|
||||
pub const PHYSICAL_DEVICE_SHADER_INTEGER_DOT_PRODUCT_PROPERTIES_KHR: Self = Self(1_000_280_001);
|
||||
}
|
||||
impl ExtTexelBufferAlignmentFn {
|
||||
pub fn name() -> &'static ::std::ffi::CStr {
|
||||
::std::ffi::CStr::from_bytes_with_nul(b"VK_EXT_texel_buffer_alignment\0")
|
||||
|
@ -21434,7 +21442,7 @@ impl QcomRenderPassStoreOpsFn {
|
|||
}
|
||||
#[doc = "Generated from 'VK_QCOM_render_pass_store_ops'"]
|
||||
impl AttachmentStoreOp {
|
||||
pub const NONE_QCOM: Self = Self(1_000_301_000);
|
||||
pub const NONE_QCOM: Self = Self::NONE_EXT;
|
||||
}
|
||||
impl QcomExtension303Fn {
|
||||
pub fn name() -> &'static ::std::ffi::CStr {
|
||||
|
@ -23527,24 +23535,30 @@ impl ExtVertexAttributeAliasingFn {
|
|||
ExtVertexAttributeAliasingFn {}
|
||||
}
|
||||
}
|
||||
impl ExtExtension357Fn {
|
||||
impl ExtPrimitiveTopologyListRestartFn {
|
||||
pub fn name() -> &'static ::std::ffi::CStr {
|
||||
::std::ffi::CStr::from_bytes_with_nul(b"VK_EXT_extension_357\0")
|
||||
::std::ffi::CStr::from_bytes_with_nul(b"VK_EXT_primitive_topology_list_restart\0")
|
||||
.expect("Wrong extension string")
|
||||
}
|
||||
pub const SPEC_VERSION: u32 = 1u32;
|
||||
}
|
||||
#[derive(Clone)]
|
||||
pub struct ExtExtension357Fn {}
|
||||
unsafe impl Send for ExtExtension357Fn {}
|
||||
unsafe impl Sync for ExtExtension357Fn {}
|
||||
impl ExtExtension357Fn {
|
||||
pub struct ExtPrimitiveTopologyListRestartFn {}
|
||||
unsafe impl Send for ExtPrimitiveTopologyListRestartFn {}
|
||||
unsafe impl Sync for ExtPrimitiveTopologyListRestartFn {}
|
||||
impl ExtPrimitiveTopologyListRestartFn {
|
||||
pub fn load<F>(mut _f: F) -> Self
|
||||
where
|
||||
F: FnMut(&::std::ffi::CStr) -> *const c_void,
|
||||
{
|
||||
ExtExtension357Fn {}
|
||||
ExtPrimitiveTopologyListRestartFn {}
|
||||
}
|
||||
}
|
||||
#[doc = "Generated from 'VK_EXT_primitive_topology_list_restart'"]
|
||||
impl StructureType {
|
||||
pub const PHYSICAL_DEVICE_PRIMITIVE_TOPOLOGY_LIST_RESTART_FEATURES_EXT: Self =
|
||||
Self(1_000_356_000);
|
||||
}
|
||||
impl KhrExtension358Fn {
|
||||
pub fn name() -> &'static ::std::ffi::CStr {
|
||||
::std::ffi::CStr::from_bytes_with_nul(b"VK_KHR_extension_358\0")
|
||||
|
@ -23569,6 +23583,7 @@ impl ExtExtension359Fn {
|
|||
::std::ffi::CStr::from_bytes_with_nul(b"VK_EXT_extension_359\0")
|
||||
.expect("Wrong extension string")
|
||||
}
|
||||
pub const SPEC_VERSION: u32 = 0u32;
|
||||
}
|
||||
#[derive(Clone)]
|
||||
pub struct ExtExtension359Fn {}
|
||||
|
@ -23587,6 +23602,7 @@ impl ExtExtension360Fn {
|
|||
::std::ffi::CStr::from_bytes_with_nul(b"VK_EXT_extension_360\0")
|
||||
.expect("Wrong extension string")
|
||||
}
|
||||
pub const SPEC_VERSION: u32 = 0u32;
|
||||
}
|
||||
#[derive(Clone)]
|
||||
pub struct ExtExtension360Fn {}
|
||||
|
@ -23605,6 +23621,7 @@ impl KhrExtension361Fn {
|
|||
::std::ffi::CStr::from_bytes_with_nul(b"VK_KHR_extension_361\0")
|
||||
.expect("Wrong extension string")
|
||||
}
|
||||
pub const SPEC_VERSION: u32 = 0u32;
|
||||
}
|
||||
#[derive(Clone)]
|
||||
pub struct KhrExtension361Fn {}
|
||||
|
@ -25220,25 +25237,33 @@ impl JuiceExtension400Fn {
|
|||
JuiceExtension400Fn {}
|
||||
}
|
||||
}
|
||||
impl KhrExtension401Fn {
|
||||
impl ExtLoadStoreOpNoneFn {
|
||||
pub fn name() -> &'static ::std::ffi::CStr {
|
||||
::std::ffi::CStr::from_bytes_with_nul(b"VK_KHR_extension_401\0")
|
||||
::std::ffi::CStr::from_bytes_with_nul(b"VK_EXT_load_store_op_none\0")
|
||||
.expect("Wrong extension string")
|
||||
}
|
||||
pub const SPEC_VERSION: u32 = 0u32;
|
||||
pub const SPEC_VERSION: u32 = 1u32;
|
||||
}
|
||||
#[derive(Clone)]
|
||||
pub struct KhrExtension401Fn {}
|
||||
unsafe impl Send for KhrExtension401Fn {}
|
||||
unsafe impl Sync for KhrExtension401Fn {}
|
||||
impl KhrExtension401Fn {
|
||||
pub struct ExtLoadStoreOpNoneFn {}
|
||||
unsafe impl Send for ExtLoadStoreOpNoneFn {}
|
||||
unsafe impl Sync for ExtLoadStoreOpNoneFn {}
|
||||
impl ExtLoadStoreOpNoneFn {
|
||||
pub fn load<F>(mut _f: F) -> Self
|
||||
where
|
||||
F: FnMut(&::std::ffi::CStr) -> *const c_void,
|
||||
{
|
||||
KhrExtension401Fn {}
|
||||
ExtLoadStoreOpNoneFn {}
|
||||
}
|
||||
}
|
||||
#[doc = "Generated from 'VK_EXT_load_store_op_none'"]
|
||||
impl AttachmentLoadOp {
|
||||
pub const NONE_EXT: Self = Self(1_000_400_000);
|
||||
}
|
||||
#[doc = "Generated from 'VK_EXT_load_store_op_none'"]
|
||||
impl AttachmentStoreOp {
|
||||
pub const NONE_EXT: Self = Self(1_000_301_000);
|
||||
}
|
||||
impl FbExtension402Fn {
|
||||
pub fn name() -> &'static ::std::ffi::CStr {
|
||||
::std::ffi::CStr::from_bytes_with_nul(b"VK_FB_extension_402\0")
|
||||
|
@ -25448,24 +25473,64 @@ impl NvExtension412Fn {
|
|||
NvExtension412Fn {}
|
||||
}
|
||||
}
|
||||
impl NvExtension413Fn {
|
||||
impl ExtPageableDeviceLocalMemoryFn {
|
||||
pub fn name() -> &'static ::std::ffi::CStr {
|
||||
::std::ffi::CStr::from_bytes_with_nul(b"VK_NV_extension_413\0")
|
||||
::std::ffi::CStr::from_bytes_with_nul(b"VK_EXT_pageable_device_local_memory\0")
|
||||
.expect("Wrong extension string")
|
||||
}
|
||||
pub const SPEC_VERSION: u32 = 0u32;
|
||||
pub const SPEC_VERSION: u32 = 1u32;
|
||||
}
|
||||
#[allow(non_camel_case_types)]
|
||||
pub type PFN_vkSetDeviceMemoryPriorityEXT =
|
||||
unsafe extern "system" fn(device: Device, memory: DeviceMemory, priority: f32);
|
||||
#[derive(Clone)]
|
||||
pub struct NvExtension413Fn {}
|
||||
unsafe impl Send for NvExtension413Fn {}
|
||||
unsafe impl Sync for NvExtension413Fn {}
|
||||
impl NvExtension413Fn {
|
||||
pub struct ExtPageableDeviceLocalMemoryFn {
|
||||
pub set_device_memory_priority_ext: PFN_vkSetDeviceMemoryPriorityEXT,
|
||||
}
|
||||
unsafe impl Send for ExtPageableDeviceLocalMemoryFn {}
|
||||
unsafe impl Sync for ExtPageableDeviceLocalMemoryFn {}
|
||||
impl ExtPageableDeviceLocalMemoryFn {
|
||||
pub fn load<F>(mut _f: F) -> Self
|
||||
where
|
||||
F: FnMut(&::std::ffi::CStr) -> *const c_void,
|
||||
{
|
||||
NvExtension413Fn {}
|
||||
ExtPageableDeviceLocalMemoryFn {
|
||||
set_device_memory_priority_ext: unsafe {
|
||||
unsafe extern "system" fn set_device_memory_priority_ext(
|
||||
_device: Device,
|
||||
_memory: DeviceMemory,
|
||||
_priority: f32,
|
||||
) {
|
||||
panic!(concat!(
|
||||
"Unable to load ",
|
||||
stringify!(set_device_memory_priority_ext)
|
||||
))
|
||||
}
|
||||
let cname = ::std::ffi::CStr::from_bytes_with_nul_unchecked(
|
||||
b"vkSetDeviceMemoryPriorityEXT\0",
|
||||
);
|
||||
let val = _f(cname);
|
||||
if val.is_null() {
|
||||
set_device_memory_priority_ext
|
||||
} else {
|
||||
::std::mem::transmute(val)
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
#[doc = "<https://www.khronos.org/registry/vulkan/specs/1.2-extensions/man/html/vkSetDeviceMemoryPriorityEXT.html>"]
|
||||
pub unsafe fn set_device_memory_priority_ext(
|
||||
&self,
|
||||
device: Device,
|
||||
memory: DeviceMemory,
|
||||
priority: f32,
|
||||
) {
|
||||
(self.set_device_memory_priority_ext)(device, memory, priority)
|
||||
}
|
||||
}
|
||||
#[doc = "Generated from 'VK_EXT_pageable_device_local_memory'"]
|
||||
impl StructureType {
|
||||
pub const PHYSICAL_DEVICE_PAGEABLE_DEVICE_LOCAL_MEMORY_FEATURES_EXT: Self = Self(1_000_412_000);
|
||||
}
|
||||
impl NvExtension414Fn {
|
||||
pub fn name() -> &'static ::std::ffi::CStr {
|
||||
|
@ -25619,3 +25684,45 @@ impl KhrExtension421Fn {
|
|||
KhrExtension421Fn {}
|
||||
}
|
||||
}
|
||||
impl ExtExtension422Fn {
|
||||
pub fn name() -> &'static ::std::ffi::CStr {
|
||||
::std::ffi::CStr::from_bytes_with_nul(b"VK_EXT_extension_422\0")
|
||||
.expect("Wrong extension string")
|
||||
}
|
||||
pub const SPEC_VERSION: u32 = 0u32;
|
||||
}
|
||||
#[derive(Clone)]
|
||||
pub struct ExtExtension422Fn {}
|
||||
unsafe impl Send for ExtExtension422Fn {}
|
||||
unsafe impl Sync for ExtExtension422Fn {}
|
||||
impl ExtExtension422Fn {
|
||||
pub fn load<F>(mut _f: F) -> Self
|
||||
where
|
||||
F: FnMut(&::std::ffi::CStr) -> *const c_void,
|
||||
{
|
||||
ExtExtension422Fn {}
|
||||
}
|
||||
}
|
||||
impl ExtDisableCubeMapWrapFn {
|
||||
pub fn name() -> &'static ::std::ffi::CStr {
|
||||
::std::ffi::CStr::from_bytes_with_nul(b"VK_EXT_disable_cube_map_wrap\0")
|
||||
.expect("Wrong extension string")
|
||||
}
|
||||
pub const SPEC_VERSION: u32 = 0u32;
|
||||
}
|
||||
#[derive(Clone)]
|
||||
pub struct ExtDisableCubeMapWrapFn {}
|
||||
unsafe impl Send for ExtDisableCubeMapWrapFn {}
|
||||
unsafe impl Sync for ExtDisableCubeMapWrapFn {}
|
||||
impl ExtDisableCubeMapWrapFn {
|
||||
pub fn load<F>(mut _f: F) -> Self
|
||||
where
|
||||
F: FnMut(&::std::ffi::CStr) -> *const c_void,
|
||||
{
|
||||
ExtDisableCubeMapWrapFn {}
|
||||
}
|
||||
}
|
||||
#[doc = "Generated from 'VK_EXT_disable_cube_map_wrap'"]
|
||||
impl SamplerCreateFlags {
|
||||
pub const RESERVED_2_EXT: Self = Self(0b100);
|
||||
}
|
||||
|
|
|
@ -1 +1 @@
|
|||
{"files":{"Cargo.toml":"4c50bdb04cb7b2c2eccf4f6f43a27bd833e3481eaaeaf44ce31e0e4842749f98","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"23f18e03dc49df91622fe2a76176497404e46ced8a715d9d2b67a7446571cca3","README.md":"7cdf53d90efa27ae464b138755eb88a7f912ff95cad3ea3a1970ee4891af8aa2","src/args.rs":"6eed5497db91752b3aae597943c39e769f60406b37055304e69e4699f1f87b15","src/expand.rs":"da89e09db97138bc7488fde2aea105329635a4467267d7cfe5d80d4550948e2a","src/lib.rs":"fee50ccfc315bb468f4207cebef12ec7285cef78c5c09c9f09d5a32b1876f4af","src/lifetime.rs":"e51bd32dba9caf32ea241d2f4fbd83c29b5c71d0308d9c18268b9e4594ec9c76","src/parse.rs":"cd9032fe2c6dcf41050b3a59b9fb98eb9700a29bbe2fa011ee2854014c1666b7","src/receiver.rs":"0a166f7423f17e0743b64a37c448dcbace89f1df71d204f94b0ed942c7d9e053","src/respan.rs":"eef5b4467f58e1df4650a2331495c5e28eff8d54a3250506fc2f6c2da3366ada","tests/compiletest.rs":"0a52a44786aea1c299c695bf948b2ed2081e4cc344e5c2cadceab4eb03d0010d","tests/executor/mod.rs":"620975b33cc2a494efb6bce230cf285a462b85e5fe12d71561b5bacd9d507b28","tests/test.rs":"78dcb0b36fa1351dd97f1d415889e1178799667ffef70daa115695ee99758e71","tests/ui/bare-trait-object.rs":"4546e8bd6682de11920fa4c768295fed61954484ef0550dfadbc5677b77f29a5","tests/ui/bare-trait-object.stderr":"b63287594e6e5183e9b5b0e701fc4dd3a9b4fb0ea93eb910be56166e5fa4cdbd","tests/ui/delimiter-span.rs":"5e11150b1448f4c5b88a08aa579a663606ccaaed7f302e9465b42fc3489f0f3e","tests/ui/delimiter-span.stderr":"a1d7ead68b8d01e6e51c0943ccd683fb5fb8c3eae2d56feb22b0ef777949b87d","tests/ui/missing-body.rs":"d06c0da8c6044e7c790b924136f167e2edc0d0d3fa01f23521f3f08ca605929b","tests/ui/missing-body.stderr":"636a03cc42933b59d73032ce6cea862e33c16efb9c7fe7f27749247998bc9f23","tests/ui/must-use.rs":"75090c7df984df0996464337f60371d198bd0caf3f9f44b10d1e131f15fd4fca","tests/ui/must-use.stderr":"e6cb190e02f0226df6444065aaca3051f7db8ae599bba18a685155c52bb799b6","tests/ui/self-span.rs":"67ddde05907d7014bfb3f2c63d427b1d72d6c4369a9108a4335dac6bee5832b2","tests/ui/self-span.stderr":"8f473640c732ce66656f7da611c8173c3f8719ad90fa42d7043bb037f43964ea","tests/ui/send-not-implemented.rs":"5f1dd26f4eb34c653048e9658fbf6b41e2930d6222869b397ca4d8d7113a2809","tests/ui/send-not-implemented.stderr":"f7ea7ed8fe196c4bfc27c028ea3e1c0253e05e45e082454dbfba7ef0655d3fa6","tests/ui/unsupported-self.rs":"f7855bc39dab1fd2f533fb2e873a27c3757dcb9fb57001e4b19f58d3dda36d01","tests/ui/unsupported-self.stderr":"2b30517b790c666ea85442afc1c701ddc235d091372e175009aa084bd57b7070"},"package":"8d3a45e77e34375a7923b1e8febb049bb011f064714a8e17a1a616fef01da13d"}
|
||||
{"files":{"Cargo.toml":"fda2e0dc95a93f95edaa7dfdf9b7323593214c1b9e165789cd8b8e6057349ecb","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"23f18e03dc49df91622fe2a76176497404e46ced8a715d9d2b67a7446571cca3","README.md":"b733a7cddbdc409fcd5fb8eff5fe1d5692b6d1e0364568366a69bb1dd68e232c","build.rs":"e2ca6b6c6f18d5d47cb662083856d1399946bc41a272b30231c31ae8317a3ed0","src/args.rs":"6eed5497db91752b3aae597943c39e769f60406b37055304e69e4699f1f87b15","src/expand.rs":"231d1e732f295949939583df7169f49f950317679e7415ee6b5d38b8414f8b7b","src/lib.rs":"51cd49b85c0a7662ef32f30631f1f6a2ce448f18e951725b9d13227b5a596d3e","src/lifetime.rs":"4b94740e2847ef8df128a25d264f0a1bc1d1723ea107fc53849322b98f1e6927","src/parse.rs":"cd9032fe2c6dcf41050b3a59b9fb98eb9700a29bbe2fa011ee2854014c1666b7","src/receiver.rs":"31f5ff929bb6ac061ca3f44d4efac1ca0c60273d54ef8f8f92234a69829dc88d","tests/compiletest.rs":"0a52a44786aea1c299c695bf948b2ed2081e4cc344e5c2cadceab4eb03d0010d","tests/executor/mod.rs":"3cf48614288715f625514a73ae642f649c2635a402a3ad90278bbee116a7234c","tests/test.rs":"8a60ea2181287bfd42bcc73df1d157398f202f60991ec91eb906029e3a1ae88b","tests/ui/bare-trait-object.rs":"4546e8bd6682de11920fa4c768295fed61954484ef0550dfadbc5677b77f29a5","tests/ui/bare-trait-object.stderr":"fd6f80e2cae790f6370c537eaabedb17e9ff06c2b1f056d3d7071ed7f021f831","tests/ui/delimiter-span.rs":"97edf38c804d5e0d4cef6f040dee113d78ff76b08bf8c49586b803caa3ce7f40","tests/ui/delimiter-span.stderr":"f3c32ae57ead984ac985641bd07f50a894b572d6b8b8269556cf606f34d05101","tests/ui/lifetime-span.rs":"263de0b98abd0772fe9dc73ced1a71a3b85efb90d2b208226fe35ab9378c5e5a","tests/ui/lifetime-span.stderr":"1e1cbcbbfded1da0a252666f2077d806d11e16fccea825c7d58805c1d88a9d58","tests/ui/missing-body.rs":"d06c0da8c6044e7c790b924136f167e2edc0d0d3fa01f23521f3f08ca605929b","tests/ui/missing-body.stderr":"636a03cc42933b59d73032ce6cea862e33c16efb9c7fe7f27749247998bc9f23","tests/ui/must-use.rs":"75090c7df984df0996464337f60371d198bd0caf3f9f44b10d1e131f15fd4fca","tests/ui/must-use.stderr":"e6cb190e02f0226df6444065aaca3051f7db8ae599bba18a685155c52bb799b6","tests/ui/self-span.rs":"67ddde05907d7014bfb3f2c63d427b1d72d6c4369a9108a4335dac6bee5832b2","tests/ui/self-span.stderr":"590ba1db336f57133b66b83a576afa6f96f2201147b9c90eea4bdc84b966b19c","tests/ui/send-not-implemented.rs":"affbbe8bc9c3501d3db3a024e06daa9d076f1d142dba290c7aa1ea119daebd19","tests/ui/send-not-implemented.stderr":"63ed733b35b71f29ff0e863d287049e831dd0923978d16f5679ebd4d9d1c6d69","tests/ui/unreachable.rs":"7905c3fd0115753d18d64e12c39f42f3abec7a41b02572ea009c7d93f6d7751d","tests/ui/unreachable.stderr":"1fe3a63e44a99c62c489e1994176f03c2218bf382439bc20f1f12d368fe1558a","tests/ui/unsupported-self.rs":"f7855bc39dab1fd2f533fb2e873a27c3757dcb9fb57001e4b19f58d3dda36d01","tests/ui/unsupported-self.stderr":"be1893e21e626f0f76d16799bf27ad12df304384245462515e1fa63f06a83d80"},"package":"44318e776df68115a881de9a8fd1b9e53368d7a4a5ce4cc48517da3393233a5e"}
|
|
@ -3,21 +3,21 @@
|
|||
# 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
|
||||
# to registry (e.g., crates.io) dependencies.
|
||||
#
|
||||
# If you believe there's an error in this file please file an
|
||||
# issue against the rust-lang/cargo repository. If you're
|
||||
# editing this file be aware that the upstream Cargo.toml
|
||||
# will likely look very different (and much more reasonable)
|
||||
# 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 = "async-trait"
|
||||
version = "0.1.42"
|
||||
version = "0.1.51"
|
||||
authors = ["David Tolnay <dtolnay@gmail.com>"]
|
||||
description = "Type erasure for async trait methods"
|
||||
documentation = "https://docs.rs/async-trait"
|
||||
readme = "README.md"
|
||||
keywords = ["async"]
|
||||
license = "MIT OR Apache-2.0"
|
||||
repository = "https://github.com/dtolnay/async-trait"
|
||||
[package.metadata.docs.rs]
|
||||
|
@ -32,8 +32,11 @@ version = "1.0"
|
|||
version = "1.0"
|
||||
|
||||
[dependencies.syn]
|
||||
version = "1.0"
|
||||
version = "1.0.61"
|
||||
features = ["full", "visit-mut"]
|
||||
[dev-dependencies.futures]
|
||||
version = "0.3"
|
||||
|
||||
[dev-dependencies.rustversion]
|
||||
version = "1.0"
|
||||
|
||||
|
@ -41,10 +44,7 @@ version = "1.0"
|
|||
version = "0.1.14"
|
||||
|
||||
[dev-dependencies.tracing-attributes]
|
||||
version = "0.1.8"
|
||||
|
||||
[dev-dependencies.tracing-futures]
|
||||
version = "0.2"
|
||||
version = "0.1.14"
|
||||
|
||||
[dev-dependencies.trybuild]
|
||||
version = "1.0.19"
|
||||
|
|
|
@ -217,7 +217,7 @@ error: the trait `Test` cannot be made into an object
|
|||
For traits that need to be object safe and need to have default implementations
|
||||
for some async methods, there are two resolutions. Either you can add Send
|
||||
and/or Sync as supertraits (Send if there are `&mut self` methods with default
|
||||
implementations, Sync if there are `&self` methods with default implementions)
|
||||
implementations, Sync if there are `&self` methods with default implementations)
|
||||
to constrain all implementors of the trait such that the default implementations
|
||||
are applicable to them:
|
||||
|
||||
|
|
|
@ -0,0 +1,25 @@
|
|||
use std::env;
|
||||
use std::process::Command;
|
||||
use std::str;
|
||||
|
||||
fn main() {
|
||||
let compiler = match rustc_minor_version() {
|
||||
Some(compiler) => compiler,
|
||||
None => return,
|
||||
};
|
||||
|
||||
if compiler < 47 {
|
||||
println!("cargo:rustc-cfg=self_span_hack");
|
||||
}
|
||||
}
|
||||
|
||||
fn rustc_minor_version() -> Option<u32> {
|
||||
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;
|
||||
}
|
||||
pieces.next()?.parse().ok()
|
||||
}
|
|
@ -1,19 +1,23 @@
|
|||
use crate::lifetime::{has_async_lifetime, CollectLifetimes};
|
||||
use crate::lifetime::CollectLifetimes;
|
||||
use crate::parse::Item;
|
||||
use crate::receiver::{
|
||||
has_self_in_block, has_self_in_sig, has_self_in_where_predicate, ReplaceReceiver,
|
||||
};
|
||||
use proc_macro2::{Span, TokenStream};
|
||||
use crate::receiver::{has_self_in_block, has_self_in_sig, mut_pat, ReplaceSelf};
|
||||
use proc_macro2::TokenStream;
|
||||
use quote::{format_ident, quote, quote_spanned, ToTokens};
|
||||
use std::mem;
|
||||
use std::collections::BTreeSet as Set;
|
||||
use syn::punctuated::Punctuated;
|
||||
use syn::visit_mut::VisitMut;
|
||||
use syn::visit_mut::{self, VisitMut};
|
||||
use syn::{
|
||||
parse_quote, Block, FnArg, GenericParam, Generics, Ident, ImplItem, Lifetime, Pat, PatIdent,
|
||||
Path, Receiver, ReturnType, Signature, Stmt, Token, TraitItem, Type, TypeParam, TypeParamBound,
|
||||
WhereClause,
|
||||
parse_quote, Attribute, Block, FnArg, GenericParam, Generics, Ident, ImplItem, Lifetime, Pat,
|
||||
PatIdent, Receiver, ReturnType, Signature, Stmt, Token, TraitItem, Type, TypeParamBound,
|
||||
TypePath, WhereClause,
|
||||
};
|
||||
|
||||
macro_rules! parse_quote_spanned {
|
||||
($span:expr=> $($t:tt)*) => {
|
||||
syn::parse2(quote_spanned!($span=> $($t)*)).unwrap()
|
||||
};
|
||||
}
|
||||
|
||||
impl ToTokens for Item {
|
||||
fn to_tokens(&self, tokens: &mut TokenStream) {
|
||||
match self {
|
||||
|
@ -26,14 +30,12 @@ impl ToTokens for Item {
|
|||
#[derive(Clone, Copy)]
|
||||
enum Context<'a> {
|
||||
Trait {
|
||||
name: &'a Ident,
|
||||
generics: &'a Generics,
|
||||
supertraits: &'a Supertraits,
|
||||
},
|
||||
Impl {
|
||||
impl_generics: &'a Generics,
|
||||
receiver: &'a Type,
|
||||
as_trait: &'a Path,
|
||||
associated_type_impl_traits: &'a Set<Ident>,
|
||||
},
|
||||
}
|
||||
|
||||
|
@ -59,7 +61,6 @@ pub fn expand(input: &mut Item, is_local: bool) {
|
|||
match input {
|
||||
Item::Trait(input) => {
|
||||
let context = Context::Trait {
|
||||
name: &input.ident,
|
||||
generics: &input.generics,
|
||||
supertraits: &input.supertraits,
|
||||
};
|
||||
|
@ -69,32 +70,40 @@ pub fn expand(input: &mut Item, is_local: bool) {
|
|||
if sig.asyncness.is_some() {
|
||||
let block = &mut method.default;
|
||||
let mut has_self = has_self_in_sig(sig);
|
||||
method.attrs.push(parse_quote!(#[must_use]));
|
||||
if let Some(block) = block {
|
||||
has_self |= has_self_in_block(block);
|
||||
transform_block(context, sig, block, has_self, is_local);
|
||||
method
|
||||
.attrs
|
||||
.push(parse_quote!(#[allow(clippy::used_underscore_binding)]));
|
||||
transform_block(context, sig, block);
|
||||
method.attrs.push(lint_suppress_with_body());
|
||||
} else {
|
||||
method.attrs.push(lint_suppress_without_body());
|
||||
}
|
||||
let has_default = method.default.is_some();
|
||||
transform_sig(context, sig, has_self, has_default, is_local);
|
||||
method.attrs.push(parse_quote!(#[must_use]));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Item::Impl(input) => {
|
||||
let mut lifetimes = CollectLifetimes::new("'impl");
|
||||
let mut lifetimes = CollectLifetimes::new("'impl", input.impl_token.span);
|
||||
lifetimes.visit_type_mut(&mut *input.self_ty);
|
||||
lifetimes.visit_path_mut(&mut input.trait_.as_mut().unwrap().1);
|
||||
let params = &input.generics.params;
|
||||
let elided = lifetimes.elided;
|
||||
input.generics.params = parse_quote!(#(#elided,)* #params);
|
||||
|
||||
let mut associated_type_impl_traits = Set::new();
|
||||
for inner in &input.items {
|
||||
if let ImplItem::Type(assoc) = inner {
|
||||
if let Type::ImplTrait(_) = assoc.ty {
|
||||
associated_type_impl_traits.insert(assoc.ident.clone());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let context = Context::Impl {
|
||||
impl_generics: &input.generics,
|
||||
receiver: &input.self_ty,
|
||||
as_trait: &input.trait_.as_ref().unwrap().1,
|
||||
associated_type_impl_traits: &associated_type_impl_traits,
|
||||
};
|
||||
for inner in &mut input.items {
|
||||
if let ImplItem::Method(method) = inner {
|
||||
|
@ -102,11 +111,9 @@ pub fn expand(input: &mut Item, is_local: bool) {
|
|||
if sig.asyncness.is_some() {
|
||||
let block = &mut method.block;
|
||||
let has_self = has_self_in_sig(sig) || has_self_in_block(block);
|
||||
transform_block(context, sig, block, has_self, is_local);
|
||||
transform_block(context, sig, block);
|
||||
transform_sig(context, sig, has_self, false, is_local);
|
||||
method
|
||||
.attrs
|
||||
.push(parse_quote!(#[allow(clippy::used_underscore_binding)]));
|
||||
method.attrs.push(lint_suppress_with_body());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -114,6 +121,26 @@ pub fn expand(input: &mut Item, is_local: bool) {
|
|||
}
|
||||
}
|
||||
|
||||
fn lint_suppress_with_body() -> Attribute {
|
||||
parse_quote! {
|
||||
#[allow(
|
||||
clippy::let_unit_value,
|
||||
clippy::type_complexity,
|
||||
clippy::type_repetition_in_bounds,
|
||||
clippy::used_underscore_binding
|
||||
)]
|
||||
}
|
||||
}
|
||||
|
||||
fn lint_suppress_without_body() -> Attribute {
|
||||
parse_quote! {
|
||||
#[allow(
|
||||
clippy::type_complexity,
|
||||
clippy::type_repetition_in_bounds
|
||||
)]
|
||||
}
|
||||
}
|
||||
|
||||
// Input:
|
||||
// async fn f<T>(&self, x: &T) -> Ret;
|
||||
//
|
||||
|
@ -141,7 +168,13 @@ fn transform_sig(
|
|||
ReturnType::Type(_, ret) => quote!(#ret),
|
||||
};
|
||||
|
||||
let mut lifetimes = CollectLifetimes::new("'life");
|
||||
let default_span = sig
|
||||
.ident
|
||||
.span()
|
||||
.join(sig.paren_token.span)
|
||||
.unwrap_or_else(|| sig.ident.span());
|
||||
|
||||
let mut lifetimes = CollectLifetimes::new("'life", default_span);
|
||||
for arg in sig.inputs.iter_mut() {
|
||||
match arg {
|
||||
FnArg::Receiver(arg) => lifetimes.visit_receiver_mut(arg),
|
||||
|
@ -149,13 +182,6 @@ fn transform_sig(
|
|||
}
|
||||
}
|
||||
|
||||
let where_clause = sig
|
||||
.generics
|
||||
.where_clause
|
||||
.get_or_insert_with(|| WhereClause {
|
||||
where_token: Default::default(),
|
||||
predicates: Punctuated::new(),
|
||||
});
|
||||
for param in sig
|
||||
.generics
|
||||
.params
|
||||
|
@ -165,33 +191,48 @@ fn transform_sig(
|
|||
match param {
|
||||
GenericParam::Type(param) => {
|
||||
let param = ¶m.ident;
|
||||
where_clause
|
||||
let span = param.span();
|
||||
where_clause_or_default(&mut sig.generics.where_clause)
|
||||
.predicates
|
||||
.push(parse_quote!(#param: 'async_trait));
|
||||
.push(parse_quote_spanned!(span=> #param: 'async_trait));
|
||||
}
|
||||
GenericParam::Lifetime(param) => {
|
||||
let param = ¶m.lifetime;
|
||||
where_clause
|
||||
let span = param.span();
|
||||
where_clause_or_default(&mut sig.generics.where_clause)
|
||||
.predicates
|
||||
.push(parse_quote!(#param: 'async_trait));
|
||||
.push(parse_quote_spanned!(span=> #param: 'async_trait));
|
||||
}
|
||||
GenericParam::Const(_) => {}
|
||||
}
|
||||
}
|
||||
|
||||
if sig.generics.lt_token.is_none() {
|
||||
sig.generics.lt_token = Some(Token![<](sig.ident.span()));
|
||||
}
|
||||
if sig.generics.gt_token.is_none() {
|
||||
sig.generics.gt_token = Some(Token![>](sig.paren_token.span));
|
||||
}
|
||||
|
||||
for elided in lifetimes.elided {
|
||||
sig.generics.params.push(parse_quote!(#elided));
|
||||
where_clause
|
||||
where_clause_or_default(&mut sig.generics.where_clause)
|
||||
.predicates
|
||||
.push(parse_quote!(#elided: 'async_trait));
|
||||
.push(parse_quote_spanned!(elided.span()=> #elided: 'async_trait));
|
||||
}
|
||||
sig.generics.params.push(parse_quote!('async_trait));
|
||||
|
||||
sig.generics
|
||||
.params
|
||||
.push(parse_quote_spanned!(default_span=> 'async_trait));
|
||||
|
||||
if has_self {
|
||||
let bound: Ident = match sig.inputs.iter().next() {
|
||||
let bound_span = sig.ident.span();
|
||||
let bound = match sig.inputs.iter().next() {
|
||||
Some(FnArg::Receiver(Receiver {
|
||||
reference: Some(_),
|
||||
mutability: None,
|
||||
..
|
||||
})) => parse_quote!(Sync),
|
||||
})) => Ident::new("Sync", bound_span),
|
||||
Some(FnArg::Typed(arg))
|
||||
if match (arg.pat.as_ref(), arg.ty.as_ref()) {
|
||||
(Pat::Ident(pat), Type::Reference(ty)) => {
|
||||
|
@ -200,18 +241,21 @@ fn transform_sig(
|
|||
_ => false,
|
||||
} =>
|
||||
{
|
||||
parse_quote!(Sync)
|
||||
Ident::new("Sync", bound_span)
|
||||
}
|
||||
_ => parse_quote!(Send),
|
||||
_ => Ident::new("Send", bound_span),
|
||||
};
|
||||
|
||||
let assume_bound = match context {
|
||||
Context::Trait { supertraits, .. } => !has_default || has_bound(supertraits, &bound),
|
||||
Context::Impl { .. } => true,
|
||||
};
|
||||
|
||||
let where_clause = where_clause_or_default(&mut sig.generics.where_clause);
|
||||
where_clause.predicates.push(if assume_bound || is_local {
|
||||
parse_quote!(Self: 'async_trait)
|
||||
parse_quote_spanned!(bound_span=> Self: 'async_trait)
|
||||
} else {
|
||||
parse_quote!(Self: ::core::marker::#bound + 'async_trait)
|
||||
parse_quote_spanned!(bound_span=> Self: ::core::marker::#bound + 'async_trait)
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -226,20 +270,21 @@ fn transform_sig(
|
|||
ident.by_ref = None;
|
||||
ident.mutability = None;
|
||||
} else {
|
||||
let positional = positional_arg(i);
|
||||
*arg.pat = parse_quote!(#positional);
|
||||
let positional = positional_arg(i, &arg.pat);
|
||||
let m = mut_pat(&mut arg.pat);
|
||||
arg.pat = parse_quote!(#m #positional);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let ret_span = sig.ident.span();
|
||||
let bounds = if is_local {
|
||||
quote!('async_trait)
|
||||
quote_spanned!(ret_span=> 'async_trait)
|
||||
} else {
|
||||
quote!(::core::marker::Send + 'async_trait)
|
||||
quote_spanned!(ret_span=> ::core::marker::Send + 'async_trait)
|
||||
};
|
||||
|
||||
sig.output = parse_quote! {
|
||||
sig.output = parse_quote_spanned! {ret_span=>
|
||||
-> ::core::pin::Pin<Box<
|
||||
dyn ::core::future::Future<Output = #ret> + #bounds
|
||||
>>
|
||||
|
@ -247,256 +292,162 @@ fn transform_sig(
|
|||
}
|
||||
|
||||
// Input:
|
||||
// async fn f<T>(&self, x: &T) -> Ret {
|
||||
// self + x
|
||||
// async fn f<T>(&self, x: &T, (a, b): (A, B)) -> Ret {
|
||||
// self + x + a + b
|
||||
// }
|
||||
//
|
||||
// Output:
|
||||
// async fn f<T, AsyncTrait>(_self: &AsyncTrait, x: &T) -> Ret {
|
||||
// _self + x
|
||||
// }
|
||||
// Box::pin(async_trait_method::<T, Self>(self, x))
|
||||
fn transform_block(
|
||||
context: Context,
|
||||
sig: &mut Signature,
|
||||
block: &mut Block,
|
||||
has_self: bool,
|
||||
is_local: bool,
|
||||
) {
|
||||
// Box::pin(async move {
|
||||
// let ___ret: Ret = {
|
||||
// let __self = self;
|
||||
// let x = x;
|
||||
// let (a, b) = __arg1;
|
||||
//
|
||||
// __self + x + a + b
|
||||
// };
|
||||
//
|
||||
// ___ret
|
||||
// })
|
||||
fn transform_block(context: Context, sig: &mut Signature, block: &mut Block) {
|
||||
if let Some(Stmt::Item(syn::Item::Verbatim(item))) = block.stmts.first() {
|
||||
if block.stmts.len() == 1 && item.to_string() == ";" {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
let inner = format_ident!("__{}", sig.ident);
|
||||
let args = sig.inputs.iter().enumerate().map(|(i, arg)| match arg {
|
||||
FnArg::Receiver(Receiver { self_token, .. }) => quote!(#self_token),
|
||||
FnArg::Typed(arg) => {
|
||||
if let Pat::Ident(PatIdent { ident, .. }) = &*arg.pat {
|
||||
quote!(#ident)
|
||||
} else {
|
||||
positional_arg(i).into_token_stream()
|
||||
let mut self_span = None;
|
||||
let decls = sig
|
||||
.inputs
|
||||
.iter()
|
||||
.enumerate()
|
||||
.map(|(i, arg)| match arg {
|
||||
FnArg::Receiver(Receiver {
|
||||
self_token,
|
||||
mutability,
|
||||
..
|
||||
}) => {
|
||||
let ident = Ident::new("__self", self_token.span);
|
||||
self_span = Some(self_token.span);
|
||||
quote!(let #mutability #ident = #self_token;)
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
let mut standalone = sig.clone();
|
||||
standalone.ident = inner.clone();
|
||||
|
||||
let generics = match context {
|
||||
Context::Trait { generics, .. } => generics,
|
||||
Context::Impl { impl_generics, .. } => impl_generics,
|
||||
};
|
||||
|
||||
let mut outer_generics = generics.clone();
|
||||
for p in &mut outer_generics.params {
|
||||
match p {
|
||||
GenericParam::Type(t) => t.default = None,
|
||||
GenericParam::Const(c) => c.default = None,
|
||||
GenericParam::Lifetime(_) => {}
|
||||
}
|
||||
}
|
||||
if !has_self {
|
||||
if let Some(mut where_clause) = outer_generics.where_clause {
|
||||
where_clause.predicates = where_clause
|
||||
.predicates
|
||||
.into_iter()
|
||||
.filter_map(|mut pred| {
|
||||
if has_self_in_where_predicate(&mut pred) {
|
||||
None
|
||||
FnArg::Typed(arg) => {
|
||||
if let Pat::Ident(PatIdent {
|
||||
ident, mutability, ..
|
||||
}) = &*arg.pat
|
||||
{
|
||||
if ident == "self" {
|
||||
self_span = Some(ident.span());
|
||||
let prefixed = Ident::new("__self", ident.span());
|
||||
quote!(let #mutability #prefixed = #ident;)
|
||||
} else {
|
||||
Some(pred)
|
||||
quote!(let #mutability #ident = #ident;)
|
||||
}
|
||||
})
|
||||
.collect();
|
||||
outer_generics.where_clause = Some(where_clause);
|
||||
}
|
||||
}
|
||||
|
||||
let fn_generics = mem::replace(&mut standalone.generics, outer_generics);
|
||||
standalone.generics.params.extend(fn_generics.params);
|
||||
if let Some(where_clause) = fn_generics.where_clause {
|
||||
standalone
|
||||
.generics
|
||||
.make_where_clause()
|
||||
.predicates
|
||||
.extend(where_clause.predicates);
|
||||
}
|
||||
|
||||
if has_async_lifetime(&mut standalone, block) {
|
||||
standalone.generics.params.push(parse_quote!('async_trait));
|
||||
}
|
||||
|
||||
let mut types = standalone
|
||||
.generics
|
||||
.type_params()
|
||||
.map(|param| param.ident.clone())
|
||||
} else {
|
||||
let pat = &arg.pat;
|
||||
let ident = positional_arg(i, pat);
|
||||
quote!(let #pat = #ident;)
|
||||
}
|
||||
}
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
let mut self_bound = None::<TypeParamBound>;
|
||||
match standalone.inputs.iter_mut().next() {
|
||||
Some(
|
||||
arg @ FnArg::Receiver(Receiver {
|
||||
reference: Some(_), ..
|
||||
}),
|
||||
) => {
|
||||
let (lifetime, mutability, self_token) = match arg {
|
||||
FnArg::Receiver(Receiver {
|
||||
reference: Some((_, lifetime)),
|
||||
mutability,
|
||||
self_token,
|
||||
..
|
||||
}) => (lifetime, mutability, self_token),
|
||||
_ => unreachable!(),
|
||||
};
|
||||
let under_self = Ident::new("_self", self_token.span);
|
||||
match context {
|
||||
Context::Trait { .. } => {
|
||||
self_bound = Some(match mutability {
|
||||
Some(_) => parse_quote!(::core::marker::Send),
|
||||
None => parse_quote!(::core::marker::Sync),
|
||||
});
|
||||
*arg = parse_quote! {
|
||||
#under_self: &#lifetime #mutability AsyncTrait
|
||||
};
|
||||
if let Some(span) = self_span {
|
||||
let mut replace_self = ReplaceSelf(span);
|
||||
replace_self.visit_block_mut(block);
|
||||
}
|
||||
|
||||
let stmts = &block.stmts;
|
||||
let let_ret = match &mut sig.output {
|
||||
ReturnType::Default => quote_spanned! {block.brace_token.span=>
|
||||
#(#decls)*
|
||||
let _: () = { #(#stmts)* };
|
||||
},
|
||||
ReturnType::Type(_, ret) => {
|
||||
if contains_associated_type_impl_trait(context, ret) {
|
||||
if decls.is_empty() {
|
||||
quote!(#(#stmts)*)
|
||||
} else {
|
||||
quote!(#(#decls)* { #(#stmts)* })
|
||||
}
|
||||
Context::Impl { receiver, .. } => {
|
||||
let mut ty = quote!(#receiver);
|
||||
if let Type::TraitObject(trait_object) = receiver {
|
||||
if trait_object.dyn_token.is_none() {
|
||||
ty = quote!(dyn #ty);
|
||||
}
|
||||
if trait_object.bounds.len() > 1 {
|
||||
ty = quote!((#ty));
|
||||
}
|
||||
} else {
|
||||
quote_spanned! {block.brace_token.span=>
|
||||
if let ::core::option::Option::Some(__ret) = ::core::option::Option::None::<#ret> {
|
||||
return __ret;
|
||||
}
|
||||
*arg = parse_quote! {
|
||||
#under_self: &#lifetime #mutability #ty
|
||||
};
|
||||
#(#decls)*
|
||||
let __ret: #ret = { #(#stmts)* };
|
||||
#[allow(unreachable_code)]
|
||||
__ret
|
||||
}
|
||||
}
|
||||
}
|
||||
Some(arg @ FnArg::Receiver(_)) => {
|
||||
let (self_token, mutability) = match arg {
|
||||
FnArg::Receiver(Receiver {
|
||||
self_token,
|
||||
mutability,
|
||||
..
|
||||
}) => (self_token, mutability),
|
||||
_ => unreachable!(),
|
||||
};
|
||||
let under_self = Ident::new("_self", self_token.span);
|
||||
match context {
|
||||
Context::Trait { .. } => {
|
||||
self_bound = Some(parse_quote!(::core::marker::Send));
|
||||
*arg = parse_quote! {
|
||||
#mutability #under_self: AsyncTrait
|
||||
};
|
||||
}
|
||||
Context::Impl { receiver, .. } => {
|
||||
*arg = parse_quote! {
|
||||
#mutability #under_self: #receiver
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
Some(FnArg::Typed(arg)) => {
|
||||
if let Pat::Ident(arg) = &mut *arg.pat {
|
||||
if arg.ident == "self" {
|
||||
arg.ident = Ident::new("_self", arg.ident.span());
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
||||
if let Context::Trait { name, generics, .. } = context {
|
||||
if has_self {
|
||||
let (_, generics, _) = generics.split_for_impl();
|
||||
let mut self_param: TypeParam = parse_quote!(AsyncTrait: ?Sized + #name #generics);
|
||||
if !is_local {
|
||||
self_param.bounds.extend(self_bound);
|
||||
}
|
||||
let count = standalone
|
||||
.generics
|
||||
.params
|
||||
.iter()
|
||||
.take_while(|param| {
|
||||
if let GenericParam::Const(_) = param {
|
||||
false
|
||||
} else {
|
||||
true
|
||||
}
|
||||
})
|
||||
.count();
|
||||
standalone
|
||||
.generics
|
||||
.params
|
||||
.insert(count, GenericParam::Type(self_param));
|
||||
types.push(Ident::new("Self", Span::call_site()));
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(where_clause) = &mut standalone.generics.where_clause {
|
||||
// Work around an input bound like `where Self::Output: Send` expanding
|
||||
// to `where <AsyncTrait>::Output: Send` which is illegal syntax because
|
||||
// `where<T>` is reserved for future use... :(
|
||||
where_clause.predicates.insert(0, parse_quote!((): Sized));
|
||||
}
|
||||
|
||||
let mut replace = match context {
|
||||
Context::Trait { .. } => ReplaceReceiver::with(parse_quote!(AsyncTrait)),
|
||||
Context::Impl {
|
||||
receiver, as_trait, ..
|
||||
} => ReplaceReceiver::with_as_trait(receiver.clone(), as_trait.clone()),
|
||||
};
|
||||
replace.visit_signature_mut(&mut standalone);
|
||||
replace.visit_block_mut(block);
|
||||
|
||||
let mut generics = types;
|
||||
let consts = standalone
|
||||
.generics
|
||||
.const_params()
|
||||
.map(|param| param.ident.clone());
|
||||
generics.extend(consts);
|
||||
|
||||
let allow_non_snake_case = if sig.ident != sig.ident.to_string().to_lowercase() {
|
||||
Some(quote!(non_snake_case,))
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
let brace = block.brace_token;
|
||||
let box_pin = quote_spanned!(brace.span=> {
|
||||
#[allow(
|
||||
#allow_non_snake_case
|
||||
unused_parens, // https://github.com/dtolnay/async-trait/issues/118
|
||||
clippy::missing_docs_in_private_items,
|
||||
clippy::needless_lifetimes,
|
||||
clippy::ptr_arg,
|
||||
clippy::trivially_copy_pass_by_ref,
|
||||
clippy::type_repetition_in_bounds,
|
||||
clippy::used_underscore_binding,
|
||||
)]
|
||||
#standalone #block
|
||||
Box::pin(#inner::<#(#generics),*>(#(#args),*))
|
||||
});
|
||||
*block = parse_quote!(#box_pin);
|
||||
block.brace_token = brace;
|
||||
let box_pin = quote_spanned!(block.brace_token.span=>
|
||||
Box::pin(async move { #let_ret })
|
||||
);
|
||||
block.stmts = parse_quote!(#box_pin);
|
||||
}
|
||||
|
||||
fn positional_arg(i: usize) -> Ident {
|
||||
format_ident!("__arg{}", i)
|
||||
fn positional_arg(i: usize, pat: &Pat) -> Ident {
|
||||
use syn::spanned::Spanned;
|
||||
format_ident!("__arg{}", i, span = pat.span())
|
||||
}
|
||||
|
||||
fn has_bound(supertraits: &Supertraits, marker: &Ident) -> bool {
|
||||
for bound in supertraits {
|
||||
if let TypeParamBound::Trait(bound) = bound {
|
||||
if bound.path.is_ident(marker) {
|
||||
if bound.path.is_ident(marker)
|
||||
|| bound.path.segments.len() == 3
|
||||
&& (bound.path.segments[0].ident == "std"
|
||||
|| bound.path.segments[0].ident == "core")
|
||||
&& bound.path.segments[1].ident == "marker"
|
||||
&& bound.path.segments[2].ident == *marker
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
false
|
||||
}
|
||||
|
||||
fn contains_associated_type_impl_trait(context: Context, ret: &mut Type) -> bool {
|
||||
struct AssociatedTypeImplTraits<'a> {
|
||||
set: &'a Set<Ident>,
|
||||
contains: bool,
|
||||
}
|
||||
|
||||
impl<'a> VisitMut for AssociatedTypeImplTraits<'a> {
|
||||
fn visit_type_path_mut(&mut self, ty: &mut TypePath) {
|
||||
if ty.qself.is_none()
|
||||
&& ty.path.segments.len() == 2
|
||||
&& ty.path.segments[0].ident == "Self"
|
||||
&& self.set.contains(&ty.path.segments[1].ident)
|
||||
{
|
||||
self.contains = true;
|
||||
}
|
||||
visit_mut::visit_type_path_mut(self, ty);
|
||||
}
|
||||
}
|
||||
|
||||
match context {
|
||||
Context::Trait { .. } => false,
|
||||
Context::Impl {
|
||||
associated_type_impl_traits,
|
||||
..
|
||||
} => {
|
||||
let mut visit = AssociatedTypeImplTraits {
|
||||
set: associated_type_impl_traits,
|
||||
contains: false,
|
||||
};
|
||||
visit.visit_type_mut(ret);
|
||||
visit.contains
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn where_clause_or_default(clause: &mut Option<WhereClause>) -> &mut WhereClause {
|
||||
clause.get_or_insert_with(|| WhereClause {
|
||||
where_token: Default::default(),
|
||||
predicates: Punctuated::new(),
|
||||
})
|
||||
}
|
||||
|
|
|
@ -259,7 +259,7 @@
|
|||
//! implementations for some async methods, there are two resolutions. Either
|
||||
//! you can add Send and/or Sync as supertraits (Send if there are `&mut self`
|
||||
//! methods with default implementations, Sync if there are `&self` methods with
|
||||
//! default implementions) to constrain all implementors of the trait such that
|
||||
//! default implementations) to constrain all implementors of the trait such that
|
||||
//! the default implementations are applicable to them:
|
||||
//!
|
||||
//! ```
|
||||
|
@ -303,7 +303,16 @@
|
|||
//! let object = &value as &dyn ObjectSafe;
|
||||
//! ```
|
||||
|
||||
#![allow(clippy::match_like_matches_macro)] // matches! requires Rust 1.42
|
||||
#![allow(
|
||||
clippy::default_trait_access,
|
||||
clippy::doc_markdown,
|
||||
clippy::if_not_else,
|
||||
clippy::items_after_statements,
|
||||
clippy::module_name_repetitions,
|
||||
clippy::shadow_unrelated,
|
||||
clippy::similar_names,
|
||||
clippy::too_many_lines
|
||||
)]
|
||||
|
||||
extern crate proc_macro;
|
||||
|
||||
|
@ -312,7 +321,6 @@ mod expand;
|
|||
mod lifetime;
|
||||
mod parse;
|
||||
mod receiver;
|
||||
mod respan;
|
||||
|
||||
use crate::args::Args;
|
||||
use crate::expand::expand;
|
||||
|
|
|
@ -1,59 +1,43 @@
|
|||
use proc_macro2::Span;
|
||||
use syn::visit_mut::{self, VisitMut};
|
||||
use syn::{Block, GenericArgument, Item, Lifetime, Receiver, Signature, TypeReference};
|
||||
|
||||
pub fn has_async_lifetime(sig: &mut Signature, block: &mut Block) -> bool {
|
||||
let mut visitor = HasAsyncLifetime(false);
|
||||
visitor.visit_signature_mut(sig);
|
||||
visitor.visit_block_mut(block);
|
||||
visitor.0
|
||||
}
|
||||
|
||||
struct HasAsyncLifetime(bool);
|
||||
|
||||
impl VisitMut for HasAsyncLifetime {
|
||||
fn visit_lifetime_mut(&mut self, life: &mut Lifetime) {
|
||||
self.0 |= life.to_string() == "'async_trait";
|
||||
}
|
||||
|
||||
fn visit_item_mut(&mut self, _: &mut Item) {
|
||||
// Do not recurse into nested items.
|
||||
}
|
||||
}
|
||||
use syn::{GenericArgument, Lifetime, Receiver, TypeReference};
|
||||
|
||||
pub struct CollectLifetimes {
|
||||
pub elided: Vec<Lifetime>,
|
||||
pub explicit: Vec<Lifetime>,
|
||||
pub name: &'static str,
|
||||
pub default_span: Span,
|
||||
}
|
||||
|
||||
impl CollectLifetimes {
|
||||
pub fn new(name: &'static str) -> Self {
|
||||
pub fn new(name: &'static str, default_span: Span) -> Self {
|
||||
CollectLifetimes {
|
||||
elided: Vec::new(),
|
||||
explicit: Vec::new(),
|
||||
name,
|
||||
default_span,
|
||||
}
|
||||
}
|
||||
|
||||
fn visit_opt_lifetime(&mut self, lifetime: &mut Option<Lifetime>) {
|
||||
match lifetime {
|
||||
None => *lifetime = Some(self.next_lifetime()),
|
||||
None => *lifetime = Some(self.next_lifetime(None)),
|
||||
Some(lifetime) => self.visit_lifetime(lifetime),
|
||||
}
|
||||
}
|
||||
|
||||
fn visit_lifetime(&mut self, lifetime: &mut Lifetime) {
|
||||
if lifetime.ident == "_" {
|
||||
*lifetime = self.next_lifetime();
|
||||
*lifetime = self.next_lifetime(lifetime.span());
|
||||
} else {
|
||||
self.explicit.push(lifetime.clone());
|
||||
}
|
||||
}
|
||||
|
||||
fn next_lifetime(&mut self) -> Lifetime {
|
||||
fn next_lifetime<S: Into<Option<Span>>>(&mut self, span: S) -> Lifetime {
|
||||
let name = format!("{}{}", self.name, self.elided.len());
|
||||
let life = Lifetime::new(&name, Span::call_site());
|
||||
let span = span.into().unwrap_or(self.default_span);
|
||||
let life = Lifetime::new(&name, span);
|
||||
self.elided.push(life.clone());
|
||||
life
|
||||
}
|
||||
|
|
|
@ -1,14 +1,9 @@
|
|||
use crate::respan::respan;
|
||||
use proc_macro2::{Group, Spacing, Span, TokenStream, TokenTree};
|
||||
use quote::{quote, quote_spanned};
|
||||
use proc_macro2::{Group, Span, TokenStream, TokenTree};
|
||||
use std::iter::FromIterator;
|
||||
use std::mem;
|
||||
use syn::punctuated::Punctuated;
|
||||
use syn::visit_mut::{self, VisitMut};
|
||||
use syn::{
|
||||
parse_quote, Block, Error, ExprPath, ExprStruct, Ident, Item, Macro, PatPath, PatStruct,
|
||||
PatTupleStruct, Path, PathArguments, QSelf, Receiver, Signature, Token, Type, TypePath,
|
||||
WherePredicate,
|
||||
Block, ExprPath, Ident, Item, Macro, Pat, PatIdent, PatPath, Path, Receiver, Signature, Token,
|
||||
TypePath,
|
||||
};
|
||||
|
||||
pub fn has_self_in_sig(sig: &mut Signature) -> bool {
|
||||
|
@ -17,12 +12,6 @@ pub fn has_self_in_sig(sig: &mut Signature) -> bool {
|
|||
visitor.0
|
||||
}
|
||||
|
||||
pub fn has_self_in_where_predicate(where_predicate: &mut WherePredicate) -> bool {
|
||||
let mut visitor = HasSelf(false);
|
||||
visitor.visit_where_predicate_mut(where_predicate);
|
||||
visitor.0
|
||||
}
|
||||
|
||||
pub fn has_self_in_block(block: &mut Block) -> bool {
|
||||
let mut visitor = HasSelf(false);
|
||||
visitor.visit_block_mut(block);
|
||||
|
@ -37,6 +26,32 @@ fn has_self_in_token_stream(tokens: TokenStream) -> bool {
|
|||
})
|
||||
}
|
||||
|
||||
pub fn mut_pat(pat: &mut Pat) -> Option<Token![mut]> {
|
||||
let mut visitor = HasMutPat(None);
|
||||
visitor.visit_pat_mut(pat);
|
||||
visitor.0
|
||||
}
|
||||
|
||||
fn contains_fn(tokens: TokenStream) -> bool {
|
||||
tokens.into_iter().any(|tt| match tt {
|
||||
TokenTree::Ident(ident) => ident == "fn",
|
||||
TokenTree::Group(group) => contains_fn(group.stream()),
|
||||
_ => false,
|
||||
})
|
||||
}
|
||||
|
||||
struct HasMutPat(Option<Token![mut]>);
|
||||
|
||||
impl VisitMut for HasMutPat {
|
||||
fn visit_pat_ident_mut(&mut self, i: &mut PatIdent) {
|
||||
if let Some(m) = i.mutability {
|
||||
self.0 = Some(m);
|
||||
} else {
|
||||
visit_mut::visit_pat_ident_mut(self, i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct HasSelf(bool);
|
||||
|
||||
impl VisitMut for HasSelf {
|
||||
|
@ -70,225 +85,84 @@ impl VisitMut for HasSelf {
|
|||
}
|
||||
}
|
||||
|
||||
pub struct ReplaceReceiver {
|
||||
pub with: Type,
|
||||
pub as_trait: Option<Path>,
|
||||
}
|
||||
pub struct ReplaceSelf(pub Span);
|
||||
|
||||
impl ReplaceReceiver {
|
||||
pub fn with(ty: Type) -> Self {
|
||||
ReplaceReceiver {
|
||||
with: ty,
|
||||
as_trait: None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn with_as_trait(ty: Type, as_trait: Path) -> Self {
|
||||
ReplaceReceiver {
|
||||
with: ty,
|
||||
as_trait: Some(as_trait),
|
||||
}
|
||||
}
|
||||
|
||||
fn self_ty(&self, span: Span) -> Type {
|
||||
respan(&self.with, span)
|
||||
}
|
||||
|
||||
fn self_to_qself_type(&self, qself: &mut Option<QSelf>, path: &mut Path) {
|
||||
let include_as_trait = true;
|
||||
self.self_to_qself(qself, path, include_as_trait);
|
||||
}
|
||||
|
||||
fn self_to_qself_expr(&self, qself: &mut Option<QSelf>, path: &mut Path) {
|
||||
let include_as_trait = false;
|
||||
self.self_to_qself(qself, path, include_as_trait);
|
||||
}
|
||||
|
||||
fn self_to_qself(&self, qself: &mut Option<QSelf>, path: &mut Path, include_as_trait: bool) {
|
||||
if path.leading_colon.is_some() {
|
||||
return;
|
||||
}
|
||||
|
||||
let first = &path.segments[0];
|
||||
if first.ident != "Self" || !first.arguments.is_empty() {
|
||||
return;
|
||||
}
|
||||
|
||||
if path.segments.len() == 1 {
|
||||
self.self_to_expr_path(path);
|
||||
return;
|
||||
}
|
||||
|
||||
let span = first.ident.span();
|
||||
*qself = Some(QSelf {
|
||||
lt_token: Token![<](span),
|
||||
ty: Box::new(self.self_ty(span)),
|
||||
position: 0,
|
||||
as_token: None,
|
||||
gt_token: Token![>](span),
|
||||
});
|
||||
|
||||
if include_as_trait && self.as_trait.is_some() {
|
||||
let as_trait = self.as_trait.as_ref().unwrap().clone();
|
||||
path.leading_colon = as_trait.leading_colon;
|
||||
qself.as_mut().unwrap().position = as_trait.segments.len();
|
||||
|
||||
let segments = mem::replace(&mut path.segments, as_trait.segments);
|
||||
path.segments.push_punct(Default::default());
|
||||
path.segments.extend(segments.into_pairs().skip(1));
|
||||
} else {
|
||||
path.leading_colon = Some(**path.segments.pairs().next().unwrap().punct().unwrap());
|
||||
|
||||
let segments = mem::replace(&mut path.segments, Punctuated::new());
|
||||
path.segments = segments.into_pairs().skip(1).collect();
|
||||
}
|
||||
}
|
||||
|
||||
fn self_to_expr_path(&self, path: &mut Path) {
|
||||
if path.leading_colon.is_some() {
|
||||
return;
|
||||
}
|
||||
|
||||
let first = &path.segments[0];
|
||||
if first.ident != "Self" || !first.arguments.is_empty() {
|
||||
return;
|
||||
}
|
||||
|
||||
if let Type::Path(self_ty) = self.self_ty(first.ident.span()) {
|
||||
let variant = mem::replace(path, self_ty.path);
|
||||
for segment in &mut path.segments {
|
||||
if let PathArguments::AngleBracketed(bracketed) = &mut segment.arguments {
|
||||
if bracketed.colon2_token.is_none() && !bracketed.args.is_empty() {
|
||||
bracketed.colon2_token = Some(Default::default());
|
||||
}
|
||||
}
|
||||
}
|
||||
if variant.segments.len() > 1 {
|
||||
path.segments.push_punct(Default::default());
|
||||
path.segments.extend(variant.segments.into_pairs().skip(1));
|
||||
}
|
||||
} else {
|
||||
let span = path.segments[0].ident.span();
|
||||
let msg = "Self type of this impl is unsupported in expression position";
|
||||
let error = Error::new(span, msg).to_compile_error();
|
||||
*path = parse_quote!(::core::marker::PhantomData::<#error>);
|
||||
}
|
||||
}
|
||||
|
||||
fn visit_token_stream(&self, tokens: &mut TokenStream) -> bool {
|
||||
let mut out = Vec::new();
|
||||
let mut modified = false;
|
||||
let mut iter = tokens.clone().into_iter().peekable();
|
||||
while let Some(tt) = iter.next() {
|
||||
match tt {
|
||||
TokenTree::Ident(mut ident) => {
|
||||
modified |= prepend_underscore_to_self(&mut ident);
|
||||
if ident == "Self" {
|
||||
modified = true;
|
||||
if self.as_trait.is_none() {
|
||||
let ident = Ident::new("AsyncTrait", ident.span());
|
||||
out.push(TokenTree::Ident(ident));
|
||||
} else {
|
||||
let self_ty = self.self_ty(ident.span());
|
||||
match iter.peek() {
|
||||
Some(TokenTree::Punct(p))
|
||||
if p.as_char() == ':' && p.spacing() == Spacing::Joint =>
|
||||
{
|
||||
let next = iter.next().unwrap();
|
||||
match iter.peek() {
|
||||
Some(TokenTree::Punct(p)) if p.as_char() == ':' => {
|
||||
let span = ident.span();
|
||||
out.extend(quote_spanned!(span=> <#self_ty>));
|
||||
}
|
||||
_ => out.extend(quote!(#self_ty)),
|
||||
}
|
||||
out.push(next);
|
||||
}
|
||||
_ => out.extend(quote!(#self_ty)),
|
||||
}
|
||||
}
|
||||
} else {
|
||||
out.push(TokenTree::Ident(ident));
|
||||
}
|
||||
}
|
||||
TokenTree::Group(group) => {
|
||||
let mut content = group.stream();
|
||||
modified |= self.visit_token_stream(&mut content);
|
||||
let mut new = Group::new(group.delimiter(), content);
|
||||
new.set_span(group.span());
|
||||
out.push(TokenTree::Group(new));
|
||||
}
|
||||
other => out.push(other),
|
||||
}
|
||||
}
|
||||
impl ReplaceSelf {
|
||||
#[cfg_attr(not(self_span_hack), allow(clippy::unused_self))]
|
||||
fn prepend_underscore_to_self(&self, ident: &mut Ident) -> bool {
|
||||
let modified = ident == "self";
|
||||
if modified {
|
||||
*tokens = TokenStream::from_iter(out);
|
||||
*ident = Ident::new("__self", ident.span());
|
||||
#[cfg(self_span_hack)]
|
||||
ident.set_span(self.0);
|
||||
}
|
||||
modified
|
||||
}
|
||||
|
||||
fn visit_token_stream(&mut self, tokens: &mut TokenStream) -> bool {
|
||||
let mut out = Vec::new();
|
||||
let mut modified = false;
|
||||
visit_token_stream_impl(self, tokens.clone(), &mut modified, &mut out);
|
||||
if modified {
|
||||
*tokens = TokenStream::from_iter(out);
|
||||
}
|
||||
return modified;
|
||||
|
||||
fn visit_token_stream_impl(
|
||||
visitor: &mut ReplaceSelf,
|
||||
tokens: TokenStream,
|
||||
modified: &mut bool,
|
||||
out: &mut Vec<TokenTree>,
|
||||
) {
|
||||
for tt in tokens {
|
||||
match tt {
|
||||
TokenTree::Ident(mut ident) => {
|
||||
*modified |= visitor.prepend_underscore_to_self(&mut ident);
|
||||
out.push(TokenTree::Ident(ident));
|
||||
}
|
||||
TokenTree::Group(group) => {
|
||||
let mut content = group.stream();
|
||||
*modified |= visitor.visit_token_stream(&mut content);
|
||||
let mut new = Group::new(group.delimiter(), content);
|
||||
new.set_span(group.span());
|
||||
out.push(TokenTree::Group(new));
|
||||
}
|
||||
other => out.push(other),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl VisitMut for ReplaceReceiver {
|
||||
// `Self` -> `Receiver`
|
||||
fn visit_type_mut(&mut self, ty: &mut Type) {
|
||||
if let Type::Path(node) = ty {
|
||||
if node.qself.is_none() && node.path.is_ident("Self") {
|
||||
*ty = self.self_ty(node.path.segments[0].ident.span());
|
||||
} else {
|
||||
self.visit_type_path_mut(node);
|
||||
}
|
||||
} else {
|
||||
visit_mut::visit_type_mut(self, ty);
|
||||
impl VisitMut for ReplaceSelf {
|
||||
fn visit_ident_mut(&mut self, i: &mut Ident) {
|
||||
self.prepend_underscore_to_self(i);
|
||||
}
|
||||
|
||||
fn visit_path_mut(&mut self, p: &mut Path) {
|
||||
if p.segments.len() == 1 {
|
||||
// Replace `self`, but not `self::function`.
|
||||
self.visit_ident_mut(&mut p.segments[0].ident);
|
||||
}
|
||||
}
|
||||
|
||||
// `Self::Assoc` -> `<Receiver>::Assoc`
|
||||
fn visit_type_path_mut(&mut self, ty: &mut TypePath) {
|
||||
if ty.qself.is_none() {
|
||||
self.self_to_qself_type(&mut ty.qself, &mut ty.path);
|
||||
for segment in &mut p.segments {
|
||||
self.visit_path_arguments_mut(&mut segment.arguments);
|
||||
}
|
||||
visit_mut::visit_type_path_mut(self, ty);
|
||||
}
|
||||
|
||||
// `Self::method` -> `<Receiver>::method`
|
||||
fn visit_expr_path_mut(&mut self, expr: &mut ExprPath) {
|
||||
if expr.qself.is_none() {
|
||||
prepend_underscore_to_self(&mut expr.path.segments[0].ident);
|
||||
self.self_to_qself_expr(&mut expr.qself, &mut expr.path);
|
||||
}
|
||||
visit_mut::visit_expr_path_mut(self, expr);
|
||||
}
|
||||
|
||||
fn visit_expr_struct_mut(&mut self, expr: &mut ExprStruct) {
|
||||
self.self_to_expr_path(&mut expr.path);
|
||||
visit_mut::visit_expr_struct_mut(self, expr);
|
||||
}
|
||||
|
||||
fn visit_pat_path_mut(&mut self, pat: &mut PatPath) {
|
||||
if pat.qself.is_none() {
|
||||
self.self_to_qself_expr(&mut pat.qself, &mut pat.path);
|
||||
}
|
||||
visit_mut::visit_pat_path_mut(self, pat);
|
||||
}
|
||||
|
||||
fn visit_pat_struct_mut(&mut self, pat: &mut PatStruct) {
|
||||
self.self_to_expr_path(&mut pat.path);
|
||||
visit_mut::visit_pat_struct_mut(self, pat);
|
||||
}
|
||||
|
||||
fn visit_pat_tuple_struct_mut(&mut self, pat: &mut PatTupleStruct) {
|
||||
self.self_to_expr_path(&mut pat.path);
|
||||
visit_mut::visit_pat_tuple_struct_mut(self, pat);
|
||||
}
|
||||
|
||||
fn visit_item_mut(&mut self, i: &mut Item) {
|
||||
match i {
|
||||
// Visit `macro_rules!` because locally defined macros can refer to `self`.
|
||||
Item::Macro(i) if i.mac.path.is_ident("macro_rules") => {
|
||||
self.visit_macro_mut(&mut i.mac)
|
||||
// Visit `macro_rules!` because locally defined macros can refer to
|
||||
// `self`.
|
||||
//
|
||||
// Visit `futures::select` and similar select macros, which commonly
|
||||
// appear syntactically like an item despite expanding to an expression.
|
||||
//
|
||||
// Otherwise, do not recurse into nested items.
|
||||
if let Item::Macro(i) = i {
|
||||
if i.mac.path.is_ident("macro_rules")
|
||||
|| i.mac.path.segments.last().unwrap().ident == "select"
|
||||
{
|
||||
self.visit_macro_mut(&mut i.mac);
|
||||
}
|
||||
// Otherwise, do not recurse into nested items.
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -303,19 +177,3 @@ impl VisitMut for ReplaceReceiver {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn contains_fn(tokens: TokenStream) -> bool {
|
||||
tokens.into_iter().any(|tt| match tt {
|
||||
TokenTree::Ident(ident) => ident == "fn",
|
||||
TokenTree::Group(group) => contains_fn(group.stream()),
|
||||
_ => false,
|
||||
})
|
||||
}
|
||||
|
||||
fn prepend_underscore_to_self(ident: &mut Ident) -> bool {
|
||||
let modified = ident == "self";
|
||||
if modified {
|
||||
*ident = Ident::new("_self", ident.span());
|
||||
}
|
||||
modified
|
||||
}
|
||||
|
|
|
@ -1,22 +0,0 @@
|
|||
use proc_macro2::{Span, TokenStream};
|
||||
use quote::ToTokens;
|
||||
use syn::parse::Parse;
|
||||
|
||||
pub(crate) fn respan<T>(node: &T, span: Span) -> T
|
||||
where
|
||||
T: ToTokens + Parse,
|
||||
{
|
||||
let tokens = node.to_token_stream();
|
||||
let respanned = respan_tokens(tokens, span);
|
||||
syn::parse2(respanned).unwrap()
|
||||
}
|
||||
|
||||
fn respan_tokens(tokens: TokenStream, span: Span) -> TokenStream {
|
||||
tokens
|
||||
.into_iter()
|
||||
.map(|mut token| {
|
||||
token.set_span(span);
|
||||
token
|
||||
})
|
||||
.collect()
|
||||
}
|
|
@ -4,6 +4,7 @@ use std::ptr;
|
|||
use std::task::{Context, Poll, RawWaker, RawWakerVTable, Waker};
|
||||
|
||||
// Executor for a future that resolves immediately (test only).
|
||||
#[allow(clippy::missing_panics_doc)]
|
||||
pub fn block_on_simple<F: Future>(mut fut: F) -> F::Output {
|
||||
unsafe fn clone(_null: *const ()) -> RawWaker {
|
||||
unimplemented!()
|
||||
|
|
|
@ -1,6 +1,14 @@
|
|||
#![cfg_attr(
|
||||
async_trait_nightly_testing,
|
||||
feature(min_specialization, min_const_generics)
|
||||
feature(min_specialization, type_alias_impl_trait)
|
||||
)]
|
||||
#![allow(
|
||||
clippy::let_underscore_drop,
|
||||
clippy::let_unit_value,
|
||||
clippy::missing_panics_doc,
|
||||
clippy::needless_return,
|
||||
clippy::trivially_copy_pass_by_ref,
|
||||
clippy::unused_async
|
||||
)]
|
||||
|
||||
use async_trait::async_trait;
|
||||
|
@ -151,6 +159,79 @@ pub(crate) unsafe trait UnsafeTraitPubCrate {}
|
|||
#[async_trait]
|
||||
unsafe trait UnsafeTraitPrivate {}
|
||||
|
||||
pub async fn test_can_destruct() {
|
||||
#[async_trait]
|
||||
trait CanDestruct {
|
||||
async fn f(&self, foos: (u8, u8, u8, u8));
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
impl CanDestruct for Struct {
|
||||
async fn f(&self, (a, ref mut b, ref c, d): (u8, u8, u8, u8)) {
|
||||
let _a: u8 = a;
|
||||
let _b: &mut u8 = b;
|
||||
let _c: &u8 = c;
|
||||
let _d: u8 = d;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn test_self_in_macro() {
|
||||
#[async_trait]
|
||||
trait Trait {
|
||||
async fn a(self);
|
||||
async fn b(&mut self);
|
||||
async fn c(&self);
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
impl Trait for String {
|
||||
async fn a(self) {
|
||||
println!("{}", self);
|
||||
}
|
||||
async fn b(&mut self) {
|
||||
println!("{}", self);
|
||||
}
|
||||
async fn c(&self) {
|
||||
println!("{}", self);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn test_inference() {
|
||||
#[async_trait]
|
||||
pub trait Trait {
|
||||
async fn f() -> Box<dyn Iterator<Item = ()>> {
|
||||
Box::new(std::iter::empty())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn test_internal_items() {
|
||||
#[async_trait]
|
||||
#[allow(dead_code, clippy::items_after_statements)]
|
||||
pub trait Trait: Sized {
|
||||
async fn f(self) {
|
||||
struct Struct;
|
||||
|
||||
impl Struct {
|
||||
fn f(self) {
|
||||
let _ = self;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn test_unimplemented() {
|
||||
#[async_trait]
|
||||
pub trait Trait {
|
||||
async fn f() {
|
||||
unimplemented!()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// https://github.com/dtolnay/async-trait/issues/1
|
||||
pub mod issue1 {
|
||||
use async_trait::async_trait;
|
||||
|
@ -1077,3 +1158,221 @@ pub mod issue134 {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
// https://github.com/dtolnay/async-trait/pull/125#pullrequestreview-491880881
|
||||
pub mod drop_order {
|
||||
use crate::executor;
|
||||
use async_trait::async_trait;
|
||||
use std::sync::atomic::{AtomicBool, Ordering};
|
||||
|
||||
struct Flagger<'a>(&'a AtomicBool);
|
||||
|
||||
impl Drop for Flagger<'_> {
|
||||
fn drop(&mut self) {
|
||||
self.0.fetch_xor(true, Ordering::AcqRel);
|
||||
}
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
trait Trait {
|
||||
async fn async_trait(_: Flagger<'_>, flag: &AtomicBool);
|
||||
}
|
||||
|
||||
struct Struct;
|
||||
|
||||
#[async_trait]
|
||||
impl Trait for Struct {
|
||||
async fn async_trait(_: Flagger<'_>, flag: &AtomicBool) {
|
||||
flag.fetch_or(true, Ordering::AcqRel);
|
||||
}
|
||||
}
|
||||
|
||||
async fn standalone(_: Flagger<'_>, flag: &AtomicBool) {
|
||||
flag.fetch_or(true, Ordering::AcqRel);
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
trait SelfTrait {
|
||||
async fn async_trait(self, flag: &AtomicBool);
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
impl SelfTrait for Flagger<'_> {
|
||||
async fn async_trait(self, flag: &AtomicBool) {
|
||||
flag.fetch_or(true, Ordering::AcqRel);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_drop_order() {
|
||||
// 0 : 0 ^ 1 = 1 | 1 = 1 (if flagger then block)
|
||||
// 0 : 0 | 1 = 1 ^ 1 = 0 (if block then flagger)
|
||||
|
||||
let flag = AtomicBool::new(false);
|
||||
executor::block_on_simple(standalone(Flagger(&flag), &flag));
|
||||
assert!(!flag.load(Ordering::Acquire));
|
||||
|
||||
executor::block_on_simple(Struct::async_trait(Flagger(&flag), &flag));
|
||||
assert!(!flag.load(Ordering::Acquire));
|
||||
|
||||
executor::block_on_simple(Flagger(&flag).async_trait(&flag));
|
||||
assert!(!flag.load(Ordering::Acquire));
|
||||
}
|
||||
}
|
||||
|
||||
// https://github.com/dtolnay/async-trait/issues/145
|
||||
pub mod issue145 {
|
||||
#![deny(clippy::type_complexity)]
|
||||
|
||||
use async_trait::async_trait;
|
||||
|
||||
#[async_trait]
|
||||
pub trait ManageConnection: Sized + Send + Sync + 'static {
|
||||
type Connection: Send + 'static;
|
||||
type Error: Send + 'static;
|
||||
|
||||
async fn connect(&self) -> Result<Self::Connection, Self::Error>;
|
||||
}
|
||||
}
|
||||
|
||||
// https://github.com/dtolnay/async-trait/issues/147
|
||||
pub mod issue147 {
|
||||
#![deny(clippy::let_unit_value)]
|
||||
|
||||
use async_trait::async_trait;
|
||||
|
||||
pub struct MyType;
|
||||
|
||||
#[async_trait]
|
||||
pub trait MyTrait {
|
||||
async fn x();
|
||||
async fn y() -> ();
|
||||
async fn z();
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
impl MyTrait for MyType {
|
||||
async fn x() {}
|
||||
async fn y() -> () {}
|
||||
async fn z() {
|
||||
unimplemented!()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// https://github.com/dtolnay/async-trait/issues/149
|
||||
pub mod issue149 {
|
||||
use async_trait::async_trait;
|
||||
|
||||
pub struct Thing;
|
||||
pub trait Ret {}
|
||||
impl Ret for Thing {}
|
||||
|
||||
pub async fn ok() -> &'static dyn Ret {
|
||||
return &Thing;
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
pub trait Trait {
|
||||
async fn fail() -> &'static dyn Ret {
|
||||
return &Thing;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// https://github.com/dtolnay/async-trait/issues/152
|
||||
#[cfg(async_trait_nightly_testing)]
|
||||
pub mod issue152 {
|
||||
use async_trait::async_trait;
|
||||
|
||||
#[async_trait]
|
||||
trait Trait {
|
||||
type Assoc;
|
||||
|
||||
async fn f(&self) -> Self::Assoc;
|
||||
}
|
||||
|
||||
struct Struct;
|
||||
|
||||
#[async_trait]
|
||||
impl Trait for Struct {
|
||||
type Assoc = impl Sized;
|
||||
|
||||
async fn f(&self) -> Self::Assoc {}
|
||||
}
|
||||
}
|
||||
|
||||
// https://github.com/dtolnay/async-trait/issues/154
|
||||
pub mod issue154 {
|
||||
#![deny(clippy::items_after_statements)]
|
||||
|
||||
use async_trait::async_trait;
|
||||
|
||||
#[async_trait]
|
||||
pub trait MyTrait {
|
||||
async fn f(&self);
|
||||
}
|
||||
|
||||
pub struct Struct;
|
||||
|
||||
#[async_trait]
|
||||
impl MyTrait for Struct {
|
||||
async fn f(&self) {
|
||||
const MAX: u16 = 128;
|
||||
println!("{}", MAX);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// https://github.com/dtolnay/async-trait/issues/158
|
||||
pub mod issue158 {
|
||||
use async_trait::async_trait;
|
||||
|
||||
fn f() {}
|
||||
|
||||
#[async_trait]
|
||||
pub trait Trait {
|
||||
async fn f(&self) {
|
||||
self::f();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// https://github.com/dtolnay/async-trait/issues/161
|
||||
#[allow(clippy::mut_mut)]
|
||||
pub mod issue161 {
|
||||
use async_trait::async_trait;
|
||||
use futures::future::FutureExt;
|
||||
use std::sync::Arc;
|
||||
|
||||
#[async_trait]
|
||||
pub trait Trait {
|
||||
async fn f(self: Arc<Self>);
|
||||
}
|
||||
|
||||
pub struct MyStruct(bool);
|
||||
|
||||
#[async_trait]
|
||||
impl Trait for MyStruct {
|
||||
async fn f(self: Arc<Self>) {
|
||||
futures::select! {
|
||||
_ = async {
|
||||
println!("{}", self.0);
|
||||
}.fuse() => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// https://github.com/dtolnay/async-trait/issues/169
|
||||
#[deny(where_clauses_object_safety)]
|
||||
pub mod issue169 {
|
||||
use async_trait::async_trait;
|
||||
|
||||
#[async_trait]
|
||||
pub trait Trait: ::core::marker::Sync {
|
||||
async fn f(&self) {}
|
||||
}
|
||||
|
||||
pub fn test(_t: &dyn Trait) {}
|
||||
}
|
||||
|
|
|
@ -9,3 +9,5 @@ note: the lint level is defined here
|
|||
|
|
||||
1 | #![deny(bare_trait_objects)]
|
||||
| ^^^^^^^^^^^^^^^^^^
|
||||
= warning: this is accepted in the current edition (Rust 2018) but is a hard error in Rust 2021!
|
||||
= note: for more information, see issue #80165 <https://github.com/rust-lang/rust/issues/80165>
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
use async_trait::async_trait;
|
||||
|
||||
macro_rules! picky {
|
||||
(ident) => {};
|
||||
($(t:tt)*) => {};
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
|
@ -14,6 +14,7 @@ struct Struct;
|
|||
#[async_trait]
|
||||
impl Trait for Struct {
|
||||
async fn method() {
|
||||
picky!({ 123, self });
|
||||
picky!({ 123 });
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,5 +4,14 @@ error: no rules expected the token `{`
|
|||
3 | macro_rules! picky {
|
||||
| ------------------ when calling this macro
|
||||
...
|
||||
17 | picky!({ 123 });
|
||||
17 | picky!({ 123, self });
|
||||
| ^ no rules expected this token in macro call
|
||||
|
||||
error: no rules expected the token `{`
|
||||
--> $DIR/delimiter-span.rs:18:16
|
||||
|
|
||||
3 | macro_rules! picky {
|
||||
| ------------------ when calling this macro
|
||||
...
|
||||
18 | picky!({ 123 });
|
||||
| ^ no rules expected this token in macro call
|
||||
|
|
|
@ -0,0 +1,36 @@
|
|||
use async_trait::async_trait;
|
||||
|
||||
struct A;
|
||||
struct B;
|
||||
|
||||
#[async_trait]
|
||||
pub trait Trait<'r> {
|
||||
async fn method(&'r self);
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
impl Trait for A {
|
||||
async fn method(&self) { }
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
impl<'r> Trait<'r> for B {
|
||||
async fn method(&self) { }
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
pub trait Trait2 {
|
||||
async fn method<'r>(&'r self);
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
impl Trait2 for A {
|
||||
async fn method(&self) { }
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
impl<'r> Trait2<'r> for B {
|
||||
async fn method(&'r self) { }
|
||||
}
|
||||
|
||||
fn main() {}
|
|
@ -0,0 +1,48 @@
|
|||
error[E0726]: implicit elided lifetime not allowed here
|
||||
--> $DIR/lifetime-span.rs:12:6
|
||||
|
|
||||
12 | impl Trait for A {
|
||||
| ^^^^^- help: indicate the anonymous lifetime: `<'_>`
|
||||
|
|
||||
= note: assuming a `'static` lifetime...
|
||||
|
||||
error[E0107]: this trait takes 0 lifetime arguments but 1 lifetime argument was supplied
|
||||
--> $DIR/lifetime-span.rs:32:10
|
||||
|
|
||||
32 | impl<'r> Trait2<'r> for B {
|
||||
| ^^^^^^---- help: remove these generics
|
||||
| |
|
||||
| expected 0 lifetime arguments
|
||||
|
|
||||
note: trait defined here, with 0 lifetime parameters
|
||||
--> $DIR/lifetime-span.rs:22:11
|
||||
|
|
||||
22 | pub trait Trait2 {
|
||||
| ^^^^^^
|
||||
|
||||
error[E0195]: lifetime parameters or bounds on method `method` do not match the trait declaration
|
||||
--> $DIR/lifetime-span.rs:13:14
|
||||
|
|
||||
8 | async fn method(&'r self);
|
||||
| ---------------- lifetimes in impl do not match this method in trait
|
||||
...
|
||||
13 | async fn method(&self) { }
|
||||
| ^^^^^^^^^^^^^ lifetimes do not match method in trait
|
||||
|
||||
error[E0195]: lifetime parameters or bounds on method `method` do not match the trait declaration
|
||||
--> $DIR/lifetime-span.rs:18:14
|
||||
|
|
||||
8 | async fn method(&'r self);
|
||||
| ---------------- lifetimes in impl do not match this method in trait
|
||||
...
|
||||
18 | async fn method(&self) { }
|
||||
| ^^^^^^^^^^^^^ lifetimes do not match method in trait
|
||||
|
||||
error[E0195]: lifetime parameters or bounds on method `method` do not match the trait declaration
|
||||
--> $DIR/lifetime-span.rs:33:14
|
||||
|
|
||||
23 | async fn method<'r>(&'r self);
|
||||
| ---- lifetimes in impl do not match this method in trait
|
||||
...
|
||||
33 | async fn method(&'r self) { }
|
||||
| ^^^^^^^^^^^^^^^^ lifetimes do not match method in trait
|
|
@ -1,12 +1,3 @@
|
|||
error[E0423]: expected value, found struct `S`
|
||||
--> $DIR/self-span.rs:18:23
|
||||
|
|
||||
3 | pub struct S {}
|
||||
| --------------- `S` defined here
|
||||
...
|
||||
18 | let _: Self = Self;
|
||||
| ^^^^ help: use struct literal syntax instead: `S {}`
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/self-span.rs:17:21
|
||||
|
|
||||
|
@ -15,6 +6,12 @@ error[E0308]: mismatched types
|
|||
| |
|
||||
| expected due to this
|
||||
|
||||
error: the `Self` constructor can only be used with tuple or unit structs
|
||||
--> $DIR/self-span.rs:18:23
|
||||
|
|
||||
18 | let _: Self = Self;
|
||||
| ^^^^ help: use curly brackets: `Self { /* fields */ }`
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/self-span.rs:25:21
|
||||
|
|
||||
|
|
|
@ -10,6 +10,13 @@ trait Test {
|
|||
let _guard = mutex.lock().unwrap();
|
||||
f().await;
|
||||
}
|
||||
|
||||
async fn test_ret(&self) -> bool {
|
||||
let mutex = Mutex::new(());
|
||||
let _guard = mutex.lock().unwrap();
|
||||
f().await;
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
|
|
@ -7,7 +7,7 @@ error: future cannot be sent between threads safely
|
|||
10 | | let _guard = mutex.lock().unwrap();
|
||||
11 | | f().await;
|
||||
12 | | }
|
||||
| |_____^ future returned by `__test` is not `Send`
|
||||
| |_____^ future created by async block is not `Send`
|
||||
|
|
||||
= help: within `impl Future`, the trait `Send` is not implemented for `MutexGuard<'_, ()>`
|
||||
note: future is not `Send` as this value is used across an await
|
||||
|
@ -20,3 +20,28 @@ note: future is not `Send` as this value is used across an await
|
|||
12 | }
|
||||
| - `_guard` is later dropped here
|
||||
= note: required for the cast to the object type `dyn Future<Output = ()> + Send`
|
||||
|
||||
error: future cannot be sent between threads safely
|
||||
--> $DIR/send-not-implemented.rs:14:38
|
||||
|
|
||||
14 | async fn test_ret(&self) -> bool {
|
||||
| ______________________________________^
|
||||
15 | | let mutex = Mutex::new(());
|
||||
16 | | let _guard = mutex.lock().unwrap();
|
||||
17 | | f().await;
|
||||
18 | | true
|
||||
19 | | }
|
||||
| |_____^ future created by async block is not `Send`
|
||||
|
|
||||
= help: within `impl Future`, the trait `Send` is not implemented for `MutexGuard<'_, ()>`
|
||||
note: future is not `Send` as this value is used across an await
|
||||
--> $DIR/send-not-implemented.rs:17:9
|
||||
|
|
||||
16 | let _guard = mutex.lock().unwrap();
|
||||
| ------ has type `MutexGuard<'_, ()>` which is not `Send`
|
||||
17 | f().await;
|
||||
| ^^^^^^^^^ await occurs here, with `_guard` maybe used later
|
||||
18 | true
|
||||
19 | }
|
||||
| - `_guard` is later dropped here
|
||||
= note: required for the cast to the object type `dyn Future<Output = bool> + Send`
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
#![deny(warnings)]
|
||||
|
||||
use async_trait::async_trait;
|
||||
|
||||
#[async_trait]
|
||||
pub trait Trait {
|
||||
async fn f() {
|
||||
unimplemented!()
|
||||
}
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
pub trait TraitFoo {
|
||||
async fn f() {
|
||||
let y = unimplemented!();
|
||||
let z = y;
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {}
|
|
@ -0,0 +1,14 @@
|
|||
error: unreachable statement
|
||||
--> $DIR/unreachable.rs:16:9
|
||||
|
|
||||
15 | let y = unimplemented!();
|
||||
| ---------------- any code following this expression is unreachable
|
||||
16 | let z = y;
|
||||
| ^^^^^^^^^^ unreachable statement
|
||||
|
|
||||
note: the lint level is defined here
|
||||
--> $DIR/unreachable.rs:1:9
|
||||
|
|
||||
1 | #![deny(warnings)]
|
||||
| ^^^^^^^^
|
||||
= note: `#[deny(unreachable_code)]` implied by `#[deny(warnings)]`
|
|
@ -1,4 +1,4 @@
|
|||
error: Self type of this impl is unsupported in expression position
|
||||
error: the `Self` constructor can only be used with tuple or unit structs
|
||||
--> $DIR/unsupported-self.rs:11:17
|
||||
|
|
||||
11 | let _ = Self;
|
||||
|
|
|
@ -1 +1 @@
|
|||
{"files":{"Cargo.toml":"253bf75bbcb6396b4e9ac2f4beb6a8c6e76c7a49bfb3b1ff3df482114ef261cd","README.md":"6b468f17809063c5dcee5758d1daca147d74e2297a9dc78a5e50ae13d9ea6e42","benches/basic.rs":"aba00ab044b37a7fb4e5c855cf88a323a04d6143b651717e227fdd12735602f3","src/lib.rs":"83a538135cbe79f16dcf0e038f3fbf0ac869e4951eab61990a4ea5933755ae0e","tests/basic.rs":"2cefa20188254d8357a595975733ad1bffb4de90933d5d9e9caa17232c1d646b"},"package":"681b971236e0f76b20fcafca0236b8718c9186ee778d67cd78bd5f28fd85427f"}
|
||||
{"files":{"Cargo.toml":"1191be2168fb6a9914afd20cd5a1c7ac5e612596b834a60ac495b45629805a51","README.md":"6b468f17809063c5dcee5758d1daca147d74e2297a9dc78a5e50ae13d9ea6e42","benches/basic.rs":"aba00ab044b37a7fb4e5c855cf88a323a04d6143b651717e227fdd12735602f3","src/lib.rs":"631e765b36b20ab47c7cd35fb0bf2e9b6f9c2bf2a0ab72bd67d59759ff53a71f","tests/basic.rs":"2cefa20188254d8357a595975733ad1bffb4de90933d5d9e9caa17232c1d646b"},"package":"73b5e5f48b927f04e952dedc932f31995a65a0bf65ec971c74436e51bf6e970d"}
|
|
@ -3,16 +3,15 @@
|
|||
# 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
|
||||
# to registry (e.g., crates.io) dependencies.
|
||||
#
|
||||
# If you believe there's an error in this file please file an
|
||||
# issue against the rust-lang/cargo repository. If you're
|
||||
# editing this file be aware that the upstream Cargo.toml
|
||||
# will likely look very different (and much more reasonable)
|
||||
# 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 = "atomic_refcell"
|
||||
version = "0.1.7"
|
||||
version = "0.1.8"
|
||||
authors = ["Bobby Holley <bobbyholley@gmail.com>"]
|
||||
description = "Threadsafe RefCell"
|
||||
documentation = "https://docs.rs/atomic_refcell/"
|
||||
|
|
|
@ -123,7 +123,7 @@ impl<T: ?Sized> AtomicRefCell<T> {
|
|||
value: unsafe { &*self.value.get() },
|
||||
borrow,
|
||||
},
|
||||
Err(s) => panic!(s),
|
||||
Err(s) => panic!("{}", s),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -148,7 +148,7 @@ impl<T: ?Sized> AtomicRefCell<T> {
|
|||
value: unsafe { &mut *self.value.get() },
|
||||
borrow,
|
||||
},
|
||||
Err(s) => panic!(s),
|
||||
Err(s) => panic!("{}", s),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -310,7 +310,7 @@ impl<'b> AtomicBorrowRefMut<'b> {
|
|||
}
|
||||
}
|
||||
|
||||
unsafe impl<T: ?Sized + Send + Sync> Send for AtomicRefCell<T> {}
|
||||
unsafe impl<T: ?Sized + Send> Send for AtomicRefCell<T> {}
|
||||
unsafe impl<T: ?Sized + Send + Sync> Sync for AtomicRefCell<T> {}
|
||||
|
||||
//
|
||||
|
|
Загрузка…
Ссылка в новой задаче