|
1 | 1 | (* TEST
|
| 2 | + flags = "-extension immutable_arrays" |
2 | 3 | * expect *)
|
3 | 4 |
|
4 | 5 | let leak n =
|
@@ -2509,38 +2510,77 @@ Line 3, characters 24-26:
|
2509 | 2510 | Error: This value escapes its region
|
2510 | 2511 | |}]
|
2511 | 2512 |
|
| 2513 | +(* Test of array.*) |
2512 | 2514 |
|
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. *) |
2517 | 2518 |
|
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 | +|}] |
2519 | 2539 |
|
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" |
2522 | 2545 | [%%expect{|
|
2523 |
| -Line 2, characters 4-5: |
2524 |
| -2 | [|x; "foo"|] |
2525 |
| - ^ |
| 2546 | +Line 3, characters 22-23: |
| 2547 | +3 | | [: x; _ :] -> ref x |
| 2548 | + ^ |
2526 | 2549 | Error: This value escapes its region
|
2527 | 2550 | |}]
|
2528 | 2551 |
|
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" |
2531 | 2557 | [%%expect{|
|
2532 |
| -val f : string -> string array = <fun> |
| 2558 | +val f : string iarray -> string ref = <fun> |
2533 | 2559 | |}]
|
2534 | 2560 |
|
| 2561 | +(* Mutable array, like references, is dangerous. They must contain global |
| 2562 | + elements regardless of the array's mode. *) |
2535 | 2563 |
|
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 *) |
2539 | 2580 | let f (local_ a : string array) =
|
2540 | 2581 | match a with
|
2541 |
| - | [| x; _ |] -> ref x |
| 2582 | + | [| x |] -> ref x |
2542 | 2583 | | _ -> ref "foo"
|
2543 |
| -
|
2544 | 2584 | [%%expect{|
|
2545 | 2585 | val f : local_ string array -> string ref = <fun>
|
2546 | 2586 | |}]
|
|
0 commit comments