@@ -646,6 +646,16 @@ let rec cut n l =
646
646
647
647
let try_ids = Hashtbl. create 8
648
648
649
+ let stdlib_option_call_extra exp =
650
+ let rec aux = function
651
+ | [] -> None
652
+ | (Texp_stdlib_option_call info , _ , _ ) :: _ -> Some info
653
+ | _ :: rest -> aux rest
654
+ in
655
+ aux exp.exp_extra
656
+
657
+ let lambda_none = Lconst (Const_pointer (0 , Pt_shape_none ))
658
+
649
659
let extract_directive_for_fn exp =
650
660
exp.exp_attributes
651
661
|> List. find_map (fun ({txt} , payload ) ->
@@ -755,10 +765,11 @@ and transl_exp0 (e : Typedtree.expression) : Lambda.lambda =
755
765
(Lprim
756
766
(Pccall (set_transformed_jsx d ~transformed_jsx ), argl, e.exp_loc))
757
767
| _ -> wrap (Lprim (prim, argl, e.exp_loc))))
758
- | Texp_apply {funct; args = oargs ; partial; transformed_jsx} ->
768
+ | Texp_apply {funct; args = oargs ; partial; transformed_jsx} -> (
759
769
let inlined, funct =
760
770
Translattribute. get_and_remove_inlined_attribute funct
761
771
in
772
+ let option_call_info = stdlib_option_call_extra e in
762
773
let uncurried_partial_application =
763
774
(* In case of partial application foo(args, ...) when some args are missing,
764
775
get the arity *)
@@ -771,8 +782,17 @@ and transl_exp0 (e : Typedtree.expression) : Lambda.lambda =
771
782
| None -> None
772
783
else None
773
784
in
774
- transl_apply ~inlined ~uncurried_partial_application ~transformed_jsx
775
- (transl_exp funct) oargs e.exp_loc
785
+ match option_call_info with
786
+ | Some info when not partial -> (
787
+ match oargs with
788
+ | (Nolabel, Some opt_expr ) :: _ ->
789
+ transl_stdlib_option_call e opt_expr info oargs
790
+ | _ ->
791
+ transl_apply ~inlined ~uncurried_partial_application ~transformed_jsx
792
+ (transl_exp funct) oargs e.exp_loc)
793
+ | _ ->
794
+ transl_apply ~inlined ~uncurried_partial_application ~transformed_jsx
795
+ (transl_exp funct) oargs e.exp_loc)
776
796
| Texp_match (arg , pat_expr_list , exn_pat_expr_list , partial ) ->
777
797
transl_match e arg pat_expr_list exn_pat_expr_list partial
778
798
| Texp_try (body , pat_expr_list ) ->
@@ -924,6 +944,60 @@ and transl_exp0 (e : Typedtree.expression) : Lambda.lambda =
924
944
if ! Clflags. noassert then lambda_unit
925
945
else Lifthenelse (transl_exp cond, lambda_unit, assert_failed e)
926
946
947
+ and bind_option_value ~payload_not_nested opt_var opt_loc callback =
948
+ let value_expr =
949
+ if payload_not_nested then
950
+ Lprim (Pval_from_option_not_nest , [opt_var], opt_loc)
951
+ else Lprim (Pval_from_option , [opt_var], opt_loc)
952
+ in
953
+ match callback with
954
+ | Stdlib_option_inline_lambda {param; body} ->
955
+ bind Strict param value_expr (transl_exp body)
956
+ | Stdlib_option_inline_ident expr ->
957
+ let func = transl_exp expr in
958
+ let value_id = Ident. create " __res_option_value" in
959
+ let apply =
960
+ Lapply
961
+ {
962
+ ap_func = func;
963
+ ap_args = [Lvar value_id];
964
+ ap_inlined = Default_inline ;
965
+ ap_loc = expr.exp_loc;
966
+ ap_transformed_jsx = false ;
967
+ }
968
+ in
969
+ bind Strict value_id value_expr apply
970
+
971
+ and transl_stdlib_option_call exp opt_expr info oargs =
972
+ match oargs with
973
+ | (Nolabel , Some _ ) :: (Nolabel , Some _ ) :: _ | (Nolabel, Some _ ) :: [] ->
974
+ let opt_lam = transl_exp opt_expr in
975
+ let opt_id = Ident. create " __res_option_opt" in
976
+ let opt_var = Lvar opt_id in
977
+ let callback_result =
978
+ bind_option_value ~payload_not_nested: info.payload_not_nested opt_var
979
+ exp.exp_loc info.callback
980
+ in
981
+ let some_branch =
982
+ match info.call_kind with
983
+ | Stdlib_option_forEach -> callback_result
984
+ | Stdlib_option_map {result_cannot_contain_undefined} ->
985
+ let tag =
986
+ if result_cannot_contain_undefined then Blk_some_not_nested
987
+ else Blk_some
988
+ in
989
+ Lprim (Pmakeblock tag, [callback_result], exp.exp_loc)
990
+ | Stdlib_option_flatMap -> callback_result
991
+ in
992
+ let none_branch =
993
+ match info.call_kind with
994
+ | Stdlib_option_forEach -> lambda_unit
995
+ | Stdlib_option_map _ | Stdlib_option_flatMap -> lambda_none
996
+ in
997
+ let cond = Lprim (Pis_not_none , [opt_var], exp.exp_loc) in
998
+ bind Strict opt_id opt_lam (Lifthenelse (cond, some_branch, none_branch))
999
+ | _ -> assert false
1000
+
927
1001
and transl_list expr_list = List. map transl_exp expr_list
928
1002
929
1003
and transl_guard guard rhs =
0 commit comments