@@ -646,6 +646,16 @@ let rec cut n l =
646646
647647let try_ids = Hashtbl. create 8
648648
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+
649659let extract_directive_for_fn exp =
650660 exp.exp_attributes
651661 |> List. find_map (fun ({txt} , payload ) ->
@@ -755,10 +765,11 @@ and transl_exp0 (e : Typedtree.expression) : Lambda.lambda =
755765 (Lprim
756766 (Pccall (set_transformed_jsx d ~transformed_jsx ), argl, e.exp_loc))
757767 | _ -> 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} -> (
759769 let inlined, funct =
760770 Translattribute. get_and_remove_inlined_attribute funct
761771 in
772+ let option_call_info = stdlib_option_call_extra e in
762773 let uncurried_partial_application =
763774 (* In case of partial application foo(args, ...) when some args are missing,
764775 get the arity *)
@@ -771,8 +782,17 @@ and transl_exp0 (e : Typedtree.expression) : Lambda.lambda =
771782 | None -> None
772783 else None
773784 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)
776796 | Texp_match (arg , pat_expr_list , exn_pat_expr_list , partial ) ->
777797 transl_match e arg pat_expr_list exn_pat_expr_list partial
778798 | Texp_try (body , pat_expr_list ) ->
@@ -924,6 +944,53 @@ and transl_exp0 (e : Typedtree.expression) : Lambda.lambda =
924944 if ! Clflags. noassert then lambda_unit
925945 else Lifthenelse (transl_exp cond, lambda_unit, assert_failed e)
926946
947+ and bind_option_value opt_var opt_loc callback =
948+ let value_expr = Lprim (Pval_from_option , [opt_var], opt_loc) in
949+ match callback with
950+ | Stdlib_option_inline_lambda {param; body} ->
951+ bind Strict param value_expr (transl_exp body)
952+ | Stdlib_option_inline_ident expr ->
953+ let func = transl_exp expr in
954+ let value_id = Ident. create " __res_option_value" in
955+ let apply =
956+ Lapply
957+ {
958+ ap_func = func;
959+ ap_args = [Lvar value_id];
960+ ap_inlined = Default_inline ;
961+ ap_loc = expr.exp_loc;
962+ ap_transformed_jsx = false ;
963+ }
964+ in
965+ bind Strict value_id value_expr apply
966+
967+ and transl_stdlib_option_call exp opt_expr info oargs =
968+ match oargs with
969+ | (Nolabel , Some _ ) :: (Nolabel , Some _ ) :: _ | (Nolabel, Some _ ) :: [] ->
970+ let opt_lam = transl_exp opt_expr in
971+ let opt_id = Ident. create " __res_option_opt" in
972+ let opt_var = Lvar opt_id in
973+ let callback_result = bind_option_value opt_var exp.exp_loc info.callback in
974+ let some_branch =
975+ match info.call_kind with
976+ | Stdlib_option_forEach -> callback_result
977+ | Stdlib_option_map {result_cannot_contain_undefined} ->
978+ let tag =
979+ if result_cannot_contain_undefined then Blk_some_not_nested
980+ else Blk_some
981+ in
982+ Lprim (Pmakeblock tag, [callback_result], exp.exp_loc)
983+ | Stdlib_option_flatMap -> callback_result
984+ in
985+ let none_branch =
986+ match info.call_kind with
987+ | Stdlib_option_forEach -> lambda_unit
988+ | Stdlib_option_map _ | Stdlib_option_flatMap -> lambda_none
989+ in
990+ let cond = Lprim (Pis_not_none , [opt_var], exp.exp_loc) in
991+ bind Strict opt_id opt_lam (Lifthenelse (cond, some_branch, none_branch))
992+ | _ -> assert false
993+
927994and transl_list expr_list = List. map transl_exp expr_list
928995
929996and transl_guard guard rhs =
0 commit comments