Skip to content

Commit

Permalink
local iarray contains local values
Browse files Browse the repository at this point in the history
  • Loading branch information
riaqn committed Jul 17, 2023
1 parent 52fa220 commit c666fb9
Show file tree
Hide file tree
Showing 2 changed files with 71 additions and 26 deletions.
76 changes: 58 additions & 18 deletions ocaml/testsuite/tests/typing-local/local.ml
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
(* TEST
flags = "-extension immutable_arrays"
* expect *)

let leak n =
Expand Down Expand Up @@ -2509,38 +2510,77 @@ Line 3, characters 24-26:
Error: This value escapes its region
|}]
(* Test of array.*)
(* test of arrays *)
(* as elements of arrays are mutable *)
(* it is only safe for them to be at global mode *)
(* cf: similarly reference cell can contain only global values *)
(* Immutable arrays are like tuples or normal record: local array contains local
elements, both at construction and at projection; global array contains global
elements. *)
(* on construction of array, we ensure elements are global *)
(* constructing global iarray from local elements is rejected *)
let f (local_ x : string) = ref [: x; "foo" :]
[%%expect{|
Line 1, characters 35-36:
1 | let f (local_ x : string) = ref [: x; "foo" :]
^
Error: This value escapes its region
|}]
(* constructing local iarray from local elements is fine *)
let f (local_ x : string) = local_ [:x; "foo":]
[%%expect{|
val f : local_ string -> local_ string iarray = <fun>
|}]
(* constructing global iarray from global elements is fine *)
let f (x : string) = ref [:x; "foo":]
[%%expect{|
val f : string -> string iarray ref = <fun>
|}]
let f (local_ x : string) =
[|x; "foo"|]
(* projecting out of local array gives local elements *)
let f (local_ a : string iarray) =
match a with
| [: x; _ :] -> ref x
| _ -> ref "foo"
[%%expect{|
Line 2, characters 4-5:
2 | [|x; "foo"|]
^
Line 3, characters 22-23:
3 | | [: x; _ :] -> ref x
^
Error: This value escapes its region
|}]
let f (x : string) =
[|x; "foo"|]
(* projecting out of global iarray gives global elements *)
let f (a : string iarray) =
match a with
| [: x :] -> ref x
| _ -> ref "foo"
[%%expect{|
val f : string -> string array = <fun>
val f : string iarray -> string ref = <fun>
|}]
(* Mutable array, like references, is dangerous. They must contain global
elements regardless of the array's mode. *)
(* on pattern matching of array,
elements are strengthened to global
even if array itself is local *)
(* constructing local array from local elements is rejected *)
let f (local_ x : string) = local_ [| x |]
[%%expect{|
Line 1, characters 38-39:
1 | let f (local_ x : string) = local_ [| x |]
^
Error: This value escapes its region
|}]
(* constructing local array from global elements is allowed *)
let f (x : string) = local_ [| x |]
[%%expect{|
val f : string -> local_ string array = <fun>
|}]
(* projecting out of local array gives global elements *)
let f (local_ a : string array) =
match a with
| [| x; _ |] -> ref x
| [| x |] -> ref x
| _ -> ref "foo"
[%%expect{|
val f : local_ string array -> string ref = <fun>
|}]
Expand Down
21 changes: 13 additions & 8 deletions ocaml/typing/typecore.ml
Original file line number Diff line number Diff line change
Expand Up @@ -2269,14 +2269,19 @@ and type_pat_aux
shouldn't be too bad. We can inline this when we upstream this code and
combine the two array pattern constructors. *)
let ty_elt = solve_Ppat_array ~refine loc env mutability expected_ty in
map_fold_cont (fun p -> type_pat ~alloc_mode:(simple_pat_mode Value_mode.global)
tps Value p ty_elt) spl (fun pl ->
rvp k {
pat_desc = Tpat_array (mutability, pl);
pat_loc = loc; pat_extra=[];
pat_type = instance expected_ty;
pat_attributes;
pat_env = !env })
map_fold_cont (fun p ->
let alloc_mode =
match mutability with
| Mutable -> simple_pat_mode Value_mode.global
| Immutable -> alloc_mode
in
type_pat ~alloc_mode tps Value p ty_elt) spl (fun pl ->
rvp k {
pat_desc = Tpat_array (mutability, pl);
pat_loc = loc; pat_extra=[];
pat_type = instance expected_ty;
pat_attributes;
pat_env = !env })
in
match Jane_syntax.Pattern.of_ast sp with
| Some (jpat, attrs) -> begin
Expand Down

0 comments on commit c666fb9

Please sign in to comment.