(* TEST
   * expect
*)

  This program is a minimal example which segfault if 
    ( e1.x < - e2 ) considers that ( e2 ) is in Return mode , 
    rather than Dereference -- here a write to a 
    field in a statically - known all - float record is 
    unboxed on the flight , so accepting this example 
    would dereference ( when running ` g.f < - y ` with y 
    uninitialized ) an arbitrary address .
   (e1.x <- e2) considers that (e2) is in Return mode,
   rather than Dereference -- here a write to a
   field in a statically-known all-float record is
   unboxed on the flight, so accepting this example
   would dereference (when running `g.f <- y` with y
   uninitialized) an arbitrary address. *)
type t = { mutable f: float }
let g = { f = 0.0 }
let rec x = (g.f <- y; ()) and y = 2.0;;
[%%expect{|
type t = { mutable f : float; }
val g : t = {f = 0.}
Line 3, characters 12-26:
3 | let rec x = (g.f <- y; ()) and y = 2.0;;
                ^^^^^^^^^^^^^^
Error: This kind of expression is not allowed as right-hand side of `let rec'
|}];;

(* same example, with object instance variables
   instead of record fields *)
class c = object
  val mutable f = 0.0
  method m =
    let rec x = (f <- y; ()) and y = 2.0 in f
end;;
let _ = print_float (new c)#m;;
[%%expect{|
Line 4, characters 16-28:
4 |     let rec x = (f <- y; ()) and y = 2.0 in f
                    ^^^^^^^^^^^^
Error: This kind of expression is not allowed as right-hand side of `let rec'
|}];;

 TEST
   * expect

 same example, with object instance variables
   instead of record fields 

  This program is a minimal example which segfault if 
    ( e1.x < - e2 ) considers that ( e2 ) is in Return mode , 
    rather than Dereference -- here a write to a 
    field in a statically - known all - float record is 
    unboxed on the flight , so accepting this example 
    would dereference ( when running ` g.f < - y ` with y 
    uninitialized ) an arbitrary address .
   (e1.x <- e2) considers that (e2) is in Return mode,
   rather than Dereference -- here a write to a
   field in a statically-known all-float record is
   unboxed on the flight, so accepting this example
   would dereference (when running `g.f <- y` with y
   uninitialized) an arbitrary address. *)
type t = { mutable f: float }
let g = { f = 0.0 }
let rec x = (g.f <- y; ()) and y = 2.0;;
[%%expect{|
type t = { mutable f : float; }
val g : t = {f = 0.}
Line 3, characters 12-26:
3 | let rec x = (g.f <- y; ()) and y = 2.0;;
                ^^^^^^^^^^^^^^
Error: This kind of expression is not allowed as right-hand side of `let rec'
|}];;

class c = object
  val mutable f = 0.0
  method m =
    let rec x = (f <- y; ()) and y = 2.0 in f
end;;
let _ = print_float (new c)#m;;
[%%expect{|
Line 4, characters 16-28:
4 |     let rec x = (f <- y; ()) and y = 2.0 in f
                    ^^^^^^^^^^^^
Error: This kind of expression is not allowed as right-hand side of `let rec'
|}];;
