diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-17 12:19:03 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-17 12:19:03 +0000 |
commit | 64d98f8ee037282c35007b64c2649055c56af1db (patch) | |
tree | 5492bcf97fce41ee1c0b1cc2add283f3e66cdab0 /tests/ui/try-trait/try-operator-custom.rs | |
parent | Adding debian version 1.67.1+dfsg1-1. (diff) | |
download | rustc-64d98f8ee037282c35007b64c2649055c56af1db.tar.xz rustc-64d98f8ee037282c35007b64c2649055c56af1db.zip |
Merging upstream version 1.68.2+dfsg1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'tests/ui/try-trait/try-operator-custom.rs')
-rw-r--r-- | tests/ui/try-trait/try-operator-custom.rs | 91 |
1 files changed, 91 insertions, 0 deletions
diff --git a/tests/ui/try-trait/try-operator-custom.rs b/tests/ui/try-trait/try-operator-custom.rs new file mode 100644 index 000000000..45636a7fc --- /dev/null +++ b/tests/ui/try-trait/try-operator-custom.rs @@ -0,0 +1,91 @@ +// run-pass + +#![feature(control_flow_enum)] +#![feature(try_trait_v2)] + +use std::ops::{ControlFlow, FromResidual, Try}; + +enum MyResult<T, U> { + Awesome(T), + Terrible(U) +} + +enum Never {} + +impl<U, V> Try for MyResult<U, V> { + type Output = U; + type Residual = MyResult<Never, V>; + + fn from_output(u: U) -> MyResult<U, V> { + MyResult::Awesome(u) + } + + fn branch(self) -> ControlFlow<Self::Residual, Self::Output> { + match self { + MyResult::Awesome(u) => ControlFlow::Continue(u), + MyResult::Terrible(e) => ControlFlow::Break(MyResult::Terrible(e)), + } + } +} + +impl<U, V, W> FromResidual<MyResult<Never, V>> for MyResult<U, W> where V: Into<W> { + fn from_residual(x: MyResult<Never, V>) -> Self { + match x { + MyResult::Awesome(u) => match u {}, + MyResult::Terrible(e) => MyResult::Terrible(e.into()), + } + } +} + +type ResultResidual<E> = Result<std::convert::Infallible, E>; + +impl<U, V, W> FromResidual<ResultResidual<V>> for MyResult<U, W> where V: Into<W> { + fn from_residual(x: ResultResidual<V>) -> Self { + match x { + Ok(v) => match v {} + Err(e) => MyResult::Terrible(e.into()), + } + } +} + +impl<U, V, W> FromResidual<MyResult<Never, V>> for Result<U, W> where V: Into<W> { + fn from_residual(x: MyResult<Never, V>) -> Self { + match x { + MyResult::Awesome(u) => match u {}, + MyResult::Terrible(e) => Err(e.into()), + } + } +} + +fn f(x: i32) -> Result<i32, String> { + if x == 0 { + Ok(42) + } else { + let y = g(x)?; + Ok(y) + } +} + +fn g(x: i32) -> MyResult<i32, String> { + let _y = f(x - 1)?; + MyResult::Terrible("Hello".to_owned()) +} + +fn h() -> MyResult<i32, String> { + let a: Result<i32, &'static str> = Err("Hello"); + let b = a?; + MyResult::Awesome(b) +} + +fn i() -> MyResult<i32, String> { + let a: MyResult<i32, &'static str> = MyResult::Terrible("Hello"); + let b = a?; + MyResult::Awesome(b) +} + +fn main() { + assert!(f(0) == Ok(42)); + assert!(f(10) == Err("Hello".to_owned())); + let _ = h(); + let _ = i(); +} |