-
Notifications
You must be signed in to change notification settings - Fork 99
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
5.1 migrations: Add tests for generative functors #432
Conversation
Thanks for the descriptive issue, the pointers to the upstream PR and the test @pitag-ha, it was all very useful! My understanding of what needs to be done is:
Is it correct? If so, here's a patch to do this (I'm unsure about the effect of not having the locations in the attribute though): diff --git a/astlib/migrate_500_501.ml b/astlib/migrate_500_501.ml
index bb26e4f3..572d399a 100644
--- a/astlib/migrate_500_501.ml
+++ b/astlib/migrate_500_501.ml
@@ -750,6 +750,40 @@ and copy_module_expr_desc :
| Ast_500.Parsetree.Pmod_functor (x0, x1) ->
Ast_501.Parsetree.Pmod_functor
(copy_functor_parameter x0, copy_module_expr x1)
+ | Ast_500.Parsetree.Pmod_apply
+ ( x0,
+ ({ pmod_desc = Pmod_structure []; pmod_loc = _; pmod_attributes = _ } as
+ x1) ) ->
+ let x1 = copy_module_expr x1 in
+ let Ast_501.Parsetree.{ pmod_desc; pmod_attributes; pmod_loc } = x1 in
+ let pmod_attributes =
+ Ast_501.Parsetree.
+ {
+ attr_name = { txt = "ocaml.warning"; loc = Location.none };
+ attr_payload =
+ PStr
+ [
+ {
+ pstr_desc =
+ Pstr_eval
+ ( {
+ pexp_desc =
+ Pexp_constant
+ (Pconst_string ("-73", Location.none, None));
+ pexp_loc = Location.none;
+ pexp_loc_stack = [];
+ pexp_attributes = [];
+ },
+ [] );
+ pstr_loc = Location.none;
+ };
+ ];
+ attr_loc = Location.none;
+ }
+ :: pmod_attributes
+ in
+ Ast_501.Parsetree.Pmod_apply
+ (copy_module_expr x0, { pmod_desc; pmod_attributes; pmod_loc })
| Ast_500.Parsetree.Pmod_apply (x0, x1) ->
Ast_501.Parsetree.Pmod_apply (copy_module_expr x0, copy_module_expr x1)
| Ast_500.Parsetree.Pmod_constraint (x0, x1) -> |
Thanks for working on this, @tmattio!
We don't need to add the warning to the AST. The compiler will trigger the warning automatically on 501 on Ideally, we don't want the migrations to change the parsing behavior at all, i.e. we want
However, I'm not sure whether that's possible: Possibly,
PD: If it's the latter, then
I'd personally keep things simple and not do that, though. |
Oh, I forgot to mention: To find out whether |
Ah yes sorry I skipped the result of the detective work, assuming you already had the right migration in mind, let me expand on my message.
For the 501 -> 500 migration, there's no question:
For the 500 -> 501 migration, we have two options:
Con of (1.) is that Either way, we end up with a different syntax than we had at the beginning, so I am tempted to explore the option you listed and add attributes when down-migrating so we can restore the initial syntax. Could you expand on that idea? What attributes would you add? |
Right, I misread what you wrote. There's another important point to take into account when comparing option 1. and option 2.: Which of the two keeps the two round trips 501 -> 500 -> 501 and 500 -> 501 -> 500 as close to the identity as possible? Under that criteria, option 2. is better: Option 1.:
Option 2.:
So I'm still clearly in favor of option 2 between those two. |
You could use an attribute to distinguish the two 501 nodes also in 500:
Then, 500 -> 501 could do:
The downside would be that it means a bit more work:
The upside would be that the 501 - 500 - 501 roundtrip (i.e. the roundtrip that happens before we bump the AST) wouldn't silence the new |
I agree, I'll do it with the attribute and the way you suggested, thank you! |
Just some small comments about this...
would take care of roundtripping 501 -> 500 -> 501, but would not work well with generated code. If a PPX generates
|
692f936
to
cf54060
Compare
The migrations tests for generative functors now work, apart from locations, however all locations are reasonable: they won't confuse the user too much. |
9b2b53a
to
d3517c5
Compare
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.
Nice, thanks a lot for picking this up and finding and implementing a good solution!
I have two small questions about locations below, but everything looks good (I can't officially Approve
as I'm the theoretical author of the PR, but I would if I could).
However, more importantly: I assume the none Location reported in #433 (comment) came from the none Location in the emptry_struct
. Do you also think so?
Btw, a test with some attributes (both in syntax and generated by e.g. metaquot) would make the tests even more complete.
astlib/migrate_501_500.ml
Outdated
loc = { x1.pmod_loc with loc_ghost = true }; | ||
}; | ||
attr_payload = Ast_500.Parsetree.PStr []; | ||
attr_loc = Location.none; |
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.
Why Location.none
instead of { x1.pmod_loc with loc_ghost = true }
like above?
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.
Because you are right! It should be { x1.pmod_loc with loc_ghost = true }
like above
| Ast_501.Parsetree.Pmod_apply_unit x0 -> | ||
let empty_struct = | ||
Ast_500.Parsetree. | ||
{ | ||
pmod_desc = Pmod_structure []; | ||
pmod_loc = Location.none; | ||
pmod_loc = loc; |
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.
Shouldn't this be a ghost location?
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.
Yes, I guess it should be...
Currently it is not really used (the upward migration will not use it) but when the ppxlib AST is bumped to 5.1, it will be used.
I think I don't know sure enough how tooling treats ghost locations.
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.
Actually, making it ghost creates one more divergence in the reverse_migrations.t
test. So I guess it makes sense to leave it not ghost.
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 think I don't know sure enough how tooling treats ghost locations.
➕
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.
Some day (:tm:) I'll have a concrete look at what Merlin does.
Btw, this PR started off as "Add tests" and now is "Fix bug". Can you add the changelog entry? |
Signed-off-by: Sonja Heinze <sonjaleaheinze@gmail.com>
Signed-off-by: Sonja Heinze <sonjaleaheinze@gmail.com>
Signed-off-by: Paul-Elliot <peada@free.fr>
Two 501 constructs are represented the same way in 500. One of them raise a warning. During the 501 -> 500 -> 501 migration, we need to be careful to keep the warning where it was originally. We use attributes to remember which 501 representation to choose. The reserved namespace is "ppxlib.migration". Signed-off-by: Paul-Elliot <peada@free.fr>
Signed-off-by: Paul-Elliot <peada@free.fr>
Signed-off-by: Paul-Elliot <peada@free.fr>
Signed-off-by: Paul-Elliot <peada@free.fr>
baa3e81
to
d99bf41
Compare
Signed-off-by: Paul-Elliot <peada@free.fr>
I think so! Thanks for the review! I answered the comments, rebased and added a changelog entry. |
Signed-off-by: Paul-Elliot <peada@free.fr>
Thank you! It all looks good to me (can't officially approve because I'm the "author"). Do you want to merge? |
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 can approve!
CHANGES: - Fix support for OCaml 5.1: migrated code preserves generative functor warnings, without creating more. Locations are better preserved. (ocaml-ppx/ppxlib#432, @pitag-ha, @panglesd) - Driver: Add `-unused-code-warnings` command-line flag. (ocaml-ppx/ppxlib#444, @ceastlund) - Add `?warning` flag to `Deriving.Generator.make`. (ocaml-ppx/ppxlib#440, @jacksonzou123 via @ceastlund) - Restore the "path_arg" functionality in the V3 API (ocaml-ppx/ppxlib#431, @ELLIOTTCABLE) - Expose migration/copying/etc. functions for all AST types needed by `Pprintast` (ocaml-ppx/ppxlib#454, @antalsz) - Preserve quoted attributes on antiquotes in metaquot (ocaml-ppx/ppxlib#441, @ncik-roberts) - Attribute namespaces: Fix semantics of reserving multi-component namespaces (ocaml-ppx/ppxlib#443, @ncik-roberts)
CHANGES: - Fix support for OCaml 5.1: migrated code preserves generative functor warnings, without creating more. Locations are better preserved. (ocaml-ppx/ppxlib#432, @pitag-ha, @panglesd) - Driver: Add `-unused-code-warnings` command-line flag. (ocaml-ppx/ppxlib#444, @ceastlund) - Add `?warning` flag to `Deriving.Generator.make`. (ocaml-ppx/ppxlib#440, @jacksonzou123 via @ceastlund) - Restore the "path_arg" functionality in the V3 API (ocaml-ppx/ppxlib#431, @ELLIOTTCABLE) - Expose migration/copying/etc. functions for all AST types needed by `Pprintast` (ocaml-ppx/ppxlib#454, @antalsz) - Preserve quoted attributes on antiquotes in metaquot (ocaml-ppx/ppxlib#441, @ncik-roberts) - Attribute namespaces: Fix semantics of reserving multi-component namespaces (ocaml-ppx/ppxlib#443, @ncik-roberts)
When we added the migrations for the Parsetree change for generative functor application, we didn't have a test mechanism yet to test the migrations. Now that we have one, I've added those tests.
It turns out that the migrations aren't correct: One of the tests shows that our migrations turn
into
That bug is user-facing because the latter triggers a warning on 5.1. I've just opened in issue to keep track of that: #433