-
Notifications
You must be signed in to change notification settings - Fork 89
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
Migrate to ppxlib #206
Migrate to ppxlib #206
Conversation
Ẁow, thanks a lot! I'm looking forward to having a look at this -- I might need a few more days before I have time for a proper review. I don't have much experience working with ppxlib project. One thing that I find a bit surprising is that, for most files, you never explicitly state that you want the 4.08 version of the AST (some other modules are explicitly accessed with a |
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 you may now simplify all
# if OCAML_VERSION >= (4, 03, 0)
...
after this PR. This if statement is now always true.
As a consequence, cppo may be removed from many rules.
I can reproduce the stackoverflow in CI:
|
open Ast_helper | ||
|
||
module Ast_convenience = struct |
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.
Do we really need to redefine this? As far as I see, we are upgrading the version of the AST used by ppx_deriving - that is already a breaking change. We might as well ask users to switch to the ppxlib API in their plugins as well.
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.
The idea was mainly to reduce the amount of changes elsewhere in the library (because Ast_convenience
is used a lot of times in standard plugins).
Thanks, such comparisons are now removed systematically (commit 5d050c). |
Oops. My new code based on Ppxlib.map was incorrect (even if I was not able to figure why exactly), I restored the previous code based on Ast_mapper (even if it is now somehow discouraged by ppxlib). |
(Sorry for the very late answer: holidays, etc.)
As far as I understand, each
I think yes.
The previous times that ppxlib bumped OCaml AST versions, upper-bounds were added to all the packages that used the previous version in opam-repository. I think that it is better to wait for the next AST bump before being explicit about the upper-bound, otherwise the package will become uninstallable each time ppxlib is updated (even if the AST version remains stable). |
So, if I understand correctly, ppxlib fixes a given "recent enough" compiler version that it supports well, and deals with all other versions (older or more recent) through o-m-p conversion. Migrating to this model has a downside: users of OCaml versions more recent than ppxlib's standardized version will not be able to use their new syntactic constructs (in types) before ppxlib globally upgrades its version. Before, on each new OCaml release, ppx_deriving would have to get work to update to the new AST format (conditionally), and then users could use it (including new features) as soon as that work was done. After the switch, we don't have to do much on new OCaml versions, but users have to wait for ppxlib to upgrade to use recent features (for mere refactoring of the AST, o-m-p has their back). This upgrade is done infrequently as it breaks all ppxlib users. On the other hand, in practice before I would ensure that ppx_deriving compiles with the new OCaml version, but not that it actually supports new AST features (and: radical new changes to the type-declaration AST are fairly rare anyway). So if you tried to use one of those shiny recent features, chances are you would get into an |
Well, seems that ppxlib is just a temporary solution anyway, before new ppx is ready. |
But we don't know when the new ppx will be ready, and ppxlib already brings benefits today, so adopting ppxlib now makes a lot of sense. |
@gasche yes. I just meant that it will break older versions anyway, once migration to ppx is finished. |
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 just had an IRL meeting with @thierry-martinez to review this together (thanks!).
I now understand the PR much better, it looks very nice.
Moving to ppxlib gives us a bit less flexibility (theoretically today we could support all OCaml versions perfectly with enough work; with ppxlib we cannot deal with constructs newer than 4.08 in the [@@deriving]
-annotated parts), but the removed maintenance work makes it well worth it.
I wrote many comments on questions and additional explanations in the review. The only potential code changes to consider could be the following one:
- currently we run the whole program through the current->4.08 migration transform, but it should be possible to use Ocaml_current mapper on the whole program, and only transform the
[@@deriving]
-annotated parts.
(Minor note: the commits are not independent and could be squashed into one.)
As we went through the review, we kept a list of changes that were systematically applied in the plugin code. We should document them clearly for plugin authors, to ensure a smooth transition (all plugins will have to be updated the support the new ppxlib/o-m-p interface, but the changes are minimal.)
open Ppxlib
shadows compilerlibs modules with slightly different interfaces. In most cases it works fine,
but sometime you need to prefix the compilerlibs module (typicallyLocation
) withOcaml_common
(this is a submodule ofPpxlib
that re-exports compilerlibs-style modules.)Ast_convenience
(from ppx_tools) is not visible anymore, usePpx_deriving.Ast_convenience
instead.- All
IF OCAML_VERSION
tests can be removed: ppxlib forces all processors to use the 4.08 edition (currently). - Usage of metaquotations (
[%type: ...]
,[%expr ...]
) are now only valid ifloc
identifier is in scope; when in doubt, addlet loc = !Ast_helper.default_loc in
above the metaquotations. (Metaquotations are now provided by Ppxlib.metaquot instead of Ppx_tools.metaquot, and the implementation is slightly different.) - typical change to dune-based build systems, using
(pps ppxlib.metaquot)
instead of the(action (run ppxfind ...))
directive. (+ addition ofppxlib
in the list oflibraries
dependencies)
Note: @thierry-martinez also suggests trying to turn Ppx_deriving.register
into a Ppxlib.Deriving.add
call with an adaptation layer (instead of mapping through the whole program as is still done in this PR). We could consider this for a future PR.
@@ -9,6 +9,7 @@ let string_of_tyvar tyvar = | |||
#endif | |||
|
|||
let test_free_vars ctxt = | |||
let loc = !Ast_helper.default_loc in |
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.
Explanation: the metaquot
subsystem of ppxlib requires a loc
variable in context, while ppx_metaquot did not.
@@ -79,7 +76,7 @@ val create : | |||
val lookup : string -> deriver option | |||
|
|||
(** {2 Error handling} *) | |||
val raise_errorf : ?sub:Location.error list -> | |||
val raise_errorf : ?sub:Ocaml_common.Location.error list -> |
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.
@thierry-martinez explains doing an IRL review: ppxlib hides certain compilerlib modules that are considered unstable/unsupported. You have to explicitly use the Ocaml_common
submodule to explicitly access those unstable modules.
src/api/ppx_deriving.cppo.mli
Outdated
@@ -324,9 +321,60 @@ val strong_type_of_type: core_type -> core_type | |||
|
|||
(** The mapper for the currently loaded deriving plugins. It is useful for | |||
recursively processing expression-valued attributes. *) | |||
|
|||
module Ast_mapper = Migrate_parsetree.OCaml_408.Ast.Ast_mapper |
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.
ppxlib has a different to map over the AST (Ast_traverse.map
), but here @thierry-martinez used the Ast_mapper
module through o-m-p to keep the change less invasive.
val mapper : Ast_mapper.mapper | ||
|
||
(** {2 Miscellanea} *) | ||
|
||
(** [hash_variant x] ≡ [Btype.hash_variant x]. *) | ||
val hash_variant : string -> int | ||
|
||
module Ast_convenience : sig |
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.
Ast_convenience
was from ppx_tools and does not exist in o-m-p. Re-exporting makes the change less invasive.
Migrate_parsetree.Convert (Migrate_parsetree.OCaml_current) | ||
(Migrate_parsetree.OCaml_408) in | ||
let omp_mapper = | ||
Convert.copy_mapper (Migrate_parsetree.Driver.run_as_ast_mapper []) in |
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.
This piece of code converts the current-ast into 4.08-ast (as fixed by ppxlib) to run mapper
on it. On review, @thierry-martinez suggests that we could in fact keep a current-ast mapper for this part, and only rewrite into 4.08 on the declarations that do carry the [@@deriving ...]
annotations.
src/api/ppx_deriving.cppo.ml
Outdated
@@ -762,5 +807,5 @@ let hash_variant s = | |||
driver. *) | |||
let () = | |||
Migrate_parsetree.Driver.register ~name:"ppx_deriving" | |||
(module Migrate_parsetree.OCaml_current) | |||
(module Migrate_parsetree.OCaml_408) | |||
(fun _ _ -> mapper) |
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.
Note: api/ppx_deriving
here registers the mapper into the o-m-p driver (for use with other o-m-p-enabled transformations). In src/ppx_deriving_main
there is another registration mechanism, using Ast_mapper
from the compilerlibs, which is only used when producing an executable-style preprocessor (instead of being linked as a plugin of a driver executable). The two registration mechanisms seem to cohabit nicely enough, and in any case were already present before this PR.
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.
Would it be possible to use ppxlib's registration mechanism? Even if you don't use the context free api, it still has some advantages.
open Location | ||
open Asttypes | ||
open Parsetree | ||
open Ast_helper | ||
open Ast_convenience | ||
open Ppx_deriving.Ast_convenience |
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.
We now have to use our own redefinition of Ast_convenience
, so plugin code has to be adapted slightly. (Note: not redefining Ast_convenience
would mean cumbersome changes for third-party plugin authors.)
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.
The most notable change for this plugin is that essentially no (other) code change is required for plugin authors. (The patchset only get rids of now-useless IFDEFs.)
@@ -1,11 +1,9 @@ | |||
#include "../compat_macros.cppo" | |||
|
|||
open Longident |
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.
Longident
is not opened anymore. @thierry-martinez explains that we could not open Ppxlib.Longident in the global scope because that one shadows (=)
from the standard library (to be monomorphic on longidents), which we use in plugin code.
(action (run ppxfind -legacy ppx_tools.metaquot --as-pp %{input-file}))) | ||
(libraries compiler-libs.common ppx_tools ppx_deriving.api) | ||
(pps ppxlib.metaquot)) | ||
(libraries compiler-libs.common ppxlib ppx_deriving.api) |
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.
Plugin authors will have to change their build system in a similar way to this. Releases of the plugin with this new style will not be compatible with older versions of ppx_deriving -- but they are compatible with older OCaml releases. (@thierry-martinez explains: the reason why we need a change is that ppxlib's metaquot is fixed on 4.08, while ppx_tools.metaquot works on the current OCaml version.)
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.
So plugin authors will have to add an upper bound on their older releases to the latest non-ppxlib version, and a lower bound on their new ppxlib-friendly releases on the new ppx_deriving version. But both kind of versions will support existing OCaml releases, and the code changes are very small in simple cases.
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.
Is compiler-libs.common
still needed as a dependency here btw? Shouldn't we be using ocaml-compiler-libs
?
let sub = [Location.errorf ~loc:bloc "Same as for %s%s" sigil btxt] in | ||
let sub = | ||
[Ocaml_common.Location.errorf | ||
~loc:bloc "Same as for %s%s" sigil btxt] in |
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.
Note: we will have to document this small change patterns to third-party plugin authors.
Doesn't ppx_tools already force ppx_deriving's hand this way?
In practice, Users of ppx_deriving should not be recommended to upgrade to a version of OCaml until ppxlib worked well on it. In my opinion, we should switch to ppxlib. In ppx, there's going to be features that should make the transition easier and ppxlib will not be broken overnight once ppx is released. |
The difference, if I understand correctly, is that as soon as ppx_tools is released for a new OCaml version, all constructs of this new version work correctly with the ppx_tools codebase. For ppxlib, as long as ppxlib's own AST versoin is fixed to 4.08, releases that provide newer-version support will let users use ppx_deriving, but not in combination with the not-in-4.08 features. ppxlib could upgrade to a more recent OCaml version, but this is (if I understand correctly) done somewhat infrequently, to limit the amount of code churn (... otherwise ppxlib users would have to adapt their code at each OCaml release, which is precisely what they don't want). |
Okay, then I think we're on the same page. Just to confirm: I don't think it's in the interest of (most) users to follow changes in the compiler as soon as possible. A more controlled upgrade process as in ppxlib would be more preferable for them. |
If I'm a user of ppx_deriving and its plugin, what I want is for this code to work on my codebase whatever I do. (But of course this may require infinite amount of work for the maintainers of ppx_deriving and its plugins.) It's never in the interest of those downstream users to be told "nope, this feature is not supported yet". If I'm a plugin author, or maintainer of ppx_deriving (both are in the same boat), I have to make a choice between (1) doing the upgrade to newer OCaml features ourselves, which makes our user maximally happy (but requires maximal work), or (2) relying on a compatibility layer such as o-m-p and ppxlib, which moves the decision to other people. With o-m-p alone, I can expect good compatibility with new features a couple weeks after each new release (so my users don't really see the difference with me putting the work). With ppxlib, I tell them that I'm bound on 4.08, and I won't change except every few years; convenient for me, but choices are taken away from them (and also from me). |
This makes users happy in the short term, especially if they're just kicking the tires off a new release. Most users are much better off waiting until ppxlib (and similarly merlin, ocamlformat, dune, etc.) are updated to support the features they want. Yes, they might have their concrete problems with ppx_deriving solved earlier, but it's quite likely they'll run into other related problems. Anyways, I think we're in violent agreement regarding this PR regardless of the details :) |
I agree that we are in agreement, but I remain confused by your point. Merlin, ocamlformat, dune already support the full 4.09 language, and will support the full 4.10 shortly. My point is that ppxlib, by design, will stay longer on an older OCaml release (4.08), offering only partial compatibility with newer language features. I think this has a clear cost that extension authors deciding to rely on ppxlib need to be aware of, and it cannot be turned into a good thing; it's a downside (that comes with other positive aspects of the tools). |
The latest version of merlin does not support 4.09. As for the other tools, it's definitely a bit harder to bring examples from the past that aren't parse tree related. Let's take the upcoming I'm not really sure ppxlib stays behind by design by the way. It's just quite a bit larger than omp so it's not as easy to port it. Anyhow, let's switch gear and discuss this PR :) Do you think we should port the common plugins to work with this PR before making a release? I would think that |
Yes, I was planning to port some plugins, and then use the opam-ci to observe the revdep breakage and clear them before the release. (But for some plugins we can just add an upper bound on older versions, without making a compatible release.). It is possible that unforeseen compatibility issues would delay the release. |
I have a port of ppx_deriving_yojson to use ppxlib and the version of ppx_deriving in this branch. Things are working fine and I'm planning to do a similar port of ppx_deriving_protobuf. I'll put up some PR's shortly. |
In fact, since this PR completely eliminates the ifdef's we should just remove cppo entirely. We can rename the filenames to be just .ml and .mli, and remove cppo from the opam file. |
- Lower bound on OCaml version is raised to 4.04.1 because ppxlib 0.9.0 requires it. - ppx_tools is no longer used, because it is not compatible with ppxlib. ppx_tools was mostly used (1) for metaquot, which is handled by ppxlib.metaquot, and (2) for the Ast_convenience module, which is now defined in Ppx_deriving module. - Most cppo conditional directives are gone, either because they were there to support OCaml <4.04.1, or because they are subsumed by the Migrate_parsetree.OCaml_408 implied by opening Ppxlib.
5b223a2
to
30f6819
Compare
AST is now converted at the level of each type declaration when |
| _ -> Ast_mapper.(default_mapper.expr) mapper expr | ||
end | ||
| _ -> Ast_mapper.(default_mapper.expr) mapper expr | ||
in | ||
let structure mapper items = | ||
match items with | ||
| { pstr_desc = Pstr_type(_, typ_decls) as pstr_desc ; pstr_loc } :: rest when | ||
List.exists (fun ty -> has_attr "deriving" ty.ptype_attributes) typ_decls | ||
List.exists (fun ty -> has_attr_current "deriving" ty.ptype_attributes) typ_decls |
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 it would make sense to shadow has_attr
with has_attr_current
at the beginning of mapper
, so that these don't have to change.
I believe there's still a bit of cppo that can be removed after the switch to ppxlib. For example:
In |
I'm also in favor of removing all these macros now:
|
Also, we should remove the unsupported versions of OCaml from CI. |
Would be nice to retest with the newer ppxlib-0.10.0 released recently. |
Any updates on this one? |
@XVilka if you are dependent on this work, would you mind helping out? We could definitely use some help here to get it out faster. |
@rgrinberg ok, will do |
For the PR inside ppxlib itself, I think that not much more needs to be done than me taking a last look and clicking the "merge" button. Then we need to port the outside-tree plugins to the new API, and also to be careful in the release process to detect compatibility failures (with plugins or with user code); there will be a ton of revdeps to analyse carefully, and of course help will be more than welcome then. |
@gasche @rgrinberg there are some cppo macroses left, to support 4.04. What do you think about dropping 4.04 entirely and do minimum requirement of 4.05? See the particular example of https://travis-ci.org/ocaml-ppx/ppx_deriving/jobs/615082503#L2243 |
I think it's a good idea because the old version of ppx_deriving should still be available to users of 4.04. Are you referring to the macros that I mentioned? I don't think those are needed to support 4.04. When we use ppxlib, we are using the version of Ast that it gives us, and there's no need to conditionally compile for other versions of the Ast. |
@rgrinberg no, there are some leftovers in tests |
I created a new pull request since cannot push here #210 |
Continued in #210 . |
CHANGES: 5.0 (26/10/2020) ---------------- * Migrate to ppxlib ocaml-ppx/ppx_deriving#206, ocaml-ppx/ppx_deriving#210 (Anton Kochkov, Gabriel Scherer, Thierry Martinez) 4.5 --- * Add support for OCaml 4.11. - `Ppx_deriving.string_of_{constant,expression}_opt` to destruct `Pconst_string` in a version-independent way ocaml-ppx/ppx_deriving#220, ocaml-ppx/ppx_deriving#222 (Kate Deplaix, Thierry Martinez, review by Gabriel Scherer) * Stronger type equalities in `Ppx_deriving_runtime` (for instance, `Ppx_deriving_runtime.result` and `Result.result` are now compatible with all OCaml versions) ocaml-ppx/ppx_deriving#223, ocaml-ppx/ppx_deriving#225 (Thierry Martinez, review by Gabriel Scherer) * `Ppx_deriving_runtime.Option` compatibility module ocaml-ppx/ppx_deriving#222 (Thierry Martinez, review by Gabriel Scherer) 4.4.1 ----- * Add support for OCaml 4.10 ocaml-ppx/ppx_deriving#211 (Kate Deplaix, review by Gabriel Scherer) 4.4 --- * Restore support for OCaml 4.02.3 ocaml-ppx/ppx_deriving#188 (ELLIOTTCABLE) * workaround Location.input_filename being empty when using reason-language-server ocaml-ppx/ppx_deriving#196 (Ryan Artecona) * Add support for OCaml 4.08.0 ocaml-ppx/ppx_deriving#193, ocaml-ppx/ppx_deriving#197, ocaml-ppx/ppx_deriving#200 (Gabriel Scherer) 4.3 --- * use Format through Ppx_deriving_runtime to avoid deprecation warning for users of JaneStreet Base (Stephen Bastians and Gabriel Scherer, review by whitequark) * silence a ambiguous-field warning (41) in generated code ocaml-ppx/ppx_deriving#163 (Étienne Millon, review by Gabriel Scherer) * use dune ocaml-ppx/ppx_deriving#170 (Rudi Grinberg, Jérémie Dimino) * silence an unused-value warning for show ocaml-ppx/ppx_deriving#179 (Nathan Rebours) 4.2.1 ----- * Add support for OCaml 4.06.0 ocaml-ppx/ppx_deriving#154, ocaml-ppx/ppx_deriving#155, ocaml-ppx/ppx_deriving#156, ocaml-ppx/ppx_deriving#159 (Gabriel Scherer, Fabian, Leonid Rozenberg) * Consider { with_path = false } when printing record fields ocaml-ppx/ppx_deriving#157 (François Pottier) 4.2 --- * Add support for OCaml 4.05.0. * Use the `ocaml-migrate-parsetree` library to support multiple versions of OCaml. * Fix comparison order of fields in records (ocaml-ppx/ppx_deriving#136). * Silence an `unused rec flag` warning in generated code (ocaml-ppx/ppx_deriving#137). * Monomorphize comparison function for builtin types (ocaml-ppx/ppx_deriving#115) * Raise an error when `type nonrec` is encountered (ocaml-ppx/ppx_deriving#116). * Display an error message when dynamic package loading fails. * Add a `with_path` option to `@@deriving` to skip the module path in generated code (ocaml-ppx/ppx_deriving#120). The homepage for the project has now moved to: <https://github.com/ocaml-ppx/ppx_deriving> 4.1 --- * Fix type error with inheritied polymorphic variant type in [@@deriving map]. * Fix incorrect handling of multi-argument constructors in [@@deriving show]. * Add API hooks for ppx_type_conv. 4.0 --- * Show, eq, ord, map, iter, fold: add support for `Result.result`. * Ppx_deriving.Arg: use Result.result instead of polymorphic variants. * Ppx_deriving.sanitize: parameterize over an opened module. * Add support for `[@@deriving]` in module type declarations. * Add support for loading findlib packages instead of just files in ppx_deriving_main. * Treat types explicitly qualified with Pervasives also as builtin. * Compatibility with statically linked ppx drivers. 3.1 --- * Show, eq, ord: hygienically invoke functions from referenced modules (such as X.pp for X.t when deriving show) to coexist with modules shadowing ones from standard library. * Iter, map, fold: hygienically invoke List and Array functions. 3.0 --- * Implement hygiene: Ppx_deriving.{create_quoter,quote,sanitize,with_quoter}. * Show, eq, ord: add support for `lazy_t`. * Add support for `[@nobuiltin]` attribute. * Add Ppx_deriving.hash_variant. * Remove allow_std_type_shadowing option. * Remove Ppx_deriving.extract_typename_of_type_group. 2.1 --- * Fix breakage occurring with 4.02.2 w.r.t record labels * Fix prefixed attribute names (`[@deriving.foo.attr]` and `[@foo.attr]`). * Add allow_std_type_shadowing option for eq and show. 2.0 --- * Add support for open types. 1.1 --- * New plugin: create. * Show, eq, ord: handle `_`. * Show, eq, ord, map, iter, fold: handle inheriting from a parametric polymorphic variant type. * Make `Ppx_deriving.poly_{fun,arrow}_of_type_decl` construct functions in correct order. This also fixes all derivers with types with more than one parameter. * Add `Ppx_deriving.fold_{left,right}_type_decl`. 1.0 --- * Make deriver names lowercase. * Remove Findlib+dynlink integration. All derivers must now be explicitly required. * Allow shortening [%derive.x:] to [%x:] when deriver x exists. * Make `Ppx_deriving.core_type` field optional to allow ignoring unsupported [%x:] shorthands. * Add support for [@@deriving foo { optional = true }] that does not error out if foo is missing, useful for optional dependencies. * Rename ~name and ~prefix of `Ppx_deriving.attr` and `Ppx_deriving.Arg.payload` to `~deriver`. * Renamed `Ppx_deriving.Arg.payload` to `get_attr`. * Add `Ppx_deriving.Arg.get_expr` and `get_flag`. 0.3 --- * Show, Eq, Ord, Iter, Fold: handle ref. * Show: handle functions. * Show: include break hints in format strings. * Show: pull fprintf into local environment. * Show: add `[@polyprinter]` and `[@opaque]`. * Add `Ppx_deriving.Arg.expr`. 0.2 --- * New plugins: Enum, Iter, Map, Fold. * All plugins: don't concatenate affix if type is named `t`. * Add `[%derive.Foo:]` shorthand. * Show, Eq, Ord: add support for list, array, option. * Show: include full module path in output, including for types with manifest. * A lot of changes in `Ppx_deriving interface`. 0.1 --- * Initial release.
CHANGES: * Migrate to ppxlib ocaml-ppx/ppx_deriving#206, ocaml-ppx/ppx_deriving#210 (Anton Kochkov, Gabriel Scherer, Thierry Martinez)
Lower bound on OCaml version is raised to 4.04.1 because ppxlib
0.9.0 requires it.
ppx_tools is no longer used, because it is not compatible with
ppxlib. ppx_tools was mostly used (1) for metaquot, which is handled
by ppxlib.metaquot, and (2) for the Ast_convenience module, which is
now defined in Ppx_deriving module.
Most cppo conditional directives are gone, either because they
were there to support OCaml <4.04.1, or because they are subsumed
by the Migrate_parsetree.OCaml_408 implied by opening Ppxlib.