Skip to content

Internal ppxlib migration attributes are sometimes left in the AST #597

@patricoferris

Description

@patricoferris

Ppxlib sometimes uses AST attributes to encode information needed to perform a correct round-trip migration. For example, to correctly roundtrip function arity, we make use of ppxlib.migration.stop_taking to indicate that we should "stop taking" function arguments:

let attr = mk_ghost_attr "ppxlib.migration.stop_taking" in

In the corresponding, opposite migration (in this example, upwards from 501 to 502) there is code to make use of this attribute, and importantly remove it.

However, this opposite migration does not always happen. For example, ppxlib 0.35.0 has an internal AST from OCaml 4.14.0. If ppxlib is used on a compiler 5.2.0 and above, only the downward migration will happen which introduces the ppxlib.migration.stop_taking attribute which is then never removed as we do not migrate the AST back up through 501->502.

We need to remove any extra information ppxlib encodes in the AST for migrations. There are at least three options:

  1. Use a separate data-structure to encode extra information to help with migrations but that leaves the AST itself intact.
  2. Remove the extra information until it is needed. For example, for a vast majority of ppxlib use-cases, 0.35.0 does not need the extra migration information (unless someone is manually migrating the AST back up).
  3. Have some function that removes all of this extra information and enforce some policy that users will have to call this function in order to have a clean AST (this could perhaps be enforce via the type system?).

Test Case

Using a 5.2.0 (or higher) compiler with ppxlib.0.35.0 installed, create a standalone executable:

let () = Ppxlib.Driver.standalone ()

Call it on the following test.ml file:

let f a = fun b -> a + b

Which produces the following:

let f a = ((fun b -> a + b)[@ppxlib.migration.stop_taking ])

Thanks to @n-osborne for setting me on this issue.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions