Skip to content

Commit 13db309

Browse files
authored
Propagate the label names of optional parameters (#1723)
1 parent 94037eb commit 13db309

File tree

8 files changed

+56
-24
lines changed

8 files changed

+56
-24
lines changed

middle_end/backend_var.ml

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,17 @@ include Ident
1818

1919
type backend_var = t
2020

21-
let name_for_debugger t = name t
21+
let name_for_debugger t =
22+
let prefix = "*opt*" in
23+
let prefix_len = String.length prefix in
24+
let name = name t in
25+
if String.starts_with ~prefix name
26+
&& String.length name > prefix_len
27+
then (String.sub name prefix_len (String.length name - prefix_len)) ^ "_opt"
28+
else name
2229

2330
let unique_name_for_debugger t =
24-
Printf.sprintf "%s/%d" (name t) (stamp t)
31+
Printf.sprintf "%s/%d" (name_for_debugger t) (stamp t)
2532

2633
module Provenance = struct
2734
type t = {

middle_end/closure/closure.ml

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -829,8 +829,10 @@ let bind_params { backend; mutable_vars; _ } loc fdesc params args funct body =
829829
else begin
830830
let p1' = VP.rename p1 in
831831
let u1, u2, layout =
832-
match VP.name p1, a1 with
833-
| "*opt*", Uprim(P.Pmakeblock(0, Immutable, kind, mode), [a], dbg) ->
832+
let p1_name = VP.name p1 in
833+
match a1 with
834+
| Uprim(P.Pmakeblock(0, Immutable, kind, mode), [a], dbg)
835+
when String.starts_with ~prefix:"*opt*" p1_name ->
834836
(* This parameter corresponds to an optional parameter,
835837
and although it is used twice pushing the expression down
836838
actually allows us to remove the allocation as it will
@@ -1629,7 +1631,8 @@ and close_functions { backend; fenv; cenv; mutable_vars; kinds; catch_env } fun_
16291631
their wrapper functions) to be inlined *)
16301632
let n =
16311633
List.fold_left
1632-
(fun n (id, _, _) -> n + if V.name id = "*opt*" then 8 else 1)
1634+
(fun n (id, _, _) ->
1635+
n + if String.starts_with (V.name id) ~prefix:"*opt*" then 8 else 1)
16331636
0
16341637
fun_params
16351638
in

middle_end/flambda2/from_lambda/lambda_to_flambda.ml

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -794,10 +794,13 @@ let is_user_visible env id : IR.user_visible =
794794
then Not_user_visible
795795
else
796796
let name = Ident.name id in
797-
let len = String.length name in
798-
if len > 0 && Char.equal name.[0] '*'
799-
then Not_user_visible
800-
else User_visible
797+
if String.starts_with ~prefix:"*opt*" name
798+
then User_visible
799+
else
800+
let len = String.length name in
801+
if len > 0 && Char.equal name.[0] '*'
802+
then Not_user_visible
803+
else User_visible
801804

802805
let let_cont_nonrecursive_with_extra_params acc env ccenv ~is_exn_handler
803806
~params

ocaml/lambda/simplif.ml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -779,7 +779,7 @@ let split_default_wrapper ~id:fun_id ~kind ~params ~return ~body
779779
| Llet(Strict, k, id,
780780
(Lifthenelse(Lprim (Pisint _, [Lvar optparam], _), _, _, _) as def),
781781
rest) when
782-
Ident.name optparam = "*opt*" &&
782+
String.starts_with (Ident.name optparam) ~prefix:"*opt*" &&
783783
List.exists (fun p -> Ident.same p.name optparam) params
784784
&& not (List.mem_assoc optparam map)
785785
->

ocaml/middle_end/closure/closure.ml

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -829,8 +829,10 @@ let bind_params { backend; mutable_vars; _ } loc fdesc params args funct body =
829829
else begin
830830
let p1' = VP.rename p1 in
831831
let u1, u2, layout =
832-
match VP.name p1, a1 with
833-
| "*opt*", Uprim(P.Pmakeblock(0, Immutable, kind, mode), [a], dbg) ->
832+
let p1_name = VP.name p1 in
833+
match a1 with
834+
| Uprim(P.Pmakeblock(0, Immutable, kind, mode), [a], dbg)
835+
when String.starts_with ~prefix:"*opt*" p1_name ->
834836
(* This parameter corresponds to an optional parameter,
835837
and although it is used twice pushing the expression down
836838
actually allows us to remove the allocation as it will
@@ -1618,7 +1620,8 @@ and close_functions { backend; fenv; cenv; mutable_vars; kinds; catch_env } fun_
16181620
their wrapper functions) to be inlined *)
16191621
let n =
16201622
List.fold_left
1621-
(fun n (id, _, _) -> n + if V.name id = "*opt*" then 8 else 1)
1623+
(fun n (id, _, _) ->
1624+
n + if String.starts_with (V.name id) ~prefix:"*opt*" then 8 else 1)
16221625
0
16231626
fun_params
16241627
in

ocaml/ocamldoc/odoc_ast.ml

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -298,11 +298,12 @@ module Analyser =
298298

299299
in
300300
(* For optional parameters with a default value, a special treatment is required *)
301-
(* we look if the name of the parameter we just add is "*opt*", which means
301+
(* we look if the name of the parameter we just add starts with "*opt*", which means
302302
that there is a let param_name = ... in ... just right now *)
303303
let (p, next_exp) =
304304
match parameter with
305-
Simple_name { sn_name = "*opt*" } ->
305+
Simple_name { sn_name }
306+
when String.starts_with ~prefix:"*opt*" sn_name ->
306307
(
307308
(
308309
match func_body.exp_desc with
@@ -457,11 +458,12 @@ module Analyser =
457458
pattern_param
458459
in
459460
(* For optional parameters with a default value, a special treatment is required. *)
460-
(* We look if the name of the parameter we just add is "*opt*", which means
461+
(* We look if the name of the parameter we just add starts with "*opt*", which means
461462
that there is a let param_name = ... in ... just right now. *)
462463
let (current_param, next_exp) =
463464
match parameter with
464-
Simple_name { sn_name = "*opt*"} ->
465+
Simple_name { sn_name }
466+
when String.starts_with ~prefix:"*opt*" sn_name ->
465467
(
466468
(
467469
match body.exp_desc with
@@ -726,7 +728,7 @@ module Analyser =
726728
a default value. In this case, we look for the good parameter pattern *)
727729
let (parameter, next_tt_class_exp) =
728730
match pat.Typedtree.pat_desc with
729-
Typedtree.Tpat_var (ident, _, _) when Name.from_ident ident = "*opt*" ->
731+
Typedtree.Tpat_var (ident, _, _) when String.starts_with (Name.from_ident ident) ~prefix:"*opt*" ->
730732
(
731733
(* there must be a Tcl_let just after *)
732734
match tt_class_expr2.Typedtree.cl_desc with

ocaml/typing/typeclass.ml

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1175,14 +1175,21 @@ and class_expr_aux cl_num val_env met_env virt self_scope scl =
11751175
default;
11761176
]
11771177
in
1178+
let param_suffix =
1179+
match l with
1180+
| Optional name -> name
1181+
| Nolabel | Labelled _ ->
1182+
Misc.fatal_error "[default] allowed only with optional argument"
1183+
in
1184+
let param_name = "*opt*" ^ param_suffix in
11781185
let smatch =
1179-
Exp.match_ ~loc (Exp.ident ~loc (mknoloc (Longident.Lident "*opt*")))
1186+
Exp.match_ ~loc (Exp.ident ~loc (mknoloc (Longident.Lident param_name)))
11801187
scases
11811188
in
11821189
let sfun =
11831190
Cl.fun_ ~loc:scl.pcl_loc
11841191
l None
1185-
(Pat.var ~loc (mknoloc "*opt*"))
1192+
(Pat.var ~loc (mknoloc param_name))
11861193
(Cl.let_ ~loc:scl.pcl_loc Nonrecursive [Vb.mk spat smatch] sbody)
11871194
(* Note: we don't put the '#default' attribute, as it
11881195
is not detected for class-level let bindings. See #5975.*)

ocaml/typing/typecore.ml

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4367,7 +4367,12 @@ and type_expect_
43674367
exp_attributes = sexp.pexp_attributes;
43684368
exp_env = env }
43694369
| Pexp_fun (l, Some default, spat, sbody) ->
4370-
assert(is_optional l); (* default allowed only with optional argument *)
4370+
let param_suffix =
4371+
match l with
4372+
| Optional name -> name
4373+
| Nolabel | Labelled _ ->
4374+
Misc.fatal_error "[default] allowed only with optional argument"
4375+
in
43714376
let open Ast_helper in
43724377
let default_loc = default.pexp_loc in
43734378
(* Defaults are always global. They can be moved out of the function's
@@ -4396,12 +4401,13 @@ and type_expect_
43964401
loc_end = default_loc.Location.loc_end;
43974402
loc_ghost = true }
43984403
in
4404+
let param_name = "*opt*" ^ param_suffix in
43994405
let smatch =
44004406
Exp.match_ ~loc:sloc
4401-
(Exp.ident ~loc (mknoloc (Longident.Lident "*opt*")))
4407+
(Exp.ident ~loc (mknoloc (Longident.Lident param_name)))
44024408
scases
44034409
in
4404-
let pat = Pat.var ~loc:sloc (mknoloc "*opt*") in
4410+
let pat = Pat.var ~loc:sloc (mknoloc param_name) in
44054411
let body =
44064412
Exp.let_ ~loc Nonrecursive
44074413
~attrs:[Attr.mk (mknoloc "#default") (PStr [])]
@@ -7007,7 +7013,8 @@ and type_let
70077013
let is_fake_let =
70087014
match spat_sexp_list with
70097015
| [{pvb_expr={pexp_desc=Pexp_match(
7010-
{pexp_desc=Pexp_ident({ txt = Longident.Lident "*opt*"})},_)}}] ->
7016+
{pexp_desc=Pexp_ident({ txt = Longident.Lident name})},_)}}]
7017+
when String.starts_with ~prefix:"*opt*" name ->
70117018
true (* the fake let-declaration introduced by fun ?(x = e) -> ... *)
70127019
| _ ->
70137020
false

0 commit comments

Comments
 (0)