@@ -919,6 +919,99 @@ mod borrowed_typed {
919919 }
920920}
921921
922+ mod try_expressions {
923+ use std:: fmt:: Debug ;
924+
925+ #[ derive( Debug ) ]
926+ struct S1 ;
927+
928+ #[ derive( Debug ) ]
929+ struct S2 ;
930+
931+ #[ derive( Debug ) ]
932+ enum MyResult < T , E > {
933+ MyOk ( T ) ,
934+ MyErr ( E ) ,
935+ }
936+
937+ impl < T , E > MyResult < T , E > {
938+ fn map < U , F > ( self , op : F ) -> MyResult < U , E >
939+ where
940+ F : FnOnce ( T ) -> U ,
941+ {
942+ match self {
943+ MyResult :: MyOk ( t) => MyResult :: MyOk ( op ( t) ) ,
944+ MyResult :: MyErr ( e) => MyResult :: MyErr ( e) ,
945+ }
946+ }
947+
948+ fn and_then < U , F > ( self , op : F ) -> MyResult < U , E >
949+ where
950+ F : FnOnce ( T ) -> MyResult < U , E > ,
951+ {
952+ match self {
953+ MyResult :: MyOk ( t) => op ( t) ,
954+ MyResult :: MyErr ( e) => MyResult :: MyErr ( e) ,
955+ }
956+ }
957+ }
958+
959+ // For the try operator to work, we need to implement From<E> for OtherE
960+ impl From < S1 > for S2 {
961+ fn from ( s : S1 ) -> S2 {
962+ S2
963+ }
964+ }
965+
966+ // Simple function using ? operator with same error types
967+ fn try_same_error ( ) -> MyResult < S1 , S1 > {
968+ let x = MyResult :: MyOk ( S1 ) ?; // $ type=x:S1
969+ MyResult :: MyOk ( x)
970+ }
971+
972+ // Function using ? operator with different error types that need conversion
973+ fn try_convert_error ( ) -> MyResult < S1 , S2 > {
974+ let x: MyResult < S1 , S1 > = MyResult :: MyOk ( S1 ) ;
975+ let y = x?; // $ type=y:S1
976+ MyResult :: MyOk ( y)
977+ }
978+
979+ // Chained ? operations
980+ fn try_chained ( ) -> MyResult < S1 , S2 > {
981+ let x: MyResult < MyResult < S1 , S1 > , S1 > = MyResult :: MyOk ( MyResult :: MyOk ( S1 ) ) ;
982+ let y = x?. map ( |s| s) ?; // First ? returns MyResult<S1, S1>, second ? returns S1
983+ MyResult :: MyOk ( y)
984+ }
985+
986+ // Function that uses ? with closures and complex error cases
987+ fn try_complex < T : Debug > ( input : MyResult < T , S1 > ) -> MyResult < T , S2 > {
988+ let value = input?; // $ method=From::from
989+ let mapped = MyResult :: MyOk ( value) . and_then ( |v| {
990+ println ! ( "{:?}" , v) ;
991+ MyResult :: MyOk :: < _ , S1 > ( v)
992+ } ) ?; // $ method=From::from
993+ MyResult :: MyOk ( mapped)
994+ }
995+
996+ pub fn f ( ) {
997+ if let MyResult :: MyOk ( result) = try_same_error ( ) {
998+ println ! ( "{:?}" , result) ;
999+ }
1000+
1001+ if let MyResult :: MyOk ( result) = try_convert_error ( ) {
1002+ println ! ( "{:?}" , result) ;
1003+ }
1004+
1005+ if let MyResult :: MyOk ( result) = try_chained ( ) {
1006+ println ! ( "{:?}" , result) ;
1007+ }
1008+
1009+ if let MyResult :: MyOk ( result) = try_complex ( MyResult :: MyOk ( S1 ) ) {
1010+ println ! ( "{:?}" , result) ;
1011+ }
1012+ }
1013+ }
1014+
9221015fn main ( ) {
9231016 field_access:: f ( ) ;
9241017 method_impl:: f ( ) ;
@@ -935,4 +1028,5 @@ fn main() {
9351028 trait_implicit_self_borrow:: f ( ) ;
9361029 implicit_self_borrow:: f ( ) ;
9371030 borrowed_typed:: f ( ) ;
1031+ try_expressions:: f ( ) ;
9381032}
0 commit comments