// run-pass #![feature(control_flow_enum)] #![feature(try_trait_v2)] use std::ops::{ControlFlow, FromResidual, Try}; enum MyResult { Awesome(T), Terrible(U) } enum Never {} impl Try for MyResult { type Output = U; type Residual = MyResult; fn from_output(u: U) -> MyResult { MyResult::Awesome(u) } fn branch(self) -> ControlFlow { match self { MyResult::Awesome(u) => ControlFlow::Continue(u), MyResult::Terrible(e) => ControlFlow::Break(MyResult::Terrible(e)), } } } impl FromResidual> for MyResult where V: Into { fn from_residual(x: MyResult) -> Self { match x { MyResult::Awesome(u) => match u {}, MyResult::Terrible(e) => MyResult::Terrible(e.into()), } } } type ResultResidual = Result; impl FromResidual> for MyResult where V: Into { fn from_residual(x: ResultResidual) -> Self { match x { Ok(v) => match v {} Err(e) => MyResult::Terrible(e.into()), } } } impl FromResidual> for Result where V: Into { fn from_residual(x: MyResult) -> Self { match x { MyResult::Awesome(u) => match u {}, MyResult::Terrible(e) => Err(e.into()), } } } fn f(x: i32) -> Result { if x == 0 { Ok(42) } else { let y = g(x)?; Ok(y) } } fn g(x: i32) -> MyResult { let _y = f(x - 1)?; MyResult::Terrible("Hello".to_owned()) } fn h() -> MyResult { let a: Result = Err("Hello"); let b = a?; MyResult::Awesome(b) } fn i() -> MyResult { let a: MyResult = 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(); }