From 5a58d47dee79bdbed46b895828a989af8a09b25a Mon Sep 17 00:00:00 2001 From: Chris Casinghino Date: Thu, 15 Jun 2023 13:43:30 -0400 Subject: [PATCH 1/6] Communicate frontend layouts to lambda (#1455) --- backend/cmm_helpers.ml | 3 +- backend/cmmgen.ml | 14 +- middle_end/convert_primitives.ml | 4 +- middle_end/flambda/flambda_to_clambda.ml | 4 +- .../from_lambda/closure_conversion.ml | 9 +- .../flambda2/from_lambda/dissect_letrec.ml | 4 +- .../flambda2/from_lambda/lambda_to_flambda.ml | 4 +- ocaml/.depend | 23 +- ocaml/asmcomp/cmm_helpers.ml | 2 +- ocaml/asmcomp/cmmgen.ml | 14 +- ocaml/bytecomp/bytegen.ml | 2 +- ocaml/compilerlibs/Makefile.compilerlibs | 2 +- ocaml/dune | 4 +- ocaml/lambda/lambda.ml | 18 +- ocaml/lambda/lambda.mli | 4 +- ocaml/lambda/matching.ml | 287 +++++---- ocaml/lambda/matching.mli | 19 +- ocaml/lambda/transl_array_comprehension.ml | 14 +- ocaml/lambda/transl_array_comprehension.mli | 2 +- ocaml/lambda/transl_comprehension_utils.ml | 4 +- ocaml/lambda/transl_list_comprehension.ml | 21 +- ocaml/lambda/transl_list_comprehension.mli | 2 +- ocaml/lambda/translclass.ml | 56 +- ocaml/lambda/translcore.ml | 579 +++++++++--------- ocaml/lambda/translcore.mli | 13 +- ocaml/lambda/translmod.ml | 36 +- ocaml/lambda/translobj.ml | 3 +- ocaml/lambda/translprim.ml | 75 ++- ocaml/middle_end/convert_primitives.ml | 4 +- .../middle_end/flambda/flambda_to_clambda.ml | 4 +- ocaml/ocamldoc/odoc_ast.ml | 6 +- ocaml/otherlibs/dynlink/Makefile | 2 +- ocaml/otherlibs/dynlink/dune | 6 +- .../testsuite/tests/typing-layouts/basics.ml | 7 + .../tests/typing-layouts/basics_alpha.ml | 71 +-- .../tests/typing-layouts/basics_beta.ml | 7 + .../tests/typing-layouts/modules_alpha.ml | 3 +- ocaml/typing/ctype.ml | 63 +- ocaml/typing/ctype.mli | 20 +- ocaml/typing/includecore.ml | 4 +- ocaml/typing/layouts.ml | 44 ++ ocaml/typing/layouts.mli | 42 ++ ocaml/typing/primitive.ml | 31 +- ocaml/typing/primitive.mli | 16 +- ocaml/typing/printtyped.ml | 6 +- ocaml/typing/rec_check.ml | 6 +- ocaml/typing/tast_iterator.ml | 6 +- ocaml/typing/tast_mapper.ml | 23 +- ocaml/typing/typeclass.ml | 17 +- ocaml/typing/typecore.ml | 139 +++-- ocaml/typing/typedecl.ml | 34 +- ocaml/typing/typedecl.mli | 2 +- ocaml/typing/typedtree.ml | 16 +- ocaml/typing/typedtree.mli | 24 +- ocaml/typing/typeopt.ml | 46 +- ocaml/typing/typeopt.mli | 32 +- ocaml/typing/untypeast.ml | 4 +- 57 files changed, 1161 insertions(+), 746 deletions(-) diff --git a/backend/cmm_helpers.ml b/backend/cmm_helpers.ml index 5c5f741e8f5..a69028ddefb 100644 --- a/backend/cmm_helpers.ml +++ b/backend/cmm_helpers.ml @@ -1930,7 +1930,8 @@ let box_sized size mode dbg exp = (* Simplification of some primitives into C calls *) -let default_prim name = Primitive.simple ~name ~arity:0 (*ignored*) ~alloc:true +let default_prim name = + Primitive.simple_on_values ~name ~arity:0 (*ignored*) ~alloc:true let int64_native_prim name arity ~alloc = let u64 = Primitive.(Prim_global, Unboxed_integer Pint64) in diff --git a/backend/cmmgen.ml b/backend/cmmgen.ml index d6332849395..b7851224d48 100644 --- a/backend/cmmgen.ml +++ b/backend/cmmgen.ml @@ -612,7 +612,7 @@ let rec transl env e = transl_make_array dbg env kind alloc_heap args | (Pduparray _, [arg]) -> let prim_obj_dup = - Primitive.simple ~name:"caml_obj_dup" ~arity:1 ~alloc:true + Primitive.simple_on_values ~name:"caml_obj_dup" ~arity:1 ~alloc:true in transl_ccall env prim_obj_dup [arg] dbg | (Pmakearray _, []) -> @@ -895,9 +895,13 @@ and transl_make_array dbg env kind mode args = and transl_ccall env prim args dbg = let transl_arg native_repr arg = + (* CR layouts v2: This match to be extended with + | Same_as_ocaml_repr Float64 -> (XFloat, transl env arg) + in the PR that adds Float64 *) match native_repr with - | Same_as_ocaml_repr -> + | Same_as_ocaml_repr Value -> (XInt, transl env arg) + | Same_as_ocaml_repr Void -> assert false | Unboxed_float -> (XFloat, transl_unbox_float dbg env arg) | Unboxed_integer bi -> @@ -924,8 +928,12 @@ and transl_ccall env prim args dbg = (ty1 :: tys, arg' :: args') in let typ_res, wrap_result = + (* CR layouts v2: This match to be extended with + | Same_as_ocaml_repr Float64 -> (typ_float, fun x -> x) + in the PR that adds Float64 *) match prim.prim_native_repr_res with - | _, Same_as_ocaml_repr -> (typ_val, fun x -> x) + | _, Same_as_ocaml_repr Value -> (typ_val, fun x -> x) + | _, Same_as_ocaml_repr Void -> assert false (* TODO: Allow Alloc_local on suitably typed C stubs *) | _, Unboxed_float -> (typ_float, box_float dbg alloc_heap) | _, Unboxed_integer Pint64 when size_int = 4 -> diff --git a/middle_end/convert_primitives.ml b/middle_end/convert_primitives.ml index 7cc2e8a324c..43fab009bb4 100644 --- a/middle_end/convert_primitives.ml +++ b/middle_end/convert_primitives.ml @@ -152,8 +152,8 @@ let convert (prim : Lambda.primitive) : Clambda_primitives.primitive = ~effects:Only_generative_effects ~coeffects:Has_coeffects ~native_name:"caml_obj_dup" - ~native_repr_args:[P.Prim_global, P.Same_as_ocaml_repr] - ~native_repr_res:(P.Prim_global, P.Same_as_ocaml_repr)) + ~native_repr_args:[P.Prim_global, P.Same_as_ocaml_repr Layouts.Sort.Value] + ~native_repr_res:(P.Prim_global, P.Same_as_ocaml_repr Layouts.Sort.Value)) | Punbox_float -> Punbox_float | Pbox_float m -> Pbox_float m | Punbox_int bi -> Punbox_int bi diff --git a/middle_end/flambda/flambda_to_clambda.ml b/middle_end/flambda/flambda_to_clambda.ml index 7e25f986854..a2d6c2a23f2 100644 --- a/middle_end/flambda/flambda_to_clambda.ml +++ b/middle_end/flambda/flambda_to_clambda.ml @@ -79,7 +79,7 @@ let check_closure t ulam named : Clambda.ulambda = if not !Clflags.clambda_checks then ulam else let desc = - Primitive.simple ~name:"caml_check_value_is_closure" + Primitive.simple_on_values ~name:"caml_check_value_is_closure" ~arity:2 ~alloc:false in let str = Format.asprintf "%a" Flambda.print_named named in @@ -109,7 +109,7 @@ let check_field t ulam pos named_opt : Clambda.ulambda = if not !Clflags.clambda_checks then ulam else let desc = - Primitive.simple ~name:"caml_check_field_access" + Primitive.simple_on_values ~name:"caml_check_field_access" ~arity:3 ~alloc:false in let str = diff --git a/middle_end/flambda2/from_lambda/closure_conversion.ml b/middle_end/flambda2/from_lambda/closure_conversion.ml index 05406b95229..728991b2ca3 100644 --- a/middle_end/flambda2/from_lambda/closure_conversion.ml +++ b/middle_end/flambda2/from_lambda/closure_conversion.ml @@ -439,7 +439,7 @@ let close_c_call acc env ~loc ~let_bound_ids_with_kinds in let box_return_value = match prim_native_repr_res with - | _, Same_as_ocaml_repr -> None + | _, Same_as_ocaml_repr _ -> None | _, Unboxed_float -> Some (P.Box_number (Naked_float, Alloc_mode.For_allocations.heap)) | _, Unboxed_integer Pnativeint -> @@ -463,8 +463,11 @@ let close_c_call acc env ~loc ~let_bound_ids_with_kinds in let kind_of_primitive_native_repr ((_, repr) : Primitive.mode * Primitive.native_repr) = + (* CR layouts v2: This match will be extended with [| Same_as_ocaml_repr + Float64 -> K.naked_float] in the PR that adds Float64. *) match repr with - | Same_as_ocaml_repr -> K.value + | Same_as_ocaml_repr Value -> K.value + | Same_as_ocaml_repr Void -> assert false | Unboxed_float -> K.naked_float | Unboxed_integer Pnativeint -> K.naked_nativeint | Unboxed_integer Pint32 -> K.naked_int32 @@ -549,7 +552,7 @@ let close_c_call acc env ~loc ~let_bound_ids_with_kinds (arg_repr : Primitive.mode * Primitive.native_repr) -> let unbox_arg : P.unary_primitive option = match arg_repr with - | _, Same_as_ocaml_repr -> None + | _, Same_as_ocaml_repr _ -> None | _, Unboxed_float -> Some (P.Unbox_number Naked_float) | _, Unboxed_integer Pnativeint -> Some (P.Unbox_number Naked_nativeint) diff --git a/middle_end/flambda2/from_lambda/dissect_letrec.ml b/middle_end/flambda2/from_lambda/dissect_letrec.ml index 3f20f0e020d..551ac2e30f6 100644 --- a/middle_end/flambda2/from_lambda/dissect_letrec.ml +++ b/middle_end/flambda2/from_lambda/dissect_letrec.ml @@ -172,7 +172,7 @@ let lsequence (lam1, lam2) = [@@ocaml.warning "-fragile-match"] let caml_update_dummy_prim = - Primitive.simple ~name:"caml_update_dummy" ~arity:2 ~alloc:true + Primitive.simple_on_values ~name:"caml_update_dummy" ~arity:2 ~alloc:true let update_dummy var expr = Lprim (Pccall caml_update_dummy_prim, [Lvar var; expr], Loc_unknown) @@ -570,7 +570,7 @@ let dissect_letrec ~bindings ~body ~free_vars_kind = | Normal _tag -> "caml_alloc_dummy" | Boxed_float -> "caml_alloc_dummy_float" in - let desc = Primitive.simple ~name:fn ~arity:1 ~alloc:true in + let desc = Primitive.simple_on_values ~name:fn ~arity:1 ~alloc:true in let size : lambda = Lconst (Const_base (Const_int size)) in id, Lprim (Pccall desc, [size], Loc_unknown)) letrec.blocks diff --git a/middle_end/flambda2/from_lambda/lambda_to_flambda.ml b/middle_end/flambda2/from_lambda/lambda_to_flambda.ml index 081b2c5292b..b495613bb54 100644 --- a/middle_end/flambda2/from_lambda/lambda_to_flambda.ml +++ b/middle_end/flambda2/from_lambda/lambda_to_flambda.ml @@ -678,7 +678,7 @@ let transform_primitive env (prim : L.primitive) args loc = then let arity = 1 + num_dimensions in let name = "caml_ba_get_" ^ string_of_int num_dimensions in - let desc = Primitive.simple ~name ~arity ~alloc:true in + let desc = Primitive.simple_on_values ~name ~arity ~alloc:true in Primitive (L.Pccall desc, args, loc) else Misc.fatal_errorf @@ -695,7 +695,7 @@ let transform_primitive env (prim : L.primitive) args loc = then let arity = 2 + num_dimensions in let name = "caml_ba_set_" ^ string_of_int num_dimensions in - let desc = Primitive.simple ~name ~arity ~alloc:true in + let desc = Primitive.simple_on_values ~name ~arity ~alloc:true in Primitive (L.Pccall desc, args, loc) else Misc.fatal_errorf diff --git a/ocaml/.depend b/ocaml/.depend index 109dfb1b98b..62a55875f4f 100644 --- a/ocaml/.depend +++ b/ocaml/.depend @@ -434,7 +434,6 @@ parsing/jane_syntax.cmo : \ parsing/parsetree.cmi \ parsing/longident.cmi \ parsing/location.cmi \ - utils/language_extension.cmi \ parsing/jane_syntax_parsing.cmi \ parsing/asttypes.cmi \ parsing/ast_helper.cmi \ @@ -443,7 +442,6 @@ parsing/jane_syntax.cmx : \ parsing/parsetree.cmi \ parsing/longident.cmx \ parsing/location.cmx \ - utils/language_extension.cmx \ parsing/jane_syntax_parsing.cmx \ parsing/asttypes.cmi \ parsing/ast_helper.cmx \ @@ -1236,6 +1234,7 @@ typing/primitive.cmo : \ typing/outcometree.cmi \ utils/misc.cmi \ parsing/location.cmi \ + typing/layouts.cmi \ parsing/attr_helper.cmi \ typing/primitive.cmi typing/primitive.cmx : \ @@ -1243,12 +1242,14 @@ typing/primitive.cmx : \ typing/outcometree.cmi \ utils/misc.cmx \ parsing/location.cmx \ + typing/layouts.cmx \ parsing/attr_helper.cmx \ typing/primitive.cmi typing/primitive.cmi : \ parsing/parsetree.cmi \ typing/outcometree.cmi \ - parsing/location.cmi + parsing/location.cmi \ + typing/layouts.cmi typing/printpat.cmo : \ typing/types.cmi \ typing/typedtree.cmi \ @@ -1980,6 +1981,7 @@ typing/typeopt.cmi : \ typing/typedtree.cmi \ typing/path.cmi \ parsing/location.cmi \ + typing/layouts.cmi \ lambda/lambda.cmi \ typing/env.cmi typing/types.cmo : \ @@ -3710,6 +3712,7 @@ lambda/lambda.cmo : \ utils/misc.cmi \ parsing/longident.cmi \ parsing/location.cmi \ + typing/layouts.cmi \ typing/ident.cmi \ typing/env.cmi \ lambda/debuginfo.cmi \ @@ -3725,6 +3728,7 @@ lambda/lambda.cmx : \ utils/misc.cmx \ parsing/longident.cmx \ parsing/location.cmx \ + typing/layouts.cmx \ typing/ident.cmx \ typing/env.cmx \ lambda/debuginfo.cmx \ @@ -3739,6 +3743,7 @@ lambda/lambda.cmi : \ typing/primitive.cmi \ typing/path.cmi \ parsing/location.cmi \ + typing/layouts.cmi \ typing/ident.cmi \ typing/env.cmi \ lambda/debuginfo.cmi \ @@ -3793,6 +3798,7 @@ lambda/matching.cmx : \ lambda/matching.cmi : \ typing/typedtree.cmi \ parsing/location.cmi \ + typing/layouts.cmi \ lambda/lambda.cmi \ typing/ident.cmi \ lambda/debuginfo.cmi @@ -3881,6 +3887,7 @@ lambda/transl_array_comprehension.cmo : \ typing/predef.cmi \ utils/misc.cmi \ lambda/matching.cmi \ + typing/layouts.cmi \ lambda/lambda.cmi \ typing/ident.cmi \ typing/env.cmi \ @@ -3894,6 +3901,7 @@ lambda/transl_array_comprehension.cmx : \ typing/predef.cmx \ utils/misc.cmx \ lambda/matching.cmx \ + typing/layouts.cmx \ lambda/lambda.cmx \ typing/ident.cmx \ typing/env.cmx \ @@ -3902,6 +3910,7 @@ lambda/transl_array_comprehension.cmx : \ lambda/transl_array_comprehension.cmi lambda/transl_array_comprehension.cmi : \ typing/typedtree.cmi \ + typing/layouts.cmi \ lambda/lambda.cmi \ lambda/debuginfo.cmi lambda/transl_comprehension_utils.cmo : \ @@ -3923,6 +3932,7 @@ lambda/transl_list_comprehension.cmo : \ typing/typedtree.cmi \ lambda/transl_comprehension_utils.cmi \ lambda/matching.cmi \ + typing/layouts.cmi \ lambda/lambda.cmi \ typing/ident.cmi \ parsing/asttypes.cmi \ @@ -3932,12 +3942,14 @@ lambda/transl_list_comprehension.cmx : \ typing/typedtree.cmx \ lambda/transl_comprehension_utils.cmx \ lambda/matching.cmx \ + typing/layouts.cmx \ lambda/lambda.cmx \ typing/ident.cmx \ parsing/asttypes.cmi \ lambda/transl_list_comprehension.cmi lambda/transl_list_comprehension.cmi : \ typing/typedtree.cmi \ + typing/layouts.cmi \ lambda/lambda.cmi \ lambda/debuginfo.cmi lambda/translattribute.cmo : \ @@ -3980,6 +3992,7 @@ lambda/translclass.cmo : \ typing/path.cmi \ lambda/matching.cmi \ parsing/location.cmi \ + typing/layouts.cmi \ lambda/lambda.cmi \ typing/ident.cmi \ typing/env.cmi \ @@ -3997,6 +4010,7 @@ lambda/translclass.cmx : \ typing/path.cmx \ lambda/matching.cmx \ parsing/location.cmx \ + typing/layouts.cmx \ lambda/lambda.cmx \ typing/ident.cmx \ typing/env.cmx \ @@ -4083,6 +4097,7 @@ lambda/translcore.cmx : \ parsing/asttypes.cmi \ lambda/translcore.cmi lambda/translcore.cmi : \ + typing/types.cmi \ typing/typedtree.cmi \ parsing/longident.cmi \ parsing/location.cmi \ @@ -4204,6 +4219,7 @@ lambda/translprim.cmo : \ utils/misc.cmi \ lambda/matching.cmi \ parsing/location.cmi \ + typing/layouts.cmi \ lambda/lambda.cmi \ typing/ident.cmi \ typing/env.cmi \ @@ -4224,6 +4240,7 @@ lambda/translprim.cmx : \ utils/misc.cmx \ lambda/matching.cmx \ parsing/location.cmx \ + typing/layouts.cmx \ lambda/lambda.cmx \ typing/ident.cmx \ typing/env.cmx \ diff --git a/ocaml/asmcomp/cmm_helpers.ml b/ocaml/asmcomp/cmm_helpers.ml index 87398c9785b..5f6edb8e368 100644 --- a/ocaml/asmcomp/cmm_helpers.ml +++ b/ocaml/asmcomp/cmm_helpers.ml @@ -1579,7 +1579,7 @@ let box_sized size mode dbg exp = (* Simplification of some primitives into C calls *) let default_prim name = - Primitive.simple ~name ~arity:0(*ignored*) ~alloc:true + Primitive.simple_on_values ~name ~arity:0(*ignored*) ~alloc:true let int64_native_prim name arity ~alloc = diff --git a/ocaml/asmcomp/cmmgen.ml b/ocaml/asmcomp/cmmgen.ml index 616d86a5152..cb576e08247 100644 --- a/ocaml/asmcomp/cmmgen.ml +++ b/ocaml/asmcomp/cmmgen.ml @@ -541,7 +541,7 @@ let rec transl env e = transl_make_array dbg env kind alloc_heap args | (Pduparray _, [arg]) -> let prim_obj_dup = - Primitive.simple ~name:"caml_obj_dup" ~arity:1 ~alloc:true + Primitive.simple_on_values ~name:"caml_obj_dup" ~arity:1 ~alloc:true in transl_ccall env prim_obj_dup [arg] dbg | (Pmakearray _, []) -> @@ -826,9 +826,13 @@ and transl_make_array dbg env kind mode args = and transl_ccall env prim args dbg = let transl_arg native_repr arg = + (* CR layouts v2: This match to be extended with + | Same_as_ocaml_repr Float64 -> (XFloat, transl env arg) + in the PR that adds Float64 *) match native_repr with - | Same_as_ocaml_repr -> + | Same_as_ocaml_repr Value -> (XInt, transl env arg) + | Same_as_ocaml_repr Void -> assert false | Unboxed_float -> (XFloat, transl_unbox_float dbg env arg) | Unboxed_integer bi -> @@ -856,7 +860,11 @@ and transl_ccall env prim args dbg = in let typ_res, wrap_result = match prim.prim_native_repr_res with - | _, Same_as_ocaml_repr -> (typ_val, fun x -> x) + (* CR layouts v2: This match to be extended with + | Same_as_ocaml_repr Float64 -> (typ_float, fun x -> x) + in the PR that adds Float64 *) + | _, Same_as_ocaml_repr Value -> (typ_val, fun x -> x) + | _, Same_as_ocaml_repr Void -> assert false (* TODO: Allow Alloc_local on suitably typed C stubs *) | _, Unboxed_float -> (typ_float, box_float dbg alloc_heap) | _, Unboxed_integer Pint64 when size_int = 4 -> diff --git a/ocaml/bytecomp/bytegen.ml b/ocaml/bytecomp/bytegen.ml index c3130582a5f..f3db45b26a3 100644 --- a/ocaml/bytecomp/bytegen.ml +++ b/ocaml/bytecomp/bytegen.ml @@ -797,7 +797,7 @@ let rec comp_expr env exp sz cont = comp_expr env (Lprim (Pmakearray (kind, mutability, m), args, loc)) sz cont | Lprim (Pduparray _, [arg], loc) -> let prim_obj_dup = - Primitive.simple ~name:"caml_obj_dup" ~arity:1 ~alloc:true + Primitive.simple_on_values ~name:"caml_obj_dup" ~arity:1 ~alloc:true in comp_expr env (Lprim (Pccall prim_obj_dup, [arg], loc)) sz cont | Lprim (Pduparray _, _, _) -> diff --git a/ocaml/compilerlibs/Makefile.compilerlibs b/ocaml/compilerlibs/Makefile.compilerlibs index cfe1310e253..2f33acedcce 100644 --- a/ocaml/compilerlibs/Makefile.compilerlibs +++ b/ocaml/compilerlibs/Makefile.compilerlibs @@ -80,9 +80,9 @@ PARSING_CMI = \ TYPING = \ typing/path.cmo \ + typing/layouts.cmo \ typing/primitive.cmo \ typing/shape.cmo \ - typing/layouts.cmo \ typing/types.cmo \ typing/btype.cmo \ typing/oprint.cmo \ diff --git a/ocaml/dune b/ocaml/dune index 2bc207bf353..0d412522832 100644 --- a/ocaml/dune +++ b/ocaml/dune @@ -68,7 +68,7 @@ asttypes parsetree ;; TYPING - ident path primitive shape layouts types btype oprint subst predef datarepr + ident path layouts primitive shape types btype oprint subst predef datarepr cmi_format persistent_env env errortrace typedtree printtyped ctype printtyp includeclass mtype envaux includecore tast_iterator tast_mapper signature_group cmt_format cms_format untypeast @@ -263,8 +263,8 @@ (parsetree.mli as compiler-libs/parsetree.mli) (ident.mli as compiler-libs/ident.mli) (path.mli as compiler-libs/path.mli) - (primitive.mli as compiler-libs/primitive.mli) (layouts.mli as compiler-libs/layouts.mli) + (primitive.mli as compiler-libs/primitive.mli) (types.mli as compiler-libs/types.mli) (btype.mli as compiler-libs/btype.mli) (binutils.mli as compiler-libs/binutils.mli) diff --git a/ocaml/lambda/lambda.ml b/ocaml/lambda/lambda.ml index 7f3bca59f4a..48f210df8a7 100644 --- a/ocaml/lambda/lambda.ml +++ b/ocaml/lambda/lambda.ml @@ -637,13 +637,14 @@ let layout_class = Pvalue Pgenval let layout_module = Pvalue Pgenval let layout_module_field = Pvalue Pgenval let layout_functor = Pvalue Pgenval -let layout_float = Pvalue Pfloatval +let layout_boxed_float = Pvalue Pfloatval let layout_string = Pvalue Pgenval let layout_boxedint bi = Pvalue (Pboxedintval bi) let layout_lazy = Pvalue Pgenval let layout_lazy_contents = Pvalue Pgenval let layout_any_value = Pvalue Pgenval let layout_letrec = layout_any_value +let layout_probe_arg = Pvalue Pgenval (* CR ncourant: use [Ptop] or remove this as soon as possible. *) let layout_top = layout_any_value @@ -1438,12 +1439,15 @@ let primitive_result_layout (p : primitive) = | Pfield _ | Pfield_computed _ -> layout_field | Pfloatfield _ | Pfloatofint _ | Pnegfloat _ | Pabsfloat _ | Paddfloat _ | Psubfloat _ | Pmulfloat _ | Pdivfloat _ - | Pbox_float _ -> layout_float + | Pbox_float _ -> layout_boxed_float | Punbox_float -> Punboxed_float | Pccall { prim_native_repr_res = _, Untagged_int; _} -> layout_int - | Pccall { prim_native_repr_res = _, Unboxed_float; _} -> layout_float - | Pccall { prim_native_repr_res = _, Same_as_ocaml_repr; _} -> - layout_any_value + | Pccall { prim_native_repr_res = _, Unboxed_float; _} -> layout_boxed_float + | Pccall { prim_native_repr_res = _, Same_as_ocaml_repr s; _} -> + begin match s with + | Value -> layout_any_value + | Void -> assert false + end | Pccall { prim_native_repr_res = _, Unboxed_integer bi; _} -> layout_boxedint bi | Praise _ -> layout_bottom @@ -1465,7 +1469,7 @@ let primitive_result_layout (p : primitive) = | Parrayrefu array_ref_kind | Parrayrefs array_ref_kind -> (match array_ref_kind with | Pintarray_ref -> layout_int - | Pfloatarray_ref _ -> layout_float + | Pfloatarray_ref _ -> layout_boxed_float | Pgenarray_ref _ | Paddrarray_ref -> layout_field) | Pbintofint (bi, _) | Pcvtbint (_,bi,_) | Pnegbint (bi, _) | Paddbint (bi, _) | Psubbint (bi, _) @@ -1482,7 +1486,7 @@ let primitive_result_layout (p : primitive) = | Pbigarrayref (_, _, kind, _) -> begin match kind with | Pbigarray_unknown -> layout_any_value - | Pbigarray_float32 | Pbigarray_float64 -> layout_float + | Pbigarray_float32 | Pbigarray_float64 -> layout_boxed_float | Pbigarray_sint8 | Pbigarray_uint8 | Pbigarray_sint16 | Pbigarray_uint16 | Pbigarray_caml_int -> layout_int diff --git a/ocaml/lambda/lambda.mli b/ocaml/lambda/lambda.mli index cf4809d63fe..09ea1eb336d 100644 --- a/ocaml/lambda/lambda.mli +++ b/ocaml/lambda/lambda.mli @@ -527,7 +527,7 @@ val layout_module : layout val layout_functor : layout val layout_module_field : layout val layout_string : layout -val layout_float : layout +val layout_boxed_float : layout val layout_boxedint : boxed_integer -> layout (* A layout that is Pgenval because it is the field of a block *) val layout_field : layout @@ -537,6 +537,8 @@ val layout_lazy_contents : layout val layout_any_value : layout (* A layout that is Pgenval because it is bound by a letrec *) val layout_letrec : layout +(* The probe hack: Free vars in probes must have layout value. *) +val layout_probe_arg : layout val layout_top : layout val layout_bottom : layout diff --git a/ocaml/lambda/matching.ml b/ocaml/lambda/matching.ml index 273b9c26f65..e0f52b2a237 100644 --- a/ocaml/lambda/matching.ml +++ b/ocaml/lambda/matching.ml @@ -163,8 +163,8 @@ let expand_record_head h = { h with pat_desc = Record (Array.to_list lbl_all) } | _ -> h -let bind_alias p id ~arg ~action = - let k = Typeopt.layout p.pat_env p.pat_loc p.pat_type in +let bind_alias p id ~arg ~arg_sort ~action = + let k = Typeopt.layout p.pat_env p.pat_loc arg_sort p.pat_type in bind_with_layout Alias (id, k) arg action let head_loc ~scopes head = @@ -209,7 +209,8 @@ module Half_simple : sig type nonrec clause = pattern Non_empty_row.t clause - val of_clause : arg:lambda -> General.clause -> clause + val of_clause : + arg:lambda -> arg_sort:Layouts.sort -> General.clause -> clause end = struct include Patterns.Half_simple @@ -234,7 +235,7 @@ end = struct | _ -> p (* Explode or-patterns and turn aliases into bindings in actions *) - let of_clause ~arg cl = + let of_clause ~arg ~arg_sort cl = let rec aux (((p, patl), action) : General.clause) : clause = let continue p (view : General.view) : clause = aux (({ p with pat_desc = view }, patl), action) @@ -248,7 +249,7 @@ end = struct | `Alias (p, id, _, _) -> aux ( (General.view p, patl), - bind_alias p id ~arg ~action ) + bind_alias p id ~arg ~arg_sort ~action ) | `Record ([], _) as view -> stop p view | `Record (lbls, closed) -> let full_view = `Record (all_record_args lbls, closed) in @@ -277,6 +278,7 @@ module Simple : sig val explode_or_pat : arg:lambda -> + arg_sort:Layouts.sort -> Half_simple.pattern -> mk_action:(vars:Ident.t list -> lambda) -> patbound_action_vars:Ident.t list -> @@ -331,7 +333,7 @@ end = struct compiling in [do_for_multiple_match] where it is a tuple of variables. *) - let explode_or_pat ~arg (p : Half_simple.pattern) + let explode_or_pat ~arg ~arg_sort (p : Half_simple.pattern) ~mk_action ~patbound_action_vars : (pattern * lambda) list = let rec explode p aliases rem = @@ -384,7 +386,7 @@ end = struct let pat, action = fresh_clause (Some id) action_vars renaming_env rem_vars in - pat, bind_alias pat id ~arg ~action + pat, bind_alias pat id ~arg ~arg_sort ~action end in fresh_clause None [] [] patbound_action_vars :: rem @@ -939,7 +941,7 @@ end type 'row pattern_matching = { mutable cases : 'row list; - args : (lambda * let_kind * layout) list; + args : (lambda * let_kind * Layouts.sort * layout) list; (** args are not just Ident.t in at least the following cases: - when matching the arguments of a constructor, direct field projections are used (make_field_args) @@ -1113,16 +1115,16 @@ let safe_before ((p, ps), act_p) l = || not (may_compats (General.erase p :: ps) (General.erase q :: qs))) l -let half_simplify_nonempty ~arg (cls : Typedtree.pattern Non_empty_row.t clause) - : Half_simple.clause = +let half_simplify_nonempty ~arg ~arg_sort + (cls : Typedtree.pattern Non_empty_row.t clause) : Half_simple.clause = cls |> map_on_row (Non_empty_row.map_first General.view) - |> Half_simple.of_clause ~arg + |> Half_simple.of_clause ~arg ~arg_sort -let half_simplify_clause ~arg (cls : Typedtree.pattern list clause) = +let half_simplify_clause ~arg ~arg_sort (cls : Typedtree.pattern list clause) = cls |> map_on_row Non_empty_row.of_initial - |> half_simplify_nonempty ~arg + |> half_simplify_nonempty ~arg ~arg_sort (* Once matchings are *fully* simplified, one can easily find their nature. *) @@ -1338,7 +1340,7 @@ let as_matrix cases = *) -let rec split_or ~arg (cls : Half_simple.clause list) args def = +let rec split_or ~arg ~arg_sort (cls : Half_simple.clause list) args def = let rec do_split (rev_before : Simple.clause list) rev_ors rev_no = function | [] -> cons_next (List.rev rev_before) (List.rev rev_ors) (List.rev rev_no) @@ -1369,7 +1371,7 @@ let rec split_or ~arg (cls : Half_simple.clause list) args def = in match yesor with | [] -> split_no_or yes args def nexts - | _ -> precompile_or ~arg yes yesor args def nexts + | _ -> precompile_or ~arg ~arg_sort yes yesor args def nexts in do_split [] [] [] cls @@ -1446,7 +1448,7 @@ and precompile_var args cls def k = If the rest doesn't generate any split, abort and do_not_precompile. *) match args with | [] -> assert false - | _ :: ((Lvar v, _, _) as arg) :: rargs -> ( + | _ :: ((Lvar v, _, arg_sort, _) as arg) :: rargs -> ( (* We will use the name of the head column of the submatrix we compile, and this is the *second* column of our argument. *) match cls with @@ -1464,11 +1466,11 @@ and precompile_var args cls def k = (* we learned by pattern-matching on [args] that [p::ps] has at least two arguments, so [ps] must be non-empty *) - half_simplify_clause ~arg:(Lvar v) (ps, act)) + half_simplify_clause ~arg:(Lvar v) ~arg_sort (ps, act)) cls and var_def = Default_environment.pop_column def in let { me = first; matrix }, nexts = - split_or ~arg:(Lvar v) var_cls var_args var_def + split_or ~arg:(Lvar v) ~arg_sort var_cls var_args var_def in (* Compute top information *) match nexts with @@ -1519,7 +1521,7 @@ and do_not_precompile args cls def k = }, k ) -and precompile_or ~arg (cls : Simple.clause list) ors args def k = +and precompile_or ~arg ~arg_sort (cls : Simple.clause list) ors args def k = (* Example: if [cls] is a single-row matrix s11 p12 .. p1n -> act1 @@ -1586,10 +1588,10 @@ and precompile_or ~arg (cls : Simple.clause list) ors args def k = let patbound_action_vars = (* variables bound in the or-pattern that are used in the orpm actions *) - Typedtree.pat_bound_idents_with_types orp - |> List.filter (fun (id, _) -> Ident.Set.mem id pm_fv) - |> List.map (fun (id, ty) -> - (id, Typeopt.layout orp.pat_env orp.pat_loc ty)) + Typedtree.pat_bound_idents_full arg_sort orp + |> List.filter (fun (id, _, _, _) -> Ident.Set.mem id pm_fv) + |> List.map (fun (id, _, ty, id_sort) -> + (id, Typeopt.layout orp.pat_env orp.pat_loc id_sort ty)) in let or_num = next_raise_count () in let new_patl = Patterns.omega_list patl in @@ -1597,7 +1599,7 @@ and precompile_or ~arg (cls : Simple.clause list) ors args def k = Lstaticraise (or_num, List.map (fun v -> Lvar v) vars) in let new_cases = - Simple.explode_or_pat ~arg p + Simple.explode_or_pat ~arg ~arg_sort p ~mk_action:mk_new_action ~patbound_action_vars:(List.map fst patbound_action_vars) |> List.map (fun (p, act) -> ((p, new_patl), act)) in @@ -1645,8 +1647,10 @@ let split_and_precompile_simplified pm = dbg_split_and_precompile pm next nexts; (next, nexts) -let split_and_precompile_half_simplified ~arg pm = - let { me = next }, nexts = split_or ~arg pm.cases pm.args pm.default in +let split_and_precompile_half_simplified ~arg ~arg_sort pm = + let { me = next }, nexts = + split_or ~arg ~arg_sort pm.cases pm.args pm.default + in dbg_split_and_precompile pm next nexts; (next, nexts) @@ -1677,7 +1681,7 @@ let make_line_matching get_expr_args head def = function } type 'a division = { - args : (lambda * let_kind * layout) list; + args : (lambda * let_kind * Layouts.sort * layout) list; cells : ('a * cell) list } @@ -1773,7 +1777,7 @@ let get_pat_args_constr p rem = args @ rem | _ -> assert false -let get_expr_args_constr ~scopes head (arg, _mut, layout) rem = +let get_expr_args_constr ~scopes head (arg, _mut, sort, layout) rem = let cstr = match head.pat_desc with | Patterns.Head.Construct cstr -> cstr @@ -1790,18 +1794,18 @@ let get_expr_args_constr ~scopes head (arg, _mut, layout) rem = argl else (Lprim (Pfield (pos, Reads_agree), [ arg ], loc), binding_kind, - layout_field) + Sort.for_constructor_arg, layout_field) :: make_args (pos + 1) in make_args first_pos in if cstr.cstr_inlined <> None then - (arg, Alias, layout) :: rem + (arg, Alias, sort, layout) :: rem else match cstr.cstr_repr with | Variant_boxed _ -> make_field_accesses Alias 0 (cstr.cstr_arity - 1) rem - | Variant_unboxed -> (arg, Alias, layout) :: rem + | Variant_unboxed -> (arg, Alias, sort, layout) :: rem | Variant_extensible -> make_field_accesses Alias 1 cstr.cstr_arity rem let divide_constructor ~scopes ctx pm = @@ -1819,10 +1823,13 @@ let get_expr_args_variant_constant = drop_expr_arg let nonconstant_variant_field index = Lambda.Pfield(index, Reads_agree) -let get_expr_args_variant_nonconst ~scopes head (arg, _mut, _layout) rem = +let get_expr_args_variant_nonconst ~scopes head (arg, _mut, _sort, _layout) + rem = let loc = head_loc ~scopes head in let field_prim = nonconstant_variant_field 1 in - (Lprim (field_prim, [ arg ], loc), Alias, layout_field) :: rem + (Lprim (field_prim, [ arg ], loc), Alias, Sort.for_constructor_arg, + layout_field) + :: rem let divide_variant ~scopes row ctx { cases = cl; args; default = def } = let rec divide = function @@ -1884,7 +1891,8 @@ let get_pat_args_lazy p rem = No other call than Obj.tag when the value has been forced before. *) -let prim_obj_tag = Primitive.simple ~name:"caml_obj_tag" ~arity:1 ~alloc:false +let prim_obj_tag = + Primitive.simple_on_values ~name:"caml_obj_tag" ~arity:1 ~alloc:false let get_mod_field modname field = lazy @@ -2029,9 +2037,10 @@ let inline_lazy_force arg pos loc = tables (~ 250 elts); conditionals are better *) inline_lazy_force_cond arg pos loc -let get_expr_args_lazy ~scopes head (arg, _mut, _layout) rem = +let get_expr_args_lazy ~scopes head (arg, _mut, _sort, _layout) rem = let loc = head_loc ~scopes head in - (inline_lazy_force arg Rc_normal loc, Strict, layout_lazy_contents) :: rem + (inline_lazy_force arg Rc_normal loc, Strict, Sort.for_lazy_body, + layout_lazy_contents) :: rem let divide_lazy ~scopes head ctx pm = divide_line (Context.specialize head) @@ -2047,14 +2056,15 @@ let get_pat_args_tuple arity p rem = | { pat_desc = Tpat_tuple args } -> args @ rem | _ -> assert false -let get_expr_args_tuple ~scopes head (arg, _mut, _layout) rem = +let get_expr_args_tuple ~scopes head (arg, _mut, _sort, _layout) rem = let loc = head_loc ~scopes head in let arity = Patterns.Head.arity head in let rec make_args pos = if pos >= arity then rem else - (Lprim (Pfield (pos, Reads_agree), [ arg ], loc), Alias, layout_field) + (Lprim (Pfield (pos, Reads_agree), [ arg ], loc), Alias, + Sort.for_tuple_element, layout_field) :: make_args (pos + 1) in make_args 0 @@ -2085,7 +2095,7 @@ let get_pat_args_record num_fields p rem = record_matching_line num_fields lbl_pat_list @ rem | _ -> assert false -let get_expr_args_record ~scopes head (arg, _mut, layout) rem = +let get_expr_args_record ~scopes head (arg, _mut, sort, layout) rem = let loc = head_loc ~scopes head in let all_labels = let open Patterns.Head in @@ -2106,34 +2116,36 @@ let get_expr_args_record ~scopes head (arg, _mut, layout) rem = | Immutable -> Reads_agree | Mutable -> Reads_vary in - let access, layout = - (* CR layouts v2: Here we'll need to get the layout from the + let access, sort, layout = + (* CR layouts v5: Here we'll need to get the layout from the record_representation and translate it to `Lambda.layout`, rather than just using layout_field everywhere. (Though layout_field is safe for now, particularly after checking for void above.) I think only the sort information matters here, so when we make that change - we'll probably want a cheaper version of the `Typeopt.layout` - function that avoids calling `value_kind` in the value case. *) + we may want to use `Typeopt.layout_of_sort` rather than + `Typeopt.layout`. *) match lbl.lbl_repres with | Record_boxed _ | Record_inlined (_, Variant_boxed _) -> - Lprim (Pfield (lbl.lbl_pos, sem), [ arg ], loc), layout_field + Lprim (Pfield (lbl.lbl_pos, sem), [ arg ], loc), + Sort.for_record_field, layout_field | Record_unboxed - | Record_inlined (_, Variant_unboxed) -> arg, layout + | Record_inlined (_, Variant_unboxed) -> arg, sort, layout | Record_float -> (* TODO: could optimise to Alloc_local sometimes *) Lprim (Pfloatfield (lbl.lbl_pos, sem, alloc_heap), [ arg ], loc), - (* CR layouts v2: is this really unboxed float? *) - layout_float + (* Here we are projecting a boxed float from a float record. *) + Sort.for_predef_value, layout_boxed_float | Record_inlined (_, Variant_extensible) -> - Lprim (Pfield (lbl.lbl_pos + 1, sem), [ arg ], loc), layout_field + Lprim (Pfield (lbl.lbl_pos + 1, sem), [ arg ], loc), + Sort.for_record_field, layout_field in let str = match lbl.lbl_mut with | Immutable -> Alias | Mutable -> StrictOpt in - (access, str, layout) :: make_args (pos + 1) + (access, str, sort, layout) :: make_args (pos + 1) in make_args 0 @@ -2160,7 +2172,7 @@ let get_pat_args_array p rem = | { pat_desc = Tpat_array (_, patl) } -> patl @ rem | _ -> assert false -let get_expr_args_array ~scopes kind head (arg, _mut, _layout) rem = +let get_expr_args_array ~scopes kind head (arg, _mut, _sort, _layout) rem = let am, len = let open Patterns.Head in match head.pat_desc with @@ -2182,6 +2194,7 @@ let get_expr_args_array ~scopes kind head (arg, _mut, _layout) rem = (match am with | Mutable -> StrictOpt | Immutable -> Alias), + Sort.for_array_get_result, layout_field) :: make_args (pos + 1) in @@ -2211,10 +2224,12 @@ let divide_array ~scopes kind ctx pm = let strings_test_threshold = 8 let prim_string_notequal = - Pccall (Primitive.simple ~name:"caml_string_notequal" ~arity:2 ~alloc:false) + Pccall (Primitive.simple_on_values ~name:"caml_string_notequal" ~arity:2 + ~alloc:false) let prim_string_compare = - Pccall (Primitive.simple ~name:"caml_string_compare" ~arity:2 ~alloc:false) + Pccall (Primitive.simple_on_values ~name:"caml_string_compare" ~arity:2 + ~alloc:false) let bind_sw arg layout k = match arg with @@ -3329,13 +3344,17 @@ and compile_match_nonempty ~scopes value_kind repr partial ctx (m : Typedtree.pattern Non_empty_row.t clause pattern_matching)= match m with | { cases = []; args = [] } -> comp_exit ctx m - | { args = (arg, str, layout) :: argl } -> + | { args = (arg, str, arg_sort, layout) :: argl } -> let v, newarg = arg_to_var arg m.cases in - let args = (newarg, Alias, layout) :: argl in - let cases = List.map (half_simplify_nonempty ~arg:newarg) m.cases in + let args = (newarg, Alias, arg_sort, layout) :: argl in + let cases = + List.map (half_simplify_nonempty ~arg:newarg ~arg_sort) + m.cases + in let m = { m with args; cases } in let first_match, rem = - split_and_precompile_half_simplified ~arg:newarg m in + split_and_precompile_half_simplified ~arg:newarg ~arg_sort m + in combine_handlers ~scopes value_kind repr partial ctx (v, str, layout, arg) first_match rem | _ -> assert false @@ -3343,8 +3362,8 @@ and compile_match_simplified ~scopes value_kind repr partial ctx (m : Simple.clause pattern_matching) = match m with | { cases = []; args = [] } -> comp_exit ctx m - | { args = ((Lvar v as arg), str, layout) :: argl } -> - let args = (arg, Alias, layout) :: argl in + | { args = ((Lvar v as arg), str, sort, layout) :: argl } -> + let args = (arg, Alias, sort, layout) :: argl in let m = { m with args } in let first_match, rem = split_and_precompile_simplified m in combine_handlers value_kind ~scopes repr partial ctx (v, str, layout, arg) @@ -3385,7 +3404,7 @@ and do_compile_matching ~scopes value_kind repr partial ctx pmh = | Pm pm -> ( let arg = match pm.args with - | (first_arg, _, _) :: _ -> first_arg + | (first_arg, _, _, _) :: _ -> first_arg | _ -> (* We arrive in do_compile_matching from: - compile_matching @@ -3589,7 +3608,7 @@ let check_total ~scopes value_kind loc ~failer total lambda i = Lstaticcatch (lambda, (i, []), failure_handler ~scopes loc ~failer (), value_kind) -let toplevel_handler ~scopes value_kind loc ~failer partial args cases compile_fun = +let toplevel_handler ~scopes ~return_layout loc ~failer partial args cases compile_fun = match partial with | Total -> let default = Default_environment.empty in @@ -3606,22 +3625,25 @@ let toplevel_handler ~scopes value_kind loc ~failer partial args cases compile_f begin match compile_fun Partial pm with | exception Unused -> assert false | (lam, total) -> - check_total ~scopes value_kind loc ~failer total lam raise_num + check_total ~scopes return_layout loc ~failer total lam raise_num end -let compile_matching ~scopes value_kind loc ~failer repr (arg, arg_layout) pat_act_list partial = +let compile_matching ~scopes ~arg_sort ~arg_layout ~return_layout loc ~failer repr arg + pat_act_list partial = let partial = check_partial pat_act_list partial in - let args = [ (arg, Strict, arg_layout) ] in + let args = [ (arg, Strict, arg_sort, arg_layout) ] in let rows = map_on_rows (fun pat -> (pat, [])) pat_act_list in - toplevel_handler ~scopes value_kind loc ~failer partial args rows (fun partial pm -> - compile_match_nonempty ~scopes value_kind repr partial (Context.start 1) pm) + toplevel_handler ~scopes ~return_layout loc ~failer partial args rows + (fun partial pm -> compile_match_nonempty ~scopes return_layout repr + partial (Context.start 1) pm) -let for_function ~scopes kind loc repr param pat_act_list partial = - compile_matching ~scopes kind loc ~failer:Raise_match_failure - repr param pat_act_list partial +let for_function ~scopes ~arg_sort ~arg_layout ~return_layout loc repr param + pat_act_list partial = + compile_matching ~scopes ~arg_sort ~arg_layout ~return_layout loc + ~failer:Raise_match_failure repr param pat_act_list partial (* In the following two cases, exhaustiveness info is not available! *) -let for_trywith ~scopes value_kind loc param pat_act_list = +let for_trywith ~scopes ~return_layout loc param pat_act_list = (* Note: the failure action of [for_trywith] corresponds to an exception that is not matched by a try..with handler, and is thus reraised for the next handler in the stack. @@ -3629,13 +3651,16 @@ let for_trywith ~scopes value_kind loc param pat_act_list = It is important to *not* include location information in the reraise (hence the [_noloc]) to avoid seeing this silent reraise in exception backtraces. *) - compile_matching ~scopes value_kind loc ~failer:(Reraise_noloc param) - None (param, layout_block) pat_act_list Partial + compile_matching ~scopes ~arg_sort:Sort.for_predef_value + ~arg_layout:layout_block ~return_layout loc ~failer:(Reraise_noloc param) + None param pat_act_list Partial -let simple_for_let ~scopes value_kind loc param pat body = - compile_matching ~scopes value_kind loc ~failer:Raise_match_failure - None (param, Typeopt.layout pat.pat_env pat.pat_loc pat.pat_type) - [ (pat, body) ] Partial +let simple_for_let ~scopes ~arg_sort ~return_layout loc param pat body = + let arg_layout = + Typeopt.layout pat.pat_env pat.pat_loc arg_sort pat.pat_type + in + compile_matching ~scopes ~arg_sort ~arg_layout ~return_layout loc + ~failer:Raise_match_failure None param [ (pat, body) ] Partial (* Optimize binding of immediate tuples @@ -3736,42 +3761,46 @@ let rec map_return f = function can be costly (one unnecessary tuple allocation). *) -let assign_pat ~scopes value_kind opt nraise catch_ids loc pat lam = - let rec collect acc pat lam = +let assign_pat ~scopes body_layout opt nraise catch_ids loc pat pat_sort lam = + let rec collect pat_sort acc pat lam = match (pat.pat_desc, lam) with | Tpat_tuple patl, Lprim (Pmakeblock _, lams, _) -> opt := true; - List.fold_left2 collect acc patl lams + List.fold_left2 (collect Sort.for_tuple_element) acc patl lams | Tpat_tuple patl, Lconst (Const_block (_, scl)) -> opt := true; - let collect_const acc pat sc = collect acc pat (Lconst sc) in + let collect_const acc pat sc = + collect Sort.for_tuple_element acc pat (Lconst sc) + in List.fold_left2 collect_const acc patl scl | _ -> (* pattern idents will be bound in staticcatch (let body), so we refresh them here to guarantee binders uniqueness *) let pat_ids = pat_bound_idents pat in let fresh_ids = List.map (fun id -> (id, Ident.rename id)) pat_ids in - (fresh_ids, alpha_pat fresh_ids pat, lam) :: acc + (fresh_ids, alpha_pat fresh_ids pat, lam, pat_sort) :: acc in (* sublets were accumulated by 'collect' with the leftmost tuple pattern at the bottom of the list; to respect right-to-left evaluation order for tuples, we must evaluate sublets top-to-bottom. To preserve tail-rec, we will fold_left the reversed list. *) - let rev_sublets = List.rev (collect [] pat lam) in + let rev_sublets = List.rev (collect pat_sort [] pat lam) in let exit = (* build an Ident.tbl to avoid quadratic refreshing costs *) let add t (id, fresh_id) = Ident.add id fresh_id t in - let add_ids acc (ids, _pat, _lam) = List.fold_left add acc ids in + let add_ids acc (ids, _pat, _lam, _sort) = List.fold_left add acc ids in let tbl = List.fold_left add_ids Ident.empty rev_sublets in let fresh_var id = Lvar (Ident.find_same id tbl) in Lstaticraise (nraise, List.map fresh_var catch_ids) in - let push_sublet code (_ids, pat, lam) = - simple_for_let ~scopes value_kind loc lam pat code in + let push_sublet code (_ids, pat, lam, pat_sort ) = + simple_for_let ~scopes ~arg_sort:pat_sort ~return_layout:body_layout loc lam + pat code + in List.fold_left push_sublet exit rev_sublets -let for_let ~scopes loc param pat body_kind body = +let for_let ~scopes ~arg_sort ~return_layout loc param pat body = match pat.pat_desc with | Tpat_any -> (* This eliminates a useless variable (and stack slot in bytecode) @@ -3779,7 +3808,7 @@ let for_let ~scopes loc param pat body_kind body = Lsequence (param, body) | Tpat_var (id, _, _) -> (* fast path, and keep track of simple bindings to unboxable numbers *) - let k = Typeopt.layout pat.pat_env pat.pat_loc pat.pat_type in + let k = Typeopt.layout pat.pat_env pat.pat_loc arg_sort pat.pat_type in Llet (Strict, k, id, param, body) | _ -> let opt = ref false in @@ -3787,29 +3816,36 @@ let for_let ~scopes loc param pat body_kind body = let catch_ids = pat_bound_idents_with_types pat in let ids_with_kinds = List.map - (fun (id, typ) -> (id, Typeopt.layout pat.pat_env pat.pat_loc typ)) + (fun (id, typ) -> + (id, Typeopt.layout pat.pat_env pat.pat_loc arg_sort typ)) catch_ids in let ids = List.map (fun (id, _) -> id) catch_ids in let bind = - map_return (assign_pat ~scopes body_kind opt nraise ids loc pat) param in + map_return (assign_pat ~scopes return_layout opt nraise ids loc pat + arg_sort) + param + in if !opt then - Lstaticcatch (bind, (nraise, ids_with_kinds), body, body_kind) + Lstaticcatch (bind, (nraise, ids_with_kinds), body, return_layout) else - simple_for_let ~scopes body_kind loc param pat body + simple_for_let ~scopes ~arg_sort ~return_layout loc param pat body (* Handling of tupled functions and matchings *) (* Easy case since variables are available *) -let for_tupled_function ~scopes loc kind paraml pats_act_list partial = +let for_tupled_function ~scopes ~return_layout loc paraml pats_act_list partial = let partial = check_partial_list pats_act_list partial in (* The arguments of a tupled function are always values since they must be fields *) - let args = List.map (fun id -> (Lvar id, Strict, layout_field)) paraml in + let args = + List.map (fun id -> (Lvar id, Strict, Sort.for_tuple_element, layout_field)) + paraml + in let handler = - toplevel_handler ~scopes kind loc ~failer:Raise_match_failure + toplevel_handler ~scopes ~return_layout loc ~failer:Raise_match_failure partial args pats_act_list in handler (fun partial pm -> - compile_match ~scopes kind None partial + compile_match ~scopes return_layout None partial (Context.start (List.length paraml)) pm ) @@ -3891,58 +3927,75 @@ let compile_flattened ~scopes value_kind repr partial ctx pmh = (compile_match ~scopes value_kind repr partial) lam total ctx hs -let do_for_multiple_match ~scopes value_kind loc paraml mode pat_act_list partial = +let do_for_multiple_match ~scopes ~return_layout loc paraml mode pat_act_list partial = + (* CR layouts v5: This function is called in cases where the scrutinee of a + match is a literal tuple (e.g., [match e1, e2, e3 with ...]). The + typechecker treats the scrutinee here like any other tuple, so it's fine to + assume the whole thing and the elements have sort value. That will change + when we allow non-values in structures. *) let repr = None in + let param_lambda = List.map (fun (l, _, _) -> l) paraml in let arg = let sloc = Scoped_location.of_location ~scopes loc in - (* CR ncourant: this can build a mixed block, but it should never actually be - created except if the pattern-matching binds it, in which case it should be - rejected by the typing. Do we really trust this case will not happen? *) - Lprim (Pmakeblock (0, Immutable, None, mode), List.map fst paraml, sloc) in + Lprim (Pmakeblock (0, Immutable, None, mode), param_lambda, sloc) + in + let arg_sort = Sort.for_tuple in let handler = let partial = check_partial pat_act_list partial in let rows = map_on_rows (fun p -> (p, [])) pat_act_list in - toplevel_handler ~scopes value_kind loc ~failer:Raise_match_failure - partial [ (arg, Strict, layout_block) ] rows in + toplevel_handler ~scopes ~return_layout loc ~failer:Raise_match_failure + partial [ (arg, Strict, Sort.for_tuple, layout_block) ] rows in handler (fun partial pm1 -> let pm1_half = - { pm1 with cases = List.map (half_simplify_nonempty ~arg) pm1.cases } + { pm1 with + cases = List.map (half_simplify_nonempty ~arg ~arg_sort) pm1.cases } + in + let next, nexts = split_and_precompile_half_simplified ~arg ~arg_sort pm1_half in + let size = List.length paraml in + let (idl_with_layouts, args) = + List.map (function + | Lvar id as lid, sort, layout -> + (id, layout), (lid, Alias, sort, layout) + | _, sort, layout -> + let id = Ident.create_local "*match*" in + (id, layout), (Lvar id, Alias, sort, layout)) + paraml + |> List.split in - let next, nexts = split_and_precompile_half_simplified ~arg pm1_half in - let size = List.length paraml - and idl_with_layouts = List.map (function - | Lvar id, layout -> id, layout - | _, layout -> Ident.create_local "*match*", layout) paraml in - let args = List.map (fun (id, layout) -> (Lvar id, Alias, layout)) idl_with_layouts in let flat_next = flatten_precompiled size args next and flat_nexts = List.map (fun (e, pm) -> (e, flatten_precompiled size args pm)) nexts in let lam, total = - comp_match_handlers value_kind (compile_flattened ~scopes value_kind repr) partial + comp_match_handlers return_layout + (compile_flattened ~scopes return_layout repr) partial (Context.start size) flat_next flat_nexts in - List.fold_right2 (bind_with_layout Strict) idl_with_layouts (List.map fst paraml) lam, total + List.fold_right2 (bind_with_layout Strict) idl_with_layouts param_lambda lam, + total ) (* PR#4828: Believe it or not, the 'paraml' argument below may not be side effect free. *) -let param_to_var (param, layout) = +let param_to_var (param, sort, layout) = match param with - | Lvar v -> (v, layout, None) - | _ -> (Ident.create_local "*match*", layout, Some param) + | Lvar v -> (v, sort, layout, None) + | _ -> (Ident.create_local "*match*", sort, layout, Some param) -let bind_opt (v, layout, eo) k = +let bind_opt (v, _, layout, eo) k = match eo with | None -> k | Some e -> Lambda.bind_with_layout Strict (v, layout) e k -let for_multiple_match ~scopes value_kind loc paraml mode pat_act_list partial = +let for_multiple_match ~scopes ~return_layout loc paraml mode pat_act_list partial = let v_paraml = List.map param_to_var paraml in - let paraml = List.map (fun (v, layout, _) -> (Lvar v, layout)) v_paraml in + let paraml = + List.map (fun (v, sort, layout, _) -> (Lvar v, sort, layout)) v_paraml + in List.fold_right bind_opt v_paraml - (do_for_multiple_match ~scopes value_kind loc paraml mode pat_act_list partial) + (do_for_multiple_match ~scopes ~return_layout loc paraml mode pat_act_list + partial) (* Error report *) (* CR layouts v2: This file didn't use to have the report_error infrastructure - diff --git a/ocaml/lambda/matching.mli b/ocaml/lambda/matching.mli index 9753213061c..904c49c22a0 100644 --- a/ocaml/lambda/matching.mli +++ b/ocaml/lambda/matching.mli @@ -21,24 +21,27 @@ open Debuginfo.Scoped_location (* Entry points to match compiler *) val for_function: - scopes:scopes -> layout -> Location.t -> - int ref option -> (lambda * layout) -> (pattern * lambda) list -> partial -> + scopes:scopes -> + arg_sort:Layouts.sort -> arg_layout:layout -> return_layout:layout -> + Location.t -> int ref option -> lambda -> (pattern * lambda) list -> + partial -> lambda val for_trywith: - scopes:scopes -> layout -> Location.t -> + scopes:scopes -> return_layout:layout -> Location.t -> lambda -> (pattern * lambda) list -> lambda val for_let: - scopes:scopes -> Location.t -> - lambda -> pattern -> layout -> lambda -> + scopes:scopes -> arg_sort:Layouts.sort -> return_layout:layout -> + Location.t -> lambda -> pattern -> lambda -> lambda val for_multiple_match: - scopes:scopes -> layout -> Location.t -> - (lambda * layout) list -> alloc_mode -> (pattern * lambda) list -> partial -> + scopes:scopes -> return_layout:layout -> Location.t -> + (lambda * Layouts.sort * layout) list -> alloc_mode -> + (pattern * lambda) list -> partial -> lambda val for_tupled_function: - scopes:scopes -> Location.t -> layout -> + scopes:scopes -> return_layout:layout -> Location.t -> Ident.t list -> (pattern list * lambda) list -> partial -> lambda diff --git a/ocaml/lambda/transl_array_comprehension.ml b/ocaml/lambda/transl_array_comprehension.ml index 4277e8e4a46..bd92585eca4 100644 --- a/ocaml/lambda/transl_array_comprehension.ml +++ b/ocaml/lambda/transl_array_comprehension.ml @@ -1,3 +1,4 @@ +open Layouts open Lambda open Typedtree open Asttypes @@ -455,7 +456,7 @@ let iterator ~transl_exp ~scopes ~loc | Texp_comp_range { ident; pattern = _; start; stop; direction } -> let bound name value = Let_binding.make (Immutable Strict) (Pvalue Pintval) - name (transl_exp ~scopes value) + name (transl_exp ~scopes Sort.for_predef_value value) in let start = bound "start" start in let stop = bound "stop" stop in @@ -472,7 +473,7 @@ let iterator ~transl_exp ~scopes ~loc | Texp_comp_in { pattern; sequence = iter_arr_exp } -> let iter_arr = Let_binding.make (Immutable Strict) (Pvalue Pgenval) - "iter_arr" (transl_exp ~scopes iter_arr_exp) + "iter_arr" (transl_exp ~scopes Sort.for_predef_value iter_arr_exp) in let iter_arr_kind = Typeopt.array_kind iter_arr_exp in let iter_len = @@ -486,7 +487,7 @@ let iterator ~transl_exp ~scopes ~loc let mk_iterator body = let open (val Lambda_utils.int_ops ~loc) in (* for iter_ix = 0 to Array.length iter_arr - 1 ... *) - (* CR layouts: will need updating when we allow non-values in arrays. *) + (* CR layouts v4: will need updating when we allow non-values in arrays. *) Lfor { for_id = iter_ix ; for_from = l0 ; for_to = iter_len.var - l1 @@ -494,13 +495,14 @@ let iterator ~transl_exp ~scopes ~loc ; for_body = Matching.for_let ~scopes + ~arg_sort:Sort.for_array_element + ~return_layout:(Pvalue Pintval) pattern.pat_loc (Lprim(Parrayrefu Lambda.(array_ref_kind alloc_heap iter_arr_kind), [iter_arr.var; Lvar iter_ix], loc)) pattern - (Pvalue Pintval) body } in @@ -549,7 +551,7 @@ let clause ~transl_exp ~scopes ~loc = function (Iterator_bindings.all_let_bindings var_bindings) (make_clause body) | Texp_comp_when cond -> - fun body -> Lifthenelse(transl_exp ~scopes cond, + fun body -> Lifthenelse(transl_exp ~scopes Sort.for_predef_value cond, body, lambda_unit, (Pvalue Pintval) (* [unit] is immediate *)) @@ -830,7 +832,7 @@ let comprehension ~array_sizing ~array ~index - ~body:(transl_exp ~scopes comp_body)), + ~body:(transl_exp ~scopes Sort.for_array_element comp_body)), (* If it was dynamically grown, cut it down to size *) match array_sizing with | Fixed_size -> array.var diff --git a/ocaml/lambda/transl_array_comprehension.mli b/ocaml/lambda/transl_array_comprehension.mli index 064079879ab..4e50a627d21 100644 --- a/ocaml/lambda/transl_array_comprehension.mli +++ b/ocaml/lambda/transl_array_comprehension.mli @@ -22,7 +22,7 @@ open Debuginfo.Scoped_location so is parameterized by [Translcore.transl_exp], its [scopes] argument, and the [loc]ation. *) val comprehension - : transl_exp:(scopes:scopes -> expression -> lambda) + : transl_exp:(scopes:scopes -> Layouts.sort -> expression -> lambda) -> scopes:scopes -> loc:scoped_location -> array_kind:array_kind diff --git a/ocaml/lambda/transl_comprehension_utils.ml b/ocaml/lambda/transl_comprehension_utils.ml index 8b0dc95d15f..381ff6b3c60 100644 --- a/ocaml/lambda/transl_comprehension_utils.ml +++ b/ocaml/lambda/transl_comprehension_utils.ml @@ -112,7 +112,9 @@ module Lambda_utils = struct module Primitive = struct (** The Lambda primitive for calling a simple C primitive *) - let c_prim name arity = Pccall (Primitive.simple ~name ~arity ~alloc:true) + (* CR layouts v4: To change when non-values are allowed in arrays. *) + let c_prim name arity = + Pccall (Primitive.simple_on_values ~name ~arity ~alloc:true) (** Create a function that produces the Lambda representation for a one-argument C primitive when provided with a Lambda argument *) diff --git a/ocaml/lambda/transl_list_comprehension.ml b/ocaml/lambda/transl_list_comprehension.ml index 89f9646397a..eb705471204 100644 --- a/ocaml/lambda/transl_list_comprehension.ml +++ b/ocaml/lambda/transl_list_comprehension.ml @@ -1,3 +1,4 @@ +open Layouts open Lambda open Typedtree open Asttypes @@ -165,11 +166,6 @@ type translated_iterator = desugars into a higher-order function which is applied to another function containing the body of the iteration; that body function can't be filled in until the rest of the translations have been done. *) -(* CR layouts v2: the value that is passed to this function for [transl_exp] - (and all the other [~transl_exp] parameters in this file) must only be called - on expressions whose types have sort value. Probably [transl_exp] will have - been updated to allow other sorts by the time we allow array elements other - than value, but check that. *) let iterator ~transl_exp ~scopes = function | Texp_comp_range { ident; pattern = _; start; stop; direction } -> (* We have to let-bind [start] and [stop] so that they're evaluated in the @@ -177,7 +173,7 @@ let iterator ~transl_exp ~scopes = function let transl_bound var bound = Let_binding.make (Immutable Strict) (Pvalue Pintval) - var (transl_exp ~scopes bound) + var (transl_exp ~scopes Sort.for_predef_value bound) in let start = transl_bound "start" start in let stop = transl_bound "stop" stop in @@ -192,7 +188,7 @@ let iterator ~transl_exp ~scopes = function | Texp_comp_in { pattern; sequence } -> let iter_list = Let_binding.make (Immutable Strict) (Pvalue Pgenval) - "iter_list" (transl_exp ~scopes sequence) + "iter_list" (transl_exp ~scopes Sort.for_predef_value sequence) in (* Create a fresh variable to use as the function argument *) let element = Ident.create_local "element" in @@ -200,11 +196,14 @@ let iterator ~transl_exp ~scopes = function ; arg_lets = [iter_list] ; element ; element_kind = - Typeopt.layout pattern.pat_env pattern.pat_loc pattern.pat_type + Typeopt.layout pattern.pat_env pattern.pat_loc + Layouts.Sort.for_list_element pattern.pat_type ; add_bindings = (* CR layouts: to change when we allow non-values in sequences *) Matching.for_let - ~scopes pattern.pat_loc (Lvar element) pattern (Pvalue Pgenval) + ~scopes ~arg_sort:Sort.for_list_element + ~return_layout:(Pvalue Pgenval) pattern.pat_loc (Lvar element) + pattern } (** Translates a list comprehension binding @@ -289,7 +288,7 @@ let rec translate_clauses in Let_binding.let_all arg_lets bindings | Texp_comp_when cond -> - Lifthenelse(transl_exp ~scopes cond, + Lifthenelse(transl_exp ~scopes Sort.for_predef_value cond, body ~accumulator, accumulator, (Pvalue Pgenval) (* [list]s have the standard representation *)) @@ -304,7 +303,7 @@ let comprehension ~transl_exp ~scopes ~loc { comp_body; comp_clauses } = rev_list_snoc_local ~loc ~init:accumulator - ~last:(transl_exp ~scopes comp_body)) + ~last:(transl_exp ~scopes Sort.for_list_element comp_body)) ~accumulator:rev_list_nil comp_clauses in diff --git a/ocaml/lambda/transl_list_comprehension.mli b/ocaml/lambda/transl_list_comprehension.mli index 3369e08776c..bc564dc4767 100644 --- a/ocaml/lambda/transl_list_comprehension.mli +++ b/ocaml/lambda/transl_list_comprehension.mli @@ -15,7 +15,7 @@ open Debuginfo.Scoped_location so is parameterized by [Translcore.transl_exp], its [scopes] argument, and the [loc]ation. *) val comprehension - : transl_exp:(scopes:scopes -> expression -> lambda) + : transl_exp:(scopes:scopes -> Layouts.sort -> expression -> lambda) -> scopes:scopes -> loc:scoped_location -> comprehension diff --git a/ocaml/lambda/translclass.ml b/ocaml/lambda/translclass.ml index 39021e1cbf5..a24eeae0b4e 100644 --- a/ocaml/lambda/translclass.ml +++ b/ocaml/lambda/translclass.ml @@ -14,6 +14,7 @@ (**************************************************************************) open Asttypes +open Layouts open Types open Typedtree open Lambda @@ -98,7 +99,8 @@ let transl_meth_list lst = let set_inst_var ~scopes obj id expr = Lprim(Psetfield_computed (Typeopt.maybe_pointer expr, Assignment modify_heap), - [Lvar obj; Lvar id; transl_exp ~scopes expr], Loc_unknown) + [Lvar obj; Lvar id; transl_exp ~scopes Sort.for_instance_var expr], + Loc_unknown) let transl_val tbl create name = mkappl (oo_prim (if create then "new_variable" else "get_variable"), @@ -204,16 +206,22 @@ let rec build_object_init ~scopes cl_table obj params inh_init obj_init cl = (inh_init, let build params rem = let param = name_pattern "param" pat in - let param_layout = - Typeopt.layout pat.pat_env pat.pat_loc pat.pat_type + let arg_sort = Sort.for_class_arg in + let arg_layout = + Typeopt.layout pat.pat_env pat.pat_loc arg_sort pat.pat_type + in + let body = + Matching.for_function ~scopes ~arg_sort ~arg_layout + ~return_layout:layout_obj pat.pat_loc None (Lvar param) [pat, rem] + partial in Lambda.lfunction - ~kind:(Curried {nlocal=0}) ~params:((param, param_layout)::params) + ~kind:(Curried {nlocal=0}) + ~params:((param, arg_layout)::params) ~return:layout_obj ~attr:default_function_attribute ~loc:(of_location ~scopes pat.pat_loc) - ~body:(Matching.for_function ~scopes layout_obj pat.pat_loc - None (Lvar param, param_layout) [pat, rem] partial) + ~body ~mode:alloc_heap ~region:true in @@ -233,7 +241,8 @@ let rec build_object_init ~scopes cl_table obj params inh_init obj_init cl = build_object_init ~scopes cl_table obj (vals @ params) inh_init obj_init cl in - (inh_init, Translcore.transl_let ~scopes rec_flag defs layout_obj obj_init) + (inh_init, Translcore.transl_let ~return_layout:layout_obj ~scopes + rec_flag defs obj_init) | Tcl_open (_, cl) | Tcl_constraint (cl, _, _, _, _) -> build_object_init ~scopes cl_table obj params inh_init obj_init cl @@ -350,7 +359,8 @@ let rec build_class_init ~scopes cla cstr super inh_init cl_init msubst top cl = | Tcf_method (name, _, Tcfk_concrete (_, exp)) -> let scopes = enter_method_definition ~scopes name.txt in let met_code = - msubst true (transl_scoped_exp ~scopes exp) in + msubst true (transl_scoped_exp ~scopes Sort.for_method exp) + in let met_code = if !Clflags.native_code && List.length met_code = 1 then (* Force correct naming of method for profiles *) @@ -365,7 +375,9 @@ let rec build_class_init ~scopes cla cstr super inh_init cl_init msubst top cl = (inh_init, Lsequence(mkappl (oo_prim "add_initializer", Lvar cla :: msubst false - (transl_exp ~scopes exp), layout_unit), + (transl_exp ~scopes + Sort.for_initializer exp), + layout_unit), cl_init), methods, values) | Tcf_attribute _ -> @@ -445,8 +457,9 @@ let rec build_class_lets ~scopes cl = match cl.cl_desc with Tcl_let (rec_flag, defs, _vals, cl') -> let env, wrap = build_class_lets ~scopes cl' in - (env, fun x_layout x -> - Translcore.transl_let ~scopes rec_flag defs x_layout (wrap x_layout x)) + (env, fun return_layout x -> + Translcore.transl_let ~scopes ~return_layout rec_flag defs + (wrap return_layout x)) | _ -> (cl.cl_env, fun _ x -> x) @@ -481,17 +494,22 @@ let rec transl_class_rebind ~scopes obj_init cl vf = transl_class_rebind ~scopes obj_init cl vf in let build params rem = let param = name_pattern "param" pat in - let param_layout = - Typeopt.layout pat.pat_env pat.pat_loc pat.pat_type + let arg_sort = Sort.for_class_arg in + let arg_layout = + Typeopt.layout pat.pat_env pat.pat_loc arg_sort pat.pat_type in let return_layout = layout_class in + let body = + Matching.for_function ~scopes ~arg_sort ~arg_layout ~return_layout pat.pat_loc + None (Lvar param) [pat, rem] partial + in Lambda.lfunction - ~kind:(Curried {nlocal=0}) ~params:((param, param_layout)::params) + ~kind:(Curried {nlocal=0}) + ~params:((param, arg_layout)::params) ~return:return_layout ~attr:default_function_attribute ~loc:(of_location ~scopes pat.pat_loc) - ~body:(Matching.for_function ~scopes return_layout pat.pat_loc - None (Lvar param, param_layout) [pat, rem] partial) + ~body ~mode:alloc_heap ~region:true in @@ -509,7 +527,8 @@ let rec transl_class_rebind ~scopes obj_init cl vf = let path, path_lam, obj_init = transl_class_rebind ~scopes obj_init cl vf in (path, path_lam, - Translcore.transl_let ~scopes rec_flag defs layout_obj obj_init) + Translcore.transl_let ~scopes ~return_layout:layout_obj rec_flag defs + obj_init) | Tcl_structure _ -> raise Exit | Tcl_constraint (cl', _, _, _, _) -> let path, path_lam, obj_init = @@ -531,7 +550,8 @@ let rec transl_class_rebind_0 ~scopes (self:Ident.t) obj_init cl vf = transl_class_rebind_0 ~scopes self obj_init cl vf in (path, path_lam, - Translcore.transl_let ~scopes rec_flag defs layout_obj obj_init) + Translcore.transl_let ~scopes ~return_layout:layout_obj rec_flag defs + obj_init) | _ -> let path, path_lam, obj_init = transl_class_rebind ~scopes obj_init cl vf in diff --git a/ocaml/lambda/translcore.ml b/ocaml/lambda/translcore.ml index 9e5c387eb68..da004126656 100644 --- a/ocaml/lambda/translcore.ml +++ b/ocaml/lambda/translcore.ml @@ -32,45 +32,31 @@ type error = | Unreachable_reached | Bad_probe_layout of Ident.t | Non_value_layout of Layout.Violation.t + | Void_sort of type_expr exception Error of Location.t * error let use_dup_for_constant_mutable_arrays_bigger_than = 4 -(* CR layouts v2: When we're ready to allow non-values, these can be deleted or - changed to check for void. *) -let sort_must_be_value ~why loc sort = - if not Sort.(equate sort value) then - let violation = Layout.(Violation.of_ (Not_a_sublayout - (of_sort ~why sort, - value ~why:V1_safety_check))) in - raise (Error (loc, Non_value_layout violation)) - let layout_must_be_value loc layout = match Layout.(sub layout (value ~why:V1_safety_check)) with | Ok _ -> () | Error e -> raise (Error (loc, Non_value_layout e)) -(* CR layouts v2: In the places where this is used, we want to allow any (the - left of a semicolon and loop bodies). So we want this instead of the usual - sanity check for value. But we still default to value before checking for - void, to allow for sort variables arising in situations like +(* CR layouts v2: In the places where this is used, we will want to allow + #float, but not void yet (e.g., the left of a semicolon and loop bodies). we + still default to value before checking for void, to allow for sort variables + arising in situations like let foo () = raise Foo; () When this sanity check is removed, consider whether we are still defaulting appropriately. *) -let layout_must_not_be_void loc layout = - Layout.default_to_value layout; - match Layout.(sub layout (void ~why:V1_safety_check)) with - | Ok _ -> - let violation = Layout.(Violation.of_ (Not_a_sublayout - (layout, value ~why:V1_safety_check))) in - raise (Error (loc, Non_value_layout violation)) - | Error _ -> () +let sort_must_not_be_void loc ty sort = + if Sort.is_void_defaulting sort then raise (Error (loc, Void_sort ty)) -let layout_exp e = layout e.exp_env e.exp_loc e.exp_type +let layout_exp sort e = layout e.exp_env e.exp_loc sort e.exp_type (* Forward declaration -- to be filled in by Translmod.transl_module *) let transl_module = @@ -95,7 +81,8 @@ let declare_probe_handlers lam = (* Compile an exception/extension definition *) let prim_fresh_oo_id = - Pccall (Primitive.simple ~name:"caml_fresh_oo_id" ~arity:1 ~alloc:false) + Pccall + (Primitive.simple_on_values ~name:"caml_fresh_oo_id" ~arity:1 ~alloc:false) let transl_extension_constructor ~scopes env path ext = let path = @@ -203,8 +190,8 @@ let maybe_region get_layout lam = let maybe_region_layout layout lam = maybe_region (fun () -> layout) lam -let maybe_region_exp exp lam = - maybe_region (fun () -> layout_exp exp) lam +let maybe_region_exp sort exp lam = + maybe_region (fun () -> layout_exp sort exp) lam (* Push the default values under the functional abstractions *) @@ -226,23 +213,30 @@ let rec trivial_pat pat = List.for_all trivial_pat patl | _ -> false -let rec push_defaults loc bindings use_lhs arg_mode cases partial warnings = +let rec push_defaults loc bindings use_lhs arg_mode arg_sort cases + partial warnings = match cases with [{c_lhs=pat; c_guard=None; c_rhs={exp_desc = Texp_function { arg_label; param; cases; partial; - region; curry; warnings; arg_mode; alloc_mode } } + region; curry; warnings; arg_mode; + arg_sort; ret_sort; alloc_mode } } as exp}] when bindings = [] || trivial_pat pat -> - let cases = push_defaults exp.exp_loc bindings false arg_mode cases partial warnings in + let cases = + push_defaults exp.exp_loc bindings false arg_mode arg_sort cases partial + warnings + in [{c_lhs=pat; c_guard=None; - c_rhs={exp with exp_desc = Texp_function { arg_label; param; cases; - partial; region; curry; warnings; arg_mode; alloc_mode }}}] + c_rhs={exp with exp_desc = + Texp_function { arg_label; param; cases; partial; + region; curry; warnings; arg_mode; + arg_sort; ret_sort; alloc_mode }}}] | [{c_lhs=pat; c_guard=None; c_rhs={exp_attributes=[{Parsetree.attr_name = {txt="#default"};_}]; exp_desc = Texp_let (Nonrecursive, binds, ({exp_desc = Texp_function _} as e2))}}] -> push_defaults loc (binds :: bindings) true - arg_mode [{c_lhs=pat;c_guard=None;c_rhs=e2}] + arg_mode arg_sort [{c_lhs=pat;c_guard=None;c_rhs=e2}] partial warnings | [{c_lhs=pat; c_guard=None; c_rhs=exp} as case] when use_lhs || trivial_pat pat && exp.exp_desc <> Texp_unreachable -> @@ -268,9 +262,7 @@ let rec push_defaults loc bindings use_lhs arg_mode cases partial warnings = Texp_ident (Path.Pident param, mknoloc (Longident.Lident name), desc, Id_value)}, - Sort.value, - (* CR layouts v2: Value here will changes when functions take other - layouts. Maybe we need a sort in [Typedtree.case]? *) + arg_sort, cases, partial) } in [{c_lhs = {pat with pat_desc = Tpat_var (param, mknoloc name, mode)}; @@ -321,11 +313,6 @@ let assert_failed ~scopes exp = Const_base(Const_int char)]))], loc))], loc) ;; -let rec cut n l = - if n = 0 then ([],l) else - match l with [] -> failwith "Translcore.cut" - | a::l -> let (l1,l2) = cut (n-1) l in (a::l1,l2) - (* Translation of expressions *) let rec iter_exn_names f pat = @@ -363,27 +350,25 @@ let can_apply_primitive p pmode pos args = end end -(* CR layouts v2: Invariant - this is only called on values. Relax that. *) -let rec transl_exp ~scopes e = - transl_exp1 ~scopes ~in_new_scope:false e +let rec transl_exp ~scopes sort e = + transl_exp1 ~scopes ~in_new_scope:false sort e (* ~in_new_scope tracks whether we just opened a new scope. We go to some trouble to avoid introducing many new anonymous function scopes, as `let f a b = ...` is desugared to several Pexp_fun. *) -(* CR layouts v2: Invariant - this is only called on values. Relax that. *) -and transl_exp1 ~scopes ~in_new_scope e = +and transl_exp1 ~scopes ~in_new_scope sort e = let eval_once = (* Whether classes for immediate objects must be cached *) match e.exp_desc with Texp_function _ | Texp_for _ | Texp_while _ -> false | _ -> true in - if eval_once then transl_exp0 ~scopes ~in_new_scope e else - Translobj.oo_wrap e.exp_env true (transl_exp0 ~scopes ~in_new_scope) e + if eval_once then transl_exp0 ~scopes ~in_new_scope sort e else + Translobj.oo_wrap e.exp_env true (transl_exp0 ~scopes ~in_new_scope sort) e -and transl_exp0 ~in_new_scope ~scopes e = +and transl_exp0 ~in_new_scope ~scopes sort e = match e.exp_desc with | Texp_ident(path, _, desc, kind) -> transl_ident (of_location ~scopes e.exp_loc) @@ -391,31 +376,32 @@ and transl_exp0 ~in_new_scope ~scopes e = | Texp_constant cst -> Lconst(Const_base cst) | Texp_let(rec_flag, pat_expr_list, body) -> - let body_layout = layout_exp body in - transl_let ~scopes rec_flag pat_expr_list - body_layout (event_before ~scopes body (transl_exp ~scopes body)) - | Texp_function { arg_label = _; param; cases; partial; - region; curry; warnings; arg_mode; alloc_mode } -> - (* CR ncourant: it would be better if we had [arg_layout] here *) - let arg_layout = - match is_function_type e.exp_env e.exp_type with - | None -> Misc.fatal_error "Translcore.transl_exp0: Type of a function is not a function type" - | Some (arg_type, _) -> - Typeopt.layout e.exp_env e.exp_loc arg_type - in + let return_layout = layout_exp sort body in + transl_let ~scopes ~return_layout rec_flag pat_expr_list + (event_before ~scopes body (transl_exp ~scopes sort body)) + | Texp_function { arg_label = _; param; cases; partial; region; curry; + warnings; arg_mode; arg_sort; ret_sort; alloc_mode } -> let scopes = if in_new_scope then scopes else enter_anonymous_function ~scopes in - transl_function ~scopes e alloc_mode param arg_mode arg_layout cases partial warnings region curry + transl_function ~scopes e alloc_mode param arg_mode arg_sort ret_sort + cases partial warnings region curry | Texp_apply({ exp_desc = Texp_ident(path, _, {val_kind = Val_prim p}, Id_prim pmode); exp_type = prim_type; } as funct, oargs, pos, alloc_mode) when can_apply_primitive p pmode pos oargs -> - let argl, extra_args = cut p.prim_arity oargs in - let arg_exps = - List.map (function _, Arg x -> x | _ -> assert false) argl + let rec cut_args prim_repr oargs = + match prim_repr, oargs with + | [], _ -> [], oargs + | _, [] -> failwith "Translcore cut_args" + | ((_, arg_repr) :: prim_repr), ((_, Arg (x, _)) :: oargs) -> + let arg_exps, extra_args = cut_args prim_repr oargs in + let arg_sort = Sort.of_const (sort_of_native_repr arg_repr) in + (x, arg_sort) :: arg_exps, extra_args + | _, ((_, Omitted _) :: _) -> assert false in + let arg_exps, extra_args = cut_args p.prim_native_repr_args oargs in let args = transl_list ~scopes arg_exps in let prim_exp = if extra_args = [] then Some e else None in let position = @@ -425,7 +411,7 @@ and transl_exp0 ~in_new_scope ~scopes e = let lam = Translprim.transl_primitive_application (of_location ~scopes e.exp_loc) p e.exp_env prim_type pmode - path prim_exp args arg_exps position + path prim_exp args (List.map fst arg_exps) position in if extra_args = [] then lam else begin @@ -434,7 +420,7 @@ and transl_exp0 ~in_new_scope ~scopes e = let specialised = Translattribute.get_specialised_attribute funct in let position = transl_apply_position pos in let mode = transl_alloc_mode alloc_mode in - let result_layout = layout_exp e in + let result_layout = layout_exp sort e in event_after ~scopes e (transl_apply ~scopes ~tailcall ~inlined ~specialised ~position ~mode ~result_layout lam extra_args (of_location ~scopes e.exp_loc)) @@ -443,24 +429,28 @@ and transl_exp0 ~in_new_scope ~scopes e = let tailcall = Translattribute.get_tailcall_attribute funct in let inlined = Translattribute.get_inlined_attribute funct in let specialised = Translattribute.get_specialised_attribute funct in - let result_layout = layout_exp e in + let result_layout = layout_exp sort e in let position = transl_apply_position position in let mode = transl_alloc_mode alloc_mode in event_after ~scopes e (transl_apply ~scopes ~tailcall ~inlined ~specialised ~result_layout - ~position ~mode (transl_exp ~scopes funct) + ~position ~mode (transl_exp ~scopes Sort.for_function funct) oargs (of_location ~scopes e.exp_loc)) - | Texp_match(arg, sort, pat_expr_list, partial) -> - transl_match ~scopes e arg sort pat_expr_list partial + | Texp_match(arg, arg_sort, pat_expr_list, partial) -> + transl_match ~scopes ~arg_sort ~return_sort:sort e arg pat_expr_list + partial | Texp_try(body, pat_expr_list) -> let id = Typecore.name_cases "exn" pat_expr_list in - let layout = layout_exp e in - Ltrywith(transl_exp ~scopes body, id, - Matching.for_trywith ~scopes layout e.exp_loc (Lvar id) - (transl_cases_try ~scopes pat_expr_list), - layout) + let return_layout = layout_exp sort e in + Ltrywith(transl_exp ~scopes sort body, id, + Matching.for_trywith ~scopes ~return_layout e.exp_loc (Lvar id) + (transl_cases_try ~scopes sort pat_expr_list), + return_layout) | Texp_tuple (el, alloc_mode) -> - let ll, shape = transl_list_with_shape ~scopes el in + let ll, shape = + transl_list_with_shape ~scopes + (List.map (fun a -> (a, Sort.for_tuple_element)) el) + in begin try Lconst(Const_block(0, List.map extract_constant ll)) with Not_constant -> @@ -470,7 +460,10 @@ and transl_exp0 ~in_new_scope ~scopes e = (of_location ~scopes e.exp_loc)) end | Texp_construct(_, cstr, args, alloc_mode) -> - let ll, shape = transl_list_with_shape ~scopes args in + let ll, shape = + transl_list_with_shape ~scopes + (List.map (fun a -> (a, Sort.for_constructor_arg)) args) + in if cstr.cstr_inlined <> None then begin match ll with | [x] -> x | _ -> assert false @@ -512,7 +505,7 @@ and transl_exp0 ~in_new_scope ~scopes e = begin match arg with None -> Lconst(const_int tag) | Some (arg, alloc_mode) -> - let lam = transl_exp ~scopes arg in + let lam = transl_exp ~scopes Sort.for_poly_variant arg in try Lconst(Const_block(0, [const_int tag; extract_constant lam])) @@ -527,7 +520,7 @@ and transl_exp0 ~in_new_scope ~scopes e = (Option.map transl_alloc_mode alloc_mode) fields representation extended_expression | Texp_field(arg, _, lbl, alloc_mode) -> - let targ = transl_exp ~scopes arg in + let targ = transl_exp ~scopes Sort.for_record arg in let sem = match lbl.lbl_mut with | Immutable -> Reads_agree @@ -562,12 +555,16 @@ and transl_exp0 ~in_new_scope ~scopes e = | Record_inlined (_, Variant_extensible) -> Psetfield (lbl.lbl_pos + 1, maybe_pointer newval, mode) in - Lprim(access, [transl_exp ~scopes arg; transl_exp ~scopes newval], + Lprim(access, [transl_exp ~scopes Sort.for_record arg; + transl_exp ~scopes Sort.for_record_field newval], of_location ~scopes e.exp_loc) | Texp_array (amut, expr_list, alloc_mode) -> let mode = transl_alloc_mode alloc_mode in let kind = array_kind e in - let ll = transl_list ~scopes expr_list in + let ll = + transl_list ~scopes + (List.map (fun e -> (e, Sort.for_array_element)) expr_list) + in let loc = of_location ~scopes e.exp_loc in let makearray mutability = Lprim (Pmakearray (kind, mutability, mode), ll, loc) @@ -642,35 +639,35 @@ and transl_exp0 ~in_new_scope ~scopes e = Transl_array_comprehension.comprehension ~transl_exp ~scopes ~loc ~array_kind comp | Texp_ifthenelse(cond, ifso, Some ifnot) -> - Lifthenelse(transl_exp ~scopes cond, - event_before ~scopes ifso (transl_exp ~scopes ifso), - event_before ~scopes ifnot (transl_exp ~scopes ifnot), - layout_exp e) + Lifthenelse(transl_exp ~scopes Sort.for_predef_value cond, + event_before ~scopes ifso (transl_exp ~scopes sort ifso), + event_before ~scopes ifnot (transl_exp ~scopes sort ifnot), + layout_exp sort e) | Texp_ifthenelse(cond, ifso, None) -> - Lifthenelse(transl_exp ~scopes cond, - event_before ~scopes ifso (transl_exp ~scopes ifso), + Lifthenelse(transl_exp ~scopes Sort.for_predef_value cond, + event_before ~scopes ifso (transl_exp ~scopes sort ifso), lambda_unit, Lambda.layout_unit) - | Texp_sequence(expr1, layout, expr2) -> - layout_must_not_be_void expr1.exp_loc layout; - Lsequence(transl_exp ~scopes expr1, - event_before ~scopes expr2 (transl_exp ~scopes expr2)) - | Texp_while {wh_body; wh_body_layout; wh_cond} -> - layout_must_not_be_void wh_body.exp_loc wh_body_layout; - let cond = transl_exp ~scopes wh_cond in - let body = transl_exp ~scopes wh_body in + | Texp_sequence(expr1, sort, expr2) -> + sort_must_not_be_void expr1.exp_loc expr1.exp_type sort; + Lsequence(transl_exp ~scopes sort expr1, + event_before ~scopes expr2 (transl_exp ~scopes sort expr2)) + | Texp_while {wh_body; wh_body_sort; wh_cond} -> + sort_must_not_be_void wh_body.exp_loc wh_body.exp_type wh_body_sort; + let cond = transl_exp ~scopes Sort.for_predef_value wh_cond in + let body = transl_exp ~scopes wh_body_sort wh_body in Lwhile { wh_cond = maybe_region_layout layout_int cond; wh_body = event_before ~scopes wh_body (maybe_region_layout layout_unit body); } - | Texp_for {for_id; for_from; for_to; for_dir; for_body; for_body_layout} -> - layout_must_not_be_void for_body.exp_loc for_body_layout; - let body = transl_exp ~scopes for_body in + | Texp_for {for_id; for_from; for_to; for_dir; for_body; for_body_sort} -> + sort_must_not_be_void for_body.exp_loc for_body.exp_type for_body_sort; + let body = transl_exp ~scopes for_body_sort for_body in Lfor { for_id; - for_from = transl_exp ~scopes for_from; - for_to = transl_exp ~scopes for_to; + for_from = transl_exp ~scopes Sort.for_predef_value for_from; + for_to = transl_exp ~scopes Sort.for_predef_value for_to; for_dir; for_body = event_before ~scopes for_body (maybe_region_layout layout_unit body); @@ -680,13 +677,13 @@ and transl_exp0 ~in_new_scope ~scopes e = let pos = transl_apply_position pos in let mode = transl_alloc_mode alloc_mode in let loc = of_location ~scopes e.exp_loc in - let layout = layout_exp e in + let layout = layout_exp sort e in match met with | Tmeth_val id -> - let obj = transl_exp ~scopes expr in + let obj = transl_exp ~scopes Sort.for_object expr in Lsend (Self, Lvar id, obj, [], pos, mode, loc, layout) | Tmeth_name nm -> - let obj = transl_exp ~scopes expr in + let obj = transl_exp ~scopes Sort.for_object expr in let (tag, cache) = Translobj.meth obj nm in let kind = if cache = [] then Public else Cached in Lsend (kind, tag, obj, cache, pos, mode, loc, layout) @@ -713,7 +710,7 @@ and transl_exp0 ~in_new_scope ~scopes e = Lprim(Pfield (0, Reads_vary), [transl_class_path loc e.exp_env cl], loc); ap_args=[lambda_unit]; - ap_result_layout=layout_exp e; + ap_result_layout=layout_exp sort e; ap_region_close=pos; ap_mode=alloc_heap; ap_tailcall=Default_tailcall; @@ -757,19 +754,20 @@ and transl_exp0 ~in_new_scope ~scopes e = | Texp_letmodule(None, loc, Mp_present, modl, body) -> let lam = !transl_module ~scopes Tcoerce_none None modl in Lsequence(Lprim(Pignore, [lam], of_location ~scopes loc.loc), - transl_exp ~scopes body) + transl_exp ~scopes sort body) | Texp_letmodule(Some id, _loc, Mp_present, modl, body) -> let defining_expr = let mod_scopes = enter_module_definition ~scopes id in !transl_module ~scopes:mod_scopes Tcoerce_none None modl in - Llet(Strict, Lambda.layout_module, id, defining_expr, transl_exp ~scopes body) + Llet(Strict, Lambda.layout_module, id, defining_expr, + transl_exp ~scopes sort body) | Texp_letmodule(_, _, Mp_absent, _, body) -> - transl_exp ~scopes body + transl_exp ~scopes sort body | Texp_letexception(cd, body) -> Llet(Strict, Lambda.layout_block, cd.ext_id, transl_extension_constructor ~scopes e.exp_env None cd, - transl_exp ~scopes body) + transl_exp ~scopes sort body) | Texp_pack modl -> !transl_module ~scopes Tcoerce_none None modl | Texp_assert {exp_desc=Texp_construct(_, {cstr_name="false"}, _, _)} -> @@ -779,7 +777,7 @@ and transl_exp0 ~in_new_scope ~scopes e = then lambda_unit else begin Lifthenelse - (transl_exp ~scopes cond, + (transl_exp ~scopes Sort.for_predef_value cond, lambda_unit, assert_failed ~scopes e, Lambda.layout_unit) @@ -792,14 +790,15 @@ and transl_exp0 ~in_new_scope ~scopes e = | `Constant_or_function -> (* A constant expr (of type <> float if [Config.flat_float_array] is true) gets compiled as itself. *) - transl_exp ~scopes e + transl_exp ~scopes Sort.for_lazy_body e | `Float_that_cannot_be_shortcut -> (* We don't need to wrap with Popaque: this forward block will never be shortcutted since it points to a float and Config.flat_float_array is true. *) Lprim(Pmakeblock(Obj.forward_tag, Immutable, None, alloc_heap), - [transl_exp ~scopes e], of_location ~scopes e.exp_loc) + [transl_exp ~scopes Sort.for_lazy_body e], + of_location ~scopes e.exp_loc) | `Identifier `Forward_value -> (* CR-someday mshinwell: Consider adding a new primitive that expresses the construction of forward_tag blocks. @@ -810,11 +809,11 @@ and transl_exp0 ~in_new_scope ~scopes e = Lprim (Popaque Lambda.layout_lazy, [Lprim(Pmakeblock(Obj.forward_tag, Immutable, None, alloc_heap), - [transl_exp ~scopes e], + [transl_exp ~scopes Sort.for_lazy_body e], of_location ~scopes e.exp_loc)], of_location ~scopes e.exp_loc) | `Identifier `Other -> - transl_exp ~scopes e + transl_exp ~scopes Sort.for_lazy_body e | `Other -> (* other cases compile to a lazy block holding a function. The typechecker enforces that e has layout value. *) @@ -828,7 +827,7 @@ and transl_exp0 ~in_new_scope ~scopes e = ~region:true ~body:(maybe_region_layout Lambda.layout_lazy_contents - (transl_exp ~scopes e)) + (transl_exp ~scopes Sort.for_lazy_body e)) in Lprim(Pmakeblock(Config.lazy_tag, Mutable, None, alloc_heap), [fn], of_location ~scopes e.exp_loc) @@ -843,10 +842,11 @@ and transl_exp0 ~in_new_scope ~scopes e = cl_env = e.exp_env; cl_attributes = []; } - | Texp_letop{let_; ands; param; body; partial; warnings} -> + | Texp_letop{let_; ands; param; param_sort; body; body_sort; partial; + warnings} -> event_after ~scopes e (transl_letop ~scopes e.exp_loc e.exp_env let_ ands - param body partial warnings) + param param_sort body body_sort partial warnings) | Texp_unreachable -> raise (Error (e.exp_loc, Unreachable_reached)) | Texp_open (od, e) -> @@ -856,7 +856,7 @@ and transl_exp0 ~in_new_scope ~scopes e = But since [scan_used_globals] runs before Simplif, we need to do it. *) begin match od.open_bound_items with - | [] when pure = Alias -> transl_exp ~scopes e + | [] when pure = Alias -> transl_exp ~scopes sort e | _ -> let oid = Ident.create_local "open" in let body, _ = @@ -868,7 +868,7 @@ and transl_exp0 ~in_new_scope ~scopes e = Lprim(mod_field pos, [Lvar oid], of_location ~scopes od.open_loc), body), pos + 1 - ) (transl_exp ~scopes e, 0) + ) (transl_exp ~scopes sort e, 0) (bound_value_identifiers od.open_bound_items) in Llet(pure, Lambda.layout_module, oid, @@ -876,7 +876,7 @@ and transl_exp0 ~in_new_scope ~scopes e = end | Texp_probe {name; handler=exp; enabled_at_init} -> if !Clflags.native_code && !Clflags.probes then begin - let lam = transl_exp ~scopes exp in + let lam = transl_exp ~scopes Sort.for_probe_body exp in let map = Ident.Set.fold (fun v acc -> Ident.Map.add v (Ident.rename v) acc) (free_variables lam) @@ -899,8 +899,7 @@ and transl_exp0 ~in_new_scope ~scopes e = (We could probably calculate the layouts of these variables here rather than requiring them all to be value, but that would be even - more hacky, and in any event we don't yet want to connect the - front-end layout support to the middle-end layout support). *) + more hacky.) *) (* CR layouts v2: if we get close to releasing other layout somebody actually might put in a probe, check with the middle-end team about the status of fixing this. *) @@ -934,14 +933,15 @@ and transl_exp0 ~in_new_scope ~scopes e = tmc_candidate = false; } in let funcid = Ident.create_local ("probe_handler_" ^ name) in - let layout = layout_exp exp in - (* CR ncourant: how do we get the layouts for the free variables? *) + let return_layout = layout_unit (* Probe bodies have type unit. *) in let handler = let scopes = enter_value_definition ~scopes funcid in lfunction ~kind:(Curried {nlocal=0}) - ~params:(List.map (fun v -> v, Lambda.layout_top) param_idents) - ~return:layout + (* CR layouts: Adjust param layouts when we allow other things in + probes. *) + ~params:(List.map (fun v -> v, layout_probe_arg) param_idents) + ~return:return_layout ~body ~loc:(of_location ~scopes exp.exp_loc) ~attr @@ -951,7 +951,7 @@ and transl_exp0 ~in_new_scope ~scopes e = let app = { ap_func = Lvar funcid; ap_args = List.map (fun id -> Lvar id) arg_idents; - ap_result_layout = layout; + ap_result_layout = return_layout; ap_region_close = Rc_normal; ap_mode = alloc_heap; ap_loc = of_location e.exp_loc ~scopes; @@ -982,7 +982,7 @@ and transl_exp0 ~in_new_scope ~scopes e = else lambda_unit | Texp_exclave e -> - let l = transl_exp ~scopes e in + let l = transl_exp ~scopes sort e in if Config.stack_allocation then Lexclave l else l @@ -992,62 +992,60 @@ and pure_module m = | Tmod_constraint (m,_,_,_) -> pure_module m | _ -> Strict -(* List elements must have layout value (this does not check). *) and transl_list ~scopes expr_list = - List.map (transl_exp ~scopes) expr_list + List.map (fun (exp, sort) -> transl_exp ~scopes sort exp) expr_list -(* Will raise if a list element has a non-value layout. *) and transl_list_with_layout ~scopes expr_list = - List.map (fun exp -> transl_exp ~scopes exp, layout_exp exp) expr_list + List.map (fun (exp, sort) -> transl_exp ~scopes sort exp, + sort, + layout_exp sort exp) + expr_list (* Will raise if a list element has a non-value layout. *) and transl_list_with_shape ~scopes expr_list = - let transl_with_shape e = - let shape = Lambda.must_be_value (layout_exp e) in - transl_exp ~scopes e, shape + let transl_with_shape (e, sort) = + let shape = Lambda.must_be_value (layout_exp sort e) in + transl_exp ~scopes sort e, shape in List.split (List.map transl_with_shape expr_list) -(* Will raise if rhs has a non-value layout *) -and transl_guard ~scopes guard rhs = - let layout = layout_exp rhs in - let expr = event_before ~scopes rhs (transl_exp ~scopes rhs) in +and transl_guard ~scopes guard rhs_sort rhs = + let layout = layout_exp rhs_sort rhs in + let expr = event_before ~scopes rhs (transl_exp ~scopes rhs_sort rhs) in match guard with | None -> expr | Some cond -> event_before ~scopes cond - (Lifthenelse(transl_exp ~scopes cond, expr, staticfail, layout)) + (Lifthenelse(transl_exp ~scopes Sort.for_predef_value cond, + expr, staticfail, layout)) -(* will raise if c_rhs has a non-value layout *) -and transl_case ~scopes {c_lhs; c_guard; c_rhs} = - c_lhs, transl_guard ~scopes c_guard c_rhs +and transl_case ~scopes rhs_sort {c_lhs; c_guard; c_rhs} = + c_lhs, transl_guard ~scopes c_guard rhs_sort c_rhs -(* will raise if any cases have a non-value rhs *) -and transl_cases ~scopes cases = +and transl_cases ~scopes rhs_sort cases = let cases = List.filter (fun c -> c.c_rhs.exp_desc <> Texp_unreachable) cases in - List.map (transl_case ~scopes) cases + List.map (transl_case ~scopes rhs_sort) cases -(* will raise if the case has a non-value rhs *) -and transl_case_try ~scopes {c_lhs; c_guard; c_rhs} = +and transl_case_try ~scopes rhs_sort {c_lhs; c_guard; c_rhs} = iter_exn_names Translprim.add_exception_ident c_lhs; Misc.try_finally - (fun () -> c_lhs, transl_guard ~scopes c_guard c_rhs) + (fun () -> c_lhs, transl_guard ~scopes c_guard rhs_sort c_rhs) ~always:(fun () -> iter_exn_names Translprim.remove_exception_ident c_lhs) -(* will raise if any cases have a non-value rhs *) -and transl_cases_try ~scopes cases = +and transl_cases_try ~scopes rhs_sort cases = let cases = List.filter (fun c -> c.c_rhs.exp_desc <> Texp_unreachable) cases in - List.map (transl_case_try ~scopes) cases + List.map (transl_case_try ~scopes rhs_sort) cases -(* will raise if any cases have a non-value rhs *) -and transl_tupled_cases ~scopes patl_expr_list = +and transl_tupled_cases ~scopes rhs_sort patl_expr_list = let patl_expr_list = List.filter (fun (_,_,e) -> e.exp_desc <> Texp_unreachable) patl_expr_list in - List.map (fun (patl, guard, expr) -> (patl, transl_guard ~scopes guard expr)) + List.map + (fun (patl, guard, expr) -> + (patl, transl_guard ~scopes guard rhs_sort expr)) patl_expr_list and transl_apply ~scopes @@ -1098,7 +1096,7 @@ and transl_apply ~scopes } in let rec build_apply lam args loc pos ap_mode = function - | Omitted { mode_closure; mode_arg; mode_ret; ty_arg; ty_env } :: l -> + | Omitted { mode_closure; mode_arg; mode_ret; sort_arg } :: l -> assert (pos = Rc_normal); let defs = ref [] in let protect name (lam, layout) = @@ -1141,7 +1139,7 @@ and transl_apply ~scopes | Alloc_local -> false | Alloc_heap -> true in - let layout_arg = Typeopt.layout ty_env (to_location loc) ty_arg in + let layout_arg = layout_of_sort (to_location loc) sort_arg in lfunction ~kind:(Curried {nlocal}) ~params:[id_arg, layout_arg] ~return:result_layout ~body ~mode ~region ~attr:default_stub_attribute ~loc @@ -1157,17 +1155,18 @@ and transl_apply ~scopes (fun (_, arg) -> match arg with | Omitted _ as arg -> arg - | Arg exp -> Arg (transl_exp ~scopes exp, layout_exp exp)) + | Arg (exp, sort_arg) -> + Arg (transl_exp ~scopes sort_arg exp, layout_exp sort_arg exp)) sargs in build_apply lam [] loc position mode args and transl_curried_function - ~scopes loc return - repr ~region ~curry partial warnings (param:Ident.t) arg_layout cases = + ~scopes ~arg_sort ~arg_layout ~return_sort ~return_layout loc repr ~region + ~curry partial warnings (param:Ident.t) cases = let max_arity = Lambda.max_arity () in - let rec loop ~scopes loc return ~arity ~region ~curry - partial warnings (param:Ident.t) arg_layout cases = + let rec loop ~scopes ~arg_sort ~arg_layout ~return_sort ~return_layout loc + ~arity ~region ~curry partial warnings (param:Ident.t) cases = match curry, cases with More_args {partial_mode}, [{c_lhs=pat; c_guard=None; @@ -1176,25 +1175,23 @@ and transl_curried_function { arg_label = _; param = param'; cases = cases'; partial = partial'; region = region'; curry = curry'; - warnings = warnings' }; + warnings = warnings'; arg_sort; ret_sort }; exp_env; exp_type; exp_loc }}] when arity < max_arity -> (* Lfunctions must have local returns after the first local arg/ret *) if Parmatch.inactive ~partial pat then let partial_mode = transl_alloc_mode partial_mode in - let return_layout = function_return_layout exp_env exp_loc exp_type in - let arg_layout' = - match is_function_type exp_env exp_type with - | None -> - Misc.fatal_error "Translcore.transl_curried_function: \ - Type of Texp_function is not function" - | Some (lhs, _) -> layout exp_env exp_loc lhs - in - let ((fnkind, params, return, region), body) = - loop ~scopes exp_loc return_layout - ~arity:(arity + 1) ~region:region' ~curry:curry' - partial' warnings' param' arg_layout' cases' + let ((fnkind, params, return_layout, region), body) = + let return_layout = + function_return_layout exp_env exp_loc ret_sort exp_type + in + let arg_layout = + function_arg_layout exp_env exp_loc arg_sort exp_type + in + loop ~scopes ~arg_sort ~arg_layout ~return_sort:ret_sort + ~return_layout exp_loc ~arity:(arity + 1) ~region:region' + ~curry:curry' partial' warnings' param' cases' in let fnkind = match partial_mode, fnkind with @@ -1207,9 +1204,9 @@ and transl_curried_function assert (nlocal = List.length params); Curried {nlocal = nlocal + 1} in - ((fnkind, (param, arg_layout) :: params, return, region), - Matching.for_function ~scopes return_layout loc None (Lvar param, arg_layout) - [pat, body] partial) + ((fnkind, (param, arg_layout) :: params, return_layout, region), + Matching.for_function ~scopes ~arg_sort ~arg_layout ~return_layout loc + None (Lvar param) [pat, body] partial) else begin begin match partial with | Total -> @@ -1220,19 +1217,20 @@ and transl_curried_function Warnings.restore prev | Partial -> () end; - transl_tupled_function ~scopes ~arity ~region ~curry - loc return repr partial param arg_layout cases + transl_tupled_function ~scopes ~arg_sort ~arg_layout + ~return_sort:ret_sort ~return_layout ~arity ~region ~curry loc repr + partial param cases end | curry, cases -> - transl_tupled_function ~scopes ~arity ~region ~curry - loc return repr partial param arg_layout cases + transl_tupled_function ~scopes ~arg_sort ~arg_layout ~return_sort + ~return_layout ~arity ~region ~curry loc repr partial param cases in - loop ~scopes loc return ~arity:1 ~region ~curry - partial warnings param arg_layout cases + loop ~scopes ~arg_sort ~arg_layout ~return_sort ~return_layout loc ~arity:1 + ~region ~curry partial warnings param cases and transl_tupled_function - ~scopes ~arity ~region ~curry loc return - repr partial (param:Ident.t) arg_layout cases = + ~scopes ~arg_layout ~arg_sort ~return_sort ~return_layout ~arity ~region + ~curry loc repr partial (param:Ident.t) cases = let partial_mode = match curry with | More_args {partial_mode} | Final_arg {partial_mode} -> @@ -1253,7 +1251,8 @@ and transl_tupled_function let kinds = match arg_layout with | Pvalue (Pvariant { consts = []; non_consts = [0, kinds] }) -> - (* CR layouts v2: to change when we have non-value args. *) + (* CR layouts v5: to change when we have non-value tuple + elements. *) List.map (fun vk -> Pvalue vk) kinds | _ -> Misc.fatal_error @@ -1265,24 +1264,24 @@ and transl_tupled_function in let params = List.map fst tparams in let body = - Matching.for_tupled_function ~scopes loc return params - (transl_tupled_cases ~scopes pats_expr_list) partial + Matching.for_tupled_function ~scopes ~return_layout loc params + (transl_tupled_cases ~scopes return_sort pats_expr_list) partial in let region = region || not (may_allocate_in_region body) in - ((Tupled, tparams, return, region), body) + ((Tupled, tparams, return_layout, region), body) with Matching.Cannot_flatten -> - transl_function0 ~scopes loc ~region ~partial_mode - return repr partial param arg_layout cases + transl_function0 ~scopes ~arg_sort ~arg_layout ~return_sort ~return_layout + loc ~region ~partial_mode repr partial param cases end - | _ -> transl_function0 ~scopes loc ~region ~partial_mode - return repr partial param arg_layout cases + | _ -> transl_function0 ~scopes ~arg_sort ~arg_layout ~return_sort + ~return_layout loc ~region ~partial_mode repr partial param cases and transl_function0 - ~scopes loc ~region ~partial_mode return - repr partial (param:Ident.t) arg_layout cases = + ~scopes ~arg_sort ~arg_layout ~return_sort ~return_layout loc ~region + ~partial_mode repr partial (param:Ident.t) cases = let body = - Matching.for_function ~scopes return loc repr (Lvar param, arg_layout) - (transl_cases ~scopes cases) partial + Matching.for_function ~scopes ~arg_sort ~arg_layout ~return_layout loc + repr (Lvar param) (transl_cases ~scopes return_sort cases) partial in let region = region || not (may_allocate_in_region body) in let nlocal = @@ -1291,19 +1290,26 @@ and transl_function0 | Alloc_local -> 1 | Alloc_heap -> 0 in - ((Curried {nlocal}, [param, arg_layout], return, region), body) + ((Curried {nlocal}, [param, arg_layout], return_layout, region), body) -and transl_function ~scopes e alloc_mode param arg_mode arg_layout cases partial warnings region curry = +and transl_function ~scopes e alloc_mode param arg_mode arg_sort return_sort + cases partial warnings region curry = let mode = transl_alloc_mode alloc_mode in + let arg_layout = + function_arg_layout e.exp_env e.exp_loc arg_sort e.exp_type + in let ((kind, params, return, region), body) = event_function ~scopes e (function repr -> - let pl = push_defaults e.exp_loc arg_mode cases partial warnings in + let pl = + push_defaults e.exp_loc arg_mode arg_sort cases partial warnings + in let return_layout = - function_return_layout e.exp_env e.exp_loc e.exp_type + function_return_layout e.exp_env e.exp_loc return_sort e.exp_type in - transl_curried_function ~scopes e.exp_loc return_layout - repr ~region ~curry partial warnings param arg_layout pl) + transl_curried_function ~arg_sort ~arg_layout ~return_sort + ~return_layout ~scopes e.exp_loc repr ~region ~curry partial warnings + param pl) in let attr = default_function_attribute in let loc = of_location ~scopes e.exp_loc in @@ -1324,13 +1330,11 @@ and transl_function ~scopes e alloc_mode param arg_mode arg_layout cases partial Translattribute.add_function_attributes lam e.exp_loc attrs (* Like transl_exp, but used when a new scope was just introduced. *) -(* CR layouts v2: Invariant - this is only called on values. Relax that. *) -and transl_scoped_exp ~scopes expr = - transl_exp1 ~scopes ~in_new_scope:true expr +and transl_scoped_exp ~scopes sort expr = + transl_exp1 ~scopes ~in_new_scope:true sort expr (* Decides whether a pattern binding should introduce a new scope. *) -(* CR layouts v2: Invariant - this is only called on values. Relax that. *) -and transl_bound_exp ~scopes ~in_structure pat expr = +and transl_bound_exp ~scopes ~in_structure pat sort expr = let should_introduce_scope = match expr.exp_desc with | Texp_function _ -> true @@ -1338,8 +1342,8 @@ and transl_bound_exp ~scopes ~in_structure pat expr = | _ -> false in match pat_bound_idents pat with | (id :: _) when should_introduce_scope -> - transl_scoped_exp ~scopes:(enter_value_definition ~scopes id) expr - | _ -> transl_exp ~scopes expr + transl_scoped_exp ~scopes:(enter_value_definition ~scopes id) sort expr + | _ -> transl_exp ~scopes sort expr (* Notice: transl_let consumes (ie compiles) its pat_expr_list argument, @@ -1347,8 +1351,8 @@ and transl_bound_exp ~scopes ~in_structure pat expr = This complication allows choosing any compilation order for the bindings and body of let constructs. *) -and transl_let ~scopes ?(add_regions=false) ?(in_structure=false) - rec_flag pat_expr_list body_kind = +and transl_let ~scopes ~return_layout ?(add_regions=false) ?(in_structure=false) + rec_flag pat_expr_list = match rec_flag with Nonrecursive -> let rec transl = function @@ -1356,15 +1360,15 @@ and transl_let ~scopes ?(add_regions=false) ?(in_structure=false) fun body -> body | {vb_pat=pat; vb_expr=expr; vb_sort=sort; vb_attributes=attr; vb_loc} :: rem -> - (* CR layouts v2: allow non-values. Either remove this or replace - with void-specific sanity check. *) - sort_must_be_value ~why:Let_binding expr.exp_loc sort; - let lam = transl_bound_exp ~scopes ~in_structure pat expr in + let lam = transl_bound_exp ~scopes ~in_structure pat sort expr in let lam = Translattribute.add_function_attributes lam vb_loc attr in - let lam = if add_regions then maybe_region_exp expr lam else lam in + let lam = + if add_regions then maybe_region_exp sort expr lam else lam + in let mk_body = transl rem in fun body -> - Matching.for_let ~scopes pat.pat_loc lam pat body_kind (mk_body body) + Matching.for_let ~scopes ~arg_sort:sort ~return_layout pat.pat_loc + lam pat (mk_body body) in transl pat_expr_list | Recursive -> @@ -1376,21 +1380,22 @@ and transl_let ~scopes ?(add_regions=false) ?(in_structure=false) pat_expr_list in let transl_case {vb_expr=expr; vb_sort; vb_attributes; vb_loc; vb_pat} id = - (* CR layouts v2: allow non-values. Either remove this or replace - with void-specific sanity check. *) - sort_must_be_value ~why:Let_binding expr.exp_loc vb_sort; - let lam = transl_bound_exp ~scopes ~in_structure vb_pat expr in + let lam = + transl_bound_exp ~scopes ~in_structure vb_pat vb_sort expr + in let lam = Translattribute.add_function_attributes lam vb_loc vb_attributes in - let lam = if add_regions then maybe_region_exp expr lam else lam in + let lam = + if add_regions then maybe_region_exp vb_sort expr lam else lam + in (id, lam) in let lam_bds = List.map2 transl_case pat_expr_list idlist in fun body -> Lletrec(lam_bds, body) and transl_setinstvar ~scopes loc self var expr = Lprim(Psetfield_computed (maybe_pointer expr, Assignment modify_heap), - [self; var; transl_exp ~scopes expr], loc) + [self; var; transl_exp ~scopes Sort.for_instance_var expr], loc) (* CR layouts v5: Invariant - this is only called on values. Relax that. *) and transl_record ~scopes loc env mode fields repres opt_init_expr = @@ -1414,7 +1419,9 @@ and transl_record ~scopes loc env mode fields repres opt_init_expr = (fun i (lbl, definition) -> match definition with | Kept typ -> - let field_kind = must_be_value (layout env lbl.lbl_loc typ) in + let field_kind = + must_be_value (layout env lbl.lbl_loc Sort.for_record_field typ) + in let sem = match lbl.lbl_mut with | Immutable -> Reads_agree @@ -1435,8 +1442,10 @@ and transl_record ~scopes loc env mode fields repres opt_init_expr = of_location ~scopes loc), field_kind | Overridden (_lid, expr) -> - let field_kind = must_be_value (layout_exp expr) in - transl_exp ~scopes expr, field_kind) + let field_kind = + must_be_value (layout_exp Sort.for_record_field expr) + in + transl_exp ~scopes Sort.for_record_field expr, field_kind) fields in let ll, shape = List.split (Array.to_list lv) in @@ -1482,7 +1491,7 @@ and transl_record ~scopes loc env mode fields repres opt_init_expr = begin match opt_init_expr with None -> lam | Some init_expr -> Llet(Strict, Lambda.layout_block, init_id, - transl_exp ~scopes init_expr, lam) + transl_exp ~scopes Sort.for_record init_expr, lam) end end else begin (* Take a shallow copy of the init record, then mutate the fields @@ -1510,7 +1519,8 @@ and transl_record ~scopes loc env mode fields repres opt_init_expr = let ptr = maybe_pointer expr in Psetfield(pos, ptr, Assignment modify_heap) in - Lsequence(Lprim(upd, [Lvar copy_id; transl_exp ~scopes expr], + Lsequence(Lprim(upd, [Lvar copy_id; + transl_exp ~scopes Sort.for_record_field expr], of_location ~scopes loc), cont) in @@ -1519,14 +1529,15 @@ and transl_record ~scopes loc env mode fields repres opt_init_expr = | Some init_expr -> assert (is_heap_mode (Option.get mode)); (* Pduprecord must be Alloc_heap and not unboxed *) Llet(Strict, Lambda.layout_block, copy_id, - Lprim(Pduprecord (repres, size), [transl_exp ~scopes init_expr], + Lprim(Pduprecord (repres, size), + [transl_exp ~scopes Sort.for_record init_expr], of_location ~scopes loc), Array.fold_left update_field (Lvar copy_id) fields) end end -and transl_match ~scopes e arg sort pat_expr_list partial = - let layout = layout_exp e in +and transl_match ~scopes ~arg_sort ~return_sort e arg pat_expr_list partial = + let return_layout = layout_exp arg_sort e in let rewrite_case (val_cases, exn_cases, static_handlers as acc) ({ c_lhs; c_guard; c_rhs } as case) = if c_rhs.exp_desc = Texp_unreachable then acc else @@ -1535,11 +1546,13 @@ and transl_match ~scopes e arg sort pat_expr_list partial = | None, None -> assert false | Some pv, None -> let val_case = - transl_case ~scopes { case with c_lhs = pv } + transl_case ~scopes return_sort { case with c_lhs = pv } in val_case :: val_cases, exn_cases, static_handlers | None, Some pe -> - let exn_case = transl_case_try ~scopes { case with c_lhs = pe } in + let exn_case = + transl_case_try ~scopes return_sort { case with c_lhs = pe } + in val_cases, exn_case :: exn_cases, static_handlers | Some pv, Some pe -> assert (c_guard = None); @@ -1549,11 +1562,11 @@ and transl_match ~scopes e arg sort pat_expr_list partial = in (* Simplif doesn't like it if binders are not uniq, so we make sure to use different names in the value and the exception branches. *) - let ids_full = Typedtree.pat_bound_idents_full sort pv in + let ids_full = Typedtree.pat_bound_idents_full arg_sort pv in let ids = List.map (fun (id, _, _, _) -> id) ids_full in let ids_kinds = - List.map (fun (id, {Location.loc; _}, ty, _) -> - id, Typeopt.layout pv.pat_env loc ty) + List.map (fun (id, {Location.loc; _}, ty, s) -> + id, Typeopt.layout pv.pat_env loc s ty) ids_full in let vids = List.map Ident.rename ids in @@ -1563,7 +1576,7 @@ and transl_match ~scopes e arg sort pat_expr_list partial = let rhs = Misc.try_finally (fun () -> event_before ~scopes c_rhs - (transl_exp ~scopes c_rhs)) + (transl_exp ~scopes return_sort c_rhs)) ~always:(fun () -> iter_exn_names Translprim.remove_exception_ident pe) in @@ -1597,51 +1610,54 @@ and transl_match ~scopes e arg sort pat_expr_list partial = let static_exception_id = next_raise_count () in Lstaticcatch (Ltrywith (Lstaticraise (static_exception_id, scrutinees), id, - Matching.for_trywith ~scopes layout e.exp_loc (Lvar id) exn_cases, - layout), + Matching.for_trywith ~scopes ~return_layout e.exp_loc (Lvar id) + exn_cases, + return_layout), (static_exception_id, val_ids), handler, - layout) + return_layout) in let classic = match arg, exn_cases with | {exp_desc = Texp_tuple (argl, alloc_mode)}, [] -> assert (static_handlers = []); let mode = transl_alloc_mode alloc_mode in - Matching.for_multiple_match ~scopes layout e.exp_loc + let argl = List.map (fun a -> (a, Sort.for_tuple_element)) argl in + Matching.for_multiple_match ~scopes ~return_layout e.exp_loc (transl_list_with_layout ~scopes argl) mode val_cases partial | {exp_desc = Texp_tuple (argl, alloc_mode)}, _ :: _ -> - let val_ids = + let argl = List.map (fun a -> (a, Sort.for_tuple_element)) argl in + let val_ids, lvars = List.map - (fun arg -> Typecore.name_pattern "val" [], layout_exp arg) + (fun (arg,s) -> + let layout = layout_exp s arg in + let id = Typecore.name_pattern "val" [] in + (id, layout), (Lvar id, s, layout)) argl + |> List.split in - let lvars = List.map (fun (id, layout) -> Lvar id, layout) val_ids in let mode = transl_alloc_mode alloc_mode in static_catch (transl_list ~scopes argl) val_ids - (Matching.for_multiple_match ~scopes layout e.exp_loc + (Matching.for_multiple_match ~scopes ~return_layout e.exp_loc lvars mode val_cases partial) | arg, [] -> assert (static_handlers = []); - let k = layout_exp arg in - Matching.for_function ~scopes layout e.exp_loc - None (transl_exp ~scopes arg, k) val_cases partial + let arg_layout = layout_exp arg_sort arg in + Matching.for_function ~scopes ~arg_sort ~arg_layout ~return_layout + e.exp_loc None (transl_exp ~scopes arg_sort arg) val_cases partial | arg, _ :: _ -> let val_id = Typecore.name_pattern "val" (List.map fst val_cases) in - let k = layout_exp arg in - static_catch [transl_exp ~scopes arg] [val_id, k] - (Matching.for_function ~scopes layout e.exp_loc - None (Lvar val_id, k) val_cases partial) + let arg_layout = layout_exp arg_sort arg in + static_catch [transl_exp ~scopes arg_sort arg] [val_id, arg_layout] + (Matching.for_function ~scopes ~arg_sort ~arg_layout ~return_layout + e.exp_loc None (Lvar val_id) val_cases partial) in List.fold_left (fun body (static_exception_id, val_ids, handler) -> - Lstaticcatch (body, (static_exception_id, val_ids), handler, layout) + Lstaticcatch (body, (static_exception_id, val_ids), handler, return_layout) ) classic static_handlers -and transl_letop ~scopes loc env let_ ands param case partial warnings = - (* CR layouts: The typechecker is currently enforcing that everything here has - layout value, but we might want to relax that when we allow non-value - function args and returns, and then this code would need to be - revisited. *) +and transl_letop ~scopes loc env let_ ands param param_sort case case_sort + partial warnings = let rec loop prev_layout prev_lam = function | [] -> prev_lam | and_ :: rest -> @@ -1651,10 +1667,11 @@ and transl_letop ~scopes loc env let_ ands param case partial warnings = transl_ident (of_location ~scopes and_.bop_op_name.loc) env and_.bop_op_type and_.bop_op_path and_.bop_op_val Id_value in - let exp = transl_exp ~scopes and_.bop_exp in - let right_layout = layout_exp and_.bop_exp in + let exp = transl_exp ~scopes Sort.for_bop_exp and_.bop_exp in + let right_layout = layout_exp Sort.for_bop_exp and_.bop_exp in let result_layout = - function2_return_layout env and_.bop_loc and_.bop_op_type + function2_return_layout env and_.bop_loc and_.bop_op_return_sort + and_.bop_op_type in let lam = bind_with_layout Strict (right_id, right_layout) exp @@ -1678,7 +1695,8 @@ and transl_letop ~scopes loc env let_ ands param case partial warnings = let_.bop_op_type let_.bop_op_path let_.bop_op_val Id_value in let exp = - loop (layout_exp let_.bop_exp) (transl_exp ~scopes let_.bop_exp) ands + loop (layout_exp Sort.for_bop_exp let_.bop_exp) + (transl_exp ~scopes Sort.for_bop_exp let_.bop_exp) ands in let func = let arg_layout = @@ -1691,21 +1709,16 @@ and transl_letop ~scopes loc env let_ ands param case partial warnings = | None -> Misc.fatal_error "Translcore.transl_letop: letop should have at least two arguments" - | Some (lhs, _) -> - match Typeopt.is_function_type env lhs with - | None -> - Misc.fatal_error - "Translcore.transl_letop: letop second argument should be a function" - | Some (arg_type, _) -> - Typeopt.layout env loc arg_type + | Some (lhs, _) -> Typeopt.function_arg_layout env loc param_sort lhs in - let return_layout = layout_exp case.c_rhs in + let return_layout = layout_exp case_sort case.c_rhs in let curry = More_args { partial_mode = Alloc_mode.global } in let (kind, params, return, _region), body = event_function ~scopes case.c_rhs (function repr -> - transl_curried_function ~scopes case.c_rhs.exp_loc return_layout - repr ~region:true ~curry partial warnings param arg_layout [case]) + transl_curried_function ~scopes ~arg_sort:param_sort ~arg_layout + ~return_sort:case_sort ~return_layout case.c_rhs.exp_loc repr + ~region:true ~curry partial warnings param [case]) in let attr = default_function_attribute in let loc = of_location ~scopes case.c_rhs.exp_loc in @@ -1717,7 +1730,9 @@ and transl_letop ~scopes loc env let_ ands param case partial warnings = ap_loc = of_location ~scopes loc; ap_func = op; ap_args=[exp; func]; - ap_result_layout=function2_return_layout env let_.bop_loc let_.bop_op_type; + ap_result_layout= + function2_return_layout env let_.bop_loc let_.bop_op_return_sort + let_.bop_op_type; ap_region_close=Rc_normal; ap_mode=alloc_heap; ap_tailcall = Default_tailcall; @@ -1729,14 +1744,15 @@ and transl_letop ~scopes loc env let_ ands param case partial warnings = (* Wrapper for class/module compilation, that can only return global values *) -let transl_exp ~scopes exp = - maybe_region_exp exp (transl_exp ~scopes exp) +let transl_exp ~scopes sort exp = + maybe_region_exp sort exp (transl_exp ~scopes sort exp) -let transl_let ~scopes ?in_structure rec_flag pat_expr_list = - transl_let ~scopes ~add_regions:true ?in_structure rec_flag pat_expr_list +let transl_let ~scopes ~return_layout ?in_structure rec_flag pat_expr_list = + transl_let ~scopes ~return_layout ~add_regions:true ?in_structure rec_flag + pat_expr_list -let transl_scoped_exp ~scopes exp = - maybe_region_exp exp (transl_scoped_exp ~scopes exp) +let transl_scoped_exp ~scopes sort exp = + maybe_region_exp sort exp (transl_scoped_exp ~scopes sort exp) let transl_apply ~scopes ?tailcall ?inlined ?specialised ?position ?mode ~result_layout fn args loc = @@ -1761,6 +1777,11 @@ let report_error ppf = function "Non-value detected in translation:@ Please report this error to \ the Jane Street compilers team.@ %a" (Layout.Violation.report_with_name ~name:"This expression") err + | Void_sort ty -> + fprintf ppf + "Void detected in translation for type %a:@ Please report this error \ + to the Jane Street compilers team." + Printtyp.type_expr ty let () = Location.register_error_of_exn diff --git a/ocaml/lambda/translcore.mli b/ocaml/lambda/translcore.mli index d78490bdba6..e08849a27a4 100644 --- a/ocaml/lambda/translcore.mli +++ b/ocaml/lambda/translcore.mli @@ -23,10 +23,8 @@ open Debuginfo.Scoped_location val pure_module : module_expr -> let_kind -(* Used for translating Alloc_heap values in classes and modules. [transl_exp] - and [transl_scoped_exp] must be called on expressions whose types have sort - value. *) -val transl_exp: scopes:scopes -> expression -> lambda +(* Used for translating Alloc_heap values in classes and modules. *) +val transl_exp: scopes:scopes -> Layouts.sort -> expression -> lambda val transl_apply: scopes:scopes -> ?tailcall:tailcall_attribute -> ?inlined:inlined_attribute @@ -37,20 +35,21 @@ val transl_apply: scopes:scopes -> lambda -> (arg_label * apply_arg) list -> scoped_location -> lambda -val transl_let: scopes:scopes -> ?in_structure:bool - -> rec_flag -> value_binding list -> layout -> lambda -> lambda +val transl_let: scopes:scopes -> return_layout:layout -> ?in_structure:bool + -> rec_flag -> value_binding list -> lambda -> lambda val transl_extension_constructor: scopes:scopes -> Env.t -> Longident.t option -> extension_constructor -> lambda -val transl_scoped_exp : scopes:scopes -> expression -> lambda +val transl_scoped_exp : scopes:scopes -> Layouts.sort -> expression -> lambda type error = Free_super_var | Unreachable_reached | Bad_probe_layout of Ident.t | Non_value_layout of Layouts.Layout.Violation.t + | Void_sort of Types.type_expr exception Error of Location.t * error diff --git a/ocaml/lambda/translmod.ml b/ocaml/lambda/translmod.ml index ccbcfd1a199..c63d5595181 100644 --- a/ocaml/lambda/translmod.ml +++ b/ocaml/lambda/translmod.ml @@ -261,7 +261,7 @@ let record_primitive = function let preallocate_letrec ~bindings ~body = assert (Clflags.is_flambda2 ()); let caml_update_dummy_prim = - Primitive.simple ~name:"caml_update_dummy" ~arity:2 ~alloc:true + Primitive.simple_on_values ~name:"caml_update_dummy" ~arity:2 ~alloc:true in let update_dummy var expr = Lprim (Pccall caml_update_dummy_prim, [Lvar var; expr], Loc_unknown) @@ -275,7 +275,8 @@ let preallocate_letrec ~bindings ~body = List.fold_left (fun body (id, _def, size) -> let desc = - Primitive.simple ~name:"caml_alloc_dummy" ~arity:1 ~alloc:true + Primitive.simple_on_values ~name:"caml_alloc_dummy" ~arity:1 + ~alloc:true in let size : lambda = Lconst (Const_base (Const_int size)) in Llet (Strict, Lambda.layout_block, id, @@ -617,7 +618,8 @@ and transl_module ~scopes cc rootpath mexp = | Tmod_constraint(arg, _, _, ccarg) -> transl_module ~scopes (compose_coercions cc ccarg) rootpath arg | Tmod_unpack(arg, _) -> - apply_coercion loc Strict cc (Translcore.transl_exp ~scopes arg) + apply_coercion loc Strict cc + (Translcore.transl_exp ~scopes Sort.for_module arg) and transl_struct ~scopes loc fields cc rootpath {str_final_env; str_items; _} = transl_structure ~scopes loc fields cc rootpath str_final_env str_items @@ -684,12 +686,12 @@ and transl_structure ~scopes loc fields cc rootpath final_env = function transl_structure ~scopes loc fields cc rootpath final_env rem in sort_must_not_be_void expr.exp_loc expr.exp_type sort; - Lsequence(transl_exp ~scopes expr, body), size + Lsequence(transl_exp ~scopes sort expr, body), size | Tstr_value(rec_flag, pat_expr_list) -> (* Translate bindings first *) let mk_lam_let = - transl_let ~scopes ~in_structure:true rec_flag pat_expr_list - Lambda.layout_module_field + transl_let ~scopes ~return_layout:Lambda.layout_module_field + ~in_structure:true rec_flag pat_expr_list in let ext_fields = List.rev_append (let_bound_idents pat_expr_list) fields in @@ -1119,14 +1121,14 @@ let transl_store_structure ~scopes glob map prims aliases str = | Tstr_eval (expr, sort, _attrs) -> sort_must_not_be_void expr.exp_loc expr.exp_type sort; Lsequence(Lambda.subst no_env_update subst - (transl_exp ~scopes expr), + (transl_exp ~scopes sort expr), transl_store ~scopes rootpath subst cont rem) | Tstr_value(rec_flag, pat_expr_list) -> let ids = let_bound_idents pat_expr_list in let lam = - transl_let ~scopes ~in_structure:true rec_flag pat_expr_list - Lambda.layout_unit - (store_idents Loc_unknown ids) + transl_let ~scopes ~return_layout:Lambda.layout_unit + ~in_structure:true rec_flag pat_expr_list + (store_idents Loc_unknown ids) in Lsequence(Lambda.subst no_env_update subst lam, transl_store ~scopes rootpath @@ -1516,7 +1518,7 @@ let transl_store_gen ~scopes module_name ({ str_items = str }, restr) topl = assert (size = 0); sort_must_not_be_void expr.exp_loc expr.exp_type sort; Lambda.subst (fun _ _ env -> env) !transl_store_subst - (transl_exp ~scopes expr) + (transl_exp ~scopes sort expr) | str -> transl_store_structure ~scopes module_name map prims aliases str in @@ -1617,15 +1619,15 @@ let transl_toplevel_item ~scopes item = unit. *) Tstr_eval (expr, sort, _) -> sort_must_not_be_void expr.exp_loc expr.exp_type sort; - transl_exp ~scopes expr + transl_exp ~scopes sort expr | Tstr_value(Nonrecursive, - [{vb_pat = {pat_desc=Tpat_any};vb_expr = expr}]) -> - transl_exp ~scopes expr + [{vb_pat = {pat_desc=Tpat_any}; vb_expr = expr; + vb_sort = sort}]) -> + transl_exp ~scopes sort expr | Tstr_value(rec_flag, pat_expr_list) -> let idents = let_bound_idents pat_expr_list in - transl_let ~scopes ~in_structure:true rec_flag pat_expr_list - Lambda.layout_unit - (make_sequence toploop_setvalue_id idents) + transl_let ~scopes ~return_layout:Lambda.layout_unit ~in_structure:true + rec_flag pat_expr_list (make_sequence toploop_setvalue_id idents) | Tstr_typext(tyext) -> let idents = List.map (fun ext -> ext.ext_id) tyext.tyext_constructors diff --git a/ocaml/lambda/translobj.ml b/ocaml/lambda/translobj.ml index c04fa8089e1..6f491bbd794 100644 --- a/ocaml/lambda/translobj.ml +++ b/ocaml/lambda/translobj.ml @@ -83,8 +83,9 @@ let reset_labels () = let int n = Lconst (Const_base (Const_int n)) +(* CR layouts v5: To change when we have arrays of other sorts *) let prim_makearray = - Primitive.simple ~name:"caml_make_vect" ~arity:2 ~alloc:true + Primitive.simple_on_values ~name:"caml_make_vect" ~arity:2 ~alloc:true (* Also use it for required globals *) let transl_label_init_general f = diff --git a/ocaml/lambda/translprim.ml b/ocaml/lambda/translprim.ml index c3a87af2a8c..b3dd12b3c92 100644 --- a/ocaml/lambda/translprim.ml +++ b/ocaml/lambda/translprim.ml @@ -18,6 +18,7 @@ open Asttypes open Primitive open Types +open Layouts open Typedtree open Typeopt open Lambda @@ -121,7 +122,7 @@ let gen_array_set_kind mode = if Config.flat_float_array then Pgenarray_set mode else Paddrarray_set mode let prim_sys_argv = - Primitive.simple ~name:"caml_sys_argv" ~arity:1 ~alloc:true + Primitive.simple_on_values ~name:"caml_sys_argv" ~arity:1 ~alloc:true let to_alloc_mode ~poly = function | Prim_global, _ -> alloc_heap @@ -572,7 +573,8 @@ let specialize_primitive env loc ty ~has_constant_constructor prim = | Primitive (Pmakeblock(tag, mut, None, mode), arity), fields -> begin let shape = List.map (fun typ -> - Lambda.must_be_value (Typeopt.layout env (to_location loc) typ)) + Lambda.must_be_value (Typeopt.layout env (to_location loc) + Sort.for_block_element typ)) fields in let useful = List.exists (fun knd -> knd <> Pgenval) shape in @@ -606,47 +608,51 @@ let specialize_primitive env loc ty ~has_constant_constructor prim = | _ -> None let caml_equal = - Primitive.simple ~name:"caml_equal" ~arity:2 ~alloc:true + Primitive.simple_on_values ~name:"caml_equal" ~arity:2 ~alloc:true let caml_string_equal = - Primitive.simple ~name:"caml_string_equal" ~arity:2 ~alloc:false + Primitive.simple_on_values ~name:"caml_string_equal" ~arity:2 ~alloc:false let caml_bytes_equal = - Primitive.simple ~name:"caml_bytes_equal" ~arity:2 ~alloc:false + Primitive.simple_on_values ~name:"caml_bytes_equal" ~arity:2 ~alloc:false let caml_notequal = - Primitive.simple ~name:"caml_notequal" ~arity:2 ~alloc:true + Primitive.simple_on_values ~name:"caml_notequal" ~arity:2 ~alloc:true let caml_string_notequal = - Primitive.simple ~name:"caml_string_notequal" ~arity:2 ~alloc:false + Primitive.simple_on_values ~name:"caml_string_notequal" ~arity:2 ~alloc:false let caml_bytes_notequal = - Primitive.simple ~name:"caml_bytes_notequal" ~arity:2 ~alloc:false + Primitive.simple_on_values ~name:"caml_bytes_notequal" ~arity:2 ~alloc:false let caml_lessequal = - Primitive.simple ~name:"caml_lessequal" ~arity:2 ~alloc:true + Primitive.simple_on_values ~name:"caml_lessequal" ~arity:2 ~alloc:true let caml_string_lessequal = - Primitive.simple ~name:"caml_string_lessequal" ~arity:2 ~alloc:false + Primitive.simple_on_values ~name:"caml_string_lessequal" ~arity:2 ~alloc:false let caml_bytes_lessequal = - Primitive.simple ~name:"caml_bytes_lessequal" ~arity:2 ~alloc:false + Primitive.simple_on_values ~name:"caml_bytes_lessequal" ~arity:2 ~alloc:false let caml_lessthan = - Primitive.simple ~name:"caml_lessthan" ~arity:2 ~alloc:true + Primitive.simple_on_values ~name:"caml_lessthan" ~arity:2 ~alloc:true let caml_string_lessthan = - Primitive.simple ~name:"caml_string_lessthan" ~arity:2 ~alloc:false + Primitive.simple_on_values ~name:"caml_string_lessthan" ~arity:2 ~alloc:false let caml_bytes_lessthan = - Primitive.simple ~name:"caml_bytes_lessthan" ~arity:2 ~alloc:false + Primitive.simple_on_values ~name:"caml_bytes_lessthan" ~arity:2 ~alloc:false let caml_greaterequal = - Primitive.simple ~name:"caml_greaterequal" ~arity:2 ~alloc:true + Primitive.simple_on_values ~name:"caml_greaterequal" ~arity:2 ~alloc:true let caml_string_greaterequal = - Primitive.simple ~name:"caml_string_greaterequal" ~arity:2 ~alloc:false + Primitive.simple_on_values ~name:"caml_string_greaterequal" ~arity:2 + ~alloc:false let caml_bytes_greaterequal = - Primitive.simple ~name:"caml_bytes_greaterequal" ~arity:2 ~alloc:false + Primitive.simple_on_values ~name:"caml_bytes_greaterequal" ~arity:2 + ~alloc:false let caml_greaterthan = - Primitive.simple ~name:"caml_greaterthan" ~arity:2 ~alloc:true + Primitive.simple_on_values ~name:"caml_greaterthan" ~arity:2 ~alloc:true let caml_string_greaterthan = - Primitive.simple ~name:"caml_string_greaterthan" ~arity:2 ~alloc: false + Primitive.simple_on_values ~name:"caml_string_greaterthan" ~arity:2 + ~alloc:false let caml_bytes_greaterthan = - Primitive.simple ~name:"caml_bytes_greaterthan" ~arity:2 ~alloc: false + Primitive.simple_on_values ~name:"caml_bytes_greaterthan" ~arity:2 + ~alloc:false let caml_compare = - Primitive.simple ~name:"caml_compare" ~arity:2 ~alloc:true + Primitive.simple_on_values ~name:"caml_compare" ~arity:2 ~alloc:true let caml_string_compare = - Primitive.simple ~name:"caml_string_compare" ~arity:2 ~alloc:false + Primitive.simple_on_values ~name:"caml_string_compare" ~arity:2 ~alloc:false let caml_bytes_compare = - Primitive.simple ~name:"caml_bytes_compare" ~arity:2 ~alloc:false + Primitive.simple_on_values ~name:"caml_bytes_compare" ~arity:2 ~alloc:false let comparison_primitive comparison comparison_kind = match comparison, comparison_kind with @@ -747,7 +753,8 @@ let lambda_of_loc kind sloc = Lconst (Const_immstring scope_name) let caml_restore_raw_backtrace = - Primitive.simple ~name:"caml_restore_raw_backtrace" ~arity:2 ~alloc:false + Primitive.simple_on_values ~name:"caml_restore_raw_backtrace" ~arity:2 + ~alloc:false let try_ids = Hashtbl.create 8 @@ -880,19 +887,27 @@ let transl_primitive loc p env ty ~poly_mode path = | None -> prim | Some prim -> prim in - let rec make_params ty n = - if n <= 0 then [], Typeopt.layout env (to_location loc) ty - else + let rec make_params ty repr_args repr_res = + match repr_args, repr_res with + | [], (_, res_repr) -> + let res_sort = sort_of_native_repr res_repr in + [], Typeopt.layout env (to_location loc) (Sort.of_const res_sort) ty + | ((_, arg_repr) :: repr_args), _ -> match Typeopt.is_function_type env ty with | None -> Misc.fatal_errorf "Primitive %s type does not correspond to arity" (Primitive.byte_name p) | Some (arg_ty, ret_ty) -> - let arg_layout = Typeopt.layout env (to_location loc) arg_ty in - let params, return = make_params ret_ty (n-1) in + let arg_sort = sort_of_native_repr arg_repr in + let arg_layout = + Typeopt.layout env (to_location loc) (Sort.of_const arg_sort) arg_ty + in + let params, return = make_params ret_ty repr_args repr_res in (Ident.create_local "prim", arg_layout) :: params, return in - let params, return = make_params ty p.prim_arity in + let params, return = + make_params ty p.prim_native_repr_args p.prim_native_repr_res + in let args = List.map (fun (id, _) -> Lvar id) params in match params with | [] -> lambda_of_prim p.prim_name prim loc args None diff --git a/ocaml/middle_end/convert_primitives.ml b/ocaml/middle_end/convert_primitives.ml index 7cc2e8a324c..43fab009bb4 100644 --- a/ocaml/middle_end/convert_primitives.ml +++ b/ocaml/middle_end/convert_primitives.ml @@ -152,8 +152,8 @@ let convert (prim : Lambda.primitive) : Clambda_primitives.primitive = ~effects:Only_generative_effects ~coeffects:Has_coeffects ~native_name:"caml_obj_dup" - ~native_repr_args:[P.Prim_global, P.Same_as_ocaml_repr] - ~native_repr_res:(P.Prim_global, P.Same_as_ocaml_repr)) + ~native_repr_args:[P.Prim_global, P.Same_as_ocaml_repr Layouts.Sort.Value] + ~native_repr_res:(P.Prim_global, P.Same_as_ocaml_repr Layouts.Sort.Value)) | Punbox_float -> Punbox_float | Pbox_float m -> Pbox_float m | Punbox_int bi -> Punbox_int bi diff --git a/ocaml/middle_end/flambda/flambda_to_clambda.ml b/ocaml/middle_end/flambda/flambda_to_clambda.ml index 591e91da625..7a337694c12 100644 --- a/ocaml/middle_end/flambda/flambda_to_clambda.ml +++ b/ocaml/middle_end/flambda/flambda_to_clambda.ml @@ -79,7 +79,7 @@ let check_closure t ulam named : Clambda.ulambda = if not !Clflags.clambda_checks then ulam else let desc = - Primitive.simple ~name:"caml_check_value_is_closure" + Primitive.simple_on_values ~name:"caml_check_value_is_closure" ~arity:2 ~alloc:false in let str = Format.asprintf "%a" Flambda.print_named named in @@ -108,7 +108,7 @@ let check_field t ulam pos named_opt : Clambda.ulambda = if not !Clflags.clambda_checks then ulam else let desc = - Primitive.simple ~name:"caml_check_field_access" + Primitive.simple_on_values ~name:"caml_check_field_access" ~arity:3 ~alloc:false in let str = diff --git a/ocaml/ocamldoc/odoc_ast.ml b/ocaml/ocamldoc/odoc_ast.ml index b8a745df79a..02018ede594 100644 --- a/ocaml/ocamldoc/odoc_ast.ml +++ b/ocaml/ocamldoc/odoc_ast.ml @@ -784,10 +784,12 @@ module Analyser = [] arg_list in - let param_types = List.map (fun e -> e.Typedtree.exp_type) param_exps in + let param_types = + List.map (fun (e, _) -> e.Typedtree.exp_type) param_exps + in let params_code = List.map - (fun e -> get_string_of_file + (fun (e, _) -> get_string_of_file e.exp_loc.Location.loc_start.Lexing.pos_cnum e.exp_loc.Location.loc_end.Lexing.pos_cnum) param_exps diff --git a/ocaml/otherlibs/dynlink/Makefile b/ocaml/otherlibs/dynlink/Makefile index 22baeaaf1c3..800a34b4652 100644 --- a/ocaml/otherlibs/dynlink/Makefile +++ b/ocaml/otherlibs/dynlink/Makefile @@ -107,9 +107,9 @@ COMPILERLIBS_SOURCES=\ parsing/attr_helper.ml \ parsing/pprintast.ml \ typing/path.ml \ - typing/primitive.ml \ typing/shape.ml \ typing/layouts.ml \ + typing/primitive.ml \ typing/types.ml \ typing/btype.ml \ typing/subst.ml \ diff --git a/ocaml/otherlibs/dynlink/dune b/ocaml/otherlibs/dynlink/dune index f767d94ec18..9f36d60d96b 100644 --- a/ocaml/otherlibs/dynlink/dune +++ b/ocaml/otherlibs/dynlink/dune @@ -52,9 +52,9 @@ builtin_attributes ident path - primitive shape layouts + primitive types btype lazy_backtrack @@ -136,9 +136,9 @@ (copy_files ../../parsing/builtin_attributes.ml) (copy_files ../../typing/ident.ml) (copy_files ../../typing/path.ml) +(copy_files ../../typing/layouts.ml) (copy_files ../../typing/primitive.ml) (copy_files ../../typing/shape.ml) -(copy_files ../../typing/layouts.ml) (copy_files ../../typing/types.ml) (copy_files ../../typing/btype.ml) (copy_files ../../typing/subst.ml) @@ -193,9 +193,9 @@ (copy_files ../../parsing/builtin_attributes.mli) (copy_files ../../typing/ident.mli) (copy_files ../../typing/path.mli) +(copy_files ../../typing/layouts.mli) (copy_files ../../typing/primitive.mli) (copy_files ../../typing/shape.mli) -(copy_files ../../typing/layouts.mli) (copy_files ../../typing/types.mli) (copy_files ../../typing/btype.mli) (copy_files ../../typing/subst.mli) diff --git a/ocaml/testsuite/tests/typing-layouts/basics.ml b/ocaml/testsuite/tests/typing-layouts/basics.ml index f5233e4f582..708922d3804 100644 --- a/ocaml/testsuite/tests/typing-layouts/basics.ml +++ b/ocaml/testsuite/tests/typing-layouts/basics.ml @@ -311,3 +311,10 @@ Error: Layout void is used here, but the appropriate layouts extension is not en (* CR layouts: This test moves to [basics_alpha.ml] as it needs a non-value sort. Bring back here when we have one enabled by default. *) + +(******************************************************) +(* Test 33: Externals must have representable types *) + +(* CR layouts v2: This test moved to [basics_alpha.ml] as it needs a + non-representable layout. Bring it back here when we can mention [t_any] in + [-extension layouts]. *) diff --git a/ocaml/testsuite/tests/typing-layouts/basics_alpha.ml b/ocaml/testsuite/tests/typing-layouts/basics_alpha.ml index dd15839a54a..d0850d59575 100644 --- a/ocaml/testsuite/tests/typing-layouts/basics_alpha.ml +++ b/ocaml/testsuite/tests/typing-layouts/basics_alpha.ml @@ -185,9 +185,8 @@ end;; Line 2, characters 8-44: 2 | let g z = X.f { vr_void = z; vr_int = 42 } ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Error: Non-value detected in [value_kind]. +Error: Non-value detected in [Typeopt.layout] as sort for type t_void. Please report this error to the Jane Street compilers team. - t_void has layout void, which is not a sublayout of value. |}];; (**************************************) @@ -1095,12 +1094,11 @@ let f19 () = let _y = (x :> t_void) in ();; [%%expect{| -Line 3, characters 12-13: +Line 3, characters 6-8: 3 | let _y = (x :> t_void) in - ^ -Error: Non-value detected in translation: + ^^ +Error: Non-value detected in [Typeopt.layout] as sort for type t_void. Please report this error to the Jane Street compilers team. - This expression has layout void, which is not a sublayout of value. |}];; (********************************************) @@ -1113,12 +1111,11 @@ let f20 () = in ();; [%%expect{| -Lines 4-5, characters 4-5: -4 | ....let module M = struct end in -5 | x -Error: Non-value detected in translation: +Line 3, characters 6-8: +3 | let _y = + ^^ +Error: Non-value detected in [Typeopt.layout] as sort for type t_void. Please report this error to the Jane Street compilers team. - This expression has layout void, which is not a sublayout of value. |}];; (**********************************) @@ -1134,12 +1131,11 @@ let f21 () = ();; [%%expect{| module type M21 = sig end -Lines 6-7, characters 4-5: -6 | ....let (module M) = (module struct end : M21) in +Line 7, characters 4-5: 7 | x -Error: Non-value detected in translation: + ^ +Error: Non-value detected in [Typeopt.layout] as sort for type t_void. Please report this error to the Jane Street compilers team. - This expression has layout void, which is not a sublayout of value. |}];; (***************************************************************) @@ -1209,9 +1205,9 @@ type 'a t2_void [@@void] Line 3, characters 6-30: 3 | let f (x : 'a. 'a t2_void) = x ^^^^^^^^^^^^^^^^^^^^^^^^ -Error: Non-value detected in [value_kind]. +Error: Non-value detected in [Typeopt.layout] as sort for type + 'a. 'a t2_void. Please report this error to the Jane Street compilers team. - 'a. 'a t2_void has layout void, which is not a sublayout of value. |}] (**************************************************) @@ -1239,9 +1235,8 @@ let g f (x : t_void) : t_void = f x Line 1, characters 8-35: 1 | let g f (x : t_void) : t_void = f x ^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Error: Non-value detected in [value_kind]. +Error: Non-value detected in [Typeopt.layout] as sort for type t_void. Please report this error to the Jane Street compilers team. - t_void has layout void, which is not a sublayout of value. |}] (******************************************) @@ -1253,9 +1248,8 @@ let rec f : _ -> _ = fun (x : t_void) -> x Line 1, characters 21-42: 1 | let rec f : _ -> _ = fun (x : t_void) -> x ^^^^^^^^^^^^^^^^^^^^^ -Error: Non-value detected in [value_kind]. +Error: Non-value detected in [Typeopt.layout] as sort for type t_void. Please report this error to the Jane Street compilers team. - t_void has layout void, which is not a sublayout of value. |}] (**********************************************) @@ -1276,9 +1270,8 @@ and q () = Line 1, characters 17-36: 1 | let rec ( let* ) (x : t_void) f = () ^^^^^^^^^^^^^^^^^^^ -Error: Non-value detected in [value_kind]. +Error: Non-value detected in [Typeopt.layout] as sort for type t_void. Please report this error to the Jane Street compilers team. - t_void has layout void, which is not a sublayout of value. |}] let rec ( let* ) x (f : t_void -> _) = () @@ -1291,9 +1284,8 @@ and q () = Lines 4-5, characters 2-4: 4 | ..let* x = assert false in 5 | () -Error: Non-value detected in [value_kind]. +Error: Non-value detected in [Typeopt.layout] as sort for type t_void. Please report this error to the Jane Street compilers team. - t_void has layout void, which is not a sublayout of value. |}] let rec ( let* ) x (f : _ -> t_void) = () @@ -1306,9 +1298,8 @@ and q () = Line 5, characters 2-14: 5 | assert false ^^^^^^^^^^^^ -Error: Non-value detected in [value_kind]. +Error: Non-value detected in [Typeopt.layout] as sort for type t_void. Please report this error to the Jane Street compilers team. - t_void has layout void, which is not a sublayout of value. |}] let rec ( let* ) x f : t_void = assert false @@ -1321,9 +1312,8 @@ and q () = Line 1, characters 19-44: 1 | let rec ( let* ) x f : t_void = assert false ^^^^^^^^^^^^^^^^^^^^^^^^^ -Error: Non-value detected in [value_kind]. +Error: Non-value detected in [Typeopt.layout] as sort for type t_void. Please report this error to the Jane Street compilers team. - t_void has layout void, which is not a sublayout of value. |}] let rec ( let* ) x f = () @@ -1338,9 +1328,8 @@ and q () = Line 2, characters 16-34: 2 | and ( and* ) x1 (x2 : t_void) = () ^^^^^^^^^^^^^^^^^^ -Error: Non-value detected in [value_kind]. +Error: Non-value detected in [Typeopt.layout] as sort for type t_void. Please report this error to the Jane Street compilers team. - t_void has layout void, which is not a sublayout of value. |}] let rec ( let* ) x f = () @@ -1355,9 +1344,8 @@ and q () = Line 2, characters 13-34: 2 | and ( and* ) (x1 : t_void) x2 = () ^^^^^^^^^^^^^^^^^^^^^ -Error: Non-value detected in [value_kind]. +Error: Non-value detected in [Typeopt.layout] as sort for type t_void. Please report this error to the Jane Street compilers team. - t_void has layout void, which is not a sublayout of value. |}] let rec ( let* ) x f = () @@ -1372,9 +1360,8 @@ and q () = Line 1, characters 17-25: 1 | let rec ( let* ) x f = () ^^^^^^^^ -Error: Non-value detected in [value_kind]. +Error: Non-value detected in [Typeopt.layout] as sort for type t_void. Please report this error to the Jane Street compilers team. - t_void has layout void, which is not a sublayout of value. |}] (* CR layouts v5: when we allow non-values in tuples, this next one should @@ -1458,6 +1445,7 @@ Line 1, characters 41-43: Error: This type ('a : value) should be an instance of type ('a0 : void) 'a has layout void, which does not overlap with value. |}] + (* CR layouts bug: this should be accepted (or maybe we should reject the type definition if we're not allowing `void` things in structures). This bug is a goof at the top of Typecore.build_or_pat; @@ -1476,3 +1464,16 @@ Error: This expression has type t_void but an expression was expected of type ('a : value) t_void has layout void, which is not a sublayout of value. |}] + +(******************************************************) +(* Test 33: Externals must have representable types *) +external foo33 : t_any = "foo33";; + +[%%expect{| +Line 1, characters 17-22: +1 | external foo33 : t_any = "foo33";; + ^^^^^ +Error: This type signature for foo33 is not a value type. + foo33 has layout any, which is not a sublayout of value. +|}] + diff --git a/ocaml/testsuite/tests/typing-layouts/basics_beta.ml b/ocaml/testsuite/tests/typing-layouts/basics_beta.ml index 636fa63575a..cc789c785ba 100644 --- a/ocaml/testsuite/tests/typing-layouts/basics_beta.ml +++ b/ocaml/testsuite/tests/typing-layouts/basics_beta.ml @@ -517,3 +517,10 @@ Error: Layout void is used here, but the appropriate layouts extension is not en (* CR layouts: This test moves to [basics_alpha.ml] as it needs a non-value sort. Bring back here when we have one. *) + +(******************************************************) +(* Test 33: Externals must have representable types *) + +(* CR layouts v2: This test moved to [basics_alpha.ml] as it needs a + non-representable layout. Bring it back here when we can mention [t_any] in + [-extension layouts_beta]. *) diff --git a/ocaml/testsuite/tests/typing-layouts/modules_alpha.ml b/ocaml/testsuite/tests/typing-layouts/modules_alpha.ml index e464b3e4e67..b4429deeee8 100644 --- a/ocaml/testsuite/tests/typing-layouts/modules_alpha.ml +++ b/ocaml/testsuite/tests/typing-layouts/modules_alpha.ml @@ -162,9 +162,8 @@ end;; Line 4, characters 13-19: 4 | let create _ = () ^^^^^^ -Error: Non-value detected in [value_kind]. +Error: Non-value detected in [Typeopt.layout] as sort for type 'a. Please report this error to the Jane Street compilers team. - 'a has layout void, which is not a sublayout of value. |}];; module rec Foo3 : sig diff --git a/ocaml/typing/ctype.ml b/ocaml/typing/ctype.ml index 54781d1c2d3..5e33c347bf1 100644 --- a/ocaml/typing/ctype.ml +++ b/ocaml/typing/ctype.ml @@ -2075,6 +2075,11 @@ let type_sort ~why env ty = | Ok _ -> Ok sort | Error _ as e -> e +let type_sort_exn ~why env ty = + match type_sort ~why env ty with + | Ok s -> s + | Error _ -> Misc.fatal_error "Ctype.type_sort_exn on non-sort" + (* Note: Because [estimate_type_layout] actually returns an upper bound, this function computes an inaccurate intersection in some cases. @@ -3774,6 +3779,15 @@ type filter_arrow_failure = exception Filter_arrow_failed of filter_arrow_failure +type filtered_arrow = + { ty_arg : type_expr; + arg_mode : alloc_mode; + arg_sort : sort; + ty_ret : type_expr; + ret_mode : alloc_mode; + ret_sort : sort + } + let filter_arrow env t l ~force_tpoly = let function_type level = (* CR layouts v3: This is one of two primary places where we are restricting @@ -3784,12 +3798,14 @@ let filter_arrow env t l ~force_tpoly = allow both to be any. Separately, the relevant checks on function arguments should happen when functions are constructed, not their types. *) - let l1 = Layout.of_new_sort_var ~why:Function_argument in - let l2 = Layout.of_new_sort_var ~why:Function_result in - let t1 = + let arg_sort = Sort.new_var () in + let l_arg = Layout.of_sort ~why:Function_argument arg_sort in + let ret_sort = Sort.new_var () in + let l_res = Layout.of_sort ~why:Function_result ret_sort in + let ty_arg = if not force_tpoly then begin assert (not (is_optional l)); - newvar2 level l1 + newvar2 level l_arg end else begin let t1 = if is_optional l then @@ -3800,21 +3816,23 @@ let filter_arrow env t l ~force_tpoly = [newvar2 level (Layout.value ~why:Type_argument)], ref Mnil)) else - newvar2 level l1 + newvar2 level l_arg in newty2 ~level (Tpoly(t1, [])) end in - let t2 = newvar2 level l2 in - let marg = Alloc_mode.newvar () in - let mret = Alloc_mode.newvar () in - let t' = newty2 ~level (Tarrow ((l,marg,mret), t1, t2, commu_ok)) in - t', marg, t1, mret, t2 + let ty_ret = newvar2 level l_res in + let arg_mode = Alloc_mode.newvar () in + let ret_mode = Alloc_mode.newvar () in + let t' = + newty2 ~level (Tarrow ((l, arg_mode, ret_mode), ty_arg, ty_ret, commu_ok)) + in + t', { ty_arg; arg_mode; arg_sort; ty_ret; ret_mode; ret_sort } in let t = try expand_head_trace env t with Unify_trace trace -> - let t', _, _, _, _ = function_type (get_level t) in + let t', _ = function_type (get_level t) in raise (Filter_arrow_failed (Unification_error (expand_to_unification_error @@ -3823,13 +3841,22 @@ let filter_arrow env t l ~force_tpoly = in match get_desc t with Tvar { layout } -> - let t', marg, t1, mret, t2 = function_type (get_level t) in + let t', arrow_desc = function_type (get_level t) in link_type t t'; constrain_type_layout_exn env Unify t' layout; - (marg, t1, mret, t2) - | Tarrow((l', marg, mret), t1, t2, _) -> + arrow_desc + | Tarrow((l', arg_mode, ret_mode), ty_arg, ty_ret, _) -> if l = l' || !Clflags.classic && l = Nolabel && not (is_optional l') - then (marg, t1, mret, t2) + then + (* CR layouts v2.5: When we move the restrictions on argument from + arrows to functions, this function doesn't need to return a sort and + these calls to [type_sort] can move. We could eliminate them + entirely by storing sorts on [TArrow], but that seems incompatible + with the future plan to shift the layout requirements from the types + to the terms. *) + let arg_sort = type_sort_exn ~why:Function_argument env ty_arg in + let ret_sort = type_sort_exn ~why:Function_argument env ty_ret in + { ty_arg; arg_mode; arg_sort; ty_ret; ret_mode; ret_sort } else raise (Filter_arrow_failed (Label_mismatch { got = l; expected = l'; expected_type = t })) @@ -3849,10 +3876,10 @@ exception Filter_arrow_mono_failed let filter_arrow_mono env t l = match filter_arrow env t l ~force_tpoly:true with | exception Filter_arrow_failed _ -> raise Filter_arrow_mono_failed - | (marg, t1, mret, t2) -> - match filter_mono t1 with + | {ty_arg; _} as farr -> + match filter_mono ty_arg with | exception Filter_mono_failed -> raise Filter_arrow_mono_failed - | t1 -> (marg, t1, mret, t2) + | ty_arg -> { farr with ty_arg } type filter_method_failure = | Unification_error of unification_error diff --git a/ocaml/typing/ctype.mli b/ocaml/typing/ctype.mli index b12ec0d4e3f..43571efc192 100644 --- a/ocaml/typing/ctype.mli +++ b/ocaml/typing/ctype.mli @@ -245,8 +245,17 @@ val unify_delaying_layout_checks : typedecl before well-foundedness checks have made layout checking safe. *) +type filtered_arrow = + { ty_arg : type_expr; + arg_mode : alloc_mode; + arg_sort : sort; + ty_ret : type_expr; + ret_mode : alloc_mode; + ret_sort : sort + } + val filter_arrow: Env.t -> type_expr -> arg_label -> force_tpoly:bool -> - alloc_mode * type_expr * alloc_mode * type_expr + filtered_arrow (* A special case of unification (with l:'a -> 'b). If [force_poly] is false then the usual invariant that the argument type be a [Tpoly] node is not enforced. Raises @@ -255,8 +264,7 @@ val filter_mono: type_expr -> type_expr (* A special case of unification (with Tpoly('a, [])). Can only be called on [Tpoly] nodes. Raises [Filter_mono_failed] instead of [Unify] *) -val filter_arrow_mono: Env.t -> type_expr -> arg_label -> - alloc_mode * type_expr * alloc_mode * type_expr +val filter_arrow_mono: Env.t -> type_expr -> arg_label -> filtered_arrow (* A special case of unification. Composition of [filter_arrow] with [filter_mono] on the argument type. Raises [Filter_arrow_mono_failed] instead of [Unify] *) @@ -490,6 +498,12 @@ val type_sort : why:Layouts.Layout.concrete_layout_reason -> Env.t -> type_expr -> (sort, Layout.Violation.t) result +(* Same as [type_sort], but only safe to call on types known to be a sort. + For example, if the type is used as an argument in a function type that + has already been translated. *) +val type_sort_exn : + why:Layouts.Layout.concrete_layout_reason -> Env.t -> type_expr -> sort + (* Layout checking. [constrain_type_layout] will update the layout of type variables to make the check true, if possible. [check_decl_layout] and [check_type_layout] won't, but will still instantiate sort variables. diff --git a/ocaml/typing/includecore.ml b/ocaml/typing/includecore.ml index f8377cf20fd..6a1b6cee289 100644 --- a/ocaml/typing/includecore.ml +++ b/ocaml/typing/includecore.ml @@ -76,8 +76,8 @@ let primitive_descriptions pd1 pd2 = else if not (String.equal pd1.prim_native_name pd2.prim_native_name) then Some Native_name else if not - (Primitive.equal_native_repr - (snd pd1.prim_native_repr_res) (snd pd2.prim_native_repr_res)) then + (match pd1.prim_native_repr_res, pd2.prim_native_repr_res with + | (_, nr1), (_, nr2) -> Primitive.equal_native_repr nr1 nr2) then Some Result_repr else native_repr_args pd1.prim_native_repr_args pd2.prim_native_repr_args diff --git a/ocaml/typing/layouts.ml b/ocaml/typing/layouts.ml index 49fcbc62fd1..aaf2af9ad8b 100644 --- a/ocaml/typing/layouts.ml +++ b/ocaml/typing/layouts.ml @@ -151,6 +151,13 @@ module Sort = struct | Unequal -> false | Equal_mutated_first | Equal_mutated_second | Equal_no_mutation -> true + let equal_const c1 c2 = + match c1, c2 with + | Void, Void + | Value, Value -> true + | Void, Value + | Value, Void -> false + let rec is_void_defaulting = function | Const Void -> true | Var v -> begin match !v with @@ -189,6 +196,28 @@ module Sort = struct and var ppf v = fprintf ppf "{ contents = %a }" opt_t (!v) end + + let for_function = value + let for_predef_value = value + let for_block_element = value + let for_probe_body = value + let for_poly_variant = value + let for_record = value + let for_record_field = value + let for_constructor_arg = value + let for_object = value + let for_lazy_body = value + let for_tuple_element = value + let for_instance_var = value + let for_bop_exp = value + let for_class_arg = value + let for_method = value + let for_initializer = value + let for_module = value + let for_tuple = value + let for_array_get_result = value + let for_array_element = value + let for_list_element = value end type sort = Sort.t @@ -208,6 +237,9 @@ module Layout = struct | Function_result | Structure_item_expression | V1_safety_check + | External_argument + | External_result + | Statement type value_creation_reason = | Class_let_binding @@ -568,6 +600,12 @@ module Layout = struct fprintf ppf "used in an expression in a structure" | V1_safety_check -> fprintf ppf "part of the v1 safety check" + | External_argument -> + fprintf ppf "used as an argument in an external declaration" + | External_result -> + fprintf ppf "used as the result of an external declaration" + | Statement -> + fprintf ppf "used as a statement" let format_annotation_context ppf : annotation_context -> unit = function | Type_declaration p -> @@ -998,6 +1036,12 @@ module Layout = struct fprintf ppf "Structure_item_expression" | V1_safety_check -> fprintf ppf "V1_safety_check" + | External_argument -> + fprintf ppf "External_argument" + | External_result -> + fprintf ppf "External_result" + | Statement -> + fprintf ppf "Statement" let annotation_context ppf : annotation_context -> unit = function | Type_declaration p -> diff --git a/ocaml/typing/layouts.mli b/ocaml/typing/layouts.mli index 796f6b0aa72..869b2296dd7 100644 --- a/ocaml/typing/layouts.mli +++ b/ocaml/typing/layouts.mli @@ -50,6 +50,8 @@ module Sort : sig equal, if possible *) val equate : t -> t -> bool + val equal_const : const -> const -> bool + val format : Format.formatter -> t -> unit (** Defaults any variables to value; leaves other sorts alone *) @@ -59,10 +61,47 @@ module Sort : sig variable is unfilled. *) val is_void_defaulting : t -> bool + (** [get_default_value] extracts the sort as a `const`. If it's a variable, + it is set to [value] first. *) + val get_default_value : t -> const + module Debug_printers : sig val t : Format.formatter -> t -> unit val var : Format.formatter -> var -> unit end + + (* CR layouts: These are sorts for the types of ocaml expressions that are + currently required to be values, but for which we expect to relax that + restriction in versions 2 and beyond. Naming them makes it easy to find + where in the translation to lambda they are assume to be value. *) + (* CR layouts: add similarly named layouts and use those names everywhere (not + just the translation to lambda) rather than writing specific layouts and + sorts in the code. *) + val for_class_arg : t + val for_instance_var : t + val for_bop_exp : t + val for_lazy_body : t + val for_tuple_element : t + val for_record : t + val for_record_field : t + val for_constructor_arg : t + val for_block_element : t + val for_array_get_result : t + val for_array_element : t + val for_list_element : t + + (** These are sorts for the types of ocaml expressions that we expect will + always be "value". These names are used in the translation to lambda to + make the code clearer. *) + val for_function : t + val for_probe_body : t + val for_poly_variant : t + val for_object : t + val for_initializer : t + val for_method : t + val for_module : t + val for_predef_value : t (* Predefined value types, e.g. int and string *) + val for_tuple : t end type sort = Sort.t @@ -101,6 +140,9 @@ module Layout : sig | Function_result | Structure_item_expression | V1_safety_check + | External_argument + | External_result + | Statement type annotation_context = | Type_declaration of Path.t diff --git a/ocaml/typing/primitive.ml b/ocaml/typing/primitive.ml index d6de7b654dd..34804aaee3b 100644 --- a/ocaml/typing/primitive.ml +++ b/ocaml/typing/primitive.ml @@ -17,11 +17,12 @@ open Misc open Parsetree +open Layouts type boxed_integer = Pnativeint | Pint32 | Pint64 type native_repr = - | Same_as_ocaml_repr + | Same_as_ocaml_repr of Layouts.Sort.const | Unboxed_float | Unboxed_integer of boxed_integer | Untagged_int @@ -55,20 +56,20 @@ type error = exception Error of Location.t * error let is_ocaml_repr = function - | _, Same_as_ocaml_repr -> true + | _, Same_as_ocaml_repr _ -> true | _, Unboxed_float | _, Unboxed_integer _ | _, Untagged_int -> false let is_unboxed = function - | _, Same_as_ocaml_repr + | _, Same_as_ocaml_repr _ | _, Untagged_int -> false | _, Unboxed_float | _, Unboxed_integer _ -> true let is_untagged = function | _, Untagged_int -> true - | _, Same_as_ocaml_repr + | _, Same_as_ocaml_repr _ | _, Unboxed_float | _, Unboxed_integer _ -> false @@ -78,7 +79,7 @@ let rec make_native_repr_args arity x = else x :: make_native_repr_args (arity - 1) x -let simple ~name ~arity ~alloc = +let simple_on_values ~name ~arity ~alloc = {prim_name = name; prim_arity = arity; prim_alloc = alloc; @@ -87,8 +88,8 @@ let simple ~name ~arity ~alloc = prim_coeffects = Has_coeffects; prim_native_name = ""; prim_native_repr_args = - make_native_repr_args arity (Prim_global, Same_as_ocaml_repr); - prim_native_repr_res = (Prim_global, Same_as_ocaml_repr) } + make_native_repr_args arity (Prim_global, Same_as_ocaml_repr Sort.Value); + prim_native_repr_res = (Prim_global, Same_as_ocaml_repr Sort.Value) } let make ~name ~alloc ~c_builtin ~effects ~coeffects ~native_name ~native_repr_args ~native_repr_res = @@ -254,7 +255,7 @@ let print p osig_val_decl = | Prim_poly -> [oattr_local_opt]) @ (match repr with - | Same_as_ocaml_repr -> [] + | Same_as_ocaml_repr _ -> [] | Unboxed_float | Unboxed_integer _ -> if all_unboxed then [] else [oattr_unboxed] | Untagged_int -> if all_untagged then [] else [oattr_untagged]) @@ -287,18 +288,18 @@ let equal_boxed_integer bi1 bi2 = let equal_native_repr nr1 nr2 = match nr1, nr2 with - | Same_as_ocaml_repr, Same_as_ocaml_repr -> true - | Same_as_ocaml_repr, + | Same_as_ocaml_repr s1, Same_as_ocaml_repr s2 -> Sort.equal_const s1 s2 + | Same_as_ocaml_repr _, (Unboxed_float | Unboxed_integer _ | Untagged_int) -> false | Unboxed_float, Unboxed_float -> true | Unboxed_float, - (Same_as_ocaml_repr | Unboxed_integer _ | Untagged_int) -> false + (Same_as_ocaml_repr _ | Unboxed_integer _ | Untagged_int) -> false | Unboxed_integer bi1, Unboxed_integer bi2 -> equal_boxed_integer bi1 bi2 | Unboxed_integer _, - (Same_as_ocaml_repr | Unboxed_float | Untagged_int) -> false + (Same_as_ocaml_repr _ | Unboxed_float | Untagged_int) -> false | Untagged_int, Untagged_int -> true | Untagged_int, - (Same_as_ocaml_repr | Unboxed_float | Unboxed_integer _) -> false + (Same_as_ocaml_repr _ | Unboxed_float | Unboxed_integer _) -> false let equal_effects ef1 ef2 = match ef1, ef2 with @@ -320,6 +321,10 @@ let native_name_is_external p = let nat_name = native_name p in nat_name <> "" && nat_name.[0] <> '%' +let sort_of_native_repr = function + | Same_as_ocaml_repr s -> s + | (Unboxed_float | Unboxed_integer _ | Untagged_int) -> Sort.Value + let report_error ppf err = match err with | Old_style_float_with_native_repr_attribute -> diff --git a/ocaml/typing/primitive.mli b/ocaml/typing/primitive.mli index de496fc3711..a52e550c5fe 100644 --- a/ocaml/typing/primitive.mli +++ b/ocaml/typing/primitive.mli @@ -20,7 +20,7 @@ type boxed_integer = Pnativeint | Pint32 | Pint64 (* Representation of arguments/result for the native code version of a primitive *) type native_repr = - | Same_as_ocaml_repr + | Same_as_ocaml_repr of Layouts.Sort.const | Unboxed_float | Unboxed_integer of boxed_integer | Untagged_int @@ -56,7 +56,7 @@ type description = private (* Invariant [List.length d.prim_native_repr_args = d.prim_arity] *) -val simple +val simple_on_values : name:string -> arity:int -> alloc:bool @@ -69,14 +69,14 @@ val make -> effects:effects -> coeffects:coeffects -> native_name:string - -> native_repr_args: (mode*native_repr) list - -> native_repr_res: mode*native_repr + -> native_repr_args: (mode * native_repr) list + -> native_repr_res: mode * native_repr -> description val parse_declaration : Parsetree.value_description - -> native_repr_args:(mode*native_repr) list - -> native_repr_res:(mode*native_repr) + -> native_repr_args:(mode * native_repr) list + -> native_repr_res:(mode * native_repr) -> description val print @@ -97,6 +97,10 @@ val equal_coeffects : coeffects -> coeffects -> bool compiler itself. *) val native_name_is_external : description -> bool +(** [sort_of_native_repr] returns the sort expected during typechecking (which + may be different than the sort used in the external interface). *) +val sort_of_native_repr : native_repr -> Layouts.Sort.const + type error = | Old_style_float_with_native_repr_attribute | Old_style_noalloc_with_noalloc_attribute diff --git a/ocaml/typing/printtyped.ml b/ocaml/typing/printtyped.ml index 5a882d80b04..d16fc148a18 100644 --- a/ocaml/typing/printtyped.ml +++ b/ocaml/typing/printtyped.ml @@ -452,10 +452,10 @@ and expression i ppf x = expression i ppf e1; expression i ppf e2; option i expression ppf eo; - | Texp_sequence (e1, l, e2) -> + | Texp_sequence (e1, s, e2) -> line i ppf "Texp_sequence\n"; expression i ppf e1; - line i ppf "%a\n" Layouts.Layout.format l; + line i ppf "%a\n" Layouts.Sort.format s; expression i ppf e2; | Texp_while {wh_cond; wh_body} -> line i ppf "Texp_while\n"; @@ -1061,7 +1061,7 @@ and record_field i ppf = function and label_x_apply_arg i ppf (l, e) = line i ppf "\n"; arg_label (i+1) ppf l; - (match e with Omitted _ -> () | Arg e -> expression (i+1) ppf e) + (match e with Omitted _ -> () | Arg (e, _) -> expression (i+1) ppf e) and ident_x_expression_def i ppf (l, e) = line i ppf " \"%a\"\n" fmt_ident l; diff --git a/ocaml/typing/rec_check.ml b/ocaml/typing/rec_check.ml index ba061870720..7b429cd495d 100644 --- a/ocaml/typing/rec_check.ml +++ b/ocaml/typing/rec_check.ml @@ -583,7 +583,7 @@ let rec expression : Typedtree.expression -> term_judg = | Texp_instvar (self_path, pth, _inst_var) -> join [path self_path << Dereference; path pth] | Texp_apply - ({exp_desc = Texp_ident (_, _, vd, Id_prim _)}, [_, Arg arg], _, _) + ({exp_desc = Texp_ident (_, _, vd, Id_prim _)}, [_, Arg (arg, _)], _, _) when is_ref vd -> (* G |- e: m[Guard] @@ -595,7 +595,7 @@ let rec expression : Typedtree.expression -> term_judg = let arg (_, arg) = match arg with | Omitted _ -> empty - | Arg e -> expression e + | Arg (e, _) -> expression e in let app_mode = if List.exists is_abstracted_arg args then (* see the comment on Texp_apply in typedtree.mli; @@ -1071,7 +1071,7 @@ and class_expr : Typedtree.class_expr -> term_judg = let arg (_, arg) = match arg with | Omitted _ -> empty - | Arg e -> expression e + | Arg (e, _) -> expression e in join [ class_expr ce << Dereference; diff --git a/ocaml/typing/tast_iterator.ml b/ocaml/typing/tast_iterator.ml index 801c571de81..b54dd1b4601 100644 --- a/ocaml/typing/tast_iterator.ml +++ b/ocaml/typing/tast_iterator.ml @@ -211,7 +211,7 @@ let expr sub {exp_extra; exp_desc; exp_env; _} = | Texp_apply (exp, list, _, _) -> sub.expr sub exp; List.iter (function - | (_, Arg exp) -> sub.expr sub exp + | (_, Arg (exp, _)) -> sub.expr sub exp | (_, Omitted _) -> ()) list | Texp_match (exp, _, cases, _) -> @@ -416,8 +416,8 @@ let class_expr sub {cl_desc; cl_env; _} = | Tcl_apply (cl, args) -> sub.class_expr sub cl; List.iter (function - | (_, Arg exp) -> sub.expr sub exp - | (_, Omitted o) -> sub.env sub o.ty_env) + | (_, Arg (exp, _)) -> sub.expr sub exp + | (_, Omitted _) -> ()) args | Tcl_let (rec_flag, value_bindings, ivars, cl) -> sub.value_bindings sub (rec_flag, value_bindings); diff --git a/ocaml/typing/tast_mapper.ml b/ocaml/typing/tast_mapper.ml index 40b70425734..b39623f5ead 100644 --- a/ocaml/typing/tast_mapper.ml +++ b/ocaml/typing/tast_mapper.ml @@ -298,19 +298,17 @@ let expr sub x = | Texp_let (rec_flag, list, exp) -> let (rec_flag, list) = sub.value_bindings sub (rec_flag, list) in Texp_let (rec_flag, list, sub.expr sub exp) - | Texp_function { arg_label; param; cases; - partial; region; curry; warnings; arg_mode; alloc_mode } -> + | Texp_function { arg_label; param; cases; partial; region; curry; + warnings; arg_mode; arg_sort; ret_sort; alloc_mode } -> let cases = List.map (sub.case sub) cases in - Texp_function { arg_label; param; cases; - partial; region; curry; warnings; arg_mode; alloc_mode } + Texp_function { arg_label; param; cases; partial; region; curry; + warnings; arg_mode; arg_sort; ret_sort; alloc_mode } | Texp_apply (exp, list, pos, am) -> Texp_apply ( sub.expr sub exp, List.map (function - | (lbl, Arg exp) -> (lbl, Arg (sub.expr sub exp)) - | (lbl, Omitted o) -> - let o' = { o with ty_env = sub.env sub o.ty_env } in - (lbl, Omitted o')) + | (lbl, Arg (exp, sort)) -> (lbl, Arg (sub.expr sub exp, sort)) + | (lbl, Omitted o) -> (lbl, Omitted o)) list, pos, am ) @@ -375,7 +373,7 @@ let expr sub x = | Texp_while wh -> Texp_while { wh_cond = sub.expr sub wh.wh_cond; wh_body = sub.expr sub wh.wh_body; - wh_body_layout = wh.wh_body_layout + wh_body_sort = wh.wh_body_sort } | Texp_for tf -> Texp_for {tf with for_from = sub.expr sub tf.for_from; @@ -424,12 +422,15 @@ let expr sub x = Texp_object (sub.class_structure sub cl, sl) | Texp_pack mexpr -> Texp_pack (sub.module_expr sub mexpr) - | Texp_letop {let_; ands; param; body; partial; warnings} -> + | Texp_letop {let_; ands; param; param_sort; body; body_sort; partial; + warnings} -> Texp_letop{ let_ = sub.binding_op sub let_; ands = List.map (sub.binding_op sub) ands; param; + param_sort; body = sub.case sub body; + body_sort; partial; warnings } @@ -621,7 +622,7 @@ let class_expr sub x = Tcl_apply ( sub.class_expr sub cl, List.map (function - | (lbl, Arg exp) -> (lbl, Arg (sub.expr sub exp)) + | (lbl, Arg (exp, sort)) -> (lbl, Arg (sub.expr sub exp, sort)) | (lbl, Omitted o) -> (lbl, Omitted o)) args ) diff --git a/ocaml/typing/typeclass.ml b/ocaml/typing/typeclass.ml index d6f96ec8a13..347f1387098 100644 --- a/ocaml/typing/typeclass.ml +++ b/ocaml/typing/typeclass.ml @@ -1280,16 +1280,24 @@ and class_expr_aux cl_num val_env met_env virt self_scope scl = let use_arg sarg l' = Arg ( if not optional || Btype.is_optional l' then - type_argument val_env sarg ty ty0 + let arg = type_argument val_env sarg ty ty0 in + arg, Sort.value else let ty' = extract_option_type val_env ty and ty0' = extract_option_type val_env ty0 in let arg = type_argument val_env sarg ty' ty0' in - option_some val_env arg Value_mode.global + option_some val_env arg Value_mode.global, + (* CR layouts v5: Change the sort when options can hold + non-values. *) + Sort.value ) in let eliminate_optional_arg () = - Arg (option_none val_env ty0 Location.none) + Arg (option_none val_env ty0 Location.none, + (* CR layouts v5: Change the sort when options can hold + non-values. *) + Sort.value + ) in let remaining_sargs, arg = if ignore_labels then begin @@ -1324,7 +1332,8 @@ and class_expr_aux cl_num val_env met_env virt self_scope scl = let mode_closure = Alloc_mode.global in let mode_arg = Alloc_mode.global in let mode_ret = Alloc_mode.global in - Omitted { mode_closure; mode_arg; mode_ret; ty_arg = ty; ty_env = val_env } + let sort_arg = Sort.value in + Omitted { mode_closure; mode_arg; mode_ret; sort_arg } end in let omitted = diff --git a/ocaml/typing/typecore.ml b/ocaml/typing/typecore.ml index d170bfd7928..14797f82241 100644 --- a/ocaml/typing/typecore.ml +++ b/ocaml/typing/typecore.ml @@ -3260,7 +3260,10 @@ let type_omitted_parameters expected_mode env ty_ret mode_ret args = match arg with | Arg (exp, exp_mode) -> let open_args = (exp_mode, exp) :: open_args in - let args = (lbl, Arg exp) :: args in + let sort = + type_sort_exn ~why:Function_argument exp.exp_env exp.exp_type + in + let args = (lbl, Arg (exp, sort)) :: args in (ty_ret, mode_ret, open_args, closed_args, args) | Omitted { mode_fun; ty_arg; mode_arg; level } -> let arrow_desc = (lbl, mode_arg, mode_ret) in @@ -3280,7 +3283,10 @@ let type_omitted_parameters expected_mode env ty_ret mode_ret args = let open_args = [] in let mode_closure = Alloc_mode.join (mode_fun :: closed_args) in register_allocation_mode mode_closure; - let arg = Omitted { mode_closure; mode_arg; mode_ret; ty_arg; ty_env = env } in + let sort_arg = + type_sort_exn ~why:Function_argument env ty_arg + in + let arg = Omitted { mode_closure; mode_arg; mode_ret; sort_arg } in let args = (lbl, arg) :: args in (ty_ret, mode_closure, open_args, closed_args, args)) (ty_ret, mode_ret, [], [], []) (List.rev args) @@ -3373,7 +3379,7 @@ let rec is_nonexpansive exp = Val_prim {Primitive.prim_name = ("%raise" | "%reraise" | "%raise_notrace")}}, Id_prim _) }, - [Nolabel, Arg e], _, _) -> + [Nolabel, Arg (e, _)], _, _) -> is_nonexpansive e | Texp_array (_, _ :: _, _) | Texp_apply _ @@ -3433,7 +3439,7 @@ and is_nonexpansive_opt = function and is_nonexpansive_arg = function | Omitted _ -> true - | Arg e -> is_nonexpansive e + | Arg (e, _) -> is_nonexpansive e let maybe_expansive e = not (is_nonexpansive e) @@ -3637,7 +3643,7 @@ let rec type_function_approx env loc label spato sexp in_function ty_expected = | Some (loc, ty) -> loc, ty | None -> loc, ty_expected in - let (arg_mode, ty_arg, _, ty_res) = + let { ty_arg; arg_mode; ty_ret; _ } = try filter_arrow env ty_expected label ~force_tpoly:(not has_poly) with Filter_arrow_failed err -> let explanation = None in @@ -3663,7 +3669,7 @@ let rec type_function_approx env loc label spato sexp in_function ty_expected = | Some spat -> type_pattern_approx env spat ty_arg end; let in_function = Some (loc_fun, ty_fun) in - type_approx_aux env sexp in_function ty_res + type_approx_aux env sexp in_function ty_ret and type_approx_aux env sexp in_function ty_expected = match Jane_syntax.Expression.of_ast sexp with @@ -4922,12 +4928,12 @@ and type_expect_ exp_env = env } end | Pexp_sequence(sexp1, sexp2) -> - let exp1 = type_statement ~explanation:Sequence_left_hand_side - env sexp1 in + let exp1, sort1 = + type_statement ~explanation:Sequence_left_hand_side env sexp1 + in let exp2 = type_expect env expected_mode sexp2 ty_expected_explained in - let layout = type_layout env exp1.exp_type in re { - exp_desc = Texp_sequence(exp1, layout, exp2); + exp_desc = Texp_sequence(exp1, sort1, exp2); exp_loc = loc; exp_extra = []; exp_type = exp2.exp_type; exp_attributes = sexp.pexp_attributes; @@ -4941,14 +4947,13 @@ and type_expect_ in let body_env = Env.add_region_lock env in let position = RTail (Value_mode.local, FNontail) in - let wh_body = + let wh_body, wh_body_sort = type_statement ~explanation:While_loop_body ~position body_env sbody in - let wh_body_layout = Ctype.type_layout env wh_body.exp_type in rue { exp_desc = - Texp_while {wh_cond; wh_body; wh_body_layout}; + Texp_while {wh_cond; wh_body; wh_body_sort}; exp_loc = loc; exp_extra = []; exp_type = instance Predef.type_unit; exp_attributes = sexp.pexp_attributes; @@ -4967,13 +4972,12 @@ and type_expect_ in let new_env = Env.add_region_lock new_env in let position = RTail (Value_mode.local, FNontail) in - let for_body = + let for_body, for_body_sort = type_statement ~explanation:For_loop_body ~position new_env sbody in - let for_body_layout = Ctype.type_layout env for_body.exp_type in rue { exp_desc = Texp_for {for_id; for_pat = param; for_from; for_to; - for_dir = dir; for_body; for_body_layout }; + for_dir = dir; for_body; for_body_sort }; exp_loc = loc; exp_extra = []; exp_type = instance Predef.type_unit; exp_attributes = sexp.pexp_attributes; @@ -5504,37 +5508,43 @@ and type_expect_ exp_env = env; } | Pexp_letop{ let_ = slet; ands = sands; body = sbody } -> - let rec loop spat_acc ty_acc sands = + let rec loop spat_acc ty_acc ty_acc_sort sands = match sands with - | [] -> spat_acc, ty_acc + | [] -> spat_acc, ty_acc, ty_acc_sort | { pbop_pat = spat; _} :: rest -> (* CR layouts v5: eliminate value requirement *) let ty = newvar (Layout.value ~why:Tuple_element) in let loc = Location.ghostify slet.pbop_op.loc in let spat_acc = Ast_helper.Pat.tuple ~loc [spat_acc; spat] in let ty_acc = newty (Ttuple [ty_acc; ty]) in - loop spat_acc ty_acc rest + loop spat_acc ty_acc Sort.value rest in if !Clflags.principal then begin_def (); let let_loc = slet.pbop_op.loc in let op_path, op_desc = type_binding_op_ident env slet.pbop_op in let op_type = instance op_desc.val_type in - let spat_params, ty_params = - let initial_layout = match sands with - | [] -> Layout.of_new_sort_var ~why:Function_argument + let spat_params, ty_params, param_sort = + let initial_layout, initial_sort = match sands with + | [] -> + let sort = Sort.new_var () in + Layout.of_sort ~why:Function_argument sort, sort (* CR layouts v5: eliminate value requirement for tuple elements *) - | _ -> Layout.value ~why:Tuple_element + | _ -> Layout.value ~why:Tuple_element, Sort.value in - loop slet.pbop_pat (newvar initial_layout) sands + loop slet.pbop_pat (newvar initial_layout) initial_sort sands in + let body_sort = Sort.new_var () in let ty_func_result = - newvar (Layout.of_new_sort_var ~why:Function_result) + newvar (Layout.of_sort ~why:Function_result body_sort) in let arrow_desc = Nolabel, Alloc_mode.global, Alloc_mode.global in let ty_func = newty (Tarrow(arrow_desc, newmono ty_params, ty_func_result, commu_ok)) in - let ty_result = newvar (Layout.of_new_sort_var ~why:Function_result) in + let op_result_sort = Sort.new_var () in + let ty_result = + newvar (Layout.of_sort ~why:Function_result op_result_sort) + in let ty_andops = newvar (Layout.of_new_sort_var ~why:Function_argument) in let ty_op = newty (Tarrow(arrow_desc, newmono ty_andops, @@ -5575,12 +5585,14 @@ and type_expect_ bop_op_path = op_path; bop_op_val = op_desc; bop_op_type = op_type; + bop_op_return_sort = op_result_sort; bop_exp = exp; bop_loc = slet.pbop_loc; } in let warnings = Warnings.backup () in let desc = - Texp_letop{let_; ands; param; body; partial; warnings} + Texp_letop{let_; ands; param; param_sort; body; body_sort; partial; + warnings} in rue { exp_desc = desc; exp_loc = sexp.pexp_loc; @@ -5764,7 +5776,7 @@ and type_function ?in_function loc attrs env (expected_mode : expected_mode) | _ -> false in let ty_expected' = instance ty_expected in - let (arg_mode, ty_arg, ret_mode, ty_res) = + let { ty_arg; arg_mode; arg_sort; ty_ret; ret_mode; ret_sort } = let force_tpoly = (* If [has_poly] is true then we rely on the later call to type_pat to enforce the invariant that the parameter type @@ -5792,7 +5804,7 @@ and type_function ?in_function loc attrs env (expected_mode : expected_mode) if separate then begin end_def (); generalize_structure ty_arg; - generalize_structure ty_res + generalize_structure ty_ret end; if not has_poly && not (tpoly_is_mono ty_arg) && !Clflags.principal && get_level ty_arg < Btype.generic_level then begin @@ -5858,7 +5870,7 @@ and type_function ?in_function loc attrs env (expected_mode : expected_mode) | Error () -> raise (Error (loc_fun, env, Function_returns_local)) end in - let ret_value_mode = expect_mode_cross env ty_res ret_value_mode in + let ret_value_mode = expect_mode_cross env ty_ret ret_value_mode in ret_value_mode, Final_arg { partial_mode = Alloc_mode.join [arg_mode; alloc_mode] } end @@ -5885,12 +5897,12 @@ and type_function ?in_function loc attrs env (expected_mode : expected_mode) in let cases, partial = type_cases Value ?in_function env (simple_pat_mode arg_value_mode) - cases_expected_mode ty_arg_mono (mk_expected ty_res) true loc caselist in + cases_expected_mode ty_arg_mono (mk_expected ty_ret) true loc caselist in let not_nolabel_function ty = let ls, tvar = list_labels env ty in List.for_all ((<>) Nolabel) ls && not tvar in - if is_optional arg_label && not_nolabel_function ty_res then + if is_optional arg_label && not_nolabel_function ty_ret then Location.prerr_warning (List.hd cases).c_lhs.pat_loc Warnings.Unerasable_optional_argument; let param = name_cases "param" cases in @@ -5899,11 +5911,12 @@ and type_function ?in_function loc attrs env (expected_mode : expected_mode) re { exp_desc = Texp_function - { arg_label; param; cases; partial; region; curry; warnings; arg_mode; alloc_mode }; + { arg_label; param; cases; partial; region; curry; warnings; + arg_mode; arg_sort; alloc_mode; ret_sort }; exp_loc = loc; exp_extra = []; exp_type = instance (newgenty (Tarrow((arg_label,arg_mode,ret_mode), - ty_arg, ty_res, commu_ok))); + ty_arg, ty_ret, commu_ok))); exp_attributes = attrs; exp_env = env } @@ -6328,7 +6341,9 @@ and type_argument ?explanation ?recarg env (mode : expected_mode) sarg option_none env (instance (tpoly_get_mono ty_arg)) sarg.pexp_loc in - make_args ((l, Arg ty) :: args) ty_fun + (* CR layouts v5: change value assumption below when we allow + non-values in structures. *) + make_args ((l, Arg (ty, Sort.value)) :: args) ty_fun | Tarrow ((l,_,_),_,ty_res',_) when l = Nolabel || !Clflags.classic -> List.rev args, ty_fun, no_labels ty_res' | Tvar _ -> List.rev args, ty_fun, false @@ -6379,13 +6394,18 @@ and type_argument ?explanation ?recarg env (mode : expected_mode) sarg in let eta_mode = Value_mode.local_to_regional (Value_mode.of_alloc marg) in let eta_pat, eta_var = var_pair ~mode:eta_mode "eta" ty_arg in + (* CR layouts v10: When we add abstract layouts, the eta expansion here + becomes impossible in some cases - we'll need good errors and test + cases instead of `type_sort_exn`. *) + let arg_sort = type_sort_exn env ~why:Function_argument ty_arg in + let ret_sort = type_sort_exn env ~why:Function_argument ty_res in let func texp = let ret_mode = Value_mode.of_alloc mret in let e = {texp with exp_type = ty_res; exp_desc = Texp_apply (texp, - args @ [Nolabel, Arg eta_var], Nontail, + args @ [Nolabel, Arg (eta_var, arg_sort)], Nontail, Value_mode.regional_to_global_alloc ret_mode)} in let cases = [case eta_pat e] in @@ -6398,7 +6418,8 @@ and type_argument ?explanation ?recarg env (mode : expected_mode) sarg exp_desc = Texp_function { arg_label = Nolabel; param; cases; partial = Total; region = false; curry; warnings = Warnings.backup (); - arg_mode = marg; alloc_mode } } + arg_mode = marg; arg_sort; ret_sort; + alloc_mode } } in Location.prerr_warning texp.exp_loc (Warnings.Eliminated_optional_arguments @@ -6407,12 +6428,10 @@ and type_argument ?explanation ?recarg env (mode : expected_mode) sarg (Warnings.Non_principal_labels "eliminated optional argument"); (* let-expand to have side effects *) let let_pat, let_var = var_pair ~mode:exp_mode "arg" texp.exp_type in - (* CR layouts v2: `vb_sort=Sort.value` below to change when we allow - non-value function arguments. *) re { texp with exp_type = ty_fun; exp_desc = Texp_let (Nonrecursive, - [{vb_pat=let_pat; vb_expr=texp; vb_sort=Sort.value; + [{vb_pat=let_pat; vb_expr=texp; vb_sort=arg_sort; vb_attributes=[]; vb_loc=Location.none; }], func let_var) } @@ -6513,26 +6532,26 @@ and type_application env app_loc expected_mode pm | (* Special case for ignore: avoid discarding warning *) [Nolabel, sarg] when is_ignore funct -> if !Clflags.principal then begin_def () ; - let marg, ty_arg, mres, ty_res = + let {ty_arg; arg_mode; arg_sort; ty_ret; ret_mode} = filter_arrow_mono env (instance funct.exp_type) Nolabel in if !Clflags.principal then begin end_def (); - generalize_structure ty_res + generalize_structure ty_ret end; - let ap_mode = mres in + let ap_mode = ret_mode in let mode_res = - mode_cross_to_global env ty_res (Value_mode.of_alloc mres) + mode_cross_to_global env ty_ret (Value_mode.of_alloc ret_mode) in submode ~loc:app_loc ~env ~reason:Other mode_res expected_mode; - let marg = + let arg_mode = mode_argument ~funct ~index:0 ~position:(pm.apply_position) - ~partial_app:false marg + ~partial_app:false arg_mode in - let exp = type_expect env marg sarg (mk_expected ty_arg) in + let exp = type_expect env arg_mode sarg (mk_expected ty_arg) in check_partial_application ~statement:false exp; - ([Nolabel, Arg exp], ty_res, ap_mode, pm) + ([Nolabel, Arg (exp, arg_sort)], ty_ret, ap_mode, pm) | _ -> let ty = funct.exp_type in let ignore_labels = @@ -6566,8 +6585,7 @@ and type_application env app_loc expected_mode pm untyped_args in let ty_ret, mode_ret, args = - type_omitted_parameters expected_mode env - ty_ret mode_ret args + type_omitted_parameters expected_mode env ty_ret mode_ret args in check_local_application_complete ~env ~app_loc untyped_args; if !Clflags.principal then begin @@ -6694,9 +6712,14 @@ and type_statement ?explanation ?(position=RNontail) env sexp = begin_def(); let exp = type_exp env (mode_local_with_position position) sexp in end_def(); - let ty = expand_head env exp.exp_type - and tv = newvar (Layout.any ~why:Dummy_layout) - in + let ty = expand_head env exp.exp_type in + (* We're requiring the statement to have a representable layout. But that + doesn't actually rule out things like "assert false"---we'll just end up + getting a sort variable for its layout. *) + (* CR layouts v10: Abstract layouts will introduce cases where we really + have [any] and can't get a sort here. *) + let sort = Sort.new_var () in + let tv = newvar (Layout.of_sort ~why:Statement sort) in if is_Tvar ty && get_level ty > get_level tv then Location.prerr_warning (final_subexpression exp).exp_loc @@ -6706,11 +6729,11 @@ and type_statement ?explanation ?(position=RNontail) env sexp = let expected_ty = instance Predef.type_unit in with_explanation explanation (fun () -> unify_exp env exp expected_ty); - exp + exp, Sort.value else begin check_partial_application ~statement:true exp; unify_var env tv ty; - exp + exp, sort end (* Typing of match cases *) @@ -7285,7 +7308,10 @@ and type_andops env sarg sands expected_ty = let op_type = op_desc.val_type in let ty_arg = newvar (Layout.of_new_sort_var ~why:Function_argument) in let ty_rest = newvar (Layout.of_new_sort_var ~why:Function_argument) in - let ty_result = newvar (Layout.of_new_sort_var ~why:Function_result) in + let op_result_sort = Sort.new_var () in + let ty_result = + newvar (Layout.of_sort ~why:Function_result op_result_sort) + in let arrow_desc = (Nolabel,Alloc_mode.global,Alloc_mode.global) in let ty_rest_fun = newty (Tarrow(arrow_desc, newmono ty_arg, ty_result, commu_ok)) @@ -7318,6 +7344,7 @@ and type_andops env sarg sands expected_ty = bop_op_path = op_path; bop_op_val = op_desc; bop_op_type = op_type; + bop_op_return_sort = op_result_sort; bop_exp = exp; bop_loc = loc } in diff --git a/ocaml/typing/typedecl.ml b/ocaml/typing/typedecl.ml index f49571ba3c8..48a5ad061c2 100644 --- a/ocaml/typing/typedecl.ml +++ b/ocaml/typing/typedecl.ml @@ -27,7 +27,7 @@ module String = Misc.Stdlib.String type native_repr_kind = Unboxed | Untagged -type layout_sort_loc = Cstr_tuple | Record +type layout_sort_loc = Cstr_tuple | Record | External type error = Repeated_parameter @@ -1105,7 +1105,6 @@ let update_decl_layout env dpath decl = | [{Types.cd_args;cd_loc} as cstr], Variant_unboxed -> begin match cd_args with | Cstr_tuple [ty,_] -> begin - (* CR layouts: check_representable should return the sort *) check_representable ~why:(Constructor_declaration 0) env cd_loc Cstr_tuple ty; let layout = Ctype.type_layout env ty in @@ -1885,11 +1884,11 @@ let error_if_has_deep_native_repr_attributes core_type = in default_iterator.typ this_iterator core_type -let make_native_repr env core_type ty ~global_repr = +let make_native_repr env core_type sort ty ~global_repr = error_if_has_deep_native_repr_attributes core_type; match get_native_repr_attribute core_type.ptyp_attributes ~global_repr with | Native_repr_attr_absent -> - Same_as_ocaml_repr + Same_as_ocaml_repr sort | Native_repr_attr_present kind -> begin match native_repr_of_type env kind ty with | None -> @@ -1903,6 +1902,19 @@ let prim_const_mode m = | Some Local -> Prim_local | None -> assert false +(* Note that [ty] is guaranteed not to contain sort variables because it was + produced by [type_scheme], which defaults them. Further, if ty is an arrow + we know its bits are representable, so [type_sort_external] can only fail + on externals with non-arrow types. *) +(* CR layouts v3: When we allow non-representable function args/returns, the + representability argument above isn't quite right. Decide whether we want to + allow non-representable types in external args/returns then. *) +let type_sort_external ~why env loc typ = + match Ctype.type_sort ~why env typ with + | Ok s -> Sort.get_default_value s + | Error err -> + raise (Error (loc,Layout_sort {lloc = External; typ; err})) + let rec parse_native_repr_attributes env core_type ty rmode ~global_repr = match core_type.ptyp_desc, get_desc ty, get_native_repr_attribute core_type.ptyp_attributes ~global_repr:None @@ -1912,7 +1924,10 @@ let rec parse_native_repr_attributes env core_type ty rmode ~global_repr = | Ptyp_arrow (_, ct1, ct2), Tarrow ((_,marg,mret), t1, t2, _), _ when not (Builtin_attributes.has_curry core_type.ptyp_attributes) -> let t1, _ = Btype.tpoly_get_poly t1 in - let repr_arg = make_native_repr env ct1 t1 ~global_repr in + let sort_arg = + type_sort_external ~why:External_argument env ct1.ptyp_loc t1 + in + let repr_arg = make_native_repr env ct1 sort_arg t1 ~global_repr in let mode = if Builtin_attributes.has_local_opt ct1.ptyp_attributes then Prim_poly @@ -1921,7 +1936,7 @@ let rec parse_native_repr_attributes env core_type ty rmode ~global_repr = let repr_args, repr_res = parse_native_repr_attributes env ct2 t2 (prim_const_mode mret) ~global_repr in - ((mode,repr_arg) :: repr_args, repr_res) + ((mode, repr_arg) :: repr_args, repr_res) | (Ptyp_poly (_, t) | Ptyp_alias (t, _)), _, _ -> parse_native_repr_attributes env t ty rmode ~global_repr | _ -> @@ -1930,8 +1945,10 @@ let rec parse_native_repr_attributes env core_type ty rmode ~global_repr = then Prim_poly else rmode in - ([], (rmode, make_native_repr env core_type ty ~global_repr)) - + let sort_res = + type_sort_external ~why:External_result env core_type.ptyp_loc ty + in + ([], (rmode, make_native_repr env core_type sort_res ty ~global_repr)) let check_unboxable env loc ty = let rec check_type acc ty : Path.Set.t = @@ -2508,6 +2525,7 @@ let report_error ppf = function match lloc with | Cstr_tuple -> "Constructor argument" | Record -> "Record element" + | External -> "External" in fprintf ppf "@[%s types must have a representable layout.@ \ %a@]" s (Layout.Violation.report_with_offender diff --git a/ocaml/typing/typedecl.mli b/ocaml/typing/typedecl.mli index e0c3556b8e3..3c0b732b150 100644 --- a/ocaml/typing/typedecl.mli +++ b/ocaml/typing/typedecl.mli @@ -66,7 +66,7 @@ val is_fixed_type : Parsetree.type_declaration -> bool type native_repr_kind = Unboxed | Untagged (* Records reason for a layout representability requirement in errors. *) -type layout_sort_loc = Cstr_tuple | Record +type layout_sort_loc = Cstr_tuple | Record | External type error = Repeated_parameter diff --git a/ocaml/typing/typedtree.ml b/ocaml/typing/typedtree.ml index d388bb7d6a9..d4ccd1ddbbc 100644 --- a/ocaml/typing/typedtree.ml +++ b/ocaml/typing/typedtree.ml @@ -113,6 +113,8 @@ and expression_desc = region : bool; curry : fun_curry_state; warnings : Warnings.state; arg_mode : Types.alloc_mode; + arg_sort : sort; + ret_sort : sort; alloc_mode : Types.alloc_mode } | Texp_apply of expression * (arg_label * apply_arg) list * apply_position * Types.alloc_mode | Texp_match of expression * sort * computation case list * partial @@ -134,11 +136,11 @@ and expression_desc = | Texp_list_comprehension of comprehension | Texp_array_comprehension of mutable_flag * comprehension | Texp_ifthenelse of expression * expression * expression option - | Texp_sequence of expression * layout * expression + | Texp_sequence of expression * sort * expression | Texp_while of { wh_cond : expression; wh_body : expression; - wh_body_layout : layout + wh_body_sort : sort } | Texp_for of { for_id : Ident.t; @@ -147,7 +149,7 @@ and expression_desc = for_to : expression; for_dir : direction_flag; for_body : expression; - for_body_layout : Layouts.layout; + for_body_sort : sort; } | Texp_send of expression * meth * apply_position * Types.alloc_mode | Texp_new of @@ -167,7 +169,9 @@ and expression_desc = let_ : binding_op; ands : binding_op list; param : Ident.t; + param_sort : sort; body : value case; + body_sort : sort; partial : partial; warnings : Warnings.state; } @@ -229,6 +233,7 @@ and binding_op = bop_op_name : string loc; bop_op_val : Types.value_description; bop_op_type : Types.type_expr; + bop_op_return_sort : sort; bop_exp : expression; bop_loc : Location.t; } @@ -241,10 +246,9 @@ and omitted_parameter = { mode_closure : alloc_mode; mode_arg : alloc_mode; mode_ret : alloc_mode; - ty_arg : Types.type_expr; - ty_env : Env.t } + sort_arg : sort } -and apply_arg = (expression, omitted_parameter) arg_or_omitted +and apply_arg = (expression * sort, omitted_parameter) arg_or_omitted and apply_position = | Tail diff --git a/ocaml/typing/typedtree.mli b/ocaml/typing/typedtree.mli index 0ef4e177160..a1dffe4d3d8 100644 --- a/ocaml/typing/typedtree.mli +++ b/ocaml/typing/typedtree.mli @@ -214,6 +214,8 @@ and expression_desc = region : bool; curry : fun_curry_state; warnings : Warnings.state; arg_mode : Types.alloc_mode; + arg_sort : Layouts.sort; + ret_sort : Layouts.sort; alloc_mode : Types.alloc_mode} (** [Pexp_fun] and [Pexp_function] both translate to [Texp_function]. See {!Parsetree} for more details. @@ -303,15 +305,11 @@ and expression_desc = | Texp_list_comprehension of comprehension | Texp_array_comprehension of mutable_flag * comprehension | Texp_ifthenelse of expression * expression * expression option - | Texp_sequence of expression * Layouts.layout * expression - (* CR layouts v5: The layout above is only used for the void sanity check now. - Remove it at an appropriate time. *) + | Texp_sequence of expression * Layouts.sort * expression | Texp_while of { wh_cond : expression; wh_body : expression; - wh_body_layout : Layouts.layout - (* CR layouts v5: The layout above is only used for the void sanity check - now. Remove it at an appropriate time. *) + wh_body_sort : Layouts.sort } | Texp_for of { for_id : Ident.t; @@ -320,9 +318,7 @@ and expression_desc = for_to : expression; for_dir : direction_flag; for_body : expression; - for_body_layout : Layouts.layout; - (* CR layouts v5: The layout above is only used for the void sanity check - now. Remove it at an appropriate time. *) + for_body_sort : Layouts.sort; } | Texp_send of expression * meth * apply_position * Types.alloc_mode (** [alloc_mode] is the allocation mode of the result *) @@ -343,7 +339,9 @@ and expression_desc = let_ : binding_op; ands : binding_op list; param : Ident.t; + param_sort : Layouts.sort; body : value case; + body_sort : Layouts.sort; partial : partial; warnings : Warnings.state; } @@ -416,6 +414,7 @@ and binding_op = bop_op_type : Types.type_expr; (* This is the type at which the operator was used. It is always an instance of [bop_op_val.val_type] *) + bop_op_return_sort : Layouts.sort; bop_exp : expression; bop_loc : Location.t; } @@ -428,12 +427,9 @@ and omitted_parameter = { mode_closure : Types.alloc_mode; mode_arg : Types.alloc_mode; mode_ret : Types.alloc_mode; - (* CR ncourant: actually, we only need this to be able to compute the layout - in [Translcore], change this when merging with the front-end. *) - ty_arg : Types.type_expr; - ty_env : Env.t} + sort_arg : Layouts.sort } -and apply_arg = (expression, omitted_parameter) arg_or_omitted +and apply_arg = (expression * Layouts.sort, omitted_parameter) arg_or_omitted and apply_position = | Tail (* must be tail-call optimised *) diff --git a/ocaml/typing/typeopt.ml b/ocaml/typing/typeopt.ml index 1978a50b75f..48eb70aebee 100644 --- a/ocaml/typing/typeopt.ml +++ b/ocaml/typing/typeopt.ml @@ -27,6 +27,8 @@ open Lambda stuff. *) type error = Non_value_layout of type_expr * Layout.Violation.t + | Non_value_sort of type_expr + | Non_value_sort_unknown_ty exception Error of Location.t * error @@ -484,20 +486,41 @@ let value_kind env loc ty = in value_kind -(* CR layouts v2: We'll have other layouts. Think about what to do with the - sanity check in value_kind. *) -let layout env loc ty = Lambda.Pvalue (value_kind env loc ty) +(* CR layouts v2: We are planning to put a sanity check here that you don't get + passed float# as the sort unless layouts_alpha is on. This violates our + previous rule that extensions only control syntax, but seems like a nice + implementation of a sanity check, since the availability of the Float_u + module will result in ways to get at unboxed floats that aren't just writing + #float in your program. -let function_return_layout env loc ty = + We also do the void sanity check here. We do it in value_kind as well, + because the sort argument here is sometimes not computed from the type or + typed tree, but just one of the defaults from layouts.ml. +*) +let layout env loc sort ty = + match Layouts.Sort.get_default_value sort with + | Void -> raise (Error (loc, Non_value_sort ty)) + | Value -> Lambda.Pvalue (value_kind env loc ty) + +let layout_of_sort loc sort = + match Layouts.Sort.get_default_value sort with + | Void -> raise (Error (loc, Non_value_sort_unknown_ty)) + | Value -> Lambda.Pvalue Pgenval + +let function_return_layout env loc sort ty = match is_function_type env ty with - | Some (_lhs, rhs) -> layout env loc rhs + | Some (_lhs, rhs) -> layout env loc sort rhs | None -> Misc.fatal_errorf "function_return_layout called on non-function type" -let function2_return_layout env loc ty = +let function2_return_layout env loc sort ty = match is_function_type env ty with - | Some (_lhs, rhs) -> function_return_layout env loc rhs + | Some (_lhs, rhs) -> function_return_layout env loc sort rhs | None -> Misc.fatal_errorf "function_return_layout called on non-function type" +let function_arg_layout env loc sort ty = + match is_function_type env ty with + | Some (arg_type, _) -> layout env loc sort arg_type + | None -> Misc.fatal_error "function_arg_layout called on non-function type" (** Whether a forward block is needed for a lazy thunk on a value, i.e. if the value can be represented as a float/forward/lazy *) @@ -559,6 +582,15 @@ let report_error ppf = function the Jane Street compilers team.@ %a" (Layout.Violation.report_with_offender ~offender:(fun ppf -> Printtyp.type_expr ppf ty)) err + | Non_value_sort ty -> + fprintf ppf + "Non-value detected in [Typeopt.layout] as sort for type@ %a.@ \ + Please report this error to the Jane Street compilers team." + Printtyp.type_expr ty + | Non_value_sort_unknown_ty -> + fprintf ppf + "Non-value detected in [layout_of_sort]@ Please report this \ + error to the Jane Street compilers team." let () = Location.register_error_of_exn diff --git a/ocaml/typing/typeopt.mli b/ocaml/typing/typeopt.mli index 767b4ac4683..262e705fa45 100644 --- a/ocaml/typing/typeopt.mli +++ b/ocaml/typing/typeopt.mli @@ -30,17 +30,33 @@ val bigarray_type_kind_and_layout : Env.t -> Types.type_expr -> Lambda.bigarray_kind * Lambda.bigarray_layout (* CR layouts: `layout` should have a `sort` argument. *) -(* CR layouts v2: [layout], [function_return_layout] and - [function2_return_layout] have had location arguments added just to support - the void check error message. These arguments can be removed when we're - happy to take that check out. *) -val layout : Env.t -> Location.t -> Types.type_expr -> Lambda.layout +(* CR layouts v2: [layout], [function_return_layout], [function2_return_layout], + and [layout_of_sort] have had location arguments added just to support the + void check error message. These arguments can be removed when we're happy to + take that check out. *) +val layout : + Env.t -> Location.t -> Layouts.sort -> Types.type_expr -> Lambda.layout +(* This translates a type system sort to a lambda layout. The function [layout] + gives a more precise result---this should only be used when the precise + Lambda.layout isn't needed for optimization. *) +val layout_of_sort : Location.t -> Layouts.sort -> Lambda.layout + +(* Given a function type and the sort of its return type, compute the layout of + its return type. *) val function_return_layout : - Env.t -> Location.t -> Types.type_expr -> Lambda.layout -(* Gives the return layout of a function with two arguments. *) + Env.t -> Location.t -> Layouts.sort -> Types.type_expr -> Lambda.layout + +(* Given a function type with two arguments and the sort of its return type, + compute the layout of its return type. *) val function2_return_layout : - Env.t -> Location.t -> Types.type_expr -> Lambda.layout + Env.t -> Location.t -> Layouts.sort -> Types.type_expr -> Lambda.layout + +(* Given a function type and the sort of its argument, compute the layout + of its argument. Fails loudly if the type isn't a function type. *) +val function_arg_layout : + Env.t -> Location.t -> Layouts.sort -> Types.type_expr -> Lambda.layout + val classify_lazy_argument : Typedtree.expression -> [ `Constant_or_function diff --git a/ocaml/typing/untypeast.ml b/ocaml/typing/untypeast.ml index 08fa37d8a0f..f10866552f0 100644 --- a/ocaml/typing/untypeast.ml +++ b/ocaml/typing/untypeast.ml @@ -493,7 +493,7 @@ let expression sub exp = List.fold_right (fun (label, arg) list -> match arg with | Omitted _ -> list - | Arg exp -> (label, sub.expr sub exp) :: list + | Arg (exp, _) -> (label, sub.expr sub exp) :: list ) list []) | Texp_match (exp, _, cases, _) -> Pexp_match (sub.expr sub exp, List.map (sub.case sub) cases) @@ -835,7 +835,7 @@ let class_expr sub cexpr = List.fold_right (fun (label, expo) list -> match expo with | Omitted _ -> list - | Arg exp -> (label, sub.expr sub exp) :: list + | Arg (exp, _) -> (label, sub.expr sub exp) :: list ) args []) | Tcl_let (rec_flat, bindings, _ivars, cl) -> From 316dde1e07fb34fb0ec0849feae31217ea17bcfc Mon Sep 17 00:00:00 2001 From: Richard Eisenberg Date: Fri, 16 Jun 2023 13:40:15 -0400 Subject: [PATCH 2/6] Add failing test for type_sort_exn failure --- .../typing-layouts-missing-cmi/function_a.ml | 3 +++ .../typing-layouts-missing-cmi/function_arg.ml | 17 +++++++++++++++++ .../typing-layouts-missing-cmi/function_b.ml | 3 +++ 3 files changed, 23 insertions(+) create mode 100644 ocaml/testsuite/tests/typing-layouts-missing-cmi/function_a.ml create mode 100644 ocaml/testsuite/tests/typing-layouts-missing-cmi/function_arg.ml create mode 100644 ocaml/testsuite/tests/typing-layouts-missing-cmi/function_b.ml diff --git a/ocaml/testsuite/tests/typing-layouts-missing-cmi/function_a.ml b/ocaml/testsuite/tests/typing-layouts-missing-cmi/function_a.ml new file mode 100644 index 00000000000..f18979e3c71 --- /dev/null +++ b/ocaml/testsuite/tests/typing-layouts-missing-cmi/function_a.ml @@ -0,0 +1,3 @@ + +type t = Mk of int + diff --git a/ocaml/testsuite/tests/typing-layouts-missing-cmi/function_arg.ml b/ocaml/testsuite/tests/typing-layouts-missing-cmi/function_arg.ml new file mode 100644 index 00000000000..d832091bc67 --- /dev/null +++ b/ocaml/testsuite/tests/typing-layouts-missing-cmi/function_arg.ml @@ -0,0 +1,17 @@ +(* TEST + +readonly_files = "function_a.ml function_b.ml" +* setup-ocamlc.byte-build-env +** ocamlc.byte +module = "function_a.ml" +*** ocamlc.byte +module = "function_b.ml" +**** script +script = "rm -f function_a.cmi" +***** expect +*) + +#directory "ocamlc.byte";; +#load "function_b.cmo";; + +let f : Function_b.fun_t = fun ~arg1:_ ~arg2 -> arg2 diff --git a/ocaml/testsuite/tests/typing-layouts-missing-cmi/function_b.ml b/ocaml/testsuite/tests/typing-layouts-missing-cmi/function_b.ml new file mode 100644 index 00000000000..b5ebc4fcf15 --- /dev/null +++ b/ocaml/testsuite/tests/typing-layouts-missing-cmi/function_b.ml @@ -0,0 +1,3 @@ + +type fun_t = arg1:Function_a.t -> arg2:Function_a.t -> Function_a.t + From 3cee7e03da5c6ba9b5adae6dcb3da7e9d3c0d990 Mon Sep 17 00:00:00 2001 From: Richard Eisenberg Date: Fri, 16 Jun 2023 14:23:59 -0400 Subject: [PATCH 3/6] Remove some type_sort_exns --- ocaml/typing/typecore.ml | 76 ++++++++++++++++++++++++--------------- ocaml/typing/typecore.mli | 2 +- 2 files changed, 49 insertions(+), 29 deletions(-) diff --git a/ocaml/typing/typecore.ml b/ocaml/typing/typecore.ml index 14797f82241..dfa4fdbb235 100644 --- a/ocaml/typing/typecore.ml +++ b/ocaml/typing/typecore.ml @@ -192,6 +192,7 @@ type error = | Layout_not_enabled of Layout.const | Unboxed_int_literals_not_supported | Unboxed_float_literals_not_supported + | Function_arg_not_rep of type_expr * Layout.Violation.t exception Error of Location.t * Env.t * error exception Error_forward of Location.error @@ -3000,6 +3001,7 @@ type untyped_apply_arg = { sarg : Parsetree.expression; ty_arg : type_expr; ty_arg0 : type_expr; + sort_arg : sort; commuted : bool; mode_fun : Alloc_mode.t; mode_arg : Alloc_mode.t; @@ -3007,11 +3009,13 @@ type untyped_apply_arg = | Unknown_arg of { sarg : Parsetree.expression; ty_arg_mono : type_expr; + sort_arg : sort; mode_fun : Alloc_mode.t; mode_arg : Alloc_mode.t; } | Eliminated_optional_arg of { mode_fun: Alloc_mode.t; ty_arg : type_expr; + sort_arg : sort; mode_arg : Alloc_mode.t; level: int; } @@ -3019,7 +3023,8 @@ type untyped_omitted_param = { mode_fun: Alloc_mode.t; ty_arg : type_expr; mode_arg : Alloc_mode.t; - level: int; } + level: int; + sort_arg : sort } let is_partial_apply args = List.exists @@ -3121,12 +3126,13 @@ let collect_unknown_apply_args env funct ty_fun mode_fun rev_args sargs ret_tvar match sargs with | [] -> ty_fun, mode_fun, List.rev rev_args | (lbl, sarg) :: rest -> - let (mode_arg, ty_arg_mono, mode_ret, ty_res) = + let (sort_arg, mode_arg, ty_arg_mono, mode_ret, ty_res) = let ty_fun = expand_head env ty_fun in match get_desc ty_fun with | Tvar _ -> + let sort_arg = Sort.new_var () in let ty_arg_mono = - newvar (Layout.of_new_sort_var ~why:Function_argument) + newvar (Layout.of_sort ~why:Function_argument sort_arg) in let ty_arg = newmono ty_arg_mono in let ty_res = @@ -3143,10 +3149,16 @@ let collect_unknown_apply_args env funct ty_fun mode_fun rev_args sargs ret_tvar let kind = (lbl, mode_arg, mode_ret) in unify env ty_fun (newty (Tarrow(kind,ty_arg,ty_res,commu_var ()))); - (mode_arg, ty_arg_mono, mode_ret, ty_res) + (sort_arg, mode_arg, ty_arg_mono, mode_ret, ty_res) | Tarrow ((l, mode_arg, mode_ret), ty_arg, ty_res, _) when labels_match ~param:l ~arg:lbl -> - (mode_arg, tpoly_get_mono ty_arg, mode_ret, ty_res) + let sort_arg = + match type_sort ~why:Function_argument env ty_arg with + | Ok sort -> sort + | Error err -> raise(Error(funct.exp_loc, env, + Function_arg_not_rep (ty_arg,err))) + in + (sort_arg, mode_arg, tpoly_get_mono ty_arg, mode_ret, ty_res) | td -> let ty_fun = match td with Tarrow _ -> newty td | _ -> ty_fun in let ty_res = remaining_function_type ty_fun mode_fun rev_args in @@ -3160,9 +3172,11 @@ let collect_unknown_apply_args env funct ty_fun mode_fun rev_args sargs ret_tvar | _ -> raise(Error(funct.exp_loc, env, Apply_non_function (expand_head env funct.exp_type))) - in - let arg = Unknown_arg { sarg; ty_arg_mono; mode_fun; mode_arg } in - loop ty_res mode_ret ((lbl, Arg arg) :: rev_args) rest + in + let arg = + Unknown_arg { sarg; ty_arg_mono; mode_fun; mode_arg; sort_arg } + in + loop ty_res mode_ret ((lbl, Arg arg) :: rev_args) rest in loop ty_fun mode_fun rev_args sargs @@ -3170,10 +3184,11 @@ let collect_apply_args env funct ignore_labels ty_fun ty_fun0 mode_fun sargs ret let warned = ref false in let rec loop ty_fun ty_fun0 mode_fun rev_args sargs = let ty_fun' = expand_head env ty_fun in - match get_desc ty_fun', get_desc (expand_head env ty_fun0) with + match get_desc ty_fun', get_desc (expand_head env ty_fun0), sargs with | Tarrow (ad, ty_arg, ty_ret, com), - Tarrow (_, ty_arg0, ty_ret0, _) - when sargs <> [] && is_commu_ok com -> + Tarrow (_, ty_arg0, ty_ret0, _), + (_, sarg1) :: _ + when is_commu_ok com -> let lv = get_level ty_fun' in let (l, mode_arg, mode_ret) = ad in let may_warn loc w = @@ -3183,6 +3198,11 @@ let collect_apply_args env funct ignore_labels ty_fun ty_fun0 mode_fun sargs ret Location.prerr_warning loc w end in + let sort_arg = match type_sort ~why:Function_argument env ty_arg with + | Ok sort -> sort + | Error err -> raise(Error(sarg1.pexp_loc, env, + Function_arg_not_rep(ty_arg, err))) + in let name = label_name l and optional = is_optional l in let use_arg ~commuted sarg l' = @@ -3191,7 +3211,7 @@ let collect_apply_args env funct ignore_labels ty_fun ty_fun0 mode_fun sargs ret may_warn sarg.pexp_loc (Warnings.Not_principal "using an optional argument here"); Arg (Known_arg - { sarg; ty_arg; ty_arg0; commuted; + { sarg; ty_arg; ty_arg0; commuted; sort_arg; mode_fun; mode_arg; wrapped_in_some }) in let eliminate_optional_arg () = @@ -3199,7 +3219,7 @@ let collect_apply_args env funct ignore_labels ty_fun ty_fun0 mode_fun sargs ret (Warnings.Non_principal_labels "eliminated optional argument"); Arg (Eliminated_optional_arg - { mode_fun; ty_arg; mode_arg; level = lv }) + { mode_fun; ty_arg; mode_arg; sort_arg; level = lv }) in let remaining_sargs, arg = if ignore_labels then begin @@ -3242,7 +3262,7 @@ let collect_apply_args env funct ignore_labels ty_fun ty_fun0 mode_fun sargs ret it. *) may_warn funct.exp_loc (Warnings.Non_principal_labels "commuted an argument"); - Omitted { mode_fun; ty_arg; mode_arg; level = lv } + Omitted { mode_fun; ty_arg; mode_arg; level = lv; sort_arg } end in loop ty_ret ty_ret0 mode_ret ((l, arg) :: rev_args) remaining_sargs @@ -3258,14 +3278,11 @@ let type_omitted_parameters expected_mode env ty_ret mode_ret args = List.fold_left (fun (ty_ret, mode_ret, open_args, closed_args, args) (lbl, arg) -> match arg with - | Arg (exp, exp_mode) -> + | Arg (exp, exp_mode, sort) -> let open_args = (exp_mode, exp) :: open_args in - let sort = - type_sort_exn ~why:Function_argument exp.exp_env exp.exp_type - in let args = (lbl, Arg (exp, sort)) :: args in (ty_ret, mode_ret, open_args, closed_args, args) - | Omitted { mode_fun; ty_arg; mode_arg; level } -> + | Omitted { mode_fun; ty_arg; mode_arg; level; sort_arg } -> let arrow_desc = (lbl, mode_arg, mode_ret) in let ty_ret = newty2 ~level @@ -3283,9 +3300,6 @@ let type_omitted_parameters expected_mode env ty_ret mode_ret args = let open_args = [] in let mode_closure = Alloc_mode.join (mode_fun :: closed_args) in register_allocation_mode mode_closure; - let sort_arg = - type_sort_exn ~why:Function_argument env ty_arg - in let arg = Omitted { mode_closure; mode_arg; mode_ret; sort_arg } in let args = (lbl, arg) :: args in (ty_ret, mode_closure, open_args, closed_args, args)) @@ -6446,7 +6460,7 @@ and type_argument ?explanation ?recarg env (mode : expected_mode) sarg and type_apply_arg env ~app_loc ~funct ~index ~position ~partial_app (lbl, arg) = match arg with - | Arg (Unknown_arg { sarg; ty_arg_mono; mode_arg }) -> + | Arg (Unknown_arg { sarg; ty_arg_mono; mode_arg; sort_arg }) -> let mode, _ = Alloc_mode.newvar_below mode_arg in let expected_mode = mode_argument ~funct ~index ~position ~partial_app mode in @@ -6457,9 +6471,9 @@ and type_apply_arg env ~app_loc ~funct ~index ~position ~partial_app (lbl, arg) (* CR layouts v5: relax value requirement *) unify_exp env arg (type_option(newvar (Layout.value ~why:Type_argument))); - (lbl, Arg (arg, expected_mode.mode)) + (lbl, Arg (arg, expected_mode.mode, sort_arg)) | Arg (Known_arg { sarg; ty_arg; ty_arg0; - mode_arg; wrapped_in_some }) -> + mode_arg; wrapped_in_some; sort_arg }) -> let mode, _ = Alloc_mode.newvar_below mode_arg in let expected_mode = mode_argument ~funct ~index ~position ~partial_app mode in @@ -6515,10 +6529,10 @@ and type_apply_arg env ~app_loc ~funct ~index ~position ~partial_app (lbl, arg) {arg with exp_type = instance arg.exp_type} end in - (lbl, Arg (arg, expected_mode.mode)) - | Arg (Eliminated_optional_arg { ty_arg; _ }) -> + (lbl, Arg (arg, expected_mode.mode, sort_arg)) + | Arg (Eliminated_optional_arg { ty_arg; sort_arg; _ }) -> let arg = option_none env (instance ty_arg) Location.none in - (lbl, Arg (arg, Value_mode.global)) + (lbl, Arg (arg, Value_mode.global, sort_arg)) | Omitted _ as arg -> (lbl, arg) and type_application env app_loc expected_mode pm @@ -8397,6 +8411,12 @@ let report_error ~loc env = function | Unboxed_float_literals_not_supported -> Location.errorf ~loc "@[Unboxed float literals aren't supported yet.@]" + | Function_arg_not_rep (ty_arg,violation) -> + Location.errorf ~loc + "@[Function argument of type %a@ is not representable.@]@ %a" + Printtyp.type_expr ty_arg + (Layout.Violation.report_with_offender + ~offender:(fun ppf -> Printtyp.type_expr ppf ty_arg)) violation let report_error ~loc env err = Printtyp.wrap_printing_env ~error:true env diff --git a/ocaml/typing/typecore.mli b/ocaml/typing/typecore.mli index 44a7a07e1a7..6446704f6b9 100644 --- a/ocaml/typing/typecore.mli +++ b/ocaml/typing/typecore.mli @@ -269,7 +269,7 @@ type error = | Layout_not_enabled of Layout.const | Unboxed_int_literals_not_supported | Unboxed_float_literals_not_supported - + | Function_arg_not_rep of type_expr * Layout.Violation.t exception Error of Location.t * Env.t * error exception Error_forward of Location.error From ef5b4ae763d6d0fd699ffacdead27740d4cf3ed5 Mon Sep 17 00:00:00 2001 From: Richard Eisenberg Date: Fri, 16 Jun 2023 14:32:07 -0400 Subject: [PATCH 4/6] More tests --- .../function_arg.ml | 21 ++++++++++++++++++- .../typing-layouts-missing-cmi/function_b.ml | 2 +- 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/ocaml/testsuite/tests/typing-layouts-missing-cmi/function_arg.ml b/ocaml/testsuite/tests/typing-layouts-missing-cmi/function_arg.ml index d832091bc67..6ae408e3201 100644 --- a/ocaml/testsuite/tests/typing-layouts-missing-cmi/function_arg.ml +++ b/ocaml/testsuite/tests/typing-layouts-missing-cmi/function_arg.ml @@ -14,4 +14,23 @@ script = "rm -f function_a.cmi" #directory "ocamlc.byte";; #load "function_b.cmo";; -let f : Function_b.fun_t = fun ~arg1:_ ~arg2 -> arg2 +(* This tests that sorts are correctly extracted from function types, + even in the presence of a missing cmi file. *) + +let f0 (g : Function_b.fun_t) = g ~arg1:(assert false) + +[%%expect{| +blah +|}] + +let f1 (g : Function_b.fun_t) = g () + +[%%expect{| +blah +|}] + +let f2 : Function_b.fun_t = fun ~arg1:_ ~arg2 () -> arg2 + +[%%expect{| +blah +|}] diff --git a/ocaml/testsuite/tests/typing-layouts-missing-cmi/function_b.ml b/ocaml/testsuite/tests/typing-layouts-missing-cmi/function_b.ml index b5ebc4fcf15..c4645fc4bf6 100644 --- a/ocaml/testsuite/tests/typing-layouts-missing-cmi/function_b.ml +++ b/ocaml/testsuite/tests/typing-layouts-missing-cmi/function_b.ml @@ -1,3 +1,3 @@ -type fun_t = arg1:Function_a.t -> arg2:Function_a.t -> Function_a.t +type fun_t = arg1:Function_a.t -> arg2:Function_a.t -> unit -> Function_a.t From 330d35832924d2a291c82488b534b9f4671598bb Mon Sep 17 00:00:00 2001 From: Richard Eisenberg Date: Fri, 16 Jun 2023 15:45:12 -0400 Subject: [PATCH 5/6] Finish getting rid of type_sort_exn --- .../function_arg.ml | 64 +++++++++++++++++- .../typing-layouts-missing-cmi/function_b.ml | 6 ++ ocaml/typing/ctype.ml | 15 +++-- ocaml/typing/ctype.mli | 7 +- ocaml/typing/typecore.ml | 66 ++++++++++--------- ocaml/typing/typecore.mli | 2 +- 6 files changed, 111 insertions(+), 49 deletions(-) diff --git a/ocaml/testsuite/tests/typing-layouts-missing-cmi/function_arg.ml b/ocaml/testsuite/tests/typing-layouts-missing-cmi/function_arg.ml index 6ae408e3201..98f31cdf84b 100644 --- a/ocaml/testsuite/tests/typing-layouts-missing-cmi/function_arg.ml +++ b/ocaml/testsuite/tests/typing-layouts-missing-cmi/function_arg.ml @@ -20,17 +20,75 @@ script = "rm -f function_a.cmi" let f0 (g : Function_b.fun_t) = g ~arg1:(assert false) [%%expect{| -blah +Line 1, characters 40-54: +1 | let f0 (g : Function_b.fun_t) = g ~arg1:(assert false) + ^^^^^^^^^^^^^^ +Error: Function arguments and returns must be representable. + Function_a.t has an unknown layout, which might not be representable. + No .cmi file found containing Function_a.t. + Hint: Adding "function_a" to your dependencies might help. |}] let f1 (g : Function_b.fun_t) = g () [%%expect{| -blah +Line 1, characters 34-36: +1 | let f1 (g : Function_b.fun_t) = g () + ^^ +Error: Function arguments and returns must be representable. + Function_a.t has an unknown layout, which might not be representable. + No .cmi file found containing Function_a.t. + Hint: Adding "function_a" to your dependencies might help. |}] let f2 : Function_b.fun_t = fun ~arg1:_ ~arg2 () -> arg2 [%%expect{| -blah +Line 1, characters 28-56: +1 | let f2 : Function_b.fun_t = fun ~arg1:_ ~arg2 () -> arg2 + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Error: Function arguments and returns must be representable. + Function_a.t has an unknown layout, which might not be representable. + No .cmi file found containing Function_a.t. + Hint: Adding "function_a" to your dependencies might help. +|}] + +let f3 : Function_b.return_t = fun () -> assert false + +[%%expect{| +Line 1, characters 31-53: +1 | let f3 : Function_b.return_t = fun () -> assert false + ^^^^^^^^^^^^^^^^^^^^^^ +Error: Function arguments and returns must be representable. + Function_a.t has an unknown layout, which might not be representable. + No .cmi file found containing Function_a.t. + Hint: Adding "function_a" to your dependencies might help. +|}] + +let f4 (_ : Function_b.take_t) = () +let x1 = f4 Function_b.f_opt + +[%%expect{| +val f4 : Function_b.take_t -> unit = +Line 2, characters 12-28: +2 | let x1 = f4 Function_b.f_opt + ^^^^^^^^^^^^^^^^ +Error: Function arguments and returns must be representable. + Function_a.t has an unknown layout, which might not be representable. + No .cmi file found containing Function_a.t. + Hint: Adding "function_a" to your dependencies might help. +|}] + +let f5 (_ : Function_b.return_t) = () +let x2 = f5 Function_b.f_opt_2 + +[%%expect{| +val f5 : Function_b.return_t -> unit = +Line 2, characters 12-30: +2 | let x2 = f5 Function_b.f_opt_2 + ^^^^^^^^^^^^^^^^^^ +Error: Function arguments and returns must be representable. + Function_a.t has an unknown layout, which might not be representable. + No .cmi file found containing Function_a.t. + Hint: Adding "function_a" to your dependencies might help. |}] diff --git a/ocaml/testsuite/tests/typing-layouts-missing-cmi/function_b.ml b/ocaml/testsuite/tests/typing-layouts-missing-cmi/function_b.ml index c4645fc4bf6..5afc4484a19 100644 --- a/ocaml/testsuite/tests/typing-layouts-missing-cmi/function_b.ml +++ b/ocaml/testsuite/tests/typing-layouts-missing-cmi/function_b.ml @@ -1,3 +1,9 @@ type fun_t = arg1:Function_a.t -> arg2:Function_a.t -> unit -> Function_a.t +type take_t = Function_a.t -> unit +type return_t = unit -> Function_a.t + +let f_opt : ?opt:int -> Function_a.t -> unit = fun ?opt _ -> () +let f_opt_2 : ?opt:int -> unit -> Function_a.t = fun ?opt _ -> assert false + diff --git a/ocaml/typing/ctype.ml b/ocaml/typing/ctype.ml index 5e33c347bf1..10cf12857c1 100644 --- a/ocaml/typing/ctype.ml +++ b/ocaml/typing/ctype.ml @@ -2075,11 +2075,6 @@ let type_sort ~why env ty = | Ok _ -> Ok sort | Error _ as e -> e -let type_sort_exn ~why env ty = - match type_sort ~why env ty with - | Ok s -> s - | Error _ -> Misc.fatal_error "Ctype.type_sort_exn on non-sort" - (* Note: Because [estimate_type_layout] actually returns an upper bound, this function computes an inaccurate intersection in some cases. @@ -3776,6 +3771,7 @@ type filter_arrow_failure = ; expected_type : type_expr } | Not_a_function + | Layout_error of type_expr * Layout.Violation.t exception Filter_arrow_failed of filter_arrow_failure @@ -3854,8 +3850,13 @@ let filter_arrow env t l ~force_tpoly = entirely by storing sorts on [TArrow], but that seems incompatible with the future plan to shift the layout requirements from the types to the terms. *) - let arg_sort = type_sort_exn ~why:Function_argument env ty_arg in - let ret_sort = type_sort_exn ~why:Function_argument env ty_ret in + let type_sort ~why ty = + match type_sort ~why env ty with + | Ok sort -> sort + | Error err -> raise (Filter_arrow_failed (Layout_error (ty, err))) + in + let arg_sort = type_sort ~why:Function_argument ty_arg in + let ret_sort = type_sort ~why:Function_result ty_ret in { ty_arg; arg_mode; arg_sort; ty_ret; ret_mode; ret_sort } else raise (Filter_arrow_failed (Label_mismatch diff --git a/ocaml/typing/ctype.mli b/ocaml/typing/ctype.mli index 43571efc192..60846b8440e 100644 --- a/ocaml/typing/ctype.mli +++ b/ocaml/typing/ctype.mli @@ -305,6 +305,7 @@ type filter_arrow_failure = ; expected_type : type_expr } | Not_a_function + | Layout_error of type_expr * Layout.Violation.t exception Filter_arrow_failed of filter_arrow_failure @@ -498,12 +499,6 @@ val type_sort : why:Layouts.Layout.concrete_layout_reason -> Env.t -> type_expr -> (sort, Layout.Violation.t) result -(* Same as [type_sort], but only safe to call on types known to be a sort. - For example, if the type is used as an argument in a function type that - has already been translated. *) -val type_sort_exn : - why:Layouts.Layout.concrete_layout_reason -> Env.t -> type_expr -> sort - (* Layout checking. [constrain_type_layout] will update the layout of type variables to make the check true, if possible. [check_decl_layout] and [check_type_layout] won't, but will still instantiate sort variables. diff --git a/ocaml/typing/typecore.ml b/ocaml/typing/typecore.ml index dfa4fdbb235..17cc37ea608 100644 --- a/ocaml/typing/typecore.ml +++ b/ocaml/typing/typecore.ml @@ -192,11 +192,24 @@ type error = | Layout_not_enabled of Layout.const | Unboxed_int_literals_not_supported | Unboxed_float_literals_not_supported - | Function_arg_not_rep of type_expr * Layout.Violation.t + | Function_type_not_rep of type_expr * Layout.Violation.t exception Error of Location.t * Env.t * error exception Error_forward of Location.error +let error_of_filter_arrow_failure ~explanation in_function ty_fun + : filter_arrow_failure -> _ = function + | Unification_error unif_err -> + Expr_type_clash(unif_err, explanation, None) + | Label_mismatch { got; expected; expected_type} -> + Abstract_wrong_label { got; expected; expected_type; explanation } + | Not_a_function -> begin + match in_function with + | Some _ -> Too_many_arguments(ty_fun, explanation) + | None -> Not_a_function(ty_fun, explanation) + end + | Layout_error (ty, err) -> Function_type_not_rep (ty, err) + (* Forward declaration, to be filled in by Typemod.type_module *) let type_module = @@ -3156,7 +3169,7 @@ let collect_unknown_apply_args env funct ty_fun mode_fun rev_args sargs ret_tvar match type_sort ~why:Function_argument env ty_arg with | Ok sort -> sort | Error err -> raise(Error(funct.exp_loc, env, - Function_arg_not_rep (ty_arg,err))) + Function_type_not_rep (ty_arg,err))) in (sort_arg, mode_arg, tpoly_get_mono ty_arg, mode_ret, ty_res) | td -> @@ -3201,7 +3214,7 @@ let collect_apply_args env funct ignore_labels ty_fun ty_fun0 mode_fun sargs ret let sort_arg = match type_sort ~why:Function_argument env ty_arg with | Ok sort -> sort | Error err -> raise(Error(sarg1.pexp_loc, env, - Function_arg_not_rep(ty_arg, err))) + Function_type_not_rep(ty_arg, err))) in let name = label_name l and optional = is_optional l in @@ -3660,17 +3673,8 @@ let rec type_function_approx env loc label spato sexp in_function ty_expected = let { ty_arg; arg_mode; ty_ret; _ } = try filter_arrow env ty_expected label ~force_tpoly:(not has_poly) with Filter_arrow_failed err -> - let explanation = None in - let err = match err with - | Unification_error unif_err -> - Expr_type_clash(unif_err, explanation, None) - | Label_mismatch { got; expected; expected_type} -> - Abstract_wrong_label { got; expected; expected_type; explanation } - | Not_a_function -> begin - match in_function with - | Some _ -> Too_many_arguments(ty_fun, explanation) - | None -> Not_a_function(ty_fun, explanation) - end + let err = + error_of_filter_arrow_failure ~explanation:None in_function ty_fun err in raise (Error(loc_fun, env, err)) in @@ -5799,16 +5803,8 @@ and type_function ?in_function loc attrs env (expected_mode : expected_mode) in try filter_arrow env ty_expected' arg_label ~force_tpoly with Filter_arrow_failed err -> - let err = match err with - | Unification_error unif_err -> - Expr_type_clash(unif_err, explanation, None) - | Label_mismatch { got; expected; expected_type} -> - Abstract_wrong_label { got; expected; expected_type; explanation } - | Not_a_function -> begin - match in_function with - | Some _ -> Too_many_arguments(ty_fun, explanation) - | None -> Not_a_function(ty_fun, explanation) - end + let err = + error_of_filter_arrow_failure ~explanation in_function ty_fun err in raise (Error(loc_fun, env, err)) in @@ -6409,10 +6405,17 @@ and type_argument ?explanation ?recarg env (mode : expected_mode) sarg let eta_mode = Value_mode.local_to_regional (Value_mode.of_alloc marg) in let eta_pat, eta_var = var_pair ~mode:eta_mode "eta" ty_arg in (* CR layouts v10: When we add abstract layouts, the eta expansion here - becomes impossible in some cases - we'll need good errors and test - cases instead of `type_sort_exn`. *) - let arg_sort = type_sort_exn env ~why:Function_argument ty_arg in - let ret_sort = type_sort_exn env ~why:Function_argument ty_res in + becomes impossible in some cases - we'll need better errors. For test + cases, look toward the end of + typing-layouts-missing-cmi/function_arg.ml *) + let type_sort ~why ty = + match type_sort ~why env ty with + | Ok sort -> sort + | Error err -> + raise(Error(sarg.pexp_loc, env, Function_type_not_rep (ty, err))) + in + let arg_sort = type_sort ~why:Function_argument ty_arg in + let ret_sort = type_sort ~why:Function_result ty_res in let func texp = let ret_mode = Value_mode.of_alloc mret in let e = @@ -8411,12 +8414,11 @@ let report_error ~loc env = function | Unboxed_float_literals_not_supported -> Location.errorf ~loc "@[Unboxed float literals aren't supported yet.@]" - | Function_arg_not_rep (ty_arg,violation) -> + | Function_type_not_rep (ty,violation) -> Location.errorf ~loc - "@[Function argument of type %a@ is not representable.@]@ %a" - Printtyp.type_expr ty_arg + "@[Function arguments and returns must be representable.@]@ %a" (Layout.Violation.report_with_offender - ~offender:(fun ppf -> Printtyp.type_expr ppf ty_arg)) violation + ~offender:(fun ppf -> Printtyp.type_expr ppf ty)) violation let report_error ~loc env err = Printtyp.wrap_printing_env ~error:true env diff --git a/ocaml/typing/typecore.mli b/ocaml/typing/typecore.mli index 6446704f6b9..84b1054a070 100644 --- a/ocaml/typing/typecore.mli +++ b/ocaml/typing/typecore.mli @@ -269,7 +269,7 @@ type error = | Layout_not_enabled of Layout.const | Unboxed_int_literals_not_supported | Unboxed_float_literals_not_supported - | Function_arg_not_rep of type_expr * Layout.Violation.t + | Function_type_not_rep of type_expr * Layout.Violation.t exception Error of Location.t * Env.t * error exception Error_forward of Location.error From f61c4c394739b486fe94bebd7c24e41dcafb7b41 Mon Sep 17 00:00:00 2001 From: Chris Casinghino Date: Fri, 23 Jun 2023 09:50:17 -0400 Subject: [PATCH 6/6] bootstrap --- ocaml/boot/ocamlc | Bin 3491457 -> 3500512 bytes ocaml/boot/ocamllex | Bin 372351 -> 372351 bytes 2 files changed, 0 insertions(+), 0 deletions(-) diff --git a/ocaml/boot/ocamlc b/ocaml/boot/ocamlc index 99880e14bc4a00601d9f9eb7e6baee873eed83be..b0ee3819b10e48d27cbe9a436f1104642c5fe6f5 100755 GIT binary patch delta 206891 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 OD#tVrc&?|LsR97vY=4aa delta 198911 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%0Ah$WPl4bO8u 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 diff --git a/ocaml/boot/ocamllex b/ocaml/boot/ocamllex index b519679d2d4375eb0b01dc5cff311edd384fac0c..6da593d2da41da971ac6ee57a9ec27fed3b58999 100755 GIT binary patch delta 396 zcmex=N9_L{v4$4L7N!>F7M3lnn#%EHm!~u&6$yQoGK!w8`upvXd(%xcO!nOT zyD6G~fi{wU17_{iRl?={^#|+1#hg25&s$`Kkd05yNX(layNdOWfVpwr%j`T!Jvpx5 zZLa)lz`t>dwUAXOCydZP51q^E>+Y z^uw!J4Ftpv3fH~OWjtnPz2W)CD5b*b%xhSq1pK$1Ew~YNF7M3lnn#%>2u>7~Xez&aYsFYXgomPq$posv%Gl9Td~O z>Tj}uiqQt9ct7^-h09sl83mq;yOycn3cY3LwP%O6S;vX#9V=KX1-SegfB0tojovx$ zk6*f9PTX|Cm8>EHpTj=RO04Rge9m1|Ib%`n&grHrSy$G(sB95eWpwyg;I(M3Q0A$c z1-ii{DLI)*@$sH{C1xfDdP`O+29%g4Du&*2&Z%iTh$3%nWUyT#c=68{oJQZuxHh>M z-ws)zjile;&w(nVGx8jEvu3~OI=B3{)*>T>Y%)Pg1|J~A8 z#mXOp8mD`%W>plhWEG7n$e7%(sIY;F>!6GK^s3dYmIC_~FZ<>sHptaT^_fi| z;nl1L0#WN$>^f4rNk&n?Kjiu$Pp#?9YgnTMy!$=Xr0VWOWSJIrL?nEVnx4CcRb9Y+ b?d+?fZw0@Gb4?e&I@NE&_9bgrZ!-b_vd*bt