summaryrefslogtreecommitdiffstats
path: root/third_party/rust/derive_more/tests/error
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-19 01:47:29 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-19 01:47:29 +0000
commit0ebf5bdf043a27fd3dfb7f92e0cb63d88954c44d (patch)
treea31f07c9bcca9d56ce61e9a1ffd30ef350d513aa /third_party/rust/derive_more/tests/error
parentInitial commit. (diff)
downloadfirefox-esr-0ebf5bdf043a27fd3dfb7f92e0cb63d88954c44d.tar.xz
firefox-esr-0ebf5bdf043a27fd3dfb7f92e0cb63d88954c44d.zip
Adding upstream version 115.8.0esr.upstream/115.8.0esr
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'third_party/rust/derive_more/tests/error')
-rw-r--r--third_party/rust/derive_more/tests/error/derives_for_enums_with_source.rs249
-rw-r--r--third_party/rust/derive_more/tests/error/derives_for_generic_enums_with_source.rs248
-rw-r--r--third_party/rust/derive_more/tests/error/derives_for_generic_structs_with_source.rs245
-rw-r--r--third_party/rust/derive_more/tests/error/derives_for_structs_with_source.rs249
-rw-r--r--third_party/rust/derive_more/tests/error/mod.rs56
-rw-r--r--third_party/rust/derive_more/tests/error/nightly/derives_for_enums_with_backtrace.rs272
-rw-r--r--third_party/rust/derive_more/tests/error/nightly/derives_for_generic_enums_with_backtrace.rs272
-rw-r--r--third_party/rust/derive_more/tests/error/nightly/derives_for_generic_structs_with_backtrace.rs275
-rw-r--r--third_party/rust/derive_more/tests/error/nightly/derives_for_structs_with_backtrace.rs280
-rw-r--r--third_party/rust/derive_more/tests/error/nightly/mod.rs85
10 files changed, 2231 insertions, 0 deletions
diff --git a/third_party/rust/derive_more/tests/error/derives_for_enums_with_source.rs b/third_party/rust/derive_more/tests/error/derives_for_enums_with_source.rs
new file mode 100644
index 0000000000..2513ab60cd
--- /dev/null
+++ b/third_party/rust/derive_more/tests/error/derives_for_enums_with_source.rs
@@ -0,0 +1,249 @@
+use super::*;
+
+derive_display!(TestErr);
+#[derive(Debug, Error)]
+enum TestErr {
+ Unit,
+ NamedImplicitNoSource {
+ field: i32,
+ },
+ NamedImplicitSource {
+ source: SimpleErr,
+ field: i32,
+ },
+ NamedExplicitNoSource {
+ #[error(not(source))]
+ source: SimpleErr,
+ field: i32,
+ },
+ NamedExplicitSource {
+ #[error(source)]
+ explicit_source: SimpleErr,
+ field: i32,
+ },
+ NamedExplicitNoSourceRedundant {
+ #[error(not(source))]
+ field: i32,
+ },
+ NamedExplicitSourceRedundant {
+ #[error(source)]
+ source: SimpleErr,
+ field: i32,
+ },
+ NamedExplicitSuppressesImplicit {
+ source: i32,
+ #[error(source)]
+ field: SimpleErr,
+ },
+ UnnamedImplicitNoSource(i32, i32),
+ UnnamedImplicitSource(SimpleErr),
+ UnnamedExplicitNoSource(#[error(not(source))] SimpleErr),
+ UnnamedExplicitSource(#[error(source)] SimpleErr, i32),
+ UnnamedExplicitNoSourceRedundant(
+ #[error(not(source))] i32,
+ #[error(not(source))] i32,
+ ),
+ UnnamedExplicitSourceRedundant(#[error(source)] SimpleErr),
+ NamedIgnore {
+ #[error(ignore)]
+ source: SimpleErr,
+ field: i32,
+ },
+ UnnamedIgnore(#[error(ignore)] SimpleErr),
+ NamedIgnoreRedundant {
+ #[error(ignore)]
+ field: i32,
+ },
+ UnnamedIgnoreRedundant(#[error(ignore)] i32, #[error(ignore)] i32),
+ #[error(ignore)]
+ NamedVariantIgnore {
+ source: SimpleErr,
+ field: i32,
+ },
+ #[error(ignore)]
+ UnnamedVariantIgnore(SimpleErr),
+ #[error(ignore)]
+ NamedVariantIgnoreRedundant {
+ field: i32,
+ },
+ #[error(ignore)]
+ UnnamedVariantIgnoreRedundant(i32, i32),
+}
+
+#[test]
+fn unit() {
+ assert!(TestErr::Unit.source().is_none());
+}
+
+#[test]
+fn named_implicit_no_source() {
+ let err = TestErr::NamedImplicitNoSource { field: 0 };
+
+ assert!(err.source().is_none());
+}
+
+#[test]
+fn named_implicit_source() {
+ let err = TestErr::NamedImplicitSource {
+ source: SimpleErr,
+ field: 0,
+ };
+
+ assert!(err.source().is_some());
+ assert!(err.source().unwrap().is::<SimpleErr>());
+}
+
+#[test]
+fn named_explicit_no_source() {
+ let err = TestErr::NamedExplicitNoSource {
+ source: SimpleErr,
+ field: 0,
+ };
+
+ assert!(err.source().is_none());
+}
+
+#[test]
+fn named_explicit_source() {
+ let err = TestErr::NamedExplicitSource {
+ explicit_source: SimpleErr,
+ field: 0,
+ };
+
+ assert!(err.source().is_some());
+ assert!(err.source().unwrap().is::<SimpleErr>());
+}
+
+#[test]
+fn named_explicit_no_source_redundant() {
+ let err = TestErr::NamedExplicitNoSourceRedundant { field: 0 };
+
+ assert!(err.source().is_none());
+}
+
+#[test]
+fn named_explicit_source_redundant() {
+ let err = TestErr::NamedExplicitSourceRedundant {
+ source: SimpleErr,
+ field: 0,
+ };
+
+ assert!(err.source().is_some());
+ assert!(err.source().unwrap().is::<SimpleErr>());
+}
+
+#[test]
+fn named_explicit_suppresses_implicit() {
+ let err = TestErr::NamedExplicitSuppressesImplicit {
+ source: 0,
+ field: SimpleErr,
+ };
+
+ assert!(err.source().is_some());
+ assert!(err.source().unwrap().is::<SimpleErr>());
+}
+
+#[test]
+fn unnamed_implicit_no_source() {
+ assert!(TestErr::UnnamedImplicitNoSource(0, 0).source().is_none());
+}
+
+#[test]
+fn unnamed_implicit_source() {
+ let err = TestErr::UnnamedImplicitSource(SimpleErr);
+
+ assert!(err.source().is_some());
+ assert!(err.source().unwrap().is::<SimpleErr>());
+}
+
+#[test]
+fn unnamed_explicit_no_source() {
+ let err = TestErr::UnnamedExplicitNoSource(SimpleErr);
+
+ assert!(err.source().is_none());
+}
+
+#[test]
+fn unnamed_explicit_source() {
+ let err = TestErr::UnnamedExplicitSource(SimpleErr, 0);
+
+ assert!(err.source().is_some());
+ assert!(err.source().unwrap().is::<SimpleErr>());
+}
+
+#[test]
+fn unnamed_explicit_no_source_redundant() {
+ let err = TestErr::UnnamedExplicitNoSourceRedundant(0, 0);
+
+ assert!(err.source().is_none());
+}
+
+#[test]
+fn unnamed_explicit_source_redundant() {
+ let err = TestErr::UnnamedExplicitSourceRedundant(SimpleErr);
+
+ assert!(err.source().is_some());
+ assert!(err.source().unwrap().is::<SimpleErr>());
+}
+
+#[test]
+fn named_ignore() {
+ let err = TestErr::NamedIgnore {
+ source: SimpleErr,
+ field: 0,
+ };
+
+ assert!(err.source().is_none());
+}
+
+#[test]
+fn unnamed_ignore() {
+ let err = TestErr::UnnamedIgnore(SimpleErr);
+
+ assert!(err.source().is_none());
+}
+
+#[test]
+fn named_ignore_redundant() {
+ let err = TestErr::NamedIgnoreRedundant { field: 0 };
+
+ assert!(err.source().is_none());
+}
+
+#[test]
+fn unnamed_ignore_redundant() {
+ let err = TestErr::UnnamedIgnoreRedundant(0, 0);
+
+ assert!(err.source().is_none());
+}
+
+#[test]
+fn named_variant_ignore() {
+ let err = TestErr::NamedVariantIgnore {
+ source: SimpleErr,
+ field: 0,
+ };
+
+ assert!(err.source().is_none());
+}
+
+#[test]
+fn unnamed_variant_ignore() {
+ let err = TestErr::UnnamedVariantIgnore(SimpleErr);
+
+ assert!(err.source().is_none())
+}
+
+#[test]
+fn named_variant_ignore_redundant() {
+ let err = TestErr::NamedVariantIgnoreRedundant { field: 0 };
+
+ assert!(err.source().is_none());
+}
+
+#[test]
+fn unnamed_variant_ignore_redundant() {
+ let err = TestErr::UnnamedVariantIgnoreRedundant(0, 0);
+
+ assert!(err.source().is_none())
+}
diff --git a/third_party/rust/derive_more/tests/error/derives_for_generic_enums_with_source.rs b/third_party/rust/derive_more/tests/error/derives_for_generic_enums_with_source.rs
new file mode 100644
index 0000000000..92f3b3ae9e
--- /dev/null
+++ b/third_party/rust/derive_more/tests/error/derives_for_generic_enums_with_source.rs
@@ -0,0 +1,248 @@
+use super::*;
+
+derive_display!(TestErr, T, E);
+#[derive(Debug, Error)]
+enum TestErr<E, T> {
+ Unit,
+ NamedImplicitNoSource {
+ field: T,
+ },
+ NamedImplicitSource {
+ source: E,
+ field: T,
+ },
+ NamedExplicitNoSource {
+ #[error(not(source))]
+ source: E,
+ field: T,
+ },
+ NamedExplicitSource {
+ #[error(source)]
+ explicit_source: E,
+ field: T,
+ },
+ NamedExplicitNoSourceRedundant {
+ #[error(not(source))]
+ field: T,
+ },
+ NamedExplicitSourceRedundant {
+ #[error(source)]
+ source: E,
+ field: T,
+ },
+ NamedExplicitSuppressesImplicit {
+ source: T,
+ #[error(source)]
+ field: E,
+ },
+ UnnamedImplicitNoSource(T, T),
+ UnnamedImplicitSource(E),
+ UnnamedExplicitNoSource(#[error(not(source))] E),
+ UnnamedExplicitSource(#[error(source)] E, T),
+ UnnamedExplicitNoSourceRedundant(#[error(not(source))] T, #[error(not(source))] T),
+ UnnamedExplicitSourceRedundant(#[error(source)] E),
+ NamedIgnore {
+ #[error(ignore)]
+ source: E,
+ field: T,
+ },
+ UnnamedIgnore(#[error(ignore)] E),
+ NamedIgnoreRedundant {
+ #[error(ignore)]
+ field: T,
+ },
+ UnnamedIgnoreRedundant(#[error(ignore)] T, #[error(ignore)] T),
+ #[error(ignore)]
+ NamedVariantIgnore {
+ source: E,
+ field: T,
+ },
+ #[error(ignore)]
+ UnnamedVariantIgnore(E),
+ #[error(ignore)]
+ NamedVariantIgnoreRedundant {
+ field: T,
+ },
+ #[error(ignore)]
+ UnnamedVariantIgnoreRedundant(T, T),
+}
+
+#[test]
+fn unit() {
+ assert!(TestErr::<SimpleErr, i32>::Unit.source().is_none());
+}
+
+#[test]
+fn named_implicit_no_source() {
+ let err = TestErr::<SimpleErr, _>::NamedImplicitNoSource { field: 0 };
+
+ assert!(err.source().is_none());
+}
+
+#[test]
+fn named_implicit_source() {
+ let err = TestErr::NamedImplicitSource {
+ source: SimpleErr,
+ field: 0,
+ };
+
+ assert!(err.source().is_some());
+ assert!(err.source().unwrap().is::<SimpleErr>());
+}
+
+#[test]
+fn named_explicit_no_source() {
+ let err = TestErr::NamedExplicitNoSource {
+ source: SimpleErr,
+ field: 0,
+ };
+
+ assert!(err.source().is_none());
+}
+
+#[test]
+fn named_explicit_source() {
+ let err = TestErr::NamedExplicitSource {
+ explicit_source: SimpleErr,
+ field: 0,
+ };
+
+ assert!(err.source().is_some());
+ assert!(err.source().unwrap().is::<SimpleErr>());
+}
+
+#[test]
+fn named_explicit_no_source_redundant() {
+ let err = TestErr::<SimpleErr, _>::NamedExplicitNoSourceRedundant { field: 0 };
+
+ assert!(err.source().is_none());
+}
+
+#[test]
+fn named_explicit_source_redundant() {
+ let err = TestErr::NamedExplicitSourceRedundant {
+ source: SimpleErr,
+ field: 0,
+ };
+
+ assert!(err.source().is_some());
+ assert!(err.source().unwrap().is::<SimpleErr>());
+}
+
+#[test]
+fn named_explicit_suppresses_implicit() {
+ let err = TestErr::NamedExplicitSuppressesImplicit {
+ source: 0,
+ field: SimpleErr,
+ };
+
+ assert!(err.source().is_some());
+ assert!(err.source().unwrap().is::<SimpleErr>());
+}
+
+#[test]
+fn unnamed_implicit_no_source() {
+ let err = TestErr::<SimpleErr, _>::UnnamedImplicitNoSource(0, 0);
+
+ assert!(err.source().is_none());
+}
+
+#[test]
+fn unnamed_implicit_source() {
+ let err = TestErr::<_, i32>::UnnamedImplicitSource(SimpleErr);
+
+ assert!(err.source().is_some());
+ assert!(err.source().unwrap().is::<SimpleErr>());
+}
+
+#[test]
+fn unnamed_explicit_no_source() {
+ let err = TestErr::<_, i32>::UnnamedExplicitNoSource(SimpleErr);
+
+ assert!(err.source().is_none());
+}
+
+#[test]
+fn unnamed_explicit_source() {
+ let err = TestErr::UnnamedExplicitSource(SimpleErr, 0);
+
+ assert!(err.source().is_some());
+ assert!(err.source().unwrap().is::<SimpleErr>());
+}
+
+#[test]
+fn unnamed_explicit_no_source_redundant() {
+ let err = TestErr::<SimpleErr, _>::UnnamedExplicitNoSourceRedundant(0, 0);
+
+ assert!(err.source().is_none());
+}
+
+#[test]
+fn unnamed_explicit_source_redundant() {
+ let err = TestErr::<_, i32>::UnnamedExplicitSourceRedundant(SimpleErr);
+
+ assert!(err.source().is_some());
+ assert!(err.source().unwrap().is::<SimpleErr>());
+}
+
+#[test]
+fn named_ignore() {
+ let err = TestErr::NamedIgnore {
+ source: SimpleErr,
+ field: 0,
+ };
+
+ assert!(err.source().is_none());
+}
+
+#[test]
+fn unnamed_ignore() {
+ let err = TestErr::<_, i32>::UnnamedIgnore(SimpleErr);
+
+ assert!(err.source().is_none());
+}
+
+#[test]
+fn named_ignore_redundant() {
+ let err = TestErr::<SimpleErr, _>::NamedIgnoreRedundant { field: 0 };
+
+ assert!(err.source().is_none());
+}
+
+#[test]
+fn unnamed_ignore_redundant() {
+ let err = TestErr::<SimpleErr, _>::UnnamedIgnoreRedundant(0, 0);
+
+ assert!(err.source().is_none());
+}
+
+#[test]
+fn named_variant_ignore() {
+ let err = TestErr::NamedVariantIgnore {
+ source: SimpleErr,
+ field: 0,
+ };
+
+ assert!(err.source().is_none());
+}
+
+#[test]
+fn unnamed_variant_ignore() {
+ let err = TestErr::<_, i32>::UnnamedVariantIgnore(SimpleErr);
+
+ assert!(err.source().is_none())
+}
+
+#[test]
+fn named_variant_ignore_redundant() {
+ let err = TestErr::<SimpleErr, _>::NamedVariantIgnoreRedundant { field: 0 };
+
+ assert!(err.source().is_none());
+}
+
+#[test]
+fn unnamed_variant_ignore_redundant() {
+ let err = TestErr::<SimpleErr, _>::UnnamedVariantIgnoreRedundant(0, 0);
+
+ assert!(err.source().is_none())
+}
diff --git a/third_party/rust/derive_more/tests/error/derives_for_generic_structs_with_source.rs b/third_party/rust/derive_more/tests/error/derives_for_generic_structs_with_source.rs
new file mode 100644
index 0000000000..248e3c97ff
--- /dev/null
+++ b/third_party/rust/derive_more/tests/error/derives_for_generic_structs_with_source.rs
@@ -0,0 +1,245 @@
+use super::*;
+
+#[test]
+fn named_implicit_no_source() {
+ derive_display!(TestErr, T);
+ #[derive(Default, Debug, Error)]
+ struct TestErr<T> {
+ field: T,
+ }
+
+ assert!(TestErr::<i32>::default().source().is_none());
+}
+
+#[test]
+fn named_implicit_source() {
+ derive_display!(TestErr, E, T);
+ #[derive(Default, Debug, Error)]
+ struct TestErr<E, T> {
+ source: E,
+ field: T,
+ }
+
+ let err = TestErr::<SimpleErr, i32>::default();
+ assert!(err.source().is_some());
+ assert!(err.source().unwrap().is::<SimpleErr>());
+}
+
+#[test]
+fn named_explicit_no_source() {
+ derive_display!(TestErr, E, T);
+ #[derive(Default, Debug, Error)]
+ struct TestErr<E, T> {
+ #[error(not(source))]
+ source: E,
+ field: T,
+ }
+
+ let err = TestErr::<SimpleErr, i32>::default();
+ assert!(err.source().is_none());
+}
+
+#[test]
+fn named_explicit_source() {
+ derive_display!(TestErr, E, T);
+ #[derive(Default, Debug, Error)]
+ struct TestErr<E, T> {
+ #[error(source)]
+ explicit_source: E,
+ field: T,
+ }
+
+ let err = TestErr::<SimpleErr, i32>::default();
+ assert!(err.source().is_some());
+ assert!(err.source().unwrap().is::<SimpleErr>());
+}
+
+#[test]
+fn named_explicit_no_source_redundant() {
+ derive_display!(TestErr, T);
+ #[derive(Default, Debug, Error)]
+ struct TestErr<T> {
+ #[error(not(source))]
+ field: T,
+ }
+
+ assert!(TestErr::<i32>::default().source().is_none());
+}
+
+#[test]
+fn named_explicit_source_redundant() {
+ derive_display!(TestErr, E, T);
+ #[derive(Default, Debug, Error)]
+ struct TestErr<E, T> {
+ #[error(source)]
+ source: E,
+ field: T,
+ }
+
+ let err = TestErr::<SimpleErr, i32>::default();
+ assert!(err.source().is_some());
+ assert!(err.source().unwrap().is::<SimpleErr>());
+}
+
+#[test]
+fn named_explicit_suppresses_implicit() {
+ derive_display!(TestErr, E, T);
+ #[derive(Default, Debug, Error)]
+ struct TestErr<E, T> {
+ source: E,
+ #[error(source)]
+ field: T,
+ }
+
+ let err = TestErr::<i32, SimpleErr>::default();
+ assert!(err.source().is_some());
+ assert!(err.source().unwrap().is::<SimpleErr>());
+}
+
+#[test]
+fn unnamed_implicit_no_source() {
+ derive_display!(TestErr, T);
+ #[derive(Default, Debug, Error)]
+ struct TestErr<T>(T, T);
+
+ assert!(TestErr::<i32>::default().source().is_none());
+}
+
+#[test]
+fn unnamed_implicit_source() {
+ derive_display!(TestErr, E);
+ #[derive(Default, Debug, Error)]
+ struct TestErr<E>(E);
+
+ let err = TestErr::<SimpleErr>::default();
+ assert!(err.source().is_some());
+ assert!(err.source().unwrap().is::<SimpleErr>());
+}
+
+#[test]
+fn unnamed_explicit_no_source() {
+ derive_display!(TestErr, E);
+ #[derive(Default, Debug, Error)]
+ struct TestErr<E>(#[error(not(source))] E);
+
+ assert!(TestErr::<SimpleErr>::default().source().is_none());
+}
+
+#[test]
+fn unnamed_explicit_source() {
+ derive_display!(TestErr, E, T);
+ #[derive(Default, Debug, Error)]
+ struct TestErr<E, T>(#[error(source)] E, T);
+
+ let err = TestErr::<SimpleErr, i32>::default();
+ assert!(err.source().is_some());
+ assert!(err.source().unwrap().is::<SimpleErr>());
+}
+
+#[test]
+fn unnamed_explicit_no_source_redundant() {
+ derive_display!(TestErr, T);
+ #[derive(Default, Debug, Error)]
+ struct TestErr<T>(#[error(not(source))] T, #[error(not(source))] T);
+
+ assert!(TestErr::<i32>::default().source().is_none());
+}
+
+#[test]
+fn unnamed_explicit_source_redundant() {
+ derive_display!(TestErr, E);
+ #[derive(Default, Debug, Error)]
+ struct TestErr<E>(#[error(source)] E);
+
+ let err = TestErr::<SimpleErr>::default();
+ assert!(err.source().is_some());
+ assert!(err.source().unwrap().is::<SimpleErr>());
+}
+
+#[test]
+fn named_ignore() {
+ derive_display!(TestErr, E, T);
+ #[derive(Default, Debug, Error)]
+ struct TestErr<E, T> {
+ #[error(ignore)]
+ source: E,
+ field: T,
+ }
+
+ assert!(TestErr::<SimpleErr, i32>::default().source().is_none());
+}
+
+#[test]
+fn unnamed_ignore() {
+ derive_display!(TestErr, E);
+ #[derive(Default, Debug, Error)]
+ struct TestErr<E>(#[error(ignore)] E);
+
+ assert!(TestErr::<SimpleErr>::default().source().is_none());
+}
+
+#[test]
+fn named_ignore_redundant() {
+ derive_display!(TestErr, T);
+ #[derive(Default, Debug, Error)]
+ struct TestErr<T> {
+ #[error(ignore)]
+ field: T,
+ }
+
+ assert!(TestErr::<i32>::default().source().is_none());
+}
+
+#[test]
+fn unnamed_ignore_redundant() {
+ derive_display!(TestErr, T);
+ #[derive(Default, Debug, Error)]
+ struct TestErr<T>(#[error(ignore)] T, #[error(ignore)] T);
+
+ assert!(TestErr::<i32>::default().source().is_none());
+}
+
+#[test]
+fn named_struct_ignore() {
+ derive_display!(TestErr, E, T);
+ #[derive(Default, Debug, Error)]
+ #[error(ignore)]
+ struct TestErr<E, T> {
+ source: E,
+ field: T,
+ }
+
+ assert!(TestErr::<SimpleErr, i32>::default().source().is_none())
+}
+
+#[test]
+fn unnamed_struct_ignore() {
+ derive_display!(TestErr, E);
+ #[derive(Default, Debug, Error)]
+ #[error(ignore)]
+ struct TestErr<E>(E);
+
+ assert!(TestErr::<SimpleErr>::default().source().is_none())
+}
+
+#[test]
+fn named_struct_ignore_redundant() {
+ derive_display!(TestErr, T);
+ #[derive(Default, Debug, Error)]
+ #[error(ignore)]
+ struct TestErr<T> {
+ field: T,
+ }
+
+ assert!(TestErr::<i32>::default().source().is_none())
+}
+
+#[test]
+fn unnamed_struct_ignore_redundant() {
+ derive_display!(TestErr, T);
+ #[derive(Default, Debug, Error)]
+ #[error(ignore)]
+ struct TestErr<T>(T, T);
+
+ assert!(TestErr::<i32>::default().source().is_none())
+}
diff --git a/third_party/rust/derive_more/tests/error/derives_for_structs_with_source.rs b/third_party/rust/derive_more/tests/error/derives_for_structs_with_source.rs
new file mode 100644
index 0000000000..d46bd5ad58
--- /dev/null
+++ b/third_party/rust/derive_more/tests/error/derives_for_structs_with_source.rs
@@ -0,0 +1,249 @@
+use super::*;
+
+#[test]
+fn unit() {
+ assert!(SimpleErr.source().is_none());
+}
+
+#[test]
+fn named_implicit_no_source() {
+ derive_display!(TestErr);
+ #[derive(Default, Debug, Error)]
+ struct TestErr {
+ field: i32,
+ }
+
+ assert!(TestErr::default().source().is_none());
+}
+
+#[test]
+fn named_implicit_source() {
+ derive_display!(TestErr);
+ #[derive(Default, Debug, Error)]
+ struct TestErr {
+ source: SimpleErr,
+ field: i32,
+ }
+
+ let err = TestErr::default();
+ assert!(err.source().is_some());
+ assert!(err.source().unwrap().is::<SimpleErr>());
+}
+
+#[test]
+fn named_explicit_no_source() {
+ derive_display!(TestErr);
+ #[derive(Default, Debug, Error)]
+ struct TestErr {
+ #[error(not(source))]
+ source: SimpleErr,
+ field: i32,
+ }
+
+ assert!(TestErr::default().source().is_none());
+}
+
+#[test]
+fn named_explicit_source() {
+ derive_display!(TestErr);
+ #[derive(Default, Debug, Error)]
+ struct TestErr {
+ #[error(source)]
+ explicit_source: SimpleErr,
+ field: i32,
+ }
+
+ let err = TestErr::default();
+ assert!(err.source().is_some());
+ assert!(err.source().unwrap().is::<SimpleErr>());
+}
+
+#[test]
+fn named_explicit_no_source_redundant() {
+ derive_display!(TestErr);
+ #[derive(Default, Debug, Error)]
+ struct TestErr {
+ #[error(not(source))]
+ field: i32,
+ }
+
+ assert!(TestErr::default().source().is_none());
+}
+
+#[test]
+fn named_explicit_source_redundant() {
+ derive_display!(TestErr);
+ #[derive(Default, Debug, Error)]
+ struct TestErr {
+ #[error(source)]
+ source: SimpleErr,
+ field: i32,
+ }
+
+ let err = TestErr::default();
+ assert!(err.source().is_some());
+ assert!(err.source().unwrap().is::<SimpleErr>());
+}
+
+#[test]
+fn named_explicit_suppresses_implicit() {
+ derive_display!(TestErr);
+ #[derive(Default, Debug, Error)]
+ struct TestErr {
+ source: i32,
+ #[error(source)]
+ field: SimpleErr,
+ }
+
+ let err = TestErr::default();
+ assert!(err.source().is_some());
+ assert!(err.source().unwrap().is::<SimpleErr>());
+}
+
+#[test]
+fn unnamed_implicit_no_source() {
+ derive_display!(TestErr);
+ #[derive(Default, Debug, Error)]
+ struct TestErr(i32, i32);
+
+ assert!(TestErr::default().source().is_none());
+}
+
+#[test]
+fn unnamed_implicit_source() {
+ derive_display!(TestErr);
+ #[derive(Default, Debug, Error)]
+ struct TestErr(SimpleErr);
+
+ let err = TestErr::default();
+ assert!(err.source().is_some());
+ assert!(err.source().unwrap().is::<SimpleErr>());
+}
+
+#[test]
+fn unnamed_explicit_no_source() {
+ derive_display!(TestErr);
+ #[derive(Default, Debug, Error)]
+ struct TestErr(#[error(not(source))] SimpleErr);
+
+ assert!(TestErr::default().source().is_none());
+}
+
+#[test]
+fn unnamed_explicit_source() {
+ derive_display!(TestErr);
+ #[derive(Default, Debug, Error)]
+ struct TestErr(#[error(source)] SimpleErr, i32);
+
+ let err = TestErr::default();
+ assert!(err.source().is_some());
+ assert!(err.source().unwrap().is::<SimpleErr>());
+}
+
+#[test]
+fn unnamed_explicit_no_source_redundant() {
+ derive_display!(TestErr);
+ #[derive(Default, Debug, Error)]
+ struct TestErr(#[error(not(source))] i32, #[error(not(source))] i32);
+
+ assert!(TestErr::default().source().is_none());
+}
+
+#[test]
+fn unnamed_explicit_source_redundant() {
+ derive_display!(TestErr);
+ #[derive(Default, Debug, Error)]
+ struct TestErr(#[error(source)] SimpleErr);
+
+ let err = TestErr::default();
+ assert!(err.source().is_some());
+ assert!(err.source().unwrap().is::<SimpleErr>());
+}
+
+#[test]
+fn named_ignore() {
+ derive_display!(TestErr);
+ #[derive(Default, Debug, Error)]
+ struct TestErr {
+ #[error(ignore)]
+ source: SimpleErr,
+ field: i32,
+ }
+
+ assert!(TestErr::default().source().is_none());
+}
+
+#[test]
+fn unnamed_ignore() {
+ derive_display!(TestErr);
+ #[derive(Default, Debug, Error)]
+ struct TestErr(#[error(ignore)] SimpleErr);
+
+ assert!(TestErr::default().source().is_none());
+}
+
+#[test]
+fn named_ignore_redundant() {
+ derive_display!(TestErr);
+ #[derive(Default, Debug, Error)]
+ struct TestErr {
+ #[error(ignore)]
+ field: i32,
+ }
+
+ assert!(TestErr::default().source().is_none());
+}
+
+#[test]
+fn unnamed_ignore_redundant() {
+ derive_display!(TestErr);
+ #[derive(Default, Debug, Error)]
+ struct TestErr(#[error(ignore)] i32, #[error(ignore)] i32);
+
+ assert!(TestErr::default().source().is_none());
+}
+
+#[test]
+fn named_struct_ignore() {
+ derive_display!(TestErr);
+ #[derive(Default, Debug, Error)]
+ #[error(ignore)]
+ struct TestErr {
+ source: SimpleErr,
+ field: i32,
+ }
+
+ assert!(TestErr::default().source().is_none())
+}
+
+#[test]
+fn unnamed_struct_ignore() {
+ derive_display!(TestErr);
+ #[derive(Default, Debug, Error)]
+ #[error(ignore)]
+ struct TestErr(SimpleErr);
+
+ assert!(TestErr::default().source().is_none())
+}
+
+#[test]
+fn named_struct_ignore_redundant() {
+ derive_display!(TestErr);
+ #[derive(Default, Debug, Error)]
+ #[error(ignore)]
+ struct TestErr {
+ field: i32,
+ }
+
+ assert!(TestErr::default().source().is_none())
+}
+
+#[test]
+fn unnamed_struct_ignore_redundant() {
+ derive_display!(TestErr);
+ #[derive(Default, Debug, Error)]
+ #[error(ignore)]
+ struct TestErr(i32, i32);
+
+ assert!(TestErr::default().source().is_none())
+}
diff --git a/third_party/rust/derive_more/tests/error/mod.rs b/third_party/rust/derive_more/tests/error/mod.rs
new file mode 100644
index 0000000000..5d7190d8f7
--- /dev/null
+++ b/third_party/rust/derive_more/tests/error/mod.rs
@@ -0,0 +1,56 @@
+use std::error::Error;
+
+/// Derives `std::fmt::Display` for structs/enums.
+/// Derived implementation outputs empty string.
+/// Useful, as a way to formally satisfy `Display` trait bound.
+///
+/// ## Syntax:
+///
+/// For regular structs/enums:
+///
+/// ```
+/// enum MyEnum {
+/// ...
+/// }
+///
+/// derive_display!(MyEnum);
+/// ```
+///
+/// For generic structs/enums:
+///
+/// ```
+/// struct MyGenericStruct<T, U> {
+/// ...
+/// }
+///
+/// derive_display!(MyGenericStruct, T, U);
+/// ```
+macro_rules! derive_display {
+ (@fmt) => {
+ fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
+ write!(f, "")
+ }
+ };
+ ($type:ident) => {
+ impl ::std::fmt::Display for $type {
+ derive_display!(@fmt);
+ }
+ };
+ ($type:ident, $($type_parameters:ident),*) => {
+ impl<$($type_parameters),*> ::std::fmt::Display for $type<$($type_parameters),*> {
+ derive_display!(@fmt);
+ }
+ };
+}
+
+mod derives_for_enums_with_source;
+mod derives_for_generic_enums_with_source;
+mod derives_for_generic_structs_with_source;
+mod derives_for_structs_with_source;
+
+#[cfg(feature = "nightly")]
+mod nightly;
+
+derive_display!(SimpleErr);
+#[derive(Default, Debug, Error)]
+struct SimpleErr;
diff --git a/third_party/rust/derive_more/tests/error/nightly/derives_for_enums_with_backtrace.rs b/third_party/rust/derive_more/tests/error/nightly/derives_for_enums_with_backtrace.rs
new file mode 100644
index 0000000000..c4ff4817d6
--- /dev/null
+++ b/third_party/rust/derive_more/tests/error/nightly/derives_for_enums_with_backtrace.rs
@@ -0,0 +1,272 @@
+use super::*;
+
+derive_display!(TestErr);
+#[derive(Debug, Error)]
+enum TestErr {
+ Unit,
+ NamedImplicitNoBacktrace {
+ field: i32,
+ },
+ NamedImplicitBacktraceByFieldName {
+ backtrace: MyBacktrace,
+ field: i32,
+ },
+ NamedImplicitBacktraceByFieldType {
+ implicit_backtrace: Backtrace,
+ field: i32,
+ },
+ NamedExplicitNoBacktraceByFieldName {
+ #[error(not(backtrace))]
+ backtrace: MyBacktrace,
+ field: i32,
+ },
+ NamedExplicitNoBacktraceByFieldType {
+ #[error(not(backtrace))]
+ implicit_backtrace: Backtrace,
+ field: i32,
+ },
+ NamedExplicitBacktrace {
+ #[error(backtrace)]
+ explicit_backtrace: MyBacktrace,
+ field: i32,
+ },
+ NamedExplicitNoBacktraceRedundant {
+ #[error(not(backtrace))]
+ not_backtrace: MyBacktrace,
+ #[error(not(backtrace))]
+ field: i32,
+ },
+ NamedExplicitBacktraceByFieldNameRedundant {
+ #[error(backtrace)]
+ backtrace: MyBacktrace,
+ field: i32,
+ },
+ NamedExplicitBacktraceByFieldTypeRedundant {
+ #[error(backtrace)]
+ implicit_backtrace: Backtrace,
+ field: i32,
+ },
+ NamedExplicitSupressesImplicit {
+ #[error(backtrace)]
+ not_backtrace: MyBacktrace,
+ backtrace: Backtrace,
+ field: i32,
+ },
+ UnnamedImplicitNoBacktrace(i32, i32),
+ UnnamedImplicitBacktrace(Backtrace, i32, i32),
+ UnnamedExplicitNoBacktrace(#[error(not(backtrace))] Backtrace, i32),
+ UnnamedExplicitBacktrace(#[error(backtrace)] MyBacktrace, i32, i32),
+ UnnamedExplicitNoBacktraceRedundant(
+ #[error(not(backtrace))] MyBacktrace,
+ #[error(not(backtrace))] i32,
+ ),
+ UnnamedExplicitBacktraceRedundant(#[error(backtrace)] Backtrace, i32, i32),
+ UnnamedExplicitSupressesImplicit(#[error(backtrace)] MyBacktrace, Backtrace, i32),
+}
+
+impl TestErr {
+ fn get_stored_backtrace(&self) -> &Backtrace {
+ match self {
+ Self::NamedImplicitBacktraceByFieldName { backtrace, .. } => backtrace,
+ Self::NamedImplicitBacktraceByFieldType {
+ implicit_backtrace, ..
+ } => implicit_backtrace,
+ Self::NamedExplicitBacktrace {
+ explicit_backtrace, ..
+ } => explicit_backtrace,
+ Self::NamedExplicitBacktraceByFieldNameRedundant { backtrace, .. } => {
+ backtrace
+ }
+ Self::NamedExplicitBacktraceByFieldTypeRedundant {
+ implicit_backtrace,
+ ..
+ } => implicit_backtrace,
+ Self::NamedExplicitSupressesImplicit { not_backtrace, .. } => not_backtrace,
+ Self::UnnamedImplicitBacktrace(backtrace, _, _) => backtrace,
+ Self::UnnamedExplicitBacktrace(backtrace, _, _) => backtrace,
+ Self::UnnamedExplicitBacktraceRedundant(backtrace, _, _) => backtrace,
+ Self::UnnamedExplicitSupressesImplicit(backtrace, _, _) => backtrace,
+ _ => panic!("ERROR IN TEST IMPLEMENTATION"),
+ }
+ }
+
+ fn get_unused_backtrace(&self) -> &Backtrace {
+ match self {
+ Self::NamedExplicitSupressesImplicit { backtrace, .. } => backtrace,
+ Self::UnnamedExplicitSupressesImplicit(_, backtrace, _) => backtrace,
+ _ => panic!("ERROR IN TEST IMPLEMENTATION"),
+ }
+ }
+}
+
+type MyBacktrace = Backtrace;
+
+#[test]
+fn unit() {
+ assert!(TestErr::Unit.backtrace().is_none());
+}
+
+#[test]
+fn named_implicit_no_backtrace() {
+ let err = TestErr::NamedImplicitNoBacktrace { field: 0 };
+
+ assert!(err.backtrace().is_none());
+}
+
+#[test]
+fn named_implicit_backtrace_by_field_name() {
+ let err = TestErr::NamedImplicitBacktraceByFieldName {
+ backtrace: Backtrace::force_capture(),
+ field: 0,
+ };
+
+ assert!(err.backtrace().is_some());
+ assert_bt!(==, err, .get_stored_backtrace);
+}
+
+#[test]
+fn named_implicit_backtrace_by_field_type() {
+ let err = TestErr::NamedImplicitBacktraceByFieldType {
+ implicit_backtrace: Backtrace::force_capture(),
+ field: 0,
+ };
+
+ assert!(err.backtrace().is_some());
+ assert_bt!(==, err, .get_stored_backtrace);
+}
+
+#[test]
+fn named_explicit_no_backtrace_by_field_name() {
+ let err = TestErr::NamedExplicitNoBacktraceByFieldName {
+ backtrace: Backtrace::force_capture(),
+ field: 0,
+ };
+
+ assert!(err.backtrace().is_none());
+}
+
+#[test]
+fn named_explicit_no_backtrace_by_field_type() {
+ let err = TestErr::NamedExplicitNoBacktraceByFieldType {
+ implicit_backtrace: Backtrace::force_capture(),
+ field: 0,
+ };
+
+ assert!(err.backtrace().is_none());
+}
+
+#[test]
+fn named_explicit_backtrace() {
+ let err = TestErr::NamedExplicitBacktrace {
+ explicit_backtrace: Backtrace::force_capture(),
+ field: 0,
+ };
+
+ assert!(err.backtrace().is_some());
+ assert_bt!(==, err, .get_stored_backtrace);
+}
+
+#[test]
+fn named_explicit_no_backtrace_redundant() {
+ let err = TestErr::NamedExplicitNoBacktraceRedundant {
+ not_backtrace: Backtrace::force_capture(),
+ field: 0,
+ };
+
+ assert!(err.backtrace().is_none());
+}
+
+#[test]
+fn named_explicit_backtrace_by_field_name_redundant() {
+ let err = TestErr::NamedExplicitBacktraceByFieldNameRedundant {
+ backtrace: Backtrace::force_capture(),
+ field: 0,
+ };
+
+ assert!(err.backtrace().is_some());
+ assert_bt!(==, err, .get_stored_backtrace);
+}
+
+#[test]
+fn named_explicit_backtrace_by_field_type_redundant() {
+ let err = TestErr::NamedExplicitBacktraceByFieldTypeRedundant {
+ implicit_backtrace: Backtrace::force_capture(),
+ field: 0,
+ };
+
+ assert!(err.backtrace().is_some());
+ assert_bt!(==, err, .get_stored_backtrace);
+}
+
+#[test]
+fn named_explicit_supresses_implicit() {
+ let err = TestErr::NamedExplicitSupressesImplicit {
+ not_backtrace: Backtrace::force_capture(),
+ backtrace: (|| Backtrace::force_capture())(), // ensure backtraces are different
+ field: 0,
+ };
+
+ assert!(err.backtrace().is_some());
+ assert_bt!(==, err, .get_stored_backtrace);
+ assert_bt!(!=, err, .get_unused_backtrace);
+}
+
+#[test]
+fn unnamed_implicit_no_backtrace() {
+ let err = TestErr::UnnamedImplicitNoBacktrace(0, 0);
+
+ assert!(err.backtrace().is_none());
+}
+
+#[test]
+fn unnamed_implicit_backtrace() {
+ let err = TestErr::UnnamedImplicitBacktrace(Backtrace::force_capture(), 0, 0);
+
+ assert!(err.backtrace().is_some());
+ assert_bt!(==, err, .get_stored_backtrace);
+}
+
+#[test]
+fn unnamed_explicit_no_backtrace() {
+ let err = TestErr::UnnamedExplicitNoBacktrace(Backtrace::force_capture(), 0);
+
+ assert!(err.backtrace().is_none());
+}
+
+#[test]
+fn unnamed_explicit_backtrace() {
+ let err = TestErr::UnnamedExplicitBacktrace(Backtrace::force_capture(), 0, 0);
+
+ assert!(err.backtrace().is_some());
+ assert_bt!(==, err, .get_stored_backtrace);
+}
+
+#[test]
+fn unnamed_explicit_no_backtrace_redundant() {
+ let err =
+ TestErr::UnnamedExplicitNoBacktraceRedundant(Backtrace::force_capture(), 0);
+
+ assert!(err.backtrace().is_none());
+}
+
+#[test]
+fn unnamed_explicit_backtrace_redundant() {
+ let err =
+ TestErr::UnnamedExplicitBacktraceRedundant(Backtrace::force_capture(), 0, 0);
+
+ assert!(err.backtrace().is_some());
+ assert_bt!(==, err, .get_stored_backtrace);
+}
+
+#[test]
+fn unnamed_explicit_supresses_implicit() {
+ let err = TestErr::UnnamedExplicitSupressesImplicit(
+ Backtrace::force_capture(),
+ (|| Backtrace::force_capture())(), // ensure backtraces are different
+ 0,
+ );
+
+ assert!(err.backtrace().is_some());
+ assert_bt!(==, err, .get_stored_backtrace);
+ assert_bt!(!=, err, .get_unused_backtrace);
+}
diff --git a/third_party/rust/derive_more/tests/error/nightly/derives_for_generic_enums_with_backtrace.rs b/third_party/rust/derive_more/tests/error/nightly/derives_for_generic_enums_with_backtrace.rs
new file mode 100644
index 0000000000..8574751d02
--- /dev/null
+++ b/third_party/rust/derive_more/tests/error/nightly/derives_for_generic_enums_with_backtrace.rs
@@ -0,0 +1,272 @@
+use super::*;
+
+derive_display!(TestErr, T);
+#[derive(Debug, Error)]
+enum TestErr<T> {
+ Unit,
+ NamedImplicitNoBacktrace {
+ field: T,
+ },
+ NamedImplicitBacktraceByFieldName {
+ backtrace: MyBacktrace,
+ field: T,
+ },
+ NamedImplicitBacktraceByFieldType {
+ implicit_backtrace: Backtrace,
+ field: T,
+ },
+ NamedExplicitNoBacktraceByFieldName {
+ #[error(not(backtrace))]
+ backtrace: MyBacktrace,
+ field: T,
+ },
+ NamedExplicitNoBacktraceByFieldType {
+ #[error(not(backtrace))]
+ implicit_backtrace: Backtrace,
+ field: T,
+ },
+ NamedExplicitBacktrace {
+ #[error(backtrace)]
+ explicit_backtrace: MyBacktrace,
+ field: T,
+ },
+ NamedExplicitNoBacktraceRedundant {
+ #[error(not(backtrace))]
+ not_backtrace: MyBacktrace,
+ #[error(not(backtrace))]
+ field: T,
+ },
+ NamedExplicitBacktraceByFieldNameRedundant {
+ #[error(backtrace)]
+ backtrace: MyBacktrace,
+ field: T,
+ },
+ NamedExplicitBacktraceByFieldTypeRedundant {
+ #[error(backtrace)]
+ implicit_backtrace: Backtrace,
+ field: T,
+ },
+ NamedExplicitSupressesImplicit {
+ #[error(backtrace)]
+ not_backtrace: MyBacktrace,
+ backtrace: Backtrace,
+ field: T,
+ },
+ UnnamedImplicitNoBacktrace(T, T),
+ UnnamedImplicitBacktrace(Backtrace, T, T),
+ UnnamedExplicitNoBacktrace(#[error(not(backtrace))] Backtrace, T),
+ UnnamedExplicitBacktrace(#[error(backtrace)] MyBacktrace, T, T),
+ UnnamedExplicitNoBacktraceRedundant(
+ #[error(not(backtrace))] MyBacktrace,
+ #[error(not(backtrace))] T,
+ ),
+ UnnamedExplicitBacktraceRedundant(#[error(backtrace)] Backtrace, T, T),
+ UnnamedExplicitSupressesImplicit(#[error(backtrace)] MyBacktrace, Backtrace, T),
+}
+
+impl<T> TestErr<T> {
+ fn get_stored_backtrace(&self) -> &Backtrace {
+ match self {
+ Self::NamedImplicitBacktraceByFieldName { backtrace, .. } => backtrace,
+ Self::NamedImplicitBacktraceByFieldType {
+ implicit_backtrace, ..
+ } => implicit_backtrace,
+ Self::NamedExplicitBacktrace {
+ explicit_backtrace, ..
+ } => explicit_backtrace,
+ Self::NamedExplicitBacktraceByFieldNameRedundant { backtrace, .. } => {
+ backtrace
+ }
+ Self::NamedExplicitBacktraceByFieldTypeRedundant {
+ implicit_backtrace,
+ ..
+ } => implicit_backtrace,
+ Self::NamedExplicitSupressesImplicit { not_backtrace, .. } => not_backtrace,
+ Self::UnnamedImplicitBacktrace(backtrace, _, _) => backtrace,
+ Self::UnnamedExplicitBacktrace(backtrace, _, _) => backtrace,
+ Self::UnnamedExplicitBacktraceRedundant(backtrace, _, _) => backtrace,
+ Self::UnnamedExplicitSupressesImplicit(backtrace, _, _) => backtrace,
+ _ => panic!("ERROR IN TEST IMPLEMENTATION"),
+ }
+ }
+
+ fn get_unused_backtrace(&self) -> &Backtrace {
+ match self {
+ Self::NamedExplicitSupressesImplicit { backtrace, .. } => backtrace,
+ Self::UnnamedExplicitSupressesImplicit(_, backtrace, _) => backtrace,
+ _ => panic!("ERROR IN TEST IMPLEMENTATION"),
+ }
+ }
+}
+
+type MyBacktrace = Backtrace;
+
+#[test]
+fn unit() {
+ assert!(TestErr::<i32>::Unit.backtrace().is_none());
+}
+
+#[test]
+fn named_implicit_no_backtrace() {
+ let err = TestErr::NamedImplicitNoBacktrace { field: 0 };
+
+ assert!(err.backtrace().is_none());
+}
+
+#[test]
+fn named_implicit_backtrace_by_field_name() {
+ let err = TestErr::NamedImplicitBacktraceByFieldName {
+ backtrace: Backtrace::force_capture(),
+ field: 0,
+ };
+
+ assert!(err.backtrace().is_some());
+ assert_bt!(==, err, .get_stored_backtrace);
+}
+
+#[test]
+fn named_implicit_backtrace_by_field_type() {
+ let err = TestErr::NamedImplicitBacktraceByFieldType {
+ implicit_backtrace: Backtrace::force_capture(),
+ field: 0,
+ };
+
+ assert!(err.backtrace().is_some());
+ assert_bt!(==, err, .get_stored_backtrace);
+}
+
+#[test]
+fn named_explicit_no_backtrace_by_field_name() {
+ let err = TestErr::NamedExplicitNoBacktraceByFieldName {
+ backtrace: Backtrace::force_capture(),
+ field: 0,
+ };
+
+ assert!(err.backtrace().is_none());
+}
+
+#[test]
+fn named_explicit_no_backtrace_by_field_type() {
+ let err = TestErr::NamedExplicitNoBacktraceByFieldType {
+ implicit_backtrace: Backtrace::force_capture(),
+ field: 0,
+ };
+
+ assert!(err.backtrace().is_none());
+}
+
+#[test]
+fn named_explicit_backtrace() {
+ let err = TestErr::NamedExplicitBacktrace {
+ explicit_backtrace: Backtrace::force_capture(),
+ field: 0,
+ };
+
+ assert!(err.backtrace().is_some());
+ assert_bt!(==, err, .get_stored_backtrace);
+}
+
+#[test]
+fn named_explicit_no_backtrace_redundant() {
+ let err = TestErr::NamedExplicitNoBacktraceRedundant {
+ not_backtrace: Backtrace::force_capture(),
+ field: 0,
+ };
+
+ assert!(err.backtrace().is_none());
+}
+
+#[test]
+fn named_explicit_backtrace_by_field_name_redundant() {
+ let err = TestErr::NamedExplicitBacktraceByFieldNameRedundant {
+ backtrace: Backtrace::force_capture(),
+ field: 0,
+ };
+
+ assert!(err.backtrace().is_some());
+ assert_bt!(==, err, .get_stored_backtrace);
+}
+
+#[test]
+fn named_explicit_backtrace_by_field_type_redundant() {
+ let err = TestErr::NamedExplicitBacktraceByFieldTypeRedundant {
+ implicit_backtrace: Backtrace::force_capture(),
+ field: 0,
+ };
+
+ assert!(err.backtrace().is_some());
+ assert_bt!(==, err, .get_stored_backtrace);
+}
+
+#[test]
+fn named_explicit_supresses_implicit() {
+ let err = TestErr::NamedExplicitSupressesImplicit {
+ not_backtrace: Backtrace::force_capture(),
+ backtrace: (|| Backtrace::force_capture())(), // ensure backtraces are different
+ field: 0,
+ };
+
+ assert!(err.backtrace().is_some());
+ assert_bt!(==, err, .get_stored_backtrace);
+ assert_bt!(!=, err, .get_unused_backtrace);
+}
+
+#[test]
+fn unnamed_implicit_no_backtrace() {
+ let err = TestErr::UnnamedImplicitNoBacktrace(0, 0);
+
+ assert!(err.backtrace().is_none());
+}
+
+#[test]
+fn unnamed_implicit_backtrace() {
+ let err = TestErr::UnnamedImplicitBacktrace(Backtrace::force_capture(), 0, 0);
+
+ assert!(err.backtrace().is_some());
+ assert_bt!(==, err, .get_stored_backtrace);
+}
+
+#[test]
+fn unnamed_explicit_no_backtrace() {
+ let err = TestErr::UnnamedExplicitNoBacktrace(Backtrace::force_capture(), 0);
+
+ assert!(err.backtrace().is_none());
+}
+
+#[test]
+fn unnamed_explicit_backtrace() {
+ let err = TestErr::UnnamedExplicitBacktrace(Backtrace::force_capture(), 0, 0);
+
+ assert!(err.backtrace().is_some());
+ assert_bt!(==, err, .get_stored_backtrace);
+}
+
+#[test]
+fn unnamed_explicit_no_backtrace_redundant() {
+ let err =
+ TestErr::UnnamedExplicitNoBacktraceRedundant(Backtrace::force_capture(), 0);
+
+ assert!(err.backtrace().is_none());
+}
+
+#[test]
+fn unnamed_explicit_backtrace_redundant() {
+ let err =
+ TestErr::UnnamedExplicitBacktraceRedundant(Backtrace::force_capture(), 0, 0);
+
+ assert!(err.backtrace().is_some());
+ assert_bt!(==, err, .get_stored_backtrace);
+}
+
+#[test]
+fn unnamed_explicit_supresses_implicit() {
+ let err = TestErr::UnnamedExplicitSupressesImplicit(
+ Backtrace::force_capture(),
+ (|| Backtrace::force_capture())(), // ensure backtraces are different
+ 0,
+ );
+
+ assert!(err.backtrace().is_some());
+ assert_bt!(==, err, .get_stored_backtrace);
+ assert_bt!(!=, err, .get_unused_backtrace);
+}
diff --git a/third_party/rust/derive_more/tests/error/nightly/derives_for_generic_structs_with_backtrace.rs b/third_party/rust/derive_more/tests/error/nightly/derives_for_generic_structs_with_backtrace.rs
new file mode 100644
index 0000000000..91df87c82a
--- /dev/null
+++ b/third_party/rust/derive_more/tests/error/nightly/derives_for_generic_structs_with_backtrace.rs
@@ -0,0 +1,275 @@
+use super::*;
+
+#[test]
+fn named_implicit_no_backtrace() {
+ derive_display!(TestErr, T);
+ #[derive(Default, Debug, Error)]
+ struct TestErr<T> {
+ field: T,
+ }
+
+ assert!(TestErr::<i32>::default().backtrace().is_none());
+}
+
+#[test]
+fn named_implicit_backtrace_by_field_name() {
+ derive_display!(TestErr, T);
+ #[derive(Debug, Error)]
+ struct TestErr<T> {
+ backtrace: MyBacktrace,
+ field: T,
+ }
+
+ type MyBacktrace = Backtrace;
+
+ let err = TestErr {
+ backtrace: Backtrace::force_capture(),
+ field: 0,
+ };
+ assert!(err.backtrace().is_some());
+ assert_bt!(==, err);
+}
+
+#[test]
+fn named_implicit_backtrace_by_field_type() {
+ derive_display!(TestErr, T);
+ #[derive(Debug, Error)]
+ struct TestErr<T> {
+ implicit_backtrace: Backtrace,
+ field: T,
+ }
+
+ let err = TestErr {
+ implicit_backtrace: Backtrace::force_capture(),
+ field: 0,
+ };
+ assert!(err.backtrace().is_some());
+ assert_bt!(==, err, implicit_backtrace);
+}
+
+#[test]
+fn named_explicit_no_backtrace_by_field_name() {
+ derive_display!(TestErr, T);
+ #[derive(Debug, Error)]
+ struct TestErr<T> {
+ #[error(not(backtrace))]
+ backtrace: MyBacktrace,
+ field: T,
+ }
+
+ type MyBacktrace = Backtrace;
+
+ assert!(TestErr {
+ backtrace: Backtrace::force_capture(),
+ field: 0
+ }
+ .backtrace()
+ .is_none());
+}
+
+#[test]
+fn named_explicit_no_backtrace_by_field_type() {
+ derive_display!(TestErr, T);
+ #[derive(Debug, Error)]
+ struct TestErr<T> {
+ #[error(not(backtrace))]
+ implicit_backtrace: Backtrace,
+ field: T,
+ }
+
+ assert!(TestErr {
+ implicit_backtrace: Backtrace::force_capture(),
+ field: 0
+ }
+ .backtrace()
+ .is_none());
+}
+
+#[test]
+fn named_explicit_backtrace() {
+ derive_display!(TestErr, T);
+ #[derive(Debug, Error)]
+ struct TestErr<T> {
+ #[error(backtrace)]
+ explicit_backtrace: MyBacktrace,
+ field: T,
+ }
+
+ type MyBacktrace = Backtrace;
+
+ let err = TestErr {
+ explicit_backtrace: Backtrace::force_capture(),
+ field: 0,
+ };
+ assert!(err.backtrace().is_some());
+ assert_bt!(==, err, explicit_backtrace);
+}
+
+#[test]
+fn named_explicit_no_backtrace_redundant() {
+ derive_display!(TestErr, T);
+ #[derive(Debug, Error)]
+ struct TestErr<T> {
+ #[error(not(backtrace))]
+ not_backtrace: MyBacktrace,
+ #[error(not(backtrace))]
+ field: T,
+ }
+
+ type MyBacktrace = Backtrace;
+
+ assert!(TestErr {
+ not_backtrace: Backtrace::force_capture(),
+ field: 0
+ }
+ .backtrace()
+ .is_none());
+}
+
+#[test]
+fn named_explicit_backtrace_by_field_name_redundant() {
+ derive_display!(TestErr, T);
+ #[derive(Debug, Error)]
+ struct TestErr<T> {
+ #[error(backtrace)]
+ backtrace: MyBacktrace,
+ field: T,
+ }
+
+ type MyBacktrace = Backtrace;
+
+ let err = TestErr {
+ backtrace: Backtrace::force_capture(),
+ field: 0,
+ };
+ assert!(err.backtrace().is_some());
+ assert_bt!(==, err);
+}
+
+#[test]
+fn named_explicit_backtrace_by_field_type_redundant() {
+ derive_display!(TestErr, T);
+ #[derive(Debug, Error)]
+ struct TestErr<T> {
+ #[error(backtrace)]
+ implicit_backtrace: Backtrace,
+ field: T,
+ }
+
+ let err = TestErr {
+ implicit_backtrace: Backtrace::force_capture(),
+ field: 0,
+ };
+ assert!(err.backtrace().is_some());
+ assert_bt!(==, err, implicit_backtrace);
+}
+
+#[test]
+fn named_explicit_supresses_implicit() {
+ derive_display!(TestErr, T);
+ #[derive(Debug, Error)]
+ struct TestErr<T> {
+ #[error(backtrace)]
+ not_backtrace: MyBacktrace,
+ backtrace: Backtrace,
+ field: T,
+ }
+
+ type MyBacktrace = Backtrace;
+
+ let err = TestErr {
+ not_backtrace: Backtrace::force_capture(),
+ backtrace: (|| Backtrace::force_capture())(), // ensure backtraces are different
+ field: 0,
+ };
+
+ assert!(err.backtrace().is_some());
+ assert_bt!(==, err, not_backtrace);
+ assert_bt!(!=, err);
+}
+
+#[test]
+fn unnamed_implicit_no_backtrace() {
+ derive_display!(TestErr, T);
+ #[derive(Default, Debug, Error)]
+ struct TestErr<T>(T, T);
+
+ assert!(TestErr::<i32>::default().backtrace().is_none());
+}
+
+#[test]
+fn unnamed_implicit_backtrace() {
+ derive_display!(TestErr, T);
+ #[derive(Debug, Error)]
+ struct TestErr<T>(Backtrace, T, T);
+
+ let err = TestErr(Backtrace::force_capture(), 0, 0);
+ assert!(err.backtrace().is_some());
+ assert_bt!(==, err, 0);
+}
+
+#[test]
+fn unnamed_explicit_no_backtrace() {
+ derive_display!(TestErr, T);
+ #[derive(Debug, Error)]
+ struct TestErr<T>(#[error(not(backtrace))] Backtrace, T);
+
+ assert!(TestErr(Backtrace::force_capture(), 0).backtrace().is_none());
+}
+
+#[test]
+fn unnamed_explicit_backtrace() {
+ derive_display!(TestErr, T);
+ #[derive(Debug, Error)]
+ struct TestErr<T>(#[error(backtrace)] MyBacktrace, T, T);
+
+ type MyBacktrace = Backtrace;
+
+ let err = TestErr(Backtrace::force_capture(), 0, 0);
+ assert!(err.backtrace().is_some());
+ assert_bt!(==, err, 0);
+}
+
+#[test]
+fn unnamed_explicit_no_backtrace_redundant() {
+ derive_display!(TestErr, T);
+ #[derive(Debug, Error)]
+ struct TestErr<T>(
+ #[error(not(backtrace))] MyBacktrace,
+ #[error(not(backtrace))] T,
+ );
+
+ type MyBacktrace = Backtrace;
+
+ assert!(TestErr(Backtrace::force_capture(), 0).backtrace().is_none());
+}
+
+#[test]
+fn unnamed_explicit_backtrace_redundant() {
+ derive_display!(TestErr, T);
+ #[derive(Debug, Error)]
+ struct TestErr<T>(#[error(backtrace)] Backtrace, T, T);
+
+ let err = TestErr(Backtrace::force_capture(), 0, 0);
+ assert!(err.backtrace().is_some());
+ assert_bt!(==, err, 0);
+}
+
+#[test]
+fn unnamed_explicit_supresses_implicit() {
+ derive_display!(TestErr, T);
+ #[derive(Debug, Error)]
+ struct TestErr<T>(#[error(backtrace)] MyBacktrace, Backtrace, T);
+
+ type MyBacktrace = Backtrace;
+
+ let err = TestErr(
+ Backtrace::force_capture(),
+ (|| Backtrace::force_capture())(), // ensure backtraces are different
+ 0,
+ );
+
+ assert!(err.backtrace().is_some());
+ assert_bt!(==, err, 0);
+ assert_bt!(!=, err, 1);
+}
diff --git a/third_party/rust/derive_more/tests/error/nightly/derives_for_structs_with_backtrace.rs b/third_party/rust/derive_more/tests/error/nightly/derives_for_structs_with_backtrace.rs
new file mode 100644
index 0000000000..18e268f841
--- /dev/null
+++ b/third_party/rust/derive_more/tests/error/nightly/derives_for_structs_with_backtrace.rs
@@ -0,0 +1,280 @@
+use super::*;
+
+#[test]
+fn unit() {
+ assert!(SimpleErr.backtrace().is_none());
+}
+
+#[test]
+fn named_implicit_no_backtrace() {
+ derive_display!(TestErr);
+ #[derive(Default, Debug, Error)]
+ struct TestErr {
+ field: i32,
+ }
+
+ assert!(TestErr::default().backtrace().is_none());
+}
+
+#[test]
+fn named_implicit_backtrace_by_field_name() {
+ derive_display!(TestErr);
+ #[derive(Debug, Error)]
+ struct TestErr {
+ backtrace: MyBacktrace,
+ field: i32,
+ }
+
+ type MyBacktrace = Backtrace;
+
+ let err = TestErr {
+ backtrace: Backtrace::force_capture(),
+ field: 0,
+ };
+ assert!(err.backtrace().is_some());
+ assert_bt!(==, err);
+}
+
+#[test]
+fn named_implicit_backtrace_by_field_type() {
+ derive_display!(TestErr);
+ #[derive(Debug, Error)]
+ struct TestErr {
+ implicit_backtrace: Backtrace,
+ field: i32,
+ }
+
+ let err = TestErr {
+ implicit_backtrace: Backtrace::force_capture(),
+ field: 0,
+ };
+ assert!(err.backtrace().is_some());
+ assert_bt!(==, err, implicit_backtrace);
+}
+
+#[test]
+fn named_explicit_no_backtrace_by_field_name() {
+ derive_display!(TestErr);
+ #[derive(Debug, Error)]
+ struct TestErr {
+ #[error(not(backtrace))]
+ backtrace: MyBacktrace,
+ field: i32,
+ }
+
+ type MyBacktrace = Backtrace;
+
+ assert!(TestErr {
+ backtrace: Backtrace::force_capture(),
+ field: 0
+ }
+ .backtrace()
+ .is_none());
+}
+
+#[test]
+fn named_explicit_no_backtrace_by_field_type() {
+ derive_display!(TestErr);
+ #[derive(Debug, Error)]
+ struct TestErr {
+ #[error(not(backtrace))]
+ implicit_backtrace: Backtrace,
+ field: i32,
+ }
+
+ assert!(TestErr {
+ implicit_backtrace: Backtrace::force_capture(),
+ field: 0
+ }
+ .backtrace()
+ .is_none());
+}
+
+#[test]
+fn named_explicit_backtrace() {
+ derive_display!(TestErr);
+ #[derive(Debug, Error)]
+ struct TestErr {
+ #[error(backtrace)]
+ explicit_backtrace: MyBacktrace,
+ field: i32,
+ }
+
+ type MyBacktrace = Backtrace;
+
+ let err = TestErr {
+ explicit_backtrace: Backtrace::force_capture(),
+ field: 0,
+ };
+ assert!(err.backtrace().is_some());
+ assert_bt!(==, err, explicit_backtrace);
+}
+
+#[test]
+fn named_explicit_no_backtrace_redundant() {
+ derive_display!(TestErr);
+ #[derive(Debug, Error)]
+ struct TestErr {
+ #[error(not(backtrace))]
+ not_backtrace: MyBacktrace,
+ #[error(not(backtrace))]
+ field: i32,
+ }
+
+ type MyBacktrace = Backtrace;
+
+ assert!(TestErr {
+ not_backtrace: Backtrace::force_capture(),
+ field: 0
+ }
+ .backtrace()
+ .is_none());
+}
+
+#[test]
+fn named_explicit_backtrace_by_field_name_redundant() {
+ derive_display!(TestErr);
+ #[derive(Debug, Error)]
+ struct TestErr {
+ #[error(backtrace)]
+ backtrace: MyBacktrace,
+ field: i32,
+ }
+
+ type MyBacktrace = Backtrace;
+
+ let err = TestErr {
+ backtrace: Backtrace::force_capture(),
+ field: 0,
+ };
+ assert!(err.backtrace().is_some());
+ assert_bt!(==, err);
+}
+
+#[test]
+fn named_explicit_backtrace_by_field_type_redundant() {
+ derive_display!(TestErr);
+ #[derive(Debug, Error)]
+ struct TestErr {
+ #[error(backtrace)]
+ implicit_backtrace: Backtrace,
+ field: i32,
+ }
+
+ let err = TestErr {
+ implicit_backtrace: Backtrace::force_capture(),
+ field: 0,
+ };
+ assert!(err.backtrace().is_some());
+ assert_bt!(==, err, implicit_backtrace);
+}
+
+#[test]
+fn named_explicit_supresses_implicit() {
+ derive_display!(TestErr);
+ #[derive(Debug, Error)]
+ struct TestErr {
+ #[error(backtrace)]
+ not_backtrace: MyBacktrace,
+ backtrace: Backtrace,
+ field: i32,
+ }
+
+ type MyBacktrace = Backtrace;
+
+ let err = TestErr {
+ not_backtrace: Backtrace::force_capture(),
+ backtrace: (|| Backtrace::force_capture())(), // ensure backtraces are different
+ field: 0,
+ };
+
+ assert!(err.backtrace().is_some());
+ assert_bt!(==, err, not_backtrace);
+ assert_bt!(!=, err);
+}
+
+#[test]
+fn unnamed_implicit_no_backtrace() {
+ derive_display!(TestErr);
+ #[derive(Default, Debug, Error)]
+ struct TestErr(i32, i32);
+
+ assert!(TestErr::default().backtrace().is_none());
+}
+
+#[test]
+fn unnamed_implicit_backtrace() {
+ derive_display!(TestErr);
+ #[derive(Debug, Error)]
+ struct TestErr(Backtrace, i32, i32);
+
+ let err = TestErr(Backtrace::force_capture(), 0, 0);
+ assert!(err.backtrace().is_some());
+ assert_bt!(==, err, 0);
+}
+
+#[test]
+fn unnamed_explicit_no_backtrace() {
+ derive_display!(TestErr);
+ #[derive(Debug, Error)]
+ struct TestErr(#[error(not(backtrace))] Backtrace, i32);
+
+ assert!(TestErr(Backtrace::force_capture(), 0).backtrace().is_none());
+}
+
+#[test]
+fn unnamed_explicit_backtrace() {
+ derive_display!(TestErr);
+ #[derive(Debug, Error)]
+ struct TestErr(#[error(backtrace)] MyBacktrace, i32, i32);
+
+ type MyBacktrace = Backtrace;
+
+ let err = TestErr(Backtrace::force_capture(), 0, 0);
+ assert!(err.backtrace().is_some());
+ assert_bt!(==, err, 0);
+}
+
+#[test]
+fn unnamed_explicit_no_backtrace_redundant() {
+ derive_display!(TestErr);
+ #[derive(Debug, Error)]
+ struct TestErr(
+ #[error(not(backtrace))] MyBacktrace,
+ #[error(not(backtrace))] i32,
+ );
+
+ type MyBacktrace = Backtrace;
+
+ assert!(TestErr(Backtrace::force_capture(), 0).backtrace().is_none());
+}
+
+#[test]
+fn unnamed_explicit_backtrace_redundant() {
+ derive_display!(TestErr);
+ #[derive(Debug, Error)]
+ struct TestErr(#[error(backtrace)] Backtrace, i32, i32);
+
+ let err = TestErr(Backtrace::force_capture(), 0, 0);
+ assert!(err.backtrace().is_some());
+ assert_bt!(==, err, 0);
+}
+
+#[test]
+fn unnamed_explicit_supresses_implicit() {
+ derive_display!(TestErr);
+ #[derive(Debug, Error)]
+ struct TestErr(#[error(backtrace)] MyBacktrace, Backtrace, i32);
+
+ type MyBacktrace = Backtrace;
+
+ let err = TestErr(
+ Backtrace::force_capture(),
+ (|| Backtrace::force_capture())(), // ensure backtraces are different
+ 0,
+ );
+
+ assert!(err.backtrace().is_some());
+ assert_bt!(==, err, 0);
+ assert_bt!(!=, err, 1);
+}
diff --git a/third_party/rust/derive_more/tests/error/nightly/mod.rs b/third_party/rust/derive_more/tests/error/nightly/mod.rs
new file mode 100644
index 0000000000..57de7ba2ab
--- /dev/null
+++ b/third_party/rust/derive_more/tests/error/nightly/mod.rs
@@ -0,0 +1,85 @@
+use std::backtrace::Backtrace;
+
+use super::*;
+
+/// Asserts that backtrace returned by `Error::backtrace` method equals/not-equals
+/// backtrace stored in object itself.
+///
+/// Comparison is done by converting backtraces to strings
+/// and then comparing these strings.
+///
+/// ## Syntax
+///
+/// * Equals: `assert_bt!(==, ...)`
+/// * Not-equals: `assert_bt!(!=, ...)`
+///
+/// ### Backtrace Access
+///
+/// Shortcut for named-structs with `backtrace` field.
+/// Access backtrace as `error.backtrace`.
+///
+/// ```
+/// assert_bt!(==, error);
+/// ```
+///
+/// Full form for named- and tuple-structs.
+/// Access backtrace as `error.some_other_field` and `error.1` respectively.
+///
+/// ```
+/// assert_bt!(!=, error, some_other_field);
+/// assert_bt!(==, error, 1);
+/// ```
+///
+/// Access as a method call.
+/// Useful for enums (i.e., you can define a method that will match on enum variants
+/// and return backtrace for each variant).
+/// Access backtrace as `error.get_stored_backtrace_method()`.
+///
+/// ```
+/// assert_bt!(!=, error, .get_stored_backtrace_method);
+/// ```
+macro_rules! assert_bt {
+ (@impl $macro:ident, $error:expr, $backtrace:expr) => {
+ $macro!($error.backtrace().unwrap().to_string(), $backtrace.to_string());
+ };
+ (@expand $macro:ident, $error:expr, .$backtrace:ident) => {
+ assert_bt!(@impl $macro, $error, $error.$backtrace())
+ };
+ (@expand $macro:ident, $error:expr, $backtrace:tt) => {
+ assert_bt!(@impl $macro, $error, $error.$backtrace)
+ };
+ (@expand $macro:ident, $error:expr) => {
+ assert_bt!(@expand $macro, $error, backtrace)
+ };
+ (==, $($args:tt)*) => {
+ assert_bt!(@expand assert_eq, $($args)*)
+ };
+ (!=, $($args:tt)*) => {
+ assert_bt!(@expand assert_ne, $($args)*)
+ };
+}
+
+mod derives_for_enums_with_backtrace;
+mod derives_for_generic_enums_with_backtrace;
+mod derives_for_generic_structs_with_backtrace;
+mod derives_for_structs_with_backtrace;
+
+derive_display!(BacktraceErr);
+#[derive(Debug)]
+struct BacktraceErr {
+ backtrace: Backtrace,
+}
+
+impl Default for BacktraceErr {
+ fn default() -> Self {
+ Self {
+ backtrace: Backtrace::force_capture(),
+ }
+ }
+}
+
+impl Error for BacktraceErr {
+ fn backtrace(&self) -> Option<&Backtrace> {
+ Some(&self.backtrace)
+ }
+}