Moved from fsharp/fsharp#847
When initializing mutually recursive values, some fields may end up null (i.e. uninitialized). This does not depend on whether the values are not actually recursive or only declared as such.
No warnings are issued by the compiler, and no runtime errors are raised.
Repro steps
Here is a minimal repro:
type A = A of B
and B = B of A | C
// Case 1: non-recursive
let rec a1 = B (A b1)
and b1 = B (A c1)
and c1 = C
// Case 2: true recursive
let rec a2 = A b2
and b2 = B a2
- Case 1: the values are not actually recursive, but are declared as such. The value
a1 ends up under-initialized: a1 = B (A null). However, value b1 initializes correctly: b1 = B (A C).
- Case 2: the values are actually recursive, and both end up invalid:
a2 = A null, b2 = B (A null). Also, b2 itself seems to get initialized correctly as far as its own fields, that is: obj.ReferenceEquals( (fun (B a) -> a) b2, a2 ) = true
Expected behavior
a1 = B (A (B (A C)))
b1 = B (A C)
c1 = C
a2 = A (B a2)
b2 = B (A b2)
Moved from fsharp/fsharp#847
When initializing mutually recursive values, some fields may end up
null(i.e. uninitialized). This does not depend on whether the values are not actually recursive or only declared as such.No warnings are issued by the compiler, and no runtime errors are raised.
Repro steps
Here is a minimal repro:
a1ends up under-initialized:a1 = B (A null). However, valueb1initializes correctly:b1 = B (A C).a2 = A null,b2 = B (A null). Also,b2itself seems to get initialized correctly as far as its own fields, that is:obj.ReferenceEquals( (fun (B a) -> a) b2, a2 ) = trueExpected behavior