Upgrade anyhow to 1.0.79

This project was upgraded with external_updater.
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

Test: TreeHugger
Change-Id: Ia1018a59b95fc556734ba765e9bd9a2cfe18a7ac
diff --git a/.cargo_vcs_info.json b/.cargo_vcs_info.json
index 6baca52..b74022b 100644
--- a/.cargo_vcs_info.json
+++ b/.cargo_vcs_info.json
@@ -1,6 +1,6 @@
 {
   "git": {
-    "sha1": "6485caebde8e5c8bc313cd1a5ff6d70e58670b42"
+    "sha1": "71ab53dd2e89ff816bebaa452ad5a968f4c4105d"
   },
   "path_in_vcs": ""
 }
\ No newline at end of file
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 4ee51c8..017ddbd 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -24,10 +24,10 @@
     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}}
@@ -35,6 +35,9 @@
       - 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
@@ -50,7 +53,7 @@
         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}}
@@ -65,7 +68,7 @@
     runs-on: ubuntu-latest
     timeout-minutes: 45
     steps:
-      - uses: actions/checkout@v3
+      - uses: actions/checkout@v4
       - uses: dtolnay/rust-toolchain@nightly
       - run: cargo generate-lockfile -Z minimal-versions
       - run: cargo check --locked --features backtrace
@@ -77,19 +80,35 @@
     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
@@ -102,7 +121,7 @@
     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
@@ -115,6 +134,6 @@
     if: github.event_name != 'pull_request'
     timeout-minutes: 45
     steps:
-      - uses: actions/checkout@v3
+      - uses: actions/checkout@v4
       - uses: dtolnay/install@cargo-outdated
       - run: cargo outdated --workspace --exit-code 1
diff --git a/Android.bp b/Android.bp
index 3531fe0..f512722 100644
--- a/Android.bp
+++ b/Android.bp
@@ -42,7 +42,7 @@
     host_supported: true,
     crate_name: "anyhow",
     cargo_env_compat: true,
-    cargo_pkg_version: "1.0.75",
+    cargo_pkg_version: "1.0.79",
     srcs: ["src/lib.rs"],
     test_suites: ["general-tests"],
     auto_gen_config: true,
@@ -65,7 +65,7 @@
     host_supported: true,
     crate_name: "test_autotrait",
     cargo_env_compat: true,
-    cargo_pkg_version: "1.0.75",
+    cargo_pkg_version: "1.0.79",
     srcs: ["tests/test_autotrait.rs"],
     test_suites: ["general-tests"],
     auto_gen_config: true,
@@ -89,7 +89,7 @@
     host_supported: true,
     crate_name: "test_boxed",
     cargo_env_compat: true,
-    cargo_pkg_version: "1.0.75",
+    cargo_pkg_version: "1.0.79",
     srcs: ["tests/test_boxed.rs"],
     test_suites: ["general-tests"],
     auto_gen_config: true,
@@ -113,7 +113,7 @@
     host_supported: true,
     crate_name: "test_chain",
     cargo_env_compat: true,
-    cargo_pkg_version: "1.0.75",
+    cargo_pkg_version: "1.0.79",
     srcs: ["tests/test_chain.rs"],
     test_suites: ["general-tests"],
     auto_gen_config: true,
@@ -137,7 +137,7 @@
     host_supported: true,
     crate_name: "test_context",
     cargo_env_compat: true,
-    cargo_pkg_version: "1.0.75",
+    cargo_pkg_version: "1.0.79",
     srcs: ["tests/test_context.rs"],
     test_suites: ["general-tests"],
     auto_gen_config: true,
@@ -161,7 +161,7 @@
     host_supported: true,
     crate_name: "test_convert",
     cargo_env_compat: true,
-    cargo_pkg_version: "1.0.75",
+    cargo_pkg_version: "1.0.79",
     srcs: ["tests/test_convert.rs"],
     test_suites: ["general-tests"],
     auto_gen_config: true,
@@ -185,7 +185,7 @@
     host_supported: true,
     crate_name: "test_downcast",
     cargo_env_compat: true,
-    cargo_pkg_version: "1.0.75",
+    cargo_pkg_version: "1.0.79",
     srcs: ["tests/test_downcast.rs"],
     test_suites: ["general-tests"],
     auto_gen_config: true,
@@ -209,7 +209,7 @@
     host_supported: true,
     crate_name: "test_fmt",
     cargo_env_compat: true,
-    cargo_pkg_version: "1.0.75",
+    cargo_pkg_version: "1.0.79",
     srcs: ["tests/test_fmt.rs"],
     test_suites: ["general-tests"],
     auto_gen_config: true,
@@ -233,7 +233,7 @@
     host_supported: true,
     crate_name: "test_macros",
     cargo_env_compat: true,
-    cargo_pkg_version: "1.0.75",
+    cargo_pkg_version: "1.0.79",
     srcs: ["tests/test_macros.rs"],
     test_suites: ["general-tests"],
     auto_gen_config: true,
@@ -257,7 +257,7 @@
     host_supported: true,
     crate_name: "test_repr",
     cargo_env_compat: true,
-    cargo_pkg_version: "1.0.75",
+    cargo_pkg_version: "1.0.79",
     srcs: ["tests/test_repr.rs"],
     test_suites: ["general-tests"],
     auto_gen_config: true,
@@ -281,7 +281,7 @@
     host_supported: true,
     crate_name: "test_source",
     cargo_env_compat: true,
-    cargo_pkg_version: "1.0.75",
+    cargo_pkg_version: "1.0.79",
     srcs: ["tests/test_source.rs"],
     test_suites: ["general-tests"],
     auto_gen_config: true,
@@ -305,7 +305,7 @@
     host_supported: true,
     crate_name: "anyhow",
     cargo_env_compat: true,
-    cargo_pkg_version: "1.0.75",
+    cargo_pkg_version: "1.0.79",
     srcs: ["src/lib.rs"],
     edition: "2018",
     features: [
diff --git a/Cargo.toml b/Cargo.toml
index b6d042b..b92e7a3 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -13,7 +13,7 @@
 edition = "2018"
 rust-version = "1.39"
 name = "anyhow"
-version = "1.0.75"
+version = "1.0.79"
 authors = ["David Tolnay <[email protected]>"]
 description = "Flexible concrete Error type built on std::error::Error"
 documentation = "https://docs.rs/anyhow"
diff --git a/Cargo.toml.orig b/Cargo.toml.orig
index 88be2c2..3a5cce4 100644
--- a/Cargo.toml.orig
+++ b/Cargo.toml.orig
@@ -1,6 +1,6 @@
 [package]
 name = "anyhow"
-version = "1.0.75" # remember to update html_root_url
+version = "1.0.79"
 authors = ["David Tolnay <[email protected]>"]
 categories = ["rust-patterns", "no-std"]
 description = "Flexible concrete Error type built on std::error::Error"
@@ -16,6 +16,10 @@
 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]
diff --git a/METADATA b/METADATA
index 6ed96b3..447f25e 100644
--- a/METADATA
+++ b/METADATA
@@ -1,5 +1,5 @@
 # This project was upgraded with external_updater.
-# Usage: tools/external_updater/updater.sh update rust/crates/anyhow
+# 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"
@@ -7,14 +7,14 @@
 third_party {
   license_type: NOTICE
   last_upgrade_date {
-    year: 2023
-    month: 12
-    day: 4
+    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.75.crate"
-    version: "1.0.75"
+    value: "https://static.crates.io/crates/anyhow/anyhow-1.0.79.crate"
+    version: "1.0.79"
   }
 }
diff --git a/README.md b/README.md
index 6380c1c..ccf3097 100644
--- a/README.md
+++ b/README.md
@@ -75,10 +75,10 @@
   }
   ```
 
-- If using the nightly channel, or stable with `features = ["backtrace"]`, a
-  backtrace is captured and printed with the error if the underlying error type
-  does not already provide its own. In order to see backtraces, they must be
-  enabled through the environment variables described in [`std::backtrace`]:
+- If using Rust &ge; 1.65, a backtrace is captured and printed with the error if
+  the underlying error type does not already provide its own. In order to see
+  backtraces, they must be enabled through the environment variables described
+  in [`std::backtrace`]:
 
   - If you want panics and errors to both have backtraces, set
     `RUST_BACKTRACE=1`;
@@ -86,10 +86,7 @@
   - If you want only panics to have backtraces, set `RUST_BACKTRACE=1` and
     `RUST_LIB_BACKTRACE=0`.
 
-  The tracking issue for this feature is [rust-lang/rust#53487].
-
   [`std::backtrace`]: https://doc.rust-lang.org/std/backtrace/index.html#environment-variables
-  [rust-lang/rust#53487]: https://github.com/rust-lang/rust/issues/53487
 
 - Anyhow works with any error type that has an impl of `std::error::Error`,
   including ones defined in your crate. We do not bundle a `derive(Error)` macro
diff --git a/build.rs b/build.rs
index fc585cf..7e95e6b 100644
--- a/build.rs
+++ b/build.rs
@@ -1,9 +1,7 @@
-#![allow(clippy::option_if_let_else)]
-
 use std::env;
-use std::fs;
+use std::ffi::OsString;
 use std::path::Path;
-use std::process::{Command, ExitStatus, Stdio};
+use std::process::{self, Command, Stdio};
 use std::str;
 
 #[cfg(all(feature = "backtrace", not(feature = "std")))]
@@ -11,45 +9,53 @@
     "`backtrace` feature without `std` feature is not supported"
 }
 
-// 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)]
-
-    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);
-"#;
-
 fn main() {
+    let mut error_generic_member_access = false;
     if cfg!(feature = "std") {
-        match compile_probe() {
-            Some(status) if status.success() => println!("cargo:rustc-cfg=backtrace"),
-            _ => {}
+        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;
+        }
+
+        if error_generic_member_access {
+            println!("cargo:rustc-cfg=std_backtrace");
+            println!("cargo:rustc-cfg=error_generic_member_access");
+        }
+
+        if consider_rustc_bootstrap {
+            println!("cargo:rerun-if-env-changed=RUSTC_BOOTSTRAP");
         }
     }
 
@@ -59,15 +65,29 @@
     };
 
     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> {
+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:
@@ -76,13 +96,12 @@
         //     https://github.com/rust-lang/rust/issues/114839
         //
         // Let's just not use nightly features here.
-        return None;
+        return false;
     }
 
-    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()?;
+    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 @@
         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 @@
         }
     }
 
-    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 @@
     }
     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 <[email protected]>
-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 @@
  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 @@
  }
  
  #[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 @@
 +    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 7c1906b..65ad1cc 100644
--- a/src/backtrace.rs
+++ b/src/backtrace.rs
@@ -1,41 +1,41 @@
-#[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 std::error::request_ref::<std::backtrace::Backtrace>($err as &dyn std::error::Error) {
@@ -45,21 +45,25 @@
     };
 }
 
-#[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 d81b9a7..11b31ba 100644
--- a/src/context.rs
+++ b/src/context.rs
@@ -3,7 +3,7 @@
 use core::convert::Infallible;
 use core::fmt::{self, Debug, Display, Write};
 
-#[cfg(backtrace)]
+#[cfg(error_generic_member_access)]
 use std::error::Request;
 
 mod ext {
@@ -143,7 +143,7 @@
         Some(&self.error)
     }
 
-    #[cfg(backtrace)]
+    #[cfg(error_generic_member_access)]
     fn provide<'a>(&'a self, request: &mut Request<'a>) {
         StdError::provide(&self.error, request);
     }
@@ -157,7 +157,7 @@
         Some(unsafe { crate::ErrorImpl::error(self.error.inner.by_ref()) })
     }
 
-    #[cfg(backtrace)]
+    #[cfg(error_generic_member_access)]
     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 01402d4..f24c4a6 100644
--- a/src/error.rs
+++ b/src/error.rs
@@ -11,7 +11,7 @@
 #[cfg(not(anyhow_no_ptr_addr_of))]
 use core::ptr;
 use core::ptr::NonNull;
-#[cfg(backtrace)]
+#[cfg(error_generic_member_access)]
 use std::error::{self, Request};
 
 #[cfg(feature = "std")]
@@ -99,7 +99,10 @@
             #[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 @@
             #[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 @@
             #[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 @@
             #[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 @@
             #[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 @@
             #[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 @@
     ///
     /// # Stability
     ///
-    /// Standard library backtraces are only available on the nightly channel.
-    /// Tracking issue: [rust-lang/rust#53487][tracking].
-    ///
-    /// On stable compilers, this function is only available if the crate's
+    /// Standard library backtraces are only available when using Rust &ge;
+    /// 1.65. On older compilers, this function is only available if the crate's
     /// "backtrace" feature is enabled, and will use the `backtrace` crate as
-    /// the underlying backtrace implementation.
+    /// the underlying backtrace implementation. The return type of this
+    /// function on old compilers is `&(impl Debug + Display)`.
     ///
     /// ```toml
     /// [dependencies]
     /// anyhow = { version = "1.0", features = ["backtrace"] }
     /// ```
-    ///
-    /// [tracking]: https://github.com/rust-lang/rust/issues/53487
-    #[cfg(any(backtrace, feature = "backtrace"))]
-    #[cfg_attr(doc_cfg, doc(cfg(any(nightly, feature = "backtrace"))))]
+    #[cfg(any(std_backtrace, feature = "backtrace"))]
     pub fn backtrace(&self) -> &impl_backtrace!() {
         unsafe { ErrorImpl::backtrace(self.inner.by_ref()) }
     }
@@ -523,7 +537,7 @@
         }
     }
 
-    #[cfg(backtrace)]
+    #[cfg(error_generic_member_access)]
     pub(crate) fn provide<'a>(&'a self, request: &mut Request<'a>) {
         unsafe { ErrorImpl::provide(self.inner.by_ref(), request) }
     }
@@ -533,7 +547,7 @@
     // 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.
-    #[cfg(backtrace)]
+    #[cfg(error_generic_member_access)]
     #[doc(hidden)]
     pub fn thiserror_provide<'a>(&'a self, request: &mut Request<'a>) {
         Self::provide(self, request);
@@ -602,7 +616,10 @@
     #[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>,
 }
 
@@ -610,8 +627,8 @@
 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>.
@@ -620,8 +637,8 @@
     // 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>.
@@ -631,15 +648,15 @@
 {
     // 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
@@ -650,7 +667,8 @@
     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>.
@@ -659,7 +677,8 @@
     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>.
@@ -671,18 +690,18 @@
         // 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
     }
@@ -697,14 +716,18 @@
     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
@@ -718,10 +741,12 @@
     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
@@ -736,10 +761,12 @@
     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
@@ -756,15 +783,11 @@
     // 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() });
     }
 }
 
@@ -773,13 +796,14 @@
 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) }
     }
 }
 
@@ -789,13 +813,14 @@
 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) }
     }
 }
 
@@ -807,33 +832,34 @@
     // 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)
 }
 
@@ -853,7 +879,7 @@
 // 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
@@ -877,7 +903,7 @@
     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")]
@@ -886,42 +912,44 @@
         // 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 error::request_ref::<Backtrace>(Self::error(this));
-                #[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)]
+    #[cfg(error_generic_member_access)]
     unsafe fn provide<'a>(this: Ref<'a, Self>, request: &mut Request<'a>) {
-        if let Some(backtrace) = &this.deref().backtrace {
+        if let Some(backtrace) = unsafe { &this.deref().backtrace } {
             request.provide_ref(backtrace);
         }
-        Self::error(this).provide(request);
+        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) })
     }
 }
 
@@ -933,7 +961,7 @@
         unsafe { ErrorImpl::error(self.erase()).source() }
     }
 
-    #[cfg(backtrace)]
+    #[cfg(error_generic_member_access)]
     fn provide<'a>(&'a self, request: &mut Request<'a>) {
         unsafe { ErrorImpl::provide(self.erase(), request) }
     }
diff --git a/src/fmt.rs b/src/fmt.rs
index 03d8fd3..a99649b 100644
--- a/src/fmt.rs
+++ b/src/fmt.rs
@@ -5,10 +5,11 @@
 
 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 @@
     }
 
     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 @@
             }
         }
 
-        #[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/lib.rs b/src/lib.rs
index 5ec17ad..490a075 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -128,11 +128,10 @@
 //!   # ;
 //!   ```
 //!
-//! - If using the nightly channel, or stable with `features = ["backtrace"]`, a
-//!   backtrace is captured and printed with the error if the underlying error
-//!   type does not already provide its own. In order to see backtraces, they
-//!   must be enabled through the environment variables described in
-//!   [`std::backtrace`]:
+//! - If using Rust &ge; 1.65, a backtrace is captured and printed with the
+//!   error if the underlying error type does not already provide its own. In
+//!   order to see backtraces, they must be enabled through the environment
+//!   variables described in [`std::backtrace`]:
 //!
 //!   - If you want panics and errors to both have backtraces, set
 //!     `RUST_BACKTRACE=1`;
@@ -140,10 +139,7 @@
 //!   - If you want only panics to have backtraces, set `RUST_BACKTRACE=1` and
 //!     `RUST_LIB_BACKTRACE=0`.
 //!
-//!   The tracking issue for this feature is [rust-lang/rust#53487].
-//!
 //!   [`std::backtrace`]: https://doc.rust-lang.org/std/backtrace/index.html#environment-variables
-//!   [rust-lang/rust#53487]: https://github.com/rust-lang/rust/issues/53487
 //!
 //! - Anyhow works with any error type that has an impl of `std::error::Error`,
 //!   including ones defined in your crate. We do not bundle a `derive(Error)`
@@ -210,11 +206,16 @@
 //! 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.75")]
-#![cfg_attr(backtrace, feature(error_generic_member_access))]
+#![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,
@@ -229,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]
diff --git a/src/ptr.rs b/src/ptr.rs
index c7fe488..a1b7126 100644
--- a/src/ptr.rs
+++ b/src/ptr.rs
@@ -42,7 +42,7 @@
     }
 
     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 @@
     }
 
     pub unsafe fn deref(self) -> &'a T {
-        &*self.ptr.as_ptr()
+        unsafe { &*self.ptr.as_ptr() }
     }
 }
 
@@ -179,13 +179,13 @@
     }
 
     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 8a6d686..0eb5478 100644
--- a/src/wrapper.rs
+++ b/src/wrapper.rs
@@ -1,7 +1,7 @@
 use crate::StdError;
 use core::fmt::{self, Debug, Display};
 
-#[cfg(backtrace)]
+#[cfg(error_generic_member_access)]
 use std::error::Request;
 
 #[repr(transparent)]
@@ -74,7 +74,7 @@
         self.0.source()
     }
 
-    #[cfg(backtrace)]
+    #[cfg(error_generic_member_access)]
     fn provide<'a>(&'a self, request: &mut Request<'a>) {
         self.0.provide(request);
     }
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 @@
 }
 
 #[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));