aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2024-02-02 23:51:52 +0000
committerAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2024-02-02 23:51:52 +0000
commit63eb178fd7baf881e66e16a4965ee9bc157b42db (patch)
tree6472acf7b15f35c854c3abadd3c1d16db4a77773
parent38abe5f4e6cc71f2733d48fb8fe8171dce200c55 (diff)
parent5891f6a953b29e9786c84ced4b4ca7204a583bd1 (diff)
downloadanyhow-simpleperf-release.tar.gz
Snap for 11400057 from 5891f6a953b29e9786c84ced4b4ca7204a583bd1 to simpleperf-releasesimpleperf-release
Change-Id: Ica69082948a1aa504ce4b9d866cefeece13ed653
-rw-r--r--.cargo_vcs_info.json2
-rw-r--r--.clippy.toml1
-rw-r--r--.github/FUNDING.yml1
-rw-r--r--.github/workflows/ci.yml50
-rw-r--r--Android.bp24
-rw-r--r--Cargo.toml9
-rw-r--r--Cargo.toml.orig12
-rw-r--r--METADATA25
-rw-r--r--README.md11
-rw-r--r--build.rs154
-rw-r--r--build/probe.rs35
-rw-r--r--patches/0001-Support-RUST_BACKTRACE-settings-in-test_fmt.patch10
-rw-r--r--src/backtrace.rs28
-rw-r--r--src/context.rs16
-rw-r--r--src/ensure.rs5
-rw-r--r--src/error.rs212
-rw-r--r--src/fmt.rs11
-rw-r--r--src/kind.rs3
-rw-r--r--src/lib.rs38
-rw-r--r--src/ptr.rs8
-rw-r--r--src/wrapper.rs10
-rw-r--r--tests/test_autotrait.rs2
-rw-r--r--tests/test_backtrace.rs2
-rw-r--r--tests/test_ensure.rs4
-rw-r--r--tests/test_fmt.rs2
-rw-r--r--tests/test_repr.rs2
26 files changed, 428 insertions, 249 deletions
diff --git a/.cargo_vcs_info.json b/.cargo_vcs_info.json
index 4958ce0..b74022b 100644
--- a/.cargo_vcs_info.json
+++ b/.cargo_vcs_info.json
@@ -1,6 +1,6 @@
{
"git": {
- "sha1": "58377abfea67601caf6a7051de082484717fe79f"
+ "sha1": "71ab53dd2e89ff816bebaa452ad5a968f4c4105d"
},
"path_in_vcs": ""
} \ No newline at end of file
diff --git a/.clippy.toml b/.clippy.toml
deleted file mode 100644
index 78eb145..0000000
--- a/.clippy.toml
+++ /dev/null
@@ -1 +0,0 @@
-msrv = "1.38.0"
diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml
new file mode 100644
index 0000000..7507077
--- /dev/null
+++ b/.github/FUNDING.yml
@@ -0,0 +1 @@
+github: dtolnay
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 198a836..017ddbd 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -3,6 +3,7 @@ name: CI
on:
push:
pull_request:
+ workflow_dispatch:
schedule: [cron: "40 1 * * *"]
permissions:
@@ -23,14 +24,20 @@ jobs:
strategy:
fail-fast: false
matrix:
- rust: [nightly, beta, stable, 1.60.0]
+ rust: [nightly, beta, stable, 1.65.0]
timeout-minutes: 45
steps:
- - uses: actions/checkout@v3
+ - uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@master
with:
toolchain: ${{matrix.rust}}
components: rust-src
+ - name: Enable type layout randomization
+ run: echo RUSTFLAGS=${RUSTFLAGS}\ -Zrandomize-layout >> $GITHUB_ENV
+ if: matrix.rust == 'nightly'
+ - name: Enable nightly-only tests
+ run: echo RUSTFLAGS=${RUSTFLAGS}\ --cfg=anyhow_nightly_testing >> $GITHUB_ENV
+ if: matrix.rust == 'nightly'
- run: cargo test
- run: cargo check --no-default-features
- run: cargo check --features backtrace
@@ -46,7 +53,7 @@ jobs:
rust: [1.52.0, 1.51.0, 1.50.0, 1.42.0, 1.39.0]
timeout-minutes: 45
steps:
- - uses: actions/checkout@v3
+ - uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@master
with:
toolchain: ${{matrix.rust}}
@@ -54,6 +61,18 @@ jobs:
- run: cargo check
- run: cargo check --no-default-features
+ minimal:
+ name: Minimal versions
+ needs: pre_ci
+ if: needs.pre_ci.outputs.continue
+ runs-on: ubuntu-latest
+ timeout-minutes: 45
+ steps:
+ - uses: actions/checkout@v4
+ - uses: dtolnay/rust-toolchain@nightly
+ - run: cargo generate-lockfile -Z minimal-versions
+ - run: cargo check --locked --features backtrace
+
windows:
name: Windows
needs: pre_ci
@@ -61,19 +80,35 @@ jobs:
runs-on: windows-latest
timeout-minutes: 45
steps:
- - uses: actions/checkout@v3
+ - uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@stable
with:
components: rust-src
- run: cargo check --features backtrace
+ doc:
+ name: Documentation
+ needs: pre_ci
+ if: needs.pre_ci.outputs.continue
+ runs-on: ubuntu-latest
+ timeout-minutes: 45
+ env:
+ RUSTDOCFLAGS: -Dwarnings
+ steps:
+ - uses: actions/checkout@v4
+ - uses: dtolnay/rust-toolchain@nightly
+ with:
+ components: rust-src
+ - uses: dtolnay/install@cargo-docs-rs
+ - run: cargo docs-rs
+
clippy:
name: Clippy
runs-on: ubuntu-latest
if: github.event_name != 'pull_request'
timeout-minutes: 45
steps:
- - uses: actions/checkout@v3
+ - uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@nightly
with:
components: clippy, rust-src
@@ -86,8 +121,9 @@ jobs:
runs-on: ubuntu-latest
timeout-minutes: 45
steps:
- - uses: actions/checkout@v3
+ - uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@miri
+ - run: cargo miri setup
- run: cargo miri test
env:
MIRIFLAGS: -Zmiri-strict-provenance
@@ -98,6 +134,6 @@ jobs:
if: github.event_name != 'pull_request'
timeout-minutes: 45
steps:
- - uses: actions/checkout@v3
+ - uses: actions/checkout@v4
- uses: dtolnay/install@cargo-outdated
- run: cargo outdated --workspace --exit-code 1
diff --git a/Android.bp b/Android.bp
index 613a9c6..f512722 100644
--- a/Android.bp
+++ b/Android.bp
@@ -42,7 +42,7 @@ rust_test {
host_supported: true,
crate_name: "anyhow",
cargo_env_compat: true,
- cargo_pkg_version: "1.0.69",
+ cargo_pkg_version: "1.0.79",
srcs: ["src/lib.rs"],
test_suites: ["general-tests"],
auto_gen_config: true,
@@ -65,7 +65,7 @@ rust_test {
host_supported: true,
crate_name: "test_autotrait",
cargo_env_compat: true,
- cargo_pkg_version: "1.0.69",
+ cargo_pkg_version: "1.0.79",
srcs: ["tests/test_autotrait.rs"],
test_suites: ["general-tests"],
auto_gen_config: true,
@@ -89,7 +89,7 @@ rust_test {
host_supported: true,
crate_name: "test_boxed",
cargo_env_compat: true,
- cargo_pkg_version: "1.0.69",
+ cargo_pkg_version: "1.0.79",
srcs: ["tests/test_boxed.rs"],
test_suites: ["general-tests"],
auto_gen_config: true,
@@ -113,7 +113,7 @@ rust_test {
host_supported: true,
crate_name: "test_chain",
cargo_env_compat: true,
- cargo_pkg_version: "1.0.69",
+ cargo_pkg_version: "1.0.79",
srcs: ["tests/test_chain.rs"],
test_suites: ["general-tests"],
auto_gen_config: true,
@@ -137,7 +137,7 @@ rust_test {
host_supported: true,
crate_name: "test_context",
cargo_env_compat: true,
- cargo_pkg_version: "1.0.69",
+ cargo_pkg_version: "1.0.79",
srcs: ["tests/test_context.rs"],
test_suites: ["general-tests"],
auto_gen_config: true,
@@ -161,7 +161,7 @@ rust_test {
host_supported: true,
crate_name: "test_convert",
cargo_env_compat: true,
- cargo_pkg_version: "1.0.69",
+ cargo_pkg_version: "1.0.79",
srcs: ["tests/test_convert.rs"],
test_suites: ["general-tests"],
auto_gen_config: true,
@@ -185,7 +185,7 @@ rust_test {
host_supported: true,
crate_name: "test_downcast",
cargo_env_compat: true,
- cargo_pkg_version: "1.0.69",
+ cargo_pkg_version: "1.0.79",
srcs: ["tests/test_downcast.rs"],
test_suites: ["general-tests"],
auto_gen_config: true,
@@ -209,7 +209,7 @@ rust_test {
host_supported: true,
crate_name: "test_fmt",
cargo_env_compat: true,
- cargo_pkg_version: "1.0.69",
+ cargo_pkg_version: "1.0.79",
srcs: ["tests/test_fmt.rs"],
test_suites: ["general-tests"],
auto_gen_config: true,
@@ -233,7 +233,7 @@ rust_test {
host_supported: true,
crate_name: "test_macros",
cargo_env_compat: true,
- cargo_pkg_version: "1.0.69",
+ cargo_pkg_version: "1.0.79",
srcs: ["tests/test_macros.rs"],
test_suites: ["general-tests"],
auto_gen_config: true,
@@ -257,7 +257,7 @@ rust_test {
host_supported: true,
crate_name: "test_repr",
cargo_env_compat: true,
- cargo_pkg_version: "1.0.69",
+ cargo_pkg_version: "1.0.79",
srcs: ["tests/test_repr.rs"],
test_suites: ["general-tests"],
auto_gen_config: true,
@@ -281,7 +281,7 @@ rust_test {
host_supported: true,
crate_name: "test_source",
cargo_env_compat: true,
- cargo_pkg_version: "1.0.69",
+ cargo_pkg_version: "1.0.79",
srcs: ["tests/test_source.rs"],
test_suites: ["general-tests"],
auto_gen_config: true,
@@ -305,7 +305,7 @@ rust_library {
host_supported: true,
crate_name: "anyhow",
cargo_env_compat: true,
- cargo_pkg_version: "1.0.69",
+ cargo_pkg_version: "1.0.79",
srcs: ["src/lib.rs"],
edition: "2018",
features: [
diff --git a/Cargo.toml b/Cargo.toml
index d42c470..b92e7a3 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -13,7 +13,7 @@
edition = "2018"
rust-version = "1.39"
name = "anyhow"
-version = "1.0.69"
+version = "1.0.79"
authors = ["David Tolnay <dtolnay@gmail.com>"]
description = "Flexible concrete Error type built on std::error::Error"
documentation = "https://docs.rs/anyhow"
@@ -30,11 +30,12 @@ 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",
+ "--generate-link-to-definition",
]
+targets = ["x86_64-unknown-linux-gnu"]
[lib]
doc-scrape-examples = false
@@ -51,11 +52,11 @@ default-features = false
version = "1.0.6"
[dev-dependencies.syn]
-version = "1.0"
+version = "2.0"
features = ["full"]
[dev-dependencies.thiserror]
-version = "1.0"
+version = "1.0.45"
[dev-dependencies.trybuild]
version = "1.0.66"
diff --git a/Cargo.toml.orig b/Cargo.toml.orig
index b16323b..3a5cce4 100644
--- a/Cargo.toml.orig
+++ b/Cargo.toml.orig
@@ -1,6 +1,6 @@
[package]
name = "anyhow"
-version = "1.0.69" # remember to update html_root_url
+version = "1.0.79"
authors = ["David Tolnay <dtolnay@gmail.com>"]
categories = ["rust-patterns", "no-std"]
description = "Flexible concrete Error type built on std::error::Error"
@@ -16,13 +16,17 @@ default = ["std"]
std = []
[dependencies]
+# On compilers older than 1.65, features=["backtrace"] may be used to enable
+# backtraces via the `backtrace` crate. This feature has no effect on 1.65+
+# besides bringing in an unused dependency, as `std::backtrace` is always
+# preferred.
backtrace = { version = "0.3.51", optional = true }
[dev-dependencies]
futures = { version = "0.3", default-features = false }
rustversion = "1.0.6"
-syn = { version = "1.0", features = ["full"] }
-thiserror = "1.0"
+syn = { version = "2.0", features = ["full"] }
+thiserror = "1.0.45"
trybuild = { version = "1.0.66", features = ["diff"] }
[lib]
@@ -30,4 +34,4 @@ doc-scrape-examples = false
[package.metadata.docs.rs]
targets = ["x86_64-unknown-linux-gnu"]
-rustdoc-args = ["--cfg", "doc_cfg"]
+rustdoc-args = ["--cfg", "doc_cfg", "--generate-link-to-definition"]
diff --git a/METADATA b/METADATA
index cb503ee..447f25e 100644
--- a/METADATA
+++ b/METADATA
@@ -1,23 +1,20 @@
# This project was upgraded with external_updater.
-# Usage: tools/external_updater/updater.sh update rust/crates/anyhow
-# For more info, check https://cs.android.com/android/platform/superproject/+/master:tools/external_updater/README.md
+# Usage: tools/external_updater/updater.sh update external/rust/crates/anyhow
+# For more info, check https://cs.android.com/android/platform/superproject/+/main:tools/external_updater/README.md
name: "anyhow"
description: "Flexible concrete Error type built on std::error::Error"
third_party {
- url {
- type: HOMEPAGE
- value: "https://crates.io/crates/anyhow"
- }
- url {
- type: ARCHIVE
- value: "https://static.crates.io/crates/anyhow/anyhow-1.0.69.crate"
- }
- version: "1.0.69"
license_type: NOTICE
last_upgrade_date {
- year: 2023
- month: 2
- day: 15
+ year: 2024
+ month: 1
+ day: 31
+ }
+ homepage: "https://crates.io/crates/anyhow"
+ identifier {
+ type: "Archive"
+ value: "https://static.crates.io/crates/anyhow/anyhow-1.0.79.crate"
+ version: "1.0.79"
}
}
diff --git a/README.md b/README.md
index 6380c1c..ccf3097 100644
--- a/README.md
+++ b/README.md
@@ -75,10 +75,10 @@ anyhow = "1.0"
}
```
-- 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 using Rust &ge; 1.65, 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`;
@@ -86,10 +86,7 @@ anyhow = "1.0"
- 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
diff --git a/build.rs b/build.rs
index 3800683..7e95e6b 100644
--- a/build.rs
+++ b/build.rs
@@ -1,9 +1,7 @@
-#![allow(clippy::option_if_let_else)]
-
use std::env;
-use std::fs;
+use std::ffi::OsString;
use std::path::Path;
-use std::process::{Command, ExitStatus, Stdio};
+use std::process::{self, Command, Stdio};
use std::str;
#[cfg(all(feature = "backtrace", not(feature = "std")))]
@@ -11,56 +9,53 @@ 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!()
+fn main() {
+ let mut error_generic_member_access = false;
+ if cfg!(feature = "std") {
+ println!("cargo:rerun-if-changed=build/probe.rs");
+
+ let consider_rustc_bootstrap;
+ if compile_probe(false) {
+ // This is a nightly or dev compiler, so it supports unstable
+ // features regardless of RUSTC_BOOTSTRAP. No need to rerun build
+ // script if RUSTC_BOOTSTRAP is changed.
+ error_generic_member_access = true;
+ consider_rustc_bootstrap = false;
+ } else if let Some(rustc_bootstrap) = env::var_os("RUSTC_BOOTSTRAP") {
+ if compile_probe(true) {
+ // This is a stable or beta compiler for which the user has set
+ // RUSTC_BOOTSTRAP to turn on unstable features. Rerun build
+ // script if they change it.
+ error_generic_member_access = true;
+ consider_rustc_bootstrap = true;
+ } else if rustc_bootstrap == "1" {
+ // This compiler does not support the generic member access API
+ // in the form that anyhow expects. No need to pay attention to
+ // RUSTC_BOOTSTRAP.
+ error_generic_member_access = false;
+ consider_rustc_bootstrap = false;
+ } else {
+ // This is a stable or beta compiler for which RUSTC_BOOTSTRAP
+ // is set to restrict the use of unstable features by this
+ // crate.
+ error_generic_member_access = false;
+ consider_rustc_bootstrap = true;
+ }
+ } else {
+ // Without RUSTC_BOOTSTRAP, this compiler does not support the
+ // generic member access API in the form that anyhow expects, but
+ // try again if the user turns on unstable features.
+ error_generic_member_access = false;
+ consider_rustc_bootstrap = true;
}
- }
- impl Error for E {
- fn provide<'a>(&'a self, demand: &mut Demand<'a>) {
- demand.provide_ref(&self.backtrace);
+ if error_generic_member_access {
+ println!("cargo:rustc-cfg=std_backtrace");
+ println!("cargo:rustc-cfg=error_generic_member_access");
}
- }
- 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"),
- _ => {}
+ if consider_rustc_bootstrap {
+ println!("cargo:rerun-if-env-changed=RUSTC_BOOTSTRAP");
}
}
@@ -70,19 +65,43 @@ fn main() {
};
if rustc < 51 {
+ // core::ptr::addr_of
+ // https://blog.rust-lang.org/2021/03/25/Rust-1.51.0.html#stabilized-apis
println!("cargo:rustc-cfg=anyhow_no_ptr_addr_of");
}
if rustc < 52 {
+ // core::fmt::Arguments::as_str
+ // https://blog.rust-lang.org/2021/05/06/Rust-1.52.0.html#stabilized-apis
println!("cargo:rustc-cfg=anyhow_no_fmt_arguments_as_str");
+
+ // #![deny(unsafe_op_in_unsafe_fn)]
+ // https://github.com/rust-lang/rust/issues/71668
+ println!("cargo:rustc-cfg=anyhow_no_unsafe_op_in_unsafe_fn_lint");
+ }
+
+ if !error_generic_member_access && cfg!(feature = "std") && rustc >= 65 {
+ // std::backtrace::Backtrace
+ // https://blog.rust-lang.org/2022/11/03/Rust-1.65.0.html#stabilized-apis
+ println!("cargo:rustc-cfg=std_backtrace");
}
}
-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()?;
+fn compile_probe(rustc_bootstrap: bool) -> bool {
+ if env::var_os("RUSTC_STAGE").is_some() {
+ // We are running inside rustc bootstrap. This is a highly non-standard
+ // environment with issues such as:
+ //
+ // https://github.com/rust-lang/cargo/issues/11138
+ // https://github.com/rust-lang/rust/issues/114839
+ //
+ // Let's just not use nightly features here.
+ return false;
+ }
+
+ let rustc = cargo_env_var("RUSTC");
+ let out_dir = cargo_env_var("OUT_DIR");
+ let probefile = Path::new("build").join("probe.rs");
// Make sure to pick up Cargo rustc configuration.
let mut cmd = if let Some(wrapper) = env::var_os("RUSTC_WRAPPER") {
@@ -94,11 +113,15 @@ fn compile_probe() -> Option<ExitStatus> {
Command::new(rustc)
};
+ if !rustc_bootstrap {
+ cmd.env_remove("RUSTC_BOOTSTRAP");
+ }
+
cmd.stderr(Stdio::null())
.arg("--edition=2018")
- .arg("--crate-name=anyhow_build")
+ .arg("--crate-name=anyhow")
.arg("--crate-type=lib")
- .arg("--emit=metadata")
+ .arg("--emit=dep-info,metadata")
.arg("--out-dir")
.arg(out_dir)
.arg(probefile);
@@ -116,11 +139,14 @@ fn compile_probe() -> Option<ExitStatus> {
}
}
- cmd.status().ok()
+ match cmd.status() {
+ Ok(status) => status.success(),
+ Err(_) => false,
+ }
}
fn rustc_minor_version() -> Option<u32> {
- let rustc = env::var_os("RUSTC")?;
+ let rustc = cargo_env_var("RUSTC");
let output = Command::new(rustc).arg("--version").output().ok()?;
let version = str::from_utf8(&output.stdout).ok()?;
let mut pieces = version.split('.');
@@ -129,3 +155,13 @@ fn rustc_minor_version() -> Option<u32> {
}
pieces.next()?.parse().ok()
}
+
+fn cargo_env_var(key: &str) -> OsString {
+ env::var_os(key).unwrap_or_else(|| {
+ eprintln!(
+ "Environment variable ${} is not set during execution of build script",
+ key,
+ );
+ process::exit(1);
+ })
+}
diff --git a/build/probe.rs b/build/probe.rs
new file mode 100644
index 0000000..21e776d
--- /dev/null
+++ b/build/probe.rs
@@ -0,0 +1,35 @@
+// This code exercises the surface area that we expect of the Error generic
+// member access API. If the current toolchain is able to compile it, then
+// anyhow is able to provide backtrace support.
+
+#![feature(error_generic_member_access)]
+
+use std::backtrace::Backtrace;
+use std::error::{self, Error, Request};
+use std::fmt::{self, Debug, Display};
+
+struct MyError(Thing);
+struct Thing;
+
+impl Debug for MyError {
+ fn fmt(&self, _formatter: &mut fmt::Formatter) -> fmt::Result {
+ unimplemented!()
+ }
+}
+
+impl Display for MyError {
+ fn fmt(&self, _formatter: &mut fmt::Formatter) -> fmt::Result {
+ unimplemented!()
+ }
+}
+
+impl Error for MyError {
+ fn provide<'a>(&'a self, request: &mut Request<'a>) {
+ request.provide_ref(&self.0);
+ }
+}
+
+const _: fn(&dyn Error) -> Option<&Backtrace> = |err| error::request_ref::<Backtrace>(err);
+
+// Include in sccache cache key.
+const _: Option<&str> = option_env!("RUSTC_BOOTSTRAP");
diff --git a/patches/0001-Support-RUST_BACKTRACE-settings-in-test_fmt.patch b/patches/0001-Support-RUST_BACKTRACE-settings-in-test_fmt.patch
index b577c41..1b59607 100644
--- a/patches/0001-Support-RUST_BACKTRACE-settings-in-test_fmt.patch
+++ b/patches/0001-Support-RUST_BACKTRACE-settings-in-test_fmt.patch
@@ -1,6 +1,6 @@
-From 7a58c3792b5f844514036b1f098eda228ba0ab8f Mon Sep 17 00:00:00 2001
+From 0dedafec9fb850f4041cb7b323282b19381cb1f2 Mon Sep 17 00:00:00 2001
From: Matthew Maurer <mmaurer@google.com>
-Date: Tue, 23 Nov 2021 22:39:07 +0000
+Date: Wed, 31 Jan 2024 15:07:59 +0100
Subject: [PATCH] Support RUST_BACKTRACE settings in test_fmt
Setting `RUST_BACKTRACE` when running tests is useful so that the logs
@@ -18,7 +18,7 @@ Change-Id: I7ea8bcded841558d845f0cba4a92a2339a6db3f5
1 file changed, 10 insertions(+), 10 deletions(-)
diff --git a/tests/test_fmt.rs b/tests/test_fmt.rs
-index cc49291..5703ebb 100644
+index 9766d36..016b4b8 100644
--- a/tests/test_fmt.rs
+++ b/tests/test_fmt.rs
@@ -68,27 +68,27 @@ Error {
@@ -40,7 +40,7 @@ index cc49291..5703ebb 100644
}
#[test]
- #[cfg_attr(not(backtrace), ignore)]
+ #[cfg_attr(not(std_backtrace), ignore)]
fn test_debug() {
- assert_eq!(EXPECTED_DEBUG_F, format!("{:?}", f().unwrap_err()));
- assert_eq!(EXPECTED_DEBUG_G, format!("{:?}", g().unwrap_err()));
@@ -60,5 +60,5 @@ index cc49291..5703ebb 100644
+ assert!(format!("{:#?}", h().unwrap_err()).starts_with(EXPECTED_ALTDEBUG_H));
}
--
-2.34.0.rc2.393.gf8c9666880-goog
+2.43.0.429.g432eaa2c6b-goog
diff --git a/src/backtrace.rs b/src/backtrace.rs
index 23c0c85..65ad1cc 100644
--- a/src/backtrace.rs
+++ b/src/backtrace.rs
@@ -1,65 +1,69 @@
-#[cfg(backtrace)]
+#[cfg(std_backtrace)]
pub(crate) use std::backtrace::{Backtrace, BacktraceStatus};
-#[cfg(all(not(backtrace), feature = "backtrace"))]
+#[cfg(all(not(std_backtrace), feature = "backtrace"))]
pub(crate) use self::capture::{Backtrace, BacktraceStatus};
-#[cfg(not(any(backtrace, feature = "backtrace")))]
+#[cfg(not(any(std_backtrace, feature = "backtrace")))]
pub(crate) enum Backtrace {}
-#[cfg(backtrace)]
+#[cfg(std_backtrace)]
macro_rules! impl_backtrace {
() => {
std::backtrace::Backtrace
};
}
-#[cfg(all(not(backtrace), feature = "backtrace"))]
+#[cfg(all(not(std_backtrace), feature = "backtrace"))]
macro_rules! impl_backtrace {
() => {
impl core::fmt::Debug + core::fmt::Display
};
}
-#[cfg(any(backtrace, feature = "backtrace"))]
+#[cfg(any(std_backtrace, feature = "backtrace"))]
macro_rules! backtrace {
() => {
Some(crate::backtrace::Backtrace::capture())
};
}
-#[cfg(not(any(backtrace, feature = "backtrace")))]
+#[cfg(not(any(std_backtrace, feature = "backtrace")))]
macro_rules! backtrace {
() => {
None
};
}
-#[cfg(backtrace)]
+#[cfg(error_generic_member_access)]
macro_rules! backtrace_if_absent {
($err:expr) => {
- match ($err as &dyn std::error::Error).request_ref::<std::backtrace::Backtrace>() {
+ match std::error::request_ref::<std::backtrace::Backtrace>($err as &dyn std::error::Error) {
Some(_) => None,
None => backtrace!(),
}
};
}
-#[cfg(all(feature = "std", not(backtrace), feature = "backtrace"))]
+#[cfg(all(
+ feature = "std",
+ not(error_generic_member_access),
+ any(std_backtrace, feature = "backtrace")
+))]
macro_rules! backtrace_if_absent {
($err:expr) => {
backtrace!()
};
}
-#[cfg(all(feature = "std", not(backtrace), not(feature = "backtrace")))]
+#[cfg(all(feature = "std", not(std_backtrace), not(feature = "backtrace")))]
macro_rules! backtrace_if_absent {
($err:expr) => {
None
};
}
-#[cfg(all(not(backtrace), feature = "backtrace"))]
+#[cfg(all(not(std_backtrace), feature = "backtrace"))]
mod capture {
use backtrace::{BacktraceFmt, BytesOrWideString, Frame, PrintFmt, SymbolName};
use core::cell::UnsafeCell;
diff --git a/src/context.rs b/src/context.rs
index 9df8693..11b31ba 100644
--- a/src/context.rs
+++ b/src/context.rs
@@ -3,8 +3,8 @@ use crate::{Context, Error, StdError};
use core::convert::Infallible;
use core::fmt::{self, Debug, Display, Write};
-#[cfg(backtrace)]
-use std::any::{Demand, Provider};
+#[cfg(error_generic_member_access)]
+use std::error::Request;
mod ext {
use super::*;
@@ -143,9 +143,9 @@ where
Some(&self.error)
}
- #[cfg(backtrace)]
- fn provide<'a>(&'a self, demand: &mut Demand<'a>) {
- StdError::provide(&self.error, demand);
+ #[cfg(error_generic_member_access)]
+ fn provide<'a>(&'a self, request: &mut Request<'a>) {
+ StdError::provide(&self.error, request);
}
}
@@ -157,9 +157,9 @@ where
Some(unsafe { crate::ErrorImpl::error(self.error.inner.by_ref()) })
}
- #[cfg(backtrace)]
- fn provide<'a>(&'a self, demand: &mut Demand<'a>) {
- Provider::provide(&self.error, demand);
+ #[cfg(error_generic_member_access)]
+ fn provide<'a>(&'a self, request: &mut Request<'a>) {
+ Error::provide(&self.error, request);
}
}
diff --git a/src/ensure.rs b/src/ensure.rs
index 0ab4471..c40cb92 100644
--- a/src/ensure.rs
+++ b/src/ensure.rs
@@ -231,6 +231,11 @@ macro_rules! __parse_ensure {
$crate::__parse_ensure!(atom $stack $bail ($($fuel)*) {($($buf)* $unsafe $block) $($parse)*} ($($rest)*) $($rest)*)
};
+ (0 $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($const:tt $block:tt $($dup:tt)*) const {$($body:tt)*} $($rest:tt)*) => {
+ // TODO: this is mostly useless due to https://github.com/rust-lang/rust/issues/86730
+ $crate::__parse_ensure!(atom $stack $bail ($($fuel)*) {($($buf)* $const $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)*)
};
diff --git a/src/error.rs b/src/error.rs
index 9f6ce8c..f24c4a6 100644
--- a/src/error.rs
+++ b/src/error.rs
@@ -5,14 +5,14 @@ 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(error_generic_member_access)]
+use std::error::{self, Request};
#[cfg(feature = "std")]
use core::ops::{Deref, DerefMut};
@@ -99,7 +99,10 @@ impl Error {
#[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"))]
+ #[cfg(all(
+ not(error_generic_member_access),
+ any(std_backtrace, feature = "backtrace")
+ ))]
object_backtrace: no_backtrace,
};
@@ -124,7 +127,10 @@ impl Error {
#[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"))]
+ #[cfg(all(
+ not(error_generic_member_access),
+ any(std_backtrace, feature = "backtrace")
+ ))]
object_backtrace: no_backtrace,
};
@@ -150,7 +156,10 @@ impl Error {
#[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"))]
+ #[cfg(all(
+ not(error_generic_member_access),
+ any(std_backtrace, feature = "backtrace")
+ ))]
object_backtrace: no_backtrace,
};
@@ -178,7 +187,10 @@ impl Error {
#[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"))]
+ #[cfg(all(
+ not(error_generic_member_access),
+ any(std_backtrace, feature = "backtrace")
+ ))]
object_backtrace: no_backtrace,
};
@@ -204,7 +216,10 @@ impl Error {
#[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"))]
+ #[cfg(all(
+ not(error_generic_member_access),
+ any(std_backtrace, feature = "backtrace")
+ ))]
object_backtrace: no_backtrace,
};
@@ -317,7 +332,10 @@ impl Error {
#[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"))]
+ #[cfg(all(
+ not(error_generic_member_access),
+ any(std_backtrace, feature = "backtrace")
+ ))]
object_backtrace: context_backtrace::<C>,
};
@@ -345,21 +363,17 @@ impl Error {
///
/// # 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
+ /// Standard library backtraces are only available when using Rust &ge;
+ /// 1.65. On older 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.
+ /// the underlying backtrace implementation. The return type of this
+ /// function on old compilers is `&(impl Debug + Display)`.
///
/// ```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"))))]
+ #[cfg(any(std_backtrace, feature = "backtrace"))]
pub fn backtrace(&self) -> &impl_backtrace!() {
unsafe { ErrorImpl::backtrace(self.inner.by_ref()) }
}
@@ -522,17 +536,21 @@ impl Error {
Some(addr.cast::<E>().deref_mut())
}
}
-}
-#[cfg(backtrace)]
-impl std::any::Provider for Error {
+ #[cfg(error_generic_member_access)]
+ pub(crate) fn provide<'a>(&'a self, request: &mut Request<'a>) {
+ unsafe { ErrorImpl::provide(self.inner.by_ref(), request) }
+ }
+
// 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(error_generic_member_access)]
+ #[doc(hidden)]
+ pub fn thiserror_provide<'a>(&'a self, request: &mut Request<'a>) {
+ Self::provide(self, request);
}
}
@@ -598,7 +616,10 @@ struct ErrorVTable {
#[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"))]
+ #[cfg(all(
+ not(error_generic_member_access),
+ any(std_backtrace, feature = "backtrace")
+ ))]
object_backtrace: unsafe fn(Ref<ErrorImpl>) -> Option<&Backtrace>,
}
@@ -606,8 +627,8 @@ struct ErrorVTable {
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);
+ let unerased_own = e.cast::<ErrorImpl<E>>();
+ drop(unsafe { unerased_own.boxed() });
}
// Safety: requires layout of *e to match ErrorImpl<E>.
@@ -616,8 +637,8 @@ unsafe fn object_drop_front<E>(e: Own<ErrorImpl>, target: TypeId) {
// 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);
+ let unerased_own = e.cast::<ErrorImpl<ManuallyDrop<E>>>();
+ drop(unsafe { unerased_own.boxed() });
}
// Safety: requires layout of *e to match ErrorImpl<E>.
@@ -627,15 +648,15 @@ where
{
// Attach E's native StdError vtable onto a pointer to self._object.
- let unerased = e.cast::<ErrorImpl<E>>();
+ let unerased_ref = 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,
- ));
+ return Ref::from_raw(unsafe {
+ NonNull::new_unchecked(ptr::addr_of!((*unerased_ref.as_ptr())._object) as *mut E)
+ });
#[cfg(anyhow_no_ptr_addr_of)]
- return Ref::new(&unerased.deref()._object);
+ return Ref::new(unsafe { &unerased_ref.deref()._object });
}
// Safety: requires layout of *e to match ErrorImpl<E>, and for `e` to be derived
@@ -646,7 +667,8 @@ 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
+ let unerased_mut = e.cast::<ErrorImpl<E>>();
+ unsafe { &mut unerased_mut.deref_mut()._object }
}
// Safety: requires layout of *e to match ErrorImpl<E>.
@@ -655,7 +677,8 @@ where
E: StdError + Send + Sync + 'static,
{
// Attach ErrorImpl<E>'s native StdError vtable. The StdError impl is below.
- e.cast::<ErrorImpl<E>>().boxed()
+ let unerased_own = e.cast::<ErrorImpl<E>>();
+ unsafe { unerased_own.boxed() }
}
// Safety: requires layout of *e to match ErrorImpl<E>.
@@ -667,18 +690,18 @@ where
// 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>>();
+ let unerased_ref = 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,
- ))
+ Ref::from_raw(unsafe {
+ NonNull::new_unchecked(ptr::addr_of!((*unerased_ref.as_ptr())._object) as *mut E)
+ })
.cast::<()>(),
);
#[cfg(anyhow_no_ptr_addr_of)]
- return Some(Ref::new(&unerased.deref()._object).cast::<()>());
+ return Some(Ref::new(unsafe { &unerased_ref.deref()._object }).cast::<()>());
} else {
None
}
@@ -693,14 +716,18 @@ where
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();
+ let unerased_mut = e.cast::<ErrorImpl<E>>();
+ let unerased = unsafe { unerased_mut.deref_mut() };
Some(Mut::new(&mut unerased._object).cast::<()>())
} else {
None
}
}
-#[cfg(all(not(backtrace), feature = "backtrace"))]
+#[cfg(all(
+ not(error_generic_member_access),
+ any(std_backtrace, feature = "backtrace")
+))]
fn no_backtrace(e: Ref<ErrorImpl>) -> Option<&Backtrace> {
let _ = e;
None
@@ -714,10 +741,12 @@ where
E: 'static,
{
if TypeId::of::<C>() == target {
- let unerased = e.cast::<ErrorImpl<ContextError<C, E>>>().deref();
+ let unerased_ref = e.cast::<ErrorImpl<ContextError<C, E>>>();
+ let unerased = unsafe { unerased_ref.deref() };
Some(Ref::new(&unerased._object.context).cast::<()>())
} else if TypeId::of::<E>() == target {
- let unerased = e.cast::<ErrorImpl<ContextError<C, E>>>().deref();
+ let unerased_ref = e.cast::<ErrorImpl<ContextError<C, E>>>();
+ let unerased = unsafe { unerased_ref.deref() };
Some(Ref::new(&unerased._object.error).cast::<()>())
} else {
None
@@ -732,10 +761,12 @@ where
E: 'static,
{
if TypeId::of::<C>() == target {
- let unerased = e.cast::<ErrorImpl<ContextError<C, E>>>().deref_mut();
+ let unerased_mut = e.cast::<ErrorImpl<ContextError<C, E>>>();
+ let unerased = unsafe { unerased_mut.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();
+ let unerased_mut = e.cast::<ErrorImpl<ContextError<C, E>>>();
+ let unerased = unsafe { unerased_mut.deref_mut() };
Some(Mut::new(&mut unerased._object.error).cast::<()>())
} else {
None
@@ -752,15 +783,11 @@ where
// 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);
+ let unerased_own = e.cast::<ErrorImpl<ContextError<ManuallyDrop<C>, E>>>();
+ drop(unsafe { unerased_own.boxed() });
} else {
- let unerased = e
- .cast::<ErrorImpl<ContextError<C, ManuallyDrop<E>>>>()
- .boxed();
- drop(unerased);
+ let unerased_own = e.cast::<ErrorImpl<ContextError<C, ManuallyDrop<E>>>>();
+ drop(unsafe { unerased_own.boxed() });
}
}
@@ -769,13 +796,14 @@ unsafe fn context_chain_downcast<C>(e: Ref<ErrorImpl>, target: TypeId) -> Option
where
C: 'static,
{
- let unerased = e.cast::<ErrorImpl<ContextError<C, Error>>>().deref();
+ let unerased_ref = e.cast::<ErrorImpl<ContextError<C, Error>>>();
+ let unerased = unsafe { unerased_ref.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)
+ unsafe { (vtable(source.inner.ptr).object_downcast)(source.inner.by_ref(), target) }
}
}
@@ -785,13 +813,14 @@ unsafe fn context_chain_downcast_mut<C>(e: Mut<ErrorImpl>, target: TypeId) -> Op
where
C: 'static,
{
- let unerased = e.cast::<ErrorImpl<ContextError<C, Error>>>().deref_mut();
+ let unerased_mut = e.cast::<ErrorImpl<ContextError<C, Error>>>();
+ let unerased = unsafe { unerased_mut.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)
+ unsafe { (vtable(source.inner.ptr).object_downcast_mut)(source.inner.by_mut(), target) }
}
}
@@ -803,33 +832,34 @@ where
// 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();
+ let unerased_own = e.cast::<ErrorImpl<ContextError<ManuallyDrop<C>, Error>>>();
// Drop the entire rest of the data structure rooted in the next Error.
- drop(unerased);
+ drop(unsafe { unerased_own.boxed() });
} else {
- let unerased = e
- .cast::<ErrorImpl<ContextError<C, ManuallyDrop<Error>>>>()
- .boxed();
+ let unerased_own = e.cast::<ErrorImpl<ContextError<C, ManuallyDrop<Error>>>>();
+ let unerased = unsafe { unerased_own.boxed() };
// Read the Own<ErrorImpl> from the next error.
let inner = unerased._object.error.inner;
drop(unerased);
- let vtable = vtable(inner.ptr);
+ let vtable = unsafe { vtable(inner.ptr) };
// Recursively drop the next error using the same target typeid.
- (vtable.object_drop_rest)(inner, target);
+ unsafe { (vtable.object_drop_rest)(inner, target) };
}
}
// Safety: requires layout of *e to match ErrorImpl<ContextError<C, Error>>.
-#[cfg(all(not(backtrace), feature = "backtrace"))]
+#[cfg(all(
+ not(error_generic_member_access),
+ any(std_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());
+ let unerased_ref = e.cast::<ErrorImpl<ContextError<C, Error>>>();
+ let unerased = unsafe { unerased_ref.deref() };
+ let backtrace = unsafe { ErrorImpl::backtrace(unerased._object.error.inner.by_ref()) };
Some(backtrace)
}
@@ -849,7 +879,7 @@ pub(crate) struct ErrorImpl<E = ()> {
// 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)
+ unsafe { *(p.as_ptr() as *const &'static ErrorVTable) }
}
// repr C to ensure that ContextError<C, E> has the same layout as
@@ -873,7 +903,7 @@ 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()
+ unsafe { (vtable(this.ptr).object_ref)(this).deref() }
}
#[cfg(feature = "std")]
@@ -882,42 +912,44 @@ impl ErrorImpl {
// original type E.
#[cfg(not(anyhow_no_ptr_addr_of))]
- return (vtable(this.ptr).object_ref)(this.by_ref())
- .by_mut()
- .deref_mut();
+ return unsafe {
+ (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);
+ return unsafe { (vtable(this.ptr).object_mut)(this) };
}
- #[cfg(any(backtrace, feature = "backtrace"))]
+ #[cfg(any(std_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()
+ unsafe { 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);
+ #[cfg(error_generic_member_access)]
+ return error::request_ref::<Backtrace>(unsafe { Self::error(this) });
+ #[cfg(not(error_generic_member_access))]
+ return unsafe { (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);
+ #[cfg(error_generic_member_access)]
+ unsafe fn provide<'a>(this: Ref<'a, Self>, request: &mut Request<'a>) {
+ if let Some(backtrace) = unsafe { &this.deref().backtrace } {
+ request.provide_ref(backtrace);
}
- Self::error(this).provide(demand);
+ unsafe { Self::error(this) }.provide(request);
}
#[cold]
pub(crate) unsafe fn chain(this: Ref<Self>) -> Chain {
- Chain::new(Self::error(this))
+ Chain::new(unsafe { Self::error(this) })
}
}
@@ -929,9 +961,9 @@ where
unsafe { ErrorImpl::error(self.erase()).source() }
}
- #[cfg(backtrace)]
- fn provide<'a>(&'a self, demand: &mut Demand<'a>) {
- unsafe { ErrorImpl::provide(self.erase(), demand) }
+ #[cfg(error_generic_member_access)]
+ fn provide<'a>(&'a self, request: &mut Request<'a>) {
+ unsafe { ErrorImpl::provide(self.erase(), request) }
}
}
diff --git a/src/fmt.rs b/src/fmt.rs
index 03d8fd3..a99649b 100644
--- a/src/fmt.rs
+++ b/src/fmt.rs
@@ -5,10 +5,11 @@ 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))?;
+ write!(f, "{}", unsafe { Self::error(this) })?;
if f.alternate() {
- for cause in Self::chain(this).skip(1) {
+ let chain = unsafe { Self::chain(this) };
+ for cause in chain.skip(1) {
write!(f, ": {}", cause)?;
}
}
@@ -17,7 +18,7 @@ impl ErrorImpl {
}
pub(crate) unsafe fn debug(this: Ref<Self>, f: &mut fmt::Formatter) -> fmt::Result {
- let error = Self::error(this);
+ let error = unsafe { Self::error(this) };
if f.alternate() {
return Debug::fmt(error, f);
@@ -39,11 +40,11 @@ impl ErrorImpl {
}
}
- #[cfg(any(backtrace, feature = "backtrace"))]
+ #[cfg(any(std_backtrace, feature = "backtrace"))]
{
use crate::backtrace::BacktraceStatus;
- let backtrace = Self::backtrace(this);
+ let backtrace = unsafe { Self::backtrace(this) };
if let BacktraceStatus::Captured = backtrace.status() {
let mut backtrace = backtrace.to_string();
write!(f, "\n\n")?;
diff --git a/src/kind.rs b/src/kind.rs
index f47fe44..21d76aa 100644
--- a/src/kind.rs
+++ b/src/kind.rs
@@ -52,6 +52,7 @@ use crate::StdError;
pub struct Adhoc;
+#[doc(hidden)]
pub trait AdhocKind: Sized {
#[inline]
fn anyhow_kind(&self) -> Adhoc {
@@ -73,6 +74,7 @@ impl Adhoc {
pub struct Trait;
+#[doc(hidden)]
pub trait TraitKind: Sized {
#[inline]
fn anyhow_kind(&self) -> Trait {
@@ -96,6 +98,7 @@ impl Trait {
pub struct Boxed;
#[cfg(feature = "std")]
+#[doc(hidden)]
pub trait BoxedKind: Sized {
#[inline]
fn anyhow_kind(&self) -> Boxed {
diff --git a/src/lib.rs b/src/lib.rs
index e570d6e..490a075 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -128,11 +128,10 @@
//! # ;
//! ```
//!
-//! - 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 using Rust &ge; 1.65, 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`;
@@ -140,10 +139,7 @@
//! - 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)`
@@ -210,15 +206,22 @@
//! 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.69")]
-#![cfg_attr(backtrace, feature(error_generic_member_access, provide_any))]
+#![doc(html_root_url = "https://docs.rs/anyhow/1.0.79")]
+#![cfg_attr(error_generic_member_access, feature(error_generic_member_access))]
#![cfg_attr(doc_cfg, feature(doc_cfg))]
#![cfg_attr(not(feature = "std"), no_std)]
#![deny(dead_code, unused_imports, unused_mut)]
+#![cfg_attr(
+ not(anyhow_no_unsafe_op_in_unsafe_fn_lint),
+ deny(unsafe_op_in_unsafe_fn)
+)]
+#![cfg_attr(anyhow_no_unsafe_op_in_unsafe_fn_lint, allow(unused_unsafe))]
#![allow(
clippy::doc_markdown,
clippy::enum_glob_use,
clippy::explicit_auto_deref,
+ clippy::extra_unused_type_parameters,
+ clippy::let_underscore_untyped,
clippy::missing_errors_doc,
clippy::missing_panics_doc,
clippy::module_name_repetitions,
@@ -227,12 +230,20 @@
clippy::new_ret_no_self,
clippy::redundant_else,
clippy::return_self_not_must_use,
+ clippy::struct_field_names,
clippy::unused_self,
clippy::used_underscore_binding,
clippy::wildcard_imports,
clippy::wrong_self_convention
)]
+#[cfg(all(
+ anyhow_nightly_testing,
+ feature = "std",
+ not(error_generic_member_access)
+))]
+compile_error!("Build script probe failed to compile.");
+
extern crate alloc;
#[macro_use]
@@ -264,6 +275,7 @@ trait StdError: Debug + Display {
}
}
+#[doc(no_inline)]
pub use anyhow as format_err;
/// The `Error` type, a wrapper around a dynamic error type.
@@ -639,16 +651,22 @@ pub mod __private {
use alloc::fmt;
use core::fmt::Arguments;
+ #[doc(hidden)]
pub use crate::ensure::{BothDebug, NotBothDebug};
+ #[doc(hidden)]
pub use alloc::format;
+ #[doc(hidden)]
pub use core::result::Result::Err;
+ #[doc(hidden)]
pub use core::{concat, format_args, stringify};
#[doc(hidden)]
pub mod kind {
+ #[doc(hidden)]
pub use crate::kind::{AdhocKind, TraitKind};
#[cfg(feature = "std")]
+ #[doc(hidden)]
pub use crate::kind::BoxedKind;
}
diff --git a/src/ptr.rs b/src/ptr.rs
index c7fe488..a1b7126 100644
--- a/src/ptr.rs
+++ b/src/ptr.rs
@@ -42,7 +42,7 @@ where
}
pub unsafe fn boxed(self) -> Box<T> {
- Box::from_raw(self.ptr.as_ptr())
+ unsafe { Box::from_raw(self.ptr.as_ptr()) }
}
pub fn by_ref(&self) -> Ref<T> {
@@ -120,7 +120,7 @@ where
}
pub unsafe fn deref(self) -> &'a T {
- &*self.ptr.as_ptr()
+ unsafe { &*self.ptr.as_ptr() }
}
}
@@ -179,13 +179,13 @@ where
}
pub unsafe fn deref_mut(self) -> &'a mut T {
- &mut *self.ptr.as_ptr()
+ unsafe { &mut *self.ptr.as_ptr() }
}
}
impl<'a, T> Mut<'a, T> {
pub unsafe fn read(self) -> T {
- self.ptr.as_ptr().read()
+ unsafe { self.ptr.as_ptr().read() }
}
}
diff --git a/src/wrapper.rs b/src/wrapper.rs
index 5f18a50..0eb5478 100644
--- a/src/wrapper.rs
+++ b/src/wrapper.rs
@@ -1,8 +1,8 @@
use crate::StdError;
use core::fmt::{self, Debug, Display};
-#[cfg(backtrace)]
-use std::any::Demand;
+#[cfg(error_generic_member_access)]
+use std::error::Request;
#[repr(transparent)]
pub struct MessageError<M>(pub M);
@@ -74,8 +74,8 @@ impl StdError for BoxedError {
self.0.source()
}
- #[cfg(backtrace)]
- fn provide<'a>(&'a self, demand: &mut Demand<'a>) {
- self.0.provide(demand);
+ #[cfg(error_generic_member_access)]
+ fn provide<'a>(&'a self, request: &mut Request<'a>) {
+ self.0.provide(request);
}
}
diff --git a/tests/test_autotrait.rs b/tests/test_autotrait.rs
index 0c9326d..94d7a59 100644
--- a/tests/test_autotrait.rs
+++ b/tests/test_autotrait.rs
@@ -1,3 +1,5 @@
+#![allow(clippy::extra_unused_type_parameters)]
+
use anyhow::Error;
#[test]
diff --git a/tests/test_backtrace.rs b/tests/test_backtrace.rs
index ce385f5..c89559e 100644
--- a/tests/test_backtrace.rs
+++ b/tests/test_backtrace.rs
@@ -1,3 +1,5 @@
+#![allow(clippy::let_underscore_untyped)]
+
#[rustversion::not(nightly)]
#[ignore]
#[test]
diff --git a/tests/test_ensure.rs b/tests/test_ensure.rs
index de867f7..aeff3ac 100644
--- a/tests/test_ensure.rs
+++ b/tests/test_ensure.rs
@@ -1,11 +1,15 @@
#![allow(
clippy::bool_to_int_with_if,
clippy::diverging_sub_expression,
+ clippy::extra_unused_type_parameters,
clippy::if_same_then_else,
clippy::ifs_same_cond,
+ clippy::ignored_unit_patterns,
clippy::items_after_statements,
clippy::let_and_return,
+ clippy::let_underscore_untyped,
clippy::match_bool,
+ clippy::needless_else,
clippy::never_loop,
clippy::overly_complex_bool_expr,
clippy::redundant_closure_call,
diff --git a/tests/test_fmt.rs b/tests/test_fmt.rs
index 5703ebb..016b4b8 100644
--- a/tests/test_fmt.rs
+++ b/tests/test_fmt.rs
@@ -79,7 +79,7 @@ fn test_altdisplay() {
}
#[test]
-#[cfg_attr(not(backtrace), ignore)]
+#[cfg_attr(not(std_backtrace), ignore)]
fn test_debug() {
assert!(format!("{:?}", f().unwrap_err()).starts_with(EXPECTED_DEBUG_F));
assert!(format!("{:?}", g().unwrap_err()).starts_with(EXPECTED_DEBUG_G));
diff --git a/tests/test_repr.rs b/tests/test_repr.rs
index 72f5002..065041c 100644
--- a/tests/test_repr.rs
+++ b/tests/test_repr.rs
@@ -1,3 +1,5 @@
+#![allow(clippy::extra_unused_type_parameters)]
+
mod drop;
use self::drop::{DetectDrop, Flag};