Upgrade thiserror to 1.0.38 am: 6a1290e25d am: 5199a97d8d am: 919d6d931b

Original change: https://android-review.googlesource.com/c/platform/external/rust/crates/thiserror/+/2361766

Change-Id: Ibb29c1333f30620b3ad57e61dbc19f358659a061
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
diff --git a/.cargo_vcs_info.json b/.cargo_vcs_info.json
index cafa20e..302d141 100644
--- a/.cargo_vcs_info.json
+++ b/.cargo_vcs_info.json
@@ -1,6 +1,6 @@
 {
   "git": {
-    "sha1": "672e9525bbc2e5682c380d36974f34716b963591"
+    "sha1": "74bfe75eb25ba9d39b0ae5b570d611855cbc5086"
   },
   "path_in_vcs": ""
 }
\ No newline at end of file
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 61714b6..e1db2ed 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -5,6 +5,12 @@
   pull_request:
   schedule: [cron: "40 1 * * *"]
 
+permissions:
+  contents: read
+
+env:
+  RUSTFLAGS: -Dwarnings
+
 jobs:
   test:
     name: Rust ${{matrix.rust}}
@@ -12,41 +18,61 @@
     strategy:
       fail-fast: false
       matrix:
-        rust: [beta, stable, 1.36.0]
+        rust: [beta, stable, 1.56.0]
         include:
           - rust: nightly
             rustflags: --cfg thiserror_nightly_testing
+    timeout-minutes: 45
     steps:
-      - uses: actions/checkout@v2
+      - uses: actions/checkout@v3
       - uses: dtolnay/rust-toolchain@master
         with:
           toolchain: ${{matrix.rust}}
           components: rust-src
       - run: cargo test --all
         env:
-          RUSTFLAGS: ${{matrix.rustflags}}
+          RUSTFLAGS: ${{matrix.rustflags}} ${{env.RUSTFLAGS}}
 
   msrv:
     name: Rust 1.31.0
     runs-on: ubuntu-latest
+    timeout-minutes: 45
     steps:
-      - uses: actions/checkout@v2
+      - uses: actions/checkout@v3
       - uses: dtolnay/rust-toolchain@1.31.0
+        with:
+          components: rust-src
       - run: cargo check
 
   clippy:
     name: Clippy
     runs-on: ubuntu-latest
     if: github.event_name != 'pull_request'
+    timeout-minutes: 45
     steps:
-      - uses: actions/checkout@v2
-      - uses: dtolnay/rust-toolchain@clippy
+      - uses: actions/checkout@v3
+      - uses: dtolnay/rust-toolchain@nightly
+        with:
+          components: clippy, rust-src
       - run: cargo clippy --tests -- -Dclippy::all -Dclippy::pedantic
 
+  miri:
+    name: Miri
+    runs-on: ubuntu-latest
+    timeout-minutes: 45
+    steps:
+      - uses: actions/checkout@v3
+      - uses: dtolnay/rust-toolchain@miri
+      - run: cargo miri test
+        env:
+          MIRIFLAGS: -Zmiri-strict-provenance
+
   outdated:
     name: Outdated
     runs-on: ubuntu-latest
     if: github.event_name != 'pull_request'
+    timeout-minutes: 45
     steps:
-      - uses: actions/checkout@v2
-      - run: cargo outdated --exit-code 1
+      - uses: actions/checkout@v3
+      - uses: dtolnay/install@cargo-outdated
+      - run: cargo outdated --workspace --exit-code 1
diff --git a/Android.bp b/Android.bp
index e9e1757..8d36e8a 100644
--- a/Android.bp
+++ b/Android.bp
@@ -42,9 +42,10 @@
     host_supported: true,
     crate_name: "thiserror",
     cargo_env_compat: true,
-    cargo_pkg_version: "1.0.30",
+    cargo_pkg_version: "1.0.38",
     srcs: ["src/lib.rs"],
     edition: "2018",
+    cfgs: ["provide_any"],
     proc_macros: ["libthiserror_impl"],
     apex_available: [
         "//apex_available:platform",
diff --git a/Cargo.toml b/Cargo.toml
index 78c99d6..e235408 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -13,20 +13,28 @@
 edition = "2018"
 rust-version = "1.31"
 name = "thiserror"
-version = "1.0.30"
+version = "1.0.38"
 authors = ["David Tolnay <dtolnay@gmail.com>"]
 description = "derive(Error)"
 documentation = "https://docs.rs/thiserror"
 readme = "README.md"
+keywords = [
+    "error",
+    "error-handling",
+    "derive",
+]
 categories = ["rust-patterns"]
 license = "MIT OR Apache-2.0"
 repository = "https://github.com/dtolnay/thiserror"
+
 [package.metadata.docs.rs]
 targets = ["x86_64-unknown-linux-gnu"]
+
 [dependencies.thiserror-impl]
-version = "=1.0.30"
+version = "=1.0.38"
+
 [dev-dependencies.anyhow]
-version = "1.0"
+version = "1.0.65"
 
 [dev-dependencies.ref-cast]
 version = "1.0"
@@ -35,5 +43,5 @@
 version = "1.0"
 
 [dev-dependencies.trybuild]
-version = "1.0.49"
+version = "1.0.66"
 features = ["diff"]
diff --git a/Cargo.toml.orig b/Cargo.toml.orig
index efa9af1..82ef03d 100644
--- a/Cargo.toml.orig
+++ b/Cargo.toml.orig
@@ -1,24 +1,24 @@
 [package]
 name = "thiserror"
-version = "1.0.30"
+version = "1.0.38"
 authors = ["David Tolnay <dtolnay@gmail.com>"]
-edition = "2018"
-rust-version = "1.31"
-license = "MIT OR Apache-2.0"
-description = "derive(Error)"
-repository = "https://github.com/dtolnay/thiserror"
-documentation = "https://docs.rs/thiserror"
 categories = ["rust-patterns"]
-readme = "README.md"
+description = "derive(Error)"
+documentation = "https://docs.rs/thiserror"
+edition = "2018"
+keywords = ["error", "error-handling", "derive"]
+license = "MIT OR Apache-2.0"
+repository = "https://github.com/dtolnay/thiserror"
+rust-version = "1.31"
 
 [dependencies]
-thiserror-impl = { version = "=1.0.30", path = "impl" }
+thiserror-impl = { version = "=1.0.38", path = "impl" }
 
 [dev-dependencies]
-anyhow = "1.0"
+anyhow = "1.0.65"
 ref-cast = "1.0"
 rustversion = "1.0"
-trybuild = { version = "1.0.49", features = ["diff"] }
+trybuild = { version = "1.0.66", features = ["diff"] }
 
 [workspace]
 members = ["impl"]
diff --git a/METADATA b/METADATA
index e961418..db2395f 100644
--- a/METADATA
+++ b/METADATA
@@ -1,3 +1,7 @@
+# This project was upgraded with external_updater.
+# Usage: tools/external_updater/updater.sh update rust/crates/thiserror
+# For more info, check https://cs.android.com/android/platform/superproject/+/master:tools/external_updater/README.md
+
 name: "thiserror"
 description: "derive(Error)"
 third_party {
@@ -7,13 +11,13 @@
   }
   url {
     type: ARCHIVE
-    value: "https://static.crates.io/crates/thiserror/thiserror-1.0.30.crate"
+    value: "https://static.crates.io/crates/thiserror/thiserror-1.0.38.crate"
   }
-  version: "1.0.30"
+  version: "1.0.38"
   license_type: NOTICE
   last_upgrade_date {
     year: 2022
-    month: 3
-    day: 1
+    month: 12
+    day: 19
   }
 }
diff --git a/README.md b/README.md
index e12b693..3ba375f 100644
--- a/README.md
+++ b/README.md
@@ -3,8 +3,8 @@
 
 [<img alt="github" src="https://img.shields.io/badge/github-dtolnay/thiserror-8da0cb?style=for-the-badge&labelColor=555555&logo=github" height="20">](https://github.com/dtolnay/thiserror)
 [<img alt="crates.io" src="https://img.shields.io/crates/v/thiserror.svg?style=for-the-badge&color=fc8d62&logo=rust" height="20">](https://crates.io/crates/thiserror)
-[<img alt="docs.rs" src="https://img.shields.io/badge/docs.rs-thiserror-66c2a5?style=for-the-badge&labelColor=555555&logoColor=white&logo=data:image/svg+xml;base64,PHN2ZyByb2xlPSJpbWciIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgdmlld0JveD0iMCAwIDUxMiA1MTIiPjxwYXRoIGZpbGw9IiNmNWY1ZjUiIGQ9Ik00ODguNiAyNTAuMkwzOTIgMjE0VjEwNS41YzAtMTUtOS4zLTI4LjQtMjMuNC0zMy43bC0xMDAtMzcuNWMtOC4xLTMuMS0xNy4xLTMuMS0yNS4zIDBsLTEwMCAzNy41Yy0xNC4xIDUuMy0yMy40IDE4LjctMjMuNCAzMy43VjIxNGwtOTYuNiAzNi4yQzkuMyAyNTUuNSAwIDI2OC45IDAgMjgzLjlWMzk0YzAgMTMuNiA3LjcgMjYuMSAxOS45IDMyLjJsMTAwIDUwYzEwLjEgNS4xIDIyLjEgNS4xIDMyLjIgMGwxMDMuOS01MiAxMDMuOSA1MmMxMC4xIDUuMSAyMi4xIDUuMSAzMi4yIDBsMTAwLTUwYzEyLjItNi4xIDE5LjktMTguNiAxOS45LTMyLjJWMjgzLjljMC0xNS05LjMtMjguNC0yMy40LTMzLjd6TTM1OCAyMTQuOGwtODUgMzEuOXYtNjguMmw4NS0zN3Y3My4zek0xNTQgMTA0LjFsMTAyLTM4LjIgMTAyIDM4LjJ2LjZsLTEwMiA0MS40LTEwMi00MS40di0uNnptODQgMjkxLjFsLTg1IDQyLjV2LTc5LjFsODUtMzguOHY3NS40em0wLTExMmwtMTAyIDQxLjQtMTAyLTQxLjR2LS42bDEwMi0zOC4yIDEwMiAzOC4ydi42em0yNDAgMTEybC04NSA0Mi41di03OS4xbDg1LTM4Ljh2NzUuNHptMC0xMTJsLTEwMiA0MS40LTEwMi00MS40di0uNmwxMDItMzguMiAxMDIgMzguMnYuNnoiPjwvcGF0aD48L3N2Zz4K" height="20">](https://docs.rs/thiserror)
-[<img alt="build status" src="https://img.shields.io/github/workflow/status/dtolnay/thiserror/CI/master?style=for-the-badge" height="20">](https://github.com/dtolnay/thiserror/actions?query=branch%3Amaster)
+[<img alt="docs.rs" src="https://img.shields.io/badge/docs.rs-thiserror-66c2a5?style=for-the-badge&labelColor=555555&logo=docs.rs" height="20">](https://docs.rs/thiserror)
+[<img alt="build status" src="https://img.shields.io/github/actions/workflow/status/dtolnay/thiserror/ci.yml?branch=master&style=for-the-badge" height="20">](https://github.com/dtolnay/thiserror/actions?query=branch%3Amaster)
 
 This library provides a convenient derive macro for the standard library's
 [`std::error::Error`] trait.
@@ -124,8 +124,8 @@
   }
   ```
 
-- The Error trait's `backtrace()` method is implemented to return whichever
-  field has a type named `Backtrace`, if any.
+- The Error trait's `provide()` method is implemented to provide whichever field
+  has a type named `Backtrace`, if any, as a `std::backtrace::Backtrace`.
 
   ```rust
   use std::backtrace::Backtrace;
@@ -138,8 +138,9 @@
   ```
 
 - If a field is both a source (named `source`, or has `#[source]` or `#[from]`
-  attribute) *and* is marked `#[backtrace]`, then the Error trait's
-  `backtrace()` method is forwarded to the source's backtrace.
+  attribute) *and* is marked `#[backtrace]`, then the Error trait's `provide()`
+  method is forwarded to the source's `provide` so that both layers of the error
+  share the same backtrace.
 
   ```rust
   #[derive(Error, Debug)]
@@ -165,6 +166,27 @@
   }
   ```
 
+  Another use case is hiding implementation details of an error representation
+  behind an opaque error type, so that the representation is able to evolve
+  without breaking the crate's public API.
+
+  ```rust
+  // PublicError is public, but opaque and easy to keep compatible.
+  #[derive(Error, Debug)]
+  #[error(transparent)]
+  pub struct PublicError(#[from] ErrorRepr);
+
+  impl PublicError {
+      // Accessors for anything we do want to expose publicly.
+  }
+
+  // Private and free to change across minor version of the crate.
+  #[derive(Error, Debug)]
+  enum ErrorRepr {
+      ...
+  }
+  ```
+
 - See also the [`anyhow`] library for a convenient single error type to use in
   application code.
 
diff --git a/build.rs b/build.rs
new file mode 100644
index 0000000..004dfb0
--- /dev/null
+++ b/build.rs
@@ -0,0 +1,66 @@
+use std::env;
+use std::fs;
+use std::path::Path;
+use std::process::{Command, ExitStatus, Stdio};
+use std::str;
+
+// This code exercises the surface area that we expect of the Provider API. If
+// the current toolchain is able to compile it, then thiserror is able to use
+// providers for backtrace support.
+const PROBE: &str = r#"
+    #![feature(provide_any)]
+
+    use std::any::{Demand, Provider};
+
+    fn _f<'a, P: Provider>(p: &'a P, demand: &mut Demand<'a>) {
+        p.provide(demand);
+    }
+"#;
+
+fn main() {
+    match compile_probe() {
+        Some(status) if status.success() => println!("cargo:rustc-cfg=provide_any"),
+        _ => {}
+    }
+}
+
+fn compile_probe() -> Option<ExitStatus> {
+    let rustc = env::var_os("RUSTC")?;
+    let out_dir = env::var_os("OUT_DIR")?;
+    let probefile = Path::new(&out_dir).join("probe.rs");
+    fs::write(&probefile, PROBE).ok()?;
+
+    // Make sure to pick up Cargo rustc configuration.
+    let mut cmd = if let Some(wrapper) = env::var_os("RUSTC_WRAPPER") {
+        let mut cmd = Command::new(wrapper);
+        // The wrapper's first argument is supposed to be the path to rustc.
+        cmd.arg(rustc);
+        cmd
+    } else {
+        Command::new(rustc)
+    };
+
+    cmd.stderr(Stdio::null())
+        .arg("--edition=2018")
+        .arg("--crate-name=thiserror_build")
+        .arg("--crate-type=lib")
+        .arg("--emit=metadata")
+        .arg("--out-dir")
+        .arg(out_dir)
+        .arg(probefile);
+
+    if let Some(target) = env::var_os("TARGET") {
+        cmd.arg("--target").arg(target);
+    }
+
+    // If Cargo wants to set RUSTFLAGS, use that.
+    if let Ok(rustflags) = env::var("CARGO_ENCODED_RUSTFLAGS") {
+        if !rustflags.is_empty() {
+            for arg in rustflags.split('\x1f') {
+                cmd.arg(arg);
+            }
+        }
+    }
+
+    cmd.status().ok()
+}
diff --git a/src/aserror.rs b/src/aserror.rs
index c036b7b..5fea84e 100644
--- a/src/aserror.rs
+++ b/src/aserror.rs
@@ -1,7 +1,7 @@
 use std::error::Error;
 use std::panic::UnwindSafe;
 
-pub trait AsDynError<'a> {
+pub trait AsDynError<'a>: Sealed {
     fn as_dyn_error(&self) -> &(dyn Error + 'a);
 }
 
@@ -39,3 +39,10 @@
         self
     }
 }
+
+pub trait Sealed {}
+impl<'a, T: Error + 'a> Sealed for T {}
+impl<'a> Sealed for dyn Error + 'a {}
+impl<'a> Sealed for dyn Error + Send + 'a {}
+impl<'a> Sealed for dyn Error + Send + Sync + 'a {}
+impl<'a> Sealed for dyn Error + Send + Sync + UnwindSafe + 'a {}
diff --git a/src/lib.rs b/src/lib.rs
index 2fae25c..aae6552 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -2,7 +2,7 @@
 //!
 //! [github]: https://img.shields.io/badge/github-8da0cb?style=for-the-badge&labelColor=555555&logo=github
 //! [crates-io]: https://img.shields.io/badge/crates.io-fc8d62?style=for-the-badge&labelColor=555555&logo=rust
-//! [docs-rs]: https://img.shields.io/badge/docs.rs-66c2a5?style=for-the-badge&labelColor=555555&logoColor=white&logo=data:image/svg+xml;base64,PHN2ZyByb2xlPSJpbWciIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgdmlld0JveD0iMCAwIDUxMiA1MTIiPjxwYXRoIGZpbGw9IiNmNWY1ZjUiIGQ9Ik00ODguNiAyNTAuMkwzOTIgMjE0VjEwNS41YzAtMTUtOS4zLTI4LjQtMjMuNC0zMy43bC0xMDAtMzcuNWMtOC4xLTMuMS0xNy4xLTMuMS0yNS4zIDBsLTEwMCAzNy41Yy0xNC4xIDUuMy0yMy40IDE4LjctMjMuNCAzMy43VjIxNGwtOTYuNiAzNi4yQzkuMyAyNTUuNSAwIDI2OC45IDAgMjgzLjlWMzk0YzAgMTMuNiA3LjcgMjYuMSAxOS45IDMyLjJsMTAwIDUwYzEwLjEgNS4xIDIyLjEgNS4xIDMyLjIgMGwxMDMuOS01MiAxMDMuOSA1MmMxMC4xIDUuMSAyMi4xIDUuMSAzMi4yIDBsMTAwLTUwYzEyLjItNi4xIDE5LjktMTguNiAxOS45LTMyLjJWMjgzLjljMC0xNS05LjMtMjguNC0yMy40LTMzLjd6TTM1OCAyMTQuOGwtODUgMzEuOXYtNjguMmw4NS0zN3Y3My4zek0xNTQgMTA0LjFsMTAyLTM4LjIgMTAyIDM4LjJ2LjZsLTEwMiA0MS40LTEwMi00MS40di0uNnptODQgMjkxLjFsLTg1IDQyLjV2LTc5LjFsODUtMzguOHY3NS40em0wLTExMmwtMTAyIDQxLjQtMTAyLTQxLjR2LS42bDEwMi0zOC4yIDEwMiAzOC4ydi42em0yNDAgMTEybC04NSA0Mi41di03OS4xbDg1LTM4Ljh2NzUuNHptMC0xMTJsLTEwMiA0MS40LTEwMi00MS40di0uNmwxMDItMzguMiAxMDIgMzguMnYuNnoiPjwvcGF0aD48L3N2Zz4K
+//! [docs-rs]: https://img.shields.io/badge/docs.rs-66c2a5?style=for-the-badge&labelColor=555555&logo=docs.rs
 //!
 //! <br>
 //!
@@ -146,8 +146,9 @@
 //!   # }
 //!   ```
 //!
-//! - The Error trait's `backtrace()` method is implemented to return whichever
-//!   field has a type named `Backtrace`, if any.
+//! - The Error trait's `provide()` method is implemented to provide whichever
+//!   field has a type named `Backtrace`, if any, as a
+//!   `std::backtrace::Backtrace`.
 //!
 //!   ```rust
 //!   # const IGNORE: &str = stringify! {
@@ -163,7 +164,8 @@
 //!
 //! - If a field is both a source (named `source`, or has `#[source]` or
 //!   `#[from]` attribute) *and* is marked `#[backtrace]`, then the Error
-//!   trait's `backtrace()` method is forwarded to the source's backtrace.
+//!   trait's `provide()` method is forwarded to the source's `provide` so that
+//!   both layers of the error share the same backtrace.
 //!
 //!   ```rust
 //!   # const IGNORE: &str = stringify! {
@@ -196,6 +198,31 @@
 //!   }
 //!   ```
 //!
+//!   Another use case is hiding implementation details of an error
+//!   representation behind an opaque error type, so that the representation is
+//!   able to evolve without breaking the crate's public API.
+//!
+//!   ```
+//!   # use thiserror::Error;
+//!   #
+//!   // PublicError is public, but opaque and easy to keep compatible.
+//!   #[derive(Error, Debug)]
+//!   #[error(transparent)]
+//!   pub struct PublicError(#[from] ErrorRepr);
+//!
+//!   impl PublicError {
+//!       // Accessors for anything we do want to expose publicly.
+//!   }
+//!
+//!   // Private and free to change across minor version of the crate.
+//!   #[derive(Error, Debug)]
+//!   enum ErrorRepr {
+//!       # /*
+//!       ...
+//!       # */
+//!   }
+//!   ```
+//!
 //! - See also the [`anyhow`] library for a convenient single error type to use
 //!   in application code.
 //!
@@ -205,16 +232,23 @@
     // Clippy bug: https://github.com/rust-lang/rust-clippy/issues/7421
     clippy::doc_markdown,
     clippy::module_name_repetitions,
+    clippy::return_self_not_must_use,
+    clippy::wildcard_imports,
 )]
+#![cfg_attr(provide_any, feature(provide_any))]
 
 mod aserror;
 mod display;
+#[cfg(provide_any)]
+mod provide;
 
 pub use thiserror_impl::*;
 
 // Not public API.
 #[doc(hidden)]
-pub mod private {
+pub mod __private {
     pub use crate::aserror::AsDynError;
     pub use crate::display::{DisplayAsDisplay, PathAsDisplay};
+    #[cfg(provide_any)]
+    pub use crate::provide::ThiserrorProvide;
 }
diff --git a/src/provide.rs b/src/provide.rs
new file mode 100644
index 0000000..524e743
--- /dev/null
+++ b/src/provide.rs
@@ -0,0 +1,15 @@
+use std::any::{Demand, Provider};
+
+pub trait ThiserrorProvide: Sealed {
+    fn thiserror_provide<'a>(&'a self, demand: &mut Demand<'a>);
+}
+
+impl<T: Provider + ?Sized> ThiserrorProvide for T {
+    #[inline]
+    fn thiserror_provide<'a>(&'a self, demand: &mut Demand<'a>) {
+        self.provide(demand);
+    }
+}
+
+pub trait Sealed {}
+impl<T: Provider + ?Sized> Sealed for T {}
diff --git a/tests/compiletest.rs b/tests/compiletest.rs
index 641d03c..7974a62 100644
--- a/tests/compiletest.rs
+++ b/tests/compiletest.rs
@@ -1,6 +1,5 @@
-#![deny(clippy::all, clippy::pedantic)]
-
 #[rustversion::attr(not(nightly), ignore)]
+#[cfg_attr(miri, ignore)]
 #[test]
 fn ui() {
     let t = trybuild::TestCases::new();
diff --git a/tests/test_backtrace.rs b/tests/test_backtrace.rs
index 42e37ca..43f68b8 100644
--- a/tests/test_backtrace.rs
+++ b/tests/test_backtrace.rs
@@ -1,4 +1,7 @@
-#![cfg_attr(thiserror_nightly_testing, feature(backtrace))]
+#![cfg_attr(
+    thiserror_nightly_testing,
+    feature(error_generic_member_access, provide_any)
+)]
 
 use thiserror::Error;
 
@@ -16,6 +19,7 @@
 #[cfg(thiserror_nightly_testing)]
 pub mod structs {
     use super::{Inner, InnerBacktrace};
+    use std::any;
     use std::backtrace::Backtrace;
     use std::error::Error;
     use std::sync::Arc;
@@ -83,49 +87,94 @@
         backtrace: Arc<Backtrace>,
     }
 
+    #[derive(Error, Debug)]
+    #[error("...")]
+    pub struct AnyhowBacktrace {
+        #[backtrace]
+        source: anyhow::Error,
+    }
+
+    #[derive(Error, Debug)]
+    #[error("...")]
+    pub struct BoxDynErrorBacktrace {
+        #[backtrace]
+        source: Box<dyn Error>,
+    }
+
     #[test]
     fn test_backtrace() {
         let error = PlainBacktrace {
             backtrace: Backtrace::capture(),
         };
-        assert!(error.backtrace().is_some());
+        assert!(any::request_ref::<Backtrace>(&error).is_some());
 
         let error = ExplicitBacktrace {
             backtrace: Backtrace::capture(),
         };
-        assert!(error.backtrace().is_some());
+        assert!(any::request_ref::<Backtrace>(&error).is_some());
 
         let error = OptBacktrace {
             backtrace: Some(Backtrace::capture()),
         };
-        assert!(error.backtrace().is_some());
+        assert!(any::request_ref::<Backtrace>(&error).is_some());
 
         let error = ArcBacktrace {
             backtrace: Arc::new(Backtrace::capture()),
         };
-        assert!(error.backtrace().is_some());
+        assert!(any::request_ref::<Backtrace>(&error).is_some());
 
         let error = BacktraceFrom::from(Inner);
-        assert!(error.backtrace().is_some());
+        assert!(any::request_ref::<Backtrace>(&error).is_some());
 
         let error = CombinedBacktraceFrom::from(InnerBacktrace {
             backtrace: Backtrace::capture(),
         });
-        assert!(error.backtrace().is_some());
+        assert!(any::request_ref::<Backtrace>(&error).is_some());
 
         let error = OptBacktraceFrom::from(Inner);
-        assert!(error.backtrace().is_some());
+        assert!(any::request_ref::<Backtrace>(&error).is_some());
 
         let error = ArcBacktraceFrom::from(Inner);
-        assert!(error.backtrace().is_some());
+        assert!(any::request_ref::<Backtrace>(&error).is_some());
+
+        let error = AnyhowBacktrace {
+            source: anyhow::Error::msg("..."),
+        };
+        assert!(any::request_ref::<Backtrace>(&error).is_some());
+
+        let error = BoxDynErrorBacktrace {
+            source: Box::new(PlainBacktrace {
+                backtrace: Backtrace::capture(),
+            }),
+        };
+        assert!(any::request_ref::<Backtrace>(&error).is_some());
+    }
+
+    // https://github.com/dtolnay/thiserror/issues/185 -- std::error::Error and
+    // std::any::Provide both have a method called 'provide', so directly
+    // calling it from generated code could be ambiguous.
+    #[test]
+    fn test_provide_name_collision() {
+        use std::any::Provider;
+
+        #[derive(Error, Debug)]
+        #[error("...")]
+        struct MyError {
+            #[source]
+            #[backtrace]
+            x: std::io::Error,
+        }
+
+        let _: dyn Error;
+        let _: dyn Provider;
     }
 }
 
 #[cfg(thiserror_nightly_testing)]
 pub mod enums {
     use super::{Inner, InnerBacktrace};
+    use std::any;
     use std::backtrace::Backtrace;
-    use std::error::Error;
     use std::sync::Arc;
     use thiserror::Error;
 
@@ -210,36 +259,36 @@
         let error = PlainBacktrace::Test {
             backtrace: Backtrace::capture(),
         };
-        assert!(error.backtrace().is_some());
+        assert!(any::request_ref::<Backtrace>(&error).is_some());
 
         let error = ExplicitBacktrace::Test {
             backtrace: Backtrace::capture(),
         };
-        assert!(error.backtrace().is_some());
+        assert!(any::request_ref::<Backtrace>(&error).is_some());
 
         let error = OptBacktrace::Test {
             backtrace: Some(Backtrace::capture()),
         };
-        assert!(error.backtrace().is_some());
+        assert!(any::request_ref::<Backtrace>(&error).is_some());
 
         let error = ArcBacktrace::Test {
             backtrace: Arc::new(Backtrace::capture()),
         };
-        assert!(error.backtrace().is_some());
+        assert!(any::request_ref::<Backtrace>(&error).is_some());
 
         let error = BacktraceFrom::from(Inner);
-        assert!(error.backtrace().is_some());
+        assert!(any::request_ref::<Backtrace>(&error).is_some());
 
         let error = CombinedBacktraceFrom::from(InnerBacktrace {
             backtrace: Backtrace::capture(),
         });
-        assert!(error.backtrace().is_some());
+        assert!(any::request_ref::<Backtrace>(&error).is_some());
 
         let error = OptBacktraceFrom::from(Inner);
-        assert!(error.backtrace().is_some());
+        assert!(any::request_ref::<Backtrace>(&error).is_some());
 
         let error = ArcBacktraceFrom::from(Inner);
-        assert!(error.backtrace().is_some());
+        assert!(any::request_ref::<Backtrace>(&error).is_some());
     }
 }
 
diff --git a/tests/test_deprecated.rs b/tests/test_deprecated.rs
new file mode 100644
index 0000000..5524666
--- /dev/null
+++ b/tests/test_deprecated.rs
@@ -0,0 +1,10 @@
+#![deny(deprecated, clippy::all, clippy::pedantic)]
+
+use thiserror::Error;
+
+#[derive(Error, Debug)]
+pub enum Error {
+    #[deprecated]
+    #[error("...")]
+    Deprecated,
+}
diff --git a/tests/test_display.rs b/tests/test_display.rs
index 949d9ed..99ce2fd 100644
--- a/tests/test_display.rs
+++ b/tests/test_display.rs
@@ -1,6 +1,4 @@
-#![deny(clippy::all, clippy::pedantic)]
-
-use std::fmt::Display;
+use std::fmt::{self, Display};
 use thiserror::Error;
 
 fn assert<T: Display>(expected: &str, value: T) {
@@ -144,6 +142,35 @@
 }
 
 #[test]
+fn test_nested_display() {
+    // Same behavior as the one in `test_match`, but without String allocations.
+    #[derive(Error, Debug)]
+    #[error("{}", {
+        struct Msg<'a>(&'a String, &'a Option<usize>);
+        impl<'a> Display for Msg<'a> {
+            fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+                match self.1 {
+                    Some(n) => write!(formatter, "error occurred with {}", n),
+                    None => write!(formatter, "there was an empty error"),
+                }?;
+                write!(formatter, ": {}", self.0)
+            }
+        }
+        Msg(.0, .1)
+    })]
+    struct Error(String, Option<usize>);
+
+    assert(
+        "error occurred with 1: ...",
+        Error("...".to_owned(), Some(1)),
+    );
+    assert(
+        "there was an empty error: ...",
+        Error("...".to_owned(), None),
+    );
+}
+
+#[test]
 fn test_void() {
     #[allow(clippy::empty_enum)]
     #[derive(Error, Debug)]
diff --git a/tests/test_error.rs b/tests/test_error.rs
index ece7f91..fab934d 100644
--- a/tests/test_error.rs
+++ b/tests/test_error.rs
@@ -1,4 +1,3 @@
-#![deny(clippy::all, clippy::pedantic)]
 #![allow(dead_code)]
 
 use std::fmt::{self, Display};
diff --git a/tests/test_expr.rs b/tests/test_expr.rs
index 87a56cf..34de560 100644
--- a/tests/test_expr.rs
+++ b/tests/test_expr.rs
@@ -1,5 +1,4 @@
-#![deny(clippy::all, clippy::pedantic)]
-#![allow(clippy::option_if_let_else)]
+#![allow(clippy::iter_cloned_collect, clippy::option_if_let_else)]
 
 use std::fmt::Display;
 use thiserror::Error;
diff --git a/tests/test_from.rs b/tests/test_from.rs
index a25ce35..1f38705 100644
--- a/tests/test_from.rs
+++ b/tests/test_from.rs
@@ -1,5 +1,3 @@
-#![deny(clippy::all, clippy::pedantic)]
-
 use std::io;
 use thiserror::Error;
 
diff --git a/tests/test_generics.rs b/tests/test_generics.rs
index f5e1de2..4ab9f37 100644
--- a/tests/test_generics.rs
+++ b/tests/test_generics.rs
@@ -1,4 +1,4 @@
-#![deny(clippy::all, clippy::pedantic)]
+#![allow(clippy::needless_late_init)]
 
 use std::fmt::{self, Debug, Display};
 use thiserror::Error;
diff --git a/tests/test_option.rs b/tests/test_option.rs
index ca21713..ed5287d 100644
--- a/tests/test_option.rs
+++ b/tests/test_option.rs
@@ -1,5 +1,7 @@
-#![cfg_attr(thiserror_nightly_testing, feature(backtrace))]
-#![deny(clippy::all, clippy::pedantic)]
+#![cfg_attr(
+    thiserror_nightly_testing,
+    feature(error_generic_member_access, provide_any)
+)]
 
 #[cfg(thiserror_nightly_testing)]
 pub mod structs {
diff --git a/tests/test_path.rs b/tests/test_path.rs
index a10b1f3..a34a3d7 100644
--- a/tests/test_path.rs
+++ b/tests/test_path.rs
@@ -1,5 +1,3 @@
-#![deny(clippy::all, clippy::pedantic)]
-
 use ref_cast::RefCast;
 use std::fmt::Display;
 use std::path::{Path, PathBuf};
diff --git a/tests/test_source.rs b/tests/test_source.rs
index ab16097..637f4ac 100644
--- a/tests/test_source.rs
+++ b/tests/test_source.rs
@@ -1,5 +1,3 @@
-#![deny(clippy::all, clippy::pedantic)]
-
 use std::error::Error as StdError;
 use std::io;
 use thiserror::Error;
diff --git a/tests/test_transparent.rs b/tests/test_transparent.rs
index 84d7c91..6f3c03e 100644
--- a/tests/test_transparent.rs
+++ b/tests/test_transparent.rs
@@ -1,5 +1,3 @@
-#![deny(clippy::all, clippy::pedantic)]
-
 use anyhow::anyhow;
 use std::error::Error as _;
 use std::io;
diff --git a/tests/ui/concat-display.stderr b/tests/ui/concat-display.stderr
index 6ab4048..dbecd69 100644
--- a/tests/ui/concat-display.stderr
+++ b/tests/ui/concat-display.stderr
@@ -5,6 +5,6 @@
    |                 ^^^^^^
 ...
 13 | error_type!(Error, "foo");
-   | -------------------------- in this macro invocation
+   | ------------------------- in this macro invocation
    |
    = note: this error originates in the macro `error_type` (in Nightly builds, run with -Z macro-backtrace for more info)
diff --git a/tests/ui/from-backtrace-backtrace.rs b/tests/ui/from-backtrace-backtrace.rs
new file mode 100644
index 0000000..8f411bf
--- /dev/null
+++ b/tests/ui/from-backtrace-backtrace.rs
@@ -0,0 +1,10 @@
+// https://github.com/dtolnay/thiserror/issues/163
+
+use std::backtrace::Backtrace;
+use thiserror::Error;
+
+#[derive(Error, Debug)]
+#[error("...")]
+pub struct Error(#[from] #[backtrace] std::io::Error, Backtrace);
+
+fn main() {}
diff --git a/tests/ui/from-backtrace-backtrace.stderr b/tests/ui/from-backtrace-backtrace.stderr
new file mode 100644
index 0000000..55d647b
--- /dev/null
+++ b/tests/ui/from-backtrace-backtrace.stderr
@@ -0,0 +1,5 @@
+error: deriving From requires no fields other than source and backtrace
+ --> tests/ui/from-backtrace-backtrace.rs:8:18
+  |
+8 | pub struct Error(#[from] #[backtrace] std::io::Error, Backtrace);
+  |                  ^^^^^^^
diff --git a/tests/ui/no-display.stderr b/tests/ui/no-display.stderr
index e6a52f5..76818e1 100644
--- a/tests/ui/no-display.stderr
+++ b/tests/ui/no-display.stderr
@@ -1,23 +1,17 @@
 error[E0599]: the method `as_display` exists for reference `&NoDisplay`, but its trait bounds were not satisfied
-   --> tests/ui/no-display.rs:7:9
-    |
-4   | struct NoDisplay;
-    | ----------------- doesn't satisfy `NoDisplay: std::fmt::Display`
+ --> tests/ui/no-display.rs:7:9
+  |
+4 | struct NoDisplay;
+  | ---------------- doesn't satisfy `NoDisplay: std::fmt::Display`
 ...
-7   | #[error("thread: {thread}")]
-    |         ^^^^^^^^^^^^^^^^^^ method cannot be called on `&NoDisplay` due to unsatisfied trait bounds
-    |
-    = note: the following trait bounds were not satisfied:
-            `NoDisplay: std::fmt::Display`
-            which is required by `&NoDisplay: DisplayAsDisplay`
-note: the following trait must be implemented
-   --> $RUST/core/src/fmt/mod.rs
-    |
-    | / pub trait Display {
-    | |     /// Formats the value using the given formatter.
-    | |     ///
-    | |     /// # Examples
-...   |
-    | |     fn fmt(&self, f: &mut Formatter<'_>) -> Result;
-    | | }
-    | |_^
+7 | #[error("thread: {thread}")]
+  |         ^^^^^^^^^^^^^^^^^^ method cannot be called on `&NoDisplay` due to unsatisfied trait bounds
+  |
+  = note: the following trait bounds were not satisfied:
+          `NoDisplay: std::fmt::Display`
+          which is required by `&NoDisplay: DisplayAsDisplay`
+note: the trait `std::fmt::Display` must be implemented
+ --> $RUST/core/src/fmt/mod.rs
+  |
+  | pub trait Display {
+  | ^^^^^^^^^^^^^^^^^
diff --git a/tests/ui/source-enum-not-error.stderr b/tests/ui/source-enum-not-error.stderr
index d01cba5..750c69e 100644
--- a/tests/ui/source-enum-not-error.stderr
+++ b/tests/ui/source-enum-not-error.stderr
@@ -1,28 +1,22 @@
 error[E0599]: the method `as_dyn_error` exists for reference `&NotError`, but its trait bounds were not satisfied
-   --> tests/ui/source-enum-not-error.rs:10:9
-    |
-4   | pub struct NotError;
-    | --------------------
-    | |
-    | doesn't satisfy `NotError: AsDynError`
-    | doesn't satisfy `NotError: std::error::Error`
+  --> tests/ui/source-enum-not-error.rs:10:9
+   |
+4  | pub struct NotError;
+   | -------------------
+   | |
+   | doesn't satisfy `NotError: AsDynError<'_>`
+   | doesn't satisfy `NotError: std::error::Error`
 ...
-10  |         source: NotError,
-    |         ^^^^^^ method cannot be called on `&NotError` due to unsatisfied trait bounds
-    |
-    = note: the following trait bounds were not satisfied:
-            `NotError: std::error::Error`
-            which is required by `NotError: AsDynError`
-            `&NotError: std::error::Error`
-            which is required by `&NotError: AsDynError`
-note: the following trait must be implemented
-   --> $RUST/std/src/error.rs
-    |
-    | / pub trait Error: Debug + Display {
-    | |     /// The lower-level source of this error, if any.
-    | |     ///
-    | |     /// # Examples
-...   |
-    | |     }
-    | | }
-    | |_^
+10 |         source: NotError,
+   |         ^^^^^^ method cannot be called on `&NotError` due to unsatisfied trait bounds
+   |
+   = note: the following trait bounds were not satisfied:
+           `NotError: std::error::Error`
+           which is required by `NotError: AsDynError<'_>`
+           `&NotError: std::error::Error`
+           which is required by `&NotError: AsDynError<'_>`
+note: the trait `std::error::Error` must be implemented
+  --> $RUST/core/src/error.rs
+   |
+   | pub trait Error: Debug + Display {
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/tests/ui/source-struct-not-error.stderr b/tests/ui/source-struct-not-error.stderr
index be1331a..b98460f 100644
--- a/tests/ui/source-struct-not-error.stderr
+++ b/tests/ui/source-struct-not-error.stderr
@@ -1,27 +1,21 @@
 error[E0599]: the method `as_dyn_error` exists for struct `NotError`, but its trait bounds were not satisfied
-   --> tests/ui/source-struct-not-error.rs:9:5
-    |
-4   | struct NotError;
-    | ----------------
-    | |
-    | method `as_dyn_error` not found for this
-    | doesn't satisfy `NotError: AsDynError`
-    | doesn't satisfy `NotError: std::error::Error`
+ --> tests/ui/source-struct-not-error.rs:9:5
+  |
+4 | struct NotError;
+  | ---------------
+  | |
+  | method `as_dyn_error` not found for this struct
+  | doesn't satisfy `NotError: AsDynError<'_>`
+  | doesn't satisfy `NotError: std::error::Error`
 ...
-9   |     source: NotError,
-    |     ^^^^^^ method cannot be called on `NotError` due to unsatisfied trait bounds
-    |
-    = note: the following trait bounds were not satisfied:
-            `NotError: std::error::Error`
-            which is required by `NotError: AsDynError`
-note: the following trait must be implemented
-   --> $RUST/std/src/error.rs
-    |
-    | / pub trait Error: Debug + Display {
-    | |     /// The lower-level source of this error, if any.
-    | |     ///
-    | |     /// # Examples
-...   |
-    | |     }
-    | | }
-    | |_^
+9 |     source: NotError,
+  |     ^^^^^^ method cannot be called on `NotError` due to unsatisfied trait bounds
+  |
+  = note: the following trait bounds were not satisfied:
+          `NotError: std::error::Error`
+          which is required by `NotError: AsDynError<'_>`
+note: the trait `std::error::Error` must be implemented
+ --> $RUST/core/src/error.rs
+  |
+  | pub trait Error: Debug + Display {
+  | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^