@@ -946,6 +946,99 @@ mod impl_overlap {
946946 }
947947}
948948
949+ mod try_expressions {
950+ use std:: fmt:: Debug ;
951+
952+ #[ derive( Debug ) ]
953+ struct S1 ;
954+
955+ #[ derive( Debug ) ]
956+ struct S2 ;
957+
958+ #[ derive( Debug ) ]
959+ enum MyResult < T , E > {
960+ MyOk ( T ) ,
961+ MyErr ( E ) ,
962+ }
963+
964+ impl < T , E > MyResult < T , E > {
965+ fn map < U , F > ( self , op : F ) -> MyResult < U , E >
966+ where
967+ F : FnOnce ( T ) -> U ,
968+ {
969+ match self {
970+ MyResult :: MyOk ( t) => MyResult :: MyOk ( op ( t) ) ,
971+ MyResult :: MyErr ( e) => MyResult :: MyErr ( e) ,
972+ }
973+ }
974+
975+ fn and_then < U , F > ( self , op : F ) -> MyResult < U , E >
976+ where
977+ F : FnOnce ( T ) -> MyResult < U , E > ,
978+ {
979+ match self {
980+ MyResult :: MyOk ( t) => op ( t) ,
981+ MyResult :: MyErr ( e) => MyResult :: MyErr ( e) ,
982+ }
983+ }
984+ }
985+
986+ // For the try operator to work, we need to implement From<E> for OtherE
987+ impl From < S1 > for S2 {
988+ fn from ( s : S1 ) -> S2 {
989+ S2
990+ }
991+ }
992+
993+ // Simple function using ? operator with same error types
994+ fn try_same_error ( ) -> MyResult < S1 , S1 > {
995+ let x = MyResult :: MyOk ( S1 ) ?; // $ type=x:S1
996+ MyResult :: MyOk ( x)
997+ }
998+
999+ // Function using ? operator with different error types that need conversion
1000+ fn try_convert_error ( ) -> MyResult < S1 , S2 > {
1001+ let x: MyResult < S1 , S1 > = MyResult :: MyOk ( S1 ) ;
1002+ let y = x?; // $ type=y:S1
1003+ MyResult :: MyOk ( y)
1004+ }
1005+
1006+ // Chained ? operations
1007+ fn try_chained ( ) -> MyResult < S1 , S2 > {
1008+ let x: MyResult < MyResult < S1 , S1 > , S1 > = MyResult :: MyOk ( MyResult :: MyOk ( S1 ) ) ;
1009+ let y = x?. map ( |s| s) ?; // First ? returns MyResult<S1, S1>, second ? returns S1
1010+ MyResult :: MyOk ( y)
1011+ }
1012+
1013+ // Function that uses ? with closures and complex error cases
1014+ fn try_complex < T : Debug > ( input : MyResult < T , S1 > ) -> MyResult < T , S2 > {
1015+ let value = input?; // $ method=From::from
1016+ let mapped = MyResult :: MyOk ( value) . and_then ( |v| {
1017+ println ! ( "{:?}" , v) ;
1018+ MyResult :: MyOk :: < _ , S1 > ( v)
1019+ } ) ?; // $ method=From::from
1020+ MyResult :: MyOk ( mapped)
1021+ }
1022+
1023+ pub fn f ( ) {
1024+ if let MyResult :: MyOk ( result) = try_same_error ( ) {
1025+ println ! ( "{:?}" , result) ;
1026+ }
1027+
1028+ if let MyResult :: MyOk ( result) = try_convert_error ( ) {
1029+ println ! ( "{:?}" , result) ;
1030+ }
1031+
1032+ if let MyResult :: MyOk ( result) = try_chained ( ) {
1033+ println ! ( "{:?}" , result) ;
1034+ }
1035+
1036+ if let MyResult :: MyOk ( result) = try_complex ( MyResult :: MyOk ( S1 ) ) {
1037+ println ! ( "{:?}" , result) ;
1038+ }
1039+ }
1040+ }
1041+
9491042fn main ( ) {
9501043 field_access:: f ( ) ;
9511044 method_impl:: f ( ) ;
@@ -963,4 +1056,5 @@ fn main() {
9631056 implicit_self_borrow:: f ( ) ;
9641057 borrowed_typed:: f ( ) ;
9651058 impl_overlap:: f ( ) ;
1059+ try_expressions:: f ( ) ;
9661060}
0 commit comments