@@ -919,6 +919,99 @@ mod borrowed_typed {
919
919
}
920
920
}
921
921
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
+
922
1015
fn main ( ) {
923
1016
field_access:: f ( ) ;
924
1017
method_impl:: f ( ) ;
@@ -935,4 +1028,5 @@ fn main() {
935
1028
trait_implicit_self_borrow:: f ( ) ;
936
1029
implicit_self_borrow:: f ( ) ;
937
1030
borrowed_typed:: f ( ) ;
1031
+ try_expressions:: f ( ) ;
938
1032
}
0 commit comments