-
Notifications
You must be signed in to change notification settings - Fork 88
Implement let mutable
#3964
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Implement let mutable
#3964
Changes from 8 commits
fac96b2
bfd44d9
821925e
fc761c2
d306842
5fbcff1
449509f
27d2062
cdd9e7b
d94e261
1465fed
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -392,6 +392,10 @@ and transl_exp0 ~in_new_scope ~scopes sort e = | |
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_letmutable(pat_expr, body) -> | ||
let return_layout = layout_exp sort body in | ||
transl_letmutable ~scopes ~return_layout pat_expr | ||
(event_before ~scopes body (transl_exp ~scopes sort body)) | ||
| Texp_function { params; body; ret_sort; ret_mode; alloc_mode; | ||
zero_alloc } -> | ||
let ret_sort = Jkind.Sort.default_for_transl_and_get ret_sort in | ||
|
@@ -948,11 +952,15 @@ and transl_exp0 ~in_new_scope ~scopes sort e = | |
let self = transl_value_path loc e.exp_env path_self in | ||
let var = transl_value_path loc e.exp_env path in | ||
Lprim(Pfield_computed Reads_vary, [self; var], loc) | ||
| Texp_mutvar id -> Lmutvar id.txt | ||
| Texp_setinstvar(path_self, path, _, expr) -> | ||
let loc = of_location ~scopes e.exp_loc in | ||
let self = transl_value_path loc e.exp_env path_self in | ||
let var = transl_value_path loc e.exp_env path in | ||
transl_setinstvar ~scopes loc self var expr | ||
| Texp_setmutvar(id, expr_sort, expr) -> | ||
Lassign(id.txt, transl_exp ~scopes | ||
(Jkind.Sort.default_for_transl_and_get expr_sort) expr) | ||
| Texp_override(path_self, modifs) -> | ||
let loc = of_location ~scopes e.exp_loc in | ||
let self = transl_value_path loc e.exp_env path_self in | ||
|
@@ -1856,7 +1864,7 @@ and transl_let ~scopes ~return_layout ?(add_regions=false) ?(in_structure=false) | |
let mk_body = transl rem in | ||
fun body -> | ||
Matching.for_let ~scopes ~arg_sort:sort ~return_layout pat.pat_loc | ||
lam pat (mk_body body) | ||
lam Immutable pat (mk_body body) | ||
in | ||
transl pat_expr_list | ||
| Recursive -> | ||
|
@@ -1880,6 +1888,16 @@ and transl_let ~scopes ~return_layout ?(add_regions=false) ?(in_structure=false) | |
let lam_bds = List.map2 transl_case pat_expr_list idlist in | ||
fun body -> Value_rec_compiler.compile_letrec lam_bds body | ||
|
||
and transl_letmutable ~scopes ~return_layout | ||
{vb_pat=pat; vb_expr=expr; vb_attributes=attr; vb_loc; vb_sort} body = | ||
let arg_sort = (Jkind_types.Sort.default_to_value_and_get vb_sort) in | ||
let lam = | ||
transl_bound_exp ~scopes ~in_structure:false pat arg_sort expr vb_loc attr | ||
in | ||
let lam = Translattribute.add_function_attributes lam vb_loc attr in | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This line is interesting. It is here to support using "function attributes" with let[@zero_alloc] mutable x = fun y -> (y, y) in ... or let[@zero_alloc] mutable f y = (y, y) in ... And get an error because that function allocates. On reflection, I am leaning towards thinking that we should: (1) just ban the syntax in the second example, and (2) delete this line of code? Why? Well, I think the second example is a bit unclear. You are making a mutable variable |
||
Matching.for_let ~scopes ~return_layout ~arg_sort pat.pat_loc lam Mutable | ||
pat body | ||
|
||
and transl_setinstvar ~scopes loc self var expr = | ||
let ptr_or_imm, _ = maybe_pointer expr in | ||
Lprim(Psetfield_computed (ptr_or_imm, Assignment modify_heap), | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -118,7 +118,7 @@ let iterator = | |
| Pexp_tuple ([] | [_]) -> invalid_tuple loc | ||
| Pexp_record ([], _) -> empty_record loc | ||
| Pexp_apply (_, []) -> no_args loc | ||
| Pexp_let (_, [], _) -> empty_let loc | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This file checks various invariants that are enforced by the parser. It's used to make sure that a parsetree coming from another source (most commonly, programmatically constructed by a ppx) obeys the same invariants. I think we're introducing several such parser-enforced invariants in this PR (e.g., |
||
| Pexp_let (_, _, [], _) -> empty_let loc | ||
| Pexp_ident id | ||
| Pexp_construct (id, _) | ||
| Pexp_field (_, id) | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -73,6 +73,7 @@ let get_level_ops : type a. a t -> (module Extension_level with type t = a) = | |
| Labeled_tuples -> (module Unit) | ||
| Small_numbers -> (module Maturity) | ||
| Instances -> (module Unit) | ||
| Let_mutable -> (module Unit) | ||
|
||
(* We'll do this in a more principled way later. *) | ||
(* CR layouts: Note that layouts is only "mostly" erasable, because of annoying | ||
|
@@ -85,7 +86,8 @@ let get_level_ops : type a. a t -> (module Extension_level with type t = a) = | |
let is_erasable : type a. a t -> bool = function | ||
| Mode | Unique | Overwriting | Layouts -> true | ||
| Comprehensions | Include_functor | Polymorphic_parameters | Immutable_arrays | ||
| Module_strengthening | SIMD | Labeled_tuples | Small_numbers | Instances -> | ||
| Module_strengthening | SIMD | Labeled_tuples | Small_numbers | Instances | ||
| Let_mutable -> | ||
false | ||
|
||
let maturity_of_unique_for_drf = Stable | ||
|
@@ -109,6 +111,7 @@ module Exist_pair = struct | |
| Pair (Labeled_tuples, ()) -> Stable | ||
| Pair (Small_numbers, m) -> m | ||
| Pair (Instances, ()) -> Stable | ||
| Pair (Let_mutable, ()) -> Beta | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Per Leo's recent comments elsewhere, I think we should eagerly consider this stable in this PR. I'll discuss with you offline some testing steps we can take to feel good about that, and how/where to write documentation. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Also, we should make sure this extension is not treated as upstream compatible, at least for now, and write a test for that. In the future we could consider if it's possible to make it upstream compatible by erasing mutable variables to refs. |
||
|
||
let is_erasable : t -> bool = function Pair (ext, _) -> is_erasable ext | ||
|
||
|
@@ -122,7 +125,7 @@ module Exist_pair = struct | |
| Pair | ||
( (( Comprehensions | Include_functor | Polymorphic_parameters | ||
| Immutable_arrays | Module_strengthening | Labeled_tuples | ||
| Instances | Overwriting ) as ext), | ||
| Instances | Overwriting | Let_mutable ) as ext), | ||
_ ) -> | ||
to_string ext | ||
|
||
|
@@ -153,6 +156,7 @@ module Exist_pair = struct | |
| "small_numbers" -> Some (Pair (Small_numbers, Stable)) | ||
| "small_numbers_beta" -> Some (Pair (Small_numbers, Beta)) | ||
| "instances" -> Some (Pair (Instances, ())) | ||
| "let_mutable" -> Some (Pair (Let_mutable, ())) | ||
| _ -> None | ||
end | ||
|
||
|
@@ -173,7 +177,8 @@ let all_extensions = | |
Pack SIMD; | ||
Pack Labeled_tuples; | ||
Pack Small_numbers; | ||
Pack Instances ] | ||
Pack Instances; | ||
Pack Let_mutable ] | ||
|
||
(**********************************) | ||
(* string conversions *) | ||
|
@@ -212,9 +217,11 @@ let equal_t (type a b) (a : a t) (b : b t) : (a, b) Misc.eq option = | |
| Labeled_tuples, Labeled_tuples -> Some Refl | ||
| Small_numbers, Small_numbers -> Some Refl | ||
| Instances, Instances -> Some Refl | ||
| Let_mutable, Let_mutable -> Some Refl | ||
| ( ( Comprehensions | Mode | Unique | Overwriting | Include_functor | ||
| Polymorphic_parameters | Immutable_arrays | Module_strengthening | ||
| Layouts | SIMD | Labeled_tuples | Small_numbers | Instances ), | ||
| Layouts | SIMD | Labeled_tuples | Small_numbers | Instances | ||
| Let_mutable ), | ||
_ ) -> | ||
None | ||
|
||
|
Uh oh!
There was an error while loading. Please reload this page.