@@ -512,6 +512,15 @@ let extract_float = function
512512
513513(* To find reasonable names for let-bound and lambda-bound idents *)
514514
515+ (* I'm a bit sad about this duplication. *)
516+ let rec name_pattern ' default = function
517+ [] -> Ident. create default
518+ | (p , _ ) :: rem ->
519+ match p.pat_desc with
520+ Tpat_var (id , _ ) -> id
521+ | Tpat_alias (p , id , _ ) -> id
522+ | _ -> name_pattern' default rem
523+
515524let rec name_pattern default = function
516525 [] -> Ident. create default
517526 | {c_lhs =p ; _} :: rem ->
@@ -572,7 +581,7 @@ let rec push_defaults loc bindings cases partial =
572581 val_attributes = [] ;
573582 Types. val_loc = Location. none;
574583 })},
575- cases, [] , partial) }
584+ cases, partial) }
576585 in
577586 push_defaults loc bindings
578587 [{c_lhs= {pat with pat_desc = Tpat_var (param, mknoloc name)};
@@ -769,8 +778,8 @@ and transl_exp0 e =
769778 let e = { e with exp_desc = Texp_apply (funct, oargs) } in
770779 event_after e (transl_apply ~should_be_tailcall ~inlined
771780 (transl_exp funct) oargs e.exp_loc)
772- | Texp_match (arg , pat_expr_list , exn_pat_expr_list , partial ) ->
773- transl_match e arg pat_expr_list exn_pat_expr_list partial
781+ | Texp_match (arg , pat_expr_list , partial ) ->
782+ transl_match e arg pat_expr_list partial
774783 | Texp_try (body , pat_expr_list ) ->
775784 let id = name_pattern " exn" pat_expr_list in
776785 Ltrywith (transl_exp body, id,
@@ -1232,11 +1241,41 @@ and transl_record env all_labels repres lbl_expr_list opt_init_expr =
12321241 end
12331242 end
12341243
1235- and transl_match e arg pat_expr_list exn_pat_expr_list partial =
1236- let id = name_pattern " exn" exn_pat_expr_list
1237- and cases = transl_cases pat_expr_list
1238- and exn_cases = transl_cases exn_pat_expr_list in
1244+ and transl_match e arg pat_expr_list partial =
1245+ let rewrite_case (val_cases , exn_cases , static_handlers as acc )
1246+ ({ c_lhs; c_guard; c_rhs } as case ) =
1247+ if c_rhs.exp_desc = Texp_unreachable then acc else
1248+ let val_pat, exn_pat = split_pattern c_lhs in
1249+ match val_pat, exn_pat with
1250+ | None , None -> assert false
1251+ | Some pv , None ->
1252+ assert (Typedtree. pat_equiv pv c_lhs);
1253+ let val_case = transl_case { case with c_lhs = pv } in
1254+ val_case :: val_cases, exn_cases, static_handlers
1255+ | None , Some pe ->
1256+ let exn_case = transl_case { case with c_lhs = pe } in
1257+ val_cases, exn_case :: exn_cases, static_handlers
1258+ | Some pv , Some pe ->
1259+ assert (c_guard = None );
1260+ let lbl = next_negative_raise_count () in
1261+ let static_raise ids =
1262+ Lstaticraise (lbl, List. map (fun id -> Lvar id) ids)
1263+ in
1264+ (* Simplif doesn't like it if binders are not uniq, so we make sure to
1265+ use different names in the value and the exception branches. *)
1266+ let ids = Typedtree. pat_bound_idents pv in
1267+ let eids = List. map Ident. rename ids in
1268+ let pe = alpha_pat (List. combine ids eids) pe in
1269+ (pv, static_raise ids) :: val_cases,
1270+ (pe, static_raise eids) :: exn_cases,
1271+ (lbl, ids, transl_exp c_rhs) :: static_handlers
1272+ in
1273+ let val_cases, exn_cases, static_handlers =
1274+ let x, y, z = List. fold_left rewrite_case ([] , [] , [] ) pat_expr_list in
1275+ List. rev x, List. rev y, List. rev z
1276+ in
12391277 let static_catch body val_ids handler =
1278+ let id = name_pattern' " exn" exn_cases in
12401279 let static_exception_id = next_negative_raise_count () in
12411280 Lstaticcatch
12421281 (Ltrywith (Lstaticraise (static_exception_id, body), id,
@@ -1246,19 +1285,31 @@ and transl_match e arg pat_expr_list exn_pat_expr_list partial =
12461285 in
12471286 match arg, exn_cases with
12481287 | {exp_desc = Texp_tuple argl } , [] ->
1249- Matching. for_multiple_match e.exp_loc (transl_list argl) cases partial
1288+ assert (static_handlers = [] );
1289+ Matching. for_multiple_match e.exp_loc (transl_list argl) val_cases partial
12501290 | {exp_desc = Texp_tuple argl } , _ :: _ ->
1251- let val_ids = List. map (fun _ -> name_pattern " val" [] ) argl in
1252- let lvars = List. map (fun id -> Lvar id) val_ids in
1253- static_catch (transl_list argl) val_ids
1254- (Matching. for_multiple_match e.exp_loc lvars cases partial)
1291+ let val_ids = List. map (fun _ -> name_pattern " val" [] ) argl in
1292+ let lvars = List. map (fun id -> Lvar id) val_ids in
1293+ let classic =
1294+ static_catch (transl_list argl) val_ids
1295+ (Matching. for_multiple_match e.exp_loc lvars val_cases partial)
1296+ in
1297+ List. fold_left (fun body (static_exception_id , val_ids , handler ) ->
1298+ Lstaticcatch (body, (static_exception_id, val_ids), handler)
1299+ ) classic static_handlers
12551300 | arg , [] ->
1256- Matching. for_function e.exp_loc None (transl_exp arg) cases partial
1257- | arg , _ :: _ ->
1258- let val_id = name_pattern " val" pat_expr_list in
1259- static_catch [transl_exp arg] [val_id]
1260- (Matching. for_function e.exp_loc None (Lvar val_id) cases partial)
1301+ assert (static_handlers = [] );
1302+ Matching. for_function e.exp_loc None (transl_exp arg) val_cases partial
12611303
1304+ | arg , _ :: _ ->
1305+ let val_id = name_pattern " val" pat_expr_list in
1306+ let classic =
1307+ static_catch [transl_exp arg] [val_id]
1308+ (Matching. for_function e.exp_loc None (Lvar val_id) val_cases partial)
1309+ in
1310+ List. fold_left (fun body (static_exception_id , val_ids , handler ) ->
1311+ Lstaticcatch (body, (static_exception_id, val_ids), handler)
1312+ ) classic static_handlers
12621313
12631314(* Wrapper for class compilation *)
12641315
0 commit comments