diff options
author | Android Build Coastguard Worker <android-build-coastguard-worker@google.com> | 2024-02-02 23:51:52 +0000 |
---|---|---|
committer | Android Build Coastguard Worker <android-build-coastguard-worker@google.com> | 2024-02-02 23:51:52 +0000 |
commit | 63eb178fd7baf881e66e16a4965ee9bc157b42db (patch) | |
tree | 6472acf7b15f35c854c3abadd3c1d16db4a77773 | |
parent | 38abe5f4e6cc71f2733d48fb8fe8171dce200c55 (diff) | |
parent | 5891f6a953b29e9786c84ced4b4ca7204a583bd1 (diff) | |
download | anyhow-simpleperf-release.tar.gz |
Snap for 11400057 from 5891f6a953b29e9786c84ced4b4ca7204a583bd1 to simpleperf-releasesimpleperf-release
Change-Id: Ica69082948a1aa504ce4b9d866cefeece13ed653
-rw-r--r-- | .cargo_vcs_info.json | 2 | ||||
-rw-r--r-- | .clippy.toml | 1 | ||||
-rw-r--r-- | .github/FUNDING.yml | 1 | ||||
-rw-r--r-- | .github/workflows/ci.yml | 50 | ||||
-rw-r--r-- | Android.bp | 24 | ||||
-rw-r--r-- | Cargo.toml | 9 | ||||
-rw-r--r-- | Cargo.toml.orig | 12 | ||||
-rw-r--r-- | METADATA | 25 | ||||
-rw-r--r-- | README.md | 11 | ||||
-rw-r--r-- | build.rs | 154 | ||||
-rw-r--r-- | build/probe.rs | 35 | ||||
-rw-r--r-- | patches/0001-Support-RUST_BACKTRACE-settings-in-test_fmt.patch | 10 | ||||
-rw-r--r-- | src/backtrace.rs | 28 | ||||
-rw-r--r-- | src/context.rs | 16 | ||||
-rw-r--r-- | src/ensure.rs | 5 | ||||
-rw-r--r-- | src/error.rs | 212 | ||||
-rw-r--r-- | src/fmt.rs | 11 | ||||
-rw-r--r-- | src/kind.rs | 3 | ||||
-rw-r--r-- | src/lib.rs | 38 | ||||
-rw-r--r-- | src/ptr.rs | 8 | ||||
-rw-r--r-- | src/wrapper.rs | 10 | ||||
-rw-r--r-- | tests/test_autotrait.rs | 2 | ||||
-rw-r--r-- | tests/test_backtrace.rs | 2 | ||||
-rw-r--r-- | tests/test_ensure.rs | 4 | ||||
-rw-r--r-- | tests/test_fmt.rs | 2 | ||||
-rw-r--r-- | tests/test_repr.rs | 2 |
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 @@ -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: [ @@ -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"] @@ -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" } } @@ -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 ≥ 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 @@ -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 ≥ + /// 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) } } } @@ -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 { @@ -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 ≥ 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; } @@ -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}; |