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
Fix #16288: wrongly self-referencing extraction of primitive projections in functors #17321
Fix #16288: wrongly self-referencing extraction of primitive projections in functors #17321
Conversation
Fixes coq#14843 Fixes coq#16677 Fixes coq#12813 When dealing with collisions by means of encapsulation in a Coq_XX module, a field name should be bound to the name of the corresponding inductive type declaration. We use Table.repr_of_r to do that, but early enough to have the relevant information on how to bind a field to the name of the inductive that declares it. (In particular, we cannot rely on the global tables in structures.ml because they are not valid when inside a functor, see coq#17321.)
Fixes coq#14843 Fixes coq#16677 Fixes coq#12813 When dealing with collisions by means of encapsulation in a Coq_XX module, a field name should be bound to the name of the corresponding inductive type declaration. We use Table.repr_of_r to do that, but early enough to have the relevant information on how to bind a field to the name of the inductive that declares it. (In particular, we cannot rely on the global tables in structures.ml because they are not valid when inside a functor, see coq#17321.)
…eld names. Fixes coq#14843 Fixes coq#16677 Fixes coq#12813 When dealing with collisions by means of encapsulation in a Coq_XX module, a field name should be bound to the name of the corresponding inductive type declaration. We use Table.repr_of_r to do that, but early enough to have the relevant information on how to bind a field to the name of the inductive that declares it. (In particular, we cannot rely on the global tables in structures.ml because they are not valid when inside a functor, see coq#17321.) Note that Haskell and Scheme do not use records and it is ok on their side.
@coqbot run full ci |
The failure in itauto is because the PR now extracts the constant form of a primitive projection only if the Coq code refers to it. Previously, a projection in the primitive form was elaborated in the projection in constant form, so, even if the Coq code referred only to the primitive form ( Set Primitive Projections.
Module Import A.
Record t := {a:bool;b:bool}.
End A.
Definition c x := x.(a).
Require Import Extraction.
Recursive Extraction c.
@coq/extraction-maintainers: that would probably not be too much a problem to say that when a projection in primitive form is used, we effectively extract the projection in constant form (even if strictly speaking not needed). In case you have an opinion, would I implement this for optimal compatibility, or do you think we can as well renounce to it (then, third-party developments mixing extracted Coq code with private OCaml code, such as itauto, will have to use in OCaml the |
I think the new behaviour is correct, it means that if using the constant form is desired then the user must say |
I should also have said that the new behavior creates a difference between "primitive" and non "primitive" projections, which maybe is weakening the flexibility in using or not the "Primitive Projections" flag. So, maybe, the extraction of the constant form should be removed also in the non primitive case, on the basis that in the extracted OCaml code of non primitive projections, only the dot notation is used too (except in a functor, where the same limitation as in the current report applies: the table telling that a constant is a (non primitive) projections is not active in a functor, so a non primitive projection is printed applicatively in a functor). |
…eld names. Fixes coq#14843 Fixes coq#16677 Fixes coq#12813 When dealing with collisions by means of encapsulation in a Coq_XX module, a field name should be bound to the name of the corresponding inductive type declaration. We use Table.repr_of_r to do that, but early enough to have the relevant information on how to bind a field to the name of the inductive that declares it. (In particular, we cannot rely on the global tables in structures.ml because they are not valid when inside a functor, see coq#17321.) Note that Haskell and Scheme do not use records and it is ok on their side.
…eld names. Fixes coq#3846 Fixes coq#14843 Fixes coq#16677 Fixes coq#12813 When dealing with collisions by means of encapsulation in a Coq_XX module, a field name should be bound to the name of the corresponding inductive type declaration. We use Table.repr_of_r to do that, but early enough to have the relevant information on how to bind a field to the name of the inductive that declares it. (In particular, we cannot rely on the global tables in structures.ml because they are not valid when inside a functor, see coq#17321.) Note that Haskell and Scheme do not use records and it is ok on their side.
After more digging, I could summarize the situation in issue #17337. In particular, prior to this PR, there is a difference of behavior wrt inlining between being at toplevel (where inlined functions are pruned) or in a module (where inlined functions, especially projections, are not pruned). I made #17341 to address this and this now shows the itauto failure even without this PR. In particular, I'm now leaning towards changing itauto. |
9850095
to
e829f33
Compare
e829f33
to
8747ab0
Compare
…eld names. Fixes coq#3846 Fixes coq#14843 Fixes coq#16677 Fixes coq#12813 When dealing with collisions by means of encapsulation in a Coq_XX module, a field name should be bound to the name of the corresponding inductive type declaration. We use Table.repr_of_r to do that, but early enough to have the relevant information on how to bind a field to the name of the inductive that declares it. (In particular, we cannot rely on the global tables in structures.ml because they are not valid when inside a functor, see coq#17321.) Note that Haskell and Scheme do not use records and it is ok on their side. (cherry picked from commit c19b2cd)
The "needs: rebase" label was set more than 30 days ago. If the PR is not rebased in 30 days, it will be automatically closed. |
8747ab0
to
afce393
Compare
- The code for extracting a primitive projection was referencing the constant form of the projection. - The code for compiling the constant form of the projection was doing a call to the global table of projections which is however not fed in functors. - The declaration of constants bound to a projection had a small size and were then inlined. Instead of relying on the table of projections, we use the "match"-expanded form of the projections which has the advantage of be valid in all target languages. In particular, in OCaml extraction, this is anyway reprinted as a field. Note: we need to move the fake_match_projection function a bit earlier.
afce393
to
acb2fb1
Compare
Rerunning CI, since it is a long time ago @coqbot run full ci |
This is an old PR looking for an assigne. @ppedrot, would you have some time by chance? |
This is a bit outside of my expertise area... There are weird spec considerations as well. I'll see if I can grok this. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm a bit puzzled about why you simply don't write the miniML matching directly instead of getting it by the composition of fake_match_projection + extract_term, but I guess it's a bit more uniform this way.
Merging soon if nobody complains. |
Thanks! |
@coqbot merge now |
Reviewed-by: ejgallego Co-authored-by: ejgallego <ejgallego@users.noreply.github.com>
Fixes #16288 (usual problem of imperative tables not being updated in functors).