Skip to content
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

map plugin: add a type annotation to avoid warning 41 #163

Merged
merged 1 commit into from
Mar 6, 2018

Conversation

emillon
Copy link
Contributor

@emillon emillon commented Feb 2, 2018

Hi!

In some cases like the following, the generated code can emit instances of warning 41.

type 'a t1 = { x : 'a ; y1 : int } [@@deriving map]
type 'a t2 = { x : 'a ; y2 : int } [@@deriving map]

An alternative would be to add a constraint to the generated map function, but it does not seem to play well with polymorphism.

I also removed an intermediate List.concat since the list is always a singleton.

Let me know what you think.

Thanks!

@gasche
Copy link
Contributor

gasche commented Feb 2, 2018

Warning 41 (Ambiguous constructor or label name.) occurs when several record declarations with the used label are in scope, but the type information does not suffice to disambiguate which is meant (so we default to the declartion introduced last in scope).

It would be possible to fix the warning rather than silencing it, by adding an annotation in the generated code. (I think that would be slightly preferable if the cost is low, as it makes the code more robust to tooling changes etc.) Right now the generated code is as follows:

type 'a t1 = {
  x: 'a ;
  y1: int }[@@deriving map]
let rec map_t1 poly_a x = { x = (poly_a x.x); y1 = ((fun x -> x) x.y1) }
  [@@ocaml.warning "-39"]
type 'a t2 = {
  x: 'a ;
  y2: int }[@@deriving map]
let rec map_t2 poly_a x = { x = (poly_a x.x); y2 = ((fun x -> x) x.y2) }
  [@@ocaml.warning "-39"]

and the problematic part is the second occurrence of x.x, which may reference to either t1 or t2. Using

let rec map_t2 poly_a (x : _ t2) = ...

would suffice to silence the warning, but of course we could think of a more complete annotation.

Do some derivers already take care of producing the right annotation, whose code could be reused?

@gasche
Copy link
Contributor

gasche commented Feb 2, 2018

P.S.: I'm not convinced by the removal of the List.concat. It is a general design pattern to assume that str_of_type may return zero, one or several structure items for each type declarations, that occurs across many different deriving plugins. Right now the change looks like a simplification, but if you wanted to change the code later to generate an auxiliary declaration/module you would have to change back.

(Just for fun I grepped for lines of code containing type_decls) in my ppx directories. 34 of them also contain List.concat, and only 8 don't.)

@emillon
Copy link
Contributor Author

emillon commented Feb 2, 2018

_ t2 seems to be a good balance between suppressing the warning and adding a full polymorphic type annotation. I'll change to that.

For the concat, I don't think it's worth adding code "just in case". It's a private API just local to the module and it would be just as easy to add back, but in the meantime it just adds some noise to a module that's already pretty hard to read because of the domain logic. If you insist on keeping the concat call, may I suggest extracting a stri_of_type that just returns the structure item, a str_of_type that builds the list?

In cases like this, instances of warning 41 can be emitted:

```ocaml
type 'a t1 = { x : 'a ; y1 : int } [@@deriving map]
type 'a t2 = { x : 'a ; y2 : int } [@@deriving map]
```
@emillon
Copy link
Contributor Author

emillon commented Feb 2, 2018

And done! It seems that core_type_of_type_decl does the right thing: the generated code is now let rec map poly_a poly_b (x : ('a, 'b) t) = ....

@emillon emillon changed the title map plugin: suppress warning 41 in generated code map plugin: add a type annotation to avoid warning 41 Feb 2, 2018
Copy link
Contributor

@gasche gasche left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The new approach looks very nice to me, thanks!

@gasche
Copy link
Contributor

gasche commented Mar 6, 2018

I'm not sure why we delayed merging this for so long, I think I thought @emillon would merge or something. Apologies for the delay, merging now.

@gasche gasche merged commit 7c578e5 into ocaml-ppx:master Mar 6, 2018
@emillon emillon deleted the add-constraint-to-map-expr branch March 6, 2018 08:31
@emillon
Copy link
Contributor Author

emillon commented Mar 6, 2018

No problem! I had forgotten as well 😅 .

gasche added a commit to gasche/opam-repository that referenced this pull request Jun 8, 2019
4.3 Changelog:

* 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)

First attempt: ocaml#13652

The second attempt incorporated minor changes to the opam file (no
other change to the ppx_deriving pre-release), and occurred after the
revdeps failures of the first attempt have been reviewed and fixed.

Second attempt: ocaml#14018

Kate helped investigate the few failures remaining with the second
attempt, and provided the motivation for finally getting the release
out -- opam-repository will always be in an imperfect state... Thanks!
kit-ty-kate added a commit to kit-ty-kate/opam-repository that referenced this pull request Oct 26, 2020
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.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants