From a1f510e47fad6466921a80d653ffc7a1064666eb Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Fri, 21 Jul 2023 20:22:37 -0700 Subject: [PATCH 01/10] Temporarily disable -Zrandomize-layout due to rustc ICE https://github.com/rust-lang/rust/issues/113941 --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 4ee51c8..d67666f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -34,7 +34,7 @@ jobs: components: rust-src - name: Enable type layout randomization run: echo RUSTFLAGS=${RUSTFLAGS}\ -Zrandomize-layout >> $GITHUB_ENV - if: matrix.rust == 'nightly' + if: matrix.rust == 'nightly' && false # FIXME https://github.com/rust-lang/rust/issues/113941 - run: cargo test - run: cargo check --no-default-features - run: cargo check --features backtrace From 7fc0c073c4c31ef8664f699e9e4883b1c92b2fb6 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Sat, 22 Jul 2023 18:37:54 -0700 Subject: [PATCH 02/10] Revert "Temporarily disable -Zrandomize-layout due to rustc ICE" Fixed in nightly-2023-07-23. This reverts commit a1f510e47fad6466921a80d653ffc7a1064666eb. --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index d67666f..4ee51c8 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -34,7 +34,7 @@ jobs: components: rust-src - name: Enable type layout randomization run: echo RUSTFLAGS=${RUSTFLAGS}\ -Zrandomize-layout >> $GITHUB_ENV - if: matrix.rust == 'nightly' && false # FIXME https://github.com/rust-lang/rust/issues/113941 + if: matrix.rust == 'nightly' - run: cargo test - run: cargo check --no-default-features - run: cargo check --features backtrace From 496b9584c4897f17969ce42302675d67e2c53b81 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Fri, 11 Aug 2023 20:14:41 -0700 Subject: [PATCH 03/10] Ignore ignored_unit_patterns pedantic clippy lint in test suite warning: matching over `()` is more explicit --> tests/test_ensure.rs:710:34 | 710 | let test = || Ok(ensure!(for _ in iter::once(()) {} != ())); | ^ help: use `()` instead of `_`: `()` | = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#ignored_unit_patterns = note: `-W clippy::ignored-unit-patterns` implied by `-W clippy::pedantic` --- tests/test_ensure.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/test_ensure.rs b/tests/test_ensure.rs index 359ec73..aeff3ac 100644 --- a/tests/test_ensure.rs +++ b/tests/test_ensure.rs @@ -4,6 +4,7 @@ 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, From 31c8dff2cdc44773e5fe290881c9ce47cc3e1b21 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Mon, 14 Aug 2023 23:26:38 -0700 Subject: [PATCH 04/10] Update to nightly's new Error::provide API --- Cargo.toml | 2 +- build.rs | 47 ++++++++++++++++++----------------------------- src/backtrace.rs | 2 +- src/context.rs | 10 +++++----- src/error.rs | 30 +++++++++++++++++------------- src/lib.rs | 2 +- src/wrapper.rs | 6 +++--- 7 files changed, 46 insertions(+), 53 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index c25a387..4fa5585 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -22,7 +22,7 @@ backtrace = { version = "0.3.51", optional = true } futures = { version = "0.3", default-features = false } rustversion = "1.0.6" syn = { version = "2.0", features = ["full"] } -thiserror = "1.0" +thiserror = "1.0.45" trybuild = { version = "1.0.66", features = ["diff"] } [lib] diff --git a/build.rs b/build.rs index 3800683..de94535 100644 --- a/build.rs +++ b/build.rs @@ -11,49 +11,38 @@ 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. +// 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. const PROBE: &str = r#" - #![feature(error_generic_member_access, provide_any)] + #![feature(error_generic_member_access)] - use std::any::{Demand, Provider}; - use std::backtrace::{Backtrace, BacktraceStatus}; - use std::error::Error; - use std::fmt::{self, Display}; + use std::backtrace::Backtrace; + use std::error::{self, Error, Request}; + use std::fmt::{self, Debug, Display}; - #[derive(Debug)] - struct E { - backtrace: Backtrace, - } + struct MyError(Thing); + struct Thing; - impl Display for E { + impl Debug for MyError { fn fmt(&self, _formatter: &mut fmt::Formatter) -> fmt::Result { unimplemented!() } } - impl Error for E { - fn provide<'a>(&'a self, demand: &mut Demand<'a>) { - demand.provide_ref(&self.backtrace); + impl Display for MyError { + fn fmt(&self, _formatter: &mut fmt::Formatter) -> fmt::Result { + unimplemented!() } } - 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 | _ => {} + 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| err.request_ref::(); + const _: fn(&dyn Error) -> Option<&Backtrace> = |err| error::request_ref::(err); "#; fn main() { diff --git a/src/backtrace.rs b/src/backtrace.rs index 23c0c85..7c1906b 100644 --- a/src/backtrace.rs +++ b/src/backtrace.rs @@ -38,7 +38,7 @@ macro_rules! backtrace { #[cfg(backtrace)] macro_rules! backtrace_if_absent { ($err:expr) => { - match ($err as &dyn std::error::Error).request_ref::() { + match std::error::request_ref::($err as &dyn std::error::Error) { Some(_) => None, None => backtrace!(), } diff --git a/src/context.rs b/src/context.rs index 9df8693..d81b9a7 100644 --- a/src/context.rs +++ b/src/context.rs @@ -4,7 +4,7 @@ use core::convert::Infallible; use core::fmt::{self, Debug, Display, Write}; #[cfg(backtrace)] -use std::any::{Demand, Provider}; +use std::error::Request; mod ext { use super::*; @@ -144,8 +144,8 @@ where } #[cfg(backtrace)] - fn provide<'a>(&'a self, demand: &mut Demand<'a>) { - StdError::provide(&self.error, demand); + fn provide<'a>(&'a self, request: &mut Request<'a>) { + StdError::provide(&self.error, request); } } @@ -158,8 +158,8 @@ where } #[cfg(backtrace)] - fn provide<'a>(&'a self, demand: &mut Demand<'a>) { - Provider::provide(&self.error, demand); + fn provide<'a>(&'a self, request: &mut Request<'a>) { + Error::provide(&self.error, request); } } diff --git a/src/error.rs b/src/error.rs index 9f6ce8c..01402d4 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(backtrace)] +use std::error::{self, Request}; #[cfg(feature = "std")] use core::ops::{Deref, DerefMut}; @@ -522,17 +522,21 @@ impl Error { Some(addr.cast::().deref_mut()) } } -} -#[cfg(backtrace)] -impl std::any::Provider for Error { + #[cfg(backtrace)] + 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(backtrace)] + #[doc(hidden)] + pub fn thiserror_provide<'a>(&'a self, request: &mut Request<'a>) { + Self::provide(self, request); } } @@ -900,7 +904,7 @@ impl ErrorImpl { .as_ref() .or_else(|| { #[cfg(backtrace)] - return Self::error(this).request_ref::(); + return error::request_ref::(Self::error(this)); #[cfg(not(backtrace))] return (vtable(this.ptr).object_backtrace)(this); }) @@ -908,11 +912,11 @@ impl ErrorImpl { } #[cfg(backtrace)] - unsafe fn provide<'a>(this: Ref<'a, Self>, demand: &mut Demand<'a>) { + unsafe fn provide<'a>(this: Ref<'a, Self>, request: &mut Request<'a>) { if let Some(backtrace) = &this.deref().backtrace { - demand.provide_ref(backtrace); + request.provide_ref(backtrace); } - Self::error(this).provide(demand); + Self::error(this).provide(request); } #[cold] @@ -930,8 +934,8 @@ where } #[cfg(backtrace)] - fn provide<'a>(&'a self, demand: &mut Demand<'a>) { - unsafe { ErrorImpl::provide(self.erase(), demand) } + fn provide<'a>(&'a self, request: &mut Request<'a>) { + unsafe { ErrorImpl::provide(self.erase(), request) } } } diff --git a/src/lib.rs b/src/lib.rs index 76f3aab..b36868f 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -211,7 +211,7 @@ //! non-Anyhow error type inside a function that returns Anyhow's error type. #![doc(html_root_url = "https://docs.rs/anyhow/1.0.72")] -#![cfg_attr(backtrace, feature(error_generic_member_access, provide_any))] +#![cfg_attr(backtrace, 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)] diff --git a/src/wrapper.rs b/src/wrapper.rs index 5f18a50..8a6d686 100644 --- a/src/wrapper.rs +++ b/src/wrapper.rs @@ -2,7 +2,7 @@ use crate::StdError; use core::fmt::{self, Debug, Display}; #[cfg(backtrace)] -use std::any::Demand; +use std::error::Request; #[repr(transparent)] pub struct MessageError(pub M); @@ -75,7 +75,7 @@ impl StdError for BoxedError { } #[cfg(backtrace)] - fn provide<'a>(&'a self, demand: &mut Demand<'a>) { - self.0.provide(demand); + fn provide<'a>(&'a self, request: &mut Request<'a>) { + self.0.provide(request); } } From e471b2b6506f5dac2ce1c6a58090c9cb0936f43e Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Mon, 14 Aug 2023 23:58:36 -0700 Subject: [PATCH 05/10] Release 1.0.73 --- Cargo.toml | 2 +- src/lib.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 4fa5585..08290ab 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "anyhow" -version = "1.0.72" # remember to update html_root_url +version = "1.0.73" # remember to update html_root_url authors = ["David Tolnay "] categories = ["rust-patterns", "no-std"] description = "Flexible concrete Error type built on std::error::Error" diff --git a/src/lib.rs b/src/lib.rs index b36868f..ddeef9e 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -210,7 +210,7 @@ //! will require an explicit `.map_err(Error::msg)` when working with a //! non-Anyhow error type inside a function that returns Anyhow's error type. -#![doc(html_root_url = "https://docs.rs/anyhow/1.0.72")] +#![doc(html_root_url = "https://docs.rs/anyhow/1.0.73")] #![cfg_attr(backtrace, feature(error_generic_member_access))] #![cfg_attr(doc_cfg, feature(doc_cfg))] #![cfg_attr(not(feature = "std"), no_std)] From 663c6633e39d194bed0048df1e8ea5b60ef00e73 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Tue, 15 Aug 2023 09:44:47 +0200 Subject: [PATCH 06/10] don't run build probes in rustc bootstrap --- build.rs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/build.rs b/build.rs index de94535..8456a7d 100644 --- a/build.rs +++ b/build.rs @@ -68,6 +68,14 @@ fn main() { } fn compile_probe() -> Option { + 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 and + // . Let's just not use nightly features + // here. + return None; + } + let rustc = env::var_os("RUSTC")?; let out_dir = env::var_os("OUT_DIR")?; let probefile = Path::new(&out_dir).join("probe.rs"); From 0798a9a635edc46dd80a09b77f3238eb0d5fba7a Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Tue, 15 Aug 2023 08:25:05 -0700 Subject: [PATCH 07/10] Reword bootstrap comment --- build.rs | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/build.rs b/build.rs index 8456a7d..fc585cf 100644 --- a/build.rs +++ b/build.rs @@ -69,10 +69,13 @@ fn main() { fn compile_probe() -> Option { 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 and - // . Let's just not use nightly features - // here. + // 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 None; } From cbade7d00a0a8808fe2830e00c19b5c44789272a Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Tue, 15 Aug 2023 08:25:26 -0700 Subject: [PATCH 08/10] Release 1.0.74 --- Cargo.toml | 2 +- src/lib.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 08290ab..07bf612 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "anyhow" -version = "1.0.73" # remember to update html_root_url +version = "1.0.74" # remember to update html_root_url authors = ["David Tolnay "] categories = ["rust-patterns", "no-std"] description = "Flexible concrete Error type built on std::error::Error" diff --git a/src/lib.rs b/src/lib.rs index ddeef9e..dd3f51e 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -210,7 +210,7 @@ //! will require an explicit `.map_err(Error::msg)` when working with a //! non-Anyhow error type inside a function that returns Anyhow's error type. -#![doc(html_root_url = "https://docs.rs/anyhow/1.0.73")] +#![doc(html_root_url = "https://docs.rs/anyhow/1.0.74")] #![cfg_attr(backtrace, feature(error_generic_member_access))] #![cfg_attr(doc_cfg, feature(doc_cfg))] #![cfg_attr(not(feature = "std"), no_std)] From 238223af99dcd4ff41ad86e6ba7a0d2acb2d5ab5 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Wed, 16 Aug 2023 17:14:33 -0700 Subject: [PATCH 09/10] Work around ridiculous rust-analyzer behavior As far as I can tell there is still no way to keep it from autoimporting the private macros and enum variants here: anyhow::__private::format, anyhow::__private::Err. --- src/kind.rs | 3 +++ src/lib.rs | 6 ++++++ 2 files changed, 9 insertions(+) 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 dd3f51e..445fdf0 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -642,16 +642,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; } From 6485caebde8e5c8bc313cd1a5ff6d70e58670b42 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Wed, 16 Aug 2023 18:13:02 -0700 Subject: [PATCH 10/10] Release 1.0.75 --- Cargo.toml | 2 +- src/lib.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 07bf612..88be2c2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "anyhow" -version = "1.0.74" # remember to update html_root_url +version = "1.0.75" # remember to update html_root_url authors = ["David Tolnay "] categories = ["rust-patterns", "no-std"] description = "Flexible concrete Error type built on std::error::Error" diff --git a/src/lib.rs b/src/lib.rs index 445fdf0..5ec17ad 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -210,7 +210,7 @@ //! will require an explicit `.map_err(Error::msg)` when working with a //! non-Anyhow error type inside a function that returns Anyhow's error type. -#![doc(html_root_url = "https://docs.rs/anyhow/1.0.74")] +#![doc(html_root_url = "https://docs.rs/anyhow/1.0.75")] #![cfg_attr(backtrace, feature(error_generic_member_access))] #![cfg_attr(doc_cfg, feature(doc_cfg))] #![cfg_attr(not(feature = "std"), no_std)]