-
Notifications
You must be signed in to change notification settings - Fork 78
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
Prevent [@unboxable] from applying to local values #2322
base: main
Are you sure you want to change the base?
Conversation
Here is an example where the new warning triggers: module M : sig end = struct
type 'a t = { a : 'a; b : 'a }
let f (x[@unboxable]) =
x.a + x.b
let g a b =
let r = f {a; b} in
r
let () = assert (g 1 2 = g 2 1)
end The type-checker infers that |
Note: we're thinking of interpreting the |
What's the plan to make this work with local allocations in the longer term? |
We don't have a solution at the moment. If the type-checker understands that local unboxable parameters introduce a local allocation, then we could have the appropriate regions inserted when needed, and proper compilation errors when the new allocation would escape its region (I'm not sure it is actually possible). I think that's the easiest solution, but it requires the help of someone more familiar with the typing part of locals. |
Would you mind showing me an example of a function before and after the initial |
Sure. (* Before translation *)
let f (x[@unboxable] : local_ (_ * _)) = some_code x
(* After translation *)
let f_unboxed x0 x1 = let x = (x0, x1) in some_code x
let f x = let x0, x1 = x in f_unboxed x0 x1 The new |
Thanks. I think we can do a lot better than just disabling it for local parameters, but it does require a little bit of work. Basically, you want to rule out functions like this:
that take a local thing from outside the current region and return it. They would require allocating in the parent's region and that's not a great idea. Such functions have the parameter This means that, when a parameter is marked as |
Concretely, when a parameter is annotated as unboxable you want this if to go down the else branch even when |
Does it mean that the transformation has to happen before or during translcore ? Doing that after the normal insertion of regions looks a bit fragile. |
It would be best to do the insertion of the allocation during translcore, then there is no danger of it removing the region. Alternatively, you could annotate the region during translcore in some way to say that it can't be removed until after the transformation has been done. |
The current implementation of unboxing for parameters in Flambda2 will create allocations in the unboxed version, with the hope that these allocations will be simplified away. However, for values with local mode, inserting such allocations is bad, because we don't know the region in which they're going to live.
So until we've found a proper way to handle that, unboxing is disallowed for values with local mode.
Note that an
[@unboxable]
attribute does not prevent the type-checker from inferring a local mode, so we can end up rejecting an[@unboxable]
attribute even though the code contains no explicit local annotations.