Skip to content

Commit c666fb9

Browse files
committed
local iarray contains local values
1 parent 52fa220 commit c666fb9

File tree

2 files changed

+71
-26
lines changed

2 files changed

+71
-26
lines changed

ocaml/testsuite/tests/typing-local/local.ml

Lines changed: 58 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
(* TEST
2+
flags = "-extension immutable_arrays"
23
* expect *)
34

45
let leak n =
@@ -2509,38 +2510,77 @@ Line 3, characters 24-26:
25092510
Error: This value escapes its region
25102511
|}]
25112512
2513+
(* Test of array.*)
25122514
2513-
(* test of arrays *)
2514-
(* as elements of arrays are mutable *)
2515-
(* it is only safe for them to be at global mode *)
2516-
(* cf: similarly reference cell can contain only global values *)
2515+
(* Immutable arrays are like tuples or normal record: local array contains local
2516+
elements, both at construction and at projection; global array contains global
2517+
elements. *)
25172518
2518-
(* on construction of array, we ensure elements are global *)
2519+
(* constructing global iarray from local elements is rejected *)
2520+
let f (local_ x : string) = ref [: x; "foo" :]
2521+
[%%expect{|
2522+
Line 1, characters 35-36:
2523+
1 | let f (local_ x : string) = ref [: x; "foo" :]
2524+
^
2525+
Error: This value escapes its region
2526+
|}]
2527+
2528+
(* constructing local iarray from local elements is fine *)
2529+
let f (local_ x : string) = local_ [:x; "foo":]
2530+
[%%expect{|
2531+
val f : local_ string -> local_ string iarray = <fun>
2532+
|}]
2533+
2534+
(* constructing global iarray from global elements is fine *)
2535+
let f (x : string) = ref [:x; "foo":]
2536+
[%%expect{|
2537+
val f : string -> string iarray ref = <fun>
2538+
|}]
25192539
2520-
let f (local_ x : string) =
2521-
[|x; "foo"|]
2540+
(* projecting out of local array gives local elements *)
2541+
let f (local_ a : string iarray) =
2542+
match a with
2543+
| [: x; _ :] -> ref x
2544+
| _ -> ref "foo"
25222545
[%%expect{|
2523-
Line 2, characters 4-5:
2524-
2 | [|x; "foo"|]
2525-
^
2546+
Line 3, characters 22-23:
2547+
3 | | [: x; _ :] -> ref x
2548+
^
25262549
Error: This value escapes its region
25272550
|}]
25282551
2529-
let f (x : string) =
2530-
[|x; "foo"|]
2552+
(* projecting out of global iarray gives global elements *)
2553+
let f (a : string iarray) =
2554+
match a with
2555+
| [: x :] -> ref x
2556+
| _ -> ref "foo"
25312557
[%%expect{|
2532-
val f : string -> string array = <fun>
2558+
val f : string iarray -> string ref = <fun>
25332559
|}]
25342560
2561+
(* Mutable array, like references, is dangerous. They must contain global
2562+
elements regardless of the array's mode. *)
25352563
2536-
(* on pattern matching of array,
2537-
elements are strengthened to global
2538-
even if array itself is local *)
2564+
(* constructing local array from local elements is rejected *)
2565+
let f (local_ x : string) = local_ [| x |]
2566+
[%%expect{|
2567+
Line 1, characters 38-39:
2568+
1 | let f (local_ x : string) = local_ [| x |]
2569+
^
2570+
Error: This value escapes its region
2571+
|}]
2572+
2573+
(* constructing local array from global elements is allowed *)
2574+
let f (x : string) = local_ [| x |]
2575+
[%%expect{|
2576+
val f : string -> local_ string array = <fun>
2577+
|}]
2578+
2579+
(* projecting out of local array gives global elements *)
25392580
let f (local_ a : string array) =
25402581
match a with
2541-
| [| x; _ |] -> ref x
2582+
| [| x |] -> ref x
25422583
| _ -> ref "foo"
2543-
25442584
[%%expect{|
25452585
val f : local_ string array -> string ref = <fun>
25462586
|}]

ocaml/typing/typecore.ml

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2269,14 +2269,19 @@ and type_pat_aux
22692269
shouldn't be too bad. We can inline this when we upstream this code and
22702270
combine the two array pattern constructors. *)
22712271
let ty_elt = solve_Ppat_array ~refine loc env mutability expected_ty in
2272-
map_fold_cont (fun p -> type_pat ~alloc_mode:(simple_pat_mode Value_mode.global)
2273-
tps Value p ty_elt) spl (fun pl ->
2274-
rvp k {
2275-
pat_desc = Tpat_array (mutability, pl);
2276-
pat_loc = loc; pat_extra=[];
2277-
pat_type = instance expected_ty;
2278-
pat_attributes;
2279-
pat_env = !env })
2272+
map_fold_cont (fun p ->
2273+
let alloc_mode =
2274+
match mutability with
2275+
| Mutable -> simple_pat_mode Value_mode.global
2276+
| Immutable -> alloc_mode
2277+
in
2278+
type_pat ~alloc_mode tps Value p ty_elt) spl (fun pl ->
2279+
rvp k {
2280+
pat_desc = Tpat_array (mutability, pl);
2281+
pat_loc = loc; pat_extra=[];
2282+
pat_type = instance expected_ty;
2283+
pat_attributes;
2284+
pat_env = !env })
22802285
in
22812286
match Jane_syntax.Pattern.of_ast sp with
22822287
| Some (jpat, attrs) -> begin

0 commit comments

Comments
 (0)