dotnet / dotnet/fsharp

Null reference exception related to tuples in union types in Release mode (TaskSeq)

Open
#18,853 0 comments 0 reactions 0 assignees View on GitHub
Area-Compiler-StateMachines Bug
Dominant language
F#
Stars
4.3k
Forks
876
Avg merge
4d 11h
Merged PRs (30d)
131

Description

Once again, I ran into a bug related to TaskSeq for loops.

**Repro steps**

Repo: https://github.com/mrakgr/taskseq_bug_report/tree/bug2

```fsharp
module ICF_Main.Main

open System.Threading.Channels
open FSharp.Control

module gRPC =
type ICF_Proxy_Service_Choices =
| C_Internal_Reply of string
| C_Demand_Source_Request of int * string // The error stops happening when I replace the tuple with a singleton type like `string`

let service () = task {
let ch_internal_rep = Channel.CreateUnbounded(new UnboundedChannelOptions())
let ch_demand_source = Channel.CreateUnbounded(new UnboundedChannelOptions())
let ch_merged = Channel.CreateUnbounded(UnboundedChannelOptions())
let ch_internal_rep_loop = task { // Replies from the customer cluster
for x in ch_internal_rep.Reader.ReadAllAsync () do
do! ch_merged.Writer.WriteAsync(C_Internal_Reply x)
}
let ch_demand_source_loop = task { // Requests from the demand sources for inference requests
for x in ch_demand_source.Reader.ReadAllAsync () do
do! ch_merged.Writer.WriteAsync(C_Demand_Source_Request x)
}
let ch_merged_loop = task {
for x in ch_merged.Reader.ReadAllAsync() do
printfn "In ch_merged_loop's loop."
}
do! ch_merged_loop
}

[]
let main args =
let t = gRPC.service()
t.Wait()
0
```

Run it in Release mode with `dotnet run -c Release`. It only happens in Release mode.

**Expected behavior**

It waits forever for the task to finish.

**Actual behavior**

```
mrakgr@Marko:~/taskseq_bug_report$ dotnet run -c Release
/home/mrakgr/taskseq_bug_report/Program.fs(21,41): warning FS3511: This state machine is not statically compilable. A resumable code invocation at '(22,16--22,19)' could not be reduced. An alternative dynamic implementation will be used, which may be slower. Consider adjusting your code to ensure this state machine is statically compilable, or else suppress this warning.
Unhandled exception. System.NullReferenceException: Object reference not set to an instance of an object.
at System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1.AwaitUnsafeOnCompleted[TAwaiter](TAwaiter& awaiter, IAsyncStateMachineBox box)
--- End of stack trace from previous location ---
at System.Threading.Tasks.Task.<>c.b__128_1(Object state)
at System.Threading.ThreadPoolWorkQueue.Dispatch()
at System.Threading.PortableThreadPool.WorkerThread.WorkerThreadStart()
```

**Known workarounds**

Replace the for loops with `TaskSeq.iterAsync` calls.

**Related information**

The setup is same as in: https://github.com/dotnet/fsharp/issues/18848

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.