summaryrefslogtreecommitdiff
path: root/testsuite/tests/letrec-check/records.ml
blob: db11d41eb7e11368daf0b767b16fa040c18dcba1 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
(* TEST
   * expect
*)
type t = { x : int; self : t };;
[%%expect {|
type t = { x : int; self : t; }
|}];;

let rec x = 1
and u = Some { t with x = 2 }
and t = { x; self = t }
(* We have carefully placed `u` before `t` here,
   so that the copy { t with .. }, if accepted,
   is evaluated before 't' is initialized -- making
   the assertion below fail, typically aborting
   with a segmentation fault.

   If you exchange the declaration orders of `u` and `t`,
   and the static check accepts this example, then `t`
   is initialized first and the assertion succeeds. *)


let () = match u with
  | None -> assert false
  | Some {x = _; self} -> assert (self.x = t.x)
[%%expect {|
Line 2, characters 8-29:
2 | and u = Some { t with x = 2 }
            ^^^^^^^^^^^^^^^^^^^^^
Error: This kind of expression is not allowed as right-hand side of `let rec'
|}];;