Skip to content

Commit

Permalink
Remove function$ entirely.
Browse files Browse the repository at this point in the history
  • Loading branch information
cristianoc committed Dec 20, 2024
1 parent 6eae5c7 commit 49acad1
Show file tree
Hide file tree
Showing 62 changed files with 406 additions and 492 deletions.
2 changes: 1 addition & 1 deletion compiler/frontend/ast_core_type.ml
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,7 @@ let mk_fn_type (new_arg_types_ty : param_type list) (result : t) : t =
let list_of_arrow (ty : t) : t * param_type list =
let rec aux (ty : t) acc =
match ty.ptyp_desc with
| Ptyp_arrow (label, t1, t2, _) ->
| Ptyp_arrow (label, t1, t2, arity) when arity = None || acc = [] ->
aux t2
(({label; ty = t1; attr = ty.ptyp_attributes; loc = ty.ptyp_loc}
: param_type)
Expand Down
4 changes: 2 additions & 2 deletions compiler/frontend/ast_derive_js_mapper.ml
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ let app1 = Ast_compatible.app1
let app2 = Ast_compatible.app2

let ( ->~ ) a b =
Ast_uncurried.uncurried_type ~loc:Location.none ~arity:1
Ast_uncurried.uncurried_type ~arity:1
(Ast_compatible.arrow ~arity:(Some 1) a b)

let raise_when_not_found_ident =
Expand Down Expand Up @@ -295,7 +295,7 @@ let init () =
let pat_from_js = {Asttypes.loc; txt = from_js} in
let to_js_type result =
Ast_comb.single_non_rec_val pat_to_js
(Ast_uncurried.uncurried_type ~loc:Location.none ~arity:1
(Ast_uncurried.uncurried_type ~arity:1
(Ast_compatible.arrow ~arity:(Some 1) core_type result))
in
let new_type, new_tdcl =
Expand Down
10 changes: 4 additions & 6 deletions compiler/frontend/ast_derive_projector.ml
Original file line number Diff line number Diff line change
Expand Up @@ -120,9 +120,8 @@ let init () =
Ext_list.flat_map tdcls handle_tdcl);
signature_gen =
(fun (tdcls : Parsetree.type_declaration list) _explict_nonrec ->
let handle_uncurried_type_tranform ~loc ~arity t =
if arity > 0 then Ast_uncurried.uncurried_type ~loc ~arity t
else t
let handle_uncurried_type_tranform ~arity t =
if arity > 0 then Ast_uncurried.uncurried_type ~arity t else t
in
let handle_tdcl tdcl =
let core_type =
Expand All @@ -142,8 +141,7 @@ let init () =
Ast_comb.single_non_rec_val ?attrs:gentype_attrs pld_name
(Ast_compatible.arrow ~arity:None core_type pld_type
(*arity will alwys be 1 since these are single param functions*)
|> handle_uncurried_type_tranform ~arity:1
~loc:pld_name.loc))
|> handle_uncurried_type_tranform ~arity:1))
| Ptype_variant constructor_declarations ->
Ext_list.map constructor_declarations
(fun
Expand All @@ -170,7 +168,7 @@ let init () =
{loc; txt = Ext_string.uncapitalize_ascii con_name}
(Ext_list.fold_right pcd_args annotate_type (fun x acc ->
Ast_compatible.arrow ~arity:None x acc)
|> handle_uncurried_type_tranform ~arity ~loc))
|> handle_uncurried_type_tranform ~arity))
| Ptype_open | Ptype_abstract ->
Ast_derive_util.not_applicable tdcl.ptype_loc deriving_name;
[]
Expand Down
2 changes: 1 addition & 1 deletion compiler/frontend/ast_exp_handle_external.ml
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ let handle_ffi ~loc ~payload =
match !is_function with
| Some arity ->
let type_ =
Ast_uncurried.uncurried_type ~loc
Ast_uncurried.uncurried_type
~arity:(if arity = 0 then 1 else arity)
(arrow ~arity)
in
Expand Down
2 changes: 1 addition & 1 deletion compiler/frontend/ast_external_process.ml
Original file line number Diff line number Diff line change
Expand Up @@ -938,7 +938,7 @@ let handle_attributes (loc : Bs_loc.t) (type_annotation : Parsetree.core_type)
| {ptyp_desc = Ptyp_arrow (_, _, _, Some _); _} as t ->
( t,
fun ~arity (x : Parsetree.core_type) ->
Ast_uncurried.uncurried_type ~loc ~arity x )
Ast_uncurried.uncurried_type ~arity x )
| _ -> (type_annotation, fun ~arity:_ x -> x)
in
let result_type, arg_types_ty =
Expand Down
2 changes: 1 addition & 1 deletion compiler/frontend/ast_typ_uncurry.ml
Original file line number Diff line number Diff line change
Expand Up @@ -66,5 +66,5 @@ let to_uncurry_type loc (mapper : Bs_ast_mapper.mapper)
| _ -> assert false
in
match arity with
| Some arity -> Ast_uncurried.uncurried_type ~loc ~arity fn_type
| Some arity -> Ast_uncurried.uncurried_type ~arity fn_type
| None -> assert false
5 changes: 1 addition & 4 deletions compiler/ml/ast_mapper_from0.ml
Original file line number Diff line number Diff line change
Expand Up @@ -120,10 +120,7 @@ module T = struct
| _ -> assert false
in
let arity = arity_from_type t_arity in
let fun_t =
{fun_t with ptyp_desc = Ptyp_arrow (lbl, t1, t2, Some arity)}
in
{typ0 with ptyp_desc = Ptyp_constr (lid, [fun_t])}
{fun_t with ptyp_desc = Ptyp_arrow (lbl, t1, t2, Some arity)}
| _ -> typ0)
| Ptyp_object (l, o) ->
object_ ~loc ~attrs (List.map (object_field sub) l) o
Expand Down
27 changes: 14 additions & 13 deletions compiler/ml/ast_mapper_to0.ml
Original file line number Diff line number Diff line change
Expand Up @@ -98,20 +98,21 @@ module T = struct
match desc with
| Ptyp_any -> any ~loc ~attrs ()
| Ptyp_var s -> var ~loc ~attrs s
| Ptyp_arrow (lab, t1, t2, _) ->
arrow ~loc ~attrs lab (sub.typ sub t1) (sub.typ sub t2)
| Ptyp_arrow (lab, t1, t2, arity) -> (
let typ0 = arrow ~loc ~attrs lab (sub.typ sub t1) (sub.typ sub t2) in
match arity with
| None -> typ0
| Some arity ->
let arity_string = "Has_arity" ^ string_of_int arity in
let arity_type =
Ast_helper0.Typ.variant ~loc
[Rtag (Location.mknoloc arity_string, [], true, [])]
Closed None
in
Ast_helper0.Typ.constr ~loc
{txt = Lident "function$"; loc}
[typ0; arity_type])
| Ptyp_tuple tyl -> tuple ~loc ~attrs (List.map (sub.typ sub) tyl)
| Ptyp_constr
( ({txt = Lident "function$"} as lid),
[({ptyp_desc = Ptyp_arrow (_, _, _, Some arity)} as t_arg)] ) ->
let encode_arity_string arity = "Has_arity" ^ string_of_int arity in
let arity_type ~loc arity =
Ast_helper0.Typ.variant ~loc
[Rtag ({txt = encode_arity_string arity; loc}, [], true, [])]
Closed None
in
constr ~loc ~attrs (map_loc sub lid)
[sub.typ sub t_arg; arity_type ~loc:Location.none arity]
| Ptyp_constr (lid, tl) ->
constr ~loc ~attrs (map_loc sub lid) (List.map (sub.typ sub) tl)
| Ptyp_object (l, o) ->
Expand Down
31 changes: 11 additions & 20 deletions compiler/ml/ast_uncurried.ml
Original file line number Diff line number Diff line change
@@ -1,13 +1,10 @@
(* Uncurried AST *)

let uncurried_type ~loc ~arity (t_arg : Parsetree.core_type) =
let t_arg =
match t_arg.ptyp_desc with
| Ptyp_arrow (l, t1, t2, _) ->
{t_arg with ptyp_desc = Ptyp_arrow (l, t1, t2, Some arity)}
| _ -> assert false
in
Ast_helper.Typ.constr ~loc {txt = Lident "function$"; loc} [t_arg]
let uncurried_type ~arity (t_arg : Parsetree.core_type) =
match t_arg.ptyp_desc with
| Ptyp_arrow (l, t1, t2, _) ->
{t_arg with ptyp_desc = Ptyp_arrow (l, t1, t2, Some arity)}
| _ -> assert false

let uncurried_fun ~arity fun_expr =
let fun_expr =
Expand Down Expand Up @@ -44,8 +41,9 @@ let tarrow_to_arity_opt (t_arity : Types.type_expr) =
| _ -> None

let make_uncurried_type ~env ~arity (t : Types.type_expr) =
let lid : Longident.t = Lident "function$" in
let path = Env.lookup_type lid env in
(* let lid : Longident.t = Lident "function$" in
let path = Env.lookup_type lid env in *)
let _ = env in
let t =
match t.desc with
| Tarrow (l, t1, t2, c, _) ->
Expand All @@ -54,17 +52,13 @@ let make_uncurried_type ~env ~arity (t : Types.type_expr) =
| Tvar _ -> t
| _ -> assert false
in
Ctype.newconstr path [t]
t

let uncurried_type_get_arity ~env typ =
match (Ctype.expand_head env typ).desc with
| Tconstr (Pident {name = "function$"}, [t], _) -> tarrow_to_arity t
| _ -> assert false
tarrow_to_arity (Ctype.expand_head env typ)

let uncurried_type_get_arity_opt ~env typ =
match (Ctype.expand_head env typ).desc with
| Tconstr (Pident {name = "function$"}, [t], _) -> Some (tarrow_to_arity t)
| _ -> None
tarrow_to_arity_opt (Ctype.expand_head env typ)

let remove_function_dollar ?env typ =
match
Expand All @@ -73,15 +67,12 @@ let remove_function_dollar ?env typ =
| None -> Ctype.repr typ)
.desc
with
| Tconstr (Pident {name = "function$"}, [t], _) -> t
| _ -> typ

let core_type_remove_function_dollar (typ : Parsetree.core_type) =
match typ.ptyp_desc with
| Ptyp_constr ({txt = Lident "function$"}, [t]) -> t
| _ -> typ

let tcore_type_remove_function_dollar (typ : Typedtree.core_type) =
match typ.ctyp_desc with
| Ttyp_constr (Pident {name = "function$"}, _, [t]) -> t
| _ -> typ
20 changes: 1 addition & 19 deletions compiler/ml/oprint.ml
Original file line number Diff line number Diff line change
Expand Up @@ -249,7 +249,7 @@ let rec print_out_type ppf = function
| ty -> print_out_type_1 ppf ty

and print_out_type_1 ppf = function
| Otyp_arrow (lab, ty1, ty2) ->
| Otyp_arrow (lab, ty1, ty2, _) ->
pp_open_box ppf 0;
if lab <> "" then (
pp_print_string ppf lab;
Expand All @@ -271,24 +271,6 @@ and print_simple_out_type ppf = function
fprintf ppf "@[%a%s#%a@]" print_typargs tyl
(if ng then "_" else "")
print_ident id
| Otyp_constr (Oide_dot (Oide_dot (Oide_ident "Js", "Fn"), name), [tyl]) ->
let res =
if name = "arity0" then
Otyp_arrow ("", Otyp_constr (Oide_ident "unit", []), tyl)
else tyl
in
fprintf ppf "@[<0>(%a@ [@bs])@]" print_out_type_1 res
| Otyp_constr (Oide_dot (Oide_dot (Oide_ident "Js_OO", "Meth"), name), [tyl])
->
let res =
if name = "arity0" then
Otyp_arrow ("", Otyp_constr (Oide_ident "unit", []), tyl)
else tyl
in
fprintf ppf "@[<0>(%a@ [@meth])@]" print_out_type_1 res
| Otyp_constr (Oide_dot (Oide_dot (Oide_ident "Js_OO", "Callback"), _), [tyl])
->
fprintf ppf "@[<0>(%a@ [@this])@]" print_out_type_1 tyl
| Otyp_constr (id, tyl) ->
pp_open_box ppf 0;
print_typargs ppf tyl;
Expand Down
2 changes: 1 addition & 1 deletion compiler/ml/outcometree.ml
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ type out_type =
| Otyp_abstract
| Otyp_open
| Otyp_alias of out_type * string
| Otyp_arrow of string * out_type * out_type
| Otyp_arrow of string * out_type * out_type * Asttypes.arity
| Otyp_class of bool * out_ident * out_type list
| Otyp_constr of out_ident * out_type list
| Otyp_manifest of out_type * out_type
Expand Down
3 changes: 1 addition & 2 deletions compiler/ml/parsetree.ml
Original file line number Diff line number Diff line change
Expand Up @@ -224,8 +224,7 @@ and expression_desc =
(* let P1 = E1 and ... and Pn = EN in E (flag = Nonrecursive)
let rec P1 = E1 and ... and Pn = EN in E (flag = Recursive)
*)
| Pexp_fun of
arg_label * expression option * pattern * expression * int option
| Pexp_fun of arg_label * expression option * pattern * expression * arity
(* fun P -> E1 (Simple, None)
fun ~l:P -> E1 (Labelled l, None)
fun ?l:P -> E1 (Optional l, None)
Expand Down
5 changes: 3 additions & 2 deletions compiler/ml/printtyp.ml
Original file line number Diff line number Diff line change
Expand Up @@ -587,7 +587,7 @@ let rec tree_of_typexp sch ty =
let non_gen = is_non_gen sch ty in
let name_gen = if non_gen then new_weak_name ty else new_name in
Otyp_var (non_gen, name_of_type name_gen ty)
| Tarrow (l, ty1, ty2, _, _) ->
| Tarrow (l, ty1, ty2, _, arity) ->
let pr_arrow l ty1 ty2 =
let lab = string_of_label l in
let t1 =
Expand All @@ -599,7 +599,8 @@ let rec tree_of_typexp sch ty =
| _ -> Otyp_stuff "<hidden>"
else tree_of_typexp sch ty1
in
Otyp_arrow (lab, t1, tree_of_typexp sch ty2)
(* should pass arity here? *)
Otyp_arrow (lab, t1, tree_of_typexp sch ty2, arity)
in
pr_arrow l ty1 ty2
| Ttuple tyl -> Otyp_tuple (tree_of_typlist sch tyl)
Expand Down
51 changes: 3 additions & 48 deletions compiler/ml/typecore.ml
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,6 @@ type error =
| Literal_overflow of string
| Unknown_literal of string * char
| Illegal_letrec_pat
| Labels_omitted of string list
| Empty_record_literal
| Uncurried_arity_mismatch of type_expr * int * int
| Field_not_optional of string * type_expr
Expand Down Expand Up @@ -1945,7 +1944,7 @@ let rec list_labels_aux env visited ls ty_fun =
if List.memq ty visited then (List.rev ls, false)
else
match ty.desc with
| Tarrow (l, _, ty_res, _, _) ->
| Tarrow (l, _, ty_res, _, arity) when arity = None || visited = [] ->
list_labels_aux env (ty :: visited) (l :: ls) ty_res
| _ -> (List.rev ls, is_Tvar ty)
Expand Down Expand Up @@ -3539,7 +3538,7 @@ and type_application ?type_clash_context total_app env funct (sargs : sargs) :
in
unify_exp env funct uncurried_typ
else if
Ast_uncurried.tarrow_to_arity_opt
Ast_uncurried.uncurried_type_get_arity_opt ~env
(Ast_uncurried.remove_function_dollar ~env funct.exp_type)
= None
then
Expand Down Expand Up @@ -3700,23 +3699,6 @@ and type_application ?type_clash_context total_app env funct (sargs : sargs) :
type_unknown_args max_arity ~args ~top_arity omitted ty_fun0
sargs (* This is the hot path for non-labeled function*)
in
let () =
let ls, tvar = list_labels env funct.exp_type in
if not tvar then
let labels = Ext_list.filter ls (fun l -> not (is_optional l)) in
if
Ext_list.same_length labels sargs
&& List.for_all (fun (l, _) -> l = Nolabel) sargs
&& List.exists (fun l -> l <> Nolabel) labels
then
raise
(Error
( funct.exp_loc,
env,
Labels_omitted
(List.map Printtyp.string_of_label
(Ext_list.filter labels (fun x -> x <> Nolabel))) ))
in
if total_app then force_uncurried_type funct;
let ty, max_arity = extract_uncurried_type funct in
let top_arity = if total_app then Some max_arity else None in
Expand All @@ -3728,7 +3710,7 @@ and type_application ?type_clash_context total_app env funct (sargs : sargs) :
in
let exp = type_expect env sarg ty_arg in
(match (expand_head env exp.exp_type).desc with
| Tarrow _ ->
| Tarrow _ when not total_app ->
Location.prerr_warning exp.exp_loc Warnings.Partial_application
| Tvar _ ->
Delayed_checks.add_delayed_check (fun () ->
Expand Down Expand Up @@ -4345,23 +4327,6 @@ let report_error env ppf error =
let arity_a = arity_a |> string_of_int in
let arity_b = arity_b |> string_of_int in
report_arity_mismatch ~arity_a ~arity_b ppf
| Expr_type_clash
( ( _,
{
desc =
Tconstr
(Pdot (Pdot (Pident {name = "Js_OO"}, "Meth", _), a, _), _, _);
} )
:: ( _,
{
desc =
Tconstr
(Pdot (Pdot (Pident {name = "Js_OO"}, "Meth", _), b, _), _, _);
} )
:: _,
_ )
when a <> b ->
fprintf ppf "This method has %s but was expected %s" a b
| Expr_type_clash (trace, type_clash_context) ->
(* modified *)
fprintf ppf "@[<v>";
Expand Down Expand Up @@ -4544,16 +4509,6 @@ let report_error env ppf error =
fprintf ppf "Unknown modifier '%c' for literal %s%c" m n m
| Illegal_letrec_pat ->
fprintf ppf "Only variables are allowed as left-hand side of `let rec'"
| Labels_omitted [label] ->
fprintf ppf
"Label ~%s was omitted in the application of this labeled function." label
| Labels_omitted labels ->
let labels_string =
labels |> List.map (fun label -> "~" ^ label) |> String.concat ", "
in
fprintf ppf
"Labels %s were omitted in the application of this labeled function."
labels_string
| Empty_record_literal ->
fprintf ppf
"Empty record literal {} should be type annotated or used in a record \
Expand Down
1 change: 0 additions & 1 deletion compiler/ml/typecore.mli
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,6 @@ type error =
| Literal_overflow of string
| Unknown_literal of string * char
| Illegal_letrec_pat
| Labels_omitted of string list
| Empty_record_literal
| Uncurried_arity_mismatch of type_expr * int * int
| Field_not_optional of string * type_expr
Expand Down
2 changes: 1 addition & 1 deletion compiler/ml/typedtree.ml
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ and expression_desc =
| Texp_let of rec_flag * value_binding list * expression
| Texp_function of {
arg_label: arg_label;
arity: int option;
arity: arity;
param: Ident.t;
case: case;
partial: partial;
Expand Down
2 changes: 1 addition & 1 deletion compiler/ml/typedtree.mli
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ and expression_desc =
*)
| Texp_function of {
arg_label: arg_label;
arity: int option;
arity: arity;
param: Ident.t;
case: case;
partial: partial;
Expand Down
Loading

0 comments on commit 49acad1

Please sign in to comment.