-
Notifications
You must be signed in to change notification settings - Fork 127
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
Strange split types coercion #585
Comments
Confirmed (on amd64-linux); since it occurs during compilation of the SML code, one doesn't even need the link argument or The bug is actually from the
Possibly introduced by #569, though the type error concerns a component of a tuple (from type: |
Actually, on second thought and looking at your comment in |
I double-checked (built and installed the compiler version with the commit hash I do see that the code I wrote also has a bug/some regressions now that I can compile and test it (collision detection broke) and appreciate the hint that allowed me to do that. |
In the `Value.t` representation of the Useless optimization, sequence and tuple elements are "slots", which combine a `Useful.t` lattice element with an `Exists.t` lattice element. When a value flows, vectors and tuples coerce the `Useful.t` component of slots but unify the `Exists.t` component. This ensures that agree on whether or not the element exists even if they disagree that the element is useful. If the "from"'s element is useful (and necessarily existing) but the "to"'s element is not useful, then forcing the "to"'s element to exist avoids a potentially expensive runtime coercion (e.g., to drop a component of a tuple or, worse, to drop a component of a tuple that is the contents of a vector). Previously, the length of a sequence was represented simply as a `Useful.t`; this allowed a vector (whose contents were not useful) with a useful length to flow to a vector (whose contents are necessarily not useful) with a useless length. 1aad5fe (Optimize representation of sequences in Useless pass; MLton#569) allowed the Useless optimization to change the representation of sequence with useless contents. In particular, a vector with useless contents but useless length becomes a `word64` and a vector with useless contents and useless length becomes a `unit`. However, when such vectors are themselves components of a tuple, then the program may have a flow of tuples, where the source tuple is changed from `(..., ?? vector, ...)` to `(..., word64, ...)` but the destination tuple is changed from `(..., ?? vector, ...)` to `(..., unit, ...)`. (Note that the unification of the `Exist.t` components of the corresponding tuple elements is what makes the destination tuple have a `unit` element.) This commit treats the length of arrays and vectors as a "slot", so that they track both usefulness and existence. Now, a vector with useless contents but a length that must exist becomes a `word64` (even if the length is useless) and a vector with useless contents and a length that need not exist (and is necessarily useless) becomes a `unit`. Fixes MLton#585.
In the `Value.t` representation of the Useless optimization, sequence and tuple elements are "slots", which combine a `Useful.t` lattice element with an `Exists.t` lattice element. When a value flows, vectors and tuples coerce the `Useful.t` component of slots but unify the `Exists.t` component. This ensures that agree on whether or not the element exists even if they disagree that the element is useful. If the "from"'s element is useful (and necessarily existing) but the "to"'s element is not useful, then forcing the "to"'s element to exist avoids a potentially expensive runtime coercion (e.g., to drop a component of a tuple or, worse, to drop a component of a tuple that is the contents of a vector). Previously, the length of a sequence was represented simply as a `Useful.t`; this allowed a vector (whose contents were not useful) with a useful length to flow to a vector (whose contents are necessarily not useful) with a useless length. 1aad5fe (Optimize representation of sequences in Useless pass; MLton#569) allowed the Useless optimization to change the representation of sequence with useless contents. In particular, a vector with useless contents but useless length becomes a `word64` and a vector with useless contents and useless length becomes a `unit`. However, when such vectors are themselves components of a tuple, then the program may have a flow of tuples, where the source tuple is changed from `(..., ?? vector, ...)` to `(..., word64, ...)` but the destination tuple is changed from `(..., ?? vector, ...)` to `(..., unit, ...)`. (Note that the unification of the `Exist.t` components of the corresponding tuple elements is what makes the destination tuple have a `unit` element.) This commit treats the length of arrays and vectors as a "slot", so that they track both usefulness and existence. Now, a vector with useless contents but a length that must exist becomes a `word64` (even if the length is useless) and a vector with useless contents and a length that need not exist (and is necessarily useless) becomes a `unit`. Fixes MLton#585.
Hi there.
I'm having fun making a little game with SML and MLton ((link)[https://github.com/hummy123/quad-tree-sml/]) but I encountered a compiler bug to do with strange type coercion with MLton (freshly built from the latest commit on GitHub so not a reemergence of the bug I reported in May).
To trigger the issue on aarch64-linux (only platform I have tested on):
build-unix.sh
scriptI did look into the cause for some time and found what part of my code was triggering the error. There is a comment on line 78 of (fcore/player.sml)[https://github.com/hummy123/quad-tree-sml/blob/main/fcore/player.sml] describing what I think the issue is.
I'm having a lot of fun using SML and MLton for side projects (a small GUI app and a Vim clone) and am happy they run on my obscure platform, and appreciate the work that has gone into it.
The text was updated successfully, but these errors were encountered: