@@ -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,53 @@ 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 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
+
927
994
and transl_list expr_list = List. map transl_exp expr_list
928
995
929
996
and transl_guard guard rhs =
0 commit comments