-
Notifications
You must be signed in to change notification settings - Fork 796
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Try fix static compilation of state machines #14930
Conversation
I'll convert the 2 snippets above into a test if the fix is deemed appropriate. |
Yes. |
I could not reproduce #12839 (comment) on #12839 (comment) requires further changes: ----------- OVERALL EXPRESSION FOR STATE MACHINE CONVERSION ----------------------
let code =
let generator =
fun unitVar ->
__debugPoint( C:\code\a.fs(61,8)-(61,25) )
let testStateMachine$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 ()
member Invoke ((sm))=
true
}
T1 (): {
new ResumableCode <TaskStateMachineData <unit>,unit>
System.Object..ctor ()
member Invoke ((sm))=
true
}]
testStateMachine$cont ()
{
new TaskCode <unit,unit>
System.Object..ctor ()
member Invoke ((sm))=
Invoke (generator ()) sm
}
... vs this when one of the record fields is commented out ----------- OVERALL EXPRESSION FOR STATE MACHINE CONVERSION ----------------------
let code =
let generator =
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 ()
member Invoke ((sm))=
true
}
T1 (): {
new ResumableCode <TaskStateMachineData <unit>,unit>
System.Object..ctor ()
member Invoke ((sm))=
true
}]
{
new TaskCode <unit,unit>
System.Object..ctor ()
member Invoke ((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 |
Here's a trivial piece of code that is still failing let bad () = task {
let res = {| ResultSet2 = [| {| im = Some 1; lc = 3 |} |] |}
match [| |] with
| [| |] ->
let c = res.ResultSet2 |> Array.map (fun x -> {| Name = x.lc |})
let c = res.ResultSet2 |> Array.map (fun x -> {| Name = x.lc |})
let c = res.ResultSet2 |> Array.map (fun x -> {| Name = x.lc |})
return Some c
| _ ->
return None
} |
@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. |
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. |
Thanks. Let's park it then, I will try to revisit it in future in a separate PR |
@vzarytovskii @dsyme Any plans to revive this effort ?. There are more and more people facing this issue. |
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. |
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
TryReduceApp
call back intoTryReduceExpr
in 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