add rust modules with cargo vendor
This commit is contained in:
parent
e06d83ab68
commit
f5dd6d5176
229
Cargo.lock
generated
Normal file
229
Cargo.lock
generated
Normal file
@ -0,0 +1,229 @@
|
||||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
version = 3
|
||||
|
||||
[[package]]
|
||||
name = "anyhow"
|
||||
version = "1.0.65"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "98161a4e3e2184da77bb14f02184cdd111e83bbbcc9979dfee3c44b9a85f5602"
|
||||
|
||||
[[package]]
|
||||
name = "autocfg"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
|
||||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
version = "1.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
|
||||
|
||||
[[package]]
|
||||
name = "bytes"
|
||||
version = "1.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ec8a7b6a70fde80372154c65702f00a0f56f3e1c36abbc6c440484be248856db"
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||
|
||||
[[package]]
|
||||
name = "hermit-abi"
|
||||
version = "0.1.19"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "lazy_static"
|
||||
version = "1.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.134"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "329c933548736bc49fd575ee68c89e8be4d260064184389a5b77517cddd99ffb"
|
||||
|
||||
[[package]]
|
||||
name = "log"
|
||||
version = "0.4.17"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "memchr"
|
||||
version = "2.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d"
|
||||
|
||||
[[package]]
|
||||
name = "memoffset"
|
||||
version = "0.6.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5aa361d4faea93603064a027415f07bd8e1d5c88c9fbf68bf56a285428fd79ce"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "mio"
|
||||
version = "0.8.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "57ee1c23c7c63b0c9250c339ffdc69255f110b298b901b9f6c82547b7b87caaf"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"log",
|
||||
"wasi",
|
||||
"windows-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "nix"
|
||||
version = "0.24.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "195cdbc1741b8134346d515b3a56a1c94b0912758009cfd53f99ea0f57b065fc"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"cfg-if",
|
||||
"libc",
|
||||
"memoffset",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num_cpus"
|
||||
version = "1.13.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "19e64526ebdee182341572e50e9ad03965aa510cd94427a4549448f285e957a1"
|
||||
dependencies = [
|
||||
"hermit-abi",
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pin-project-lite"
|
||||
version = "0.2.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e0a7ae3ac2f1173085d398531c705756c94a4c56843785df85a60c1a0afac116"
|
||||
|
||||
[[package]]
|
||||
name = "pve-lxc-syscalld"
|
||||
version = "1.2.2"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"bitflags",
|
||||
"lazy_static",
|
||||
"libc",
|
||||
"nix",
|
||||
"num_cpus",
|
||||
"tokio",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "socket2"
|
||||
version = "0.4.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "02e2d2db9033d13a1567121ddd7a095ee144db4e1ca1b1bda3419bc0da294ebd"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tokio"
|
||||
version = "1.21.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a9e03c497dc955702ba729190dc4aac6f2a0ce97f913e5b1b5912fc5039d9099"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"bytes",
|
||||
"libc",
|
||||
"memchr",
|
||||
"mio",
|
||||
"num_cpus",
|
||||
"pin-project-lite",
|
||||
"socket2",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasi"
|
||||
version = "0.11.0+wasi-snapshot-preview1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
|
||||
|
||||
[[package]]
|
||||
name = "winapi"
|
||||
version = "0.3.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
|
||||
dependencies = [
|
||||
"winapi-i686-pc-windows-gnu",
|
||||
"winapi-x86_64-pc-windows-gnu",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winapi-i686-pc-windows-gnu"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
|
||||
|
||||
[[package]]
|
||||
name = "winapi-x86_64-pc-windows-gnu"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
||||
|
||||
[[package]]
|
||||
name = "windows-sys"
|
||||
version = "0.36.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ea04155a16a59f9eab786fe12a4a450e75cdb175f9e0d80da1e17db09f55b8d2"
|
||||
dependencies = [
|
||||
"windows_aarch64_msvc",
|
||||
"windows_i686_gnu",
|
||||
"windows_i686_msvc",
|
||||
"windows_x86_64_gnu",
|
||||
"windows_x86_64_msvc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_msvc"
|
||||
version = "0.36.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9bb8c3fd39ade2d67e9874ac4f3db21f0d710bee00fe7cab16949ec184eeaa47"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_gnu"
|
||||
version = "0.36.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "180e6ccf01daf4c426b846dfc66db1fc518f074baa793aa7d9b9aaeffad6a3b6"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_msvc"
|
||||
version = "0.36.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e2e7917148b2812d1eeafaeb22a97e4813dfa60a3f8f78ebe204bcc88f12f024"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnu"
|
||||
version = "0.36.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4dcd171b8776c41b97521e5da127a2d86ad280114807d0b2ab1e462bc764d9e1"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_msvc"
|
||||
version = "0.36.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c811ca4a8c853ef420abd8592ba53ddbbac90410fab6903b3e79972a631f7680"
|
1
vendor/anyhow/.cargo-checksum.json
vendored
Normal file
1
vendor/anyhow/.cargo-checksum.json
vendored
Normal file
@ -0,0 +1 @@
|
||||
{"files":{"Cargo.toml":"5779c6bea2555cdabd4560de187ac5e3c88ff2df8172077397643edc51c6fcc3","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"23f18e03dc49df91622fe2a76176497404e46ced8a715d9d2b67a7446571cca3","README.md":"4bd4d352368ac0f5447031d82454490f6ac0c80d2fa4cb64ba0c23c614670d49","build.rs":"88bf7100143c79c0af683da7f28deaac031c9b9b213a6426560dc089b0ba45aa","rust-toolchain.toml":"6bbb61302978c736b2da03e4fb40e3beab908f85d533ab46fd541e637b5f3e0f","src/backtrace.rs":"5b4103a7d24d6f438a64b8cc0fafe28d55fc0ca090368174ce44d64e3940badd","src/chain.rs":"6edefc5f3c7d69683095862e54e3bb56faba5b3387bf2eeaed429da090007a0a","src/context.rs":"0bb1566aae147d393796dd6ede6ba329916e0a373b7cbc38335c3eeeb3d48b57","src/ensure.rs":"498bc9c7fb8b93168ed12f532cb97df6ccdda9ce25371586d7f5b1b1c98a14bf","src/error.rs":"e45d4dcfe64b1823b42fbf9bb260e6437987e8c2d51f92434db9d808b36e700a","src/fmt.rs":"c2d4aad6ce20625a70a7c091e3087b6a2c19a4a87c7a12edb4c98978307245ea","src/kind.rs":"332854c5eb07d44447c356a2e7dc585634b0da1ffbbfa81269c369deaefbc247","src/lib.rs":"82011e86fb9b41fe10ab2fde2b797b4858e697e7ead3a5f0d30b018357f1721d","src/macros.rs":"dd35f2ec2a0a25e4504fb04bcd42f6d0963bc0035aaaefc412f5ee1d78945fe1","src/ptr.rs":"f4e28bc9feba1e84160ca9d185008a51b5d72e168e6546f3e942f4258c361e19","src/wrapper.rs":"ff3ad72065a30cc32e9acb0614a30703c49c57b941a335c348b6439af684316b","tests/common/mod.rs":"f9088c2d7afafa64ff730b629272045b776bfafc2f5957508242da630635f2e1","tests/compiletest.rs":"022a8e400ef813d7ea1875b944549cee5125f6a995dc33e93b48cba3e1b57bd1","tests/drop/mod.rs":"08c3e553c1cc0d2dbd936fc45f4b5b1105057186affd6865e8d261e05f0f0646","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":"797e69a72d125758c4c4897e5dc776d549d52cc9a6a633e0a33193f588a62b88","tests/test_ensure.rs":"c8137a9565685aedf02b365008b27c707f4c3d81cd2b986b3b7105b426c723b1","tests/test_ffi.rs":"d0cb4c1d6d9154090982dee72ae3ebe05a5981f976058c3250f1c9da5a45edef","tests/test_fmt.rs":"17572596f257aac9aa2ec4620e292ca6a954128b94772bb948399fab53832e70","tests/test_macros.rs":"11f05010bc9b16319884c1286444100e30cddc2ecd1ffe5e0fd3fee5ffb32683","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":"345102cbef47310f2f4066a669199873a627ca4f1fcb885505c6e17d1fc95e88","tests/ui/must-use.rs":"fb59860b43f673bf4a430a6036ba463e95028844d8dd4243cfe5ebc7f2be582f","tests/ui/must-use.stderr":"c2848c5f254b4c061eea6714d9baf709924aba06619eaf2a8b3aee1266b75f9e","tests/ui/no-impl.rs":"fab6cbf2f6ea510b86f567dfb3b7c31250a9fd71ae5d110dbb9188be569ec593","tests/ui/no-impl.stderr":"9d36a96220f0b5a81db027bcba411a61a72cc2e370c38058ab556442e8bb8a8b","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":"98161a4e3e2184da77bb14f02184cdd111e83bbbcc9979dfee3c44b9a85f5602"}
|
63
vendor/anyhow/Cargo.toml
vendored
Normal file
63
vendor/anyhow/Cargo.toml
vendored
Normal file
@ -0,0 +1,63 @@
|
||||
# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO
|
||||
#
|
||||
# When uploading crates to the registry Cargo will automatically
|
||||
# "normalize" Cargo.toml files for maximal compatibility
|
||||
# with all versions of Cargo and also rewrite `path` dependencies
|
||||
# to registry (e.g., crates.io) dependencies.
|
||||
#
|
||||
# If you are reading this file be aware that the original Cargo.toml
|
||||
# will likely look very different (and much more reasonable).
|
||||
# See Cargo.toml.orig for the original contents.
|
||||
|
||||
[package]
|
||||
edition = "2018"
|
||||
rust-version = "1.38"
|
||||
name = "anyhow"
|
||||
version = "1.0.65"
|
||||
authors = ["David Tolnay <dtolnay@gmail.com>"]
|
||||
description = "Flexible concrete Error type built on std::error::Error"
|
||||
documentation = "https://docs.rs/anyhow"
|
||||
readme = "README.md"
|
||||
keywords = [
|
||||
"error",
|
||||
"error-handling",
|
||||
]
|
||||
categories = [
|
||||
"rust-patterns",
|
||||
"no-std",
|
||||
]
|
||||
license = "MIT OR Apache-2.0"
|
||||
repository = "https://github.com/dtolnay/anyhow"
|
||||
|
||||
[package.metadata.docs.rs]
|
||||
targets = ["x86_64-unknown-linux-gnu"]
|
||||
rustdoc-args = [
|
||||
"--cfg",
|
||||
"doc_cfg",
|
||||
]
|
||||
|
||||
[dependencies.backtrace]
|
||||
version = "0.3.51"
|
||||
optional = true
|
||||
|
||||
[dev-dependencies.futures]
|
||||
version = "0.3"
|
||||
default-features = false
|
||||
|
||||
[dev-dependencies.rustversion]
|
||||
version = "1.0.6"
|
||||
|
||||
[dev-dependencies.syn]
|
||||
version = "1.0"
|
||||
features = ["full"]
|
||||
|
||||
[dev-dependencies.thiserror]
|
||||
version = "1.0"
|
||||
|
||||
[dev-dependencies.trybuild]
|
||||
version = "1.0.49"
|
||||
features = ["diff"]
|
||||
|
||||
[features]
|
||||
default = ["std"]
|
||||
std = []
|
201
vendor/anyhow/LICENSE-APACHE
vendored
Normal file
201
vendor/anyhow/LICENSE-APACHE
vendored
Normal file
@ -0,0 +1,201 @@
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
23
vendor/anyhow/LICENSE-MIT
vendored
Normal file
23
vendor/anyhow/LICENSE-MIT
vendored
Normal file
@ -0,0 +1,23 @@
|
||||
Permission is hereby granted, free of charge, to any
|
||||
person obtaining a copy of this software and associated
|
||||
documentation files (the "Software"), to deal in the
|
||||
Software without restriction, including without
|
||||
limitation the rights to use, copy, modify, merge,
|
||||
publish, distribute, sublicense, and/or sell copies of
|
||||
the Software, and to permit persons to whom the Software
|
||||
is furnished to do so, subject to the following
|
||||
conditions:
|
||||
|
||||
The above copyright notice and this permission notice
|
||||
shall be included in all copies or substantial portions
|
||||
of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
|
||||
ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
|
||||
TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
|
||||
PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
|
||||
SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
|
||||
IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
DEALINGS IN THE SOFTWARE.
|
182
vendor/anyhow/README.md
vendored
Normal file
182
vendor/anyhow/README.md
vendored
Normal file
@ -0,0 +1,182 @@
|
||||
Anyhow ¯\\\_(°ペ)\_/¯
|
||||
==========================
|
||||
|
||||
[<img alt="github" src="https://img.shields.io/badge/github-dtolnay/anyhow-8da0cb?style=for-the-badge&labelColor=555555&logo=github" height="20">](https://github.com/dtolnay/anyhow)
|
||||
[<img alt="crates.io" src="https://img.shields.io/crates/v/anyhow.svg?style=for-the-badge&color=fc8d62&logo=rust" height="20">](https://crates.io/crates/anyhow)
|
||||
[<img alt="docs.rs" src="https://img.shields.io/badge/docs.rs-anyhow-66c2a5?style=for-the-badge&labelColor=555555&logo=docs.rs" height="20">](https://docs.rs/anyhow)
|
||||
[<img alt="build status" src="https://img.shields.io/github/workflow/status/dtolnay/anyhow/CI/master?style=for-the-badge" height="20">](https://github.com/dtolnay/anyhow/actions?query=branch%3Amaster)
|
||||
|
||||
This library provides [`anyhow::Error`][Error], a trait object based error type
|
||||
for easy idiomatic error handling in Rust applications.
|
||||
|
||||
[Error]: https://docs.rs/anyhow/1.0/anyhow/struct.Error.html
|
||||
|
||||
```toml
|
||||
[dependencies]
|
||||
anyhow = "1.0"
|
||||
```
|
||||
|
||||
*Compiler support: requires rustc 1.38+*
|
||||
|
||||
<br>
|
||||
|
||||
## Details
|
||||
|
||||
- Use `Result<T, anyhow::Error>`, or equivalently `anyhow::Result<T>`, as the
|
||||
return type of any fallible function.
|
||||
|
||||
Within the function, use `?` to easily propagate any error that implements the
|
||||
`std::error::Error` trait.
|
||||
|
||||
```rust
|
||||
use anyhow::Result;
|
||||
|
||||
fn get_cluster_info() -> Result<ClusterMap> {
|
||||
let config = std::fs::read_to_string("cluster.json")?;
|
||||
let map: ClusterMap = serde_json::from_str(&config)?;
|
||||
Ok(map)
|
||||
}
|
||||
```
|
||||
|
||||
- Attach context to help the person troubleshooting the error understand where
|
||||
things went wrong. A low-level error like "No such file or directory" can be
|
||||
annoying to debug without more context about what higher level step the
|
||||
application was in the middle of.
|
||||
|
||||
```rust
|
||||
use anyhow::{Context, Result};
|
||||
|
||||
fn main() -> Result<()> {
|
||||
...
|
||||
it.detach().context("Failed to detach the important thing")?;
|
||||
|
||||
let content = std::fs::read(path)
|
||||
.with_context(|| format!("Failed to read instrs from {}", path))?;
|
||||
...
|
||||
}
|
||||
```
|
||||
|
||||
```console
|
||||
Error: Failed to read instrs from ./path/to/instrs.json
|
||||
|
||||
Caused by:
|
||||
No such file or directory (os error 2)
|
||||
```
|
||||
|
||||
- Downcasting is supported and can be by value, by shared reference, or by
|
||||
mutable reference as needed.
|
||||
|
||||
```rust
|
||||
// If the error was caused by redaction, then return a
|
||||
// tombstone instead of the content.
|
||||
match root_cause.downcast_ref::<DataStoreError>() {
|
||||
Some(DataStoreError::Censored(_)) => Ok(Poll::Ready(REDACTED_CONTENT)),
|
||||
None => Err(error),
|
||||
}
|
||||
```
|
||||
|
||||
- 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`;
|
||||
- If you want only errors to have backtraces, set `RUST_LIB_BACKTRACE=1`;
|
||||
- If you want only panics to have backtraces, set `RUST_BACKTRACE=1` and
|
||||
`RUST_LIB_BACKTRACE=0`.
|
||||
|
||||
The tracking issue for this feature is [rust-lang/rust#53487].
|
||||
|
||||
[`std::backtrace`]: https://doc.rust-lang.org/std/backtrace/index.html#environment-variables
|
||||
[rust-lang/rust#53487]: https://github.com/rust-lang/rust/issues/53487
|
||||
|
||||
- Anyhow works with any error type that has an impl of `std::error::Error`,
|
||||
including ones defined in your crate. We do not bundle a `derive(Error)` macro
|
||||
but you can write the impls yourself or use a standalone macro like
|
||||
[thiserror].
|
||||
|
||||
```rust
|
||||
use thiserror::Error;
|
||||
|
||||
#[derive(Error, Debug)]
|
||||
pub enum FormatError {
|
||||
#[error("Invalid header (expected {expected:?}, got {found:?})")]
|
||||
InvalidHeader {
|
||||
expected: String,
|
||||
found: String,
|
||||
},
|
||||
#[error("Missing attribute: {0}")]
|
||||
MissingAttribute(String),
|
||||
}
|
||||
```
|
||||
|
||||
- One-off error messages can be constructed using the `anyhow!` macro, which
|
||||
supports string interpolation and produces an `anyhow::Error`.
|
||||
|
||||
```rust
|
||||
return Err(anyhow!("Missing attribute: {}", missing));
|
||||
```
|
||||
|
||||
A `bail!` macro is provided as a shorthand for the same early return.
|
||||
|
||||
```rust
|
||||
bail!("Missing attribute: {}", missing);
|
||||
```
|
||||
|
||||
<br>
|
||||
|
||||
## No-std support
|
||||
|
||||
In no_std mode, the same API is almost all available and works the same way. To
|
||||
depend on Anyhow in no_std mode, disable our default enabled "std" feature in
|
||||
Cargo.toml. A global allocator is required.
|
||||
|
||||
```toml
|
||||
[dependencies]
|
||||
anyhow = { version = "1.0", default-features = false }
|
||||
```
|
||||
|
||||
Since the `?`-based error conversions would normally rely on the
|
||||
`std::error::Error` trait which is only available through std, no_std mode 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.
|
||||
|
||||
<br>
|
||||
|
||||
## Comparison to failure
|
||||
|
||||
The `anyhow::Error` type works something like `failure::Error`, but unlike
|
||||
failure ours is built around the standard library's `std::error::Error` trait
|
||||
rather than a separate trait `failure::Fail`. The standard library has adopted
|
||||
the necessary improvements for this to be possible as part of [RFC 2504].
|
||||
|
||||
[RFC 2504]: https://github.com/rust-lang/rfcs/blob/master/text/2504-fix-error.md
|
||||
|
||||
<br>
|
||||
|
||||
## Comparison to thiserror
|
||||
|
||||
Use Anyhow if you don't care what error type your functions return, you just
|
||||
want it to be easy. This is common in application code. Use [thiserror] if you
|
||||
are a library that wants to design your own dedicated error type(s) so that on
|
||||
failures the caller gets exactly the information that you choose.
|
||||
|
||||
[thiserror]: https://github.com/dtolnay/thiserror
|
||||
|
||||
<br>
|
||||
|
||||
#### License
|
||||
|
||||
<sup>
|
||||
Licensed under either of <a href="LICENSE-APACHE">Apache License, Version
|
||||
2.0</a> or <a href="LICENSE-MIT">MIT license</a> at your option.
|
||||
</sup>
|
||||
|
||||
<br>
|
||||
|
||||
<sub>
|
||||
Unless you explicitly state otherwise, any contribution intentionally submitted
|
||||
for inclusion in this crate by you, as defined in the Apache-2.0 license, shall
|
||||
be dual licensed as above, without any additional terms or conditions.
|
||||
</sub>
|
131
vendor/anyhow/build.rs
vendored
Normal file
131
vendor/anyhow/build.rs
vendored
Normal file
@ -0,0 +1,131 @@
|
||||
#![allow(clippy::option_if_let_else)]
|
||||
|
||||
use std::env;
|
||||
use std::fs;
|
||||
use std::path::Path;
|
||||
use std::process::{Command, ExitStatus, Stdio};
|
||||
use std::str;
|
||||
|
||||
#[cfg(all(feature = "backtrace", not(feature = "std")))]
|
||||
compile_error! {
|
||||
"`backtrace` feature without `std` feature is not supported"
|
||||
}
|
||||
|
||||
// This code exercises the surface area that we expect of the std Backtrace
|
||||
// type. If the current toolchain is able to compile it, we go ahead and use
|
||||
// backtrace in anyhow.
|
||||
const PROBE: &str = r#"
|
||||
#![feature(error_generic_member_access, provide_any)]
|
||||
|
||||
use std::any::{Demand, Provider};
|
||||
use std::backtrace::{Backtrace, BacktraceStatus};
|
||||
use std::error::Error;
|
||||
use std::fmt::{self, Display};
|
||||
|
||||
#[derive(Debug)]
|
||||
struct E {
|
||||
backtrace: Backtrace,
|
||||
}
|
||||
|
||||
impl Display for E {
|
||||
fn fmt(&self, _formatter: &mut fmt::Formatter) -> fmt::Result {
|
||||
unimplemented!()
|
||||
}
|
||||
}
|
||||
|
||||
impl Error for E {
|
||||
fn provide<'a>(&'a self, demand: &mut Demand<'a>) {
|
||||
demand.provide_ref(&self.backtrace);
|
||||
}
|
||||
}
|
||||
|
||||
struct P;
|
||||
|
||||
impl Provider for P {
|
||||
fn provide<'a>(&'a self, _demand: &mut Demand<'a>) {}
|
||||
}
|
||||
|
||||
const _: fn() = || {
|
||||
let backtrace: Backtrace = Backtrace::capture();
|
||||
let status: BacktraceStatus = backtrace.status();
|
||||
match status {
|
||||
BacktraceStatus::Captured | BacktraceStatus::Disabled | _ => {}
|
||||
}
|
||||
};
|
||||
|
||||
const _: fn(&dyn Error) -> Option<&Backtrace> = |err| err.request_ref::<Backtrace>();
|
||||
"#;
|
||||
|
||||
fn main() {
|
||||
if cfg!(feature = "std") {
|
||||
match compile_probe() {
|
||||
Some(status) if status.success() => println!("cargo:rustc-cfg=backtrace"),
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
let rustc = match rustc_minor_version() {
|
||||
Some(rustc) => rustc,
|
||||
None => return,
|
||||
};
|
||||
|
||||
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> {
|
||||
let rustc = env::var_os("RUSTC")?;
|
||||
let out_dir = env::var_os("OUT_DIR")?;
|
||||
let probefile = Path::new(&out_dir).join("probe.rs");
|
||||
fs::write(&probefile, PROBE).ok()?;
|
||||
|
||||
// Make sure to pick up Cargo rustc configuration.
|
||||
let mut cmd = if let Some(wrapper) = env::var_os("RUSTC_WRAPPER") {
|
||||
let mut cmd = Command::new(wrapper);
|
||||
// The wrapper's first argument is supposed to be the path to rustc.
|
||||
cmd.arg(rustc);
|
||||
cmd
|
||||
} else {
|
||||
Command::new(rustc)
|
||||
};
|
||||
|
||||
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);
|
||||
|
||||
if let Some(target) = env::var_os("TARGET") {
|
||||
cmd.arg("--target").arg(target);
|
||||
}
|
||||
|
||||
// If Cargo wants to set RUSTFLAGS, use that.
|
||||
if let Ok(rustflags) = env::var("CARGO_ENCODED_RUSTFLAGS") {
|
||||
if !rustflags.is_empty() {
|
||||
for arg in rustflags.split('\x1f') {
|
||||
cmd.arg(arg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
cmd.status().ok()
|
||||
}
|
||||
|
||||
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()
|
||||
}
|
2
vendor/anyhow/rust-toolchain.toml
vendored
Normal file
2
vendor/anyhow/rust-toolchain.toml
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
[toolchain]
|
||||
components = ["rust-src"]
|
401
vendor/anyhow/src/backtrace.rs
vendored
Normal file
401
vendor/anyhow/src/backtrace.rs
vendored
Normal file
@ -0,0 +1,401 @@
|
||||
#[cfg(backtrace)]
|
||||
pub(crate) use std::backtrace::{Backtrace, BacktraceStatus};
|
||||
|
||||
#[cfg(all(not(backtrace), feature = "backtrace"))]
|
||||
pub(crate) use self::capture::{Backtrace, BacktraceStatus};
|
||||
|
||||
#[cfg(not(any(backtrace, feature = "backtrace")))]
|
||||
pub(crate) enum Backtrace {}
|
||||
|
||||
#[cfg(backtrace)]
|
||||
macro_rules! impl_backtrace {
|
||||
() => {
|
||||
std::backtrace::Backtrace
|
||||
};
|
||||
}
|
||||
|
||||
#[cfg(all(not(backtrace), feature = "backtrace"))]
|
||||
macro_rules! impl_backtrace {
|
||||
() => {
|
||||
impl core::fmt::Debug + core::fmt::Display
|
||||
};
|
||||
}
|
||||
|
||||
#[cfg(any(backtrace, feature = "backtrace"))]
|
||||
macro_rules! backtrace {
|
||||
() => {
|
||||
Some(crate::backtrace::Backtrace::capture())
|
||||
};
|
||||
}
|
||||
|
||||
#[cfg(not(any(backtrace, feature = "backtrace")))]
|
||||
macro_rules! backtrace {
|
||||
() => {
|
||||
None
|
||||
};
|
||||
}
|
||||
|
||||
#[cfg(backtrace)]
|
||||
macro_rules! backtrace_if_absent {
|
||||
($err:expr) => {
|
||||
match ($err as &dyn std::error::Error).request_ref::<std::backtrace::Backtrace>() {
|
||||
Some(_) => None,
|
||||
None => backtrace!(),
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#[cfg(all(feature = "std", not(backtrace), feature = "backtrace"))]
|
||||
macro_rules! backtrace_if_absent {
|
||||
($err:expr) => {
|
||||
backtrace!()
|
||||
};
|
||||
}
|
||||
|
||||
#[cfg(all(feature = "std", not(backtrace), not(feature = "backtrace")))]
|
||||
macro_rules! backtrace_if_absent {
|
||||
($err:expr) => {
|
||||
None
|
||||
};
|
||||
}
|
||||
|
||||
#[cfg(all(not(backtrace), feature = "backtrace"))]
|
||||
mod capture {
|
||||
use backtrace::{BacktraceFmt, BytesOrWideString, Frame, PrintFmt, SymbolName};
|
||||
use core::cell::UnsafeCell;
|
||||
use core::fmt::{self, Debug, Display};
|
||||
use core::sync::atomic::{AtomicUsize, Ordering};
|
||||
use std::borrow::Cow;
|
||||
use std::env;
|
||||
use std::path::{self, Path, PathBuf};
|
||||
use std::sync::Once;
|
||||
|
||||
pub(crate) struct Backtrace {
|
||||
inner: Inner,
|
||||
}
|
||||
|
||||
pub(crate) enum BacktraceStatus {
|
||||
Unsupported,
|
||||
Disabled,
|
||||
Captured,
|
||||
}
|
||||
|
||||
enum Inner {
|
||||
Unsupported,
|
||||
Disabled,
|
||||
Captured(LazilyResolvedCapture),
|
||||
}
|
||||
|
||||
struct Capture {
|
||||
actual_start: usize,
|
||||
resolved: bool,
|
||||
frames: Vec<BacktraceFrame>,
|
||||
}
|
||||
|
||||
struct BacktraceFrame {
|
||||
frame: Frame,
|
||||
symbols: Vec<BacktraceSymbol>,
|
||||
}
|
||||
|
||||
struct BacktraceSymbol {
|
||||
name: Option<Vec<u8>>,
|
||||
filename: Option<BytesOrWide>,
|
||||
lineno: Option<u32>,
|
||||
colno: Option<u32>,
|
||||
}
|
||||
|
||||
enum BytesOrWide {
|
||||
Bytes(Vec<u8>),
|
||||
Wide(Vec<u16>),
|
||||
}
|
||||
|
||||
impl Debug for Backtrace {
|
||||
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
|
||||
let capture = match &self.inner {
|
||||
Inner::Unsupported => return fmt.write_str("<unsupported>"),
|
||||
Inner::Disabled => return fmt.write_str("<disabled>"),
|
||||
Inner::Captured(c) => c.force(),
|
||||
};
|
||||
|
||||
let frames = &capture.frames[capture.actual_start..];
|
||||
|
||||
write!(fmt, "Backtrace ")?;
|
||||
|
||||
let mut dbg = fmt.debug_list();
|
||||
|
||||
for frame in frames {
|
||||
if frame.frame.ip().is_null() {
|
||||
continue;
|
||||
}
|
||||
|
||||
dbg.entries(&frame.symbols);
|
||||
}
|
||||
|
||||
dbg.finish()
|
||||
}
|
||||
}
|
||||
|
||||
impl Debug for BacktraceFrame {
|
||||
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
|
||||
let mut dbg = fmt.debug_list();
|
||||
dbg.entries(&self.symbols);
|
||||
dbg.finish()
|
||||
}
|
||||
}
|
||||
|
||||
impl Debug for BacktraceSymbol {
|
||||
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(fmt, "{{ ")?;
|
||||
|
||||
if let Some(fn_name) = self.name.as_ref().map(|b| SymbolName::new(b)) {
|
||||
write!(fmt, "fn: \"{:#}\"", fn_name)?;
|
||||
} else {
|
||||
write!(fmt, "fn: <unknown>")?;
|
||||
}
|
||||
|
||||
if let Some(fname) = self.filename.as_ref() {
|
||||
write!(fmt, ", file: \"{:?}\"", fname)?;
|
||||
}
|
||||
|
||||
if let Some(line) = self.lineno {
|
||||
write!(fmt, ", line: {:?}", line)?;
|
||||
}
|
||||
|
||||
write!(fmt, " }}")
|
||||
}
|
||||
}
|
||||
|
||||
impl Debug for BytesOrWide {
|
||||
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
|
||||
output_filename(
|
||||
fmt,
|
||||
match self {
|
||||
BytesOrWide::Bytes(w) => BytesOrWideString::Bytes(w),
|
||||
BytesOrWide::Wide(w) => BytesOrWideString::Wide(w),
|
||||
},
|
||||
PrintFmt::Short,
|
||||
env::current_dir().as_ref().ok(),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl Backtrace {
|
||||
fn enabled() -> bool {
|
||||
static ENABLED: AtomicUsize = AtomicUsize::new(0);
|
||||
match ENABLED.load(Ordering::Relaxed) {
|
||||
0 => {}
|
||||
1 => return false,
|
||||
_ => return true,
|
||||
}
|
||||
let enabled = match env::var_os("RUST_LIB_BACKTRACE") {
|
||||
Some(s) => s != "0",
|
||||
None => match env::var_os("RUST_BACKTRACE") {
|
||||
Some(s) => s != "0",
|
||||
None => false,
|
||||
},
|
||||
};
|
||||
ENABLED.store(enabled as usize + 1, Ordering::Relaxed);
|
||||
enabled
|
||||
}
|
||||
|
||||
#[inline(never)] // want to make sure there's a frame here to remove
|
||||
pub(crate) fn capture() -> Backtrace {
|
||||
if Backtrace::enabled() {
|
||||
Backtrace::create(Backtrace::capture as usize)
|
||||
} else {
|
||||
let inner = Inner::Disabled;
|
||||
Backtrace { inner }
|
||||
}
|
||||
}
|
||||
|
||||
// Capture a backtrace which starts just before the function addressed
|
||||
// by `ip`
|
||||
fn create(ip: usize) -> Backtrace {
|
||||
let mut frames = Vec::new();
|
||||
let mut actual_start = None;
|
||||
backtrace::trace(|frame| {
|
||||
frames.push(BacktraceFrame {
|
||||
frame: frame.clone(),
|
||||
symbols: Vec::new(),
|
||||
});
|
||||
if frame.symbol_address() as usize == ip && actual_start.is_none() {
|
||||
actual_start = Some(frames.len() + 1);
|
||||
}
|
||||
true
|
||||
});
|
||||
|
||||
// If no frames came out assume that this is an unsupported platform
|
||||
// since `backtrace` doesn't provide a way of learning this right
|
||||
// now, and this should be a good enough approximation.
|
||||
let inner = if frames.is_empty() {
|
||||
Inner::Unsupported
|
||||
} else {
|
||||
Inner::Captured(LazilyResolvedCapture::new(Capture {
|
||||
actual_start: actual_start.unwrap_or(0),
|
||||
frames,
|
||||
resolved: false,
|
||||
}))
|
||||
};
|
||||
|
||||
Backtrace { inner }
|
||||
}
|
||||
|
||||
pub(crate) fn status(&self) -> BacktraceStatus {
|
||||
match self.inner {
|
||||
Inner::Unsupported => BacktraceStatus::Unsupported,
|
||||
Inner::Disabled => BacktraceStatus::Disabled,
|
||||
Inner::Captured(_) => BacktraceStatus::Captured,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Display for Backtrace {
|
||||
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
|
||||
let capture = match &self.inner {
|
||||
Inner::Unsupported => return fmt.write_str("unsupported backtrace"),
|
||||
Inner::Disabled => return fmt.write_str("disabled backtrace"),
|
||||
Inner::Captured(c) => c.force(),
|
||||
};
|
||||
|
||||
let full = fmt.alternate();
|
||||
let (frames, style) = if full {
|
||||
(&capture.frames[..], PrintFmt::Full)
|
||||
} else {
|
||||
(&capture.frames[capture.actual_start..], PrintFmt::Short)
|
||||
};
|
||||
|
||||
// When printing paths we try to strip the cwd if it exists,
|
||||
// otherwise we just print the path as-is. Note that we also only do
|
||||
// this for the short format, because if it's full we presumably
|
||||
// want to print everything.
|
||||
let cwd = env::current_dir();
|
||||
let mut print_path = move |fmt: &mut fmt::Formatter, path: BytesOrWideString| {
|
||||
output_filename(fmt, path, style, cwd.as_ref().ok())
|
||||
};
|
||||
|
||||
let mut f = BacktraceFmt::new(fmt, style, &mut print_path);
|
||||
f.add_context()?;
|
||||
for frame in frames {
|
||||
let mut f = f.frame();
|
||||
if frame.symbols.is_empty() {
|
||||
f.print_raw(frame.frame.ip(), None, None, None)?;
|
||||
} else {
|
||||
for symbol in frame.symbols.iter() {
|
||||
f.print_raw_with_column(
|
||||
frame.frame.ip(),
|
||||
symbol.name.as_ref().map(|b| SymbolName::new(b)),
|
||||
symbol.filename.as_ref().map(|b| match b {
|
||||
BytesOrWide::Bytes(w) => BytesOrWideString::Bytes(w),
|
||||
BytesOrWide::Wide(w) => BytesOrWideString::Wide(w),
|
||||
}),
|
||||
symbol.lineno,
|
||||
symbol.colno,
|
||||
)?;
|
||||
}
|
||||
}
|
||||
}
|
||||
f.finish()?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
struct LazilyResolvedCapture {
|
||||
sync: Once,
|
||||
capture: UnsafeCell<Capture>,
|
||||
}
|
||||
|
||||
impl LazilyResolvedCapture {
|
||||
fn new(capture: Capture) -> Self {
|
||||
LazilyResolvedCapture {
|
||||
sync: Once::new(),
|
||||
capture: UnsafeCell::new(capture),
|
||||
}
|
||||
}
|
||||
|
||||
fn force(&self) -> &Capture {
|
||||
self.sync.call_once(|| {
|
||||
// Safety: This exclusive reference can't overlap with any
|
||||
// others. `Once` guarantees callers will block until this
|
||||
// closure returns. `Once` also guarantees only a single caller
|
||||
// will enter this closure.
|
||||
unsafe { &mut *self.capture.get() }.resolve();
|
||||
});
|
||||
|
||||
// Safety: This shared reference can't overlap with the exclusive
|
||||
// reference above.
|
||||
unsafe { &*self.capture.get() }
|
||||
}
|
||||
}
|
||||
|
||||
// Safety: Access to the inner value is synchronized using a thread-safe
|
||||
// `Once`. So long as `Capture` is `Sync`, `LazilyResolvedCapture` is too
|
||||
unsafe impl Sync for LazilyResolvedCapture where Capture: Sync {}
|
||||
|
||||
impl Capture {
|
||||
fn resolve(&mut self) {
|
||||
// If we're already resolved, nothing to do!
|
||||
if self.resolved {
|
||||
return;
|
||||
}
|
||||
self.resolved = true;
|
||||
|
||||
for frame in self.frames.iter_mut() {
|
||||
let symbols = &mut frame.symbols;
|
||||
let frame = &frame.frame;
|
||||
backtrace::resolve_frame(frame, |symbol| {
|
||||
symbols.push(BacktraceSymbol {
|
||||
name: symbol.name().map(|m| m.as_bytes().to_vec()),
|
||||
filename: symbol.filename_raw().map(|b| match b {
|
||||
BytesOrWideString::Bytes(b) => BytesOrWide::Bytes(b.to_owned()),
|
||||
BytesOrWideString::Wide(b) => BytesOrWide::Wide(b.to_owned()),
|
||||
}),
|
||||
lineno: symbol.lineno(),
|
||||
colno: symbol.colno(),
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Prints the filename of the backtrace frame.
|
||||
fn output_filename(
|
||||
fmt: &mut fmt::Formatter,
|
||||
bows: BytesOrWideString,
|
||||
print_fmt: PrintFmt,
|
||||
cwd: Option<&PathBuf>,
|
||||
) -> fmt::Result {
|
||||
let file: Cow<Path> = match bows {
|
||||
#[cfg(unix)]
|
||||
BytesOrWideString::Bytes(bytes) => {
|
||||
use std::os::unix::ffi::OsStrExt;
|
||||
Path::new(std::ffi::OsStr::from_bytes(bytes)).into()
|
||||
}
|
||||
#[cfg(not(unix))]
|
||||
BytesOrWideString::Bytes(bytes) => {
|
||||
Path::new(std::str::from_utf8(bytes).unwrap_or("<unknown>")).into()
|
||||
}
|
||||
#[cfg(windows)]
|
||||
BytesOrWideString::Wide(wide) => {
|
||||
use std::os::windows::ffi::OsStringExt;
|
||||
Cow::Owned(std::ffi::OsString::from_wide(wide).into())
|
||||
}
|
||||
#[cfg(not(windows))]
|
||||
BytesOrWideString::Wide(_wide) => Path::new("<unknown>").into(),
|
||||
};
|
||||
if print_fmt == PrintFmt::Short && file.is_absolute() {
|
||||
if let Some(cwd) = cwd {
|
||||
if let Ok(stripped) = file.strip_prefix(&cwd) {
|
||||
if let Some(s) = stripped.to_str() {
|
||||
return write!(fmt, ".{}{}", path::MAIN_SEPARATOR, s);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Display::fmt(&file.display(), fmt)
|
||||
}
|
||||
}
|
||||
|
||||
fn _assert_send_sync() {
|
||||
fn _assert<T: Send + Sync>() {}
|
||||
_assert::<Backtrace>();
|
||||
}
|
102
vendor/anyhow/src/chain.rs
vendored
Normal file
102
vendor/anyhow/src/chain.rs
vendored
Normal file
@ -0,0 +1,102 @@
|
||||
use self::ChainState::*;
|
||||
use crate::StdError;
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
use std::vec;
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
pub(crate) use crate::Chain;
|
||||
|
||||
#[cfg(not(feature = "std"))]
|
||||
pub(crate) struct Chain<'a> {
|
||||
state: ChainState<'a>,
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub(crate) enum ChainState<'a> {
|
||||
Linked {
|
||||
next: Option<&'a (dyn StdError + 'static)>,
|
||||
},
|
||||
#[cfg(feature = "std")]
|
||||
Buffered {
|
||||
rest: vec::IntoIter<&'a (dyn StdError + 'static)>,
|
||||
},
|
||||
}
|
||||
|
||||
impl<'a> Chain<'a> {
|
||||
#[cold]
|
||||
pub fn new(head: &'a (dyn StdError + 'static)) -> Self {
|
||||
Chain {
|
||||
state: ChainState::Linked { next: Some(head) },
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Iterator for Chain<'a> {
|
||||
type Item = &'a (dyn StdError + 'static);
|
||||
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
match &mut self.state {
|
||||
Linked { next } => {
|
||||
let error = (*next)?;
|
||||
*next = error.source();
|
||||
Some(error)
|
||||
}
|
||||
#[cfg(feature = "std")]
|
||||
Buffered { rest } => rest.next(),
|
||||
}
|
||||
}
|
||||
|
||||
fn size_hint(&self) -> (usize, Option<usize>) {
|
||||
let len = self.len();
|
||||
(len, Some(len))
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
impl DoubleEndedIterator for Chain<'_> {
|
||||
fn next_back(&mut self) -> Option<Self::Item> {
|
||||
match &mut self.state {
|
||||
Linked { mut next } => {
|
||||
let mut rest = Vec::new();
|
||||
while let Some(cause) = next {
|
||||
next = cause.source();
|
||||
rest.push(cause);
|
||||
}
|
||||
let mut rest = rest.into_iter();
|
||||
let last = rest.next_back();
|
||||
self.state = Buffered { rest };
|
||||
last
|
||||
}
|
||||
Buffered { rest } => rest.next_back(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ExactSizeIterator for Chain<'_> {
|
||||
fn len(&self) -> usize {
|
||||
match &self.state {
|
||||
Linked { mut next } => {
|
||||
let mut len = 0;
|
||||
while let Some(cause) = next {
|
||||
next = cause.source();
|
||||
len += 1;
|
||||
}
|
||||
len
|
||||
}
|
||||
#[cfg(feature = "std")]
|
||||
Buffered { rest } => rest.len(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
impl Default for Chain<'_> {
|
||||
fn default() -> Self {
|
||||
Chain {
|
||||
state: ChainState::Buffered {
|
||||
rest: Vec::new().into_iter(),
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
178
vendor/anyhow/src/context.rs
vendored
Normal file
178
vendor/anyhow/src/context.rs
vendored
Normal file
@ -0,0 +1,178 @@
|
||||
use crate::error::ContextError;
|
||||
use crate::{Context, Error, StdError};
|
||||
use core::convert::Infallible;
|
||||
use core::fmt::{self, Debug, Display, Write};
|
||||
|
||||
#[cfg(backtrace)]
|
||||
use std::any::Demand;
|
||||
|
||||
mod ext {
|
||||
use super::*;
|
||||
|
||||
pub trait StdError {
|
||||
fn ext_context<C>(self, context: C) -> Error
|
||||
where
|
||||
C: Display + Send + Sync + 'static;
|
||||
}
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
impl<E> StdError for E
|
||||
where
|
||||
E: std::error::Error + Send + Sync + 'static,
|
||||
{
|
||||
fn ext_context<C>(self, context: C) -> Error
|
||||
where
|
||||
C: Display + Send + Sync + 'static,
|
||||
{
|
||||
let backtrace = backtrace_if_absent!(&self);
|
||||
Error::from_context(context, self, backtrace)
|
||||
}
|
||||
}
|
||||
|
||||
impl StdError for Error {
|
||||
fn ext_context<C>(self, context: C) -> Error
|
||||
where
|
||||
C: Display + Send + Sync + 'static,
|
||||
{
|
||||
self.context(context)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T, E> Context<T, E> for Result<T, E>
|
||||
where
|
||||
E: ext::StdError + Send + Sync + 'static,
|
||||
{
|
||||
fn context<C>(self, context: C) -> Result<T, Error>
|
||||
where
|
||||
C: Display + Send + Sync + 'static,
|
||||
{
|
||||
self.map_err(|error| error.ext_context(context))
|
||||
}
|
||||
|
||||
fn with_context<C, F>(self, context: F) -> Result<T, Error>
|
||||
where
|
||||
C: Display + Send + Sync + 'static,
|
||||
F: FnOnce() -> C,
|
||||
{
|
||||
self.map_err(|error| error.ext_context(context()))
|
||||
}
|
||||
}
|
||||
|
||||
/// ```
|
||||
/// # type T = ();
|
||||
/// #
|
||||
/// use anyhow::{Context, Result};
|
||||
///
|
||||
/// fn maybe_get() -> Option<T> {
|
||||
/// # const IGNORE: &str = stringify! {
|
||||
/// ...
|
||||
/// # };
|
||||
/// # unimplemented!()
|
||||
/// }
|
||||
///
|
||||
/// fn demo() -> Result<()> {
|
||||
/// let t = maybe_get().context("there is no T")?;
|
||||
/// # const IGNORE: &str = stringify! {
|
||||
/// ...
|
||||
/// # };
|
||||
/// # unimplemented!()
|
||||
/// }
|
||||
/// ```
|
||||
impl<T> Context<T, Infallible> for Option<T> {
|
||||
fn context<C>(self, context: C) -> Result<T, Error>
|
||||
where
|
||||
C: Display + Send + Sync + 'static,
|
||||
{
|
||||
self.ok_or_else(|| Error::from_display(context, backtrace!()))
|
||||
}
|
||||
|
||||
fn with_context<C, F>(self, context: F) -> Result<T, Error>
|
||||
where
|
||||
C: Display + Send + Sync + 'static,
|
||||
F: FnOnce() -> C,
|
||||
{
|
||||
self.ok_or_else(|| Error::from_display(context(), backtrace!()))
|
||||
}
|
||||
}
|
||||
|
||||
impl<C, E> Debug for ContextError<C, E>
|
||||
where
|
||||
C: Display,
|
||||
E: Debug,
|
||||
{
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
f.debug_struct("Error")
|
||||
.field("context", &Quoted(&self.context))
|
||||
.field("source", &self.error)
|
||||
.finish()
|
||||
}
|
||||
}
|
||||
|
||||
impl<C, E> Display for ContextError<C, E>
|
||||
where
|
||||
C: Display,
|
||||
{
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
Display::fmt(&self.context, f)
|
||||
}
|
||||
}
|
||||
|
||||
impl<C, E> StdError for ContextError<C, E>
|
||||
where
|
||||
C: Display,
|
||||
E: StdError + 'static,
|
||||
{
|
||||
fn source(&self) -> Option<&(dyn StdError + 'static)> {
|
||||
Some(&self.error)
|
||||
}
|
||||
|
||||
#[cfg(backtrace)]
|
||||
fn provide<'a>(&'a self, demand: &mut Demand<'a>) {
|
||||
self.error.provide(demand);
|
||||
}
|
||||
}
|
||||
|
||||
impl<C> StdError for ContextError<C, Error>
|
||||
where
|
||||
C: Display,
|
||||
{
|
||||
fn source(&self) -> Option<&(dyn StdError + 'static)> {
|
||||
Some(unsafe { crate::ErrorImpl::error(self.error.inner.by_ref()) })
|
||||
}
|
||||
|
||||
#[cfg(backtrace)]
|
||||
fn provide<'a>(&'a self, demand: &mut Demand<'a>) {
|
||||
demand.provide_ref(self.error.backtrace());
|
||||
self.error.provide(demand);
|
||||
}
|
||||
}
|
||||
|
||||
struct Quoted<C>(C);
|
||||
|
||||
impl<C> Debug for Quoted<C>
|
||||
where
|
||||
C: Display,
|
||||
{
|
||||
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
|
||||
formatter.write_char('"')?;
|
||||
Quoted(&mut *formatter).write_fmt(format_args!("{}", self.0))?;
|
||||
formatter.write_char('"')?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl Write for Quoted<&mut fmt::Formatter<'_>> {
|
||||
fn write_str(&mut self, s: &str) -> fmt::Result {
|
||||
Display::fmt(&s.escape_debug(), self.0)
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) mod private {
|
||||
use super::*;
|
||||
|
||||
pub trait Sealed {}
|
||||
|
||||
impl<T, E> Sealed for Result<T, E> where E: ext::StdError {}
|
||||
impl<T> Sealed for Option<T> {}
|
||||
}
|
834
vendor/anyhow/src/ensure.rs
vendored
Normal file
834
vendor/anyhow/src/ensure.rs
vendored
Normal file
@ -0,0 +1,834 @@
|
||||
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)*) :: <- $($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 $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)*} $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)*) :: <- $($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)*));
|
||||
}
|
||||
};
|
||||
}
|
992
vendor/anyhow/src/error.rs
vendored
Normal file
992
vendor/anyhow/src/error.rs
vendored
Normal file
@ -0,0 +1,992 @@
|
||||
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;
|
||||
#[cfg(backtrace)]
|
||||
use core::any::Demand;
|
||||
use core::any::TypeId;
|
||||
use core::fmt::{self, Debug, Display};
|
||||
use core::mem::ManuallyDrop;
|
||||
#[cfg(not(anyhow_no_ptr_addr_of))]
|
||||
use core::ptr;
|
||||
use core::ptr::NonNull;
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
use core::ops::{Deref, DerefMut};
|
||||
|
||||
impl Error {
|
||||
/// Create a new error object from any error type.
|
||||
///
|
||||
/// The error type must be threadsafe and `'static`, so that the `Error`
|
||||
/// will be as well.
|
||||
///
|
||||
/// If the error type does not provide a backtrace, a backtrace will be
|
||||
/// created here to ensure that a backtrace exists.
|
||||
#[cfg(feature = "std")]
|
||||
#[cfg_attr(doc_cfg, doc(cfg(feature = "std")))]
|
||||
#[cold]
|
||||
#[must_use]
|
||||
pub fn new<E>(error: E) -> Self
|
||||
where
|
||||
E: StdError + Send + Sync + 'static,
|
||||
{
|
||||
let backtrace = backtrace_if_absent!(&error);
|
||||
Error::from_std(error, backtrace)
|
||||
}
|
||||
|
||||
/// Create a new error object from a printable error message.
|
||||
///
|
||||
/// If the argument implements std::error::Error, prefer `Error::new`
|
||||
/// instead which preserves the underlying error's cause chain and
|
||||
/// backtrace. If the argument may or may not implement std::error::Error
|
||||
/// now or in the future, use `anyhow!(err)` which handles either way
|
||||
/// correctly.
|
||||
///
|
||||
/// `Error::msg("...")` is equivalent to `anyhow!("...")` but occasionally
|
||||
/// convenient in places where a function is preferable over a macro, such
|
||||
/// as iterator or stream combinators:
|
||||
///
|
||||
/// ```
|
||||
/// # mod ffi {
|
||||
/// # pub struct Input;
|
||||
/// # pub struct Output;
|
||||
/// # pub async fn do_some_work(_: Input) -> Result<Output, &'static str> {
|
||||
/// # unimplemented!()
|
||||
/// # }
|
||||
/// # }
|
||||
/// #
|
||||
/// # use ffi::{Input, Output};
|
||||
/// #
|
||||
/// use anyhow::{Error, Result};
|
||||
/// use futures::stream::{Stream, StreamExt, TryStreamExt};
|
||||
///
|
||||
/// async fn demo<S>(stream: S) -> Result<Vec<Output>>
|
||||
/// where
|
||||
/// S: Stream<Item = Input>,
|
||||
/// {
|
||||
/// stream
|
||||
/// .then(ffi::do_some_work) // returns Result<Output, &str>
|
||||
/// .map_err(Error::msg)
|
||||
/// .try_collect()
|
||||
/// .await
|
||||
/// }
|
||||
/// ```
|
||||
#[cold]
|
||||
#[must_use]
|
||||
pub fn msg<M>(message: M) -> Self
|
||||
where
|
||||
M: Display + Debug + Send + Sync + 'static,
|
||||
{
|
||||
Error::from_adhoc(message, backtrace!())
|
||||
}
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
#[cold]
|
||||
pub(crate) fn from_std<E>(error: E, backtrace: Option<Backtrace>) -> Self
|
||||
where
|
||||
E: StdError + Send + Sync + 'static,
|
||||
{
|
||||
let vtable = &ErrorVTable {
|
||||
object_drop: object_drop::<E>,
|
||||
object_ref: object_ref::<E>,
|
||||
#[cfg(anyhow_no_ptr_addr_of)]
|
||||
object_mut: object_mut::<E>,
|
||||
object_boxed: object_boxed::<E>,
|
||||
object_downcast: object_downcast::<E>,
|
||||
#[cfg(anyhow_no_ptr_addr_of)]
|
||||
object_downcast_mut: object_downcast_mut::<E>,
|
||||
object_drop_rest: object_drop_front::<E>,
|
||||
#[cfg(all(not(backtrace), feature = "backtrace"))]
|
||||
object_backtrace: no_backtrace,
|
||||
};
|
||||
|
||||
// Safety: passing vtable that operates on the right type E.
|
||||
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,
|
||||
{
|
||||
use crate::wrapper::MessageError;
|
||||
let error: MessageError<M> = MessageError(message);
|
||||
let vtable = &ErrorVTable {
|
||||
object_drop: object_drop::<MessageError<M>>,
|
||||
object_ref: object_ref::<MessageError<M>>,
|
||||
#[cfg(all(feature = "std", anyhow_no_ptr_addr_of))]
|
||||
object_mut: object_mut::<MessageError<M>>,
|
||||
object_boxed: object_boxed::<MessageError<M>>,
|
||||
object_downcast: object_downcast::<M>,
|
||||
#[cfg(anyhow_no_ptr_addr_of)]
|
||||
object_downcast_mut: object_downcast_mut::<M>,
|
||||
object_drop_rest: object_drop_front::<M>,
|
||||
#[cfg(all(not(backtrace), feature = "backtrace"))]
|
||||
object_backtrace: no_backtrace,
|
||||
};
|
||||
|
||||
// Safety: MessageError is repr(transparent) so it is okay for the
|
||||
// vtable to allow casting the MessageError<M> to M.
|
||||
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,
|
||||
{
|
||||
use crate::wrapper::DisplayError;
|
||||
let error: DisplayError<M> = DisplayError(message);
|
||||
let vtable = &ErrorVTable {
|
||||
object_drop: object_drop::<DisplayError<M>>,
|
||||
object_ref: object_ref::<DisplayError<M>>,
|
||||
#[cfg(all(feature = "std", anyhow_no_ptr_addr_of))]
|
||||
object_mut: object_mut::<DisplayError<M>>,
|
||||
object_boxed: object_boxed::<DisplayError<M>>,
|
||||
object_downcast: object_downcast::<M>,
|
||||
#[cfg(anyhow_no_ptr_addr_of)]
|
||||
object_downcast_mut: object_downcast_mut::<M>,
|
||||
object_drop_rest: object_drop_front::<M>,
|
||||
#[cfg(all(not(backtrace), feature = "backtrace"))]
|
||||
object_backtrace: no_backtrace,
|
||||
};
|
||||
|
||||
// Safety: DisplayError is repr(transparent) so it is okay for the
|
||||
// vtable to allow casting the DisplayError<M> to M.
|
||||
unsafe { Error::construct(error, vtable, backtrace) }
|
||||
}
|
||||
|
||||
#[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,
|
||||
E: StdError + Send + Sync + 'static,
|
||||
{
|
||||
let error: ContextError<C, E> = ContextError { context, error };
|
||||
|
||||
let vtable = &ErrorVTable {
|
||||
object_drop: object_drop::<ContextError<C, E>>,
|
||||
object_ref: object_ref::<ContextError<C, E>>,
|
||||
#[cfg(anyhow_no_ptr_addr_of)]
|
||||
object_mut: object_mut::<ContextError<C, E>>,
|
||||
object_boxed: object_boxed::<ContextError<C, E>>,
|
||||
object_downcast: context_downcast::<C, E>,
|
||||
#[cfg(anyhow_no_ptr_addr_of)]
|
||||
object_downcast_mut: context_downcast_mut::<C, E>,
|
||||
object_drop_rest: context_drop_rest::<C, E>,
|
||||
#[cfg(all(not(backtrace), feature = "backtrace"))]
|
||||
object_backtrace: no_backtrace,
|
||||
};
|
||||
|
||||
// Safety: passing vtable that operates on the right type.
|
||||
unsafe { Error::construct(error, vtable, backtrace) }
|
||||
}
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
#[cold]
|
||||
pub(crate) fn from_boxed(
|
||||
error: Box<dyn StdError + Send + Sync>,
|
||||
backtrace: Option<Backtrace>,
|
||||
) -> Self {
|
||||
use crate::wrapper::BoxedError;
|
||||
let error = BoxedError(error);
|
||||
let vtable = &ErrorVTable {
|
||||
object_drop: object_drop::<BoxedError>,
|
||||
object_ref: object_ref::<BoxedError>,
|
||||
#[cfg(anyhow_no_ptr_addr_of)]
|
||||
object_mut: object_mut::<BoxedError>,
|
||||
object_boxed: object_boxed::<BoxedError>,
|
||||
object_downcast: object_downcast::<Box<dyn StdError + Send + Sync>>,
|
||||
#[cfg(anyhow_no_ptr_addr_of)]
|
||||
object_downcast_mut: object_downcast_mut::<Box<dyn StdError + Send + Sync>>,
|
||||
object_drop_rest: object_drop_front::<Box<dyn StdError + Send + Sync>>,
|
||||
#[cfg(all(not(backtrace), feature = "backtrace"))]
|
||||
object_backtrace: no_backtrace,
|
||||
};
|
||||
|
||||
// Safety: BoxedError is repr(transparent) so it is okay for the vtable
|
||||
// to allow casting to Box<dyn StdError + Send + Sync>.
|
||||
unsafe { Error::construct(error, vtable, backtrace) }
|
||||
}
|
||||
|
||||
// Takes backtrace as argument rather than capturing it here so that the
|
||||
// user sees one fewer layer of wrapping noise in the backtrace.
|
||||
//
|
||||
// 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,
|
||||
backtrace: Option<Backtrace>,
|
||||
) -> Self
|
||||
where
|
||||
E: StdError + Send + Sync + 'static,
|
||||
{
|
||||
let inner: Box<ErrorImpl<E>> = Box::new(ErrorImpl {
|
||||
vtable,
|
||||
backtrace,
|
||||
_object: error,
|
||||
});
|
||||
// Erase the concrete type of E from the compile-time type system. This
|
||||
// is equivalent to the safe unsize coercion from Box<ErrorImpl<E>> to
|
||||
// Box<ErrorImpl<dyn StdError + Send + Sync + 'static>> except that the
|
||||
// result is a thin pointer. The necessary behavior for manipulating the
|
||||
// underlying ErrorImpl<E> is preserved in the vtable provided by the
|
||||
// caller rather than a builtin fat pointer vtable.
|
||||
let inner = Own::new(inner).cast::<ErrorImpl>();
|
||||
Error { inner }
|
||||
}
|
||||
|
||||
/// Wrap the error value with additional context.
|
||||
///
|
||||
/// For attaching context to a `Result` as it is propagated, the
|
||||
/// [`Context`][crate::Context] extension trait may be more convenient than
|
||||
/// this function.
|
||||
///
|
||||
/// The primary reason to use `error.context(...)` instead of
|
||||
/// `result.context(...)` via the `Context` trait would be if the context
|
||||
/// needs to depend on some data held by the underlying error:
|
||||
///
|
||||
/// ```
|
||||
/// # use std::fmt::{self, Debug, Display};
|
||||
/// #
|
||||
/// # type T = ();
|
||||
/// #
|
||||
/// # impl std::error::Error for ParseError {}
|
||||
/// # impl Debug for ParseError {
|
||||
/// # fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
|
||||
/// # unimplemented!()
|
||||
/// # }
|
||||
/// # }
|
||||
/// # impl Display for ParseError {
|
||||
/// # fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
|
||||
/// # unimplemented!()
|
||||
/// # }
|
||||
/// # }
|
||||
/// #
|
||||
/// use anyhow::Result;
|
||||
/// use std::fs::File;
|
||||
/// use std::path::Path;
|
||||
///
|
||||
/// struct ParseError {
|
||||
/// line: usize,
|
||||
/// column: usize,
|
||||
/// }
|
||||
///
|
||||
/// fn parse_impl(file: File) -> Result<T, ParseError> {
|
||||
/// # const IGNORE: &str = stringify! {
|
||||
/// ...
|
||||
/// # };
|
||||
/// # unimplemented!()
|
||||
/// }
|
||||
///
|
||||
/// pub fn parse(path: impl AsRef<Path>) -> Result<T> {
|
||||
/// let file = File::open(&path)?;
|
||||
/// parse_impl(file).map_err(|error| {
|
||||
/// let context = format!(
|
||||
/// "only the first {} lines of {} are valid",
|
||||
/// error.line, path.as_ref().display(),
|
||||
/// );
|
||||
/// anyhow::Error::new(error).context(context)
|
||||
/// })
|
||||
/// }
|
||||
/// ```
|
||||
#[cold]
|
||||
#[must_use]
|
||||
pub fn context<C>(self, context: C) -> Self
|
||||
where
|
||||
C: Display + Send + Sync + 'static,
|
||||
{
|
||||
let error: ContextError<C, Error> = ContextError {
|
||||
context,
|
||||
error: self,
|
||||
};
|
||||
|
||||
let vtable = &ErrorVTable {
|
||||
object_drop: object_drop::<ContextError<C, Error>>,
|
||||
object_ref: object_ref::<ContextError<C, Error>>,
|
||||
#[cfg(all(feature = "std", anyhow_no_ptr_addr_of))]
|
||||
object_mut: object_mut::<ContextError<C, Error>>,
|
||||
object_boxed: object_boxed::<ContextError<C, Error>>,
|
||||
object_downcast: context_chain_downcast::<C>,
|
||||
#[cfg(anyhow_no_ptr_addr_of)]
|
||||
object_downcast_mut: context_chain_downcast_mut::<C>,
|
||||
object_drop_rest: context_chain_drop_rest::<C>,
|
||||
#[cfg(all(not(backtrace), feature = "backtrace"))]
|
||||
object_backtrace: context_backtrace::<C>,
|
||||
};
|
||||
|
||||
// As the cause is anyhow::Error, we already have a backtrace for it.
|
||||
let backtrace = None;
|
||||
|
||||
// Safety: passing vtable that operates on the right type.
|
||||
unsafe { Error::construct(error, vtable, backtrace) }
|
||||
}
|
||||
|
||||
/// Get the backtrace for this Error.
|
||||
///
|
||||
/// In order for the backtrace to be meaningful, one of the two environment
|
||||
/// variables `RUST_LIB_BACKTRACE=1` or `RUST_BACKTRACE=1` must be defined
|
||||
/// and `RUST_LIB_BACKTRACE` must not be `0`. Backtraces are somewhat
|
||||
/// expensive to capture in Rust, so we don't necessarily want to be
|
||||
/// capturing them all over the place all the time.
|
||||
///
|
||||
/// - If you want panics and errors to both have backtraces, set
|
||||
/// `RUST_BACKTRACE=1`;
|
||||
/// - If you want only errors to have backtraces, set
|
||||
/// `RUST_LIB_BACKTRACE=1`;
|
||||
/// - If you want only panics to have backtraces, set `RUST_BACKTRACE=1` and
|
||||
/// `RUST_LIB_BACKTRACE=0`.
|
||||
///
|
||||
/// # Stability
|
||||
///
|
||||
/// Standard library backtraces are only available on the nightly channel.
|
||||
/// Tracking issue: [rust-lang/rust#53487][tracking].
|
||||
///
|
||||
/// On stable compilers, this function is only available if the crate's
|
||||
/// "backtrace" feature is enabled, and will use the `backtrace` crate as
|
||||
/// the underlying backtrace implementation.
|
||||
///
|
||||
/// ```toml
|
||||
/// [dependencies]
|
||||
/// anyhow = { version = "1.0", features = ["backtrace"] }
|
||||
/// ```
|
||||
///
|
||||
/// [tracking]: https://github.com/rust-lang/rust/issues/53487
|
||||
#[cfg(any(backtrace, feature = "backtrace"))]
|
||||
#[cfg_attr(doc_cfg, doc(cfg(any(nightly, feature = "backtrace"))))]
|
||||
pub fn backtrace(&self) -> &impl_backtrace!() {
|
||||
unsafe { ErrorImpl::backtrace(self.inner.by_ref()) }
|
||||
}
|
||||
|
||||
/// An iterator of the chain of source errors contained by this Error.
|
||||
///
|
||||
/// This iterator will visit every error in the cause chain of this error
|
||||
/// object, beginning with the error that this error object was created
|
||||
/// from.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```
|
||||
/// use anyhow::Error;
|
||||
/// use std::io;
|
||||
///
|
||||
/// pub fn underlying_io_error_kind(error: &Error) -> Option<io::ErrorKind> {
|
||||
/// for cause in error.chain() {
|
||||
/// if let Some(io_error) = cause.downcast_ref::<io::Error>() {
|
||||
/// return Some(io_error.kind());
|
||||
/// }
|
||||
/// }
|
||||
/// None
|
||||
/// }
|
||||
/// ```
|
||||
#[cfg(feature = "std")]
|
||||
#[cfg_attr(doc_cfg, doc(cfg(feature = "std")))]
|
||||
#[cold]
|
||||
pub fn chain(&self) -> Chain {
|
||||
unsafe { ErrorImpl::chain(self.inner.by_ref()) }
|
||||
}
|
||||
|
||||
/// The lowest level cause of this error — this error's cause's
|
||||
/// cause's cause etc.
|
||||
///
|
||||
/// The root cause is the last error in the iterator produced by
|
||||
/// [`chain()`][Error::chain].
|
||||
#[cfg(feature = "std")]
|
||||
#[cfg_attr(doc_cfg, doc(cfg(feature = "std")))]
|
||||
pub fn root_cause(&self) -> &(dyn StdError + 'static) {
|
||||
self.chain().last().unwrap()
|
||||
}
|
||||
|
||||
/// Returns true if `E` is the type held by this error object.
|
||||
///
|
||||
/// For errors with context, this method returns true if `E` matches the
|
||||
/// type of the context `C` **or** the type of the error on which the
|
||||
/// context has been attached. For details about the interaction between
|
||||
/// context and downcasting, [see here].
|
||||
///
|
||||
/// [see here]: trait.Context.html#effect-on-downcasting
|
||||
pub fn is<E>(&self) -> bool
|
||||
where
|
||||
E: Display + Debug + Send + Sync + 'static,
|
||||
{
|
||||
self.downcast_ref::<E>().is_some()
|
||||
}
|
||||
|
||||
/// Attempt to downcast the error object to a concrete type.
|
||||
pub fn downcast<E>(mut self) -> Result<E, Self>
|
||||
where
|
||||
E: Display + Debug + Send + Sync + 'static,
|
||||
{
|
||||
let target = TypeId::of::<E>();
|
||||
let inner = self.inner.by_mut();
|
||||
unsafe {
|
||||
// Use vtable to find NonNull<()> which points to a value of type E
|
||||
// somewhere inside the data structure.
|
||||
#[cfg(not(anyhow_no_ptr_addr_of))]
|
||||
let addr = match (vtable(inner.ptr).object_downcast)(inner.by_ref(), target) {
|
||||
Some(addr) => addr.by_mut().extend(),
|
||||
None => return Err(self),
|
||||
};
|
||||
#[cfg(anyhow_no_ptr_addr_of)]
|
||||
let addr = match (vtable(inner.ptr).object_downcast_mut)(inner, target) {
|
||||
Some(addr) => addr.extend(),
|
||||
None => return Err(self),
|
||||
};
|
||||
|
||||
// Prepare to read E out of the data structure. We'll drop the rest
|
||||
// of the data structure separately so that E is not dropped.
|
||||
let outer = ManuallyDrop::new(self);
|
||||
|
||||
// Read E from where the vtable found it.
|
||||
let error = addr.cast::<E>().read();
|
||||
|
||||
// Drop rest of the data structure outside of E.
|
||||
(vtable(outer.inner.ptr).object_drop_rest)(outer.inner, target);
|
||||
|
||||
Ok(error)
|
||||
}
|
||||
}
|
||||
|
||||
/// Downcast this error object by reference.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```
|
||||
/// # use anyhow::anyhow;
|
||||
/// # use std::fmt::{self, Display};
|
||||
/// # use std::task::Poll;
|
||||
/// #
|
||||
/// # #[derive(Debug)]
|
||||
/// # enum DataStoreError {
|
||||
/// # Censored(()),
|
||||
/// # }
|
||||
/// #
|
||||
/// # impl Display for DataStoreError {
|
||||
/// # fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
|
||||
/// # unimplemented!()
|
||||
/// # }
|
||||
/// # }
|
||||
/// #
|
||||
/// # impl std::error::Error for DataStoreError {}
|
||||
/// #
|
||||
/// # const REDACTED_CONTENT: () = ();
|
||||
/// #
|
||||
/// # let error = anyhow!("...");
|
||||
/// # let root_cause = &error;
|
||||
/// #
|
||||
/// # let ret =
|
||||
/// // If the error was caused by redaction, then return a tombstone instead
|
||||
/// // of the content.
|
||||
/// match root_cause.downcast_ref::<DataStoreError>() {
|
||||
/// Some(DataStoreError::Censored(_)) => Ok(Poll::Ready(REDACTED_CONTENT)),
|
||||
/// None => Err(error),
|
||||
/// }
|
||||
/// # ;
|
||||
/// ```
|
||||
pub fn downcast_ref<E>(&self) -> Option<&E>
|
||||
where
|
||||
E: Display + Debug + Send + Sync + 'static,
|
||||
{
|
||||
let target = TypeId::of::<E>();
|
||||
unsafe {
|
||||
// Use vtable to find NonNull<()> which points to a value of type E
|
||||
// somewhere inside the data structure.
|
||||
let addr = (vtable(self.inner.ptr).object_downcast)(self.inner.by_ref(), target)?;
|
||||
Some(addr.cast::<E>().deref())
|
||||
}
|
||||
}
|
||||
|
||||
/// Downcast this error object by mutable reference.
|
||||
pub fn downcast_mut<E>(&mut self) -> Option<&mut E>
|
||||
where
|
||||
E: Display + Debug + Send + Sync + 'static,
|
||||
{
|
||||
let target = TypeId::of::<E>();
|
||||
unsafe {
|
||||
// Use vtable to find NonNull<()> which points to a value of type E
|
||||
// somewhere inside the data structure.
|
||||
|
||||
#[cfg(not(anyhow_no_ptr_addr_of))]
|
||||
let addr =
|
||||
(vtable(self.inner.ptr).object_downcast)(self.inner.by_ref(), target)?.by_mut();
|
||||
|
||||
#[cfg(anyhow_no_ptr_addr_of)]
|
||||
let addr = (vtable(self.inner.ptr).object_downcast_mut)(self.inner.by_mut(), target)?;
|
||||
|
||||
Some(addr.cast::<E>().deref_mut())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(backtrace)]
|
||||
impl std::any::Provider for Error {
|
||||
// Called by thiserror when you have `#[source] anyhow::Error`. This provide
|
||||
// implementation includes the anyhow::Error's Backtrace if any, unlike
|
||||
// deref'ing to dyn Error where the provide implementation would include
|
||||
// only the original error's Backtrace from before it got wrapped into an
|
||||
// anyhow::Error.
|
||||
fn provide<'a>(&'a self, demand: &mut Demand<'a>) {
|
||||
unsafe { ErrorImpl::provide(self.inner.by_ref(), demand) }
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
#[cfg_attr(doc_cfg, doc(cfg(feature = "std")))]
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
#[cfg_attr(doc_cfg, doc(cfg(feature = "std")))]
|
||||
impl Deref for Error {
|
||||
type Target = dyn StdError + Send + Sync + 'static;
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
unsafe { ErrorImpl::error(self.inner.by_ref()) }
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
#[cfg_attr(doc_cfg, doc(cfg(feature = "std")))]
|
||||
impl DerefMut for Error {
|
||||
fn deref_mut(&mut self) -> &mut Self::Target {
|
||||
unsafe { ErrorImpl::error_mut(self.inner.by_mut()) }
|
||||
}
|
||||
}
|
||||
|
||||
impl Display for Error {
|
||||
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
|
||||
unsafe { ErrorImpl::display(self.inner.by_ref(), formatter) }
|
||||
}
|
||||
}
|
||||
|
||||
impl Debug for Error {
|
||||
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
|
||||
unsafe { ErrorImpl::debug(self.inner.by_ref(), formatter) }
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for Error {
|
||||
fn drop(&mut self) {
|
||||
unsafe {
|
||||
// Invoke the vtable's drop behavior.
|
||||
(vtable(self.inner.ptr).object_drop)(self.inner);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct ErrorVTable {
|
||||
object_drop: unsafe fn(Own<ErrorImpl>),
|
||||
object_ref: unsafe fn(Ref<ErrorImpl>) -> Ref<dyn StdError + Send + Sync + 'static>,
|
||||
#[cfg(all(feature = "std", anyhow_no_ptr_addr_of))]
|
||||
object_mut: unsafe fn(Mut<ErrorImpl>) -> &mut (dyn StdError + Send + Sync + 'static),
|
||||
object_boxed: unsafe fn(Own<ErrorImpl>) -> Box<dyn StdError + Send + Sync + 'static>,
|
||||
object_downcast: unsafe fn(Ref<ErrorImpl>, TypeId) -> Option<Ref<()>>,
|
||||
#[cfg(anyhow_no_ptr_addr_of)]
|
||||
object_downcast_mut: unsafe fn(Mut<ErrorImpl>, TypeId) -> Option<Mut<()>>,
|
||||
object_drop_rest: unsafe fn(Own<ErrorImpl>, TypeId),
|
||||
#[cfg(all(not(backtrace), feature = "backtrace"))]
|
||||
object_backtrace: unsafe fn(Ref<ErrorImpl>) -> Option<&Backtrace>,
|
||||
}
|
||||
|
||||
// Safety: requires layout of *e to match ErrorImpl<E>.
|
||||
unsafe fn object_drop<E>(e: Own<ErrorImpl>) {
|
||||
// Cast back to ErrorImpl<E> so that the allocator receives the correct
|
||||
// Layout to deallocate the Box's memory.
|
||||
let unerased = e.cast::<ErrorImpl<E>>().boxed();
|
||||
drop(unerased);
|
||||
}
|
||||
|
||||
// Safety: requires layout of *e to match ErrorImpl<E>.
|
||||
unsafe fn object_drop_front<E>(e: Own<ErrorImpl>, target: TypeId) {
|
||||
// Drop the fields of ErrorImpl other than E as well as the Box allocation,
|
||||
// without dropping E itself. This is used by downcast after doing a
|
||||
// ptr::read to take ownership of the E.
|
||||
let _ = target;
|
||||
let unerased = e.cast::<ErrorImpl<ManuallyDrop<E>>>().boxed();
|
||||
drop(unerased);
|
||||
}
|
||||
|
||||
// Safety: requires layout of *e to match ErrorImpl<E>.
|
||||
unsafe fn object_ref<E>(e: Ref<ErrorImpl>) -> Ref<dyn StdError + Send + Sync + 'static>
|
||||
where
|
||||
E: StdError + Send + Sync + 'static,
|
||||
{
|
||||
// Attach E's native StdError vtable onto a pointer to self._object.
|
||||
|
||||
let unerased = e.cast::<ErrorImpl<E>>();
|
||||
|
||||
#[cfg(not(anyhow_no_ptr_addr_of))]
|
||||
return Ref::from_raw(NonNull::new_unchecked(
|
||||
ptr::addr_of!((*unerased.as_ptr())._object) as *mut E,
|
||||
));
|
||||
|
||||
#[cfg(anyhow_no_ptr_addr_of)]
|
||||
return Ref::new(&unerased.deref()._object);
|
||||
}
|
||||
|
||||
// Safety: requires layout of *e to match ErrorImpl<E>, and for `e` to be derived
|
||||
// from a `&mut`
|
||||
#[cfg(all(feature = "std", anyhow_no_ptr_addr_of))]
|
||||
unsafe fn object_mut<E>(e: Mut<ErrorImpl>) -> &mut (dyn StdError + Send + Sync + 'static)
|
||||
where
|
||||
E: StdError + Send + Sync + 'static,
|
||||
{
|
||||
// Attach E's native StdError vtable onto a pointer to self._object.
|
||||
&mut e.cast::<ErrorImpl<E>>().deref_mut()._object
|
||||
}
|
||||
|
||||
// Safety: requires layout of *e to match ErrorImpl<E>.
|
||||
unsafe fn object_boxed<E>(e: Own<ErrorImpl>) -> Box<dyn StdError + Send + Sync + 'static>
|
||||
where
|
||||
E: StdError + Send + Sync + 'static,
|
||||
{
|
||||
// Attach ErrorImpl<E>'s native StdError vtable. The StdError impl is below.
|
||||
e.cast::<ErrorImpl<E>>().boxed()
|
||||
}
|
||||
|
||||
// Safety: requires layout of *e to match ErrorImpl<E>.
|
||||
unsafe fn object_downcast<E>(e: Ref<ErrorImpl>, target: TypeId) -> Option<Ref<()>>
|
||||
where
|
||||
E: 'static,
|
||||
{
|
||||
if TypeId::of::<E>() == target {
|
||||
// Caller is looking for an E pointer and e is ErrorImpl<E>, take a
|
||||
// pointer to its E field.
|
||||
|
||||
let unerased = e.cast::<ErrorImpl<E>>();
|
||||
|
||||
#[cfg(not(anyhow_no_ptr_addr_of))]
|
||||
return Some(
|
||||
Ref::from_raw(NonNull::new_unchecked(
|
||||
ptr::addr_of!((*unerased.as_ptr())._object) as *mut E,
|
||||
))
|
||||
.cast::<()>(),
|
||||
);
|
||||
|
||||
#[cfg(anyhow_no_ptr_addr_of)]
|
||||
return Some(Ref::new(&unerased.deref()._object).cast::<()>());
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
// Safety: requires layout of *e to match ErrorImpl<E>.
|
||||
#[cfg(anyhow_no_ptr_addr_of)]
|
||||
unsafe fn object_downcast_mut<E>(e: Mut<ErrorImpl>, target: TypeId) -> Option<Mut<()>>
|
||||
where
|
||||
E: 'static,
|
||||
{
|
||||
if TypeId::of::<E>() == target {
|
||||
// Caller is looking for an E pointer and e is ErrorImpl<E>, take a
|
||||
// pointer to its E field.
|
||||
let unerased = e.cast::<ErrorImpl<E>>().deref_mut();
|
||||
Some(Mut::new(&mut unerased._object).cast::<()>())
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(all(not(backtrace), feature = "backtrace"))]
|
||||
fn no_backtrace(e: Ref<ErrorImpl>) -> Option<&Backtrace> {
|
||||
let _ = e;
|
||||
None
|
||||
}
|
||||
|
||||
// Safety: requires layout of *e to match ErrorImpl<ContextError<C, E>>.
|
||||
#[cfg(feature = "std")]
|
||||
unsafe fn context_downcast<C, E>(e: Ref<ErrorImpl>, target: TypeId) -> Option<Ref<()>>
|
||||
where
|
||||
C: 'static,
|
||||
E: 'static,
|
||||
{
|
||||
if TypeId::of::<C>() == target {
|
||||
let unerased = e.cast::<ErrorImpl<ContextError<C, E>>>().deref();
|
||||
Some(Ref::new(&unerased._object.context).cast::<()>())
|
||||
} else if TypeId::of::<E>() == target {
|
||||
let unerased = e.cast::<ErrorImpl<ContextError<C, E>>>().deref();
|
||||
Some(Ref::new(&unerased._object.error).cast::<()>())
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
// Safety: requires layout of *e to match ErrorImpl<ContextError<C, E>>.
|
||||
#[cfg(all(feature = "std", anyhow_no_ptr_addr_of))]
|
||||
unsafe fn context_downcast_mut<C, E>(e: Mut<ErrorImpl>, target: TypeId) -> Option<Mut<()>>
|
||||
where
|
||||
C: 'static,
|
||||
E: 'static,
|
||||
{
|
||||
if TypeId::of::<C>() == target {
|
||||
let unerased = e.cast::<ErrorImpl<ContextError<C, E>>>().deref_mut();
|
||||
Some(Mut::new(&mut unerased._object.context).cast::<()>())
|
||||
} else if TypeId::of::<E>() == target {
|
||||
let unerased = e.cast::<ErrorImpl<ContextError<C, E>>>().deref_mut();
|
||||
Some(Mut::new(&mut unerased._object.error).cast::<()>())
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
// Safety: requires layout of *e to match ErrorImpl<ContextError<C, E>>.
|
||||
#[cfg(feature = "std")]
|
||||
unsafe fn context_drop_rest<C, E>(e: Own<ErrorImpl>, target: TypeId)
|
||||
where
|
||||
C: 'static,
|
||||
E: 'static,
|
||||
{
|
||||
// Called after downcasting by value to either the C or the E and doing a
|
||||
// ptr::read to take ownership of that value.
|
||||
if TypeId::of::<C>() == target {
|
||||
let unerased = e
|
||||
.cast::<ErrorImpl<ContextError<ManuallyDrop<C>, E>>>()
|
||||
.boxed();
|
||||
drop(unerased);
|
||||
} else {
|
||||
let unerased = e
|
||||
.cast::<ErrorImpl<ContextError<C, ManuallyDrop<E>>>>()
|
||||
.boxed();
|
||||
drop(unerased);
|
||||
}
|
||||
}
|
||||
|
||||
// Safety: requires layout of *e to match ErrorImpl<ContextError<C, Error>>.
|
||||
unsafe fn context_chain_downcast<C>(e: Ref<ErrorImpl>, target: TypeId) -> Option<Ref<()>>
|
||||
where
|
||||
C: 'static,
|
||||
{
|
||||
let unerased = e.cast::<ErrorImpl<ContextError<C, Error>>>().deref();
|
||||
if TypeId::of::<C>() == target {
|
||||
Some(Ref::new(&unerased._object.context).cast::<()>())
|
||||
} else {
|
||||
// Recurse down the context chain per the inner error's vtable.
|
||||
let source = &unerased._object.error;
|
||||
(vtable(source.inner.ptr).object_downcast)(source.inner.by_ref(), target)
|
||||
}
|
||||
}
|
||||
|
||||
// Safety: requires layout of *e to match ErrorImpl<ContextError<C, Error>>.
|
||||
#[cfg(anyhow_no_ptr_addr_of)]
|
||||
unsafe fn context_chain_downcast_mut<C>(e: Mut<ErrorImpl>, target: TypeId) -> Option<Mut<()>>
|
||||
where
|
||||
C: 'static,
|
||||
{
|
||||
let unerased = e.cast::<ErrorImpl<ContextError<C, Error>>>().deref_mut();
|
||||
if TypeId::of::<C>() == target {
|
||||
Some(Mut::new(&mut unerased._object.context).cast::<()>())
|
||||
} else {
|
||||
// Recurse down the context chain per the inner error's vtable.
|
||||
let source = &mut unerased._object.error;
|
||||
(vtable(source.inner.ptr).object_downcast_mut)(source.inner.by_mut(), target)
|
||||
}
|
||||
}
|
||||
|
||||
// Safety: requires layout of *e to match ErrorImpl<ContextError<C, Error>>.
|
||||
unsafe fn context_chain_drop_rest<C>(e: Own<ErrorImpl>, target: TypeId)
|
||||
where
|
||||
C: 'static,
|
||||
{
|
||||
// Called after downcasting by value to either the C or one of the causes
|
||||
// and doing a ptr::read to take ownership of that value.
|
||||
if TypeId::of::<C>() == target {
|
||||
let unerased = e
|
||||
.cast::<ErrorImpl<ContextError<ManuallyDrop<C>, Error>>>()
|
||||
.boxed();
|
||||
// Drop the entire rest of the data structure rooted in the next Error.
|
||||
drop(unerased);
|
||||
} else {
|
||||
let unerased = e
|
||||
.cast::<ErrorImpl<ContextError<C, ManuallyDrop<Error>>>>()
|
||||
.boxed();
|
||||
// Read the Own<ErrorImpl> from the next error.
|
||||
let inner = unerased._object.error.inner;
|
||||
drop(unerased);
|
||||
let vtable = vtable(inner.ptr);
|
||||
// Recursively drop the next error using the same target typeid.
|
||||
(vtable.object_drop_rest)(inner, target);
|
||||
}
|
||||
}
|
||||
|
||||
// Safety: requires layout of *e to match ErrorImpl<ContextError<C, Error>>.
|
||||
#[cfg(all(not(backtrace), feature = "backtrace"))]
|
||||
#[allow(clippy::unnecessary_wraps)]
|
||||
unsafe fn context_backtrace<C>(e: Ref<ErrorImpl>) -> Option<&Backtrace>
|
||||
where
|
||||
C: 'static,
|
||||
{
|
||||
let unerased = e.cast::<ErrorImpl<ContextError<C, Error>>>().deref();
|
||||
let backtrace = ErrorImpl::backtrace(unerased._object.error.inner.by_ref());
|
||||
Some(backtrace)
|
||||
}
|
||||
|
||||
// NOTE: If working with `ErrorImpl<()>`, references should be avoided in favor
|
||||
// of raw pointers and `NonNull`.
|
||||
// repr C to ensure that E remains in the final position.
|
||||
#[repr(C)]
|
||||
pub(crate) struct ErrorImpl<E = ()> {
|
||||
vtable: &'static ErrorVTable,
|
||||
backtrace: Option<Backtrace>,
|
||||
// NOTE: Don't use directly. Use only through vtable. Erased type may have
|
||||
// different alignment.
|
||||
_object: E,
|
||||
}
|
||||
|
||||
// Reads the vtable out of `p`. This is the same as `p.as_ref().vtable`, but
|
||||
// avoids converting `p` into a reference.
|
||||
unsafe fn vtable(p: NonNull<ErrorImpl>) -> &'static ErrorVTable {
|
||||
// NOTE: This assumes that `ErrorVTable` is the first field of ErrorImpl.
|
||||
*(p.as_ptr() as *const &'static ErrorVTable)
|
||||
}
|
||||
|
||||
// repr C to ensure that ContextError<C, E> has the same layout as
|
||||
// ContextError<ManuallyDrop<C>, E> and ContextError<C, ManuallyDrop<E>>.
|
||||
#[repr(C)]
|
||||
pub(crate) struct ContextError<C, E> {
|
||||
pub context: C,
|
||||
pub error: E,
|
||||
}
|
||||
|
||||
impl<E> ErrorImpl<E> {
|
||||
fn erase(&self) -> Ref<ErrorImpl> {
|
||||
// Erase the concrete type of E but preserve the vtable in self.vtable
|
||||
// for manipulating the resulting thin pointer. This is analogous to an
|
||||
// unsize coercion.
|
||||
Ref::new(self).cast::<ErrorImpl>()
|
||||
}
|
||||
}
|
||||
|
||||
impl ErrorImpl {
|
||||
pub(crate) unsafe fn error(this: Ref<Self>) -> &(dyn StdError + Send + Sync + 'static) {
|
||||
// Use vtable to attach E's native StdError vtable for the right
|
||||
// original type E.
|
||||
(vtable(this.ptr).object_ref)(this).deref()
|
||||
}
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
pub(crate) unsafe fn error_mut(this: Mut<Self>) -> &mut (dyn StdError + Send + Sync + 'static) {
|
||||
// Use vtable to attach E's native StdError vtable for the right
|
||||
// original type E.
|
||||
|
||||
#[cfg(not(anyhow_no_ptr_addr_of))]
|
||||
return (vtable(this.ptr).object_ref)(this.by_ref())
|
||||
.by_mut()
|
||||
.deref_mut();
|
||||
|
||||
#[cfg(anyhow_no_ptr_addr_of)]
|
||||
return (vtable(this.ptr).object_mut)(this);
|
||||
}
|
||||
|
||||
#[cfg(any(backtrace, feature = "backtrace"))]
|
||||
pub(crate) unsafe fn backtrace(this: Ref<Self>) -> &Backtrace {
|
||||
// This unwrap can only panic if the underlying error's backtrace method
|
||||
// is nondeterministic, which would only happen in maliciously
|
||||
// constructed code.
|
||||
this.deref()
|
||||
.backtrace
|
||||
.as_ref()
|
||||
.or_else(|| {
|
||||
#[cfg(backtrace)]
|
||||
return Self::error(this).request_ref::<Backtrace>();
|
||||
#[cfg(not(backtrace))]
|
||||
return (vtable(this.ptr).object_backtrace)(this);
|
||||
})
|
||||
.expect("backtrace capture failed")
|
||||
}
|
||||
|
||||
#[cfg(backtrace)]
|
||||
unsafe fn provide<'a>(this: Ref<'a, Self>, demand: &mut Demand<'a>) {
|
||||
if let Some(backtrace) = &this.deref().backtrace {
|
||||
demand.provide_ref(backtrace);
|
||||
}
|
||||
Self::error(this).provide(demand);
|
||||
}
|
||||
|
||||
#[cold]
|
||||
pub(crate) unsafe fn chain(this: Ref<Self>) -> Chain {
|
||||
Chain::new(Self::error(this))
|
||||
}
|
||||
}
|
||||
|
||||
impl<E> StdError for ErrorImpl<E>
|
||||
where
|
||||
E: StdError,
|
||||
{
|
||||
fn source(&self) -> Option<&(dyn StdError + 'static)> {
|
||||
unsafe { ErrorImpl::error(self.erase()).source() }
|
||||
}
|
||||
|
||||
#[cfg(backtrace)]
|
||||
fn provide<'a>(&'a self, demand: &mut Demand<'a>) {
|
||||
unsafe { ErrorImpl::provide(self.erase(), demand) }
|
||||
}
|
||||
}
|
||||
|
||||
impl<E> Debug for ErrorImpl<E>
|
||||
where
|
||||
E: Debug,
|
||||
{
|
||||
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
|
||||
unsafe { ErrorImpl::debug(self.erase(), formatter) }
|
||||
}
|
||||
}
|
||||
|
||||
impl<E> Display for ErrorImpl<E>
|
||||
where
|
||||
E: Display,
|
||||
{
|
||||
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
|
||||
unsafe { Display::fmt(ErrorImpl::error(self.erase()), formatter) }
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Error> for Box<dyn StdError + Send + Sync + 'static> {
|
||||
#[cold]
|
||||
fn from(error: Error) -> Self {
|
||||
let outer = ManuallyDrop::new(error);
|
||||
unsafe {
|
||||
// Use vtable to attach ErrorImpl<E>'s native StdError vtable for
|
||||
// the right original type E.
|
||||
(vtable(outer.inner.ptr).object_boxed)(outer.inner)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Error> for Box<dyn StdError + Send + 'static> {
|
||||
fn from(error: Error) -> Self {
|
||||
Box::<dyn StdError + Send + Sync>::from(error)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Error> for Box<dyn StdError + 'static> {
|
||||
fn from(error: Error) -> Self {
|
||||
Box::<dyn StdError + Send + Sync>::from(error)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
impl AsRef<dyn StdError + Send + Sync> for Error {
|
||||
fn as_ref(&self) -> &(dyn StdError + Send + Sync + 'static) {
|
||||
&**self
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
impl AsRef<dyn StdError> for Error {
|
||||
fn as_ref(&self) -> &(dyn StdError + 'static) {
|
||||
&**self
|
||||
}
|
||||
}
|
155
vendor/anyhow/src/fmt.rs
vendored
Normal file
155
vendor/anyhow/src/fmt.rs
vendored
Normal file
@ -0,0 +1,155 @@
|
||||
use crate::chain::Chain;
|
||||
use crate::error::ErrorImpl;
|
||||
use crate::ptr::Ref;
|
||||
use core::fmt::{self, Debug, Write};
|
||||
|
||||
impl ErrorImpl {
|
||||
pub(crate) unsafe fn display(this: Ref<Self>, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "{}", Self::error(this))?;
|
||||
|
||||
if f.alternate() {
|
||||
for cause in Self::chain(this).skip(1) {
|
||||
write!(f, ": {}", cause)?;
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub(crate) unsafe fn debug(this: Ref<Self>, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
let error = Self::error(this);
|
||||
|
||||
if f.alternate() {
|
||||
return Debug::fmt(error, f);
|
||||
}
|
||||
|
||||
write!(f, "{}", error)?;
|
||||
|
||||
if let Some(cause) = error.source() {
|
||||
write!(f, "\n\nCaused by:")?;
|
||||
let multiple = cause.source().is_some();
|
||||
for (n, error) in Chain::new(cause).enumerate() {
|
||||
writeln!(f)?;
|
||||
let mut indented = Indented {
|
||||
inner: f,
|
||||
number: if multiple { Some(n) } else { None },
|
||||
started: false,
|
||||
};
|
||||
write!(indented, "{}", error)?;
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(any(backtrace, feature = "backtrace"))]
|
||||
{
|
||||
use crate::backtrace::BacktraceStatus;
|
||||
|
||||
let backtrace = Self::backtrace(this);
|
||||
if let BacktraceStatus::Captured = backtrace.status() {
|
||||
let mut backtrace = backtrace.to_string();
|
||||
write!(f, "\n\n")?;
|
||||
if backtrace.starts_with("stack backtrace:") {
|
||||
// Capitalize to match "Caused by:"
|
||||
backtrace.replace_range(0..1, "S");
|
||||
} else {
|
||||
// "stack backtrace:" prefix was removed in
|
||||
// https://github.com/rust-lang/backtrace-rs/pull/286
|
||||
writeln!(f, "Stack backtrace:")?;
|
||||
}
|
||||
backtrace.truncate(backtrace.trim_end().len());
|
||||
write!(f, "{}", backtrace)?;
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
struct Indented<'a, D> {
|
||||
inner: &'a mut D,
|
||||
number: Option<usize>,
|
||||
started: bool,
|
||||
}
|
||||
|
||||
impl<T> Write for Indented<'_, T>
|
||||
where
|
||||
T: Write,
|
||||
{
|
||||
fn write_str(&mut self, s: &str) -> fmt::Result {
|
||||
for (i, line) in s.split('\n').enumerate() {
|
||||
if !self.started {
|
||||
self.started = true;
|
||||
match self.number {
|
||||
Some(number) => write!(self.inner, "{: >5}: ", number)?,
|
||||
None => self.inner.write_str(" ")?,
|
||||
}
|
||||
} else if i > 0 {
|
||||
self.inner.write_char('\n')?;
|
||||
if self.number.is_some() {
|
||||
self.inner.write_str(" ")?;
|
||||
} else {
|
||||
self.inner.write_str(" ")?;
|
||||
}
|
||||
}
|
||||
|
||||
self.inner.write_str(line)?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn one_digit() {
|
||||
let input = "verify\nthis";
|
||||
let expected = " 2: verify\n this";
|
||||
let mut output = String::new();
|
||||
|
||||
Indented {
|
||||
inner: &mut output,
|
||||
number: Some(2),
|
||||
started: false,
|
||||
}
|
||||
.write_str(input)
|
||||
.unwrap();
|
||||
|
||||
assert_eq!(expected, output);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn two_digits() {
|
||||
let input = "verify\nthis";
|
||||
let expected = " 12: verify\n this";
|
||||
let mut output = String::new();
|
||||
|
||||
Indented {
|
||||
inner: &mut output,
|
||||
number: Some(12),
|
||||
started: false,
|
||||
}
|
||||
.write_str(input)
|
||||
.unwrap();
|
||||
|
||||
assert_eq!(expected, output);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn no_digits() {
|
||||
let input = "verify\nthis";
|
||||
let expected = " verify\n this";
|
||||
let mut output = String::new();
|
||||
|
||||
Indented {
|
||||
inner: &mut output,
|
||||
number: None,
|
||||
started: false,
|
||||
}
|
||||
.write_str(input)
|
||||
.unwrap();
|
||||
|
||||
assert_eq!(expected, output);
|
||||
}
|
||||
}
|
116
vendor/anyhow/src/kind.rs
vendored
Normal file
116
vendor/anyhow/src/kind.rs
vendored
Normal file
@ -0,0 +1,116 @@
|
||||
// Tagged dispatch mechanism for resolving the behavior of `anyhow!($expr)`.
|
||||
//
|
||||
// When anyhow! is given a single expr argument to turn into anyhow::Error, we
|
||||
// want the resulting Error to pick up the input's implementation of source()
|
||||
// and backtrace() if it has a std::error::Error impl, otherwise require nothing
|
||||
// more than Display and Debug.
|
||||
//
|
||||
// Expressed in terms of specialization, we want something like:
|
||||
//
|
||||
// trait AnyhowNew {
|
||||
// fn new(self) -> Error;
|
||||
// }
|
||||
//
|
||||
// impl<T> AnyhowNew for T
|
||||
// where
|
||||
// T: Display + Debug + Send + Sync + 'static,
|
||||
// {
|
||||
// default fn new(self) -> Error {
|
||||
// /* no std error impl */
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// impl<T> AnyhowNew for T
|
||||
// where
|
||||
// T: std::error::Error + Send + Sync + 'static,
|
||||
// {
|
||||
// fn new(self) -> Error {
|
||||
// /* use std error's source() and backtrace() */
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// Since specialization is not stable yet, instead we rely on autoref behavior
|
||||
// of method resolution to perform tagged dispatch. Here we have two traits
|
||||
// AdhocKind and TraitKind that both have an anyhow_kind() method. AdhocKind is
|
||||
// implemented whether or not the caller's type has a std error impl, while
|
||||
// TraitKind is implemented only when a std error impl does exist. The ambiguity
|
||||
// is resolved by AdhocKind requiring an extra autoref so that it has lower
|
||||
// precedence.
|
||||
//
|
||||
// The anyhow! macro will set up the call in this form:
|
||||
//
|
||||
// #[allow(unused_imports)]
|
||||
// use $crate::__private::{AdhocKind, TraitKind};
|
||||
// let error = $msg;
|
||||
// (&error).anyhow_kind().new(error)
|
||||
|
||||
use crate::Error;
|
||||
use core::fmt::{Debug, Display};
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
use crate::StdError;
|
||||
|
||||
pub struct Adhoc;
|
||||
|
||||
pub trait AdhocKind: Sized {
|
||||
#[inline]
|
||||
fn anyhow_kind(&self) -> Adhoc {
|
||||
Adhoc
|
||||
}
|
||||
}
|
||||
|
||||
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,
|
||||
{
|
||||
Error::from_adhoc(message, backtrace!())
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Trait;
|
||||
|
||||
pub trait TraitKind: Sized {
|
||||
#[inline]
|
||||
fn anyhow_kind(&self) -> Trait {
|
||||
Trait
|
||||
}
|
||||
}
|
||||
|
||||
impl<E> TraitKind for E where E: Into<Error> {}
|
||||
|
||||
impl Trait {
|
||||
#[cold]
|
||||
pub fn new<E>(self, error: E) -> Error
|
||||
where
|
||||
E: Into<Error>,
|
||||
{
|
||||
error.into()
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
pub struct Boxed;
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
pub trait BoxedKind: Sized {
|
||||
#[inline]
|
||||
fn anyhow_kind(&self) -> Boxed {
|
||||
Boxed
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
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)
|
||||
}
|
||||
}
|
680
vendor/anyhow/src/lib.rs
vendored
Normal file
680
vendor/anyhow/src/lib.rs
vendored
Normal file
@ -0,0 +1,680 @@
|
||||
//! [![github]](https://github.com/dtolnay/anyhow) [![crates-io]](https://crates.io/crates/anyhow) [![docs-rs]](https://docs.rs/anyhow)
|
||||
//!
|
||||
//! [github]: https://img.shields.io/badge/github-8da0cb?style=for-the-badge&labelColor=555555&logo=github
|
||||
//! [crates-io]: https://img.shields.io/badge/crates.io-fc8d62?style=for-the-badge&labelColor=555555&logo=rust
|
||||
//! [docs-rs]: https://img.shields.io/badge/docs.rs-66c2a5?style=for-the-badge&labelColor=555555&logo=docs.rs
|
||||
//!
|
||||
//! <br>
|
||||
//!
|
||||
//! This library provides [`anyhow::Error`][Error], a trait object based error
|
||||
//! type for easy idiomatic error handling in Rust applications.
|
||||
//!
|
||||
//! <br>
|
||||
//!
|
||||
//! # Details
|
||||
//!
|
||||
//! - Use `Result<T, anyhow::Error>`, or equivalently `anyhow::Result<T>`, as
|
||||
//! the return type of any fallible function.
|
||||
//!
|
||||
//! Within the function, use `?` to easily propagate any error that implements
|
||||
//! the `std::error::Error` trait.
|
||||
//!
|
||||
//! ```
|
||||
//! # pub trait Deserialize {}
|
||||
//! #
|
||||
//! # mod serde_json {
|
||||
//! # use super::Deserialize;
|
||||
//! # use std::io;
|
||||
//! #
|
||||
//! # pub fn from_str<T: Deserialize>(json: &str) -> io::Result<T> {
|
||||
//! # unimplemented!()
|
||||
//! # }
|
||||
//! # }
|
||||
//! #
|
||||
//! # struct ClusterMap;
|
||||
//! #
|
||||
//! # impl Deserialize for ClusterMap {}
|
||||
//! #
|
||||
//! use anyhow::Result;
|
||||
//!
|
||||
//! fn get_cluster_info() -> Result<ClusterMap> {
|
||||
//! let config = std::fs::read_to_string("cluster.json")?;
|
||||
//! let map: ClusterMap = serde_json::from_str(&config)?;
|
||||
//! Ok(map)
|
||||
//! }
|
||||
//! #
|
||||
//! # fn main() {}
|
||||
//! ```
|
||||
//!
|
||||
//! - Attach context to help the person troubleshooting the error understand
|
||||
//! where things went wrong. A low-level error like "No such file or
|
||||
//! directory" can be annoying to debug without more context about what higher
|
||||
//! level step the application was in the middle of.
|
||||
//!
|
||||
//! ```
|
||||
//! # struct It;
|
||||
//! #
|
||||
//! # impl It {
|
||||
//! # fn detach(&self) -> Result<()> {
|
||||
//! # unimplemented!()
|
||||
//! # }
|
||||
//! # }
|
||||
//! #
|
||||
//! use anyhow::{Context, Result};
|
||||
//!
|
||||
//! fn main() -> Result<()> {
|
||||
//! # return Ok(());
|
||||
//! #
|
||||
//! # const _: &str = stringify! {
|
||||
//! ...
|
||||
//! # };
|
||||
//! #
|
||||
//! # let it = It;
|
||||
//! # let path = "./path/to/instrs.json";
|
||||
//! #
|
||||
//! it.detach().context("Failed to detach the important thing")?;
|
||||
//!
|
||||
//! let content = std::fs::read(path)
|
||||
//! .with_context(|| format!("Failed to read instrs from {}", path))?;
|
||||
//! #
|
||||
//! # const _: &str = stringify! {
|
||||
//! ...
|
||||
//! # };
|
||||
//! #
|
||||
//! # Ok(())
|
||||
//! }
|
||||
//! ```
|
||||
//!
|
||||
//! ```console
|
||||
//! Error: Failed to read instrs from ./path/to/instrs.json
|
||||
//!
|
||||
//! Caused by:
|
||||
//! No such file or directory (os error 2)
|
||||
//! ```
|
||||
//!
|
||||
//! - Downcasting is supported and can be by value, by shared reference, or by
|
||||
//! mutable reference as needed.
|
||||
//!
|
||||
//! ```
|
||||
//! # use anyhow::anyhow;
|
||||
//! # use std::fmt::{self, Display};
|
||||
//! # use std::task::Poll;
|
||||
//! #
|
||||
//! # #[derive(Debug)]
|
||||
//! # enum DataStoreError {
|
||||
//! # Censored(()),
|
||||
//! # }
|
||||
//! #
|
||||
//! # impl Display for DataStoreError {
|
||||
//! # fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
|
||||
//! # unimplemented!()
|
||||
//! # }
|
||||
//! # }
|
||||
//! #
|
||||
//! # impl std::error::Error for DataStoreError {}
|
||||
//! #
|
||||
//! # const REDACTED_CONTENT: () = ();
|
||||
//! #
|
||||
//! # let error = anyhow!("...");
|
||||
//! # let root_cause = &error;
|
||||
//! #
|
||||
//! # let ret =
|
||||
//! // If the error was caused by redaction, then return a
|
||||
//! // tombstone instead of the content.
|
||||
//! match root_cause.downcast_ref::<DataStoreError>() {
|
||||
//! Some(DataStoreError::Censored(_)) => Ok(Poll::Ready(REDACTED_CONTENT)),
|
||||
//! None => Err(error),
|
||||
//! }
|
||||
//! # ;
|
||||
//! ```
|
||||
//!
|
||||
//! - 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`;
|
||||
//! - If you want only errors to have backtraces, set `RUST_LIB_BACKTRACE=1`;
|
||||
//! - If you want only panics to have backtraces, set `RUST_BACKTRACE=1` and
|
||||
//! `RUST_LIB_BACKTRACE=0`.
|
||||
//!
|
||||
//! The tracking issue for this feature is [rust-lang/rust#53487].
|
||||
//!
|
||||
//! [`std::backtrace`]: https://doc.rust-lang.org/std/backtrace/index.html#environment-variables
|
||||
//! [rust-lang/rust#53487]: https://github.com/rust-lang/rust/issues/53487
|
||||
//!
|
||||
//! - Anyhow works with any error type that has an impl of `std::error::Error`,
|
||||
//! including ones defined in your crate. We do not bundle a `derive(Error)`
|
||||
//! macro but you can write the impls yourself or use a standalone macro like
|
||||
//! [thiserror].
|
||||
//!
|
||||
//! [thiserror]: https://github.com/dtolnay/thiserror
|
||||
//!
|
||||
//! ```
|
||||
//! use thiserror::Error;
|
||||
//!
|
||||
//! #[derive(Error, Debug)]
|
||||
//! pub enum FormatError {
|
||||
//! #[error("Invalid header (expected {expected:?}, got {found:?})")]
|
||||
//! InvalidHeader {
|
||||
//! expected: String,
|
||||
//! found: String,
|
||||
//! },
|
||||
//! #[error("Missing attribute: {0}")]
|
||||
//! MissingAttribute(String),
|
||||
//! }
|
||||
//! ```
|
||||
//!
|
||||
//! - One-off error messages can be constructed using the `anyhow!` macro, which
|
||||
//! supports string interpolation and produces an `anyhow::Error`.
|
||||
//!
|
||||
//! ```
|
||||
//! # use anyhow::{anyhow, Result};
|
||||
//! #
|
||||
//! # fn demo() -> Result<()> {
|
||||
//! # let missing = "...";
|
||||
//! return Err(anyhow!("Missing attribute: {}", missing));
|
||||
//! # Ok(())
|
||||
//! # }
|
||||
//! ```
|
||||
//!
|
||||
//! A `bail!` macro is provided as a shorthand for the same early return.
|
||||
//!
|
||||
//! ```
|
||||
//! # use anyhow::{bail, Result};
|
||||
//! #
|
||||
//! # fn demo() -> Result<()> {
|
||||
//! # let missing = "...";
|
||||
//! bail!("Missing attribute: {}", missing);
|
||||
//! # Ok(())
|
||||
//! # }
|
||||
//! ```
|
||||
//!
|
||||
//! <br>
|
||||
//!
|
||||
//! # No-std support
|
||||
//!
|
||||
//! In no_std mode, the same API is almost all available and works the same way.
|
||||
//! To depend on Anyhow in no_std mode, disable our default enabled "std"
|
||||
//! feature in Cargo.toml. A global allocator is required.
|
||||
//!
|
||||
//! ```toml
|
||||
//! [dependencies]
|
||||
//! anyhow = { version = "1.0", default-features = false }
|
||||
//! ```
|
||||
//!
|
||||
//! Since the `?`-based error conversions would normally rely on the
|
||||
//! `std::error::Error` trait which is only available through std, no_std mode
|
||||
//! 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.65")]
|
||||
#![cfg_attr(backtrace, feature(error_generic_member_access, provide_any))]
|
||||
#![cfg_attr(doc_cfg, feature(doc_cfg))]
|
||||
#![cfg_attr(not(feature = "std"), no_std)]
|
||||
#![deny(dead_code, unused_imports, unused_mut)]
|
||||
#![allow(
|
||||
clippy::doc_markdown,
|
||||
clippy::enum_glob_use,
|
||||
clippy::explicit_auto_deref,
|
||||
clippy::missing_errors_doc,
|
||||
clippy::missing_panics_doc,
|
||||
clippy::module_name_repetitions,
|
||||
clippy::must_use_candidate,
|
||||
clippy::needless_doctest_main,
|
||||
clippy::new_ret_no_self,
|
||||
clippy::redundant_else,
|
||||
clippy::return_self_not_must_use,
|
||||
clippy::unused_self,
|
||||
clippy::used_underscore_binding,
|
||||
clippy::wildcard_imports,
|
||||
clippy::wrong_self_convention
|
||||
)]
|
||||
|
||||
extern crate alloc;
|
||||
|
||||
#[macro_use]
|
||||
mod backtrace;
|
||||
mod chain;
|
||||
mod context;
|
||||
mod ensure;
|
||||
mod error;
|
||||
mod fmt;
|
||||
mod kind;
|
||||
mod macros;
|
||||
mod ptr;
|
||||
mod wrapper;
|
||||
|
||||
use crate::error::ErrorImpl;
|
||||
use crate::ptr::Own;
|
||||
use core::fmt::Display;
|
||||
|
||||
#[cfg(not(feature = "std"))]
|
||||
use core::fmt::Debug;
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
use std::error::Error as StdError;
|
||||
|
||||
#[cfg(not(feature = "std"))]
|
||||
trait StdError: Debug + Display {
|
||||
fn source(&self) -> Option<&(dyn StdError + 'static)> {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
pub use anyhow as format_err;
|
||||
|
||||
/// The `Error` type, a wrapper around a dynamic error type.
|
||||
///
|
||||
/// `Error` works a lot like `Box<dyn std::error::Error>`, but with these
|
||||
/// differences:
|
||||
///
|
||||
/// - `Error` requires that the error is `Send`, `Sync`, and `'static`.
|
||||
/// - `Error` guarantees that a backtrace is available, even if the underlying
|
||||
/// error type does not provide one.
|
||||
/// - `Error` is represented as a narrow pointer — exactly one word in
|
||||
/// size instead of two.
|
||||
///
|
||||
/// <br>
|
||||
///
|
||||
/// # Display representations
|
||||
///
|
||||
/// When you print an error object using "{}" or to_string(), only the outermost
|
||||
/// underlying error or context is printed, not any of the lower level causes.
|
||||
/// This is exactly as if you had called the Display impl of the error from
|
||||
/// which you constructed your anyhow::Error.
|
||||
///
|
||||
/// ```console
|
||||
/// Failed to read instrs from ./path/to/instrs.json
|
||||
/// ```
|
||||
///
|
||||
/// To print causes as well using anyhow's default formatting of causes, use the
|
||||
/// alternate selector "{:#}".
|
||||
///
|
||||
/// ```console
|
||||
/// Failed to read instrs from ./path/to/instrs.json: No such file or directory (os error 2)
|
||||
/// ```
|
||||
///
|
||||
/// The Debug format "{:?}" includes your backtrace if one was captured. Note
|
||||
/// that this is the representation you get by default if you return an error
|
||||
/// from `fn main` instead of printing it explicitly yourself.
|
||||
///
|
||||
/// ```console
|
||||
/// Error: Failed to read instrs from ./path/to/instrs.json
|
||||
///
|
||||
/// Caused by:
|
||||
/// No such file or directory (os error 2)
|
||||
/// ```
|
||||
///
|
||||
/// and if there is a backtrace available:
|
||||
///
|
||||
/// ```console
|
||||
/// Error: Failed to read instrs from ./path/to/instrs.json
|
||||
///
|
||||
/// Caused by:
|
||||
/// No such file or directory (os error 2)
|
||||
///
|
||||
/// Stack backtrace:
|
||||
/// 0: <E as anyhow::context::ext::StdError>::ext_context
|
||||
/// at /git/anyhow/src/backtrace.rs:26
|
||||
/// 1: core::result::Result<T,E>::map_err
|
||||
/// at /git/rustc/src/libcore/result.rs:596
|
||||
/// 2: anyhow::context::<impl anyhow::Context<T,E> for core::result::Result<T,E>>::with_context
|
||||
/// at /git/anyhow/src/context.rs:58
|
||||
/// 3: testing::main
|
||||
/// at src/main.rs:5
|
||||
/// 4: std::rt::lang_start
|
||||
/// at /git/rustc/src/libstd/rt.rs:61
|
||||
/// 5: main
|
||||
/// 6: __libc_start_main
|
||||
/// 7: _start
|
||||
/// ```
|
||||
///
|
||||
/// To see a conventional struct-style Debug representation, use "{:#?}".
|
||||
///
|
||||
/// ```console
|
||||
/// Error {
|
||||
/// context: "Failed to read instrs from ./path/to/instrs.json",
|
||||
/// source: Os {
|
||||
/// code: 2,
|
||||
/// kind: NotFound,
|
||||
/// message: "No such file or directory",
|
||||
/// },
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// If none of the built-in representations are appropriate and you would prefer
|
||||
/// to render the error and its cause chain yourself, it can be done something
|
||||
/// like this:
|
||||
///
|
||||
/// ```
|
||||
/// use anyhow::{Context, Result};
|
||||
///
|
||||
/// fn main() {
|
||||
/// if let Err(err) = try_main() {
|
||||
/// eprintln!("ERROR: {}", err);
|
||||
/// err.chain().skip(1).for_each(|cause| eprintln!("because: {}", cause));
|
||||
/// std::process::exit(1);
|
||||
/// }
|
||||
/// }
|
||||
///
|
||||
/// fn try_main() -> Result<()> {
|
||||
/// # const IGNORE: &str = stringify! {
|
||||
/// ...
|
||||
/// # };
|
||||
/// # Ok(())
|
||||
/// }
|
||||
/// ```
|
||||
#[repr(transparent)]
|
||||
pub struct Error {
|
||||
inner: Own<ErrorImpl>,
|
||||
}
|
||||
|
||||
/// Iterator of a chain of source errors.
|
||||
///
|
||||
/// This type is the iterator returned by [`Error::chain`].
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```
|
||||
/// use anyhow::Error;
|
||||
/// use std::io;
|
||||
///
|
||||
/// pub fn underlying_io_error_kind(error: &Error) -> Option<io::ErrorKind> {
|
||||
/// for cause in error.chain() {
|
||||
/// if let Some(io_error) = cause.downcast_ref::<io::Error>() {
|
||||
/// return Some(io_error.kind());
|
||||
/// }
|
||||
/// }
|
||||
/// None
|
||||
/// }
|
||||
/// ```
|
||||
#[cfg(feature = "std")]
|
||||
#[cfg_attr(doc_cfg, doc(cfg(feature = "std")))]
|
||||
#[derive(Clone)]
|
||||
pub struct Chain<'a> {
|
||||
state: crate::chain::ChainState<'a>,
|
||||
}
|
||||
|
||||
/// `Result<T, Error>`
|
||||
///
|
||||
/// This is a reasonable return type to use throughout your application but also
|
||||
/// for `fn main`; if you do, failures will be printed along with any
|
||||
/// [context][Context] and a backtrace if one was captured.
|
||||
///
|
||||
/// `anyhow::Result` may be used with one *or* two type parameters.
|
||||
///
|
||||
/// ```rust
|
||||
/// use anyhow::Result;
|
||||
///
|
||||
/// # const IGNORE: &str = stringify! {
|
||||
/// fn demo1() -> Result<T> {...}
|
||||
/// // ^ equivalent to std::result::Result<T, anyhow::Error>
|
||||
///
|
||||
/// fn demo2() -> Result<T, OtherError> {...}
|
||||
/// // ^ equivalent to std::result::Result<T, OtherError>
|
||||
/// # };
|
||||
/// ```
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```
|
||||
/// # pub trait Deserialize {}
|
||||
/// #
|
||||
/// # mod serde_json {
|
||||
/// # use super::Deserialize;
|
||||
/// # use std::io;
|
||||
/// #
|
||||
/// # pub fn from_str<T: Deserialize>(json: &str) -> io::Result<T> {
|
||||
/// # unimplemented!()
|
||||
/// # }
|
||||
/// # }
|
||||
/// #
|
||||
/// # #[derive(Debug)]
|
||||
/// # struct ClusterMap;
|
||||
/// #
|
||||
/// # impl Deserialize for ClusterMap {}
|
||||
/// #
|
||||
/// use anyhow::Result;
|
||||
///
|
||||
/// fn main() -> Result<()> {
|
||||
/// # return Ok(());
|
||||
/// let config = std::fs::read_to_string("cluster.json")?;
|
||||
/// let map: ClusterMap = serde_json::from_str(&config)?;
|
||||
/// println!("cluster info: {:#?}", map);
|
||||
/// Ok(())
|
||||
/// }
|
||||
/// ```
|
||||
pub type Result<T, E = Error> = core::result::Result<T, E>;
|
||||
|
||||
/// Provides the `context` method for `Result`.
|
||||
///
|
||||
/// This trait is sealed and cannot be implemented for types outside of
|
||||
/// `anyhow`.
|
||||
///
|
||||
/// <br>
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```
|
||||
/// use anyhow::{Context, Result};
|
||||
/// use std::fs;
|
||||
/// use std::path::PathBuf;
|
||||
///
|
||||
/// pub struct ImportantThing {
|
||||
/// path: PathBuf,
|
||||
/// }
|
||||
///
|
||||
/// impl ImportantThing {
|
||||
/// # const IGNORE: &'static str = stringify! {
|
||||
/// pub fn detach(&mut self) -> Result<()> {...}
|
||||
/// # };
|
||||
/// # fn detach(&mut self) -> Result<()> {
|
||||
/// # unimplemented!()
|
||||
/// # }
|
||||
/// }
|
||||
///
|
||||
/// pub fn do_it(mut it: ImportantThing) -> Result<Vec<u8>> {
|
||||
/// it.detach().context("Failed to detach the important thing")?;
|
||||
///
|
||||
/// let path = &it.path;
|
||||
/// let content = fs::read(path)
|
||||
/// .with_context(|| format!("Failed to read instrs from {}", path.display()))?;
|
||||
///
|
||||
/// Ok(content)
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// When printed, the outermost context would be printed first and the lower
|
||||
/// level underlying causes would be enumerated below.
|
||||
///
|
||||
/// ```console
|
||||
/// Error: Failed to read instrs from ./path/to/instrs.json
|
||||
///
|
||||
/// Caused by:
|
||||
/// No such file or directory (os error 2)
|
||||
/// ```
|
||||
///
|
||||
/// Refer to the [Display representations] documentation for other forms in
|
||||
/// which this context chain can be rendered.
|
||||
///
|
||||
/// [Display representations]: Error#display-representations
|
||||
///
|
||||
/// <br>
|
||||
///
|
||||
/// # Effect on downcasting
|
||||
///
|
||||
/// After attaching context of type `C` onto an error of type `E`, the resulting
|
||||
/// `anyhow::Error` may be downcast to `C` **or** to `E`.
|
||||
///
|
||||
/// That is, in codebases that rely on downcasting, Anyhow's context supports
|
||||
/// both of the following use cases:
|
||||
///
|
||||
/// - **Attaching context whose type is insignificant onto errors whose type
|
||||
/// is used in downcasts.**
|
||||
///
|
||||
/// In other error libraries whose context is not designed this way, it can
|
||||
/// be risky to introduce context to existing code because new context might
|
||||
/// break existing working downcasts. In Anyhow, any downcast that worked
|
||||
/// before adding context will continue to work after you add a context, so
|
||||
/// you should freely add human-readable context to errors wherever it would
|
||||
/// be helpful.
|
||||
///
|
||||
/// ```
|
||||
/// # use anyhow::bail;
|
||||
/// # use thiserror::Error;
|
||||
/// #
|
||||
/// # #[derive(Error, Debug)]
|
||||
/// # #[error("???")]
|
||||
/// # struct SuspiciousError;
|
||||
/// #
|
||||
/// # fn helper() -> Result<()> {
|
||||
/// # bail!(SuspiciousError);
|
||||
/// # }
|
||||
/// #
|
||||
/// use anyhow::{Context, Result};
|
||||
///
|
||||
/// fn do_it() -> Result<()> {
|
||||
/// helper().context("Failed to complete the work")?;
|
||||
/// # const IGNORE: &str = stringify! {
|
||||
/// ...
|
||||
/// # };
|
||||
/// # unreachable!()
|
||||
/// }
|
||||
///
|
||||
/// fn main() {
|
||||
/// let err = do_it().unwrap_err();
|
||||
/// if let Some(e) = err.downcast_ref::<SuspiciousError>() {
|
||||
/// // If helper() returned SuspiciousError, this downcast will
|
||||
/// // correctly succeed even with the context in between.
|
||||
/// # return;
|
||||
/// }
|
||||
/// # panic!("expected downcast to succeed");
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// - **Attaching context whose type is used in downcasts onto errors whose
|
||||
/// type is insignificant.**
|
||||
///
|
||||
/// Some codebases prefer to use machine-readable context to categorize
|
||||
/// lower level errors in a way that will be actionable to higher levels of
|
||||
/// the application.
|
||||
///
|
||||
/// ```
|
||||
/// # use anyhow::bail;
|
||||
/// # use thiserror::Error;
|
||||
/// #
|
||||
/// # #[derive(Error, Debug)]
|
||||
/// # #[error("???")]
|
||||
/// # struct HelperFailed;
|
||||
/// #
|
||||
/// # fn helper() -> Result<()> {
|
||||
/// # bail!("no such file or directory");
|
||||
/// # }
|
||||
/// #
|
||||
/// use anyhow::{Context, Result};
|
||||
///
|
||||
/// fn do_it() -> Result<()> {
|
||||
/// helper().context(HelperFailed)?;
|
||||
/// # const IGNORE: &str = stringify! {
|
||||
/// ...
|
||||
/// # };
|
||||
/// # unreachable!()
|
||||
/// }
|
||||
///
|
||||
/// fn main() {
|
||||
/// let err = do_it().unwrap_err();
|
||||
/// if let Some(e) = err.downcast_ref::<HelperFailed>() {
|
||||
/// // If helper failed, this downcast will succeed because
|
||||
/// // HelperFailed is the context that has been attached to
|
||||
/// // that error.
|
||||
/// # return;
|
||||
/// }
|
||||
/// # panic!("expected downcast to succeed");
|
||||
/// }
|
||||
/// ```
|
||||
pub trait Context<T, E>: context::private::Sealed {
|
||||
/// Wrap the error value with additional context.
|
||||
fn context<C>(self, context: C) -> Result<T, Error>
|
||||
where
|
||||
C: Display + Send + Sync + 'static;
|
||||
|
||||
/// Wrap the error value with additional context that is evaluated lazily
|
||||
/// only once an error does occur.
|
||||
fn with_context<C, F>(self, f: F) -> Result<T, Error>
|
||||
where
|
||||
C: Display + Send + Sync + 'static,
|
||||
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 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 {
|
||||
pub use crate::kind::{AdhocKind, TraitKind};
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
pub use crate::kind::BoxedKind;
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
#[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();
|
||||
|
||||
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))
|
||||
}
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
#[inline]
|
||||
#[cold]
|
||||
#[must_use]
|
||||
pub fn must_use(error: Error) -> Error {
|
||||
error
|
||||
}
|
||||
}
|
231
vendor/anyhow/src/macros.rs
vendored
Normal file
231
vendor/anyhow/src/macros.rs
vendored
Normal file
@ -0,0 +1,231 @@
|
||||
/// Return early with an error.
|
||||
///
|
||||
/// This macro is equivalent to `return Err(`[`anyhow!($args...)`][anyhow!]`)`.
|
||||
///
|
||||
/// The surrounding function's or closure's return value is required to be
|
||||
/// `Result<_,`[`anyhow::Error`][crate::Error]`>`.
|
||||
///
|
||||
/// [anyhow!]: crate::anyhow
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```
|
||||
/// # use anyhow::{bail, Result};
|
||||
/// #
|
||||
/// # fn has_permission(user: usize, resource: usize) -> bool {
|
||||
/// # true
|
||||
/// # }
|
||||
/// #
|
||||
/// # fn main() -> Result<()> {
|
||||
/// # let user = 0;
|
||||
/// # let resource = 0;
|
||||
/// #
|
||||
/// if !has_permission(user, resource) {
|
||||
/// bail!("permission denied for accessing {}", resource);
|
||||
/// }
|
||||
/// # Ok(())
|
||||
/// # }
|
||||
/// ```
|
||||
///
|
||||
/// ```
|
||||
/// # use anyhow::{bail, Result};
|
||||
/// # use thiserror::Error;
|
||||
/// #
|
||||
/// # const MAX_DEPTH: usize = 1;
|
||||
/// #
|
||||
/// #[derive(Error, Debug)]
|
||||
/// enum ScienceError {
|
||||
/// #[error("recursion limit exceeded")]
|
||||
/// RecursionLimitExceeded,
|
||||
/// # #[error("...")]
|
||||
/// # More = (stringify! {
|
||||
/// ...
|
||||
/// # }, 1).1,
|
||||
/// }
|
||||
///
|
||||
/// # fn main() -> Result<()> {
|
||||
/// # let depth = 0;
|
||||
/// #
|
||||
/// if depth > MAX_DEPTH {
|
||||
/// bail!(ScienceError::RecursionLimitExceeded);
|
||||
/// }
|
||||
/// # Ok(())
|
||||
/// # }
|
||||
/// ```
|
||||
#[macro_export]
|
||||
macro_rules! bail {
|
||||
($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
|
||||
/// Err(`[`anyhow!($args...)`][anyhow!]`); }`.
|
||||
///
|
||||
/// The surrounding function's or closure's return value is required to be
|
||||
/// `Result<_,`[`anyhow::Error`][crate::Error]`>`.
|
||||
///
|
||||
/// Analogously to `assert!`, `ensure!` takes a condition and exits the function
|
||||
/// if the condition fails. Unlike `assert!`, `ensure!` returns an `Error`
|
||||
/// rather than panicking.
|
||||
///
|
||||
/// [anyhow!]: crate::anyhow
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```
|
||||
/// # use anyhow::{ensure, Result};
|
||||
/// #
|
||||
/// # fn main() -> Result<()> {
|
||||
/// # let user = 0;
|
||||
/// #
|
||||
/// ensure!(user == 0, "only user 0 is allowed");
|
||||
/// # Ok(())
|
||||
/// # }
|
||||
/// ```
|
||||
///
|
||||
/// ```
|
||||
/// # use anyhow::{ensure, Result};
|
||||
/// # use thiserror::Error;
|
||||
/// #
|
||||
/// # const MAX_DEPTH: usize = 1;
|
||||
/// #
|
||||
/// #[derive(Error, Debug)]
|
||||
/// enum ScienceError {
|
||||
/// #[error("recursion limit exceeded")]
|
||||
/// RecursionLimitExceeded,
|
||||
/// # #[error("...")]
|
||||
/// # More = (stringify! {
|
||||
/// ...
|
||||
/// # }, 1).1,
|
||||
/// }
|
||||
///
|
||||
/// # fn main() -> Result<()> {
|
||||
/// # let depth = 0;
|
||||
/// #
|
||||
/// ensure!(depth <= MAX_DEPTH, ScienceError::RecursionLimitExceeded);
|
||||
/// # Ok(())
|
||||
/// # }
|
||||
/// ```
|
||||
#[cfg(doc)]
|
||||
#[macro_export]
|
||||
macro_rules! 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)*));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#[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.
|
||||
///
|
||||
/// This evaluates to an [`Error`][crate::Error]. It can take either just a
|
||||
/// string, or a format string with arguments. It also can take any custom type
|
||||
/// which implements `Debug` and `Display`.
|
||||
///
|
||||
/// If called with a single argument whose type implements `std::error::Error`
|
||||
/// (in addition to `Debug` and `Display`, which are always required), then that
|
||||
/// Error impl's `source` is preserved as the `source` of the resulting
|
||||
/// `anyhow::Error`.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```
|
||||
/// # type V = ();
|
||||
/// #
|
||||
/// use anyhow::{anyhow, Result};
|
||||
///
|
||||
/// fn lookup(key: &str) -> Result<V> {
|
||||
/// if key.len() != 16 {
|
||||
/// return Err(anyhow!("key length must be 16 characters, got {:?}", key));
|
||||
/// }
|
||||
///
|
||||
/// // ...
|
||||
/// # Ok(())
|
||||
/// }
|
||||
/// ```
|
||||
#[macro_export]
|
||||
macro_rules! anyhow {
|
||||
($msg:literal $(,)?) => {
|
||||
$crate::__private::must_use({
|
||||
let error = $crate::__private::format_err($crate::__private::format_args!($msg));
|
||||
error
|
||||
})
|
||||
};
|
||||
($err:expr $(,)?) => {
|
||||
$crate::__private::must_use({
|
||||
use $crate::__private::kind::*;
|
||||
let error = match $err {
|
||||
error => (&error).anyhow_kind().new(error),
|
||||
};
|
||||
error
|
||||
})
|
||||
};
|
||||
($fmt:expr, $($arg:tt)*) => {
|
||||
$crate::Error::msg($crate::__private::format!($fmt, $($arg)*))
|
||||
};
|
||||
}
|
||||
|
||||
// Not public API. This is used in the implementation of some of the other
|
||||
// macros, in which the must_use call is not needed because the value is known
|
||||
// to be used.
|
||||
#[doc(hidden)]
|
||||
#[macro_export]
|
||||
macro_rules! __anyhow {
|
||||
($msg:literal $(,)?) => ({
|
||||
let error = $crate::__private::format_err($crate::__private::format_args!($msg));
|
||||
error
|
||||
});
|
||||
($err:expr $(,)?) => ({
|
||||
use $crate::__private::kind::*;
|
||||
let error = match $err {
|
||||
error => (&error).anyhow_kind().new(error),
|
||||
};
|
||||
error
|
||||
});
|
||||
($fmt:expr, $($arg:tt)*) => {
|
||||
$crate::Error::msg($crate::__private::format!($fmt, $($arg)*))
|
||||
};
|
||||
}
|
199
vendor/anyhow/src/ptr.rs
vendored
Normal file
199
vendor/anyhow/src/ptr.rs
vendored
Normal file
@ -0,0 +1,199 @@
|
||||
use alloc::boxed::Box;
|
||||
use core::marker::PhantomData;
|
||||
use core::ptr::NonNull;
|
||||
|
||||
#[repr(transparent)]
|
||||
pub struct Own<T>
|
||||
where
|
||||
T: ?Sized,
|
||||
{
|
||||
pub ptr: NonNull<T>,
|
||||
}
|
||||
|
||||
unsafe impl<T> Send for Own<T> where T: ?Sized {}
|
||||
|
||||
unsafe impl<T> Sync for Own<T> where T: ?Sized {}
|
||||
|
||||
impl<T> Copy for Own<T> where T: ?Sized {}
|
||||
|
||||
impl<T> Clone for Own<T>
|
||||
where
|
||||
T: ?Sized,
|
||||
{
|
||||
fn clone(&self) -> Self {
|
||||
*self
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> Own<T>
|
||||
where
|
||||
T: ?Sized,
|
||||
{
|
||||
pub fn new(ptr: Box<T>) -> Self {
|
||||
Own {
|
||||
ptr: unsafe { NonNull::new_unchecked(Box::into_raw(ptr)) },
|
||||
}
|
||||
}
|
||||
|
||||
pub fn cast<U: CastTo>(self) -> Own<U::Target> {
|
||||
Own {
|
||||
ptr: self.ptr.cast(),
|
||||
}
|
||||
}
|
||||
|
||||
pub unsafe fn boxed(self) -> Box<T> {
|
||||
Box::from_raw(self.ptr.as_ptr())
|
||||
}
|
||||
|
||||
pub fn by_ref(&self) -> Ref<T> {
|
||||
Ref {
|
||||
ptr: self.ptr,
|
||||
lifetime: PhantomData,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn by_mut(&mut self) -> Mut<T> {
|
||||
Mut {
|
||||
ptr: self.ptr,
|
||||
lifetime: PhantomData,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[repr(transparent)]
|
||||
pub struct Ref<'a, T>
|
||||
where
|
||||
T: ?Sized,
|
||||
{
|
||||
pub ptr: NonNull<T>,
|
||||
lifetime: PhantomData<&'a T>,
|
||||
}
|
||||
|
||||
impl<'a, T> Copy for Ref<'a, T> where T: ?Sized {}
|
||||
|
||||
impl<'a, T> Clone for Ref<'a, T>
|
||||
where
|
||||
T: ?Sized,
|
||||
{
|
||||
fn clone(&self) -> Self {
|
||||
*self
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, T> Ref<'a, T>
|
||||
where
|
||||
T: ?Sized,
|
||||
{
|
||||
pub fn new(ptr: &'a T) -> Self {
|
||||
Ref {
|
||||
ptr: NonNull::from(ptr),
|
||||
lifetime: PhantomData,
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(anyhow_no_ptr_addr_of))]
|
||||
pub fn from_raw(ptr: NonNull<T>) -> Self {
|
||||
Ref {
|
||||
ptr,
|
||||
lifetime: PhantomData,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn cast<U: CastTo>(self) -> Ref<'a, U::Target> {
|
||||
Ref {
|
||||
ptr: self.ptr.cast(),
|
||||
lifetime: PhantomData,
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(anyhow_no_ptr_addr_of))]
|
||||
pub fn by_mut(self) -> Mut<'a, T> {
|
||||
Mut {
|
||||
ptr: self.ptr,
|
||||
lifetime: PhantomData,
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(anyhow_no_ptr_addr_of))]
|
||||
pub fn as_ptr(self) -> *const T {
|
||||
self.ptr.as_ptr() as *const T
|
||||
}
|
||||
|
||||
pub unsafe fn deref(self) -> &'a T {
|
||||
&*self.ptr.as_ptr()
|
||||
}
|
||||
}
|
||||
|
||||
#[repr(transparent)]
|
||||
pub struct Mut<'a, T>
|
||||
where
|
||||
T: ?Sized,
|
||||
{
|
||||
pub ptr: NonNull<T>,
|
||||
lifetime: PhantomData<&'a mut T>,
|
||||
}
|
||||
|
||||
impl<'a, T> Copy for Mut<'a, T> where T: ?Sized {}
|
||||
|
||||
impl<'a, T> Clone for Mut<'a, T>
|
||||
where
|
||||
T: ?Sized,
|
||||
{
|
||||
fn clone(&self) -> Self {
|
||||
*self
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, T> Mut<'a, T>
|
||||
where
|
||||
T: ?Sized,
|
||||
{
|
||||
#[cfg(anyhow_no_ptr_addr_of)]
|
||||
pub fn new(ptr: &'a mut T) -> Self {
|
||||
Mut {
|
||||
ptr: NonNull::from(ptr),
|
||||
lifetime: PhantomData,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn cast<U: CastTo>(self) -> Mut<'a, U::Target> {
|
||||
Mut {
|
||||
ptr: self.ptr.cast(),
|
||||
lifetime: PhantomData,
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(anyhow_no_ptr_addr_of))]
|
||||
pub fn by_ref(self) -> Ref<'a, T> {
|
||||
Ref {
|
||||
ptr: self.ptr,
|
||||
lifetime: PhantomData,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn extend<'b>(self) -> Mut<'b, T> {
|
||||
Mut {
|
||||
ptr: self.ptr,
|
||||
lifetime: PhantomData,
|
||||
}
|
||||
}
|
||||
|
||||
pub unsafe fn deref_mut(self) -> &'a mut T {
|
||||
&mut *self.ptr.as_ptr()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, T> Mut<'a, T> {
|
||||
pub unsafe fn read(self) -> T {
|
||||
self.ptr.as_ptr().read()
|
||||
}
|
||||
}
|
||||
|
||||
// Force turbofish on all calls of `.cast::<U>()`.
|
||||
pub trait CastTo {
|
||||
type Target;
|
||||
}
|
||||
|
||||
impl<T> CastTo for T {
|
||||
type Target = T;
|
||||
}
|
81
vendor/anyhow/src/wrapper.rs
vendored
Normal file
81
vendor/anyhow/src/wrapper.rs
vendored
Normal file
@ -0,0 +1,81 @@
|
||||
use crate::StdError;
|
||||
use core::fmt::{self, Debug, Display};
|
||||
|
||||
#[cfg(backtrace)]
|
||||
use std::any::Demand;
|
||||
|
||||
#[repr(transparent)]
|
||||
pub struct MessageError<M>(pub M);
|
||||
|
||||
impl<M> Debug for MessageError<M>
|
||||
where
|
||||
M: Display + Debug,
|
||||
{
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
Debug::fmt(&self.0, f)
|
||||
}
|
||||
}
|
||||
|
||||
impl<M> Display for MessageError<M>
|
||||
where
|
||||
M: Display + Debug,
|
||||
{
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
Display::fmt(&self.0, f)
|
||||
}
|
||||
}
|
||||
|
||||
impl<M> StdError for MessageError<M> where M: Display + Debug + 'static {}
|
||||
|
||||
#[repr(transparent)]
|
||||
pub struct DisplayError<M>(pub M);
|
||||
|
||||
impl<M> Debug for DisplayError<M>
|
||||
where
|
||||
M: Display,
|
||||
{
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
Display::fmt(&self.0, f)
|
||||
}
|
||||
}
|
||||
|
||||
impl<M> Display for DisplayError<M>
|
||||
where
|
||||
M: Display,
|
||||
{
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
Display::fmt(&self.0, f)
|
||||
}
|
||||
}
|
||||
|
||||
impl<M> StdError for DisplayError<M> where M: Display + 'static {}
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
#[repr(transparent)]
|
||||
pub struct BoxedError(pub Box<dyn StdError + Send + Sync>);
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
impl Debug for BoxedError {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
Debug::fmt(&self.0, f)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
impl Display for BoxedError {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
Display::fmt(&self.0, f)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
impl StdError for BoxedError {
|
||||
fn source(&self) -> Option<&(dyn StdError + 'static)> {
|
||||
self.0.source()
|
||||
}
|
||||
|
||||
#[cfg(backtrace)]
|
||||
fn provide<'a>(&'a self, demand: &mut Demand<'a>) {
|
||||
self.0.provide(demand);
|
||||
}
|
||||
}
|
14
vendor/anyhow/tests/common/mod.rs
vendored
Normal file
14
vendor/anyhow/tests/common/mod.rs
vendored
Normal file
@ -0,0 +1,14 @@
|
||||
use anyhow::{bail, Result};
|
||||
use std::io;
|
||||
|
||||
pub fn bail_literal() -> Result<()> {
|
||||
bail!("oh no!");
|
||||
}
|
||||
|
||||
pub fn bail_fmt() -> Result<()> {
|
||||
bail!("{} {}!", "oh", "no");
|
||||
}
|
||||
|
||||
pub fn bail_error() -> Result<()> {
|
||||
bail!(io::Error::new(io::ErrorKind::Other, "oh no!"));
|
||||
}
|
7
vendor/anyhow/tests/compiletest.rs
vendored
Normal file
7
vendor/anyhow/tests/compiletest.rs
vendored
Normal file
@ -0,0 +1,7 @@
|
||||
#[rustversion::attr(not(nightly), ignore)]
|
||||
#[cfg_attr(miri, ignore)]
|
||||
#[test]
|
||||
fn ui() {
|
||||
let t = trybuild::TestCases::new();
|
||||
t.compile_fail("tests/ui/*.rs");
|
||||
}
|
53
vendor/anyhow/tests/drop/mod.rs
vendored
Normal file
53
vendor/anyhow/tests/drop/mod.rs
vendored
Normal file
@ -0,0 +1,53 @@
|
||||
#![allow(clippy::module_name_repetitions)]
|
||||
|
||||
use std::error::Error as StdError;
|
||||
use std::fmt::{self, Display};
|
||||
use std::sync::atomic::{AtomicBool, Ordering};
|
||||
use std::sync::Arc;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Flag {
|
||||
atomic: Arc<AtomicBool>,
|
||||
}
|
||||
|
||||
impl Flag {
|
||||
pub fn new() -> Self {
|
||||
Flag {
|
||||
atomic: Arc::new(AtomicBool::new(false)),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get(&self) -> bool {
|
||||
self.atomic.load(Ordering::Relaxed)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct DetectDrop {
|
||||
has_dropped: Flag,
|
||||
}
|
||||
|
||||
impl DetectDrop {
|
||||
pub fn new(has_dropped: &Flag) -> Self {
|
||||
DetectDrop {
|
||||
has_dropped: Flag {
|
||||
atomic: Arc::clone(&has_dropped.atomic),
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl StdError for DetectDrop {}
|
||||
|
||||
impl Display for DetectDrop {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "oh no!")
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for DetectDrop {
|
||||
fn drop(&mut self) {
|
||||
let already_dropped = self.has_dropped.atomic.swap(true, Ordering::Relaxed);
|
||||
assert!(!already_dropped);
|
||||
}
|
||||
}
|
13
vendor/anyhow/tests/test_autotrait.rs
vendored
Normal file
13
vendor/anyhow/tests/test_autotrait.rs
vendored
Normal file
@ -0,0 +1,13 @@
|
||||
use anyhow::Error;
|
||||
|
||||
#[test]
|
||||
fn test_send() {
|
||||
fn assert_send<T: Send>() {}
|
||||
assert_send::<Error>();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_sync() {
|
||||
fn assert_sync<T: Sync>() {}
|
||||
assert_sync::<Error>();
|
||||
}
|
13
vendor/anyhow/tests/test_backtrace.rs
vendored
Normal file
13
vendor/anyhow/tests/test_backtrace.rs
vendored
Normal file
@ -0,0 +1,13 @@
|
||||
#[rustversion::not(nightly)]
|
||||
#[ignore]
|
||||
#[test]
|
||||
fn test_backtrace() {}
|
||||
|
||||
#[rustversion::nightly]
|
||||
#[test]
|
||||
fn test_backtrace() {
|
||||
use anyhow::anyhow;
|
||||
|
||||
let error = anyhow!("oh no!");
|
||||
let _ = error.backtrace();
|
||||
}
|
45
vendor/anyhow/tests/test_boxed.rs
vendored
Normal file
45
vendor/anyhow/tests/test_boxed.rs
vendored
Normal file
@ -0,0 +1,45 @@
|
||||
#![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;
|
||||
use thiserror::Error;
|
||||
|
||||
#[derive(Error, Debug)]
|
||||
#[error("outer")]
|
||||
struct MyError {
|
||||
source: io::Error,
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_boxed_str() {
|
||||
let error = Box::<dyn StdError + Send + Sync>::from("oh no!");
|
||||
let error = anyhow!(error);
|
||||
assert_eq!("oh no!", error.to_string());
|
||||
assert_eq!(
|
||||
"oh no!",
|
||||
error
|
||||
.downcast_ref::<Box<dyn StdError + Send + Sync>>()
|
||||
.unwrap()
|
||||
.to_string()
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_boxed_thiserror() {
|
||||
let error = MyError {
|
||||
source: io::Error::new(io::ErrorKind::Other, "oh no!"),
|
||||
};
|
||||
let error = anyhow!(error);
|
||||
assert_eq!("oh no!", error.source().unwrap().to_string());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_boxed_anyhow() {
|
||||
let error = anyhow!("oh no!").context("it failed");
|
||||
let error = anyhow!(error);
|
||||
assert_eq!("oh no!", error.source().unwrap().to_string());
|
||||
}
|
68
vendor/anyhow/tests/test_chain.rs
vendored
Normal file
68
vendor/anyhow/tests/test_chain.rs
vendored
Normal file
@ -0,0 +1,68 @@
|
||||
use anyhow::{anyhow, Chain, Error};
|
||||
|
||||
fn error() -> Error {
|
||||
anyhow!({ 0 }).context(1).context(2).context(3)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_iter() {
|
||||
let e = error();
|
||||
let mut chain = e.chain();
|
||||
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());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_rev() {
|
||||
let e = error();
|
||||
let mut chain = e.chain().rev();
|
||||
assert_eq!("0", chain.next().unwrap().to_string());
|
||||
assert_eq!("1", chain.next().unwrap().to_string());
|
||||
assert_eq!("2", chain.next().unwrap().to_string());
|
||||
assert_eq!("3", chain.next().unwrap().to_string());
|
||||
assert!(chain.next().is_none());
|
||||
assert!(chain.next_back().is_none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
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());
|
||||
}
|
172
vendor/anyhow/tests/test_context.rs
vendored
Normal file
172
vendor/anyhow/tests/test_context.rs
vendored
Normal file
@ -0,0 +1,172 @@
|
||||
#![allow(
|
||||
// Clippy bug: https://github.com/rust-lang/rust-clippy/issues/7422
|
||||
clippy::nonstandard_macro_braces,
|
||||
)]
|
||||
|
||||
mod drop;
|
||||
|
||||
use crate::drop::{DetectDrop, Flag};
|
||||
use anyhow::{Context, Error, Result};
|
||||
use std::fmt::{self, Display};
|
||||
use thiserror::Error;
|
||||
|
||||
// https://github.com/dtolnay/anyhow/issues/18
|
||||
#[test]
|
||||
fn test_inference() -> Result<()> {
|
||||
let x = "1";
|
||||
let y: u32 = x.parse().context("...")?;
|
||||
assert_eq!(y, 1);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
macro_rules! context_type {
|
||||
($name:ident) => {
|
||||
#[derive(Debug)]
|
||||
struct $name {
|
||||
message: &'static str,
|
||||
#[allow(dead_code)]
|
||||
drop: DetectDrop,
|
||||
}
|
||||
|
||||
impl Display for $name {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
f.write_str(self.message)
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
context_type!(HighLevel);
|
||||
context_type!(MidLevel);
|
||||
|
||||
#[derive(Error, Debug)]
|
||||
#[error("{message}")]
|
||||
struct LowLevel {
|
||||
message: &'static str,
|
||||
drop: DetectDrop,
|
||||
}
|
||||
|
||||
struct Dropped {
|
||||
low: Flag,
|
||||
mid: Flag,
|
||||
high: Flag,
|
||||
}
|
||||
|
||||
impl Dropped {
|
||||
fn none(&self) -> bool {
|
||||
!self.low.get() && !self.mid.get() && !self.high.get()
|
||||
}
|
||||
|
||||
fn all(&self) -> bool {
|
||||
self.low.get() && self.mid.get() && self.high.get()
|
||||
}
|
||||
}
|
||||
|
||||
fn make_chain() -> (Error, Dropped) {
|
||||
let dropped = Dropped {
|
||||
low: Flag::new(),
|
||||
mid: Flag::new(),
|
||||
high: Flag::new(),
|
||||
};
|
||||
|
||||
let low = LowLevel {
|
||||
message: "no such file or directory",
|
||||
drop: DetectDrop::new(&dropped.low),
|
||||
};
|
||||
|
||||
// impl Context for Result<T, E>
|
||||
let mid = Err::<(), LowLevel>(low)
|
||||
.context(MidLevel {
|
||||
message: "failed to load config",
|
||||
drop: DetectDrop::new(&dropped.mid),
|
||||
})
|
||||
.unwrap_err();
|
||||
|
||||
// impl Context for Result<T, Error>
|
||||
let high = Err::<(), Error>(mid)
|
||||
.context(HighLevel {
|
||||
message: "failed to start server",
|
||||
drop: DetectDrop::new(&dropped.high),
|
||||
})
|
||||
.unwrap_err();
|
||||
|
||||
(high, dropped)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_downcast_ref() {
|
||||
let (err, dropped) = make_chain();
|
||||
|
||||
assert!(!err.is::<String>());
|
||||
assert!(err.downcast_ref::<String>().is_none());
|
||||
|
||||
assert!(err.is::<HighLevel>());
|
||||
let high = err.downcast_ref::<HighLevel>().unwrap();
|
||||
assert_eq!(high.to_string(), "failed to start server");
|
||||
|
||||
assert!(err.is::<MidLevel>());
|
||||
let mid = err.downcast_ref::<MidLevel>().unwrap();
|
||||
assert_eq!(mid.to_string(), "failed to load config");
|
||||
|
||||
assert!(err.is::<LowLevel>());
|
||||
let low = err.downcast_ref::<LowLevel>().unwrap();
|
||||
assert_eq!(low.to_string(), "no such file or directory");
|
||||
|
||||
assert!(dropped.none());
|
||||
drop(err);
|
||||
assert!(dropped.all());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_downcast_high() {
|
||||
let (err, dropped) = make_chain();
|
||||
|
||||
let err = err.downcast::<HighLevel>().unwrap();
|
||||
assert!(!dropped.high.get());
|
||||
assert!(dropped.low.get() && dropped.mid.get());
|
||||
|
||||
drop(err);
|
||||
assert!(dropped.all());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_downcast_mid() {
|
||||
let (err, dropped) = make_chain();
|
||||
|
||||
let err = err.downcast::<MidLevel>().unwrap();
|
||||
assert!(!dropped.mid.get());
|
||||
assert!(dropped.low.get() && dropped.high.get());
|
||||
|
||||
drop(err);
|
||||
assert!(dropped.all());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_downcast_low() {
|
||||
let (err, dropped) = make_chain();
|
||||
|
||||
let err = err.downcast::<LowLevel>().unwrap();
|
||||
assert!(!dropped.low.get());
|
||||
assert!(dropped.mid.get() && dropped.high.get());
|
||||
|
||||
drop(err);
|
||||
assert!(dropped.all());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_unsuccessful_downcast() {
|
||||
let (err, dropped) = make_chain();
|
||||
|
||||
let err = err.downcast::<String>().unwrap_err();
|
||||
assert!(dropped.none());
|
||||
|
||||
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");
|
||||
}
|
46
vendor/anyhow/tests/test_convert.rs
vendored
Normal file
46
vendor/anyhow/tests/test_convert.rs
vendored
Normal file
@ -0,0 +1,46 @@
|
||||
#![allow(clippy::unnecessary_wraps)]
|
||||
|
||||
mod drop;
|
||||
|
||||
use self::drop::{DetectDrop, Flag};
|
||||
use anyhow::{Error, Result};
|
||||
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);
|
||||
assert_eq!("oh no!", box_dyn.to_string());
|
||||
drop(box_dyn);
|
||||
assert!(has_dropped.get());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_question_mark() -> Result<(), Box<dyn StdError>> {
|
||||
fn f() -> Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
f()?;
|
||||
Ok(())
|
||||
}
|
123
vendor/anyhow/tests/test_downcast.rs
vendored
Normal file
123
vendor/anyhow/tests/test_downcast.rs
vendored
Normal file
@ -0,0 +1,123 @@
|
||||
#![allow(clippy::assertions_on_result_states, clippy::wildcard_imports)]
|
||||
|
||||
mod common;
|
||||
mod drop;
|
||||
|
||||
use self::common::*;
|
||||
use self::drop::{DetectDrop, Flag};
|
||||
use anyhow::Error;
|
||||
use std::error::Error as StdError;
|
||||
use std::fmt::{self, Display};
|
||||
use std::io;
|
||||
|
||||
#[test]
|
||||
fn test_downcast() {
|
||||
assert_eq!(
|
||||
"oh no!",
|
||||
bail_literal().unwrap_err().downcast::<&str>().unwrap(),
|
||||
);
|
||||
assert_eq!(
|
||||
"oh no!",
|
||||
bail_fmt().unwrap_err().downcast::<String>().unwrap(),
|
||||
);
|
||||
assert_eq!(
|
||||
"oh no!",
|
||||
bail_error()
|
||||
.unwrap_err()
|
||||
.downcast::<io::Error>()
|
||||
.unwrap()
|
||||
.to_string(),
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_downcast_ref() {
|
||||
assert_eq!(
|
||||
"oh no!",
|
||||
*bail_literal().unwrap_err().downcast_ref::<&str>().unwrap(),
|
||||
);
|
||||
assert_eq!(
|
||||
"oh no!",
|
||||
bail_fmt().unwrap_err().downcast_ref::<String>().unwrap(),
|
||||
);
|
||||
assert_eq!(
|
||||
"oh no!",
|
||||
bail_error()
|
||||
.unwrap_err()
|
||||
.downcast_ref::<io::Error>()
|
||||
.unwrap()
|
||||
.to_string(),
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_downcast_mut() {
|
||||
assert_eq!(
|
||||
"oh no!",
|
||||
*bail_literal().unwrap_err().downcast_mut::<&str>().unwrap(),
|
||||
);
|
||||
assert_eq!(
|
||||
"oh no!",
|
||||
bail_fmt().unwrap_err().downcast_mut::<String>().unwrap(),
|
||||
);
|
||||
assert_eq!(
|
||||
"oh no!",
|
||||
bail_error()
|
||||
.unwrap_err()
|
||||
.downcast_mut::<io::Error>()
|
||||
.unwrap()
|
||||
.to_string(),
|
||||
);
|
||||
|
||||
let mut bailed = bail_fmt().unwrap_err();
|
||||
*bailed.downcast_mut::<String>().unwrap() = "clobber".to_string();
|
||||
assert_eq!(bailed.downcast_ref::<String>().unwrap(), "clobber");
|
||||
assert_eq!(bailed.downcast_mut::<String>().unwrap(), "clobber");
|
||||
assert_eq!(bailed.downcast::<String>().unwrap(), "clobber");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_drop() {
|
||||
let has_dropped = Flag::new();
|
||||
let error = Error::new(DetectDrop::new(&has_dropped));
|
||||
drop(error.downcast::<DetectDrop>().unwrap());
|
||||
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))]
|
||||
#[derive(Debug)]
|
||||
struct LargeAlignedError(&'static str);
|
||||
|
||||
impl Display for LargeAlignedError {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
f.write_str(self.0)
|
||||
}
|
||||
}
|
||||
|
||||
impl StdError for LargeAlignedError {}
|
||||
|
||||
let error = Error::new(LargeAlignedError("oh no!"));
|
||||
assert_eq!(
|
||||
"oh no!",
|
||||
error.downcast_ref::<LargeAlignedError>().unwrap().0
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_unsuccessful_downcast() {
|
||||
let mut error = bail_error().unwrap_err();
|
||||
assert!(error.downcast_ref::<&str>().is_none());
|
||||
assert!(error.downcast_mut::<&str>().is_none());
|
||||
assert!(error.downcast::<&str>().is_err());
|
||||
}
|
698
vendor/anyhow/tests/test_ensure.rs
vendored
Normal file
698
vendor/anyhow/tests/test_ensure.rs
vendored
Normal file
@ -0,0 +1,698 @@
|
||||
#![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::overly_complex_bool_expr,
|
||||
clippy::redundant_closure_call,
|
||||
clippy::redundant_pattern_matching,
|
||||
clippy::too_many_lines,
|
||||
clippy::unit_arg,
|
||||
clippy::while_immutable_condition,
|
||||
clippy::zero_ptr,
|
||||
irrefutable_let_patterns
|
||||
)]
|
||||
|
||||
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();
|
||||
|
||||
// In general different rustc versions will format the interpolated lhs and
|
||||
// rhs $:expr fragment with insignificant differences in whitespace or
|
||||
// punctuation, so we check the message in full against nightly and do just
|
||||
// a cursory test on older toolchains.
|
||||
if rustversion::cfg!(nightly) && !cfg!(miri) {
|
||||
assert_eq!(actual, expected);
|
||||
} else {
|
||||
assert_eq!(actual.contains(" vs "), expected.contains(" vs "));
|
||||
}
|
||||
}
|
||||
|
||||
#[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,
|
||||
"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,
|
||||
"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)",
|
||||
);
|
||||
|
||||
fn f<const I: isize>() {}
|
||||
let test = || Ok(ensure!(f::<1>() != ()));
|
||||
assert_err(test, "Condition failed: `f::<1>() != ()` (() vs ())");
|
||||
let test = || Ok(ensure!(f::<-1>() != ()));
|
||||
assert_err(test, "Condition failed: `f::<-1>() != ()` (() vs ())");
|
||||
|
||||
fn g<T, const I: isize>() {}
|
||||
let test = || Ok(ensure!(g::<u8, 1>() != ()));
|
||||
assert_err(test, "Condition failed: `g::<u8, 1>() != ()` (() vs ())");
|
||||
let test = || Ok(ensure!(g::<u8, -1>() != ()));
|
||||
assert_err(test, "Condition failed: `g::<u8, -1>() != ()` (() vs ())");
|
||||
|
||||
#[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)",
|
||||
);
|
||||
}
|
18
vendor/anyhow/tests/test_ffi.rs
vendored
Normal file
18
vendor/anyhow/tests/test_ffi.rs
vendored
Normal file
@ -0,0 +1,18 @@
|
||||
#![deny(improper_ctypes, improper_ctypes_definitions)]
|
||||
|
||||
use anyhow::anyhow;
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn anyhow1(err: anyhow::Error) {
|
||||
println!("{:?}", err);
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn anyhow2(err: &mut Option<anyhow::Error>) {
|
||||
*err = Some(anyhow!("ffi error"));
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn anyhow3() -> Option<anyhow::Error> {
|
||||
Some(anyhow!("ffi error"))
|
||||
}
|
94
vendor/anyhow/tests/test_fmt.rs
vendored
Normal file
94
vendor/anyhow/tests/test_fmt.rs
vendored
Normal file
@ -0,0 +1,94 @@
|
||||
use anyhow::{bail, Context, Result};
|
||||
use std::io;
|
||||
|
||||
fn f() -> Result<()> {
|
||||
bail!(io::Error::new(io::ErrorKind::PermissionDenied, "oh no!"));
|
||||
}
|
||||
|
||||
fn g() -> Result<()> {
|
||||
f().context("f failed")
|
||||
}
|
||||
|
||||
fn h() -> Result<()> {
|
||||
g().context("g failed")
|
||||
}
|
||||
|
||||
const EXPECTED_ALTDISPLAY_F: &str = "oh no!";
|
||||
|
||||
const EXPECTED_ALTDISPLAY_G: &str = "f failed: oh no!";
|
||||
|
||||
const EXPECTED_ALTDISPLAY_H: &str = "g failed: f failed: oh no!";
|
||||
|
||||
const EXPECTED_DEBUG_F: &str = "oh no!";
|
||||
|
||||
const EXPECTED_DEBUG_G: &str = "\
|
||||
f failed
|
||||
|
||||
Caused by:
|
||||
oh no!\
|
||||
";
|
||||
|
||||
const EXPECTED_DEBUG_H: &str = "\
|
||||
g failed
|
||||
|
||||
Caused by:
|
||||
0: f failed
|
||||
1: oh no!\
|
||||
";
|
||||
|
||||
const EXPECTED_ALTDEBUG_F: &str = "\
|
||||
Custom {
|
||||
kind: PermissionDenied,
|
||||
error: \"oh no!\",
|
||||
}\
|
||||
";
|
||||
|
||||
const EXPECTED_ALTDEBUG_G: &str = "\
|
||||
Error {
|
||||
context: \"f failed\",
|
||||
source: Custom {
|
||||
kind: PermissionDenied,
|
||||
error: \"oh no!\",
|
||||
},
|
||||
}\
|
||||
";
|
||||
|
||||
const EXPECTED_ALTDEBUG_H: &str = "\
|
||||
Error {
|
||||
context: \"g failed\",
|
||||
source: Error {
|
||||
context: \"f failed\",
|
||||
source: Custom {
|
||||
kind: PermissionDenied,
|
||||
error: \"oh no!\",
|
||||
},
|
||||
},
|
||||
}\
|
||||
";
|
||||
|
||||
#[test]
|
||||
fn test_display() {
|
||||
assert_eq!("g failed", h().unwrap_err().to_string());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_altdisplay() {
|
||||
assert_eq!(EXPECTED_ALTDISPLAY_F, format!("{:#}", f().unwrap_err()));
|
||||
assert_eq!(EXPECTED_ALTDISPLAY_G, format!("{:#}", g().unwrap_err()));
|
||||
assert_eq!(EXPECTED_ALTDISPLAY_H, format!("{:#}", h().unwrap_err()));
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg_attr(not(backtrace), ignore)]
|
||||
fn test_debug() {
|
||||
assert_eq!(EXPECTED_DEBUG_F, format!("{:?}", f().unwrap_err()));
|
||||
assert_eq!(EXPECTED_DEBUG_G, format!("{:?}", g().unwrap_err()));
|
||||
assert_eq!(EXPECTED_DEBUG_H, format!("{:?}", h().unwrap_err()));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_altdebug() {
|
||||
assert_eq!(EXPECTED_ALTDEBUG_F, format!("{:#?}", f().unwrap_err()));
|
||||
assert_eq!(EXPECTED_ALTDEBUG_G, format!("{:#?}", g().unwrap_err()));
|
||||
assert_eq!(EXPECTED_ALTDEBUG_H, format!("{:#?}", h().unwrap_err()));
|
||||
}
|
80
vendor/anyhow/tests/test_macros.rs
vendored
Normal file
80
vendor/anyhow/tests/test_macros.rs
vendored
Normal file
@ -0,0 +1,80 @@
|
||||
#![allow(
|
||||
clippy::assertions_on_result_states,
|
||||
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::{anyhow, ensure};
|
||||
use std::cell::Cell;
|
||||
use std::future;
|
||||
|
||||
#[test]
|
||||
fn test_messages() {
|
||||
assert_eq!("oh no!", bail_literal().unwrap_err().to_string());
|
||||
assert_eq!("oh no!", bail_fmt().unwrap_err().to_string());
|
||||
assert_eq!("oh no!", bail_error().unwrap_err().to_string());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_ensure() {
|
||||
let f = || {
|
||||
ensure!(1 + 1 == 2, "This is correct");
|
||||
Ok(())
|
||||
};
|
||||
assert!(f().is_ok());
|
||||
|
||||
let v = 1;
|
||||
let f = || {
|
||||
ensure!(v + v == 2, "This is correct, v: {}", v);
|
||||
Ok(())
|
||||
};
|
||||
assert!(f().is_ok());
|
||||
|
||||
let f = || {
|
||||
ensure!(v + v == 1, "This is not correct, v: {}", v);
|
||||
Ok(())
|
||||
};
|
||||
assert!(f().is_err());
|
||||
|
||||
let f = || {
|
||||
ensure!(v + v == 1);
|
||||
Ok(())
|
||||
};
|
||||
assert_eq!(
|
||||
f().unwrap_err().to_string(),
|
||||
"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());
|
||||
}
|
29
vendor/anyhow/tests/test_repr.rs
vendored
Normal file
29
vendor/anyhow/tests/test_repr.rs
vendored
Normal file
@ -0,0 +1,29 @@
|
||||
mod drop;
|
||||
|
||||
use self::drop::{DetectDrop, Flag};
|
||||
use anyhow::Error;
|
||||
use std::marker::Unpin;
|
||||
use std::mem;
|
||||
|
||||
#[test]
|
||||
fn test_error_size() {
|
||||
assert_eq!(mem::size_of::<Error>(), mem::size_of::<usize>());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_null_pointer_optimization() {
|
||||
assert_eq!(mem::size_of::<Result<(), Error>>(), mem::size_of::<usize>());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_autotraits() {
|
||||
fn assert<E: Unpin + Send + Sync + 'static>() {}
|
||||
assert::<Error>();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_drop() {
|
||||
let has_dropped = Flag::new();
|
||||
drop(Error::new(DetectDrop::new(&has_dropped)));
|
||||
assert!(has_dropped.get());
|
||||
}
|
62
vendor/anyhow/tests/test_source.rs
vendored
Normal file
62
vendor/anyhow/tests/test_source.rs
vendored
Normal file
@ -0,0 +1,62 @@
|
||||
use anyhow::anyhow;
|
||||
use std::error::Error as StdError;
|
||||
use std::fmt::{self, Display};
|
||||
use std::io;
|
||||
|
||||
#[derive(Debug)]
|
||||
enum TestError {
|
||||
Io(io::Error),
|
||||
}
|
||||
|
||||
impl Display for TestError {
|
||||
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
|
||||
match self {
|
||||
TestError::Io(e) => Display::fmt(e, formatter),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl StdError for TestError {
|
||||
fn source(&self) -> Option<&(dyn StdError + 'static)> {
|
||||
match self {
|
||||
TestError::Io(io) => Some(io),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_literal_source() {
|
||||
let error = anyhow!("oh no!");
|
||||
assert!(error.source().is_none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_variable_source() {
|
||||
let msg = "oh no!";
|
||||
let error = anyhow!(msg);
|
||||
assert!(error.source().is_none());
|
||||
|
||||
let msg = msg.to_owned();
|
||||
let error = anyhow!(msg);
|
||||
assert!(error.source().is_none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_fmt_source() {
|
||||
let error = anyhow!("{} {}!", "oh", "no");
|
||||
assert!(error.source().is_none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_io_source() {
|
||||
let io = io::Error::new(io::ErrorKind::Other, "oh no!");
|
||||
let error = anyhow!(TestError::Io(io));
|
||||
assert_eq!("oh no!", error.source().unwrap().to_string());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_anyhow_from_anyhow() {
|
||||
let error = anyhow!("oh no!").context("context");
|
||||
let error = anyhow!(error);
|
||||
assert_eq!("oh no!", error.source().unwrap().to_string());
|
||||
}
|
8
vendor/anyhow/tests/ui/chained-comparison.rs
vendored
Normal file
8
vendor/anyhow/tests/ui/chained-comparison.rs
vendored
Normal file
@ -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(())
|
||||
}
|
10
vendor/anyhow/tests/ui/chained-comparison.stderr
vendored
Normal file
10
vendor/anyhow/tests/ui/chained-comparison.stderr
vendored
Normal file
@ -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);
|
||||
| ++++++++
|
6
vendor/anyhow/tests/ui/empty-ensure.rs
vendored
Normal file
6
vendor/anyhow/tests/ui/empty-ensure.rs
vendored
Normal file
@ -0,0 +1,6 @@
|
||||
use anyhow::{ensure, Result};
|
||||
|
||||
fn main() -> Result<()> {
|
||||
ensure!();
|
||||
Ok(())
|
||||
}
|
7
vendor/anyhow/tests/ui/empty-ensure.stderr
vendored
Normal file
7
vendor/anyhow/tests/ui/empty-ensure.stderr
vendored
Normal file
@ -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` which comes from the expansion of the macro `ensure` (in Nightly builds, run with -Z macro-backtrace for more info)
|
11
vendor/anyhow/tests/ui/must-use.rs
vendored
Normal file
11
vendor/anyhow/tests/ui/must-use.rs
vendored
Normal file
@ -0,0 +1,11 @@
|
||||
#![deny(unused_must_use)]
|
||||
|
||||
use anyhow::anyhow;
|
||||
|
||||
fn main() -> anyhow::Result<()> {
|
||||
if true {
|
||||
// meant to write bail!
|
||||
anyhow!("it failed");
|
||||
}
|
||||
Ok(())
|
||||
}
|
12
vendor/anyhow/tests/ui/must-use.stderr
vendored
Normal file
12
vendor/anyhow/tests/ui/must-use.stderr
vendored
Normal file
@ -0,0 +1,12 @@
|
||||
error: unused return value of `anyhow::__private::must_use` that must be used
|
||||
--> tests/ui/must-use.rs:8:9
|
||||
|
|
||||
8 | anyhow!("it failed");
|
||||
| ^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
note: the lint level is defined here
|
||||
--> tests/ui/must-use.rs:1:9
|
||||
|
|
||||
1 | #![deny(unused_must_use)]
|
||||
| ^^^^^^^^^^^^^^^
|
||||
= note: this error originates in the macro `anyhow` (in Nightly builds, run with -Z macro-backtrace for more info)
|
8
vendor/anyhow/tests/ui/no-impl.rs
vendored
Normal file
8
vendor/anyhow/tests/ui/no-impl.rs
vendored
Normal file
@ -0,0 +1,8 @@
|
||||
use anyhow::anyhow;
|
||||
|
||||
#[derive(Debug)]
|
||||
struct Error;
|
||||
|
||||
fn main() {
|
||||
let _ = anyhow!(Error);
|
||||
}
|
31
vendor/anyhow/tests/ui/no-impl.stderr
vendored
Normal file
31
vendor/anyhow/tests/ui/no-impl.stderr
vendored
Normal file
@ -0,0 +1,31 @@
|
||||
error[E0599]: the method `anyhow_kind` exists for reference `&Error`, but its trait bounds were not satisfied
|
||||
--> tests/ui/no-impl.rs:7:13
|
||||
|
|
||||
4 | struct Error;
|
||||
| ------------
|
||||
| |
|
||||
| doesn't satisfy `Error: Into<anyhow::Error>`
|
||||
| doesn't satisfy `Error: anyhow::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::kind::TraitKind`
|
||||
`Error: std::fmt::Display`
|
||||
which is required by `&Error: anyhow::kind::AdhocKind`
|
||||
`&Error: Into<anyhow::Error>`
|
||||
which is required by `&Error: anyhow::kind::TraitKind`
|
||||
note: the following traits must be implemented
|
||||
--> $RUST/core/src/fmt/mod.rs
|
||||
|
|
||||
| pub trait Display {
|
||||
| ^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
::: $RUST/core/src/convert/mod.rs
|
||||
|
|
||||
| pub trait Into<T>: Sized {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
= note: this error originates in the macro `anyhow` (in Nightly builds, run with -Z macro-backtrace for more info)
|
5
vendor/anyhow/tests/ui/temporary-value.rs
vendored
Normal file
5
vendor/anyhow/tests/ui/temporary-value.rs
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
use anyhow::anyhow;
|
||||
|
||||
fn main() {
|
||||
let _ = anyhow!(&String::new());
|
||||
}
|
9
vendor/anyhow/tests/ui/temporary-value.stderr
vendored
Normal file
9
vendor/anyhow/tests/ui/temporary-value.stderr
vendored
Normal file
@ -0,0 +1,9 @@
|
||||
error[E0716]: temporary value dropped while borrowed
|
||||
--> tests/ui/temporary-value.rs:4:22
|
||||
|
|
||||
4 | let _ = anyhow!(&String::new());
|
||||
| ---------^^^^^^^^^^^^^-
|
||||
| | |
|
||||
| | 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`
|
5
vendor/anyhow/tests/ui/wrong-interpolation.rs
vendored
Normal file
5
vendor/anyhow/tests/ui/wrong-interpolation.rs
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
use anyhow::{bail, Result};
|
||||
|
||||
fn main() -> Result<()> {
|
||||
bail!("{} not found");
|
||||
}
|
5
vendor/anyhow/tests/ui/wrong-interpolation.stderr
vendored
Normal file
5
vendor/anyhow/tests/ui/wrong-interpolation.stderr
vendored
Normal file
@ -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
vendor/autocfg/.cargo-checksum.json
vendored
Normal file
1
vendor/autocfg/.cargo-checksum.json
vendored
Normal file
@ -0,0 +1 @@
|
||||
{"files":{"Cargo.lock":"3d91565ed13de572a9ebde408a0c98e33f931d6ab52f212b0830a60b4ab26b77","Cargo.toml":"39f627122dceaad42146634719fde802fca3baa1b3908753af723074ae2a6d69","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"27995d58ad5c1145c1a8cd86244ce844886958a35eb2b78c6b772748669999ac","README.md":"4c8f9b5016f2a0c3dbeca5bc41241f57db5568f803e58c1fa480ae2b3638d0a9","examples/integers.rs":"589ff4271566dfa322becddf3e2c7b592e6e0bc97b02892ce75619b7e452e930","examples/paths.rs":"1b30e466b824ce8df7ad0a55334424131d9d2573d6cf9f7d5d50c09c8901d526","examples/traits.rs":"cbee6a3e1f7db60b02ae25b714926517144a77cb492021f492774cf0e1865a9e","examples/versions.rs":"38535e6d9f5bfae0de474a3db79a40e8f5da8ba9334c5ff4c363de9bc99d4d12","src/error.rs":"12de7dafea4a35d1dc2f0fa79bfa038386bbbea72bf083979f4ddf227999eeda","src/lib.rs":"6fa01458e8f9258d84f83ead24fdb0cdf9aec10838b0262f1dfbdf79c530c537","src/tests.rs":"f0e6dc1ad9223c0336c02e215ea3940acb2af6c3bc8fd791e16cd4e786e6a608","src/version.rs":"175727d5f02f2fe2271ddc9b041db2a5b9c6fe0f95afd17c73a4d982612764a3","tests/rustflags.rs":"5c8169b88216055019db61b5d7baf4abdf675e3b14b54f5037bb1e3acd0a5d3f"},"package":"d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"}
|
7
vendor/autocfg/Cargo.lock
generated
vendored
Normal file
7
vendor/autocfg/Cargo.lock
generated
vendored
Normal file
@ -0,0 +1,7 @@
|
||||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
version = 3
|
||||
|
||||
[[package]]
|
||||
name = "autocfg"
|
||||
version = "1.1.0"
|
24
vendor/autocfg/Cargo.toml
vendored
Normal file
24
vendor/autocfg/Cargo.toml
vendored
Normal file
@ -0,0 +1,24 @@
|
||||
# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO
|
||||
#
|
||||
# When uploading crates to the registry Cargo will automatically
|
||||
# "normalize" Cargo.toml files for maximal compatibility
|
||||
# with all versions of Cargo and also rewrite `path` dependencies
|
||||
# to registry (e.g., crates.io) dependencies.
|
||||
#
|
||||
# If you are reading this file be aware that the original Cargo.toml
|
||||
# will likely look very different (and much more reasonable).
|
||||
# See Cargo.toml.orig for the original contents.
|
||||
|
||||
[package]
|
||||
name = "autocfg"
|
||||
version = "1.1.0"
|
||||
authors = ["Josh Stone <cuviper@gmail.com>"]
|
||||
exclude = ["/.github/**", "/bors.toml"]
|
||||
description = "Automatic cfg for Rust compiler features"
|
||||
readme = "README.md"
|
||||
keywords = ["rustc", "build", "autoconf"]
|
||||
categories = ["development-tools::build-utils"]
|
||||
license = "Apache-2.0 OR MIT"
|
||||
repository = "https://github.com/cuviper/autocfg"
|
||||
|
||||
[dependencies]
|
201
vendor/autocfg/LICENSE-APACHE
vendored
Normal file
201
vendor/autocfg/LICENSE-APACHE
vendored
Normal file
@ -0,0 +1,201 @@
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
25
vendor/autocfg/LICENSE-MIT
vendored
Normal file
25
vendor/autocfg/LICENSE-MIT
vendored
Normal file
@ -0,0 +1,25 @@
|
||||
Copyright (c) 2018 Josh Stone
|
||||
|
||||
Permission is hereby granted, free of charge, to any
|
||||
person obtaining a copy of this software and associated
|
||||
documentation files (the "Software"), to deal in the
|
||||
Software without restriction, including without
|
||||
limitation the rights to use, copy, modify, merge,
|
||||
publish, distribute, sublicense, and/or sell copies of
|
||||
the Software, and to permit persons to whom the Software
|
||||
is furnished to do so, subject to the following
|
||||
conditions:
|
||||
|
||||
The above copyright notice and this permission notice
|
||||
shall be included in all copies or substantial portions
|
||||
of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
|
||||
ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
|
||||
TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
|
||||
PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
|
||||
SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
|
||||
IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
DEALINGS IN THE SOFTWARE.
|
95
vendor/autocfg/README.md
vendored
Normal file
95
vendor/autocfg/README.md
vendored
Normal file
@ -0,0 +1,95 @@
|
||||
autocfg
|
||||
=======
|
||||
|
||||
[![autocfg crate](https://img.shields.io/crates/v/autocfg.svg)](https://crates.io/crates/autocfg)
|
||||
[![autocfg documentation](https://docs.rs/autocfg/badge.svg)](https://docs.rs/autocfg)
|
||||
![minimum rustc 1.0](https://img.shields.io/badge/rustc-1.0+-red.svg)
|
||||
![build status](https://github.com/cuviper/autocfg/workflows/master/badge.svg)
|
||||
|
||||
A Rust library for build scripts to automatically configure code based on
|
||||
compiler support. Code snippets are dynamically tested to see if the `rustc`
|
||||
will accept them, rather than hard-coding specific version support.
|
||||
|
||||
|
||||
## Usage
|
||||
|
||||
Add this to your `Cargo.toml`:
|
||||
|
||||
```toml
|
||||
[build-dependencies]
|
||||
autocfg = "1"
|
||||
```
|
||||
|
||||
Then use it in your `build.rs` script to detect compiler features. For
|
||||
example, to test for 128-bit integer support, it might look like:
|
||||
|
||||
```rust
|
||||
extern crate autocfg;
|
||||
|
||||
fn main() {
|
||||
let ac = autocfg::new();
|
||||
ac.emit_has_type("i128");
|
||||
|
||||
// (optional) We don't need to rerun for anything external.
|
||||
autocfg::rerun_path("build.rs");
|
||||
}
|
||||
```
|
||||
|
||||
If the type test succeeds, this will write a `cargo:rustc-cfg=has_i128` line
|
||||
for Cargo, which translates to Rust arguments `--cfg has_i128`. Then in the
|
||||
rest of your Rust code, you can add `#[cfg(has_i128)]` conditions on code that
|
||||
should only be used when the compiler supports it.
|
||||
|
||||
|
||||
## Release Notes
|
||||
|
||||
- 1.1.0 (2022-02-07)
|
||||
- Use `CARGO_ENCODED_RUSTFLAGS` when it is set.
|
||||
|
||||
- 1.0.1 (2020-08-20)
|
||||
- Apply `RUSTFLAGS` for more `--target` scenarios, by @adamreichold.
|
||||
|
||||
- 1.0.0 (2020-01-08)
|
||||
- 🎉 Release 1.0! 🎉 (no breaking changes)
|
||||
- Add `probe_expression` and `emit_expression_cfg` to test arbitrary expressions.
|
||||
- Add `probe_constant` and `emit_constant_cfg` to test arbitrary constant expressions.
|
||||
|
||||
- 0.1.7 (2019-10-20)
|
||||
- Apply `RUSTFLAGS` when probing `$TARGET != $HOST`, mainly for sysroot, by @roblabla.
|
||||
|
||||
- 0.1.6 (2019-08-19)
|
||||
- Add `probe`/`emit_sysroot_crate`, by @leo60228.
|
||||
|
||||
- 0.1.5 (2019-07-16)
|
||||
- Mask some warnings from newer rustc.
|
||||
|
||||
- 0.1.4 (2019-05-22)
|
||||
- Relax `std`/`no_std` probing to a warning instead of an error.
|
||||
- Improve `rustc` bootstrap compatibility.
|
||||
|
||||
- 0.1.3 (2019-05-21)
|
||||
- Auto-detects if `#![no_std]` is needed for the `$TARGET`.
|
||||
|
||||
- 0.1.2 (2019-01-16)
|
||||
- Add `rerun_env(ENV)` to print `cargo:rerun-if-env-changed=ENV`.
|
||||
- Add `rerun_path(PATH)` to print `cargo:rerun-if-changed=PATH`.
|
||||
|
||||
|
||||
## Minimum Rust version policy
|
||||
|
||||
This crate's minimum supported `rustc` version is `1.0.0`. Compatibility is
|
||||
its entire reason for existence, so this crate will be extremely conservative
|
||||
about raising this requirement. If this is ever deemed necessary, it will be
|
||||
treated as a major breaking change for semver purposes.
|
||||
|
||||
|
||||
## License
|
||||
|
||||
This project is licensed under either of
|
||||
|
||||
* Apache License, Version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or
|
||||
http://www.apache.org/licenses/LICENSE-2.0)
|
||||
* MIT license ([LICENSE-MIT](LICENSE-MIT) or
|
||||
http://opensource.org/licenses/MIT)
|
||||
|
||||
at your option.
|
9
vendor/autocfg/examples/integers.rs
vendored
Normal file
9
vendor/autocfg/examples/integers.rs
vendored
Normal file
@ -0,0 +1,9 @@
|
||||
extern crate autocfg;
|
||||
|
||||
fn main() {
|
||||
// Normally, cargo will set `OUT_DIR` for build scripts.
|
||||
let ac = autocfg::AutoCfg::with_dir("target").unwrap();
|
||||
for i in 3..8 {
|
||||
ac.emit_has_type(&format!("i{}", 1 << i));
|
||||
}
|
||||
}
|
22
vendor/autocfg/examples/paths.rs
vendored
Normal file
22
vendor/autocfg/examples/paths.rs
vendored
Normal file
@ -0,0 +1,22 @@
|
||||
extern crate autocfg;
|
||||
|
||||
fn main() {
|
||||
// Normally, cargo will set `OUT_DIR` for build scripts.
|
||||
let ac = autocfg::AutoCfg::with_dir("target").unwrap();
|
||||
|
||||
// since ancient times...
|
||||
ac.emit_has_path("std::vec::Vec");
|
||||
ac.emit_path_cfg("std::vec::Vec", "has_vec");
|
||||
|
||||
// rustc 1.10.0
|
||||
ac.emit_has_path("std::panic::PanicInfo");
|
||||
ac.emit_path_cfg("std::panic::PanicInfo", "has_panic_info");
|
||||
|
||||
// rustc 1.20.0
|
||||
ac.emit_has_path("std::mem::ManuallyDrop");
|
||||
ac.emit_path_cfg("std::mem::ManuallyDrop", "has_manually_drop");
|
||||
|
||||
// rustc 1.25.0
|
||||
ac.emit_has_path("std::ptr::NonNull");
|
||||
ac.emit_path_cfg("std::ptr::NonNull", "has_non_null");
|
||||
}
|
26
vendor/autocfg/examples/traits.rs
vendored
Normal file
26
vendor/autocfg/examples/traits.rs
vendored
Normal file
@ -0,0 +1,26 @@
|
||||
extern crate autocfg;
|
||||
|
||||
fn main() {
|
||||
// Normally, cargo will set `OUT_DIR` for build scripts.
|
||||
let ac = autocfg::AutoCfg::with_dir("target").unwrap();
|
||||
|
||||
// since ancient times...
|
||||
ac.emit_has_trait("std::ops::Add");
|
||||
ac.emit_trait_cfg("std::ops::Add", "has_ops");
|
||||
|
||||
// trait parameters have to be provided
|
||||
ac.emit_has_trait("std::borrow::Borrow<str>");
|
||||
ac.emit_trait_cfg("std::borrow::Borrow<str>", "has_borrow");
|
||||
|
||||
// rustc 1.8.0
|
||||
ac.emit_has_trait("std::ops::AddAssign");
|
||||
ac.emit_trait_cfg("std::ops::AddAssign", "has_assign_ops");
|
||||
|
||||
// rustc 1.12.0
|
||||
ac.emit_has_trait("std::iter::Sum");
|
||||
ac.emit_trait_cfg("std::iter::Sum", "has_sum");
|
||||
|
||||
// rustc 1.28.0
|
||||
ac.emit_has_trait("std::alloc::GlobalAlloc");
|
||||
ac.emit_trait_cfg("std::alloc::GlobalAlloc", "has_global_alloc");
|
||||
}
|
9
vendor/autocfg/examples/versions.rs
vendored
Normal file
9
vendor/autocfg/examples/versions.rs
vendored
Normal file
@ -0,0 +1,9 @@
|
||||
extern crate autocfg;
|
||||
|
||||
fn main() {
|
||||
// Normally, cargo will set `OUT_DIR` for build scripts.
|
||||
let ac = autocfg::AutoCfg::with_dir("target").unwrap();
|
||||
for i in 0..100 {
|
||||
ac.emit_rustc_version(1, i);
|
||||
}
|
||||
}
|
69
vendor/autocfg/src/error.rs
vendored
Normal file
69
vendor/autocfg/src/error.rs
vendored
Normal file
@ -0,0 +1,69 @@
|
||||
use std::error;
|
||||
use std::fmt;
|
||||
use std::io;
|
||||
use std::num;
|
||||
use std::str;
|
||||
|
||||
/// A common error type for the `autocfg` crate.
|
||||
#[derive(Debug)]
|
||||
pub struct Error {
|
||||
kind: ErrorKind,
|
||||
}
|
||||
|
||||
impl error::Error for Error {
|
||||
fn description(&self) -> &str {
|
||||
"AutoCfg error"
|
||||
}
|
||||
|
||||
fn cause(&self) -> Option<&error::Error> {
|
||||
match self.kind {
|
||||
ErrorKind::Io(ref e) => Some(e),
|
||||
ErrorKind::Num(ref e) => Some(e),
|
||||
ErrorKind::Utf8(ref e) => Some(e),
|
||||
ErrorKind::Other(_) => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for Error {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
|
||||
match self.kind {
|
||||
ErrorKind::Io(ref e) => e.fmt(f),
|
||||
ErrorKind::Num(ref e) => e.fmt(f),
|
||||
ErrorKind::Utf8(ref e) => e.fmt(f),
|
||||
ErrorKind::Other(s) => s.fmt(f),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
enum ErrorKind {
|
||||
Io(io::Error),
|
||||
Num(num::ParseIntError),
|
||||
Utf8(str::Utf8Error),
|
||||
Other(&'static str),
|
||||
}
|
||||
|
||||
pub fn from_io(e: io::Error) -> Error {
|
||||
Error {
|
||||
kind: ErrorKind::Io(e),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn from_num(e: num::ParseIntError) -> Error {
|
||||
Error {
|
||||
kind: ErrorKind::Num(e),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn from_utf8(e: str::Utf8Error) -> Error {
|
||||
Error {
|
||||
kind: ErrorKind::Utf8(e),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn from_str(s: &'static str) -> Error {
|
||||
Error {
|
||||
kind: ErrorKind::Other(s),
|
||||
}
|
||||
}
|
453
vendor/autocfg/src/lib.rs
vendored
Normal file
453
vendor/autocfg/src/lib.rs
vendored
Normal file
@ -0,0 +1,453 @@
|
||||
//! A Rust library for build scripts to automatically configure code based on
|
||||
//! compiler support. Code snippets are dynamically tested to see if the `rustc`
|
||||
//! will accept them, rather than hard-coding specific version support.
|
||||
//!
|
||||
//!
|
||||
//! ## Usage
|
||||
//!
|
||||
//! Add this to your `Cargo.toml`:
|
||||
//!
|
||||
//! ```toml
|
||||
//! [build-dependencies]
|
||||
//! autocfg = "1"
|
||||
//! ```
|
||||
//!
|
||||
//! Then use it in your `build.rs` script to detect compiler features. For
|
||||
//! example, to test for 128-bit integer support, it might look like:
|
||||
//!
|
||||
//! ```rust
|
||||
//! extern crate autocfg;
|
||||
//!
|
||||
//! fn main() {
|
||||
//! # // Normally, cargo will set `OUT_DIR` for build scripts.
|
||||
//! # std::env::set_var("OUT_DIR", "target");
|
||||
//! let ac = autocfg::new();
|
||||
//! ac.emit_has_type("i128");
|
||||
//!
|
||||
//! // (optional) We don't need to rerun for anything external.
|
||||
//! autocfg::rerun_path("build.rs");
|
||||
//! }
|
||||
//! ```
|
||||
//!
|
||||
//! If the type test succeeds, this will write a `cargo:rustc-cfg=has_i128` line
|
||||
//! for Cargo, which translates to Rust arguments `--cfg has_i128`. Then in the
|
||||
//! rest of your Rust code, you can add `#[cfg(has_i128)]` conditions on code that
|
||||
//! should only be used when the compiler supports it.
|
||||
//!
|
||||
//! ## Caution
|
||||
//!
|
||||
//! Many of the probing methods of `AutoCfg` document the particular template they
|
||||
//! use, **subject to change**. The inputs are not validated to make sure they are
|
||||
//! semantically correct for their expected use, so it's _possible_ to escape and
|
||||
//! inject something unintended. However, such abuse is unsupported and will not
|
||||
//! be considered when making changes to the templates.
|
||||
|
||||
#![deny(missing_debug_implementations)]
|
||||
#![deny(missing_docs)]
|
||||
// allow future warnings that can't be fixed while keeping 1.0 compatibility
|
||||
#![allow(unknown_lints)]
|
||||
#![allow(bare_trait_objects)]
|
||||
#![allow(ellipsis_inclusive_range_patterns)]
|
||||
|
||||
/// Local macro to avoid `std::try!`, deprecated in Rust 1.39.
|
||||
macro_rules! try {
|
||||
($result:expr) => {
|
||||
match $result {
|
||||
Ok(value) => value,
|
||||
Err(error) => return Err(error),
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
use std::env;
|
||||
use std::ffi::OsString;
|
||||
use std::fs;
|
||||
use std::io::{stderr, Write};
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::process::{Command, Stdio};
|
||||
#[allow(deprecated)]
|
||||
use std::sync::atomic::ATOMIC_USIZE_INIT;
|
||||
use std::sync::atomic::{AtomicUsize, Ordering};
|
||||
|
||||
mod error;
|
||||
pub use error::Error;
|
||||
|
||||
mod version;
|
||||
use version::Version;
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests;
|
||||
|
||||
/// Helper to detect compiler features for `cfg` output in build scripts.
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct AutoCfg {
|
||||
out_dir: PathBuf,
|
||||
rustc: PathBuf,
|
||||
rustc_version: Version,
|
||||
target: Option<OsString>,
|
||||
no_std: bool,
|
||||
rustflags: Vec<String>,
|
||||
}
|
||||
|
||||
/// Writes a config flag for rustc on standard out.
|
||||
///
|
||||
/// This looks like: `cargo:rustc-cfg=CFG`
|
||||
///
|
||||
/// Cargo will use this in arguments to rustc, like `--cfg CFG`.
|
||||
pub fn emit(cfg: &str) {
|
||||
println!("cargo:rustc-cfg={}", cfg);
|
||||
}
|
||||
|
||||
/// Writes a line telling Cargo to rerun the build script if `path` changes.
|
||||
///
|
||||
/// This looks like: `cargo:rerun-if-changed=PATH`
|
||||
///
|
||||
/// This requires at least cargo 0.7.0, corresponding to rustc 1.6.0. Earlier
|
||||
/// versions of cargo will simply ignore the directive.
|
||||
pub fn rerun_path(path: &str) {
|
||||
println!("cargo:rerun-if-changed={}", path);
|
||||
}
|
||||
|
||||
/// Writes a line telling Cargo to rerun the build script if the environment
|
||||
/// variable `var` changes.
|
||||
///
|
||||
/// This looks like: `cargo:rerun-if-env-changed=VAR`
|
||||
///
|
||||
/// This requires at least cargo 0.21.0, corresponding to rustc 1.20.0. Earlier
|
||||
/// versions of cargo will simply ignore the directive.
|
||||
pub fn rerun_env(var: &str) {
|
||||
println!("cargo:rerun-if-env-changed={}", var);
|
||||
}
|
||||
|
||||
/// Create a new `AutoCfg` instance.
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// Panics if `AutoCfg::new()` returns an error.
|
||||
pub fn new() -> AutoCfg {
|
||||
AutoCfg::new().unwrap()
|
||||
}
|
||||
|
||||
impl AutoCfg {
|
||||
/// Create a new `AutoCfg` instance.
|
||||
///
|
||||
/// # Common errors
|
||||
///
|
||||
/// - `rustc` can't be executed, from `RUSTC` or in the `PATH`.
|
||||
/// - The version output from `rustc` can't be parsed.
|
||||
/// - `OUT_DIR` is not set in the environment, or is not a writable directory.
|
||||
///
|
||||
pub fn new() -> Result<Self, Error> {
|
||||
match env::var_os("OUT_DIR") {
|
||||
Some(d) => Self::with_dir(d),
|
||||
None => Err(error::from_str("no OUT_DIR specified!")),
|
||||
}
|
||||
}
|
||||
|
||||
/// Create a new `AutoCfg` instance with the specified output directory.
|
||||
///
|
||||
/// # Common errors
|
||||
///
|
||||
/// - `rustc` can't be executed, from `RUSTC` or in the `PATH`.
|
||||
/// - The version output from `rustc` can't be parsed.
|
||||
/// - `dir` is not a writable directory.
|
||||
///
|
||||
pub fn with_dir<T: Into<PathBuf>>(dir: T) -> Result<Self, Error> {
|
||||
let rustc = env::var_os("RUSTC").unwrap_or_else(|| "rustc".into());
|
||||
let rustc: PathBuf = rustc.into();
|
||||
let rustc_version = try!(Version::from_rustc(&rustc));
|
||||
|
||||
let target = env::var_os("TARGET");
|
||||
|
||||
// Sanity check the output directory
|
||||
let dir = dir.into();
|
||||
let meta = try!(fs::metadata(&dir).map_err(error::from_io));
|
||||
if !meta.is_dir() || meta.permissions().readonly() {
|
||||
return Err(error::from_str("output path is not a writable directory"));
|
||||
}
|
||||
|
||||
let mut ac = AutoCfg {
|
||||
rustflags: rustflags(&target, &dir),
|
||||
out_dir: dir,
|
||||
rustc: rustc,
|
||||
rustc_version: rustc_version,
|
||||
target: target,
|
||||
no_std: false,
|
||||
};
|
||||
|
||||
// Sanity check with and without `std`.
|
||||
if !ac.probe("").unwrap_or(false) {
|
||||
ac.no_std = true;
|
||||
if !ac.probe("").unwrap_or(false) {
|
||||
// Neither worked, so assume nothing...
|
||||
ac.no_std = false;
|
||||
let warning = b"warning: autocfg could not probe for `std`\n";
|
||||
stderr().write_all(warning).ok();
|
||||
}
|
||||
}
|
||||
Ok(ac)
|
||||
}
|
||||
|
||||
/// Test whether the current `rustc` reports a version greater than
|
||||
/// or equal to "`major`.`minor`".
|
||||
pub fn probe_rustc_version(&self, major: usize, minor: usize) -> bool {
|
||||
self.rustc_version >= Version::new(major, minor, 0)
|
||||
}
|
||||
|
||||
/// Sets a `cfg` value of the form `rustc_major_minor`, like `rustc_1_29`,
|
||||
/// if the current `rustc` is at least that version.
|
||||
pub fn emit_rustc_version(&self, major: usize, minor: usize) {
|
||||
if self.probe_rustc_version(major, minor) {
|
||||
emit(&format!("rustc_{}_{}", major, minor));
|
||||
}
|
||||
}
|
||||
|
||||
fn probe<T: AsRef<[u8]>>(&self, code: T) -> Result<bool, Error> {
|
||||
#[allow(deprecated)]
|
||||
static ID: AtomicUsize = ATOMIC_USIZE_INIT;
|
||||
|
||||
let id = ID.fetch_add(1, Ordering::Relaxed);
|
||||
let mut command = Command::new(&self.rustc);
|
||||
command
|
||||
.arg("--crate-name")
|
||||
.arg(format!("probe{}", id))
|
||||
.arg("--crate-type=lib")
|
||||
.arg("--out-dir")
|
||||
.arg(&self.out_dir)
|
||||
.arg("--emit=llvm-ir");
|
||||
|
||||
if let Some(target) = self.target.as_ref() {
|
||||
command.arg("--target").arg(target);
|
||||
}
|
||||
|
||||
command.args(&self.rustflags);
|
||||
|
||||
command.arg("-").stdin(Stdio::piped());
|
||||
let mut child = try!(command.spawn().map_err(error::from_io));
|
||||
let mut stdin = child.stdin.take().expect("rustc stdin");
|
||||
|
||||
if self.no_std {
|
||||
try!(stdin.write_all(b"#![no_std]\n").map_err(error::from_io));
|
||||
}
|
||||
try!(stdin.write_all(code.as_ref()).map_err(error::from_io));
|
||||
drop(stdin);
|
||||
|
||||
let status = try!(child.wait().map_err(error::from_io));
|
||||
Ok(status.success())
|
||||
}
|
||||
|
||||
/// Tests whether the given sysroot crate can be used.
|
||||
///
|
||||
/// The test code is subject to change, but currently looks like:
|
||||
///
|
||||
/// ```ignore
|
||||
/// extern crate CRATE as probe;
|
||||
/// ```
|
||||
pub fn probe_sysroot_crate(&self, name: &str) -> bool {
|
||||
self.probe(format!("extern crate {} as probe;", name)) // `as _` wasn't stabilized until Rust 1.33
|
||||
.unwrap_or(false)
|
||||
}
|
||||
|
||||
/// Emits a config value `has_CRATE` if `probe_sysroot_crate` returns true.
|
||||
pub fn emit_sysroot_crate(&self, name: &str) {
|
||||
if self.probe_sysroot_crate(name) {
|
||||
emit(&format!("has_{}", mangle(name)));
|
||||
}
|
||||
}
|
||||
|
||||
/// Tests whether the given path can be used.
|
||||
///
|
||||
/// The test code is subject to change, but currently looks like:
|
||||
///
|
||||
/// ```ignore
|
||||
/// pub use PATH;
|
||||
/// ```
|
||||
pub fn probe_path(&self, path: &str) -> bool {
|
||||
self.probe(format!("pub use {};", path)).unwrap_or(false)
|
||||
}
|
||||
|
||||
/// Emits a config value `has_PATH` if `probe_path` returns true.
|
||||
///
|
||||
/// Any non-identifier characters in the `path` will be replaced with
|
||||
/// `_` in the generated config value.
|
||||
pub fn emit_has_path(&self, path: &str) {
|
||||
if self.probe_path(path) {
|
||||
emit(&format!("has_{}", mangle(path)));
|
||||
}
|
||||
}
|
||||
|
||||
/// Emits the given `cfg` value if `probe_path` returns true.
|
||||
pub fn emit_path_cfg(&self, path: &str, cfg: &str) {
|
||||
if self.probe_path(path) {
|
||||
emit(cfg);
|
||||
}
|
||||
}
|
||||
|
||||
/// Tests whether the given trait can be used.
|
||||
///
|
||||
/// The test code is subject to change, but currently looks like:
|
||||
///
|
||||
/// ```ignore
|
||||
/// pub trait Probe: TRAIT + Sized {}
|
||||
/// ```
|
||||
pub fn probe_trait(&self, name: &str) -> bool {
|
||||
self.probe(format!("pub trait Probe: {} + Sized {{}}", name))
|
||||
.unwrap_or(false)
|
||||
}
|
||||
|
||||
/// Emits a config value `has_TRAIT` if `probe_trait` returns true.
|
||||
///
|
||||
/// Any non-identifier characters in the trait `name` will be replaced with
|
||||
/// `_` in the generated config value.
|
||||
pub fn emit_has_trait(&self, name: &str) {
|
||||
if self.probe_trait(name) {
|
||||
emit(&format!("has_{}", mangle(name)));
|
||||
}
|
||||
}
|
||||
|
||||
/// Emits the given `cfg` value if `probe_trait` returns true.
|
||||
pub fn emit_trait_cfg(&self, name: &str, cfg: &str) {
|
||||
if self.probe_trait(name) {
|
||||
emit(cfg);
|
||||
}
|
||||
}
|
||||
|
||||
/// Tests whether the given type can be used.
|
||||
///
|
||||
/// The test code is subject to change, but currently looks like:
|
||||
///
|
||||
/// ```ignore
|
||||
/// pub type Probe = TYPE;
|
||||
/// ```
|
||||
pub fn probe_type(&self, name: &str) -> bool {
|
||||
self.probe(format!("pub type Probe = {};", name))
|
||||
.unwrap_or(false)
|
||||
}
|
||||
|
||||
/// Emits a config value `has_TYPE` if `probe_type` returns true.
|
||||
///
|
||||
/// Any non-identifier characters in the type `name` will be replaced with
|
||||
/// `_` in the generated config value.
|
||||
pub fn emit_has_type(&self, name: &str) {
|
||||
if self.probe_type(name) {
|
||||
emit(&format!("has_{}", mangle(name)));
|
||||
}
|
||||
}
|
||||
|
||||
/// Emits the given `cfg` value if `probe_type` returns true.
|
||||
pub fn emit_type_cfg(&self, name: &str, cfg: &str) {
|
||||
if self.probe_type(name) {
|
||||
emit(cfg);
|
||||
}
|
||||
}
|
||||
|
||||
/// Tests whether the given expression can be used.
|
||||
///
|
||||
/// The test code is subject to change, but currently looks like:
|
||||
///
|
||||
/// ```ignore
|
||||
/// pub fn probe() { let _ = EXPR; }
|
||||
/// ```
|
||||
pub fn probe_expression(&self, expr: &str) -> bool {
|
||||
self.probe(format!("pub fn probe() {{ let _ = {}; }}", expr))
|
||||
.unwrap_or(false)
|
||||
}
|
||||
|
||||
/// Emits the given `cfg` value if `probe_expression` returns true.
|
||||
pub fn emit_expression_cfg(&self, expr: &str, cfg: &str) {
|
||||
if self.probe_expression(expr) {
|
||||
emit(cfg);
|
||||
}
|
||||
}
|
||||
|
||||
/// Tests whether the given constant expression can be used.
|
||||
///
|
||||
/// The test code is subject to change, but currently looks like:
|
||||
///
|
||||
/// ```ignore
|
||||
/// pub const PROBE: () = ((), EXPR).0;
|
||||
/// ```
|
||||
pub fn probe_constant(&self, expr: &str) -> bool {
|
||||
self.probe(format!("pub const PROBE: () = ((), {}).0;", expr))
|
||||
.unwrap_or(false)
|
||||
}
|
||||
|
||||
/// Emits the given `cfg` value if `probe_constant` returns true.
|
||||
pub fn emit_constant_cfg(&self, expr: &str, cfg: &str) {
|
||||
if self.probe_constant(expr) {
|
||||
emit(cfg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn mangle(s: &str) -> String {
|
||||
s.chars()
|
||||
.map(|c| match c {
|
||||
'A'...'Z' | 'a'...'z' | '0'...'9' => c,
|
||||
_ => '_',
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
|
||||
fn dir_contains_target(
|
||||
target: &Option<OsString>,
|
||||
dir: &Path,
|
||||
cargo_target_dir: Option<OsString>,
|
||||
) -> bool {
|
||||
target
|
||||
.as_ref()
|
||||
.and_then(|target| {
|
||||
dir.to_str().and_then(|dir| {
|
||||
let mut cargo_target_dir = cargo_target_dir
|
||||
.map(PathBuf::from)
|
||||
.unwrap_or_else(|| PathBuf::from("target"));
|
||||
cargo_target_dir.push(target);
|
||||
|
||||
cargo_target_dir
|
||||
.to_str()
|
||||
.map(|cargo_target_dir| dir.contains(&cargo_target_dir))
|
||||
})
|
||||
})
|
||||
.unwrap_or(false)
|
||||
}
|
||||
|
||||
fn rustflags(target: &Option<OsString>, dir: &Path) -> Vec<String> {
|
||||
// Starting with rust-lang/cargo#9601, shipped in Rust 1.55, Cargo always sets
|
||||
// CARGO_ENCODED_RUSTFLAGS for any host/target build script invocation. This
|
||||
// includes any source of flags, whether from the environment, toml config, or
|
||||
// whatever may come in the future. The value is either an empty string, or a
|
||||
// list of arguments separated by the ASCII unit separator (US), 0x1f.
|
||||
if let Ok(a) = env::var("CARGO_ENCODED_RUSTFLAGS") {
|
||||
return if a.is_empty() {
|
||||
Vec::new()
|
||||
} else {
|
||||
a.split('\x1f').map(str::to_string).collect()
|
||||
};
|
||||
}
|
||||
|
||||
// Otherwise, we have to take a more heuristic approach, and we don't
|
||||
// support values from toml config at all.
|
||||
//
|
||||
// Cargo only applies RUSTFLAGS for building TARGET artifact in
|
||||
// cross-compilation environment. Sadly, we don't have a way to detect
|
||||
// when we're building HOST artifact in a cross-compilation environment,
|
||||
// so for now we only apply RUSTFLAGS when cross-compiling an artifact.
|
||||
//
|
||||
// See https://github.com/cuviper/autocfg/pull/10#issuecomment-527575030.
|
||||
if *target != env::var_os("HOST")
|
||||
|| dir_contains_target(target, dir, env::var_os("CARGO_TARGET_DIR"))
|
||||
{
|
||||
if let Ok(rustflags) = env::var("RUSTFLAGS") {
|
||||
// This is meant to match how cargo handles the RUSTFLAGS environment variable.
|
||||
// See https://github.com/rust-lang/cargo/blob/69aea5b6f69add7c51cca939a79644080c0b0ba0/src/cargo/core/compiler/build_context/target_info.rs#L434-L441
|
||||
return rustflags
|
||||
.split(' ')
|
||||
.map(str::trim)
|
||||
.filter(|s| !s.is_empty())
|
||||
.map(str::to_string)
|
||||
.collect();
|
||||
}
|
||||
}
|
||||
|
||||
Vec::new()
|
||||
}
|
174
vendor/autocfg/src/tests.rs
vendored
Normal file
174
vendor/autocfg/src/tests.rs
vendored
Normal file
@ -0,0 +1,174 @@
|
||||
use super::AutoCfg;
|
||||
use std::env;
|
||||
use std::path::Path;
|
||||
|
||||
impl AutoCfg {
|
||||
fn core_std(&self, path: &str) -> String {
|
||||
let krate = if self.no_std { "core" } else { "std" };
|
||||
format!("{}::{}", krate, path)
|
||||
}
|
||||
|
||||
fn assert_std(&self, probe_result: bool) {
|
||||
assert_eq!(!self.no_std, probe_result);
|
||||
}
|
||||
|
||||
fn assert_min(&self, major: usize, minor: usize, probe_result: bool) {
|
||||
assert_eq!(self.probe_rustc_version(major, minor), probe_result);
|
||||
}
|
||||
|
||||
fn for_test() -> Result<Self, super::error::Error> {
|
||||
match env::var_os("TESTS_TARGET_DIR") {
|
||||
Some(d) => Self::with_dir(d),
|
||||
None => Self::with_dir("target"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn autocfg_version() {
|
||||
let ac = AutoCfg::for_test().unwrap();
|
||||
println!("version: {:?}", ac.rustc_version);
|
||||
assert!(ac.probe_rustc_version(1, 0));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn version_cmp() {
|
||||
use super::version::Version;
|
||||
let v123 = Version::new(1, 2, 3);
|
||||
|
||||
assert!(Version::new(1, 0, 0) < v123);
|
||||
assert!(Version::new(1, 2, 2) < v123);
|
||||
assert!(Version::new(1, 2, 3) == v123);
|
||||
assert!(Version::new(1, 2, 4) > v123);
|
||||
assert!(Version::new(1, 10, 0) > v123);
|
||||
assert!(Version::new(2, 0, 0) > v123);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn probe_add() {
|
||||
let ac = AutoCfg::for_test().unwrap();
|
||||
let add = ac.core_std("ops::Add");
|
||||
let add_rhs = add.clone() + "<i32>";
|
||||
let add_rhs_output = add.clone() + "<i32, Output = i32>";
|
||||
let dyn_add_rhs_output = "dyn ".to_string() + &*add_rhs_output;
|
||||
assert!(ac.probe_path(&add));
|
||||
assert!(ac.probe_trait(&add));
|
||||
assert!(ac.probe_trait(&add_rhs));
|
||||
assert!(ac.probe_trait(&add_rhs_output));
|
||||
ac.assert_min(1, 27, ac.probe_type(&dyn_add_rhs_output));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn probe_as_ref() {
|
||||
let ac = AutoCfg::for_test().unwrap();
|
||||
let as_ref = ac.core_std("convert::AsRef");
|
||||
let as_ref_str = as_ref.clone() + "<str>";
|
||||
let dyn_as_ref_str = "dyn ".to_string() + &*as_ref_str;
|
||||
assert!(ac.probe_path(&as_ref));
|
||||
assert!(ac.probe_trait(&as_ref_str));
|
||||
assert!(ac.probe_type(&as_ref_str));
|
||||
ac.assert_min(1, 27, ac.probe_type(&dyn_as_ref_str));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn probe_i128() {
|
||||
let ac = AutoCfg::for_test().unwrap();
|
||||
let i128_path = ac.core_std("i128");
|
||||
ac.assert_min(1, 26, ac.probe_path(&i128_path));
|
||||
ac.assert_min(1, 26, ac.probe_type("i128"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn probe_sum() {
|
||||
let ac = AutoCfg::for_test().unwrap();
|
||||
let sum = ac.core_std("iter::Sum");
|
||||
let sum_i32 = sum.clone() + "<i32>";
|
||||
let dyn_sum_i32 = "dyn ".to_string() + &*sum_i32;
|
||||
ac.assert_min(1, 12, ac.probe_path(&sum));
|
||||
ac.assert_min(1, 12, ac.probe_trait(&sum));
|
||||
ac.assert_min(1, 12, ac.probe_trait(&sum_i32));
|
||||
ac.assert_min(1, 12, ac.probe_type(&sum_i32));
|
||||
ac.assert_min(1, 27, ac.probe_type(&dyn_sum_i32));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn probe_std() {
|
||||
let ac = AutoCfg::for_test().unwrap();
|
||||
ac.assert_std(ac.probe_sysroot_crate("std"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn probe_alloc() {
|
||||
let ac = AutoCfg::for_test().unwrap();
|
||||
ac.assert_min(1, 36, ac.probe_sysroot_crate("alloc"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn probe_bad_sysroot_crate() {
|
||||
let ac = AutoCfg::for_test().unwrap();
|
||||
assert!(!ac.probe_sysroot_crate("doesnt_exist"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn probe_no_std() {
|
||||
let ac = AutoCfg::for_test().unwrap();
|
||||
assert!(ac.probe_type("i32"));
|
||||
assert!(ac.probe_type("[i32]"));
|
||||
ac.assert_std(ac.probe_type("Vec<i32>"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn probe_expression() {
|
||||
let ac = AutoCfg::for_test().unwrap();
|
||||
assert!(ac.probe_expression(r#""test".trim_left()"#));
|
||||
ac.assert_min(1, 30, ac.probe_expression(r#""test".trim_start()"#));
|
||||
ac.assert_std(ac.probe_expression("[1, 2, 3].to_vec()"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn probe_constant() {
|
||||
let ac = AutoCfg::for_test().unwrap();
|
||||
assert!(ac.probe_constant("1 + 2 + 3"));
|
||||
ac.assert_min(1, 33, ac.probe_constant("{ let x = 1 + 2 + 3; x * x }"));
|
||||
ac.assert_min(1, 39, ac.probe_constant(r#""test".len()"#));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn dir_does_not_contain_target() {
|
||||
assert!(!super::dir_contains_target(
|
||||
&Some("x86_64-unknown-linux-gnu".into()),
|
||||
Path::new("/project/target/debug/build/project-ea75983148559682/out"),
|
||||
None,
|
||||
));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn dir_does_contain_target() {
|
||||
assert!(super::dir_contains_target(
|
||||
&Some("x86_64-unknown-linux-gnu".into()),
|
||||
Path::new(
|
||||
"/project/target/x86_64-unknown-linux-gnu/debug/build/project-0147aca016480b9d/out"
|
||||
),
|
||||
None,
|
||||
));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn dir_does_not_contain_target_with_custom_target_dir() {
|
||||
assert!(!super::dir_contains_target(
|
||||
&Some("x86_64-unknown-linux-gnu".into()),
|
||||
Path::new("/project/custom/debug/build/project-ea75983148559682/out"),
|
||||
Some("custom".into()),
|
||||
));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn dir_does_contain_target_with_custom_target_dir() {
|
||||
assert!(super::dir_contains_target(
|
||||
&Some("x86_64-unknown-linux-gnu".into()),
|
||||
Path::new(
|
||||
"/project/custom/x86_64-unknown-linux-gnu/debug/build/project-0147aca016480b9d/out"
|
||||
),
|
||||
Some("custom".into()),
|
||||
));
|
||||
}
|
60
vendor/autocfg/src/version.rs
vendored
Normal file
60
vendor/autocfg/src/version.rs
vendored
Normal file
@ -0,0 +1,60 @@
|
||||
use std::path::Path;
|
||||
use std::process::Command;
|
||||
use std::str;
|
||||
|
||||
use super::{error, Error};
|
||||
|
||||
/// A version structure for making relative comparisons.
|
||||
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
|
||||
pub struct Version {
|
||||
major: usize,
|
||||
minor: usize,
|
||||
patch: usize,
|
||||
}
|
||||
|
||||
impl Version {
|
||||
/// Creates a `Version` instance for a specific `major.minor.patch` version.
|
||||
pub fn new(major: usize, minor: usize, patch: usize) -> Self {
|
||||
Version {
|
||||
major: major,
|
||||
minor: minor,
|
||||
patch: patch,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn from_rustc(rustc: &Path) -> Result<Self, Error> {
|
||||
// Get rustc's verbose version
|
||||
let output = try!(Command::new(rustc)
|
||||
.args(&["--version", "--verbose"])
|
||||
.output()
|
||||
.map_err(error::from_io));
|
||||
if !output.status.success() {
|
||||
return Err(error::from_str("could not execute rustc"));
|
||||
}
|
||||
let output = try!(str::from_utf8(&output.stdout).map_err(error::from_utf8));
|
||||
|
||||
// Find the release line in the verbose version output.
|
||||
let release = match output.lines().find(|line| line.starts_with("release: ")) {
|
||||
Some(line) => &line["release: ".len()..],
|
||||
None => return Err(error::from_str("could not find rustc release")),
|
||||
};
|
||||
|
||||
// Strip off any extra channel info, e.g. "-beta.N", "-nightly"
|
||||
let version = match release.find('-') {
|
||||
Some(i) => &release[..i],
|
||||
None => release,
|
||||
};
|
||||
|
||||
// Split the version into semver components.
|
||||
let mut iter = version.splitn(3, '.');
|
||||
let major = try!(iter.next().ok_or(error::from_str("missing major version")));
|
||||
let minor = try!(iter.next().ok_or(error::from_str("missing minor version")));
|
||||
let patch = try!(iter.next().ok_or(error::from_str("missing patch version")));
|
||||
|
||||
Ok(Version::new(
|
||||
try!(major.parse().map_err(error::from_num)),
|
||||
try!(minor.parse().map_err(error::from_num)),
|
||||
try!(patch.parse().map_err(error::from_num)),
|
||||
))
|
||||
}
|
||||
}
|
33
vendor/autocfg/tests/rustflags.rs
vendored
Normal file
33
vendor/autocfg/tests/rustflags.rs
vendored
Normal file
@ -0,0 +1,33 @@
|
||||
extern crate autocfg;
|
||||
|
||||
use std::env;
|
||||
|
||||
/// Tests that autocfg uses the RUSTFLAGS or CARGO_ENCODED_RUSTFLAGS
|
||||
/// environment variables when running rustc.
|
||||
#[test]
|
||||
fn test_with_sysroot() {
|
||||
// Use the same path as this test binary.
|
||||
let dir = env::current_exe().unwrap().parent().unwrap().to_path_buf();
|
||||
env::set_var("OUT_DIR", &format!("{}", dir.display()));
|
||||
|
||||
// If we have encoded rustflags, they take precedence, even if empty.
|
||||
env::set_var("CARGO_ENCODED_RUSTFLAGS", "");
|
||||
env::set_var("RUSTFLAGS", &format!("-L {}", dir.display()));
|
||||
let ac = autocfg::AutoCfg::new().unwrap();
|
||||
assert!(ac.probe_sysroot_crate("std"));
|
||||
assert!(!ac.probe_sysroot_crate("autocfg"));
|
||||
|
||||
// Now try again with useful encoded args.
|
||||
env::set_var(
|
||||
"CARGO_ENCODED_RUSTFLAGS",
|
||||
&format!("-L\x1f{}", dir.display()),
|
||||
);
|
||||
let ac = autocfg::AutoCfg::new().unwrap();
|
||||
assert!(ac.probe_sysroot_crate("autocfg"));
|
||||
|
||||
// Try the old-style RUSTFLAGS, ensuring HOST != TARGET.
|
||||
env::remove_var("CARGO_ENCODED_RUSTFLAGS");
|
||||
env::set_var("HOST", "lol");
|
||||
let ac = autocfg::AutoCfg::new().unwrap();
|
||||
assert!(ac.probe_sysroot_crate("autocfg"));
|
||||
}
|
1
vendor/bitflags/.cargo-checksum.json
vendored
Normal file
1
vendor/bitflags/.cargo-checksum.json
vendored
Normal file
@ -0,0 +1 @@
|
||||
{"files":{"CHANGELOG.md":"d362fc1fccaaf4d421bcf0fe8b80ddb4f625dade0c1ee52d08bd0b95509a49d1","CODE_OF_CONDUCT.md":"42634d0f6d922f49857175af991802822f7f920487aefa2ee250a50d12251a66","Cargo.toml":"87aced7532a7974eb37ab5fe6037f0abafc36d6b2d74891ecd2bf2f14f50d11e","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"6485b8ed310d3f0340bf1ad1f47645069ce4069dcc6bb46c7d5c6faf41de1fdb","README.md":"baa8604f8afb34fd93b9c79729daafb884dedcaf34023e4af8ad037d916061fd","src/example_generated.rs":"e43eb59e90f317f38d436670a6067d2fd9eb35fb319fe716184e4a04e24ed1b2","src/lib.rs":"e6477688535ee326d27238aeedc9cb4320ac35b9d17a4deda09e0587b0ccdbd4","tests/basic.rs":"146f1cbf6279bc609242cd3349f29cb21b41294f5e4921875f5ec95bd83529a2","tests/compile-fail/impls/copy.rs":"b791371237ddc75a7c04d2130e03b462c9c00a80dca08bd45aa97433d9c0d13a","tests/compile-fail/impls/copy.stderr.beta":"77d83484ce221d4b6ff2f7de843929a452d779fcfff428122710dd8218c298e3","tests/compile-fail/impls/eq.rs":"0cee8b9e07d537890e0189710293b53972d0fab63c09366f33c391065afafa99","tests/compile-fail/impls/eq.stderr.beta":"381fc6143d45ce76d7cecc47aa59cb69fe5e79c0b60a4a85d5c6163b400b3cc7","tests/compile-fail/non_integer_base/all_defined.rs":"95e14cad9e94560262f2862c3c01865ac30369b69da1001b0e7285cb55e6cb75","tests/compile-fail/non_integer_base/all_defined.stderr.beta":"1760739a276690903bb03844025587d37939f5dfcbfab309db3c86f32bdbf748","tests/compile-fail/non_integer_base/all_missing.rs":"b3d9da619d23213731ba2581aa7999c796c3c79aaf4f0ee6b11ceec08a11537f","tests/compile-fail/non_integer_base/all_missing.stderr.beta":"37e102290d3867e175b21976be798939f294efb17580d5b51e7b17b590d55132","tests/compile-fail/visibility/private_field.rs":"38e4d3fe6471829360d12c8d09b097f6a21aa93fb51eac3b215d96bdae23316b","tests/compile-fail/visibility/private_field.stderr.beta":"5aa24a3ebb39326f31927721c5017b8beb66c3e501fb865a3fa814c9763bfa0f","tests/compile-fail/visibility/private_flags.rs":"2ce4235802aa4e9c96c4e77d9e31d8401ef58dcda4741325184f0764ab1fe393","tests/compile-fail/visibility/private_flags.stderr.beta":"f3eb9f7baf2689258f3519ff7ee5c6ec3c237264ebcfe63f40c40f2023e5022f","tests/compile-fail/visibility/pub_const.rs":"8f813a97ac518c5ea8ac65b184101912452384afaf7b8d6c5e62f8370eca3c0a","tests/compile-fail/visibility/pub_const.stderr.beta":"823976ae1794d7f5372e2ec9aabba497e7bb88004722904c38da342ed98e8962","tests/compile-pass/impls/convert.rs":"88fe80bfb9cd5779f0e1d92c9ec02a8b6bb67e334c07f2309e9c0ba5ef776eb0","tests/compile-pass/impls/default.rs":"c508f9a461691f44b45142fa5ad599f02326e1de4c0cbca6c0593f4652eba109","tests/compile-pass/impls/inherent_methods.rs":"ecc26388e9a394bfa7a5bb69a5d621ab3d4d1e53f28f657bb8e78fe79f437913","tests/compile-pass/redefinition/core.rs":"ff5b6e72f87acc6ebb12405d3c0f6e3fa62e669933656a454bb63b30ea44179c","tests/compile-pass/redefinition/stringify.rs":"1edbce42b900c14425d7ffa14e83e165ebe452d7dccd8c0a8a821bdec64f5c93","tests/compile-pass/repr/c.rs":"6fda17f7c2edfcd155314579e83d0fc8a16209e400f1f9a5ca77bd9a799041f2","tests/compile-pass/repr/transparent.rs":"6cdc87a2137d8a4e0c8ce9b6cba83c82255f8ea125951bf614418685600489ce","tests/compile-pass/visibility/bits_field.rs":"1f3e5ba5a047440066a9f6bf7b7af33f5b06f6b1da3dd9af6886168199a7ea0a","tests/compile-pass/visibility/pub_in.rs":"e95312ff60966d42ec4bc00225507895a9b8ec24056ce6a9edd9145be35d730f","tests/compile.rs":"f27c67a7dd183ca30efea1b6e0880e3469a6dd63b92b1fd711c082df182c9eec"},"package":"bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"}
|
206
vendor/bitflags/CHANGELOG.md
vendored
Normal file
206
vendor/bitflags/CHANGELOG.md
vendored
Normal file
@ -0,0 +1,206 @@
|
||||
# 1.3.2
|
||||
|
||||
- Allow `non_snake_case` in generated flags types ([#256])
|
||||
|
||||
[#252]: https://github.com/bitflags/bitflags/pull/256
|
||||
|
||||
# 1.3.1
|
||||
|
||||
- Revert unconditional `#[repr(transparent)]` ([#252])
|
||||
|
||||
[#252]: https://github.com/bitflags/bitflags/pull/252
|
||||
|
||||
# 1.3.0 (yanked)
|
||||
|
||||
- Add `#[repr(transparent)]` ([#187])
|
||||
|
||||
- End `empty` doc comment with full stop ([#202])
|
||||
|
||||
- Fix typo in crate root docs ([#206])
|
||||
|
||||
- Document from_bits_unchecked unsafety ([#207])
|
||||
|
||||
- Let `is_all` ignore extra bits ([#211])
|
||||
|
||||
- Allows empty flag definition ([#225])
|
||||
|
||||
- Making crate accessible from std ([#227])
|
||||
|
||||
- Make `from_bits` a const fn ([#229])
|
||||
|
||||
- Allow multiple bitflags structs in one macro invocation ([#235])
|
||||
|
||||
- Add named functions to perform set operations ([#244])
|
||||
|
||||
- Fix typos in method docs ([#245])
|
||||
|
||||
- Modernization of the `bitflags` macro to take advantage of newer features and 2018 idioms ([#246])
|
||||
|
||||
- Fix regression (in an unreleased feature) and simplify tests ([#247])
|
||||
|
||||
- Use `Self` and fix bug when overriding `stringify!` ([#249])
|
||||
|
||||
[#187]: https://github.com/bitflags/bitflags/pull/187
|
||||
[#202]: https://github.com/bitflags/bitflags/pull/202
|
||||
[#206]: https://github.com/bitflags/bitflags/pull/206
|
||||
[#207]: https://github.com/bitflags/bitflags/pull/207
|
||||
[#211]: https://github.com/bitflags/bitflags/pull/211
|
||||
[#225]: https://github.com/bitflags/bitflags/pull/225
|
||||
[#227]: https://github.com/bitflags/bitflags/pull/227
|
||||
[#229]: https://github.com/bitflags/bitflags/pull/229
|
||||
[#235]: https://github.com/bitflags/bitflags/pull/235
|
||||
[#244]: https://github.com/bitflags/bitflags/pull/244
|
||||
[#245]: https://github.com/bitflags/bitflags/pull/245
|
||||
[#246]: https://github.com/bitflags/bitflags/pull/246
|
||||
[#247]: https://github.com/bitflags/bitflags/pull/247
|
||||
[#249]: https://github.com/bitflags/bitflags/pull/249
|
||||
|
||||
# 1.2.1
|
||||
|
||||
- Remove extraneous `#[inline]` attributes ([#194])
|
||||
|
||||
[#194]: https://github.com/bitflags/bitflags/pull/194
|
||||
|
||||
# 1.2.0
|
||||
|
||||
- Fix typo: {Lower, Upper}Exp - {Lower, Upper}Hex ([#183])
|
||||
|
||||
- Add support for "unknown" bits ([#188])
|
||||
|
||||
[#183]: https://github.com/rust-lang-nursery/bitflags/pull/183
|
||||
[#188]: https://github.com/rust-lang-nursery/bitflags/pull/188
|
||||
|
||||
# 1.1.0
|
||||
|
||||
This is a re-release of `1.0.5`, which was yanked due to a bug in the RLS.
|
||||
|
||||
# 1.0.5
|
||||
|
||||
- Use compiletest_rs flags supported by stable toolchain ([#171])
|
||||
|
||||
- Put the user provided attributes first ([#173])
|
||||
|
||||
- Make bitflags methods `const` on newer compilers ([#175])
|
||||
|
||||
[#171]: https://github.com/rust-lang-nursery/bitflags/pull/171
|
||||
[#173]: https://github.com/rust-lang-nursery/bitflags/pull/173
|
||||
[#175]: https://github.com/rust-lang-nursery/bitflags/pull/175
|
||||
|
||||
# 1.0.4
|
||||
|
||||
- Support Rust 2018 style macro imports ([#165])
|
||||
|
||||
```rust
|
||||
use bitflags::bitflags;
|
||||
```
|
||||
|
||||
[#165]: https://github.com/rust-lang-nursery/bitflags/pull/165
|
||||
|
||||
# 1.0.3
|
||||
|
||||
- Improve zero value flag handling and documentation ([#157])
|
||||
|
||||
[#157]: https://github.com/rust-lang-nursery/bitflags/pull/157
|
||||
|
||||
# 1.0.2
|
||||
|
||||
- 30% improvement in compile time of bitflags crate ([#156])
|
||||
|
||||
- Documentation improvements ([#153])
|
||||
|
||||
- Implementation cleanup ([#149])
|
||||
|
||||
[#156]: https://github.com/rust-lang-nursery/bitflags/pull/156
|
||||
[#153]: https://github.com/rust-lang-nursery/bitflags/pull/153
|
||||
[#149]: https://github.com/rust-lang-nursery/bitflags/pull/149
|
||||
|
||||
# 1.0.1
|
||||
- Add support for `pub(restricted)` specifier on the bitflags struct ([#135])
|
||||
- Optimize performance of `all()` when called from a separate crate ([#136])
|
||||
|
||||
[#135]: https://github.com/rust-lang-nursery/bitflags/pull/135
|
||||
[#136]: https://github.com/rust-lang-nursery/bitflags/pull/136
|
||||
|
||||
# 1.0.0
|
||||
- **[breaking change]** Macro now generates [associated constants](https://doc.rust-lang.org/reference/items.html#associated-constants) ([#24])
|
||||
|
||||
- **[breaking change]** Minimum supported version is Rust **1.20**, due to usage of associated constants
|
||||
|
||||
- After being broken in 0.9, the `#[deprecated]` attribute is now supported again ([#112])
|
||||
|
||||
- Other improvements to unit tests and documentation ([#106] and [#115])
|
||||
|
||||
[#24]: https://github.com/rust-lang-nursery/bitflags/pull/24
|
||||
[#106]: https://github.com/rust-lang-nursery/bitflags/pull/106
|
||||
[#112]: https://github.com/rust-lang-nursery/bitflags/pull/112
|
||||
[#115]: https://github.com/rust-lang-nursery/bitflags/pull/115
|
||||
|
||||
## How to update your code to use associated constants
|
||||
Assuming the following structure definition:
|
||||
```rust
|
||||
bitflags! {
|
||||
struct Something: u8 {
|
||||
const FOO = 0b01,
|
||||
const BAR = 0b10
|
||||
}
|
||||
}
|
||||
```
|
||||
In 0.9 and older you could do:
|
||||
```rust
|
||||
let x = FOO.bits | BAR.bits;
|
||||
```
|
||||
Now you must use:
|
||||
```rust
|
||||
let x = Something::FOO.bits | Something::BAR.bits;
|
||||
```
|
||||
|
||||
# 0.9.1
|
||||
- Fix the implementation of `Formatting` traits when other formatting traits were present in scope ([#105])
|
||||
|
||||
[#105]: https://github.com/rust-lang-nursery/bitflags/pull/105
|
||||
|
||||
# 0.9.0
|
||||
- **[breaking change]** Use struct keyword instead of flags to define bitflag types ([#84])
|
||||
|
||||
- **[breaking change]** Terminate const items with semicolons instead of commas ([#87])
|
||||
|
||||
- Implement the `Hex`, `Octal`, and `Binary` formatting traits ([#86])
|
||||
|
||||
- Printing an empty flag value with the `Debug` trait now prints "(empty)" instead of nothing ([#85])
|
||||
|
||||
- The `bitflags!` macro can now be used inside of a fn body, to define a type local to that function ([#74])
|
||||
|
||||
[#74]: https://github.com/rust-lang-nursery/bitflags/pull/74
|
||||
[#84]: https://github.com/rust-lang-nursery/bitflags/pull/84
|
||||
[#85]: https://github.com/rust-lang-nursery/bitflags/pull/85
|
||||
[#86]: https://github.com/rust-lang-nursery/bitflags/pull/86
|
||||
[#87]: https://github.com/rust-lang-nursery/bitflags/pull/87
|
||||
|
||||
# 0.8.2
|
||||
- Update feature flag used when building bitflags as a dependency of the Rust toolchain
|
||||
|
||||
# 0.8.1
|
||||
- Allow bitflags to be used as a dependency of the Rust toolchain
|
||||
|
||||
# 0.8.0
|
||||
- Add support for the experimental `i128` and `u128` integer types ([#57])
|
||||
- Add set method: `flags.set(SOME_FLAG, true)` or `flags.set(SOME_FLAG, false)` ([#55])
|
||||
This may break code that defines its own set method
|
||||
|
||||
[#55]: https://github.com/rust-lang-nursery/bitflags/pull/55
|
||||
[#57]: https://github.com/rust-lang-nursery/bitflags/pull/57
|
||||
|
||||
# 0.7.1
|
||||
*(yanked)*
|
||||
|
||||
# 0.7.0
|
||||
- Implement the Extend trait ([#49])
|
||||
- Allow definitions inside the `bitflags!` macro to refer to items imported from other modules ([#51])
|
||||
|
||||
[#49]: https://github.com/rust-lang-nursery/bitflags/pull/49
|
||||
[#51]: https://github.com/rust-lang-nursery/bitflags/pull/51
|
||||
|
||||
# 0.6.0
|
||||
- The `no_std` feature was removed as it is now the default
|
||||
- The `assignment_operators` feature was remove as it is now enabled by default
|
||||
- Some clippy suggestions have been applied
|
73
vendor/bitflags/CODE_OF_CONDUCT.md
vendored
Normal file
73
vendor/bitflags/CODE_OF_CONDUCT.md
vendored
Normal file
@ -0,0 +1,73 @@
|
||||
# Contributor Covenant Code of Conduct
|
||||
|
||||
## Our Pledge
|
||||
|
||||
In the interest of fostering an open and welcoming environment, we as
|
||||
contributors and maintainers pledge to making participation in our project and
|
||||
our community a harassment-free experience for everyone, regardless of age, body
|
||||
size, disability, ethnicity, gender identity and expression, level of experience,
|
||||
education, socio-economic status, nationality, personal appearance, race,
|
||||
religion, or sexual identity and orientation.
|
||||
|
||||
## Our Standards
|
||||
|
||||
Examples of behavior that contributes to creating a positive environment
|
||||
include:
|
||||
|
||||
* Using welcoming and inclusive language
|
||||
* Being respectful of differing viewpoints and experiences
|
||||
* Gracefully accepting constructive criticism
|
||||
* Focusing on what is best for the community
|
||||
* Showing empathy towards other community members
|
||||
|
||||
Examples of unacceptable behavior by participants include:
|
||||
|
||||
* The use of sexualized language or imagery and unwelcome sexual attention or
|
||||
advances
|
||||
* Trolling, insulting/derogatory comments, and personal or political attacks
|
||||
* Public or private harassment
|
||||
* Publishing others' private information, such as a physical or electronic
|
||||
address, without explicit permission
|
||||
* Other conduct which could reasonably be considered inappropriate in a
|
||||
professional setting
|
||||
|
||||
## Our Responsibilities
|
||||
|
||||
Project maintainers are responsible for clarifying the standards of acceptable
|
||||
behavior and are expected to take appropriate and fair corrective action in
|
||||
response to any instances of unacceptable behavior.
|
||||
|
||||
Project maintainers have the right and responsibility to remove, edit, or
|
||||
reject comments, commits, code, wiki edits, issues, and other contributions
|
||||
that are not aligned to this Code of Conduct, or to ban temporarily or
|
||||
permanently any contributor for other behaviors that they deem inappropriate,
|
||||
threatening, offensive, or harmful.
|
||||
|
||||
## Scope
|
||||
|
||||
This Code of Conduct applies both within project spaces and in public spaces
|
||||
when an individual is representing the project or its community. Examples of
|
||||
representing a project or community include using an official project e-mail
|
||||
address, posting via an official social media account, or acting as an appointed
|
||||
representative at an online or offline event. Representation of a project may be
|
||||
further defined and clarified by project maintainers.
|
||||
|
||||
## Enforcement
|
||||
|
||||
Instances of abusive, harassing, or otherwise unacceptable behavior may be
|
||||
reported by contacting the project team at coc@senaite.org. All
|
||||
complaints will be reviewed and investigated and will result in a response that
|
||||
is deemed necessary and appropriate to the circumstances. The project team is
|
||||
obligated to maintain confidentiality with regard to the reporter of an incident.
|
||||
Further details of specific enforcement policies may be posted separately.
|
||||
|
||||
Project maintainers who do not follow or enforce the Code of Conduct in good
|
||||
faith may face temporary or permanent repercussions as determined by other
|
||||
members of the project's leadership.
|
||||
|
||||
## Attribution
|
||||
|
||||
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
|
||||
available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html
|
||||
|
||||
[homepage]: https://www.contributor-covenant.org
|
58
vendor/bitflags/Cargo.toml
vendored
Normal file
58
vendor/bitflags/Cargo.toml
vendored
Normal file
@ -0,0 +1,58 @@
|
||||
# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO
|
||||
#
|
||||
# When uploading crates to the registry Cargo will automatically
|
||||
# "normalize" Cargo.toml files for maximal compatibility
|
||||
# with all versions of Cargo and also rewrite `path` dependencies
|
||||
# to registry (e.g., crates.io) dependencies
|
||||
#
|
||||
# If you believe there's an error in this file please file an
|
||||
# issue against the rust-lang/cargo repository. If you're
|
||||
# editing this file be aware that the upstream Cargo.toml
|
||||
# will likely look very different (and much more reasonable)
|
||||
|
||||
[package]
|
||||
edition = "2018"
|
||||
name = "bitflags"
|
||||
version = "1.3.2"
|
||||
authors = ["The Rust Project Developers"]
|
||||
exclude = ["bors.toml"]
|
||||
description = "A macro to generate structures which behave like bitflags.\n"
|
||||
homepage = "https://github.com/bitflags/bitflags"
|
||||
documentation = "https://docs.rs/bitflags"
|
||||
readme = "README.md"
|
||||
keywords = ["bit", "bitmask", "bitflags", "flags"]
|
||||
categories = ["no-std"]
|
||||
license = "MIT/Apache-2.0"
|
||||
repository = "https://github.com/bitflags/bitflags"
|
||||
[package.metadata.docs.rs]
|
||||
features = ["example_generated"]
|
||||
[dependencies.compiler_builtins]
|
||||
version = "0.1.2"
|
||||
optional = true
|
||||
|
||||
[dependencies.core]
|
||||
version = "1.0.0"
|
||||
optional = true
|
||||
package = "rustc-std-workspace-core"
|
||||
[dev-dependencies.rustversion]
|
||||
version = "1.0"
|
||||
|
||||
[dev-dependencies.serde]
|
||||
version = "1.0"
|
||||
|
||||
[dev-dependencies.serde_derive]
|
||||
version = "1.0"
|
||||
|
||||
[dev-dependencies.serde_json]
|
||||
version = "1.0"
|
||||
|
||||
[dev-dependencies.trybuild]
|
||||
version = "1.0"
|
||||
|
||||
[dev-dependencies.walkdir]
|
||||
version = "2.3"
|
||||
|
||||
[features]
|
||||
default = []
|
||||
example_generated = []
|
||||
rustc-dep-of-std = ["core", "compiler_builtins"]
|
201
vendor/bitflags/LICENSE-APACHE
vendored
Normal file
201
vendor/bitflags/LICENSE-APACHE
vendored
Normal file
@ -0,0 +1,201 @@
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
25
vendor/bitflags/LICENSE-MIT
vendored
Normal file
25
vendor/bitflags/LICENSE-MIT
vendored
Normal file
@ -0,0 +1,25 @@
|
||||
Copyright (c) 2014 The Rust Project Developers
|
||||
|
||||
Permission is hereby granted, free of charge, to any
|
||||
person obtaining a copy of this software and associated
|
||||
documentation files (the "Software"), to deal in the
|
||||
Software without restriction, including without
|
||||
limitation the rights to use, copy, modify, merge,
|
||||
publish, distribute, sublicense, and/or sell copies of
|
||||
the Software, and to permit persons to whom the Software
|
||||
is furnished to do so, subject to the following
|
||||
conditions:
|
||||
|
||||
The above copyright notice and this permission notice
|
||||
shall be included in all copies or substantial portions
|
||||
of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
|
||||
ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
|
||||
TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
|
||||
PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
|
||||
SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
|
||||
IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
DEALINGS IN THE SOFTWARE.
|
32
vendor/bitflags/README.md
vendored
Normal file
32
vendor/bitflags/README.md
vendored
Normal file
@ -0,0 +1,32 @@
|
||||
bitflags
|
||||
========
|
||||
|
||||
[![Rust](https://github.com/bitflags/bitflags/workflows/Rust/badge.svg)](https://github.com/bitflags/bitflags/actions)
|
||||
[![Join the chat at https://gitter.im/bitflags/Lobby](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/bitflags/Lobby?utm_source=badge&utm_medium=badge&utm_content=badge)
|
||||
[![Latest version](https://img.shields.io/crates/v/bitflags.svg)](https://crates.io/crates/bitflags)
|
||||
[![Documentation](https://docs.rs/bitflags/badge.svg)](https://docs.rs/bitflags)
|
||||
![License](https://img.shields.io/crates/l/bitflags.svg)
|
||||
|
||||
A Rust macro to generate structures which behave like a set of bitflags
|
||||
|
||||
- [Documentation](https://docs.rs/bitflags)
|
||||
- [Release notes](https://github.com/bitflags/bitflags/releases)
|
||||
|
||||
## Usage
|
||||
|
||||
Add this to your `Cargo.toml`:
|
||||
|
||||
```toml
|
||||
[dependencies]
|
||||
bitflags = "1.3"
|
||||
```
|
||||
|
||||
and this to your source code:
|
||||
|
||||
```rust
|
||||
use bitflags::bitflags;
|
||||
```
|
||||
|
||||
## Rust Version Support
|
||||
|
||||
The minimum supported Rust version is 1.46 due to use of associated constants and const functions.
|
14
vendor/bitflags/src/example_generated.rs
vendored
Normal file
14
vendor/bitflags/src/example_generated.rs
vendored
Normal file
@ -0,0 +1,14 @@
|
||||
//! This module shows an example of code generated by the macro. **IT MUST NOT BE USED OUTSIDE THIS
|
||||
//! CRATE**.
|
||||
|
||||
bitflags! {
|
||||
/// This is the same `Flags` struct defined in the [crate level example](../index.html#example).
|
||||
/// Note that this struct is just for documentation purposes only, it must not be used outside
|
||||
/// this crate.
|
||||
pub struct Flags: u32 {
|
||||
const A = 0b00000001;
|
||||
const B = 0b00000010;
|
||||
const C = 0b00000100;
|
||||
const ABC = Self::A.bits | Self::B.bits | Self::C.bits;
|
||||
}
|
||||
}
|
1729
vendor/bitflags/src/lib.rs
vendored
Normal file
1729
vendor/bitflags/src/lib.rs
vendored
Normal file
File diff suppressed because it is too large
Load Diff
20
vendor/bitflags/tests/basic.rs
vendored
Normal file
20
vendor/bitflags/tests/basic.rs
vendored
Normal file
@ -0,0 +1,20 @@
|
||||
#![no_std]
|
||||
|
||||
use bitflags::bitflags;
|
||||
|
||||
bitflags! {
|
||||
/// baz
|
||||
struct Flags: u32 {
|
||||
const A = 0b00000001;
|
||||
#[doc = "bar"]
|
||||
const B = 0b00000010;
|
||||
const C = 0b00000100;
|
||||
#[doc = "foo"]
|
||||
const ABC = Flags::A.bits | Flags::B.bits | Flags::C.bits;
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn basic() {
|
||||
assert_eq!(Flags::ABC, Flags::A | Flags::B | Flags::C);
|
||||
}
|
10
vendor/bitflags/tests/compile-fail/impls/copy.rs
vendored
Normal file
10
vendor/bitflags/tests/compile-fail/impls/copy.rs
vendored
Normal file
@ -0,0 +1,10 @@
|
||||
use bitflags::bitflags;
|
||||
|
||||
bitflags! {
|
||||
#[derive(Clone, Copy)]
|
||||
struct Flags: u32 {
|
||||
const A = 0b00000001;
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {}
|
27
vendor/bitflags/tests/compile-fail/impls/copy.stderr.beta
vendored
Normal file
27
vendor/bitflags/tests/compile-fail/impls/copy.stderr.beta
vendored
Normal file
@ -0,0 +1,27 @@
|
||||
error[E0119]: conflicting implementations of trait `std::clone::Clone` for type `Flags`
|
||||
--> $DIR/copy.rs:3:1
|
||||
|
|
||||
3 | / bitflags! {
|
||||
4 | | #[derive(Clone, Copy)]
|
||||
| | ----- first implementation here
|
||||
5 | | struct Flags: u32 {
|
||||
6 | | const A = 0b00000001;
|
||||
7 | | }
|
||||
8 | | }
|
||||
| |_^ conflicting implementation for `Flags`
|
||||
|
|
||||
= note: this error originates in the derive macro `Clone` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error[E0119]: conflicting implementations of trait `std::marker::Copy` for type `Flags`
|
||||
--> $DIR/copy.rs:3:1
|
||||
|
|
||||
3 | / bitflags! {
|
||||
4 | | #[derive(Clone, Copy)]
|
||||
| | ---- first implementation here
|
||||
5 | | struct Flags: u32 {
|
||||
6 | | const A = 0b00000001;
|
||||
7 | | }
|
||||
8 | | }
|
||||
| |_^ conflicting implementation for `Flags`
|
||||
|
|
||||
= note: this error originates in the derive macro `Copy` (in Nightly builds, run with -Z macro-backtrace for more info)
|
10
vendor/bitflags/tests/compile-fail/impls/eq.rs
vendored
Normal file
10
vendor/bitflags/tests/compile-fail/impls/eq.rs
vendored
Normal file
@ -0,0 +1,10 @@
|
||||
use bitflags::bitflags;
|
||||
|
||||
bitflags! {
|
||||
#[derive(PartialEq, Eq)]
|
||||
struct Flags: u32 {
|
||||
const A = 0b00000001;
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {}
|
55
vendor/bitflags/tests/compile-fail/impls/eq.stderr.beta
vendored
Normal file
55
vendor/bitflags/tests/compile-fail/impls/eq.stderr.beta
vendored
Normal file
@ -0,0 +1,55 @@
|
||||
error[E0119]: conflicting implementations of trait `std::cmp::PartialEq` for type `Flags`
|
||||
--> $DIR/eq.rs:3:1
|
||||
|
|
||||
3 | / bitflags! {
|
||||
4 | | #[derive(PartialEq, Eq)]
|
||||
| | --------- first implementation here
|
||||
5 | | struct Flags: u32 {
|
||||
6 | | const A = 0b00000001;
|
||||
7 | | }
|
||||
8 | | }
|
||||
| |_^ conflicting implementation for `Flags`
|
||||
|
|
||||
= note: this error originates in the derive macro `PartialEq` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error[E0119]: conflicting implementations of trait `std::cmp::Eq` for type `Flags`
|
||||
--> $DIR/eq.rs:3:1
|
||||
|
|
||||
3 | / bitflags! {
|
||||
4 | | #[derive(PartialEq, Eq)]
|
||||
| | -- first implementation here
|
||||
5 | | struct Flags: u32 {
|
||||
6 | | const A = 0b00000001;
|
||||
7 | | }
|
||||
8 | | }
|
||||
| |_^ conflicting implementation for `Flags`
|
||||
|
|
||||
= note: this error originates in the derive macro `Eq` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error[E0119]: conflicting implementations of trait `std::marker::StructuralPartialEq` for type `Flags`
|
||||
--> $DIR/eq.rs:3:1
|
||||
|
|
||||
3 | / bitflags! {
|
||||
4 | | #[derive(PartialEq, Eq)]
|
||||
| | --------- first implementation here
|
||||
5 | | struct Flags: u32 {
|
||||
6 | | const A = 0b00000001;
|
||||
7 | | }
|
||||
8 | | }
|
||||
| |_^ conflicting implementation for `Flags`
|
||||
|
|
||||
= note: this error originates in the derive macro `PartialEq` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error[E0119]: conflicting implementations of trait `std::marker::StructuralEq` for type `Flags`
|
||||
--> $DIR/eq.rs:3:1
|
||||
|
|
||||
3 | / bitflags! {
|
||||
4 | | #[derive(PartialEq, Eq)]
|
||||
| | -- first implementation here
|
||||
5 | | struct Flags: u32 {
|
||||
6 | | const A = 0b00000001;
|
||||
7 | | }
|
||||
8 | | }
|
||||
| |_^ conflicting implementation for `Flags`
|
||||
|
|
||||
= note: this error originates in the derive macro `Eq` (in Nightly builds, run with -Z macro-backtrace for more info)
|
123
vendor/bitflags/tests/compile-fail/non_integer_base/all_defined.rs
vendored
Normal file
123
vendor/bitflags/tests/compile-fail/non_integer_base/all_defined.rs
vendored
Normal file
@ -0,0 +1,123 @@
|
||||
use std::{
|
||||
fmt::{
|
||||
self,
|
||||
Debug,
|
||||
Display,
|
||||
LowerHex,
|
||||
UpperHex,
|
||||
Octal,
|
||||
Binary,
|
||||
},
|
||||
ops::{
|
||||
BitAnd,
|
||||
BitOr,
|
||||
BitXor,
|
||||
BitAndAssign,
|
||||
BitOrAssign,
|
||||
BitXorAssign,
|
||||
Not,
|
||||
},
|
||||
};
|
||||
|
||||
use bitflags::bitflags;
|
||||
|
||||
// Ideally we'd actually want this to work, but currently need something like `num`'s `Zero`
|
||||
// With some design work it could be made possible
|
||||
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||
struct MyInt(u8);
|
||||
|
||||
impl BitAnd for MyInt {
|
||||
type Output = Self;
|
||||
|
||||
fn bitand(self, other: Self) -> Self {
|
||||
MyInt(self.0 & other.0)
|
||||
}
|
||||
}
|
||||
|
||||
impl BitOr for MyInt {
|
||||
type Output = Self;
|
||||
|
||||
fn bitor(self, other: Self) -> Self {
|
||||
MyInt(self.0 | other.0)
|
||||
}
|
||||
}
|
||||
|
||||
impl BitXor for MyInt {
|
||||
type Output = Self;
|
||||
|
||||
fn bitxor(self, other: Self) -> Self {
|
||||
MyInt(self.0 ^ other.0)
|
||||
}
|
||||
}
|
||||
|
||||
impl BitAndAssign for MyInt {
|
||||
fn bitand_assign(&mut self, other: Self) {
|
||||
self.0 &= other.0
|
||||
}
|
||||
}
|
||||
|
||||
impl BitOrAssign for MyInt {
|
||||
fn bitor_assign(&mut self, other: Self) {
|
||||
self.0 |= other.0
|
||||
}
|
||||
}
|
||||
|
||||
impl BitXorAssign for MyInt {
|
||||
fn bitxor_assign(&mut self, other: Self) {
|
||||
self.0 ^= other.0
|
||||
}
|
||||
}
|
||||
|
||||
impl Debug for MyInt {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
Debug::fmt(&self.0, f)
|
||||
}
|
||||
}
|
||||
|
||||
impl Display for MyInt {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
Display::fmt(&self.0, f)
|
||||
}
|
||||
}
|
||||
|
||||
impl LowerHex for MyInt {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
LowerHex::fmt(&self.0, f)
|
||||
}
|
||||
}
|
||||
|
||||
impl UpperHex for MyInt {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
UpperHex::fmt(&self.0, f)
|
||||
}
|
||||
}
|
||||
|
||||
impl Octal for MyInt {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
Octal::fmt(&self.0, f)
|
||||
}
|
||||
}
|
||||
|
||||
impl Binary for MyInt {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
Binary::fmt(&self.0, f)
|
||||
}
|
||||
}
|
||||
|
||||
impl Not for MyInt {
|
||||
type Output = MyInt;
|
||||
|
||||
fn not(self) -> Self {
|
||||
MyInt(!self.0)
|
||||
}
|
||||
}
|
||||
|
||||
bitflags! {
|
||||
struct Flags128: MyInt {
|
||||
const A = MyInt(0b0000_0001u8);
|
||||
const B = MyInt(0b0000_0010u8);
|
||||
const C = MyInt(0b0000_0100u8);
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {}
|
27
vendor/bitflags/tests/compile-fail/non_integer_base/all_defined.stderr.beta
vendored
Normal file
27
vendor/bitflags/tests/compile-fail/non_integer_base/all_defined.stderr.beta
vendored
Normal file
@ -0,0 +1,27 @@
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/all_defined.rs:115:1
|
||||
|
|
||||
115 | / bitflags! {
|
||||
116 | | struct Flags128: MyInt {
|
||||
117 | | const A = MyInt(0b0000_0001u8);
|
||||
118 | | const B = MyInt(0b0000_0010u8);
|
||||
119 | | const C = MyInt(0b0000_0100u8);
|
||||
120 | | }
|
||||
121 | | }
|
||||
| |_^ expected struct `MyInt`, found integer
|
||||
|
|
||||
= note: this error originates in the macro `__impl_all_bitflags` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/all_defined.rs:115:1
|
||||
|
|
||||
115 | / bitflags! {
|
||||
116 | | struct Flags128: MyInt {
|
||||
117 | | const A = MyInt(0b0000_0001u8);
|
||||
118 | | const B = MyInt(0b0000_0010u8);
|
||||
119 | | const C = MyInt(0b0000_0100u8);
|
||||
120 | | }
|
||||
121 | | }
|
||||
| |_^ expected struct `MyInt`, found integer
|
||||
|
|
||||
= note: this error originates in the macro `__impl_bitflags` (in Nightly builds, run with -Z macro-backtrace for more info)
|
13
vendor/bitflags/tests/compile-fail/non_integer_base/all_missing.rs
vendored
Normal file
13
vendor/bitflags/tests/compile-fail/non_integer_base/all_missing.rs
vendored
Normal file
@ -0,0 +1,13 @@
|
||||
use bitflags::bitflags;
|
||||
|
||||
struct MyInt(u8);
|
||||
|
||||
bitflags! {
|
||||
struct Flags128: MyInt {
|
||||
const A = MyInt(0b0000_0001);
|
||||
const B = MyInt(0b0000_0010);
|
||||
const C = MyInt(0b0000_0100);
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {}
|
13
vendor/bitflags/tests/compile-fail/non_integer_base/all_missing.stderr.beta
vendored
Normal file
13
vendor/bitflags/tests/compile-fail/non_integer_base/all_missing.stderr.beta
vendored
Normal file
@ -0,0 +1,13 @@
|
||||
error[E0204]: the trait `Copy` may not be implemented for this type
|
||||
--> $DIR/all_missing.rs:5:1
|
||||
|
|
||||
5 | / bitflags! {
|
||||
6 | | struct Flags128: MyInt {
|
||||
7 | | const A = MyInt(0b0000_0001);
|
||||
8 | | const B = MyInt(0b0000_0010);
|
||||
9 | | const C = MyInt(0b0000_0100);
|
||||
10 | | }
|
||||
11 | | }
|
||||
| |_^ this field does not implement `Copy`
|
||||
|
|
||||
= note: this error originates in the derive macro `Copy` (in Nightly builds, run with -Z macro-backtrace for more info)
|
13
vendor/bitflags/tests/compile-fail/visibility/private_field.rs
vendored
Normal file
13
vendor/bitflags/tests/compile-fail/visibility/private_field.rs
vendored
Normal file
@ -0,0 +1,13 @@
|
||||
mod example {
|
||||
use bitflags::bitflags;
|
||||
|
||||
bitflags! {
|
||||
pub struct Flags1: u32 {
|
||||
const FLAG_A = 0b00000001;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let flag1 = example::Flags1::FLAG_A.bits;
|
||||
}
|
10
vendor/bitflags/tests/compile-fail/visibility/private_field.stderr.beta
vendored
Normal file
10
vendor/bitflags/tests/compile-fail/visibility/private_field.stderr.beta
vendored
Normal file
@ -0,0 +1,10 @@
|
||||
error[E0616]: field `bits` of struct `Flags1` is private
|
||||
--> $DIR/private_field.rs:12:41
|
||||
|
|
||||
12 | let flag1 = example::Flags1::FLAG_A.bits;
|
||||
| ^^^^ private field
|
||||
|
|
||||
help: a method `bits` also exists, call it with parentheses
|
||||
|
|
||||
12 | let flag1 = example::Flags1::FLAG_A.bits();
|
||||
| ^^
|
18
vendor/bitflags/tests/compile-fail/visibility/private_flags.rs
vendored
Normal file
18
vendor/bitflags/tests/compile-fail/visibility/private_flags.rs
vendored
Normal file
@ -0,0 +1,18 @@
|
||||
mod example {
|
||||
use bitflags::bitflags;
|
||||
|
||||
bitflags! {
|
||||
pub struct Flags1: u32 {
|
||||
const FLAG_A = 0b00000001;
|
||||
}
|
||||
|
||||
struct Flags2: u32 {
|
||||
const FLAG_B = 0b00000010;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let flag1 = example::Flags1::FLAG_A;
|
||||
let flag2 = example::Flags2::FLAG_B;
|
||||
}
|
18
vendor/bitflags/tests/compile-fail/visibility/private_flags.stderr.beta
vendored
Normal file
18
vendor/bitflags/tests/compile-fail/visibility/private_flags.stderr.beta
vendored
Normal file
@ -0,0 +1,18 @@
|
||||
error[E0603]: struct `Flags2` is private
|
||||
--> $DIR/private_flags.rs:17:26
|
||||
|
|
||||
17 | let flag2 = example::Flags2::FLAG_B;
|
||||
| ^^^^^^ private struct
|
||||
|
|
||||
note: the struct `Flags2` is defined here
|
||||
--> $DIR/private_flags.rs:4:5
|
||||
|
|
||||
4 | / bitflags! {
|
||||
5 | | pub struct Flags1: u32 {
|
||||
6 | | const FLAG_A = 0b00000001;
|
||||
7 | | }
|
||||
... |
|
||||
11 | | }
|
||||
12 | | }
|
||||
| |_____^
|
||||
= note: this error originates in the macro `bitflags` (in Nightly builds, run with -Z macro-backtrace for more info)
|
9
vendor/bitflags/tests/compile-fail/visibility/pub_const.rs
vendored
Normal file
9
vendor/bitflags/tests/compile-fail/visibility/pub_const.rs
vendored
Normal file
@ -0,0 +1,9 @@
|
||||
use bitflags::bitflags;
|
||||
|
||||
bitflags! {
|
||||
pub struct Flags1: u32 {
|
||||
pub const FLAG_A = 0b00000001;
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {}
|
5
vendor/bitflags/tests/compile-fail/visibility/pub_const.stderr.beta
vendored
Normal file
5
vendor/bitflags/tests/compile-fail/visibility/pub_const.stderr.beta
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
error: no rules expected the token `pub`
|
||||
--> $DIR/pub_const.rs:5:9
|
||||
|
|
||||
5 | pub const FLAG_A = 0b00000001;
|
||||
| ^^^ no rules expected this token in macro call
|
17
vendor/bitflags/tests/compile-pass/impls/convert.rs
vendored
Normal file
17
vendor/bitflags/tests/compile-pass/impls/convert.rs
vendored
Normal file
@ -0,0 +1,17 @@
|
||||
use bitflags::bitflags;
|
||||
|
||||
bitflags! {
|
||||
struct Flags: u32 {
|
||||
const A = 0b00000001;
|
||||
}
|
||||
}
|
||||
|
||||
impl From<u32> for Flags {
|
||||
fn from(v: u32) -> Flags {
|
||||
Flags::from_bits_truncate(v)
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
|
||||
}
|
10
vendor/bitflags/tests/compile-pass/impls/default.rs
vendored
Normal file
10
vendor/bitflags/tests/compile-pass/impls/default.rs
vendored
Normal file
@ -0,0 +1,10 @@
|
||||
use bitflags::bitflags;
|
||||
|
||||
bitflags! {
|
||||
#[derive(Default)]
|
||||
struct Flags: u32 {
|
||||
const A = 0b00000001;
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {}
|
15
vendor/bitflags/tests/compile-pass/impls/inherent_methods.rs
vendored
Normal file
15
vendor/bitflags/tests/compile-pass/impls/inherent_methods.rs
vendored
Normal file
@ -0,0 +1,15 @@
|
||||
use bitflags::bitflags;
|
||||
|
||||
bitflags! {
|
||||
struct Flags: u32 {
|
||||
const A = 0b00000001;
|
||||
}
|
||||
}
|
||||
|
||||
impl Flags {
|
||||
pub fn new() -> Flags {
|
||||
Flags::A
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {}
|
14
vendor/bitflags/tests/compile-pass/redefinition/core.rs
vendored
Normal file
14
vendor/bitflags/tests/compile-pass/redefinition/core.rs
vendored
Normal file
@ -0,0 +1,14 @@
|
||||
use bitflags::bitflags;
|
||||
|
||||
// Checks for possible errors caused by overriding names used by `bitflags!` internally.
|
||||
|
||||
mod core {}
|
||||
mod _core {}
|
||||
|
||||
bitflags! {
|
||||
struct Test: u8 {
|
||||
const A = 1;
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {}
|
19
vendor/bitflags/tests/compile-pass/redefinition/stringify.rs
vendored
Normal file
19
vendor/bitflags/tests/compile-pass/redefinition/stringify.rs
vendored
Normal file
@ -0,0 +1,19 @@
|
||||
use bitflags::bitflags;
|
||||
|
||||
// Checks for possible errors caused by overriding names used by `bitflags!` internally.
|
||||
|
||||
#[allow(unused_macros)]
|
||||
macro_rules! stringify {
|
||||
($($t:tt)*) => { "..." };
|
||||
}
|
||||
|
||||
bitflags! {
|
||||
struct Test: u8 {
|
||||
const A = 1;
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
// Just make sure we don't call the redefined `stringify` macro
|
||||
assert_eq!(format!("{:?}", Test::A), "A");
|
||||
}
|
10
vendor/bitflags/tests/compile-pass/repr/c.rs
vendored
Normal file
10
vendor/bitflags/tests/compile-pass/repr/c.rs
vendored
Normal file
@ -0,0 +1,10 @@
|
||||
use bitflags::bitflags;
|
||||
|
||||
bitflags! {
|
||||
#[repr(C)]
|
||||
struct Flags: u32 {
|
||||
const A = 0b00000001;
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {}
|
10
vendor/bitflags/tests/compile-pass/repr/transparent.rs
vendored
Normal file
10
vendor/bitflags/tests/compile-pass/repr/transparent.rs
vendored
Normal file
@ -0,0 +1,10 @@
|
||||
use bitflags::bitflags;
|
||||
|
||||
bitflags! {
|
||||
#[repr(transparent)]
|
||||
struct Flags: u32 {
|
||||
const A = 0b00000001;
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {}
|
11
vendor/bitflags/tests/compile-pass/visibility/bits_field.rs
vendored
Normal file
11
vendor/bitflags/tests/compile-pass/visibility/bits_field.rs
vendored
Normal file
@ -0,0 +1,11 @@
|
||||
use bitflags::bitflags;
|
||||
|
||||
bitflags! {
|
||||
pub struct Flags1: u32 {
|
||||
const FLAG_A = 0b00000001;
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
assert_eq!(0b00000001, Flags1::FLAG_A.bits);
|
||||
}
|
19
vendor/bitflags/tests/compile-pass/visibility/pub_in.rs
vendored
Normal file
19
vendor/bitflags/tests/compile-pass/visibility/pub_in.rs
vendored
Normal file
@ -0,0 +1,19 @@
|
||||
mod a {
|
||||
mod b {
|
||||
use bitflags::bitflags;
|
||||
|
||||
bitflags! {
|
||||
pub(in crate::a) struct Flags: u32 {
|
||||
const FLAG_A = 0b00000001;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn flags() -> u32 {
|
||||
b::Flags::FLAG_A.bits()
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
assert_eq!(0b00000001, a::flags());
|
||||
}
|
63
vendor/bitflags/tests/compile.rs
vendored
Normal file
63
vendor/bitflags/tests/compile.rs
vendored
Normal file
@ -0,0 +1,63 @@
|
||||
use std::{
|
||||
fs,
|
||||
ffi::OsStr,
|
||||
io,
|
||||
path::Path,
|
||||
};
|
||||
|
||||
use walkdir::WalkDir;
|
||||
|
||||
#[test]
|
||||
fn fail() {
|
||||
prepare_stderr_files("tests/compile-fail").unwrap();
|
||||
|
||||
let t = trybuild::TestCases::new();
|
||||
t.compile_fail("tests/compile-fail/**/*.rs");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn pass() {
|
||||
let t = trybuild::TestCases::new();
|
||||
t.pass("tests/compile-pass/**/*.rs");
|
||||
}
|
||||
|
||||
// Compiler messages may change between versions
|
||||
// We don't want to have to track these too closely for `bitflags`, but
|
||||
// having some message to check makes sure user-facing errors are sensical.
|
||||
//
|
||||
// The approach we use is to run the test on all compilers, but only check stderr
|
||||
// output on beta (which is the next stable release). We do this by default ignoring
|
||||
// any `.stderr` files in the `compile-fail` directory, and copying `.stderr.beta` files
|
||||
// when we happen to be running on a beta compiler.
|
||||
fn prepare_stderr_files(path: impl AsRef<Path>) -> io::Result<()> {
|
||||
for entry in WalkDir::new(path) {
|
||||
let entry = entry?;
|
||||
|
||||
if entry.path().extension().and_then(OsStr::to_str) == Some("beta") {
|
||||
let renamed = entry.path().with_extension("");
|
||||
|
||||
// Unconditionally remove a corresponding `.stderr` file for a `.stderr.beta`
|
||||
// file if it exists. On `beta` compilers, we'll recreate it. On other compilers,
|
||||
// we don't want to end up checking it anyways.
|
||||
if renamed.exists() {
|
||||
fs::remove_file(&renamed)?;
|
||||
}
|
||||
|
||||
rename_beta_stderr(entry.path(), renamed)?;
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[rustversion::beta]
|
||||
fn rename_beta_stderr(from: impl AsRef<Path>, to: impl AsRef<Path>) -> io::Result<()> {
|
||||
fs::copy(from, to)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[rustversion::not(beta)]
|
||||
fn rename_beta_stderr(_: impl AsRef<Path>, _: impl AsRef<Path>) -> io::Result<()> {
|
||||
Ok(())
|
||||
}
|
1
vendor/bytes/.cargo-checksum.json
vendored
Normal file
1
vendor/bytes/.cargo-checksum.json
vendored
Normal file
@ -0,0 +1 @@
|
||||
{"files":{"CHANGELOG.md":"f6e9c0188bb3dea02b2db80c9a3b9bef263de53fa51303b7e3b5297e14cb2b4a","Cargo.toml":"6549e17368b94b0c93696b62a151587b8ef8879d282c4784cdc85cc1862ee242","LICENSE":"45f522cacecb1023856e46df79ca625dfc550c94910078bd8aec6e02880b3d42","README.md":"b691d6e144eb133c181e869dc2f6a6eedbf76c4f832a9ecfbed5b9c560160c7f","benches/buf.rs":"72e6b6120b52d568da068f17c66a793d65602e400c595778581b63092e41d8dc","benches/bytes.rs":"f8cc255be7e8afedf6ade95cd529d105c537c5ec51110d46d470a26b497afa05","benches/bytes_mut.rs":"1326fe6224b26826228e02b4133151e756f38152c2d9cfe66adf83af76c3ec98","ci/miri.sh":"1ee54575b55a0e495e52ca1a934beed674bc8f375f03c4cfc3e81d221ec4fe98","ci/test-stable.sh":"57dd709bc25a20103ee85e24965566900817b2e603f067fb1251a5c03e4b1d93","ci/tsan.sh":"466b86b19225dd26c756cf2252cb1973f87a145642c99364b462ed7ceb55c7dd","clippy.toml":"8522f448dfa3b33ac334ce47d233ebb6b58e8ae115e45107a64fc1b4510fe560","src/buf/buf_impl.rs":"bdd9d5bc3318185ef1bea8d7c6a9dd3712ec297e0045fd84024f188c0ad96ac0","src/buf/buf_mut.rs":"58d9a82d982b2fc4c5421beafd31a9d0ea1ae500fd4a8b469ffc22e5bb21822a","src/buf/chain.rs":"46ec16a7cc370374218c2621ad738df77d95b25216099900ad9195a08a234375","src/buf/iter.rs":"49e9990a2303252ef7c66c2cc24459097dbbf4900c978453982ef513467bbf67","src/buf/limit.rs":"e005ba140b70f68654877c96b981a220477e415ff5c92438c1b0cb9bc866d872","src/buf/mod.rs":"19ff6fb7e19cba3884bc3f1a50ef20117dbc807f6d146ed355f42344a74fdf44","src/buf/reader.rs":"856c1e7129a1eceaa3c8f9ed4da8c3b5e1cc267eeffa99fa8f7c56c5ca7834d1","src/buf/take.rs":"a897e79bf579391227816973b2aa1f1d63614bd48bc029d9371f61607dcfa23f","src/buf/uninit_slice.rs":"b3bc013336235de246ddcb87f2961c556e800851d2199f4326a7b466c566b4a0","src/buf/vec_deque.rs":"8d552c26ac6ce28a471f74c388e4749432e86b1d8f5a9759b9fc32a2549d395f","src/buf/writer.rs":"c92b5f8b9b42e2e784de474c987fe4ac50af4b5c51ac9548d19a54e8ac9ff521","src/bytes.rs":"37b2df8bc94560d6a6ba2fbfb702358686d5b016cd7d48c80f51fa2ad03c5393","src/bytes_mut.rs":"29854cf9fbedd12ca66cf76bf4b1ca4424620ad495c75243a51a77efda926c73","src/fmt/debug.rs":"97b23cfa1d2701fa187005421302eeb260e635cd4f9a9e02b044ff89fcc8b8ad","src/fmt/hex.rs":"13755ec6f1b79923e1f1a05c51b179a38c03c40bb8ed2db0210e8901812e61e7","src/fmt/mod.rs":"176da4e359da99b8e5cf16e480cb7b978f574876827f1b9bb9c08da4d74ac0f5","src/lib.rs":"d8be90ade0cf78a30d73493086c109049d8ff442d69589a07f16480578eb4b17","src/loom.rs":"eb3f577d8cce39a84155c241c4dc308f024631f02085833f7fe9f0ea817bcea9","src/serde.rs":"3ecd7e828cd4c2b7db93c807cb1548fad209e674df493edf7cda69a7b04d405d","tests/test_buf.rs":"a04fb90644fcf0444092c49a4ca848bb0fd8b2ffeeebcb705eeea2de58560859","tests/test_buf_mut.rs":"5643866cd7b0967fb36053a1da73a23b26ffaa2746c05dca91e82df91aee7f81","tests/test_bytes.rs":"fe5beb749d3d48ec0c57d2ecf0ca56edc5a08cdc07a7842d863ee64d78d0ce69","tests/test_bytes_odd_alloc.rs":"aeb7a86bf8b31f67b6f453399f3649e0d3878247debc1325d98e66201b1da15f","tests/test_bytes_vec_alloc.rs":"dd7e3c3a71abcfdcad7e3b2f52a6bd106ad6ea0d4bc634372e81dae097233cf0","tests/test_chain.rs":"e9f094539bb42b3135f50033c44122a6b44cf0f953e51e8b488f43243f1e7f10","tests/test_debug.rs":"13299107172809e8cbbd823964ac9450cd0d6b6de79f2e6a2e0f44b9225a0593","tests/test_iter.rs":"c1f46823df26a90139645fd8728a03138edd95b2849dfec830452a80ddd9726d","tests/test_reader.rs":"bf83669d4e0960dad6aa47b46a9a454814fab626eb83572aba914c3d71618f43","tests/test_serde.rs":"2691f891796ba259de0ecf926de05c514f4912cc5fcd3e6a1591efbcd23ed4d0","tests/test_take.rs":"db01bf6855097f318336e90d12c0725a92cee426d330e477a6bd1d32dac34a27"},"package":"ec8a7b6a70fde80372154c65702f00a0f56f3e1c36abbc6c440484be248856db"}
|
253
vendor/bytes/CHANGELOG.md
vendored
Normal file
253
vendor/bytes/CHANGELOG.md
vendored
Normal file
@ -0,0 +1,253 @@
|
||||
# 1.2.1 (July 30, 2022)
|
||||
|
||||
### Fixed
|
||||
|
||||
- Fix unbounded memory growth when using `reserve` (#560)
|
||||
|
||||
# 1.2.0 (July 19, 2022)
|
||||
|
||||
### Added
|
||||
|
||||
- Add `BytesMut::zeroed` (#517)
|
||||
- Implement `Extend<Bytes>` for `BytesMut` (#527)
|
||||
- Add conversion from `BytesMut` to `Vec<u8>` (#543, #554)
|
||||
- Add conversion from `Bytes` to `Vec<u8>` (#547)
|
||||
- Add `UninitSlice::as_uninit_slice_mut()` (#548)
|
||||
- Add const to `Bytes::{len,is_empty}` (#514)
|
||||
|
||||
### Changed
|
||||
|
||||
- Reuse vector in `BytesMut::reserve` (#539, #544)
|
||||
|
||||
### Fixed
|
||||
|
||||
- Make miri happy (#515, #523, #542, #545, #553)
|
||||
- Make tsan happy (#541)
|
||||
- Fix `remaining_mut()` on chain (#488)
|
||||
- Fix amortized asymptotics of `BytesMut` (#555)
|
||||
|
||||
### Documented
|
||||
|
||||
- Redraw layout diagram with box drawing characters (#539)
|
||||
- Clarify `BytesMut::unsplit` docs (#535)
|
||||
|
||||
# 1.1.0 (August 25, 2021)
|
||||
|
||||
### Added
|
||||
|
||||
- `BufMut::put_bytes(self, val, cnt)` (#487)
|
||||
- Implement `From<Box<[u8]>>` for `Bytes` (#504)
|
||||
|
||||
### Changed
|
||||
|
||||
- Override `put_slice` for `&mut [u8]` (#483)
|
||||
- Panic on integer overflow in `Chain::remaining` (#482)
|
||||
- Add inline tags to `UninitSlice` methods (#443)
|
||||
- Override `copy_to_bytes` for Chain and Take (#481)
|
||||
- Keep capacity when unsplit on empty other buf (#502)
|
||||
|
||||
### Documented
|
||||
|
||||
- Clarify `BufMut` allocation guarantees (#501)
|
||||
- Clarify `BufMut::put_int` behavior (#486)
|
||||
- Clarify actions of `clear` and `truncate`. (#508)
|
||||
|
||||
# 1.0.1 (January 11, 2021)
|
||||
|
||||
### Changed
|
||||
- mark `Vec::put_slice` with `#[inline]` (#459)
|
||||
|
||||
### Fixed
|
||||
- Fix deprecation warning (#457)
|
||||
- use `Box::into_raw` instead of `mem::forget`-in-disguise (#458)
|
||||
|
||||
# 1.0.0 (December 22, 2020)
|
||||
|
||||
### Changed
|
||||
- Rename `Buf`/`BufMut` methods `bytes()` and `bytes_mut()` to `chunk()` and `chunk_mut()` (#450)
|
||||
|
||||
### Removed
|
||||
- remove unused Buf implementation. (#449)
|
||||
|
||||
# 0.6.0 (October 21, 2020)
|
||||
|
||||
API polish in preparation for a 1.0 release.
|
||||
|
||||
### Changed
|
||||
- `BufMut` is now an `unsafe` trait (#432).
|
||||
- `BufMut::bytes_mut()` returns `&mut UninitSlice`, a type owned by `bytes` to
|
||||
avoid undefined behavior (#433).
|
||||
- `Buf::copy_to_bytes(len)` replaces `Buf::into_bytes()` (#439).
|
||||
- `Buf`/`BufMut` utility methods are moved onto the trait and `*Ext` traits are
|
||||
removed (#431).
|
||||
|
||||
### Removed
|
||||
- `BufMut::bytes_vectored_mut()` (#430).
|
||||
- `new` methods on combinator types (#434).
|
||||
|
||||
# 0.5.6 (July 13, 2020)
|
||||
|
||||
- Improve `BytesMut` to reuse buffer when fully `advance`d.
|
||||
- Mark `BytesMut::{as_mut, set_len}` with `#[inline]`.
|
||||
- Relax synchronization when cloning in shared vtable of `Bytes`.
|
||||
- Move `loom` to `dev-dependencies`.
|
||||
|
||||
# 0.5.5 (June 18, 2020)
|
||||
|
||||
### Added
|
||||
- Allow using the `serde` feature in `no_std` environments (#385).
|
||||
|
||||
### Fix
|
||||
- Fix `BufMut::advance_mut` to panic if advanced passed the capacity (#354)..
|
||||
- Fix `BytesMut::freeze` ignoring amount previously `advance`d (#352).
|
||||
|
||||
# 0.5.4 (January 23, 2020)
|
||||
|
||||
### Added
|
||||
- Make `Bytes::new` a `const fn`.
|
||||
- Add `From<BytesMut>` for `Bytes`.
|
||||
|
||||
### Fix
|
||||
- Fix reversed arguments in `PartialOrd` for `Bytes`.
|
||||
- Fix `Bytes::truncate` losing original capacity when repr is an unshared `Vec`.
|
||||
- Fix `Bytes::from(Vec)` when allocator gave `Vec` a pointer with LSB set.
|
||||
- Fix panic in `Bytes::slice_ref` if argument is an empty slice.
|
||||
|
||||
# 0.5.3 (December 12, 2019)
|
||||
|
||||
### Added
|
||||
- `must_use` attributes to `split`, `split_off`, and `split_to` methods (#337).
|
||||
|
||||
### Fix
|
||||
- Potential freeing of a null pointer in `Bytes` when constructed with an empty `Vec<u8>` (#341, #342).
|
||||
- Calling `Bytes::truncate` with a size large than the length will no longer clear the `Bytes` (#333).
|
||||
|
||||
# 0.5.2 (November 27, 2019)
|
||||
|
||||
### Added
|
||||
- `Limit` methods `into_inner`, `get_ref`, `get_mut`, `limit`, and `set_limit` (#325).
|
||||
|
||||
# 0.5.1 (November 25, 2019)
|
||||
|
||||
### Fix
|
||||
- Growth documentation for `BytesMut` (#321)
|
||||
|
||||
# 0.5.0 (November 25, 2019)
|
||||
|
||||
### Fix
|
||||
- Potential overflow in `copy_to_slice`
|
||||
|
||||
### Changed
|
||||
- Increased minimum supported Rust version to 1.39.
|
||||
- `Bytes` is now a "trait object", allowing for custom allocation strategies (#298)
|
||||
- `BytesMut` implicitly grows internal storage. `remaining_mut()` returns
|
||||
`usize::MAX` (#316).
|
||||
- `BufMut::bytes_mut` returns `&mut [MaybeUninit<u8>]` to reflect the unknown
|
||||
initialization state (#305).
|
||||
- `Buf` / `BufMut` implementations for `&[u8]` and `&mut [u8]`
|
||||
respectively (#261).
|
||||
- Move `Buf` / `BufMut` "extra" functions to an extension trait (#306).
|
||||
- `BufMutExt::limit` (#309).
|
||||
- `Bytes::slice` takes a `RangeBounds` argument (#265).
|
||||
- `Bytes::from_static` is now a `const fn` (#311).
|
||||
- A multitude of smaller performance optimizations.
|
||||
|
||||
### Added
|
||||
- `no_std` support (#281).
|
||||
- `get_*`, `put_*`, `get_*_le`, and `put_*le` accessors for handling byte order.
|
||||
- `BorrowMut` implementation for `BytesMut` (#185).
|
||||
|
||||
### Removed
|
||||
- `IntoBuf` (#288).
|
||||
- `Buf` implementation for `&str` (#301).
|
||||
- `byteorder` dependency (#280).
|
||||
- `iovec` dependency, use `std::IoSlice` instead (#263).
|
||||
- optional `either` dependency (#315).
|
||||
- optional `i128` feature -- now available on stable. (#276).
|
||||
|
||||
# 0.4.12 (March 6, 2019)
|
||||
|
||||
### Added
|
||||
- Implement `FromIterator<&'a u8>` for `BytesMut`/`Bytes` (#244).
|
||||
- Implement `Buf` for `VecDeque` (#249).
|
||||
|
||||
# 0.4.11 (November 17, 2018)
|
||||
|
||||
* Use raw pointers for potentially racy loads (#233).
|
||||
* Implement `BufRead` for `buf::Reader` (#232).
|
||||
* Documentation tweaks (#234).
|
||||
|
||||
# 0.4.10 (September 4, 2018)
|
||||
|
||||
* impl `Buf` and `BufMut` for `Either` (#225).
|
||||
* Add `Bytes::slice_ref` (#208).
|
||||
|
||||
# 0.4.9 (July 12, 2018)
|
||||
|
||||
* Add 128 bit number support behind a feature flag (#209).
|
||||
* Implement `IntoBuf` for `&mut [u8]`
|
||||
|
||||
# 0.4.8 (May 25, 2018)
|
||||
|
||||
* Fix panic in `BytesMut` `FromIterator` implementation.
|
||||
* Bytes: Recycle space when reserving space in vec mode (#197).
|
||||
* Bytes: Add resize fn (#203).
|
||||
|
||||
# 0.4.7 (April 27, 2018)
|
||||
|
||||
* Make `Buf` and `BufMut` usable as trait objects (#186).
|
||||
* impl BorrowMut for BytesMut (#185).
|
||||
* Improve accessor performance (#195).
|
||||
|
||||
# 0.4.6 (Janary 8, 2018)
|
||||
|
||||
* Implement FromIterator for Bytes/BytesMut (#148).
|
||||
* Add `advance` fn to Bytes/BytesMut (#166).
|
||||
* Add `unsplit` fn to `BytesMut` (#162, #173).
|
||||
* Improvements to Bytes split fns (#92).
|
||||
|
||||
# 0.4.5 (August 12, 2017)
|
||||
|
||||
* Fix range bug in `Take::bytes`
|
||||
* Misc performance improvements
|
||||
* Add extra `PartialEq` implementations.
|
||||
* Add `Bytes::with_capacity`
|
||||
* Implement `AsMut[u8]` for `BytesMut`
|
||||
|
||||
# 0.4.4 (May 26, 2017)
|
||||
|
||||
* Add serde support behind feature flag
|
||||
* Add `extend_from_slice` on `Bytes` and `BytesMut`
|
||||
* Add `truncate` and `clear` on `Bytes`
|
||||
* Misc additional std trait implementations
|
||||
* Misc performance improvements
|
||||
|
||||
# 0.4.3 (April 30, 2017)
|
||||
|
||||
* Fix Vec::advance_mut bug
|
||||
* Bump minimum Rust version to 1.15
|
||||
* Misc performance tweaks
|
||||
|
||||
# 0.4.2 (April 5, 2017)
|
||||
|
||||
* Misc performance tweaks
|
||||
* Improved `Debug` implementation for `Bytes`
|
||||
* Avoid some incorrect assert panics
|
||||
|
||||
# 0.4.1 (March 15, 2017)
|
||||
|
||||
* Expose `buf` module and have most types available from there vs. root.
|
||||
* Implement `IntoBuf` for `T: Buf`.
|
||||
* Add `FromBuf` and `Buf::collect`.
|
||||
* Add iterator adapter for `Buf`.
|
||||
* Add scatter/gather support to `Buf` and `BufMut`.
|
||||
* Add `Buf::chain`.
|
||||
* Reduce allocations on repeated calls to `BytesMut::reserve`.
|
||||
* Implement `Debug` for more types.
|
||||
* Remove `Source` in favor of `IntoBuf`.
|
||||
* Implement `Extend` for `BytesMut`.
|
||||
|
||||
|
||||
# 0.4.0 (February 24, 2017)
|
||||
|
||||
* Initial release
|
54
vendor/bytes/Cargo.toml
vendored
Normal file
54
vendor/bytes/Cargo.toml
vendored
Normal file
@ -0,0 +1,54 @@
|
||||
# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO
|
||||
#
|
||||
# When uploading crates to the registry Cargo will automatically
|
||||
# "normalize" Cargo.toml files for maximal compatibility
|
||||
# with all versions of Cargo and also rewrite `path` dependencies
|
||||
# to registry (e.g., crates.io) dependencies.
|
||||
#
|
||||
# If you are reading this file be aware that the original Cargo.toml
|
||||
# will likely look very different (and much more reasonable).
|
||||
# See Cargo.toml.orig for the original contents.
|
||||
|
||||
[package]
|
||||
edition = "2018"
|
||||
name = "bytes"
|
||||
version = "1.2.1"
|
||||
authors = [
|
||||
"Carl Lerche <me@carllerche.com>",
|
||||
"Sean McArthur <sean@seanmonstar.com>",
|
||||
]
|
||||
description = "Types and traits for working with bytes"
|
||||
readme = "README.md"
|
||||
keywords = [
|
||||
"buffers",
|
||||
"zero-copy",
|
||||
"io",
|
||||
]
|
||||
categories = [
|
||||
"network-programming",
|
||||
"data-structures",
|
||||
]
|
||||
license = "MIT"
|
||||
repository = "https://github.com/tokio-rs/bytes"
|
||||
|
||||
[package.metadata.docs.rs]
|
||||
rustdoc-args = [
|
||||
"--cfg",
|
||||
"docsrs",
|
||||
]
|
||||
|
||||
[dependencies.serde]
|
||||
version = "1.0.60"
|
||||
features = ["alloc"]
|
||||
optional = true
|
||||
default-features = false
|
||||
|
||||
[dev-dependencies.serde_test]
|
||||
version = "1.0"
|
||||
|
||||
[features]
|
||||
default = ["std"]
|
||||
std = []
|
||||
|
||||
[target."cfg(loom)".dev-dependencies.loom]
|
||||
version = "0.5"
|
25
vendor/bytes/LICENSE
vendored
Normal file
25
vendor/bytes/LICENSE
vendored
Normal file
@ -0,0 +1,25 @@
|
||||
Copyright (c) 2018 Carl Lerche
|
||||
|
||||
Permission is hereby granted, free of charge, to any
|
||||
person obtaining a copy of this software and associated
|
||||
documentation files (the "Software"), to deal in the
|
||||
Software without restriction, including without
|
||||
limitation the rights to use, copy, modify, merge,
|
||||
publish, distribute, sublicense, and/or sell copies of
|
||||
the Software, and to permit persons to whom the Software
|
||||
is furnished to do so, subject to the following
|
||||
conditions:
|
||||
|
||||
The above copyright notice and this permission notice
|
||||
shall be included in all copies or substantial portions
|
||||
of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
|
||||
ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
|
||||
TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
|
||||
PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
|
||||
SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
|
||||
IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
DEALINGS IN THE SOFTWARE.
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user