Skip to content

Unexpected warning '[FS3511] This state machine is not statically compilable' #12839

@BoundedChenn31

Description

@BoundedChenn31

We have a number of problems where tasks are not being statically compiled.

See also demetrixbio/Plough.WebApi#5 as an example where a library hit this.


Repro steps

I had this problem in more complicated code, however it boils down to something like this:

type Foo = { X: int option }

type BigRecord =
    {
        a1: string
        a2: string
        a3: string
        a4: string
        a5: string
        a6: string
        a7: string
        a8: string
        a9: string
        a10: string
        a11: string
        a12: string
        a13: string
        a14: string
        a15: string
        a16: string
        a17: string
        a18: string
        a19: string
        a20: string
        a21: string
        a22: string
        a23: string
        a24: string
        a25: string
        a26: string
        a27: string
        a28: string
        a29: string
        a30: string
        a31: string
        a32: string
        a33: string
        a34: string
        a35: string
        a36: string // no warning if at least one field removed

        a37Optional: string option
    }

let testStateMachine (bigRecord: BigRecord) =
    task {
        match Some 5 with // no warn if this match removed and only inner one kept
        | Some _ ->
            match Unchecked.defaultof<Foo>.X with // no warning if replaced with `match Some 5 with`
            | Some _ ->
                let d = { bigRecord with a37Optional = None } // no warning if d renamed as _ or ignore function used
                ()
            | None -> ()
        | _ -> ()
    }

printfn "Hello from F#"

Then compile it in release mode.

Original code doesn't have Unchecked.defaultof and gets Foo from another function but I wasn't able to create minimal example without it. I guess, it doesn't really matter and root cause is the same.

Expected behavior

No warning or better explanation of the problem and how to fix it.

Actual behavior

When compiling in Release mode:

dotnet build -c Release

Program.fs(46, 5): [FS3511] This state machine is not statically compilable. A resumable code invocation at '(46,4--46,8)' 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.

Known workarounds

In original code I had to create another function that works with d and inline usage let d = { bigRecord with a37Optional = None } variable at line 51:

...
match Unchecked.defaultof<Foo>.X with
| Some _ ->
    do! testStateMachineInner { bigRecord with a37Optional = None }
| None -> ()
...

Related information

.NET SDK (reflecting any global.json):
Version: 6.0.201
Commit: ef40e6aa06

Runtime Environment:
OS Name: Windows
OS Version: 10.0.19044
OS Platform: Windows
RID: win10-x64
Base Path: C:\Program Files\dotnet\sdk\6.0.201\

Host (useful for support):
Version: 6.0.3
Commit: c24d9a9c91

Metadata

Metadata

Assignees

Labels

Area-Compiler-StateMachinesSequence, list, task and other state machine compilationBugImpact-Low(Internal MS Team use only) Describes an issue with limited impact on existing code.

Type

Projects

Status

New

Relationships

None yet

Development

No branches or pull requests

Issue actions