diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-28 14:29:10 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-28 14:29:10 +0000 |
commit | 2aa4a82499d4becd2284cdb482213d541b8804dd (patch) | |
tree | b80bf8bf13c3766139fbacc530efd0dd9d54394c /third_party/rust/thiserror/tests | |
parent | Initial commit. (diff) | |
download | firefox-2aa4a82499d4becd2284cdb482213d541b8804dd.tar.xz firefox-2aa4a82499d4becd2284cdb482213d541b8804dd.zip |
Adding upstream version 86.0.1.upstream/86.0.1upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'third_party/rust/thiserror/tests')
50 files changed, 1240 insertions, 0 deletions
diff --git a/third_party/rust/thiserror/tests/compiletest.rs b/third_party/rust/thiserror/tests/compiletest.rs new file mode 100644 index 0000000000..641d03cbf4 --- /dev/null +++ b/third_party/rust/thiserror/tests/compiletest.rs @@ -0,0 +1,8 @@ +#![deny(clippy::all, clippy::pedantic)] + +#[rustversion::attr(not(nightly), ignore)] +#[test] +fn ui() { + let t = trybuild::TestCases::new(); + t.compile_fail("tests/ui/*.rs"); +} diff --git a/third_party/rust/thiserror/tests/test_backtrace.rs b/third_party/rust/thiserror/tests/test_backtrace.rs new file mode 100644 index 0000000000..09bc13dee9 --- /dev/null +++ b/third_party/rust/thiserror/tests/test_backtrace.rs @@ -0,0 +1,213 @@ +#![cfg_attr(thiserror_nightly_testing, feature(backtrace))] + +use thiserror::Error; + +#[derive(Error, Debug)] +#[error("...")] +pub struct Inner; + +#[cfg(thiserror_nightly_testing)] +pub mod structs { + use super::Inner; + use std::backtrace::Backtrace; + use std::error::Error; + use std::sync::Arc; + use thiserror::Error; + + #[derive(Error, Debug)] + #[error("...")] + pub struct PlainBacktrace { + backtrace: Backtrace, + } + + #[derive(Error, Debug)] + #[error("...")] + pub struct ExplicitBacktrace { + #[backtrace] + backtrace: Backtrace, + } + + #[derive(Error, Debug)] + #[error("...")] + pub struct OptBacktrace { + #[backtrace] + backtrace: Option<Backtrace>, + } + + #[derive(Error, Debug)] + #[error("...")] + pub struct ArcBacktrace { + #[backtrace] + backtrace: Arc<Backtrace>, + } + + #[derive(Error, Debug)] + #[error("...")] + pub struct BacktraceFrom { + #[from] + source: Inner, + #[backtrace] + backtrace: Backtrace, + } + + #[derive(Error, Debug)] + #[error("...")] + pub struct OptBacktraceFrom { + #[from] + source: Inner, + #[backtrace] + backtrace: Option<Backtrace>, + } + + #[derive(Error, Debug)] + #[error("...")] + pub struct ArcBacktraceFrom { + #[from] + source: Inner, + #[backtrace] + backtrace: Arc<Backtrace>, + } + + #[test] + fn test_backtrace() { + let error = PlainBacktrace { + backtrace: Backtrace::capture(), + }; + assert!(error.backtrace().is_some()); + + let error = ExplicitBacktrace { + backtrace: Backtrace::capture(), + }; + assert!(error.backtrace().is_some()); + + let error = OptBacktrace { + backtrace: Some(Backtrace::capture()), + }; + assert!(error.backtrace().is_some()); + + let error = ArcBacktrace { + backtrace: Arc::new(Backtrace::capture()), + }; + assert!(error.backtrace().is_some()); + + let error = BacktraceFrom::from(Inner); + assert!(error.backtrace().is_some()); + + let error = OptBacktraceFrom::from(Inner); + assert!(error.backtrace().is_some()); + + let error = ArcBacktraceFrom::from(Inner); + assert!(error.backtrace().is_some()); + } +} + +#[cfg(thiserror_nightly_testing)] +pub mod enums { + use super::Inner; + use std::backtrace::Backtrace; + use std::error::Error; + use std::sync::Arc; + use thiserror::Error; + + #[derive(Error, Debug)] + pub enum PlainBacktrace { + #[error("...")] + Test { backtrace: Backtrace }, + } + + #[derive(Error, Debug)] + pub enum ExplicitBacktrace { + #[error("...")] + Test { + #[backtrace] + backtrace: Backtrace, + }, + } + + #[derive(Error, Debug)] + pub enum OptBacktrace { + #[error("...")] + Test { + #[backtrace] + backtrace: Option<Backtrace>, + }, + } + + #[derive(Error, Debug)] + pub enum ArcBacktrace { + #[error("...")] + Test { + #[backtrace] + backtrace: Arc<Backtrace>, + }, + } + + #[derive(Error, Debug)] + pub enum BacktraceFrom { + #[error("...")] + Test { + #[from] + source: Inner, + #[backtrace] + backtrace: Backtrace, + }, + } + + #[derive(Error, Debug)] + pub enum OptBacktraceFrom { + #[error("...")] + Test { + #[from] + source: Inner, + #[backtrace] + backtrace: Option<Backtrace>, + }, + } + + #[derive(Error, Debug)] + pub enum ArcBacktraceFrom { + #[error("...")] + Test { + #[from] + source: Inner, + #[backtrace] + backtrace: Arc<Backtrace>, + }, + } + + #[test] + fn test_backtrace() { + let error = PlainBacktrace::Test { + backtrace: Backtrace::capture(), + }; + assert!(error.backtrace().is_some()); + + let error = ExplicitBacktrace::Test { + backtrace: Backtrace::capture(), + }; + assert!(error.backtrace().is_some()); + + let error = OptBacktrace::Test { + backtrace: Some(Backtrace::capture()), + }; + assert!(error.backtrace().is_some()); + + let error = ArcBacktrace::Test { + backtrace: Arc::new(Backtrace::capture()), + }; + assert!(error.backtrace().is_some()); + + let error = BacktraceFrom::from(Inner); + assert!(error.backtrace().is_some()); + + let error = OptBacktraceFrom::from(Inner); + assert!(error.backtrace().is_some()); + + let error = ArcBacktraceFrom::from(Inner); + assert!(error.backtrace().is_some()); + } +} + +#[test] +#[cfg_attr(not(thiserror_nightly_testing), ignore)] +fn test_backtrace() {} diff --git a/third_party/rust/thiserror/tests/test_deprecated.rs b/third_party/rust/thiserror/tests/test_deprecated.rs new file mode 100644 index 0000000000..5524666abc --- /dev/null +++ b/third_party/rust/thiserror/tests/test_deprecated.rs @@ -0,0 +1,10 @@ +#![deny(deprecated, clippy::all, clippy::pedantic)] + +use thiserror::Error; + +#[derive(Error, Debug)] +pub enum Error { + #[deprecated] + #[error("...")] + Deprecated, +} diff --git a/third_party/rust/thiserror/tests/test_display.rs b/third_party/rust/thiserror/tests/test_display.rs new file mode 100644 index 0000000000..9bc385a154 --- /dev/null +++ b/third_party/rust/thiserror/tests/test_display.rs @@ -0,0 +1,232 @@ +#![deny(clippy::all, clippy::pedantic)] + +use std::fmt::Display; +use thiserror::Error; + +fn assert<T: Display>(expected: &str, value: T) { + assert_eq!(expected, value.to_string()); +} + +#[test] +fn test_braced() { + #[derive(Error, Debug)] + #[error("braced error: {msg}")] + struct Error { + msg: String, + } + + let msg = "T".to_owned(); + assert("braced error: T", Error { msg }); +} + +#[test] +fn test_braced_unused() { + #[derive(Error, Debug)] + #[error("braced error")] + struct Error { + extra: usize, + } + + assert("braced error", Error { extra: 0 }); +} + +#[test] +fn test_tuple() { + #[derive(Error, Debug)] + #[error("tuple error: {0}")] + struct Error(usize); + + assert("tuple error: 0", Error(0)); +} + +#[test] +fn test_unit() { + #[derive(Error, Debug)] + #[error("unit error")] + struct Error; + + assert("unit error", Error); +} + +#[test] +fn test_enum() { + #[derive(Error, Debug)] + enum Error { + #[error("braced error: {id}")] + Braced { id: usize }, + #[error("tuple error: {0}")] + Tuple(usize), + #[error("unit error")] + Unit, + } + + assert("braced error: 0", Error::Braced { id: 0 }); + assert("tuple error: 0", Error::Tuple(0)); + assert("unit error", Error::Unit); +} + +#[test] +fn test_constants() { + #[derive(Error, Debug)] + #[error("{MSG}: {id:?} (code {CODE:?})")] + struct Error { + id: &'static str, + } + + const MSG: &str = "failed to do"; + const CODE: usize = 9; + + assert("failed to do: \"\" (code 9)", Error { id: "" }); +} + +#[test] +fn test_inherit() { + #[derive(Error, Debug)] + #[error("{0}")] + enum Error { + Some(&'static str), + #[error("other error")] + Other(&'static str), + } + + assert("some error", Error::Some("some error")); + assert("other error", Error::Other("...")); +} + +#[test] +fn test_brace_escape() { + #[derive(Error, Debug)] + #[error("fn main() {{}}")] + struct Error; + + assert("fn main() {}", Error); +} + +#[test] +fn test_expr() { + #[derive(Error, Debug)] + #[error("1 + 1 = {}", 1 + 1)] + struct Error; + assert("1 + 1 = 2", Error); +} + +#[test] +fn test_nested() { + #[derive(Error, Debug)] + #[error("!bool = {}", not(.0))] + struct Error(bool); + + #[allow(clippy::trivially_copy_pass_by_ref)] + fn not(bool: &bool) -> bool { + !*bool + } + + assert("!bool = false", Error(true)); +} + +#[test] +fn test_match() { + #[derive(Error, Debug)] + #[error("{}: {0}", match .1 { + Some(n) => format!("error occurred with {}", n), + None => "there was an empty error".to_owned(), + })] + struct Error(String, Option<usize>); + + assert( + "error occurred with 1: ...", + Error("...".to_owned(), Some(1)), + ); + assert( + "there was an empty error: ...", + Error("...".to_owned(), None), + ); +} + +#[test] +fn test_void() { + #[allow(clippy::empty_enum)] + #[derive(Error, Debug)] + #[error("...")] + pub enum Error {} + + let _: Error; +} + +#[test] +fn test_mixed() { + #[derive(Error, Debug)] + #[error("a={a} :: b={} :: c={c} :: d={d}", 1, c = 2, d = 3)] + struct Error { + a: usize, + d: usize, + } + + assert("a=0 :: b=1 :: c=2 :: d=3", Error { a: 0, d: 0 }); +} + +#[test] +fn test_ints() { + #[derive(Error, Debug)] + enum Error { + #[error("error {0}")] + Tuple(usize, usize), + #[error("error {0}", '?')] + Struct { v: usize }, + } + + assert("error 9", Error::Tuple(9, 0)); + assert("error ?", Error::Struct { v: 0 }); +} + +#[test] +fn test_trailing_comma() { + #[derive(Error, Debug)] + #[error( + "error {0}", + )] + #[rustfmt::skip] + struct Error(char); + + assert("error ?", Error('?')); +} + +#[test] +fn test_field() { + #[derive(Debug)] + struct Inner { + data: usize, + } + + #[derive(Error, Debug)] + #[error("{}", .0.data)] + struct Error(Inner); + + assert("0", Error(Inner { data: 0 })); +} + +#[test] +fn test_macro_rules() { + // Regression test for https://github.com/dtolnay/thiserror/issues/86 + + macro_rules! decl_error { + ($variant:ident($value:ident)) => { + #[derive(Debug, Error)] + pub enum Error0 { + #[error("{0:?}")] + $variant($value), + } + + #[derive(Debug, Error)] + #[error("{0:?}")] + pub enum Error1 { + $variant($value), + } + }; + } + + decl_error!(Repro(u8)); + + assert("0", Error0::Repro(0)); + assert("0", Error1::Repro(0)); +} diff --git a/third_party/rust/thiserror/tests/test_error.rs b/third_party/rust/thiserror/tests/test_error.rs new file mode 100644 index 0000000000..ece7f91a90 --- /dev/null +++ b/third_party/rust/thiserror/tests/test_error.rs @@ -0,0 +1,57 @@ +#![deny(clippy::all, clippy::pedantic)] +#![allow(dead_code)] + +use std::fmt::{self, Display}; +use std::io; +use thiserror::Error; + +macro_rules! unimplemented_display { + ($ty:ty) => { + impl Display for $ty { + fn fmt(&self, _formatter: &mut fmt::Formatter) -> fmt::Result { + unimplemented!() + } + } + }; +} + +#[derive(Error, Debug)] +struct BracedError { + msg: String, + pos: usize, +} + +#[derive(Error, Debug)] +struct TupleError(String, usize); + +#[derive(Error, Debug)] +struct UnitError; + +#[derive(Error, Debug)] +struct WithSource { + #[source] + cause: io::Error, +} + +#[derive(Error, Debug)] +struct WithAnyhow { + #[source] + cause: anyhow::Error, +} + +#[derive(Error, Debug)] +enum EnumError { + Braced { + #[source] + cause: io::Error, + }, + Tuple(#[source] io::Error), + Unit, +} + +unimplemented_display!(BracedError); +unimplemented_display!(TupleError); +unimplemented_display!(UnitError); +unimplemented_display!(WithSource); +unimplemented_display!(WithAnyhow); +unimplemented_display!(EnumError); diff --git a/third_party/rust/thiserror/tests/test_expr.rs b/third_party/rust/thiserror/tests/test_expr.rs new file mode 100644 index 0000000000..87a56cf584 --- /dev/null +++ b/third_party/rust/thiserror/tests/test_expr.rs @@ -0,0 +1,89 @@ +#![deny(clippy::all, clippy::pedantic)] +#![allow(clippy::option_if_let_else)] + +use std::fmt::Display; +use thiserror::Error; + +// Some of the elaborate cases from the rcc codebase, which is a C compiler in +// Rust. https://github.com/jyn514/rcc/blob/0.8.0/src/data/error.rs +#[derive(Error, Debug)] +pub enum CompilerError { + #[error("cannot shift {} by {maximum} or more bits (got {current})", if *.is_left { "left" } else { "right" })] + TooManyShiftBits { + is_left: bool, + maximum: u64, + current: u64, + }, + + #[error("#error {}", (.0).iter().copied().collect::<Vec<_>>().join(" "))] + User(Vec<&'static str>), + + #[error("overflow while parsing {}integer literal", + if let Some(signed) = .is_signed { + if *signed { "signed "} else { "unsigned "} + } else { + "" + } + )] + IntegerOverflow { is_signed: Option<bool> }, + + #[error("overflow while parsing {}integer literal", match .is_signed { + Some(true) => "signed ", + Some(false) => "unsigned ", + None => "", + })] + IntegerOverflow2 { is_signed: Option<bool> }, +} + +// Examples drawn from Rustup. +#[derive(Error, Debug)] +pub enum RustupError { + #[error( + "toolchain '{name}' does not contain component {component}{}", + .suggestion + .as_ref() + .map_or_else(String::new, |s| format!("; did you mean '{}'?", s)), + )] + UnknownComponent { + name: String, + component: String, + suggestion: Option<String>, + }, +} + +fn assert<T: Display>(expected: &str, value: T) { + assert_eq!(expected, value.to_string()); +} + +#[test] +fn test_rcc() { + assert( + "cannot shift left by 32 or more bits (got 50)", + CompilerError::TooManyShiftBits { + is_left: true, + maximum: 32, + current: 50, + }, + ); + + assert("#error A B C", CompilerError::User(vec!["A", "B", "C"])); + + assert( + "overflow while parsing signed integer literal", + CompilerError::IntegerOverflow { + is_signed: Some(true), + }, + ); +} + +#[test] +fn test_rustup() { + assert( + "toolchain 'nightly' does not contain component clipy; did you mean 'clippy'?", + RustupError::UnknownComponent { + name: "nightly".to_owned(), + component: "clipy".to_owned(), + suggestion: Some("clippy".to_owned()), + }, + ); +} diff --git a/third_party/rust/thiserror/tests/test_from.rs b/third_party/rust/thiserror/tests/test_from.rs new file mode 100644 index 0000000000..e8f01610d8 --- /dev/null +++ b/third_party/rust/thiserror/tests/test_from.rs @@ -0,0 +1,41 @@ +#![deny(clippy::all, clippy::pedantic)] + +use std::io; +use thiserror::Error; + +#[derive(Error, Debug)] +#[error("...")] +pub struct ErrorStruct { + #[from] + source: io::Error, +} + +#[derive(Error, Debug)] +#[error("...")] +pub struct ErrorTuple(#[from] io::Error); + +#[derive(Error, Debug)] +#[error("...")] +pub enum ErrorEnum { + Test { + #[from] + source: io::Error, + }, +} + +#[derive(Error, Debug)] +#[error("...")] +pub enum Many { + Any(#[from] anyhow::Error), + Io(#[from] io::Error), +} + +fn assert_impl<T: From<io::Error>>() {} + +#[test] +fn test_from() { + assert_impl::<ErrorStruct>(); + assert_impl::<ErrorTuple>(); + assert_impl::<ErrorEnum>(); + assert_impl::<Many>(); +} diff --git a/third_party/rust/thiserror/tests/test_lints.rs b/third_party/rust/thiserror/tests/test_lints.rs new file mode 100644 index 0000000000..59699a4a3f --- /dev/null +++ b/third_party/rust/thiserror/tests/test_lints.rs @@ -0,0 +1,18 @@ +use thiserror::Error; + +pub use std::error::Error; + +#[test] +fn test_unused_qualifications() { + #![deny(unused_qualifications)] + + // Expansion of derive(Error) macro can't know whether something like + // std::error::Error is already imported in the caller's scope so it must + // suppress unused_qualifications. + + #[derive(Debug, Error)] + #[error("...")] + pub struct MyError; + + let _: MyError; +} diff --git a/third_party/rust/thiserror/tests/test_option.rs b/third_party/rust/thiserror/tests/test_option.rs new file mode 100644 index 0000000000..ca21713852 --- /dev/null +++ b/third_party/rust/thiserror/tests/test_option.rs @@ -0,0 +1,106 @@ +#![cfg_attr(thiserror_nightly_testing, feature(backtrace))] +#![deny(clippy::all, clippy::pedantic)] + +#[cfg(thiserror_nightly_testing)] +pub mod structs { + use std::backtrace::Backtrace; + use thiserror::Error; + + #[derive(Error, Debug)] + #[error("...")] + pub struct OptSourceNoBacktrace { + #[source] + source: Option<anyhow::Error>, + } + + #[derive(Error, Debug)] + #[error("...")] + pub struct OptSourceAlwaysBacktrace { + #[source] + source: Option<anyhow::Error>, + backtrace: Backtrace, + } + + #[derive(Error, Debug)] + #[error("...")] + pub struct NoSourceOptBacktrace { + #[backtrace] + backtrace: Option<Backtrace>, + } + + #[derive(Error, Debug)] + #[error("...")] + pub struct AlwaysSourceOptBacktrace { + source: anyhow::Error, + #[backtrace] + backtrace: Option<Backtrace>, + } + + #[derive(Error, Debug)] + #[error("...")] + pub struct OptSourceOptBacktrace { + #[source] + source: Option<anyhow::Error>, + #[backtrace] + backtrace: Option<Backtrace>, + } +} + +#[cfg(thiserror_nightly_testing)] +pub mod enums { + use std::backtrace::Backtrace; + use thiserror::Error; + + #[derive(Error, Debug)] + pub enum OptSourceNoBacktrace { + #[error("...")] + Test { + #[source] + source: Option<anyhow::Error>, + }, + } + + #[derive(Error, Debug)] + pub enum OptSourceAlwaysBacktrace { + #[error("...")] + Test { + #[source] + source: Option<anyhow::Error>, + backtrace: Backtrace, + }, + } + + #[derive(Error, Debug)] + pub enum NoSourceOptBacktrace { + #[error("...")] + Test { + #[backtrace] + backtrace: Option<Backtrace>, + }, + } + + #[derive(Error, Debug)] + pub enum AlwaysSourceOptBacktrace { + #[error("...")] + Test { + source: anyhow::Error, + #[backtrace] + backtrace: Option<Backtrace>, + }, + } + + #[derive(Error, Debug)] + pub enum OptSourceOptBacktrace { + #[error("...")] + Test { + #[source] + source: Option<anyhow::Error>, + #[backtrace] + backtrace: Option<Backtrace>, + }, + } +} + +#[test] +#[cfg_attr(not(thiserror_nightly_testing), ignore)] +fn test_option() {} diff --git a/third_party/rust/thiserror/tests/test_path.rs b/third_party/rust/thiserror/tests/test_path.rs new file mode 100644 index 0000000000..a10b1f3426 --- /dev/null +++ b/third_party/rust/thiserror/tests/test_path.rs @@ -0,0 +1,39 @@ +#![deny(clippy::all, clippy::pedantic)] + +use ref_cast::RefCast; +use std::fmt::Display; +use std::path::{Path, PathBuf}; +use thiserror::Error; + +#[derive(Error, Debug)] +#[error("failed to read '{file}'")] +struct StructPathBuf { + file: PathBuf, +} + +#[derive(Error, Debug, RefCast)] +#[repr(C)] +#[error("failed to read '{file}'")] +struct StructPath { + file: Path, +} + +#[derive(Error, Debug)] +enum EnumPathBuf { + #[error("failed to read '{0}'")] + Read(PathBuf), +} + +fn assert<T: Display>(expected: &str, value: T) { + assert_eq!(expected, value.to_string()); +} + +#[test] +fn test_display() { + let path = Path::new("/thiserror"); + let file = path.to_owned(); + assert("failed to read '/thiserror'", StructPathBuf { file }); + let file = path.to_owned(); + assert("failed to read '/thiserror'", EnumPathBuf::Read(file)); + assert("failed to read '/thiserror'", StructPath::ref_cast(path)); +} diff --git a/third_party/rust/thiserror/tests/test_source.rs b/third_party/rust/thiserror/tests/test_source.rs new file mode 100644 index 0000000000..66d9dad592 --- /dev/null +++ b/third_party/rust/thiserror/tests/test_source.rs @@ -0,0 +1,50 @@ +#![deny(clippy::all, clippy::pedantic)] + +use std::error::Error as StdError; +use std::io; +use thiserror::Error; + +#[derive(Error, Debug)] +#[error("implicit source")] +pub struct ImplicitSource { + source: io::Error, +} + +#[derive(Error, Debug)] +#[error("explicit source")] +pub struct ExplicitSource { + source: String, + #[source] + io: io::Error, +} + +#[derive(Error, Debug)] +#[error("boxed source")] +pub struct BoxedSource { + #[source] + source: Box<dyn StdError + Send + 'static>, +} + +#[test] +fn test_implicit_source() { + let io = io::Error::new(io::ErrorKind::Other, "oh no!"); + let error = ImplicitSource { source: io }; + error.source().unwrap().downcast_ref::<io::Error>().unwrap(); +} + +#[test] +fn test_explicit_source() { + let io = io::Error::new(io::ErrorKind::Other, "oh no!"); + let error = ExplicitSource { + source: String::new(), + io, + }; + error.source().unwrap().downcast_ref::<io::Error>().unwrap(); +} + +#[test] +fn test_boxed_source() { + let source = Box::new(io::Error::new(io::ErrorKind::Other, "oh no!")); + let error = BoxedSource { source }; + error.source().unwrap().downcast_ref::<io::Error>().unwrap(); +} diff --git a/third_party/rust/thiserror/tests/test_transparent.rs b/third_party/rust/thiserror/tests/test_transparent.rs new file mode 100644 index 0000000000..b862b2546f --- /dev/null +++ b/third_party/rust/thiserror/tests/test_transparent.rs @@ -0,0 +1,59 @@ +#![deny(clippy::all, clippy::pedantic)] + +use anyhow::anyhow; +use std::error::Error as _; +use std::io; +use thiserror::Error; + +#[test] +fn test_transparent_struct() { + #[derive(Error, Debug)] + #[error(transparent)] + struct Error(ErrorKind); + + #[derive(Error, Debug)] + enum ErrorKind { + #[error("E0")] + E0, + #[error("E1")] + E1(#[from] io::Error), + } + + let error = Error(ErrorKind::E0); + assert_eq!("E0", error.to_string()); + assert!(error.source().is_none()); + + let io = io::Error::new(io::ErrorKind::Other, "oh no!"); + let error = Error(ErrorKind::from(io)); + assert_eq!("E1", error.to_string()); + error.source().unwrap().downcast_ref::<io::Error>().unwrap(); +} + +#[test] +fn test_transparent_enum() { + #[derive(Error, Debug)] + enum Error { + #[error("this failed")] + This, + #[error(transparent)] + Other(anyhow::Error), + } + + let error = Error::This; + assert_eq!("this failed", error.to_string()); + + let error = Error::Other(anyhow!("inner").context("outer")); + assert_eq!("outer", error.to_string()); + assert_eq!("inner", error.source().unwrap().to_string()); +} + +#[test] +fn test_anyhow() { + #[derive(Error, Debug)] + #[error(transparent)] + struct Any(#[from] anyhow::Error); + + let error = Any::from(anyhow!("inner").context("outer")); + assert_eq!("outer", error.to_string()); + assert_eq!("inner", error.source().unwrap().to_string()); +} diff --git a/third_party/rust/thiserror/tests/ui/bad-field-attr.rs b/third_party/rust/thiserror/tests/ui/bad-field-attr.rs new file mode 100644 index 0000000000..d5429b2b26 --- /dev/null +++ b/third_party/rust/thiserror/tests/ui/bad-field-attr.rs @@ -0,0 +1,7 @@ +use thiserror::Error; + +#[derive(Error, Debug)] +#[error(transparent)] +pub struct Error(#[error(transparent)] std::io::Error); + +fn main() {} diff --git a/third_party/rust/thiserror/tests/ui/bad-field-attr.stderr b/third_party/rust/thiserror/tests/ui/bad-field-attr.stderr new file mode 100644 index 0000000000..ecc4702597 --- /dev/null +++ b/third_party/rust/thiserror/tests/ui/bad-field-attr.stderr @@ -0,0 +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 + | +5 | pub struct Error(#[error(transparent)] std::io::Error); + | ^^^^^^^^^^^^^^^^^^^^^ diff --git a/third_party/rust/thiserror/tests/ui/duplicate-enum-source.rs b/third_party/rust/thiserror/tests/ui/duplicate-enum-source.rs new file mode 100644 index 0000000000..15e579f8fa --- /dev/null +++ b/third_party/rust/thiserror/tests/ui/duplicate-enum-source.rs @@ -0,0 +1,13 @@ +use thiserror::Error; + +#[derive(Error, Debug)] +pub enum ErrorEnum { + Confusing { + #[source] + a: std::io::Error, + #[source] + b: anyhow::Error, + }, +} + +fn main() {} diff --git a/third_party/rust/thiserror/tests/ui/duplicate-enum-source.stderr b/third_party/rust/thiserror/tests/ui/duplicate-enum-source.stderr new file mode 100644 index 0000000000..55d81be023 --- /dev/null +++ b/third_party/rust/thiserror/tests/ui/duplicate-enum-source.stderr @@ -0,0 +1,5 @@ +error: duplicate #[source] attribute + --> $DIR/duplicate-enum-source.rs:8:9 + | +8 | #[source] + | ^^^^^^^^^ diff --git a/third_party/rust/thiserror/tests/ui/duplicate-fmt.rs b/third_party/rust/thiserror/tests/ui/duplicate-fmt.rs new file mode 100644 index 0000000000..cb3d67881f --- /dev/null +++ b/third_party/rust/thiserror/tests/ui/duplicate-fmt.rs @@ -0,0 +1,8 @@ +use thiserror::Error; + +#[derive(Error, Debug)] +#[error("...")] +#[error("...")] +pub struct Error; + +fn main() {} diff --git a/third_party/rust/thiserror/tests/ui/duplicate-fmt.stderr b/third_party/rust/thiserror/tests/ui/duplicate-fmt.stderr new file mode 100644 index 0000000000..32066406f6 --- /dev/null +++ b/third_party/rust/thiserror/tests/ui/duplicate-fmt.stderr @@ -0,0 +1,5 @@ +error: only one #[error(...)] attribute is allowed + --> $DIR/duplicate-fmt.rs:5:1 + | +5 | #[error("...")] + | ^^^^^^^^^^^^^^^ diff --git a/third_party/rust/thiserror/tests/ui/duplicate-struct-source.rs b/third_party/rust/thiserror/tests/ui/duplicate-struct-source.rs new file mode 100644 index 0000000000..569df8dd40 --- /dev/null +++ b/third_party/rust/thiserror/tests/ui/duplicate-struct-source.rs @@ -0,0 +1,11 @@ +use thiserror::Error; + +#[derive(Error, Debug)] +pub struct ErrorStruct { + #[source] + a: std::io::Error, + #[source] + b: anyhow::Error, +} + +fn main() {} diff --git a/third_party/rust/thiserror/tests/ui/duplicate-struct-source.stderr b/third_party/rust/thiserror/tests/ui/duplicate-struct-source.stderr new file mode 100644 index 0000000000..76fc6f513b --- /dev/null +++ b/third_party/rust/thiserror/tests/ui/duplicate-struct-source.stderr @@ -0,0 +1,5 @@ +error: duplicate #[source] attribute + --> $DIR/duplicate-struct-source.rs:7:5 + | +7 | #[source] + | ^^^^^^^^^ diff --git a/third_party/rust/thiserror/tests/ui/duplicate-transparent.rs b/third_party/rust/thiserror/tests/ui/duplicate-transparent.rs new file mode 100644 index 0000000000..49c0e46679 --- /dev/null +++ b/third_party/rust/thiserror/tests/ui/duplicate-transparent.rs @@ -0,0 +1,8 @@ +use thiserror::Error; + +#[derive(Error, Debug)] +#[error(transparent)] +#[error(transparent)] +pub struct Error(anyhow::Error); + +fn main() {} diff --git a/third_party/rust/thiserror/tests/ui/duplicate-transparent.stderr b/third_party/rust/thiserror/tests/ui/duplicate-transparent.stderr new file mode 100644 index 0000000000..c9634752ac --- /dev/null +++ b/third_party/rust/thiserror/tests/ui/duplicate-transparent.stderr @@ -0,0 +1,5 @@ +error: duplicate #[error(transparent)] attribute + --> $DIR/duplicate-transparent.rs:5:1 + | +5 | #[error(transparent)] + | ^^^^^^^^^^^^^^^^^^^^^ diff --git a/third_party/rust/thiserror/tests/ui/from-not-source.rs b/third_party/rust/thiserror/tests/ui/from-not-source.rs new file mode 100644 index 0000000000..d1855bec5c --- /dev/null +++ b/third_party/rust/thiserror/tests/ui/from-not-source.rs @@ -0,0 +1,11 @@ +use thiserror::Error; + +#[derive(Debug, Error)] +pub struct Error { + #[source] + source: std::io::Error, + #[from] + other: anyhow::Error, +} + +fn main() {} diff --git a/third_party/rust/thiserror/tests/ui/from-not-source.stderr b/third_party/rust/thiserror/tests/ui/from-not-source.stderr new file mode 100644 index 0000000000..b656c8ed6b --- /dev/null +++ b/third_party/rust/thiserror/tests/ui/from-not-source.stderr @@ -0,0 +1,5 @@ +error: #[from] is only supported on the source field, not any other field + --> $DIR/from-not-source.rs:7:5 + | +7 | #[from] + | ^^^^^^^ diff --git a/third_party/rust/thiserror/tests/ui/lifetime.rs b/third_party/rust/thiserror/tests/ui/lifetime.rs new file mode 100644 index 0000000000..63c6970dbc --- /dev/null +++ b/third_party/rust/thiserror/tests/ui/lifetime.rs @@ -0,0 +1,13 @@ +use thiserror::Error; + +#[derive(Error, Debug)] +#[error("error")] +struct Error<'a>(#[from] Inner<'a>); + +#[derive(Error, Debug)] +#[error("{0}")] +struct Inner<'a>(&'a str); + +fn main() -> Result<(), Error<'static>> { + Err(Error(Inner("some text"))) +} diff --git a/third_party/rust/thiserror/tests/ui/lifetime.stderr b/third_party/rust/thiserror/tests/ui/lifetime.stderr new file mode 100644 index 0000000000..500f6abaac --- /dev/null +++ b/third_party/rust/thiserror/tests/ui/lifetime.stderr @@ -0,0 +1,5 @@ +error: non-static lifetimes are not allowed in the source of an error + --> $DIR/lifetime.rs:5:18 + | +5 | struct Error<'a>(#[from] Inner<'a>); + | ^^^^^^^^^^^^^^^^^ diff --git a/third_party/rust/thiserror/tests/ui/missing-fmt.rs b/third_party/rust/thiserror/tests/ui/missing-fmt.rs new file mode 100644 index 0000000000..d52fbdf0d9 --- /dev/null +++ b/third_party/rust/thiserror/tests/ui/missing-fmt.rs @@ -0,0 +1,10 @@ +use thiserror::Error; + +#[derive(Error, Debug)] +pub enum Error { + #[error("...")] + A(usize), + B(usize), +} + +fn main() {} diff --git a/third_party/rust/thiserror/tests/ui/missing-fmt.stderr b/third_party/rust/thiserror/tests/ui/missing-fmt.stderr new file mode 100644 index 0000000000..1d21b1b0f5 --- /dev/null +++ b/third_party/rust/thiserror/tests/ui/missing-fmt.stderr @@ -0,0 +1,5 @@ +error: missing #[error("...")] display attribute + --> $DIR/missing-fmt.rs:7:5 + | +7 | B(usize), + | ^^^^^^^^ diff --git a/third_party/rust/thiserror/tests/ui/no-display.rs b/third_party/rust/thiserror/tests/ui/no-display.rs new file mode 100644 index 0000000000..181a66e02c --- /dev/null +++ b/third_party/rust/thiserror/tests/ui/no-display.rs @@ -0,0 +1,12 @@ +use thiserror::Error; + +#[derive(Debug)] +struct NoDisplay; + +#[derive(Error, Debug)] +#[error("thread: {thread}")] +pub struct Error { + thread: NoDisplay, +} + +fn main() {} diff --git a/third_party/rust/thiserror/tests/ui/no-display.stderr b/third_party/rust/thiserror/tests/ui/no-display.stderr new file mode 100644 index 0000000000..b1a0c495f1 --- /dev/null +++ b/third_party/rust/thiserror/tests/ui/no-display.stderr @@ -0,0 +1,12 @@ +error[E0599]: no method named `as_display` found for reference `&NoDisplay` in the current scope + --> $DIR/no-display.rs:7:9 + | +4 | struct NoDisplay; + | ----------------- doesn't satisfy `NoDisplay: std::fmt::Display` +... +7 | #[error("thread: {thread}")] + | ^^^^^^^^^^^^^^^^^^ method not found in `&NoDisplay` + | + = note: the method `as_display` exists but the following trait bounds were not satisfied: + `NoDisplay: std::fmt::Display` + which is required by `&NoDisplay: DisplayAsDisplay` diff --git a/third_party/rust/thiserror/tests/ui/source-enum-not-error.rs b/third_party/rust/thiserror/tests/ui/source-enum-not-error.rs new file mode 100644 index 0000000000..3eb0d3e866 --- /dev/null +++ b/third_party/rust/thiserror/tests/ui/source-enum-not-error.rs @@ -0,0 +1,14 @@ +use thiserror::Error; + +#[derive(Debug)] +pub struct NotError; + +#[derive(Error, Debug)] +#[error("...")] +pub enum ErrorEnum { + Broken { + source: NotError, + }, +} + +fn main() {} diff --git a/third_party/rust/thiserror/tests/ui/source-enum-not-error.stderr b/third_party/rust/thiserror/tests/ui/source-enum-not-error.stderr new file mode 100644 index 0000000000..3dee730d58 --- /dev/null +++ b/third_party/rust/thiserror/tests/ui/source-enum-not-error.stderr @@ -0,0 +1,17 @@ +error[E0599]: no method named `as_dyn_error` found for reference `&NotError` in the current scope + --> $DIR/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 not found in `&NotError` + | + = note: the method `as_dyn_error` exists but 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` diff --git a/third_party/rust/thiserror/tests/ui/source-struct-not-error.rs b/third_party/rust/thiserror/tests/ui/source-struct-not-error.rs new file mode 100644 index 0000000000..d59df1eef8 --- /dev/null +++ b/third_party/rust/thiserror/tests/ui/source-struct-not-error.rs @@ -0,0 +1,12 @@ +use thiserror::Error; + +#[derive(Debug)] +struct NotError; + +#[derive(Error, Debug)] +#[error("...")] +pub struct ErrorStruct { + source: NotError, +} + +fn main() {} diff --git a/third_party/rust/thiserror/tests/ui/source-struct-not-error.stderr b/third_party/rust/thiserror/tests/ui/source-struct-not-error.stderr new file mode 100644 index 0000000000..0aa03ddcc9 --- /dev/null +++ b/third_party/rust/thiserror/tests/ui/source-struct-not-error.stderr @@ -0,0 +1,16 @@ +error[E0599]: no method named `as_dyn_error` found for struct `NotError` in the current scope + --> $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` +... +9 | source: NotError, + | ^^^^^^ method not found in `NotError` + | + = note: the method `as_dyn_error` exists but the following trait bounds were not satisfied: + `NotError: std::error::Error` + which is required by `NotError: AsDynError` diff --git a/third_party/rust/thiserror/tests/ui/transparent-display.rs b/third_party/rust/thiserror/tests/ui/transparent-display.rs new file mode 100644 index 0000000000..2a59f183ba --- /dev/null +++ b/third_party/rust/thiserror/tests/ui/transparent-display.rs @@ -0,0 +1,8 @@ +use thiserror::Error; + +#[derive(Error, Debug)] +#[error(transparent)] +#[error("...")] +pub struct Error(anyhow::Error); + +fn main() {} diff --git a/third_party/rust/thiserror/tests/ui/transparent-display.stderr b/third_party/rust/thiserror/tests/ui/transparent-display.stderr new file mode 100644 index 0000000000..014883054a --- /dev/null +++ b/third_party/rust/thiserror/tests/ui/transparent-display.stderr @@ -0,0 +1,5 @@ +error: cannot have both #[error(transparent)] and a display attribute + --> $DIR/transparent-display.rs:5:1 + | +5 | #[error("...")] + | ^^^^^^^^^^^^^^^ diff --git a/third_party/rust/thiserror/tests/ui/transparent-enum-many.rs b/third_party/rust/thiserror/tests/ui/transparent-enum-many.rs new file mode 100644 index 0000000000..e2a73a4700 --- /dev/null +++ b/third_party/rust/thiserror/tests/ui/transparent-enum-many.rs @@ -0,0 +1,9 @@ +use thiserror::Error; + +#[derive(Error, Debug)] +pub enum Error { + #[error(transparent)] + Other(anyhow::Error, String), +} + +fn main() {} diff --git a/third_party/rust/thiserror/tests/ui/transparent-enum-many.stderr b/third_party/rust/thiserror/tests/ui/transparent-enum-many.stderr new file mode 100644 index 0000000000..0c409ef401 --- /dev/null +++ b/third_party/rust/thiserror/tests/ui/transparent-enum-many.stderr @@ -0,0 +1,6 @@ +error: #[error(transparent)] requires exactly one field + --> $DIR/transparent-enum-many.rs:5:5 + | +5 | / #[error(transparent)] +6 | | Other(anyhow::Error, String), + | |________________________________^ diff --git a/third_party/rust/thiserror/tests/ui/transparent-enum-source.rs b/third_party/rust/thiserror/tests/ui/transparent-enum-source.rs new file mode 100644 index 0000000000..3849f66e78 --- /dev/null +++ b/third_party/rust/thiserror/tests/ui/transparent-enum-source.rs @@ -0,0 +1,9 @@ +use thiserror::Error; + +#[derive(Error, Debug)] +pub enum Error { + #[error(transparent)] + Other(#[source] anyhow::Error), +} + +fn main() {} diff --git a/third_party/rust/thiserror/tests/ui/transparent-enum-source.stderr b/third_party/rust/thiserror/tests/ui/transparent-enum-source.stderr new file mode 100644 index 0000000000..a4e698570f --- /dev/null +++ b/third_party/rust/thiserror/tests/ui/transparent-enum-source.stderr @@ -0,0 +1,5 @@ +error: transparent variant can't contain #[source] + --> $DIR/transparent-enum-source.rs:6:11 + | +6 | Other(#[source] anyhow::Error), + | ^^^^^^^^^ diff --git a/third_party/rust/thiserror/tests/ui/transparent-struct-many.rs b/third_party/rust/thiserror/tests/ui/transparent-struct-many.rs new file mode 100644 index 0000000000..18f2466450 --- /dev/null +++ b/third_party/rust/thiserror/tests/ui/transparent-struct-many.rs @@ -0,0 +1,10 @@ +use thiserror::Error; + +#[derive(Error, Debug)] +#[error(transparent)] +pub struct Error { + inner: anyhow::Error, + what: String, +} + +fn main() {} diff --git a/third_party/rust/thiserror/tests/ui/transparent-struct-many.stderr b/third_party/rust/thiserror/tests/ui/transparent-struct-many.stderr new file mode 100644 index 0000000000..102f0b3e25 --- /dev/null +++ b/third_party/rust/thiserror/tests/ui/transparent-struct-many.stderr @@ -0,0 +1,5 @@ +error: #[error(transparent)] requires exactly one field + --> $DIR/transparent-struct-many.rs:4:1 + | +4 | #[error(transparent)] + | ^^^^^^^^^^^^^^^^^^^^^ diff --git a/third_party/rust/thiserror/tests/ui/transparent-struct-source.rs b/third_party/rust/thiserror/tests/ui/transparent-struct-source.rs new file mode 100644 index 0000000000..d4512c288b --- /dev/null +++ b/third_party/rust/thiserror/tests/ui/transparent-struct-source.rs @@ -0,0 +1,7 @@ +use thiserror::Error; + +#[derive(Error, Debug)] +#[error(transparent)] +pub struct Error(#[source] anyhow::Error); + +fn main() {} diff --git a/third_party/rust/thiserror/tests/ui/transparent-struct-source.stderr b/third_party/rust/thiserror/tests/ui/transparent-struct-source.stderr new file mode 100644 index 0000000000..16ea50b27e --- /dev/null +++ b/third_party/rust/thiserror/tests/ui/transparent-struct-source.stderr @@ -0,0 +1,5 @@ +error: transparent error struct can't contain #[source] + --> $DIR/transparent-struct-source.rs:5:18 + | +5 | pub struct Error(#[source] anyhow::Error); + | ^^^^^^^^^ diff --git a/third_party/rust/thiserror/tests/ui/unexpected-field-fmt.rs b/third_party/rust/thiserror/tests/ui/unexpected-field-fmt.rs new file mode 100644 index 0000000000..7c439d941f --- /dev/null +++ b/third_party/rust/thiserror/tests/ui/unexpected-field-fmt.rs @@ -0,0 +1,11 @@ +use thiserror::Error; + +#[derive(Error, Debug)] +pub enum Error { + What { + #[error("...")] + io: std::io::Error, + }, +} + +fn main() {} diff --git a/third_party/rust/thiserror/tests/ui/unexpected-field-fmt.stderr b/third_party/rust/thiserror/tests/ui/unexpected-field-fmt.stderr new file mode 100644 index 0000000000..42d80db2c4 --- /dev/null +++ b/third_party/rust/thiserror/tests/ui/unexpected-field-fmt.stderr @@ -0,0 +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 + | +6 | #[error("...")] + | ^^^^^^^^^^^^^^^ diff --git a/third_party/rust/thiserror/tests/ui/unexpected-struct-source.rs b/third_party/rust/thiserror/tests/ui/unexpected-struct-source.rs new file mode 100644 index 0000000000..f39649424c --- /dev/null +++ b/third_party/rust/thiserror/tests/ui/unexpected-struct-source.rs @@ -0,0 +1,7 @@ +use thiserror::Error; + +#[derive(Error, Debug)] +#[source] +pub struct Error; + +fn main() {} diff --git a/third_party/rust/thiserror/tests/ui/unexpected-struct-source.stderr b/third_party/rust/thiserror/tests/ui/unexpected-struct-source.stderr new file mode 100644 index 0000000000..f48d5547e2 --- /dev/null +++ b/third_party/rust/thiserror/tests/ui/unexpected-struct-source.stderr @@ -0,0 +1,5 @@ +error: not expected here; the #[source] attribute belongs on a specific field + --> $DIR/unexpected-struct-source.rs:4:1 + | +4 | #[source] + | ^^^^^^^^^ diff --git a/third_party/rust/thiserror/tests/ui/union.rs b/third_party/rust/thiserror/tests/ui/union.rs new file mode 100644 index 0000000000..cd6a9346d5 --- /dev/null +++ b/third_party/rust/thiserror/tests/ui/union.rs @@ -0,0 +1,9 @@ +use thiserror::Error; + +#[derive(Error)] +pub union U { + msg: &'static str, + num: usize, +} + +fn main() {} diff --git a/third_party/rust/thiserror/tests/ui/union.stderr b/third_party/rust/thiserror/tests/ui/union.stderr new file mode 100644 index 0000000000..a378011c81 --- /dev/null +++ b/third_party/rust/thiserror/tests/ui/union.stderr @@ -0,0 +1,8 @@ +error: union as errors are not supported + --> $DIR/union.rs:4:1 + | +4 | / pub union U { +5 | | msg: &'static str, +6 | | num: usize, +7 | | } + | |_^ |