@@ -946,6 +946,99 @@ mod impl_overlap {
946
946
}
947
947
}
948
948
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
+
949
1042
fn main ( ) {
950
1043
field_access:: f ( ) ;
951
1044
method_impl:: f ( ) ;
@@ -963,4 +1056,5 @@ fn main() {
963
1056
implicit_self_borrow:: f ( ) ;
964
1057
borrowed_typed:: f ( ) ;
965
1058
impl_overlap:: f ( ) ;
1059
+ try_expressions:: f ( ) ;
966
1060
}
0 commit comments