aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2022-05-09 20:36:33 +0000
committerAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2022-05-09 20:36:33 +0000
commitc169fb29f76dfdb709529d661360572d6bf22714 (patch)
treeeb06821bbddbfa03cbbd4d43809f6ce410205f48
parentbc338c414ab221f15b0186f281d4aa989a46abff (diff)
parenta0b3187c100b0c81e2330b1b98983a1d08c22dff (diff)
downloadthiserror-android13-mainline-media-release.tar.gz
Change-Id: If7210d1df6c8c5fd113e983a6f2a75f3c72e0a54
-rw-r--r--.cargo_vcs_info.json7
-rw-r--r--.github/workflows/ci.yml10
-rw-r--r--Android.bp15
-rw-r--r--Cargo.toml16
-rw-r--r--Cargo.toml.orig7
-rw-r--r--METADATA10
-rw-r--r--README.md14
-rw-r--r--TEST_MAPPING125
-rw-r--r--cargo2android.json8
-rw-r--r--rust-toolchain.toml2
-rw-r--r--src/aserror.rs28
-rw-r--r--src/lib.rs22
-rw-r--r--tests/test_backtrace.rs39
-rw-r--r--tests/test_deprecated.rs10
-rw-r--r--tests/test_from.rs23
-rw-r--r--tests/test_generics.rs161
-rw-r--r--tests/test_source.rs6
-rw-r--r--tests/test_transparent.rs21
-rw-r--r--tests/ui/bad-field-attr.stderr2
-rw-r--r--tests/ui/concat-display.stderr4
-rw-r--r--tests/ui/duplicate-enum-source.stderr2
-rw-r--r--tests/ui/duplicate-fmt.stderr2
-rw-r--r--tests/ui/duplicate-struct-source.stderr2
-rw-r--r--tests/ui/duplicate-transparent.stderr2
-rw-r--r--tests/ui/from-not-source.stderr2
-rw-r--r--tests/ui/lifetime.stderr4
-rw-r--r--tests/ui/missing-fmt.stderr2
-rw-r--r--tests/ui/no-display.stderr31
-rw-r--r--tests/ui/source-enum-not-error.stderr41
-rw-r--r--tests/ui/source-struct-not-error.stderr39
-rw-r--r--tests/ui/transparent-display.stderr2
-rw-r--r--tests/ui/transparent-enum-many.stderr2
-rw-r--r--tests/ui/transparent-enum-source.stderr2
-rw-r--r--tests/ui/transparent-struct-many.stderr2
-rw-r--r--tests/ui/transparent-struct-source.stderr2
-rw-r--r--tests/ui/unexpected-field-fmt.stderr2
-rw-r--r--tests/ui/unexpected-struct-source.stderr2
-rw-r--r--tests/ui/union.stderr2
38 files changed, 548 insertions, 125 deletions
diff --git a/.cargo_vcs_info.json b/.cargo_vcs_info.json
index 349cbda..cafa20e 100644
--- a/.cargo_vcs_info.json
+++ b/.cargo_vcs_info.json
@@ -1,5 +1,6 @@
{
"git": {
- "sha1": "1b0a84996b9492c0dc5779127a91c930f23a259e"
- }
-}
+ "sha1": "672e9525bbc2e5682c380d36974f34716b963591"
+ },
+ "path_in_vcs": ""
+} \ No newline at end of file
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 263e04c..61714b6 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -21,6 +21,7 @@ jobs:
- uses: dtolnay/rust-toolchain@master
with:
toolchain: ${{matrix.rust}}
+ components: rust-src
- run: cargo test --all
env:
RUSTFLAGS: ${{matrix.rustflags}}
@@ -36,7 +37,16 @@ jobs:
clippy:
name: Clippy
runs-on: ubuntu-latest
+ if: github.event_name != 'pull_request'
steps:
- uses: actions/checkout@v2
- uses: dtolnay/rust-toolchain@clippy
- run: cargo clippy --tests -- -Dclippy::all -Dclippy::pedantic
+
+ outdated:
+ name: Outdated
+ runs-on: ubuntu-latest
+ if: github.event_name != 'pull_request'
+ steps:
+ - uses: actions/checkout@v2
+ - run: cargo outdated --exit-code 1
diff --git a/Android.bp b/Android.bp
index b5ce3cb..b1dc159 100644
--- a/Android.bp
+++ b/Android.bp
@@ -41,20 +41,19 @@ rust_library {
name: "libthiserror",
host_supported: true,
crate_name: "thiserror",
+ cargo_env_compat: true,
+ cargo_pkg_version: "1.0.30",
srcs: ["src/lib.rs"],
edition: "2018",
proc_macros: ["libthiserror_impl"],
apex_available: [
"//apex_available:platform",
- "com.android.resolv",
+ "com.android.bluetooth",
+ "com.android.compos",
+ "com.android.resolv",
+ "com.android.uwb",
"com.android.virt",
],
+ vendor_available: true,
min_sdk_version: "29",
}
-
-// dependent_library ["feature_list"]
-// proc-macro2-1.0.26 "default,proc-macro"
-// quote-1.0.9 "default,proc-macro"
-// syn-1.0.71 "clone-impls,default,derive,parsing,printing,proc-macro,quote"
-// thiserror-impl-1.0.24
-// unicode-xid-0.2.1 "default"
diff --git a/Cargo.toml b/Cargo.toml
index e3ef65a..78c99d6 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -3,17 +3,17 @@
# When uploading crates to the registry Cargo will automatically
# "normalize" Cargo.toml files for maximal compatibility
# with all versions of Cargo and also rewrite `path` dependencies
-# to registry (e.g., crates.io) dependencies
+# to registry (e.g., crates.io) dependencies.
#
-# If you believe there's an error in this file please file an
-# issue against the rust-lang/cargo repository. If you're
-# editing this file be aware that the upstream Cargo.toml
-# will likely look very different (and much more reasonable)
+# If you are reading this file be aware that the original Cargo.toml
+# will likely look very different (and much more reasonable).
+# See Cargo.toml.orig for the original contents.
[package]
edition = "2018"
+rust-version = "1.31"
name = "thiserror"
-version = "1.0.24"
+version = "1.0.30"
authors = ["David Tolnay <dtolnay@gmail.com>"]
description = "derive(Error)"
documentation = "https://docs.rs/thiserror"
@@ -24,7 +24,7 @@ repository = "https://github.com/dtolnay/thiserror"
[package.metadata.docs.rs]
targets = ["x86_64-unknown-linux-gnu"]
[dependencies.thiserror-impl]
-version = "=1.0.24"
+version = "=1.0.30"
[dev-dependencies.anyhow]
version = "1.0"
@@ -35,5 +35,5 @@ version = "1.0"
version = "1.0"
[dev-dependencies.trybuild]
-version = "1.0.19"
+version = "1.0.49"
features = ["diff"]
diff --git a/Cargo.toml.orig b/Cargo.toml.orig
index 0517a91..efa9af1 100644
--- a/Cargo.toml.orig
+++ b/Cargo.toml.orig
@@ -1,8 +1,9 @@
[package]
name = "thiserror"
-version = "1.0.24"
+version = "1.0.30"
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"
@@ -11,13 +12,13 @@ categories = ["rust-patterns"]
readme = "README.md"
[dependencies]
-thiserror-impl = { version = "=1.0.24", path = "impl" }
+thiserror-impl = { version = "=1.0.30", path = "impl" }
[dev-dependencies]
anyhow = "1.0"
ref-cast = "1.0"
rustversion = "1.0"
-trybuild = { version = "1.0.19", features = ["diff"] }
+trybuild = { version = "1.0.49", features = ["diff"] }
[workspace]
members = ["impl"]
diff --git a/METADATA b/METADATA
index 3b9f5d5..e961418 100644
--- a/METADATA
+++ b/METADATA
@@ -7,13 +7,13 @@ third_party {
}
url {
type: ARCHIVE
- value: "https://static.crates.io/crates/thiserror/thiserror-1.0.24.crate"
+ value: "https://static.crates.io/crates/thiserror/thiserror-1.0.30.crate"
}
- version: "1.0.24"
+ version: "1.0.30"
license_type: NOTICE
last_upgrade_date {
- year: 2021
- month: 2
- day: 18
+ year: 2022
+ month: 3
+ day: 1
}
}
diff --git a/README.md b/README.md
index 76c436a..e12b693 100644
--- a/README.md
+++ b/README.md
@@ -137,6 +137,20 @@ pub enum DataStoreError {
}
```
+- 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.
+
+ ```rust
+ #[derive(Error, Debug)]
+ pub enum MyError {
+ Io {
+ #[backtrace]
+ source: io::Error,
+ },
+ }
+ ```
+
- Errors may use `error(transparent)` to forward the source and Display methods
straight through to an underlying error without adding an additional message.
This would be appropriate for enums that need an "anything else" variant.
diff --git a/TEST_MAPPING b/TEST_MAPPING
index c21ac98..eea7991 100644
--- a/TEST_MAPPING
+++ b/TEST_MAPPING
@@ -1,53 +1,150 @@
// Generated by update_crate_tests.py for tests that depend on this crate.
{
+ "imports": [
+ {
+ "path": "external/rust/crates/anyhow"
+ },
+ {
+ "path": "external/rust/crates/jni"
+ },
+ {
+ "path": "external/rust/crates/serde-xml-rs"
+ }
+ ],
"presubmit": [
{
- "name": "anyhow_device_test_tests_test_repr"
+ "name": "ZipFuseTest"
},
{
- "name": "keystore2_test"
+ "name": "apkdmverity.test"
+ },
+ {
+ "name": "authfs_device_test_src_lib"
},
{
- "name": "anyhow_device_test_tests_test_context"
+ "name": "diced_open_dice_cbor_test"
},
{
- "name": "libsqlite3-sys_device_test_src_lib"
+ "name": "diced_sample_inputs_test"
},
{
- "name": "anyhow_device_test_tests_test_downcast"
+ "name": "diced_test"
+ },
+ {
+ "name": "diced_utils_test"
+ },
+ {
+ "name": "diced_vendor_test"
+ },
+ {
+ "name": "doh_unit_test"
},
{
"name": "keystore2_crypto_test_rust"
},
{
- "name": "anyhow_device_test_tests_test_convert"
+ "name": "keystore2_selinux_concurrency_test"
+ },
+ {
+ "name": "keystore2_selinux_test"
},
{
- "name": "anyhow_device_test_tests_test_ffi"
+ "name": "keystore2_test"
},
{
- "name": "anyhow_device_test_tests_test_autotrait"
+ "name": "keystore2_test_utils_test"
},
{
- "name": "anyhow_device_test_tests_test_macros"
+ "name": "keystore2_vintf_test"
},
{
- "name": "anyhow_device_test_tests_test_boxed"
+ "name": "legacykeystore_test"
},
{
- "name": "anyhow_device_test_tests_test_chain"
+ "name": "libapkverify.integration_test"
},
{
- "name": "anyhow_device_test_src_lib"
+ "name": "libapkverify.test"
},
{
- "name": "anyhow_device_test_tests_test_source"
+ "name": "libcert_request_validator_tests"
},
{
- "name": "anyhow_device_test_tests_test_fmt"
+ "name": "librustutils_test"
+ },
+ {
+ "name": "microdroid_manager_test"
+ },
+ {
+ "name": "virtualizationservice_device_test"
+ }
+ ],
+ "presubmit-rust": [
+ {
+ "name": "ZipFuseTest"
+ },
+ {
+ "name": "apkdmverity.test"
+ },
+ {
+ "name": "authfs_device_test_src_lib"
+ },
+ {
+ "name": "diced_open_dice_cbor_test"
+ },
+ {
+ "name": "diced_sample_inputs_test"
+ },
+ {
+ "name": "diced_test"
+ },
+ {
+ "name": "diced_utils_test"
+ },
+ {
+ "name": "diced_vendor_test"
+ },
+ {
+ "name": "doh_unit_test"
+ },
+ {
+ "name": "keystore2_crypto_test_rust"
+ },
+ {
+ "name": "keystore2_selinux_concurrency_test"
},
{
"name": "keystore2_selinux_test"
+ },
+ {
+ "name": "keystore2_test"
+ },
+ {
+ "name": "keystore2_test_utils_test"
+ },
+ {
+ "name": "keystore2_vintf_test"
+ },
+ {
+ "name": "legacykeystore_test"
+ },
+ {
+ "name": "libapkverify.integration_test"
+ },
+ {
+ "name": "libapkverify.test"
+ },
+ {
+ "name": "libcert_request_validator_tests"
+ },
+ {
+ "name": "librustutils_test"
+ },
+ {
+ "name": "microdroid_manager_test"
+ },
+ {
+ "name": "virtualizationservice_device_test"
}
]
}
diff --git a/cargo2android.json b/cargo2android.json
index 9b5d982..9a52406 100644
--- a/cargo2android.json
+++ b/cargo2android.json
@@ -1,11 +1,15 @@
{
"apex-available": [
"//apex_available:platform",
+ "com.android.bluetooth",
+ "com.android.compos",
"com.android.resolv",
+ "com.android.uwb",
"com.android.virt"
],
"dependencies": true,
"device": true,
- "min_sdk_version": "29",
- "run": true
+ "min-sdk-version": "29",
+ "run": true,
+ "vendor-available": true
}
diff --git a/rust-toolchain.toml b/rust-toolchain.toml
new file mode 100644
index 0000000..20fe888
--- /dev/null
+++ b/rust-toolchain.toml
@@ -0,0 +1,2 @@
+[toolchain]
+components = ["rust-src"]
diff --git a/src/aserror.rs b/src/aserror.rs
index 8290296..c036b7b 100644
--- a/src/aserror.rs
+++ b/src/aserror.rs
@@ -1,33 +1,41 @@
use std::error::Error;
+use std::panic::UnwindSafe;
-pub trait AsDynError {
- fn as_dyn_error(&self) -> &(dyn Error + 'static);
+pub trait AsDynError<'a> {
+ fn as_dyn_error(&self) -> &(dyn Error + 'a);
}
-impl<T: Error + 'static> AsDynError for T {
+impl<'a, T: Error + 'a> AsDynError<'a> for T {
#[inline]
- fn as_dyn_error(&self) -> &(dyn Error + 'static) {
+ fn as_dyn_error(&self) -> &(dyn Error + 'a) {
self
}
}
-impl AsDynError for dyn Error + 'static {
+impl<'a> AsDynError<'a> for dyn Error + 'a {
#[inline]
- fn as_dyn_error(&self) -> &(dyn Error + 'static) {
+ fn as_dyn_error(&self) -> &(dyn Error + 'a) {
self
}
}
-impl AsDynError for dyn Error + Send + 'static {
+impl<'a> AsDynError<'a> for dyn Error + Send + 'a {
#[inline]
- fn as_dyn_error(&self) -> &(dyn Error + 'static) {
+ fn as_dyn_error(&self) -> &(dyn Error + 'a) {
self
}
}
-impl AsDynError for dyn Error + Send + Sync + 'static {
+impl<'a> AsDynError<'a> for dyn Error + Send + Sync + 'a {
#[inline]
- fn as_dyn_error(&self) -> &(dyn Error + 'static) {
+ fn as_dyn_error(&self) -> &(dyn Error + 'a) {
+ self
+ }
+}
+
+impl<'a> AsDynError<'a> for dyn Error + Send + Sync + UnwindSafe + 'a {
+ #[inline]
+ fn as_dyn_error(&self) -> &(dyn Error + 'a) {
self
}
}
diff --git a/src/lib.rs b/src/lib.rs
index 02941c8..2fae25c 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -161,6 +161,22 @@
//! # };
//! ```
//!
+//! - 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.
+//!
+//! ```rust
+//! # const IGNORE: &str = stringify! {
+//! #[derive(Error, Debug)]
+//! pub enum MyError {
+//! Io {
+//! #[backtrace]
+//! source: io::Error,
+//! },
+//! }
+//! # };
+//! ```
+//!
//! - Errors may use `error(transparent)` to forward the source and Display
//! methods straight through to an underlying error without adding an
//! additional message. This would be appropriate for enums that need an
@@ -185,7 +201,11 @@
//!
//! [`anyhow`]: https://github.com/dtolnay/anyhow
-#![allow(clippy::module_name_repetitions)]
+#![allow(
+ // Clippy bug: https://github.com/rust-lang/rust-clippy/issues/7421
+ clippy::doc_markdown,
+ clippy::module_name_repetitions,
+)]
mod aserror;
mod display;
diff --git a/tests/test_backtrace.rs b/tests/test_backtrace.rs
index 09bc13d..42e37ca 100644
--- a/tests/test_backtrace.rs
+++ b/tests/test_backtrace.rs
@@ -7,8 +7,15 @@ use thiserror::Error;
pub struct Inner;
#[cfg(thiserror_nightly_testing)]
+#[derive(Error, Debug)]
+#[error("...")]
+pub struct InnerBacktrace {
+ backtrace: std::backtrace::Backtrace,
+}
+
+#[cfg(thiserror_nightly_testing)]
pub mod structs {
- use super::Inner;
+ use super::{Inner, InnerBacktrace};
use std::backtrace::Backtrace;
use std::error::Error;
use std::sync::Arc;
@@ -52,6 +59,14 @@ pub mod structs {
#[derive(Error, Debug)]
#[error("...")]
+ pub struct CombinedBacktraceFrom {
+ #[from]
+ #[backtrace]
+ source: InnerBacktrace,
+ }
+
+ #[derive(Error, Debug)]
+ #[error("...")]
pub struct OptBacktraceFrom {
#[from]
source: Inner,
@@ -93,6 +108,11 @@ pub mod structs {
let error = BacktraceFrom::from(Inner);
assert!(error.backtrace().is_some());
+ let error = CombinedBacktraceFrom::from(InnerBacktrace {
+ backtrace: Backtrace::capture(),
+ });
+ assert!(error.backtrace().is_some());
+
let error = OptBacktraceFrom::from(Inner);
assert!(error.backtrace().is_some());
@@ -103,7 +123,7 @@ pub mod structs {
#[cfg(thiserror_nightly_testing)]
pub mod enums {
- use super::Inner;
+ use super::{Inner, InnerBacktrace};
use std::backtrace::Backtrace;
use std::error::Error;
use std::sync::Arc;
@@ -154,6 +174,16 @@ pub mod enums {
}
#[derive(Error, Debug)]
+ pub enum CombinedBacktraceFrom {
+ #[error("...")]
+ Test {
+ #[from]
+ #[backtrace]
+ source: InnerBacktrace,
+ },
+ }
+
+ #[derive(Error, Debug)]
pub enum OptBacktraceFrom {
#[error("...")]
Test {
@@ -200,6 +230,11 @@ pub mod enums {
let error = BacktraceFrom::from(Inner);
assert!(error.backtrace().is_some());
+ let error = CombinedBacktraceFrom::from(InnerBacktrace {
+ backtrace: Backtrace::capture(),
+ });
+ assert!(error.backtrace().is_some());
+
let error = OptBacktraceFrom::from(Inner);
assert!(error.backtrace().is_some());
diff --git a/tests/test_deprecated.rs b/tests/test_deprecated.rs
deleted file mode 100644
index 5524666..0000000
--- a/tests/test_deprecated.rs
+++ /dev/null
@@ -1,10 +0,0 @@
-#![deny(deprecated, clippy::all, clippy::pedantic)]
-
-use thiserror::Error;
-
-#[derive(Error, Debug)]
-pub enum Error {
- #[deprecated]
- #[error("...")]
- Deprecated,
-}
diff --git a/tests/test_from.rs b/tests/test_from.rs
index e8f0161..a25ce35 100644
--- a/tests/test_from.rs
+++ b/tests/test_from.rs
@@ -12,10 +12,21 @@ pub struct ErrorStruct {
#[derive(Error, Debug)]
#[error("...")]
+pub struct ErrorStructOptional {
+ #[from]
+ source: Option<io::Error>,
+}
+
+#[derive(Error, Debug)]
+#[error("...")]
pub struct ErrorTuple(#[from] io::Error);
#[derive(Error, Debug)]
#[error("...")]
+pub struct ErrorTupleOptional(#[from] Option<io::Error>);
+
+#[derive(Error, Debug)]
+#[error("...")]
pub enum ErrorEnum {
Test {
#[from]
@@ -25,6 +36,15 @@ pub enum ErrorEnum {
#[derive(Error, Debug)]
#[error("...")]
+pub enum ErrorEnumOptional {
+ Test {
+ #[from]
+ source: Option<io::Error>,
+ },
+}
+
+#[derive(Error, Debug)]
+#[error("...")]
pub enum Many {
Any(#[from] anyhow::Error),
Io(#[from] io::Error),
@@ -35,7 +55,10 @@ fn assert_impl<T: From<io::Error>>() {}
#[test]
fn test_from() {
assert_impl::<ErrorStruct>();
+ assert_impl::<ErrorStructOptional>();
assert_impl::<ErrorTuple>();
+ assert_impl::<ErrorTupleOptional>();
assert_impl::<ErrorEnum>();
+ assert_impl::<ErrorEnumOptional>();
assert_impl::<Many>();
}
diff --git a/tests/test_generics.rs b/tests/test_generics.rs
new file mode 100644
index 0000000..f5e1de2
--- /dev/null
+++ b/tests/test_generics.rs
@@ -0,0 +1,161 @@
+#![deny(clippy::all, clippy::pedantic)]
+
+use std::fmt::{self, Debug, Display};
+use thiserror::Error;
+
+pub struct NoFormat;
+
+#[derive(Debug)]
+pub struct DebugOnly;
+
+pub struct DisplayOnly;
+
+impl Display for DisplayOnly {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ f.write_str("display only")
+ }
+}
+
+#[derive(Debug)]
+pub struct DebugAndDisplay;
+
+impl Display for DebugAndDisplay {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ f.write_str("debug and display")
+ }
+}
+
+// Should expand to:
+//
+// impl<E> Display for EnumDebugField<E>
+// where
+// E: Debug;
+//
+// impl<E> Error for EnumDebugField<E>
+// where
+// Self: Debug + Display;
+//
+#[derive(Error, Debug)]
+pub enum EnumDebugGeneric<E> {
+ #[error("{0:?}")]
+ FatalError(E),
+}
+
+// Should expand to:
+//
+// impl<E> Display for EnumFromGeneric<E>;
+//
+// impl<E> Error for EnumFromGeneric<E>
+// where
+// EnumDebugGeneric<E>: Error + 'static,
+// Self: Debug + Display;
+//
+#[derive(Error, Debug)]
+pub enum EnumFromGeneric<E> {
+ #[error("enum from generic")]
+ Source(#[from] EnumDebugGeneric<E>),
+}
+
+// Should expand to:
+//
+// impl<HasDisplay, HasDebug, HasNeither> Display
+// for EnumCompound<HasDisplay, HasDebug, HasNeither>
+// where
+// HasDisplay: Display,
+// HasDebug: Debug;
+//
+// impl<HasDisplay, HasDebug, HasNeither> Error
+// for EnumCompound<HasDisplay, HasDebug, HasNeither>
+// where
+// Self: Debug + Display;
+//
+#[derive(Error)]
+pub enum EnumCompound<HasDisplay, HasDebug, HasNeither> {
+ #[error("{0} {1:?}")]
+ DisplayDebug(HasDisplay, HasDebug),
+ #[error("{0}")]
+ Display(HasDisplay, HasNeither),
+ #[error("{1:?}")]
+ Debug(HasNeither, HasDebug),
+}
+
+impl<HasDisplay, HasDebug, HasNeither> Debug for EnumCompound<HasDisplay, HasDebug, HasNeither> {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ f.write_str("EnumCompound")
+ }
+}
+
+#[test]
+fn test_display_enum_compound() {
+ let mut instance: EnumCompound<DisplayOnly, DebugOnly, NoFormat>;
+
+ instance = EnumCompound::DisplayDebug(DisplayOnly, DebugOnly);
+ assert_eq!(format!("{}", instance), "display only DebugOnly");
+
+ instance = EnumCompound::Display(DisplayOnly, NoFormat);
+ assert_eq!(format!("{}", instance), "display only");
+
+ instance = EnumCompound::Debug(NoFormat, DebugOnly);
+ assert_eq!(format!("{}", instance), "DebugOnly");
+}
+
+// Should expand to:
+//
+// impl<E> Display for EnumTransparentGeneric<E>
+// where
+// E: Display;
+//
+// impl<E> Error for EnumTransparentGeneric<E>
+// where
+// E: Error,
+// Self: Debug + Display;
+//
+#[derive(Error, Debug)]
+pub enum EnumTransparentGeneric<E> {
+ #[error(transparent)]
+ Other(E),
+}
+
+// Should expand to:
+//
+// impl<E> Display for StructDebugGeneric<E>
+// where
+// E: Debug;
+//
+// impl<E> Error for StructDebugGeneric<E>
+// where
+// Self: Debug + Display;
+//
+#[derive(Error, Debug)]
+#[error("{underlying:?}")]
+pub struct StructDebugGeneric<E> {
+ pub underlying: E,
+}
+
+// Should expand to:
+//
+// impl<E> Error for StructFromGeneric<E>
+// where
+// StructDebugGeneric<E>: Error + 'static,
+// Self: Debug + Display;
+//
+#[derive(Error, Debug)]
+pub struct StructFromGeneric<E> {
+ #[from]
+ pub source: StructDebugGeneric<E>,
+}
+
+// Should expand to:
+//
+// impl<E> Display for StructTransparentGeneric<E>
+// where
+// E: Display;
+//
+// impl<E> Error for StructTransparentGeneric<E>
+// where
+// E: Error,
+// Self: Debug + Display;
+//
+#[derive(Error, Debug)]
+#[error(transparent)]
+pub struct StructTransparentGeneric<E>(E);
diff --git a/tests/test_source.rs b/tests/test_source.rs
index 860e727..ab16097 100644
--- a/tests/test_source.rs
+++ b/tests/test_source.rs
@@ -60,4 +60,8 @@ macro_rules! error_from_macro {
}
// Test that we generate impls with the proper hygiene
-error_from_macro!(#[error("Something")] Variant(#[from] io::Error));
+#[rustfmt::skip]
+error_from_macro! {
+ #[error("Something")]
+ Variant(#[from] io::Error)
+}
diff --git a/tests/test_transparent.rs b/tests/test_transparent.rs
index b862b25..84d7c91 100644
--- a/tests/test_transparent.rs
+++ b/tests/test_transparent.rs
@@ -57,3 +57,24 @@ fn test_anyhow() {
assert_eq!("outer", error.to_string());
assert_eq!("inner", error.source().unwrap().to_string());
}
+
+#[test]
+fn test_non_static() {
+ #[derive(Error, Debug)]
+ #[error(transparent)]
+ struct Error<'a> {
+ inner: ErrorKind<'a>,
+ }
+
+ #[derive(Error, Debug)]
+ enum ErrorKind<'a> {
+ #[error("unexpected token: {:?}", token)]
+ Unexpected { token: &'a str },
+ }
+
+ let error = Error {
+ inner: ErrorKind::Unexpected { token: "error" },
+ };
+ assert_eq!("unexpected token: \"error\"", error.to_string());
+ assert!(error.source().is_none());
+}
diff --git a/tests/ui/bad-field-attr.stderr b/tests/ui/bad-field-attr.stderr
index ecc4702..5fb5744 100644
--- a/tests/ui/bad-field-attr.stderr
+++ b/tests/ui/bad-field-attr.stderr
@@ -1,5 +1,5 @@
error: #[error(transparent)] needs to go outside the enum or struct, not on an individual field
- --> $DIR/bad-field-attr.rs:5:18
+ --> tests/ui/bad-field-attr.rs:5:18
|
5 | pub struct Error(#[error(transparent)] std::io::Error);
| ^^^^^^^^^^^^^^^^^^^^^
diff --git a/tests/ui/concat-display.stderr b/tests/ui/concat-display.stderr
index df1e19a..6ab4048 100644
--- a/tests/ui/concat-display.stderr
+++ b/tests/ui/concat-display.stderr
@@ -1,5 +1,5 @@
error: expected string literal
- --> $DIR/concat-display.rs:8:17
+ --> tests/ui/concat-display.rs:8:17
|
8 | #[error(concat!("invalid ", $what))]
| ^^^^^^
@@ -7,4 +7,4 @@ error: expected string literal
13 | error_type!(Error, "foo");
| -------------------------- in this macro invocation
|
- = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
+ = 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/duplicate-enum-source.stderr b/tests/ui/duplicate-enum-source.stderr
index 55d81be..4a4b2d3 100644
--- a/tests/ui/duplicate-enum-source.stderr
+++ b/tests/ui/duplicate-enum-source.stderr
@@ -1,5 +1,5 @@
error: duplicate #[source] attribute
- --> $DIR/duplicate-enum-source.rs:8:9
+ --> tests/ui/duplicate-enum-source.rs:8:9
|
8 | #[source]
| ^^^^^^^^^
diff --git a/tests/ui/duplicate-fmt.stderr b/tests/ui/duplicate-fmt.stderr
index 3206640..532b16b 100644
--- a/tests/ui/duplicate-fmt.stderr
+++ b/tests/ui/duplicate-fmt.stderr
@@ -1,5 +1,5 @@
error: only one #[error(...)] attribute is allowed
- --> $DIR/duplicate-fmt.rs:5:1
+ --> tests/ui/duplicate-fmt.rs:5:1
|
5 | #[error("...")]
| ^^^^^^^^^^^^^^^
diff --git a/tests/ui/duplicate-struct-source.stderr b/tests/ui/duplicate-struct-source.stderr
index 76fc6f5..c8de574 100644
--- a/tests/ui/duplicate-struct-source.stderr
+++ b/tests/ui/duplicate-struct-source.stderr
@@ -1,5 +1,5 @@
error: duplicate #[source] attribute
- --> $DIR/duplicate-struct-source.rs:7:5
+ --> tests/ui/duplicate-struct-source.rs:7:5
|
7 | #[source]
| ^^^^^^^^^
diff --git a/tests/ui/duplicate-transparent.stderr b/tests/ui/duplicate-transparent.stderr
index c963475..a830879 100644
--- a/tests/ui/duplicate-transparent.stderr
+++ b/tests/ui/duplicate-transparent.stderr
@@ -1,5 +1,5 @@
error: duplicate #[error(transparent)] attribute
- --> $DIR/duplicate-transparent.rs:5:1
+ --> tests/ui/duplicate-transparent.rs:5:1
|
5 | #[error(transparent)]
| ^^^^^^^^^^^^^^^^^^^^^
diff --git a/tests/ui/from-not-source.stderr b/tests/ui/from-not-source.stderr
index b656c8e..9713601 100644
--- a/tests/ui/from-not-source.stderr
+++ b/tests/ui/from-not-source.stderr
@@ -1,5 +1,5 @@
error: #[from] is only supported on the source field, not any other field
- --> $DIR/from-not-source.rs:7:5
+ --> tests/ui/from-not-source.rs:7:5
|
7 | #[from]
| ^^^^^^^
diff --git a/tests/ui/lifetime.stderr b/tests/ui/lifetime.stderr
index 5f86fa0..8b58136 100644
--- a/tests/ui/lifetime.stderr
+++ b/tests/ui/lifetime.stderr
@@ -1,11 +1,11 @@
error: non-static lifetimes are not allowed in the source of an error, because std::error::Error requires the source is dyn Error + 'static
- --> $DIR/lifetime.rs:6:26
+ --> tests/ui/lifetime.rs:6:26
|
6 | struct Error<'a>(#[from] Inner<'a>);
| ^^^^^^^^^
error: non-static lifetimes are not allowed in the source of an error, because std::error::Error requires the source is dyn Error + 'static
- --> $DIR/lifetime.rs:15:17
+ --> tests/ui/lifetime.rs:15:17
|
15 | Foo(#[from] Generic<&'a str>),
| ^^^^^^^^^^^^^^^^
diff --git a/tests/ui/missing-fmt.stderr b/tests/ui/missing-fmt.stderr
index 1d21b1b..c0be373 100644
--- a/tests/ui/missing-fmt.stderr
+++ b/tests/ui/missing-fmt.stderr
@@ -1,5 +1,5 @@
error: missing #[error("...")] display attribute
- --> $DIR/missing-fmt.rs:7:5
+ --> tests/ui/missing-fmt.rs:7:5
|
7 | B(usize),
| ^^^^^^^^
diff --git a/tests/ui/no-display.stderr b/tests/ui/no-display.stderr
index 8af2452..e6a52f5 100644
--- a/tests/ui/no-display.stderr
+++ b/tests/ui/no-display.stderr
@@ -1,12 +1,23 @@
error[E0599]: the method `as_display` exists for reference `&NoDisplay`, but its trait bounds were not satisfied
- --> $DIR/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`
+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;
+ | | }
+ | |_^
diff --git a/tests/ui/source-enum-not-error.stderr b/tests/ui/source-enum-not-error.stderr
index 2bf7aea..d01cba5 100644
--- a/tests/ui/source-enum-not-error.stderr
+++ b/tests/ui/source-enum-not-error.stderr
@@ -1,17 +1,28 @@
error[E0599]: the method `as_dyn_error` exists for reference `&NotError`, but its trait bounds were not satisfied
- --> $DIR/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`
+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
+... |
+ | | }
+ | | }
+ | |_^
diff --git a/tests/ui/source-struct-not-error.stderr b/tests/ui/source-struct-not-error.stderr
index 7a2c0fe..be1331a 100644
--- a/tests/ui/source-struct-not-error.stderr
+++ b/tests/ui/source-struct-not-error.stderr
@@ -1,16 +1,27 @@
error[E0599]: the method `as_dyn_error` exists for struct `NotError`, but its trait bounds were not satisfied
- --> $DIR/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
+ | 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`
+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
+... |
+ | | }
+ | | }
+ | |_^
diff --git a/tests/ui/transparent-display.stderr b/tests/ui/transparent-display.stderr
index 0148830..54d958b 100644
--- a/tests/ui/transparent-display.stderr
+++ b/tests/ui/transparent-display.stderr
@@ -1,5 +1,5 @@
error: cannot have both #[error(transparent)] and a display attribute
- --> $DIR/transparent-display.rs:5:1
+ --> tests/ui/transparent-display.rs:5:1
|
5 | #[error("...")]
| ^^^^^^^^^^^^^^^
diff --git a/tests/ui/transparent-enum-many.stderr b/tests/ui/transparent-enum-many.stderr
index 0c409ef..a9adfa5 100644
--- a/tests/ui/transparent-enum-many.stderr
+++ b/tests/ui/transparent-enum-many.stderr
@@ -1,5 +1,5 @@
error: #[error(transparent)] requires exactly one field
- --> $DIR/transparent-enum-many.rs:5:5
+ --> tests/ui/transparent-enum-many.rs:5:5
|
5 | / #[error(transparent)]
6 | | Other(anyhow::Error, String),
diff --git a/tests/ui/transparent-enum-source.stderr b/tests/ui/transparent-enum-source.stderr
index a4e6985..ccb9067 100644
--- a/tests/ui/transparent-enum-source.stderr
+++ b/tests/ui/transparent-enum-source.stderr
@@ -1,5 +1,5 @@
error: transparent variant can't contain #[source]
- --> $DIR/transparent-enum-source.rs:6:11
+ --> tests/ui/transparent-enum-source.rs:6:11
|
6 | Other(#[source] anyhow::Error),
| ^^^^^^^^^
diff --git a/tests/ui/transparent-struct-many.stderr b/tests/ui/transparent-struct-many.stderr
index 102f0b3..c0e3806 100644
--- a/tests/ui/transparent-struct-many.stderr
+++ b/tests/ui/transparent-struct-many.stderr
@@ -1,5 +1,5 @@
error: #[error(transparent)] requires exactly one field
- --> $DIR/transparent-struct-many.rs:4:1
+ --> tests/ui/transparent-struct-many.rs:4:1
|
4 | #[error(transparent)]
| ^^^^^^^^^^^^^^^^^^^^^
diff --git a/tests/ui/transparent-struct-source.stderr b/tests/ui/transparent-struct-source.stderr
index 16ea50b..3012ca3 100644
--- a/tests/ui/transparent-struct-source.stderr
+++ b/tests/ui/transparent-struct-source.stderr
@@ -1,5 +1,5 @@
error: transparent error struct can't contain #[source]
- --> $DIR/transparent-struct-source.rs:5:18
+ --> tests/ui/transparent-struct-source.rs:5:18
|
5 | pub struct Error(#[source] anyhow::Error);
| ^^^^^^^^^
diff --git a/tests/ui/unexpected-field-fmt.stderr b/tests/ui/unexpected-field-fmt.stderr
index 42d80db..bf3c24d 100644
--- a/tests/ui/unexpected-field-fmt.stderr
+++ b/tests/ui/unexpected-field-fmt.stderr
@@ -1,5 +1,5 @@
error: not expected here; the #[error(...)] attribute belongs on top of a struct or an enum variant
- --> $DIR/unexpected-field-fmt.rs:6:9
+ --> tests/ui/unexpected-field-fmt.rs:6:9
|
6 | #[error("...")]
| ^^^^^^^^^^^^^^^
diff --git a/tests/ui/unexpected-struct-source.stderr b/tests/ui/unexpected-struct-source.stderr
index f48d554..6f15841 100644
--- a/tests/ui/unexpected-struct-source.stderr
+++ b/tests/ui/unexpected-struct-source.stderr
@@ -1,5 +1,5 @@
error: not expected here; the #[source] attribute belongs on a specific field
- --> $DIR/unexpected-struct-source.rs:4:1
+ --> tests/ui/unexpected-struct-source.rs:4:1
|
4 | #[source]
| ^^^^^^^^^
diff --git a/tests/ui/union.stderr b/tests/ui/union.stderr
index a378011..3ec4d71 100644
--- a/tests/ui/union.stderr
+++ b/tests/ui/union.stderr
@@ -1,5 +1,5 @@
error: union as errors are not supported
- --> $DIR/union.rs:4:1
+ --> tests/ui/union.rs:4:1
|
4 | / pub union U {
5 | | msg: &'static str,