Skip to content

Commit

Permalink
Merge pull request ocaml-ppx#299 from NathanReb/fix-type-is-rec
Browse files Browse the repository at this point in the history
Fix `type_is_recursive` and `really_recursive`
  • Loading branch information
NathanReb authored Nov 15, 2021
2 parents 6b0c42b + 7f04dd6 commit 24b3e1b
Show file tree
Hide file tree
Showing 5 changed files with 97 additions and 0 deletions.
1 change: 1 addition & 0 deletions .ocamlformat-ignore
Original file line number Diff line number Diff line change
Expand Up @@ -36,3 +36,4 @@ test/location/exception/test.ml
test/ppx_import_support/test.ml
test/quoter/test.ml
test/traverse/test.ml
test/type_is_recursive/test.ml
4 changes: 4 additions & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,10 @@ unreleased

- Improve error messages in ppx raised exceptions (#292, @panglesd)

- Fix a bug in `type_is_recursive` and `really_recursive` where they would
consider a type declaration recursive if the type appeared inside an attribute
payload (#299, @NathanReb)

0.23.0 (31/08/2021)
-------------------

Expand Down
3 changes: 3 additions & 0 deletions src/common.ml
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,9 @@ class type_is_recursive rec_flag tds =
| Pcstr_tuple args -> List.iter args ~f:self#core_type
| Pcstr_record fields -> List.iter fields ~f:self#label_declaration

method! attributes _ = (* Don't recurse through attributes *)
()

method go () =
match rec_flag with
| Nonrecursive -> Nonrecursive
Expand Down
13 changes: 13 additions & 0 deletions test/type_is_recursive/dune
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
(rule
(alias runtest)
(enabled_if
(>= %{ocaml_version} "4.10.0"))
(deps
(:test test.ml)
(package ppxlib))
(action
(chdir
%{project_root}
(progn
(run expect-test %{test})
(diff? %{test} %{test}.corrected)))))
76 changes: 76 additions & 0 deletions test/type_is_recursive/test.ml
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
open Ppxlib

let test_is_recursive stri =
match stri.pstr_desc with
| Pstr_type (rf, tds) -> really_recursive rf tds
| _ -> assert false

[%%expect{|
val test_is_recursive : structure_item -> rec_flag = <fun>
|}]

let loc = Location.none

[%%expect{|
val loc : location =
{Ppxlib.Location.loc_start =
{Lexing.pos_fname = "_none_"; pos_lnum = 1; pos_bol = 0; pos_cnum = -1};
loc_end =
{Lexing.pos_fname = "_none_"; pos_lnum = 1; pos_bol = 0; pos_cnum = -1};
loc_ghost = true}
|}]

(* Should be Nonrecursive *)
let base_type = test_is_recursive [%stri type t = int]

[%%expect{|
val base_type : rec_flag = Ppxlib__.Import.Nonrecursive
|}]

(* Should be Nonrecursive *)
let looks_recursive_but_is_not = test_is_recursive [%stri type nonrec t = t]

[%%expect{|
val looks_recursive_but_is_not : rec_flag = Ppxlib__.Import.Nonrecursive
|}]

(* Should be Nonrecursive *)
let variant_non_rec = test_is_recursive [%stri type t = A of int | B of string]

[%%expect{|
val variant_non_rec : rec_flag = Ppxlib__.Import.Nonrecursive
|}]

(* Should be Nonrecursive *)
let record_non_rec = test_is_recursive [%stri type t = {a: int; b: string}]

[%%expect{|
val record_non_rec : rec_flag = Ppxlib__.Import.Nonrecursive
|}]

(* Should be Recursive *)
let actually_recursive = test_is_recursive [%stri type t = A of int | T of t]

[%%expect{|
val actually_recursive : rec_flag = Ppxlib__.Import.Recursive
|}]

(* Should be Nonrecursive *)
let ignore_attributes = test_is_recursive [%stri type t = int [@attr: t]]

[%%expect{|
val ignore_attributes : rec_flag = Ppxlib__.Import.Nonrecursive
|}]

(* Should be Recursive
This is subject to debate. @ceastlund's intuition is that we should
traverse extensions so we'll stick to this for now.
It's less of a problem as it is likely that when [really_recursive] is called
those will have been expanded anyway. *)
let extension_points = test_is_recursive [%stri type t = [%ext: t]]

[%%expect{|
val extension_points : rec_flag = Ppxlib__.Import.Recursive
|}]

0 comments on commit 24b3e1b

Please sign in to comment.