@@ -646,6 +646,16 @@ let rec cut n l =
646646
647647let try_ids= Hashtbl. create8
648648
649+ let stdlib_option_call_extra exp =
650+ let rec aux = function
651+ | [] ->None
652+ | (Texp_stdlib_option_callinfo ,_ ,_ ) ::_ ->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} -> (
759769let inlined, funct=
760770Translattribute. get_and_remove_inlined_attribute funct
761771in
772+ let option_call_info= stdlib_option_call_extra ein
762773let 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
772783else None
773784in
774- transl_apply~inlined ~uncurried_partial_application ~transformed_jsx
775- (transl_exp funct) oargs e.exp_loc
785+ match option_call_infowith
786+ | Some info when not partial -> (
787+ match oargswith
788+ | (Nolabel, Someopt_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 =
924944if ! Clflags. noassertthen lambda_unit
925945else 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 callbackwith
950+ | Stdlib_option_inline_lambda {param; body} ->
951+ bindStrict param value_expr (transl_exp body)
952+ | Stdlib_option_inline_ident expr ->
953+ let func= transl_exp exprin
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+ bindStrict value_id value_expr apply
966+
967+ and transl_stdlib_option_call exp opt_expr info oargs =
968+ match oargswith
969+ | (Nolabel ,Some _ ) :: (Nolabel ,Some _ ) ::_ | (Nolabel, Some_ ) ::[] ->
970+ let opt_lam= transl_exp opt_exprin
971+ let opt_id= Ident. create" __res_option_opt" in
972+ let opt_var= Lvar opt_idin
973+ let callback_result= bind_option_value opt_var exp.exp_loc info.callbackin
974+ let some_branch=
975+ match info.call_kindwith
976+ | Stdlib_option_forEach -> callback_result
977+ | Stdlib_option_map {result_cannot_contain_undefined} ->
978+ let tag=
979+ if result_cannot_contain_undefinedthen 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_kindwith
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+ bindStrict 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 =