Uh oh!
There was an error while loading. Please reload this page.
Try fix static compilation of state machines - #14930
Conversation
kerams
commented
Mar 19, 2023
I'll convert the 2 snippets above into a test if the fix is deemed appropriate. |
T-Gro
commented
Mar 20, 2023
Yes. |
edgarfgp
commented
Apr 13, 2023
dsyme
commented
Apr 23, 2023
I could not reproduce #12839 (comment) on #12839 (comment) requires further changes: ----------- OVERALL EXPRESSION FOR STATE MACHINE CONVERSION ----------------------letcode=letgenerator=fun unitVar ->__debugPoint( C:\code\a.fs(61,8)-(61,25))lettestStateMachine$cont =fun unitVar ->[Switch ((#EI_ilzero !0#)).# X
is None // Success T1 ()
dflt: Success T0 ()
T0 ():__debugPoint( C:\code\a.fs(65,16)-(65,61)){new ResumableCode <TaskStateMachineData <unit>,unit>
System.Object..ctor ()memberInvoke((sm))=true}
T1 ():{new ResumableCode <TaskStateMachineData <unit>,unit>
System.Object..ctor ()memberInvoke((sm))=true}]
testStateMachine$cont (){new TaskCode <unit,unit>
System.Object..ctor ()memberInvoke((sm))=
Invoke (generator ()) sm
}...vs this when one of the record fields is commented out ----------- OVERALL EXPRESSION FOR STATE MACHINE CONVERSION ----------------------letcode=letgenerator=fun unitVar ->__debugPoint( C:\code\a.fs(60,8)-(60,25))[Switch ((#EI_ilzero !0#)).# X
is None // Success T1 ()
dflt: Success T0 ()
T0 ():__debugPoint( C:\code\a.fs(64,16)-(64,61)){new ResumableCode <TaskStateMachineData <unit>,unit>
System.Object..ctor ()memberInvoke((sm))=true}
T1 ():{new ResumableCode <TaskStateMachineData <unit>,unit>
System.Object..ctor ()memberInvoke((sm))=true}]{new TaskCode <unit,unit>
System.Object..ctor ()memberInvoke((sm))=
Invoke (generator ()) sm
}...The conversion fails on trying to reduce the I can't shake the feeling that this is a bit of a bandaid, and I'm also concerned about opening the doors to bugs and creating invalid state machines (which is a lot worse than the dynamic invocation fallback). It's puzzling how adding one too many record fields can have such a snowball effect - why is |
kerams
commented
Apr 30, 2023
Here's a trivial piece of code that is still failing letbad()=task{letres={| ResultSet2 =[|{| im = Some 1; lc =3|}|]|}match[||]with|[||]->letc= res.ResultSet2 |> Array.map (fun x ->{| Name = x.lc |})letc= res.ResultSet2 |> Array.map (fun x ->{| Name = x.lc |})letc= res.ResultSet2 |> Array.map (fun x ->{| Name = x.lc |})return Some c
|_->return None
} |
vzarytovskii
commented
May 25, 2023
@kerams do you need any help with further debugging it? I can take over if you'd like, and see if I can figure it ou. |
kerams
commented
May 25, 2023
I don't know where to go with this. I managed to add support for the static compilation of a couple of additional constructs, but it feels like these are just hotfixes on a case-by-case basis; perhaps a more systematic change is needed. In any case, I'm not interested in pursuing this further. |
vzarytovskii
commented
May 29, 2023
Thanks. Let's park it then, I will try to revisit it in future in a separate PR |
edgarfgp
commented
Apr 8, 2024
@vzarytovskii@dsyme Any plans to revive this effort ?. There are more and more people facing this issue. |
vzarytovskii
commented
Apr 8, 2024
No specific plans as for now. This was not planned for the current iteration and we are way out of capacity. Unless someone finds time (and probably postpone some other work like LSP or perf to next year), this is on hold now. |
vzarytovskii
commented
Apr 8, 2024
Just for the information, it's happening because the expression is crossing a threshold in |
Attempt to fix the last case reported here #12839, specifically its minimal repro
which doesn't get statically compiled, while the following equivalent snippet does
In the first case, the input to lowering looks like this:
and in the second
The problem occurs in
TryReduceApp, which isn't able to reduceI addressed this by making
TryReduceAppcall back intoTryReduceExprin the case ofExpr.App. I am not sure if this is sound and I suspect there's a good reason why it hasn't been done before.In any case, while there might be other constructs that will still fail, the 2 above produce an almost identical state machine (the difference is just one superfluous assignment).
vs