dotnet / dotnet/fsharp

Mutually recursive non-function values with intermediate module definition not initialized incorrectly

Open
#12,384 10 comments 0 reactions 0 assignees View on GitHub
Area-Compiler-CodeGen Bug Impact-Low Ready
Dominant language
F#
Stars
4.3k
Forks
876
Avg merge
4d 11h
Merged PRs (30d)
131

Description

**Repro steps**

Consider the following code:

```fsharp
type Node =
{
Next: Node
Prev: Node
Value: int
}

let rec one =
{
Next = two
Prev = two
Value = 1
}

and two =
{
Next = one
Prev = one
Value = 2
}
printfn "%A" one
printfn "%A" two
```

**Expected behavior**

Either:
* Correctly initialize the mutually recursive values.
* Reject the code as being invalid.

**Actual behavior**

The code compiles with no warnings/errors. `two` is initialized correctly, but `one.Next` and `one.Prev` are both `null`:

```
{ Next = null
Prev = null
Value = 1 }
{ Next = { Next = null
Prev = null
Value = 1 }
Prev = { Next = null
Prev = null
Value = 1 }
Value = 2 }
```

**Known workarounds**

None

**Related information**

[Decompiled C# code with incorrect initialization.](https://sharplab.io/#v2:DYLgZgzgNAJiDUAfALgTwA4FMAEA5A9jDgLwCwAUNldgN4XUN6YAeyIehm9jVACgE6YAbuwJFuPAGoBDYAFdM7AJYA7ZBOwBfChWCZk2QQGNs+FSQ11KPJq2zFsyAO74NDAcPuOXb6jPkk2ACMGtrkFNIqMN749pa+VLgsBg5mXNY8HkJeaQnY/gpeAEyhFOj8qshgKtgARACkAIK1puZlFWrVdU0tzq7kQA)

Note that a single self-referencing value is actually initialized correctly:

```fsharp
let rec zero =
{
Next = zero
Prev = zero
Value = 0
}
```

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.