"FS3511: This state machine is not statically compilable." for large records in complex task
Repro steps The following compiles in Debug mode but warns in Release mode, with "error FS3511: This state machine is not statically compilable. A resumable code invocation at '(26,8--26,12)' 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.".
namespace Foo
type Thing =
{
A : int
B : int
C : int
D : int
E : int
F : int
G : int
H : int
I : int
J : int
K : int
L : int
M : int
N : int
O : int
}
module TestIt =
let thing () =
task {
match failwith "" with
| None -> return failwith ""
| Some _ ->
let blah =
task {
return failwith ""
}
printfn "hi"
return
{
A = failwith ""
B = failwith ""
C = failwith ""
D = failwith ""
H = failwith ""
F = failwith ""
G = failwith ""
I = failwith ""
E = failwith ""
J = failwith ""
K = failwith ""
L = failwith ""
M = failwith ""
N = failwith ""
O = failwith ""
}
|> Ok
}
This appears to be very sensitive to the details of this example. For example, removing a field from the record, it compiles cleanly. Reordering the E field to be in its alphabetical order also compiles cleanly. Removing the printfn compiles cleanly, and replacing the sub-task with a Task.FromResult compiles cleanly.
Expected behavior
Compilation succeeds identically in Release and Debug modes.
Actual behavior
Compilation fails in Release mode.
Known workarounds
Just ignore the warning and fall back to the dynamic version.
Related information
Provide any related information (optional):
$ dotnet --info
.NET SDK:
Version: 9.0.203
Commit: dc7acfa194
Workload version: 9.0.200-manifests.9df47798
MSBuild version: 17.13.20+a4ef1e90f
Runtime Environment:
OS Name: ubuntu
OS Version: 22.04
OS Platform: Linux
RID: linux-x64
Base Path: /usr/share/dotnet/sdk/9.0.203/
.NET workloads installed:
There are no installed workloads to display.
Configured to use loose manifests when installing new manifests.
Host:
Version: 9.0.4
Architecture: x64
Commit: f57e6dc747
.NET SDKs installed:
6.0.400 [/usr/share/dotnet/sdk]
8.0.408 [/usr/share/dotnet/sdk]
9.0.203 [/usr/share/dotnet/sdk]
.NET runtimes installed:
Microsoft.AspNetCore.App 6.0.36 [/usr/share/dotnet/shared/Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 8.0.15 [/usr/share/dotnet/shared/Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 9.0.4 [/usr/share/dotnet/shared/Microsoft.AspNetCore.App]
Microsoft.NETCore.App 6.0.36 [/usr/share/dotnet/shared/Microsoft.NETCore.App]
Microsoft.NETCore.App 8.0.15 [/usr/share/dotnet/shared/Microsoft.NETCore.App]
Microsoft.NETCore.App 9.0.4 [/usr/share/dotnet/shared/Microsoft.NETCore.App]
Other architectures found:
None
Environment variables:
DOTNET_ROOT [/usr/share/dotnet]
I'm using FSharp.Core 8.0.100, if that's relevant.
It seems, I can't reproduce it on a new class lib project.
cat ./Library.fs
namespace Foo
type Thing =
{
A : int
B : int
C : int
D : int
E : int
F : int
G : int
H : int
I : int
J : int
K : int
L : int
M : int
N : int
O : int
}
module TestIt =
let thing () =
task {
match failwith "" with
| None -> return failwith ""
| Some _ ->
let blah =
task {
return failwith ""
}
printfn "hi"
return
{
A = failwith ""
B = failwith ""
C = failwith ""
D = failwith ""
H = failwith ""
F = failwith ""
G = failwith ""
I = failwith ""
E = failwith ""
J = failwith ""
K = failwith ""
L = failwith ""
M = failwith ""
N = failwith ""
O = failwith ""
}
|> Ok
}
cat ./global.json
{
"sdk": {
"version": "9.0.202"
}
}
dotnet build -c Release
Restore complete (0.2s)
resumable succeeded (0.1s) → bin/Release/net8.0/resumable.dll
Build succeeded in 0.5s
Same here. I also tried sdk 9.0.203 and FSharp.Core 8.0.100. Compiles for both Debug and Release.
Sorry for the incomplete report. I didn't realise there was a Directory.Build.props file applying; it turns out that --crossoptimize- is also a critical part of the repro. I don't actually know why --crossoptimize- is set here, or whether it's expected that the static compilation fails under that condition; currently reading code and docs to try and find out.
Here is a repro from a completely different machine:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>net8.0</TargetFrameworks>
<OtherFlags>--crossoptimize- $(OtherFlags)</OtherFlags>
</PropertyGroup>
<ItemGroup>
<Compile Include="Program.fs"/>
</ItemGroup>
</Project>
namespace Foo
type Thing =
{
A : int
B : int
C : int
D : int
E : int
F : int
G : int
H : int
I : int
J : int
K : int
L : int
M : int
N : int
O : int
}
module TestIt =
let thing () =
task {
match failwith "" with
| None -> return failwith ""
| Some _ ->
let blah =
task {
return failwith ""
}
printfn "hi"
return
{
A = failwith ""
B = failwith ""
C = failwith ""
D = failwith ""
H = failwith ""
F = failwith ""
G = failwith ""
I = failwith ""
E = failwith ""
J = failwith ""
K = failwith ""
L = failwith ""
M = failwith ""
N = failwith ""
O = failwith ""
}
|> Ok
}
Output of dotnet --info:
/nix/store/j2ppnz8jdvglmkaslwr4p8jvnij0pd72-dotnet-sdk-wrapped-9.0.203/bin/dotnet --info ~/Documents/GitHub/Resumable
.NET SDK:
Version: 9.0.203
Commit: dc7acfa194
Workload version: 9.0.200-manifests.9df47798
MSBuild version: 17.13.20+a4ef1e90f
Runtime Environment:
OS Name: Mac OS X
OS Version: 15.4
OS Platform: Darwin
RID: osx-arm64
Base Path: /nix/store/4gc3gsfn90b3izf40cxclwriqkm7z9yq-dotnet-sdk-9.0.203/share/dotnet/sdk/9.0.203/
.NET workloads installed:
There are no installed workloads to display.
Configured to use loose manifests when installing new manifests.
Host:
Version: 9.0.4
Architecture: arm64
Commit: b7deac6d42
.NET SDKs installed:
9.0.203 [/nix/store/4gc3gsfn90b3izf40cxclwriqkm7z9yq-dotnet-sdk-9.0.203/share/dotnet/sdk]
.NET runtimes installed:
Microsoft.AspNetCore.App 9.0.4 [/nix/store/4gc3gsfn90b3izf40cxclwriqkm7z9yq-dotnet-sdk-9.0.203/share/dotnet/shared/Microsoft.AspNetCore.App]
Microsoft.NETCore.App 9.0.4 [/nix/store/4gc3gsfn90b3izf40cxclwriqkm7z9yq-dotnet-sdk-9.0.203/share/dotnet/shared/Microsoft.NETCore.App]
Other architectures found:
None
Environment variables:
Not set
global.json file:
Not found
This I can reproduce for both sdk 8 and 9
Duplicate https://github.com/dotnet/fsharp/issues/12839