Bug 1716518 - Upgrade anyhow to v1.0.41. r=emilio

Differential Revision: https://phabricator.services.mozilla.com/D117755
This commit is contained in:
Mike Hommey 2021-06-15 20:39:46 +00:00
Родитель 9b25e1d86e
Коммит 2c1e53b8e4
22 изменённых файлов: 1083 добавлений и 193 удалений

4
Cargo.lock сгенерированный
Просмотреть файл

@ -35,9 +35,9 @@ dependencies = [
[[package]] [[package]]
name = "anyhow" name = "anyhow"
version = "1.0.30" version = "1.0.41"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2494382e9ba43995f3c56359e518641f450f5c36feeb4632a75cde2ec297c867" checksum = "15af2628f6890fe2609a3b91bef4c83450512802e59489f9c1cb1fa5df064a61"
[[package]] [[package]]
name = "app_services_logger" name = "app_services_logger"

Просмотреть файл

@ -1 +1 @@
{"files":{"Cargo.toml":"76e6e0a729a4038b0d8bcdd36a054e96f3e93dc1922813f512d28cdf8d21e516","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"23f18e03dc49df91622fe2a76176497404e46ced8a715d9d2b67a7446571cca3","README.md":"0d9c5facc3db17123752af8c3dbcdb9bb3785c8ed046b27de26669e4e87f131c","build.rs":"d8b58acc2cd88d627763135b3b25b46f276e2672ef740efb7fb5b1404fb230d8","src/backtrace.rs":"a82a8ffae2c68ee385dc78d8ec8cb6f3351234f0ad6af7e87df2371593e0f6aa","src/chain.rs":"1627608ce95c3484d26e1742a1b8b533b74c6159916b717bacffae3ae53731f9","src/context.rs":"f2be36af9588c924ed087bcb7bd681d330889e54b8f98cdc2aba93512a28762e","src/error.rs":"2c6a51880c7379265f7f7b6557e7bed808ff0f3267337a0c77dbbc1d2c4662e7","src/fmt.rs":"079d7b4faaa23f42423e0bb6b4e8a80d7d6d45c38c0d46bebd7d647c8679469f","src/kind.rs":"8481a8b7835eebb3859a8c32c217bf9c73543cfc62e3916b98d39af8b063125c","src/lib.rs":"119a39d1062a4b99a9f888a9f595a48fabacba6c8f2c3c59361ce2065d938ef6","src/macros.rs":"77722190b58a6106b21aefd3b5d4f136a076afcdbc0fae21562d99e2c22912e1","src/wrapper.rs":"1229beca67dbd95ca77c9ecce282272acc55276c267c58cb73a75388b4693dda","tests/common/mod.rs":"f9088c2d7afafa64ff730b629272045b776bfafc2f5957508242da630635f2e1","tests/compiletest.rs":"0a52a44786aea1c299c695bf948b2ed2081e4cc344e5c2cadceab4eb03d0010d","tests/drop/mod.rs":"464bc1ddeae307eac906928286ec3edb77057c5c1302e02150d3649e2b861f1a","tests/test_autotrait.rs":"981e792db353be2f14c7a1cabe43b5f1329c168cb7679077cc2be786a0920d48","tests/test_backtrace.rs":"0e50edbb33b6bd07ba89ff3db72fb7c688ba2a4371fccdbbb20309ab02948b6a","tests/test_boxed.rs":"98a45325b1e86d4c5d3094ab99cd1ada1f771c505d2d7322f0afcbe7bdb71cfa","tests/test_chain.rs":"f28efeae7395d1c395e6f1a647b4199c25a00410ade45248c145c6fcf2fb448a","tests/test_context.rs":"f82c915b182df1a604a4cd558a03b1a821414983d6f6af6822398104cea70676","tests/test_convert.rs":"62840be1ee8022ba5e8c0d3fc1752a1526b2c47d4cceecff2b86790524c3b3ea","tests/test_downcast.rs":"253d6f54e554965023b378b037827ec6289c4779a7a7c12706e19c2731d219fe","tests/test_fmt.rs":"17572596f257aac9aa2ec4620e292ca6a954128b94772bb948399fab53832e70","tests/test_macros.rs":"c7d3d5e0b756f59d4858035025fb341d031369c88486fd9f961ee16bae6c78bf","tests/test_repr.rs":"dbb9b04ddbe1ab31eb5331ea69f05bb3a147299da2275a3d4dcc92947b5591b9","tests/test_source.rs":"b80723cf635a4f8c4df21891b34bfab9ed2b2aa407e7a2f826d24e334cd5f88e","tests/ui/no-impl.rs":"fab6cbf2f6ea510b86f567dfb3b7c31250a9fd71ae5d110dbb9188be569ec593","tests/ui/no-impl.stderr":"7c2c3f46c266a437300591f10be330f937ac6a0a2213ed5030a9fbc895e2d100"},"package":"2494382e9ba43995f3c56359e518641f450f5c36feeb4632a75cde2ec297c867"} {"files":{"Cargo.toml":"05c1bbd8a9f36fba15398f0dc3634198aca3c3f6887b085b9812d21f4f33c450","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"23f18e03dc49df91622fe2a76176497404e46ced8a715d9d2b67a7446571cca3","README.md":"4a58a26808c92aae6265a60e21745bb2891a60cf1d69985fc05d26b77c2b9a79","build.rs":"afa03584629443ec723ca4e99bd087d5f07602d8640772f6f57c8e3847f75ae6","src/backtrace.rs":"a1a52f9874f0aa1382fb404f029c6fa88e53afe38fb2417877d5711f1f2b90c9","src/chain.rs":"1627608ce95c3484d26e1742a1b8b533b74c6159916b717bacffae3ae53731f9","src/context.rs":"559478ae785ce913523aa21358cc1561ef4b0b95c5c87675a77890364c0162fe","src/error.rs":"2aa93ec95f16980037c244e94fa8ac75f8b20ac22530fe45a24550d1878eb0b5","src/fmt.rs":"c2d4aad6ce20625a70a7c091e3087b6a2c19a4a87c7a12edb4c98978307245ea","src/kind.rs":"ccf5d8075d44b03cc69c0478ee5e5b3a02d4f2e7cecb37588b30043d3fcdf65f","src/lib.rs":"c0a0f94d85f5cc4aed37048ca12d8652da85b50f0999d998903ccd3ebf043eec","src/macros.rs":"88daf58370b2fcc93c43ebd5b9c1659bf5460c972681b63d89d51132126e5560","src/ptr.rs":"f1ece995b5be064773ee3d516710b4948b0bee3c237786d9988c7d2acc52c95c","src/wrapper.rs":"1229beca67dbd95ca77c9ecce282272acc55276c267c58cb73a75388b4693dda","tests/common/mod.rs":"f9088c2d7afafa64ff730b629272045b776bfafc2f5957508242da630635f2e1","tests/compiletest.rs":"022a8e400ef813d7ea1875b944549cee5125f6a995dc33e93b48cba3e1b57bd1","tests/drop/mod.rs":"382956f4bd3dcd1f6036efb8f11193595a7c60e0a5dbf5f2da149f1f25183abf","tests/test_autotrait.rs":"981e792db353be2f14c7a1cabe43b5f1329c168cb7679077cc2be786a0920d48","tests/test_backtrace.rs":"0e50edbb33b6bd07ba89ff3db72fb7c688ba2a4371fccdbbb20309ab02948b6a","tests/test_boxed.rs":"98a45325b1e86d4c5d3094ab99cd1ada1f771c505d2d7322f0afcbe7bdb71cfa","tests/test_chain.rs":"f28efeae7395d1c395e6f1a647b4199c25a00410ade45248c145c6fcf2fb448a","tests/test_context.rs":"f82c915b182df1a604a4cd558a03b1a821414983d6f6af6822398104cea70676","tests/test_convert.rs":"cae1c941727f2371b2439ff95b2628f810cfb2f77431a0807de32db84c5844e1","tests/test_downcast.rs":"e9dc236dad1cbb8b7ad74a0d87d328f23a585fbb55670b8fe55a9a2644041c5c","tests/test_ffi.rs":"d0cb4c1d6d9154090982dee72ae3ebe05a5981f976058c3250f1c9da5a45edef","tests/test_fmt.rs":"17572596f257aac9aa2ec4620e292ca6a954128b94772bb948399fab53832e70","tests/test_macros.rs":"0288c879c4735a8d317560baa3d4a6efbf1435d8ec350c5cb12cc1ba7c484080","tests/test_repr.rs":"dbb9b04ddbe1ab31eb5331ea69f05bb3a147299da2275a3d4dcc92947b5591b9","tests/test_source.rs":"b80723cf635a4f8c4df21891b34bfab9ed2b2aa407e7a2f826d24e334cd5f88e","tests/ui/no-impl.rs":"fab6cbf2f6ea510b86f567dfb3b7c31250a9fd71ae5d110dbb9188be569ec593","tests/ui/no-impl.stderr":"7dd1b84a267c83121d9f85a9c1aadc072a863ec324e170af4d7d19516f0f526c","tests/ui/temporary-value.rs":"4dcc96271b2403e6372cf4cfc813445e5ce4365fc6e156b6bc38274098499a70","tests/ui/temporary-value.stderr":"4b0cceae9e9b27fe2594e6c02bb3e3fd9965ed04498738e5877934dab807b50f"},"package":"15af2628f6890fe2609a3b91bef4c83450512802e59489f9c1cb1fa5df064a61"}

9
third_party/rust/anyhow/Cargo.toml поставляемый
Просмотреть файл

@ -13,7 +13,7 @@
[package] [package]
edition = "2018" edition = "2018"
name = "anyhow" name = "anyhow"
version = "1.0.30" version = "1.0.41"
authors = ["David Tolnay <dtolnay@gmail.com>"] authors = ["David Tolnay <dtolnay@gmail.com>"]
description = "Flexible concrete Error type built on std::error::Error" description = "Flexible concrete Error type built on std::error::Error"
documentation = "https://docs.rs/anyhow" documentation = "https://docs.rs/anyhow"
@ -24,6 +24,9 @@ repository = "https://github.com/dtolnay/anyhow"
[package.metadata.docs.rs] [package.metadata.docs.rs]
rustdoc-args = ["--cfg", "doc_cfg"] rustdoc-args = ["--cfg", "doc_cfg"]
targets = ["x86_64-unknown-linux-gnu"] targets = ["x86_64-unknown-linux-gnu"]
[dependencies.backtrace]
version = "0.3.51"
optional = true
[dev-dependencies.futures] [dev-dependencies.futures]
version = "0.3" version = "0.3"
default-features = false default-features = false
@ -31,6 +34,10 @@ default-features = false
[dev-dependencies.rustversion] [dev-dependencies.rustversion]
version = "1.0" version = "1.0"
[dev-dependencies.syn]
version = "1.0"
features = ["full"]
[dev-dependencies.thiserror] [dev-dependencies.thiserror]
version = "1.0" version = "1.0"

10
third_party/rust/anyhow/README.md поставляемый
Просмотреть файл

@ -1,5 +1,5 @@
Anyhow&ensp;¯\\\_()\_/¯ Anyhow&ensp;¯\\\_(°ペ)\_/¯
========================= ==========================
[<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="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="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)
@ -118,6 +118,12 @@ anyhow = "1.0"
return Err(anyhow!("Missing attribute: {}", missing)); 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> <br>
## No-std support ## No-std support

39
third_party/rust/anyhow/build.rs поставляемый
Просмотреть файл

@ -2,6 +2,12 @@ use std::env;
use std::fs; use std::fs;
use std::path::Path; use std::path::Path;
use std::process::{Command, ExitStatus, Stdio}; 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 // 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 // type. If the current toolchain is able to compile it, we go ahead and use
@ -35,12 +41,24 @@ const PROBE: &str = r#"
"#; "#;
fn main() { fn main() {
if !cfg!(feature = "std") { if cfg!(feature = "std") {
return; match compile_probe() {
Some(status) if status.success() => println!("cargo:rustc-cfg=backtrace"),
_ => {}
}
} }
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 < 38 {
println!("cargo:rustc-cfg=anyhow_no_macro_reexport");
}
if rustc < 51 {
println!("cargo:rustc-cfg=anyhow_no_ptr_addr_of");
} }
} }
@ -61,3 +79,14 @@ fn compile_probe() -> Option<ExitStatus> {
.status() .status()
.ok() .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()
}

379
third_party/rust/anyhow/src/backtrace.rs поставляемый
Просмотреть файл

@ -1,17 +1,34 @@
#[cfg(backtrace)] #[cfg(backtrace)]
pub(crate) use std::backtrace::Backtrace; pub(crate) use std::backtrace::{Backtrace, BacktraceStatus};
#[cfg(not(backtrace))] #[cfg(all(not(backtrace), feature = "backtrace"))]
pub(crate) use self::capture::{Backtrace, BacktraceStatus};
#[cfg(not(any(backtrace, feature = "backtrace")))]
pub(crate) enum Backtrace {} pub(crate) enum Backtrace {}
#[cfg(backtrace)] #[cfg(backtrace)]
macro_rules! backtrace { macro_rules! impl_backtrace {
() => { () => {
Some(Backtrace::capture()) std::backtrace::Backtrace
}; };
} }
#[cfg(not(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 { macro_rules! backtrace {
() => { () => {
None None
@ -23,14 +40,362 @@ macro_rules! backtrace_if_absent {
($err:expr) => { ($err:expr) => {
match $err.backtrace() { match $err.backtrace() {
Some(_) => None, Some(_) => None,
None => Some(Backtrace::capture()), None => backtrace!(),
} }
}; };
} }
#[cfg(all(feature = "std", not(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 { macro_rules! backtrace_if_absent {
($err:expr) => { ($err:expr) => {
None 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::SeqCst) {
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::SeqCst);
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>();
}

2
third_party/rust/anyhow/src/context.rs поставляемый
Просмотреть файл

@ -143,7 +143,7 @@ where
} }
fn source(&self) -> Option<&(dyn StdError + 'static)> { fn source(&self) -> Option<&(dyn StdError + 'static)> {
Some(self.error.inner.error()) Some(unsafe { crate::ErrorImpl::error(self.error.inner.by_ref()) })
} }
} }

416
third_party/rust/anyhow/src/error.rs поставляемый
Просмотреть файл

@ -1,11 +1,16 @@
use crate::alloc::Box; use crate::alloc::Box;
use crate::backtrace::Backtrace; use crate::backtrace::Backtrace;
use crate::chain::Chain; 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 crate::{Error, StdError};
use core::any::TypeId; use core::any::TypeId;
use core::fmt::{self, Debug, Display}; use core::fmt::{self, Debug, Display};
use core::mem::{self, ManuallyDrop}; use core::mem::ManuallyDrop;
use core::ptr::{self, NonNull}; #[cfg(not(anyhow_no_ptr_addr_of))]
use core::ptr;
use core::ptr::NonNull;
#[cfg(feature = "std")] #[cfg(feature = "std")]
use core::ops::{Deref, DerefMut}; use core::ops::{Deref, DerefMut};
@ -80,11 +85,15 @@ impl Error {
let vtable = &ErrorVTable { let vtable = &ErrorVTable {
object_drop: object_drop::<E>, object_drop: object_drop::<E>,
object_ref: object_ref::<E>, object_ref: object_ref::<E>,
#[cfg(feature = "std")] #[cfg(anyhow_no_ptr_addr_of)]
object_mut: object_mut::<E>, object_mut: object_mut::<E>,
object_boxed: object_boxed::<E>, object_boxed: object_boxed::<E>,
object_downcast: object_downcast::<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>, 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. // Safety: passing vtable that operates on the right type E.
@ -100,11 +109,15 @@ impl Error {
let vtable = &ErrorVTable { let vtable = &ErrorVTable {
object_drop: object_drop::<MessageError<M>>, object_drop: object_drop::<MessageError<M>>,
object_ref: object_ref::<MessageError<M>>, object_ref: object_ref::<MessageError<M>>,
#[cfg(feature = "std")] #[cfg(all(feature = "std", anyhow_no_ptr_addr_of))]
object_mut: object_mut::<MessageError<M>>, object_mut: object_mut::<MessageError<M>>,
object_boxed: object_boxed::<MessageError<M>>, object_boxed: object_boxed::<MessageError<M>>,
object_downcast: object_downcast::<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>, 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 // Safety: MessageError is repr(transparent) so it is okay for the
@ -121,11 +134,15 @@ impl Error {
let vtable = &ErrorVTable { let vtable = &ErrorVTable {
object_drop: object_drop::<DisplayError<M>>, object_drop: object_drop::<DisplayError<M>>,
object_ref: object_ref::<DisplayError<M>>, object_ref: object_ref::<DisplayError<M>>,
#[cfg(feature = "std")] #[cfg(all(feature = "std", anyhow_no_ptr_addr_of))]
object_mut: object_mut::<DisplayError<M>>, object_mut: object_mut::<DisplayError<M>>,
object_boxed: object_boxed::<DisplayError<M>>, object_boxed: object_boxed::<DisplayError<M>>,
object_downcast: object_downcast::<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>, 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 // Safety: DisplayError is repr(transparent) so it is okay for the
@ -144,11 +161,15 @@ impl Error {
let vtable = &ErrorVTable { let vtable = &ErrorVTable {
object_drop: object_drop::<ContextError<C, E>>, object_drop: object_drop::<ContextError<C, E>>,
object_ref: object_ref::<ContextError<C, E>>, object_ref: object_ref::<ContextError<C, E>>,
#[cfg(feature = "std")] #[cfg(anyhow_no_ptr_addr_of)]
object_mut: object_mut::<ContextError<C, E>>, object_mut: object_mut::<ContextError<C, E>>,
object_boxed: object_boxed::<ContextError<C, E>>, object_boxed: object_boxed::<ContextError<C, E>>,
object_downcast: context_downcast::<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>, 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. // Safety: passing vtable that operates on the right type.
@ -165,11 +186,15 @@ impl Error {
let vtable = &ErrorVTable { let vtable = &ErrorVTable {
object_drop: object_drop::<BoxedError>, object_drop: object_drop::<BoxedError>,
object_ref: object_ref::<BoxedError>, object_ref: object_ref::<BoxedError>,
#[cfg(feature = "std")] #[cfg(anyhow_no_ptr_addr_of)]
object_mut: object_mut::<BoxedError>, object_mut: object_mut::<BoxedError>,
object_boxed: object_boxed::<BoxedError>, object_boxed: object_boxed::<BoxedError>,
object_downcast: object_downcast::<Box<dyn StdError + Send + Sync>>, 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>>, 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 // Safety: BoxedError is repr(transparent) so it is okay for the vtable
@ -190,19 +215,18 @@ impl Error {
where where
E: StdError + Send + Sync + 'static, E: StdError + Send + Sync + 'static,
{ {
let inner = Box::new(ErrorImpl { let inner: Box<ErrorImpl<E>> = Box::new(ErrorImpl {
vtable, vtable,
backtrace, backtrace,
_object: error, _object: error,
}); });
// Erase the concrete type of E from the compile-time type system. This // Erase the concrete type of E from the compile-time type system. This
// is equivalent to the safe unsize coersion from Box<ErrorImpl<E>> to // is equivalent to the safe unsize coercion from Box<ErrorImpl<E>> to
// Box<ErrorImpl<dyn StdError + Send + Sync + 'static>> except that the // Box<ErrorImpl<dyn StdError + Send + Sync + 'static>> except that the
// result is a thin pointer. The necessary behavior for manipulating the // result is a thin pointer. The necessary behavior for manipulating the
// underlying ErrorImpl<E> is preserved in the vtable provided by the // underlying ErrorImpl<E> is preserved in the vtable provided by the
// caller rather than a builtin fat pointer vtable. // caller rather than a builtin fat pointer vtable.
let erased = mem::transmute::<Box<ErrorImpl<E>>, Box<ErrorImpl<()>>>(inner); let inner = Own::new(inner).cast::<ErrorImpl>();
let inner = ManuallyDrop::new(erased);
Error { inner } Error { inner }
} }
@ -272,11 +296,15 @@ impl Error {
let vtable = &ErrorVTable { let vtable = &ErrorVTable {
object_drop: object_drop::<ContextError<C, Error>>, object_drop: object_drop::<ContextError<C, Error>>,
object_ref: object_ref::<ContextError<C, Error>>, object_ref: object_ref::<ContextError<C, Error>>,
#[cfg(feature = "std")] #[cfg(all(feature = "std", anyhow_no_ptr_addr_of))]
object_mut: object_mut::<ContextError<C, Error>>, object_mut: object_mut::<ContextError<C, Error>>,
object_boxed: object_boxed::<ContextError<C, Error>>, object_boxed: object_boxed::<ContextError<C, Error>>,
object_downcast: context_chain_downcast::<C>, 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>, 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. // As the cause is anyhow::Error, we already have a backtrace for it.
@ -288,9 +316,6 @@ impl Error {
/// Get the backtrace for this Error. /// Get the backtrace for this Error.
/// ///
/// Backtraces are only available on the nightly channel. Tracking issue:
/// [rust-lang/rust#53487][tracking].
///
/// In order for the backtrace to be meaningful, one of the two environment /// 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 /// variables `RUST_LIB_BACKTRACE=1` or `RUST_BACKTRACE=1` must be defined
/// and `RUST_LIB_BACKTRACE` must not be `0`. Backtraces are somewhat /// and `RUST_LIB_BACKTRACE` must not be `0`. Backtraces are somewhat
@ -304,10 +329,25 @@ impl Error {
/// - If you want only panics to have backtraces, set `RUST_BACKTRACE=1` and /// - If you want only panics to have backtraces, set `RUST_BACKTRACE=1` and
/// `RUST_LIB_BACKTRACE=0`. /// `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 /// [tracking]: https://github.com/rust-lang/rust/issues/53487
#[cfg(backtrace)] #[cfg(any(backtrace, feature = "backtrace"))]
pub fn backtrace(&self) -> &Backtrace { #[cfg_attr(doc_cfg, doc(cfg(any(nightly, feature = "backtrace"))))]
self.inner.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. /// An iterator of the chain of source errors contained by this Error.
@ -332,8 +372,9 @@ impl Error {
/// } /// }
/// ``` /// ```
#[cfg(feature = "std")] #[cfg(feature = "std")]
#[cfg_attr(doc_cfg, doc(cfg(feature = "std")))]
pub fn chain(&self) -> Chain { pub fn chain(&self) -> Chain {
self.inner.chain() unsafe { ErrorImpl::chain(self.inner.by_ref()) }
} }
/// The lowest level cause of this error &mdash; this error's cause's /// The lowest level cause of this error &mdash; this error's cause's
@ -342,13 +383,9 @@ impl Error {
/// The root cause is the last error in the iterator produced by /// The root cause is the last error in the iterator produced by
/// [`chain()`][Error::chain]. /// [`chain()`][Error::chain].
#[cfg(feature = "std")] #[cfg(feature = "std")]
#[cfg_attr(doc_cfg, doc(cfg(feature = "std")))]
pub fn root_cause(&self) -> &(dyn StdError + 'static) { pub fn root_cause(&self) -> &(dyn StdError + 'static) {
let mut chain = self.chain(); self.chain().last().unwrap()
let mut root_cause = chain.next().unwrap();
for cause in chain {
root_cause = cause;
}
root_cause
} }
/// Returns true if `E` is the type held by this error object. /// Returns true if `E` is the type held by this error object.
@ -367,16 +404,23 @@ impl Error {
} }
/// Attempt to downcast the error object to a concrete type. /// Attempt to downcast the error object to a concrete type.
pub fn downcast<E>(self) -> Result<E, Self> pub fn downcast<E>(mut self) -> Result<E, Self>
where where
E: Display + Debug + Send + Sync + 'static, E: Display + Debug + Send + Sync + 'static,
{ {
let target = TypeId::of::<E>(); let target = TypeId::of::<E>();
let inner = self.inner.by_mut();
unsafe { unsafe {
// Use vtable to find NonNull<()> which points to a value of type E // Use vtable to find NonNull<()> which points to a value of type E
// somewhere inside the data structure. // somewhere inside the data structure.
let addr = match (self.inner.vtable.object_downcast)(&self.inner, target) { #[cfg(not(anyhow_no_ptr_addr_of))]
Some(addr) => addr, 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), None => return Err(self),
}; };
@ -385,15 +429,10 @@ impl Error {
let outer = ManuallyDrop::new(self); let outer = ManuallyDrop::new(self);
// Read E from where the vtable found it. // Read E from where the vtable found it.
let error = ptr::read(addr.cast::<E>().as_ptr()); let error = addr.cast::<E>().read();
// Read Box<ErrorImpl<()>> from self. Can't move it out because
// Error has a Drop impl which we want to not run.
let inner = ptr::read(&outer.inner);
let erased = ManuallyDrop::into_inner(inner);
// Drop rest of the data structure outside of E. // Drop rest of the data structure outside of E.
(erased.vtable.object_drop_rest)(erased, target); (vtable(outer.inner.ptr).object_drop_rest)(outer.inner, target);
Ok(error) Ok(error)
} }
@ -443,8 +482,8 @@ impl Error {
unsafe { unsafe {
// Use vtable to find NonNull<()> which points to a value of type E // Use vtable to find NonNull<()> which points to a value of type E
// somewhere inside the data structure. // somewhere inside the data structure.
let addr = (self.inner.vtable.object_downcast)(&self.inner, target)?; let addr = (vtable(self.inner.ptr).object_downcast)(self.inner.by_ref(), target)?;
Some(&*addr.cast::<E>().as_ptr()) Some(addr.cast::<E>().deref())
} }
} }
@ -457,13 +496,21 @@ impl Error {
unsafe { unsafe {
// Use vtable to find NonNull<()> which points to a value of type E // Use vtable to find NonNull<()> which points to a value of type E
// somewhere inside the data structure. // somewhere inside the data structure.
let addr = (self.inner.vtable.object_downcast)(&self.inner, target)?;
Some(&mut *addr.cast::<E>().as_ptr()) #[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(feature = "std")] #[cfg(feature = "std")]
#[cfg_attr(doc_cfg, doc(cfg(feature = "std")))]
impl<E> From<E> for Error impl<E> From<E> for Error
where where
E: StdError + Send + Sync + 'static, E: StdError + Send + Sync + 'static,
@ -475,133 +522,193 @@ where
} }
#[cfg(feature = "std")] #[cfg(feature = "std")]
#[cfg_attr(doc_cfg, doc(cfg(feature = "std")))]
impl Deref for Error { impl Deref for Error {
type Target = dyn StdError + Send + Sync + 'static; type Target = dyn StdError + Send + Sync + 'static;
fn deref(&self) -> &Self::Target { fn deref(&self) -> &Self::Target {
self.inner.error() unsafe { ErrorImpl::error(self.inner.by_ref()) }
} }
} }
#[cfg(feature = "std")] #[cfg(feature = "std")]
#[cfg_attr(doc_cfg, doc(cfg(feature = "std")))]
impl DerefMut for Error { impl DerefMut for Error {
fn deref_mut(&mut self) -> &mut Self::Target { fn deref_mut(&mut self) -> &mut Self::Target {
self.inner.error_mut() unsafe { ErrorImpl::error_mut(self.inner.by_mut()) }
} }
} }
impl Display for Error { impl Display for Error {
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
self.inner.display(formatter) unsafe { ErrorImpl::display(self.inner.by_ref(), formatter) }
} }
} }
impl Debug for Error { impl Debug for Error {
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
self.inner.debug(formatter) unsafe { ErrorImpl::debug(self.inner.by_ref(), formatter) }
} }
} }
impl Drop for Error { impl Drop for Error {
fn drop(&mut self) { fn drop(&mut self) {
unsafe { unsafe {
// Read Box<ErrorImpl<()>> from self.
let inner = ptr::read(&self.inner);
let erased = ManuallyDrop::into_inner(inner);
// Invoke the vtable's drop behavior. // Invoke the vtable's drop behavior.
(erased.vtable.object_drop)(erased); (vtable(self.inner.ptr).object_drop)(self.inner);
} }
} }
} }
struct ErrorVTable { struct ErrorVTable {
object_drop: unsafe fn(Box<ErrorImpl<()>>), object_drop: unsafe fn(Own<ErrorImpl>),
object_ref: unsafe fn(&ErrorImpl<()>) -> &(dyn StdError + Send + Sync + 'static), object_ref: unsafe fn(Ref<ErrorImpl>) -> Ref<dyn StdError + Send + Sync + 'static>,
#[cfg(feature = "std")] #[cfg(all(feature = "std", anyhow_no_ptr_addr_of))]
object_mut: unsafe fn(&mut ErrorImpl<()>) -> &mut (dyn StdError + Send + Sync + 'static), object_mut: unsafe fn(Mut<ErrorImpl>) -> &mut (dyn StdError + Send + Sync + 'static),
object_boxed: unsafe fn(Box<ErrorImpl<()>>) -> Box<dyn StdError + Send + Sync + 'static>, object_boxed: unsafe fn(Own<ErrorImpl>) -> Box<dyn StdError + Send + Sync + 'static>,
object_downcast: unsafe fn(&ErrorImpl<()>, TypeId) -> Option<NonNull<()>>, object_downcast: unsafe fn(Ref<ErrorImpl>, TypeId) -> Option<Ref<()>>,
object_drop_rest: unsafe fn(Box<ErrorImpl<()>>, TypeId), #[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>. // Safety: requires layout of *e to match ErrorImpl<E>.
unsafe fn object_drop<E>(e: Box<ErrorImpl<()>>) { unsafe fn object_drop<E>(e: Own<ErrorImpl>) {
// Cast back to ErrorImpl<E> so that the allocator receives the correct // Cast back to ErrorImpl<E> so that the allocator receives the correct
// Layout to deallocate the Box's memory. // Layout to deallocate the Box's memory.
let unerased = mem::transmute::<Box<ErrorImpl<()>>, Box<ErrorImpl<E>>>(e); let unerased = e.cast::<ErrorImpl<E>>().boxed();
drop(unerased); drop(unerased);
} }
// Safety: requires layout of *e to match ErrorImpl<E>. // Safety: requires layout of *e to match ErrorImpl<E>.
unsafe fn object_drop_front<E>(e: Box<ErrorImpl<()>>, target: TypeId) { 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, // 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 // without dropping E itself. This is used by downcast after doing a
// ptr::read to take ownership of the E. // ptr::read to take ownership of the E.
let _ = target; let _ = target;
let unerased = mem::transmute::<Box<ErrorImpl<()>>, Box<ErrorImpl<ManuallyDrop<E>>>>(e); let unerased = e.cast::<ErrorImpl<ManuallyDrop<E>>>().boxed();
drop(unerased); drop(unerased);
} }
// Safety: requires layout of *e to match ErrorImpl<E>. // Safety: requires layout of *e to match ErrorImpl<E>.
unsafe fn object_ref<E>(e: &ErrorImpl<()>) -> &(dyn StdError + Send + Sync + 'static) unsafe fn object_ref<E>(e: Ref<ErrorImpl>) -> Ref<dyn StdError + Send + Sync + 'static>
where where
E: StdError + Send + Sync + 'static, E: StdError + Send + Sync + 'static,
{ {
// Attach E's native StdError vtable onto a pointer to self._object. // Attach E's native StdError vtable onto a pointer to self._object.
&(*(e as *const ErrorImpl<()> as *const ErrorImpl<E>))._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>. // Safety: requires layout of *e to match ErrorImpl<E>, and for `e` to be derived
#[cfg(feature = "std")] // from a `&mut`
unsafe fn object_mut<E>(e: &mut ErrorImpl<()>) -> &mut (dyn StdError + Send + Sync + 'static) #[cfg(all(feature = "std", anyhow_no_ptr_addr_of))]
unsafe fn object_mut<E>(e: Mut<ErrorImpl>) -> &mut (dyn StdError + Send + Sync + 'static)
where where
E: StdError + Send + Sync + 'static, E: StdError + Send + Sync + 'static,
{ {
// Attach E's native StdError vtable onto a pointer to self._object. // Attach E's native StdError vtable onto a pointer to self._object.
&mut (*(e as *mut ErrorImpl<()> as *mut ErrorImpl<E>))._object &mut e.cast::<ErrorImpl<E>>().deref_mut()._object
} }
// Safety: requires layout of *e to match ErrorImpl<E>. // Safety: requires layout of *e to match ErrorImpl<E>.
unsafe fn object_boxed<E>(e: Box<ErrorImpl<()>>) -> Box<dyn StdError + Send + Sync + 'static> unsafe fn object_boxed<E>(e: Own<ErrorImpl>) -> Box<dyn StdError + Send + Sync + 'static>
where where
E: StdError + Send + Sync + 'static, E: StdError + Send + Sync + 'static,
{ {
// Attach ErrorImpl<E>'s native StdError vtable. The StdError impl is below. // Attach ErrorImpl<E>'s native StdError vtable. The StdError impl is below.
mem::transmute::<Box<ErrorImpl<()>>, Box<ErrorImpl<E>>>(e) e.cast::<ErrorImpl<E>>().boxed()
} }
// Safety: requires layout of *e to match ErrorImpl<E>. // Safety: requires layout of *e to match ErrorImpl<E>.
unsafe fn object_downcast<E>(e: &ErrorImpl<()>, target: TypeId) -> Option<NonNull<()>> unsafe fn object_downcast<E>(e: Ref<ErrorImpl>, target: TypeId) -> Option<Ref<()>>
where where
E: 'static, E: 'static,
{ {
if TypeId::of::<E>() == target { if TypeId::of::<E>() == target {
// Caller is looking for an E pointer and e is ErrorImpl<E>, take a // Caller is looking for an E pointer and e is ErrorImpl<E>, take a
// pointer to its E field. // pointer to its E field.
let unerased = e as *const ErrorImpl<()> as *const ErrorImpl<E>;
let addr = &(*unerased)._object as *const E as *mut (); let unerased = e.cast::<ErrorImpl<E>>();
Some(NonNull::new_unchecked(addr))
#[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 { } else {
None 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>>. // Safety: requires layout of *e to match ErrorImpl<ContextError<C, E>>.
#[cfg(feature = "std")] #[cfg(feature = "std")]
unsafe fn context_downcast<C, E>(e: &ErrorImpl<()>, target: TypeId) -> Option<NonNull<()>> unsafe fn context_downcast<C, E>(e: Ref<ErrorImpl>, target: TypeId) -> Option<Ref<()>>
where where
C: 'static, C: 'static,
E: 'static, E: 'static,
{ {
if TypeId::of::<C>() == target { if TypeId::of::<C>() == target {
let unerased = e as *const ErrorImpl<()> as *const ErrorImpl<ContextError<C, E>>; let unerased = e.cast::<ErrorImpl<ContextError<C, E>>>().deref();
let addr = &(*unerased)._object.context as *const C as *mut (); Some(Ref::new(&unerased._object.context).cast::<()>())
Some(NonNull::new_unchecked(addr))
} else if TypeId::of::<E>() == target { } else if TypeId::of::<E>() == target {
let unerased = e as *const ErrorImpl<()> as *const ErrorImpl<ContextError<C, E>>; let unerased = e.cast::<ErrorImpl<ContextError<C, E>>>().deref();
let addr = &(*unerased)._object.error as *const E as *mut (); Some(Ref::new(&unerased._object.error).cast::<()>())
Some(NonNull::new_unchecked(addr)) } 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 { } else {
None None
} }
@ -609,7 +716,7 @@ where
// Safety: requires layout of *e to match ErrorImpl<ContextError<C, E>>. // Safety: requires layout of *e to match ErrorImpl<ContextError<C, E>>.
#[cfg(feature = "std")] #[cfg(feature = "std")]
unsafe fn context_drop_rest<C, E>(e: Box<ErrorImpl<()>>, target: TypeId) unsafe fn context_drop_rest<C, E>(e: Own<ErrorImpl>, target: TypeId)
where where
C: 'static, C: 'static,
E: 'static, E: 'static,
@ -617,68 +724,92 @@ where
// Called after downcasting by value to either the C or the E and doing a // Called after downcasting by value to either the C or the E and doing a
// ptr::read to take ownership of that value. // ptr::read to take ownership of that value.
if TypeId::of::<C>() == target { if TypeId::of::<C>() == target {
let unerased = mem::transmute::< let unerased = e
Box<ErrorImpl<()>>, .cast::<ErrorImpl<ContextError<ManuallyDrop<C>, E>>>()
Box<ErrorImpl<ContextError<ManuallyDrop<C>, E>>>, .boxed();
>(e);
drop(unerased); drop(unerased);
} else { } else {
let unerased = mem::transmute::< let unerased = e
Box<ErrorImpl<()>>, .cast::<ErrorImpl<ContextError<C, ManuallyDrop<E>>>>()
Box<ErrorImpl<ContextError<C, ManuallyDrop<E>>>>, .boxed();
>(e);
drop(unerased); drop(unerased);
} }
} }
// Safety: requires layout of *e to match ErrorImpl<ContextError<C, Error>>. // Safety: requires layout of *e to match ErrorImpl<ContextError<C, Error>>.
unsafe fn context_chain_downcast<C>(e: &ErrorImpl<()>, target: TypeId) -> Option<NonNull<()>> unsafe fn context_chain_downcast<C>(e: Ref<ErrorImpl>, target: TypeId) -> Option<Ref<()>>
where where
C: 'static, C: 'static,
{ {
let unerased = e.cast::<ErrorImpl<ContextError<C, Error>>>().deref();
if TypeId::of::<C>() == target { if TypeId::of::<C>() == target {
let unerased = e as *const ErrorImpl<()> as *const ErrorImpl<ContextError<C, Error>>; Some(Ref::new(&unerased._object.context).cast::<()>())
let addr = &(*unerased)._object.context as *const C as *mut ();
Some(NonNull::new_unchecked(addr))
} else { } else {
// Recurse down the context chain per the inner error's vtable. // Recurse down the context chain per the inner error's vtable.
let unerased = e as *const ErrorImpl<()> as *const ErrorImpl<ContextError<C, Error>>; let source = &unerased._object.error;
let source = &(*unerased)._object.error; (vtable(source.inner.ptr).object_downcast)(source.inner.by_ref(), target)
(source.inner.vtable.object_downcast)(&source.inner, target)
} }
} }
// Safety: requires layout of *e to match ErrorImpl<ContextError<C, Error>>. // Safety: requires layout of *e to match ErrorImpl<ContextError<C, Error>>.
unsafe fn context_chain_drop_rest<C>(e: Box<ErrorImpl<()>>, target: TypeId) #[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 where
C: 'static, C: 'static,
{ {
// Called after downcasting by value to either the C or one of the causes // 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. // and doing a ptr::read to take ownership of that value.
if TypeId::of::<C>() == target { if TypeId::of::<C>() == target {
let unerased = mem::transmute::< let unerased = e
Box<ErrorImpl<()>>, .cast::<ErrorImpl<ContextError<ManuallyDrop<C>, Error>>>()
Box<ErrorImpl<ContextError<ManuallyDrop<C>, Error>>>, .boxed();
>(e);
// Drop the entire rest of the data structure rooted in the next Error. // Drop the entire rest of the data structure rooted in the next Error.
drop(unerased); drop(unerased);
} else { } else {
let unerased = mem::transmute::< let unerased = e
Box<ErrorImpl<()>>, .cast::<ErrorImpl<ContextError<C, ManuallyDrop<Error>>>>()
Box<ErrorImpl<ContextError<C, ManuallyDrop<Error>>>>, .boxed();
>(e); // Read the Own<ErrorImpl> from the next error.
// Read out a ManuallyDrop<Box<ErrorImpl<()>>> from the next error. let inner = unerased._object.error.inner;
let inner = ptr::read(&unerased._object.error.inner);
drop(unerased); drop(unerased);
let erased = ManuallyDrop::into_inner(inner); let vtable = vtable(inner.ptr);
// Recursively drop the next error using the same target typeid. // Recursively drop the next error using the same target typeid.
(erased.vtable.object_drop_rest)(erased, target); (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 to ensure that E remains in the final position.
#[repr(C)] #[repr(C)]
pub(crate) struct ErrorImpl<E> { pub(crate) struct ErrorImpl<E = ()> {
vtable: &'static ErrorVTable, vtable: &'static ErrorVTable,
backtrace: Option<Backtrace>, backtrace: Option<Backtrace>,
// NOTE: Don't use directly. Use only through vtable. Erased type may have // NOTE: Don't use directly. Use only through vtable. Erased type may have
@ -686,6 +817,13 @@ pub(crate) struct ErrorImpl<E> {
_object: E, _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 // repr C to ensure that ContextError<C, E> has the same layout as
// ContextError<ManuallyDrop<C>, E> and ContextError<C, ManuallyDrop<E>>. // ContextError<ManuallyDrop<C>, E> and ContextError<C, ManuallyDrop<E>>.
#[repr(C)] #[repr(C)]
@ -695,41 +833,54 @@ pub(crate) struct ContextError<C, E> {
} }
impl<E> ErrorImpl<E> { impl<E> ErrorImpl<E> {
fn erase(&self) -> &ErrorImpl<()> { fn erase(&self) -> Ref<ErrorImpl> {
// Erase the concrete type of E but preserve the vtable in self.vtable // Erase the concrete type of E but preserve the vtable in self.vtable
// for manipulating the resulting thin pointer. This is analogous to an // for manipulating the resulting thin pointer. This is analogous to an
// unsize coersion. // unsize coercion.
unsafe { &*(self as *const ErrorImpl<E> as *const ErrorImpl<()>) } Ref::new(self).cast::<ErrorImpl>()
} }
} }
impl ErrorImpl<()> { impl ErrorImpl {
pub(crate) fn error(&self) -> &(dyn StdError + Send + Sync + 'static) { 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 // Use vtable to attach E's native StdError vtable for the right
// original type E. // original type E.
unsafe { &*(self.vtable.object_ref)(self) } (vtable(this.ptr).object_ref)(this).deref()
} }
#[cfg(feature = "std")] #[cfg(feature = "std")]
pub(crate) fn error_mut(&mut self) -> &mut (dyn StdError + Send + Sync + 'static) { 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 // Use vtable to attach E's native StdError vtable for the right
// original type E. // original type E.
unsafe { &mut *(self.vtable.object_mut)(self) }
#[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(backtrace)] #[cfg(any(backtrace, feature = "backtrace"))]
pub(crate) fn backtrace(&self) -> &Backtrace { pub(crate) unsafe fn backtrace(this: Ref<Self>) -> &Backtrace {
// This unwrap can only panic if the underlying error's backtrace method // This unwrap can only panic if the underlying error's backtrace method
// is nondeterministic, which would only happen in maliciously // is nondeterministic, which would only happen in maliciously
// constructed code. // constructed code.
self.backtrace this.deref()
.backtrace
.as_ref() .as_ref()
.or_else(|| self.error().backtrace()) .or_else(|| {
#[cfg(backtrace)]
return Self::error(this).backtrace();
#[cfg(all(not(backtrace), feature = "backtrace"))]
return (vtable(this.ptr).object_backtrace)(this);
})
.expect("backtrace capture failed") .expect("backtrace capture failed")
} }
pub(crate) fn chain(&self) -> Chain { pub(crate) unsafe fn chain(this: Ref<Self>) -> Chain {
Chain::new(self.error()) Chain::new(Self::error(this))
} }
} }
@ -739,11 +890,11 @@ where
{ {
#[cfg(backtrace)] #[cfg(backtrace)]
fn backtrace(&self) -> Option<&Backtrace> { fn backtrace(&self) -> Option<&Backtrace> {
Some(self.erase().backtrace()) Some(unsafe { ErrorImpl::backtrace(self.erase()) })
} }
fn source(&self) -> Option<&(dyn StdError + 'static)> { fn source(&self) -> Option<&(dyn StdError + 'static)> {
self.erase().error().source() unsafe { ErrorImpl::error(self.erase()).source() }
} }
} }
@ -752,7 +903,7 @@ where
E: Debug, E: Debug,
{ {
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
self.erase().debug(formatter) unsafe { ErrorImpl::debug(self.erase(), formatter) }
} }
} }
@ -761,7 +912,7 @@ where
E: Display, E: Display,
{ {
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
Display::fmt(&self.erase().error(), formatter) unsafe { Display::fmt(ErrorImpl::error(self.erase()), formatter) }
} }
} }
@ -769,18 +920,19 @@ impl From<Error> for Box<dyn StdError + Send + Sync + 'static> {
fn from(error: Error) -> Self { fn from(error: Error) -> Self {
let outer = ManuallyDrop::new(error); let outer = ManuallyDrop::new(error);
unsafe { unsafe {
// Read Box<ErrorImpl<()>> from error. Can't move it out because
// Error has a Drop impl which we want to not run.
let inner = ptr::read(&outer.inner);
let erased = ManuallyDrop::into_inner(inner);
// Use vtable to attach ErrorImpl<E>'s native StdError vtable for // Use vtable to attach ErrorImpl<E>'s native StdError vtable for
// the right original type E. // the right original type E.
(erased.vtable.object_boxed)(erased) (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> { impl From<Error> for Box<dyn StdError + 'static> {
fn from(error: Error) -> Self { fn from(error: Error) -> Self {
Box::<dyn StdError + Send + Sync>::from(error) Box::<dyn StdError + Send + Sync>::from(error)

26
third_party/rust/anyhow/src/fmt.rs поставляемый
Просмотреть файл

@ -1,13 +1,14 @@
use crate::chain::Chain; use crate::chain::Chain;
use crate::error::ErrorImpl; use crate::error::ErrorImpl;
use crate::ptr::Ref;
use core::fmt::{self, Debug, Write}; use core::fmt::{self, Debug, Write};
impl ErrorImpl<()> { impl ErrorImpl {
pub(crate) fn display(&self, f: &mut fmt::Formatter) -> fmt::Result { pub(crate) unsafe fn display(this: Ref<Self>, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}", self.error())?; write!(f, "{}", Self::error(this))?;
if f.alternate() { if f.alternate() {
for cause in self.chain().skip(1) { for cause in Self::chain(this).skip(1) {
write!(f, ": {}", cause)?; write!(f, ": {}", cause)?;
} }
} }
@ -15,8 +16,8 @@ impl ErrorImpl<()> {
Ok(()) Ok(())
} }
pub(crate) fn debug(&self, f: &mut fmt::Formatter) -> fmt::Result { pub(crate) unsafe fn debug(this: Ref<Self>, f: &mut fmt::Formatter) -> fmt::Result {
let error = self.error(); let error = Self::error(this);
if f.alternate() { if f.alternate() {
return Debug::fmt(error, f); return Debug::fmt(error, f);
@ -38,19 +39,24 @@ impl ErrorImpl<()> {
} }
} }
#[cfg(backtrace)] #[cfg(any(backtrace, feature = "backtrace"))]
{ {
use std::backtrace::BacktraceStatus; use crate::backtrace::BacktraceStatus;
let backtrace = self.backtrace(); let backtrace = Self::backtrace(this);
if let BacktraceStatus::Captured = backtrace.status() { if let BacktraceStatus::Captured = backtrace.status() {
let mut backtrace = backtrace.to_string(); let mut backtrace = backtrace.to_string();
write!(f, "\n\n")?;
if backtrace.starts_with("stack backtrace:") { if backtrace.starts_with("stack backtrace:") {
// Capitalize to match "Caused by:" // Capitalize to match "Caused by:"
backtrace.replace_range(0..1, "S"); 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()); backtrace.truncate(backtrace.trim_end().len());
write!(f, "\n\n{}", backtrace)?; write!(f, "{}", backtrace)?;
} }
} }

3
third_party/rust/anyhow/src/kind.rs поставляемый
Просмотреть файл

@ -50,9 +50,6 @@ use core::fmt::{Debug, Display};
#[cfg(feature = "std")] #[cfg(feature = "std")]
use crate::StdError; use crate::StdError;
#[cfg(backtrace)]
use std::backtrace::Backtrace;
pub struct Adhoc; pub struct Adhoc;
pub trait AdhocKind: Sized { pub trait AdhocKind: Sized {

68
third_party/rust/anyhow/src/lib.rs поставляемый
Просмотреть файл

@ -179,6 +179,18 @@
//! # } //! # }
//! ``` //! ```
//! //!
//! 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> //! <br>
//! //!
//! # No-std support //! # No-std support
@ -197,13 +209,24 @@
//! will require an explicit `.map_err(Error::msg)` when working with a //! 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. //! non-Anyhow error type inside a function that returns Anyhow's error type.
#![doc(html_root_url = "https://docs.rs/anyhow/1.0.30")] #![doc(html_root_url = "https://docs.rs/anyhow/1.0.41")]
#![cfg_attr(backtrace, feature(backtrace))] #![cfg_attr(backtrace, feature(backtrace))]
#![cfg_attr(doc_cfg, feature(doc_cfg))] #![cfg_attr(doc_cfg, feature(doc_cfg))]
#![cfg_attr(not(feature = "std"), no_std)] #![cfg_attr(not(feature = "std"), no_std)]
#![deny(dead_code, unused_imports, unused_mut)]
#![allow( #![allow(
clippy::doc_markdown,
clippy::enum_glob_use,
clippy::missing_errors_doc,
clippy::missing_panics_doc,
clippy::module_name_repetitions,
clippy::must_use_candidate,
clippy::needless_doctest_main, clippy::needless_doctest_main,
clippy::new_ret_no_self, clippy::new_ret_no_self,
clippy::redundant_else,
clippy::unused_self,
clippy::used_underscore_binding,
clippy::wildcard_imports,
clippy::wrong_self_convention clippy::wrong_self_convention
)] )]
@ -226,12 +249,12 @@ mod error;
mod fmt; mod fmt;
mod kind; mod kind;
mod macros; mod macros;
mod ptr;
mod wrapper; mod wrapper;
use crate::alloc::Box;
use crate::error::ErrorImpl; use crate::error::ErrorImpl;
use crate::ptr::Own;
use core::fmt::Display; use core::fmt::Display;
use core::mem::ManuallyDrop;
#[cfg(not(feature = "std"))] #[cfg(not(feature = "std"))]
use core::fmt::Debug; use core::fmt::Debug;
@ -288,6 +311,15 @@ pub use anyhow as format_err;
/// ///
/// Caused by: /// Caused by:
/// No such file or directory (os error 2) /// 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: /// Stack backtrace:
/// 0: <E as anyhow::context::ext::StdError>::ext_context /// 0: <E as anyhow::context::ext::StdError>::ext_context
@ -340,8 +372,9 @@ pub use anyhow as format_err;
/// # Ok(()) /// # Ok(())
/// } /// }
/// ``` /// ```
#[repr(transparent)]
pub struct Error { pub struct Error {
inner: ManuallyDrop<Box<ErrorImpl<()>>>, inner: Own<ErrorImpl>,
} }
/// Iterator of a chain of source errors. /// Iterator of a chain of source errors.
@ -364,6 +397,7 @@ pub struct Error {
/// } /// }
/// ``` /// ```
#[cfg(feature = "std")] #[cfg(feature = "std")]
#[cfg_attr(doc_cfg, doc(cfg(feature = "std")))]
#[derive(Clone)] #[derive(Clone)]
pub struct Chain<'a> { pub struct Chain<'a> {
state: crate::chain::ChainState<'a>, state: crate::chain::ChainState<'a>,
@ -581,9 +615,6 @@ pub mod private {
use crate::Error; use crate::Error;
use core::fmt::{Debug, Display}; use core::fmt::{Debug, Display};
#[cfg(backtrace)]
use std::backtrace::Backtrace;
pub use core::result::Result::Err; pub use core::result::Result::Err;
#[doc(hidden)] #[doc(hidden)]
@ -600,4 +631,27 @@ pub mod private {
{ {
Error::from_adhoc(message, backtrace!()) Error::from_adhoc(message, backtrace!())
} }
#[cfg(anyhow_no_macro_reexport)]
pub use crate::{__anyhow_concat as concat, __anyhow_stringify as stringify};
#[cfg(not(anyhow_no_macro_reexport))]
pub use core::{concat, stringify};
#[cfg(anyhow_no_macro_reexport)]
#[doc(hidden)]
#[macro_export]
macro_rules! __anyhow_concat {
($($tt:tt)*) => {
concat!($($tt)*)
};
}
#[cfg(anyhow_no_macro_reexport)]
#[doc(hidden)]
#[macro_export]
macro_rules! __anyhow_stringify {
($($tt:tt)*) => {
stringify!($($tt)*)
};
}
} }

42
third_party/rust/anyhow/src/macros.rs поставляемый
Просмотреть файл

@ -1,6 +1,9 @@
/// Return early with an error. /// Return early with an error.
/// ///
/// This macro is equivalent to `return Err(From::from($err))`. /// 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]`>`.
/// ///
/// # Example /// # Example
/// ///
@ -50,19 +53,23 @@
#[macro_export] #[macro_export]
macro_rules! bail { macro_rules! bail {
($msg:literal $(,)?) => { ($msg:literal $(,)?) => {
return $crate::private::Err($crate::anyhow!($msg)); return $crate::private::Err($crate::anyhow!($msg))
}; };
($err:expr $(,)?) => { ($err:expr $(,)?) => {
return $crate::private::Err($crate::anyhow!($err)); return $crate::private::Err($crate::anyhow!($err))
}; };
($fmt:expr, $($arg:tt)*) => { ($fmt:expr, $($arg:tt)*) => {
return $crate::private::Err($crate::anyhow!($fmt, $($arg)*)); return $crate::private::Err($crate::anyhow!($fmt, $($arg)*))
}; };
} }
/// Return early with an error if a condition is not satisfied. /// Return early with an error if a condition is not satisfied.
/// ///
/// This macro is equivalent to `if !$cond { return Err(From::from($err)); }`. /// 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 /// Analogously to `assert!`, `ensure!` takes a condition and exits the function
/// if the condition fails. Unlike `assert!`, `ensure!` returns an `Error` /// if the condition fails. Unlike `assert!`, `ensure!` returns an `Error`
@ -106,6 +113,12 @@ macro_rules! bail {
/// ``` /// ```
#[macro_export] #[macro_export]
macro_rules! ensure { macro_rules! ensure {
($cond:expr $(,)?) => {
$crate::ensure!(
$cond,
$crate::private::concat!("Condition failed: `", $crate::private::stringify!($cond), "`"),
)
};
($cond:expr, $msg:literal $(,)?) => { ($cond:expr, $msg:literal $(,)?) => {
if !$cond { if !$cond {
return $crate::private::Err($crate::anyhow!($msg)); return $crate::private::Err($crate::anyhow!($msg));
@ -123,11 +136,17 @@ macro_rules! ensure {
}; };
} }
/// Construct an ad-hoc error from a string. /// Construct an ad-hoc error from a string or existing non-`anyhow` error
/// value.
/// ///
/// This evaluates to an `Error`. It can take either just a string, or a format /// This evaluates to an [`Error`][crate::Error]. It can take either just a
/// string with arguments. It also can take any custom type which implements /// string, or a format string with arguments. It also can take any custom type
/// `Debug` and `Display`. /// 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 /// # Example
/// ///
@ -154,8 +173,9 @@ macro_rules! anyhow {
}; };
($err:expr $(,)?) => ({ ($err:expr $(,)?) => ({
use $crate::private::kind::*; use $crate::private::kind::*;
let error = $err; match $err {
(&error).anyhow_kind().new(error) error => (&error).anyhow_kind().new(error),
}
}); });
($fmt:expr, $($arg:tt)*) => { ($fmt:expr, $($arg:tt)*) => {
$crate::private::new_adhoc(format!($fmt, $($arg)*)) $crate::private::new_adhoc(format!($fmt, $($arg)*))

199
third_party/rust/anyhow/src/ptr.rs поставляемый Normal file
Просмотреть файл

@ -0,0 +1,199 @@
use crate::alloc::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;
}

Просмотреть файл

@ -1,4 +1,5 @@
#[rustversion::attr(not(nightly), ignore)] #[rustversion::attr(not(nightly), ignore)]
#[cfg_attr(miri, ignore)]
#[test] #[test]
fn ui() { fn ui() {
let t = trybuild::TestCases::new(); let t = trybuild::TestCases::new();

2
third_party/rust/anyhow/tests/drop/mod.rs поставляемый
Просмотреть файл

@ -1,3 +1,5 @@
#![allow(clippy::module_name_repetitions)]
use std::error::Error as StdError; use std::error::Error as StdError;
use std::fmt::{self, Display}; use std::fmt::{self, Display};
use std::sync::atomic::AtomicBool; use std::sync::atomic::AtomicBool;

Просмотреть файл

@ -1,3 +1,5 @@
#![allow(clippy::unnecessary_wraps)]
mod drop; mod drop;
use self::drop::{DetectDrop, Flag}; use self::drop::{DetectDrop, Flag};

Просмотреть файл

@ -1,3 +1,5 @@
#![allow(clippy::wildcard_imports)]
mod common; mod common;
mod drop; mod drop;
@ -66,6 +68,12 @@ fn test_downcast_mut() {
.unwrap() .unwrap()
.to_string(), .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] #[test]

18
third_party/rust/anyhow/tests/test_ffi.rs поставляемый 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"))
}

11
third_party/rust/anyhow/tests/test_macros.rs поставляемый
Просмотреть файл

@ -1,3 +1,5 @@
#![allow(clippy::eq_op, clippy::shadow_unrelated, clippy::wildcard_imports)]
mod common; mod common;
use self::common::*; use self::common::*;
@ -30,4 +32,13 @@ fn test_ensure() {
Ok(()) Ok(())
}; };
assert!(f().is_err()); assert!(f().is_err());
let f = || {
ensure!(v + v == 1);
Ok(())
};
assert_eq!(
f().unwrap_err().to_string(),
"Condition failed: `v + v == 1`",
);
} }

Просмотреть файл

@ -1,21 +1,21 @@
error[E0599]: no method named `anyhow_kind` found for reference `&Error` in the current scope error[E0599]: the method `anyhow_kind` exists for reference `&Error`, but its trait bounds were not satisfied
--> $DIR/no-impl.rs:7:13 --> $DIR/no-impl.rs:7:13
| |
4 | struct Error; 4 | struct Error;
| ------------- | -------------
| | | |
| doesn't satisfy `Error: anyhow::kind::TraitKind` | doesn't satisfy `Error: Into<anyhow::Error>`
| doesn't satisfy `Error: std::convert::Into<anyhow::Error>` | doesn't satisfy `Error: anyhow::private::kind::TraitKind`
| doesn't satisfy `Error: std::fmt::Display` | doesn't satisfy `Error: std::fmt::Display`
... ...
7 | let _ = anyhow!(Error); 7 | let _ = anyhow!(Error);
| ^^^^^^^^^^^^^^ method not found in `&Error` | ^^^^^^^^^^^^^^ method cannot be called on `&Error` due to unsatisfied trait bounds
| |
= note: the method `anyhow_kind` exists but the following trait bounds were not satisfied: = note: the following trait bounds were not satisfied:
`Error: std::convert::Into<anyhow::Error>` `Error: Into<anyhow::Error>`
which is required by `Error: anyhow::kind::TraitKind` which is required by `Error: anyhow::private::kind::TraitKind`
`Error: std::fmt::Display` `Error: std::fmt::Display`
which is required by `&Error: anyhow::kind::AdhocKind` which is required by `&Error: anyhow::private::kind::AdhocKind`
`&Error: std::convert::Into<anyhow::Error>` `&Error: Into<anyhow::Error>`
which is required by `&Error: anyhow::kind::TraitKind` which is required by `&Error: anyhow::private::kind::TraitKind`
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) = note: this error originates in the macro `anyhow` (in Nightly builds, run with -Z macro-backtrace for more info)

5
third_party/rust/anyhow/tests/ui/temporary-value.rs поставляемый Normal file
Просмотреть файл

@ -0,0 +1,5 @@
use anyhow::anyhow;
fn main() {
let _ = anyhow!(&String::new());
}

8
third_party/rust/anyhow/tests/ui/temporary-value.stderr поставляемый Normal file
Просмотреть файл

@ -0,0 +1,8 @@
error[E0716]: temporary value dropped while borrowed
--> $DIR/temporary-value.rs:4:22
|
4 | let _ = anyhow!(&String::new());
| ---------^^^^^^^^^^^^^-- temporary value is freed at the end of this statement
| | |
| | creates a temporary which is freed while still in use
| argument requires that borrow lasts for `'static`