Skip to content

Cleanup Outcometree and separated arg_labels #1652

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

Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
59 commits
Select commit Hold shift + click to select a range
32f9e45
src_pos in fn decls and defns
vivianyyd Jul 20, 2023
d18c590
Revert is_optional modifications for now
vivianyyd Jul 20, 2023
3dc24fc
src_pos shouldn't work in arbitrary places
vivianyyd Jul 20, 2023
a0a7c83
Tidy code
vivianyyd Jul 20, 2023
3b60c1f
Whitespace
vivianyyd Jul 20, 2023
a0edae2
Add test
vivianyyd Jul 20, 2023
9051a44
Comment on documentation
vivianyyd Jul 20, 2023
01e5122
Whitespace
vivianyyd Jul 20, 2023
199d898
more whitespace
vivianyyd Jul 20, 2023
3973ba0
Amend test to use Position
vivianyyd Jul 21, 2023
b9f893f
Correctly print [%src_pos] rather than lexing_position and fix corres…
vivianyyd Jul 21, 2023
5572374
Merge branch 'src_pos-in-fn-decls-and-defns' of https://github.com/vi…
vivianyyd Jul 21, 2023
ce0541f
Store hard-coded string in variable
vivianyyd Jul 24, 2023
318c9da
Hacky outcometree printing without creating nontrivial node
vivianyyd Jul 24, 2023
3136a38
Update documentation for Position labels
vivianyyd Jul 24, 2023
77ccf4f
Update tests
vivianyyd Jul 24, 2023
6cf29f7
Fix erroneously printing lexing_position for Position arguments
vivianyyd Jul 24, 2023
320a06b
Clean up code
vivianyyd Jul 24, 2023
5ad8a08
Reconstruct constraint for Position arguments in Untypeast
vivianyyd Jul 24, 2023
74812a7
Update tests
vivianyyd Jul 24, 2023
23a501d
Move comments around
vivianyyd Jul 24, 2023
b9f37b1
Slightly prettify
vivianyyd Jul 24, 2023
d008587
Use Location.none in Untypeast reconstructed extensions
vivianyyd Jul 25, 2023
41ce411
Add Ttyp_src_pos to Typedtree
vivianyyd Jul 25, 2023
222b7fc
Add CR
vivianyyd Jul 25, 2023
50ebc32
Comments
vivianyyd Jul 26, 2023
69ee34f
Clean up code
vivianyyd Jul 26, 2023
8143a0d
Update comment in printtyp.ml
vivianyyd Jul 26, 2023
23d4b7c
Add documentation for Ttyp_src_pos, remove extraneous comments
vivianyyd Jul 26, 2023
a68e240
*synonyms.ml
vivianyyd Jul 26, 2023
56e9a2f
src_pos in fn decls and defns
vivianyyd Jul 20, 2023
9dddc8b
Revert is_optional modifications for now
vivianyyd Jul 20, 2023
b7f7f45
src_pos shouldn't work in arbitrary places
vivianyyd Jul 20, 2023
d5750ce
Tidy code
vivianyyd Jul 20, 2023
6b29f40
Whitespace
vivianyyd Jul 20, 2023
606141d
Add test
vivianyyd Jul 20, 2023
1016785
Comment on documentation
vivianyyd Jul 20, 2023
0df7cab
Whitespace
vivianyyd Jul 20, 2023
5400e49
Correctly print [%src_pos] rather than lexing_position and fix corres…
vivianyyd Jul 21, 2023
3a192ca
Store hard-coded string in variable
vivianyyd Jul 24, 2023
99db743
Hacky outcometree printing without creating nontrivial node
vivianyyd Jul 24, 2023
e17cb00
Update documentation for Position labels
vivianyyd Jul 24, 2023
e33371d
Update tests
vivianyyd Jul 24, 2023
edb3d61
Fix erroneously printing lexing_position for Position arguments
vivianyyd Jul 24, 2023
98c6db4
Clean up code
vivianyyd Jul 24, 2023
3af543e
Reconstruct constraint for Position arguments in Untypeast
vivianyyd Jul 24, 2023
c05055f
Update tests
vivianyyd Jul 24, 2023
924b01e
Move comments around
vivianyyd Jul 24, 2023
1068c30
Slightly prettify
vivianyyd Jul 24, 2023
b51d977
Use Location.none in Untypeast reconstructed extensions
vivianyyd Jul 25, 2023
252281f
Add Ttyp_src_pos to Typedtree
vivianyyd Jul 25, 2023
3a4db9b
Add CR
vivianyyd Jul 25, 2023
0191678
Comments
vivianyyd Jul 26, 2023
8e062cf
Clean up code
vivianyyd Jul 26, 2023
e0b0eb9
Add documentation for Ttyp_src_pos, remove extraneous comments
vivianyyd Jul 26, 2023
5ab340e
*synonyms.ml
vivianyyd Jul 26, 2023
ef4a66e
Merge branch 'src_pos-in-fn-decls-and-defns' of https://github.com/vi…
vivianyyd Jul 26, 2023
1930706
Merge cleanup
vivianyyd Jul 27, 2023
0f6478b
Add label to Octy_arrow
vivianyyd Jul 27, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions ocaml/parsing/parsetree.mli
Original file line number Diff line number Diff line change
Expand Up @@ -170,8 +170,8 @@ and core_type_desc =

and arg_label = Asttypes.arg_label =
Nolabel
| Labelled of string (** [label:T -> ...] *)
| Optional of string (** [?label:T -> ...] *)
| Labelled of string
| Optional of string

and package_type = Longident.t loc * (Longident.t loc * core_type) list
(** As {!package_type} typed values:
Expand Down Expand Up @@ -338,6 +338,9 @@ and expression_desc =
{{!expression_desc.Pexp_fun}[Pexp_fun]}.
- [let f P = E] is represented using
{{!expression_desc.Pexp_fun}[Pexp_fun]}.
- While Position arguments are parsed as
{{!Asttypes.arg_label.Labelled}[Labelled l]}, they are converted to
{{!Asttypes.arg_label.Position}[Position l]} arguments for type-checking.
*)
| Pexp_apply of expression * (arg_label * expression) list
(** [Pexp_apply(E0, [(l1, E1) ; ... ; (ln, En)])]
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
(* TEST
* expect
*)

type t = src_pos:[%src_pos] -> unit -> unit

[%%expect {|
type t = src_pos:[%src_pos] -> unit -> unit
|}]

let f : t = fun ~(src_pos:[%src_pos]) () -> ()

[%%expect{|
val f : t = <fun>
|}]

let g ~(src_pos:[%src_pos]) () = ()

[%%expect{|
val g : src_pos:[%src_pos] -> unit -> unit = <fun>
|}]

let apply (f : t) = f ~src_pos:Lexing.dummy_pos () ;;
[%%expect {|
val apply : t -> unit = <fun>
|}]

let _ = apply f ;;
[%%expect{|
- : unit = ()
|}]

let _ = apply g ;;
[%%expect{|
- : unit = ()
|}]
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
(* TEST
* expect
*)

type t = [%src_pos]
[%%expect {|
Line 1, characters 11-18:
1 | type t = [%src_pos]
^^^^^^^
Error: Uninterpreted extension 'src_pos'.
|}]
(* CR src_pos: Improve this error message to notify that [%src_pos] may only
be used in arguments *)

type t = unit -> unit -> [%src_pos]
[%%expect {|
Line 1, characters 27-34:
1 | type t = unit -> unit -> [%src_pos]
^^^^^^^
Error: Uninterpreted extension 'src_pos'.
|}]

let f ~(src_pos:[%src_pos]) () : [%src_pos] = src_pos

[%%expect{|
Line 1, characters 35-42:
1 | let f ~(src_pos:[%src_pos]) () : [%src_pos] = src_pos
^^^^^^^
Error: Uninterpreted extension 'src_pos'.
|}]

let apply f = f ~src_pos:Lexing.dummy_pos () ;;
[%%expect {|
val apply : (src_pos:Lexing.position -> unit -> 'a) -> 'a = <fun>
|}]

let g = fun ~(src_pos:[%src_pos]) () -> ()

[%%expect{|
val g : src_pos:[%src_pos] -> unit -> unit = <fun>
|}]

let _ = apply g ;;
[%%expect{|
Line 1, characters 14-15:
1 | let _ = apply g ;;
^
Error: This expression has type src_pos:[%src_pos] -> unit -> unit
but an expression was expected of type
src_pos:Lexing.position -> unit -> 'a
|}]

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -10,18 +10,18 @@ type lexing_position = int
|}]

(* src_pos works *)
let f ~(src_pos:[%src_pos]) = ();;
let f ~(src_pos:[%src_pos]) () = ();;
[%%expect{|
val f : src_pos:lexing_position/2 -> unit = <fun>
val f : src_pos:[%src_pos] -> unit -> unit = <fun>
|}]

let _ = f ~src_pos:{pos_fname="hello" ; pos_lnum=1; pos_bol=2; pos_cnum=3} ;;
let _ = f ~src_pos:Lexing.dummy_pos () ;;
[%%expect{|
- : unit = ()
|}]

(* new type works *)
let h (x:lexing_position) = x ;;
let h (x : lexing_position) = x ;;
[%%expect{|
val h : lexing_position -> lexing_position = <fun>
|}]
Expand Down
28 changes: 20 additions & 8 deletions ocaml/testsuite/tests/typing-implicit-source-positions/synonyms.ml
Original file line number Diff line number Diff line change
Expand Up @@ -2,27 +2,39 @@
* expect
*)

(* src_pos (lexing_position) and Lexing.position are synonyms *)
let predef_to_module ~(src_pos:[%src_pos]) : Lexing.position = src_pos ;;
(* lexing_position and Lexing.position are synonyms *)
let x = Lexing.dummy_pos;;
[%%expect {|
val x : Lexing.position =
{Lexing.pos_fname = ""; pos_lnum = 0; pos_bol = 0; pos_cnum = -1}
|}]

let y : lexing_position = x;;
[%%expect {|
val y : lexing_position =
{pos_fname = ""; pos_lnum = 0; pos_bol = 0; pos_cnum = -1}
|}]

let predef_to_module ~(src_pos:[%src_pos]) () : Lexing.position = src_pos ;;
[%%expect{|
val predef_to_module : src_pos:lexing_position -> Lexing.position = <fun>
val predef_to_module : src_pos:[%src_pos] -> unit -> Lexing.position = <fun>
|}]

let module_to_predef (src_pos:Lexing.position) : [%src_pos] = src_pos ;;
let module_to_predef (src_pos:Lexing.position) : lexing_position = src_pos ;;
[%%expect{|
val module_to_predef : Lexing.position -> lexing_position = <fun>
|}]

let x = predef_to_module ~src_pos:{pos_fname="hello" ; pos_lnum=1; pos_bol=2; pos_cnum=3};;
let x = predef_to_module ~src_pos:Lexing.dummy_pos ();;
[%%expect{|
val x : Lexing.position =
{Lexing.pos_fname = "hello"; pos_lnum = 1; pos_bol = 2; pos_cnum = 3}
{Lexing.pos_fname = ""; pos_lnum = 0; pos_bol = 0; pos_cnum = -1}
|}]

let y = module_to_predef {pos_fname="hello" ; pos_lnum=1; pos_bol=2; pos_cnum=3};;
let y = module_to_predef Lexing.dummy_pos;;
[%%expect{|
val y : lexing_position =
{pos_fname = "hello"; pos_lnum = 1; pos_bol = 2; pos_cnum = 3}
{pos_fname = ""; pos_lnum = 0; pos_bol = 0; pos_cnum = -1}
|}]

(* Fields accessible from within Lexing module *)
Expand Down
12 changes: 10 additions & 2 deletions ocaml/typing/btype.ml
Original file line number Diff line number Diff line change
Expand Up @@ -579,14 +579,22 @@ let is_optional_parsetree : Parsetree.arg_label -> bool = function

let is_optional = function Optional _ -> true | _ -> false

let is_position = function Position _ -> true | _ -> false

let is_omittable = function
Optional _
| Position _ -> true
| Nolabel | Labelled _ -> false

let label_name = function
Nolabel -> ""
| Labelled s
| Optional s -> s
| Optional s
| Position s -> s

let prefixed_label_name = function
Nolabel -> ""
| Labelled s -> "~" ^ s
| Labelled s | Position s -> "~" ^ s
| Optional s -> "?" ^ s

let rec extract_label_aux hd l = function
Expand Down
2 changes: 2 additions & 0 deletions ocaml/typing/btype.mli
Original file line number Diff line number Diff line change
Expand Up @@ -253,6 +253,8 @@ val backtrack: snapshot -> unit

val is_optional_parsetree : Parsetree.arg_label -> bool
val is_optional : arg_label -> bool
val is_position : arg_label -> bool
val is_omittable : arg_label -> bool
val label_name : arg_label -> label

(* Returns the label name with first character '?' or '~' as appropriate. *)
Expand Down
2 changes: 2 additions & 0 deletions ocaml/typing/ctype.ml
Original file line number Diff line number Diff line change
Expand Up @@ -3811,6 +3811,8 @@ let filter_arrow env t l ~force_tpoly =
(Tconstr(Predef.path_option,
[newvar2 level (Layout.value ~why:Type_argument)],
ref Mnil))
else if is_position l then
newty2 ~level (Tconstr (Predef.path_lexing_position, [], ref Mnil))
else
newvar2 level l_arg
in
Expand Down
26 changes: 20 additions & 6 deletions ocaml/typing/oprint.ml
Original file line number Diff line number Diff line change
Expand Up @@ -305,11 +305,16 @@ and print_out_type_1 mode ppf =
function
| Otyp_arrow (lab, am, ty1, rm, ty2) ->
pp_open_box ppf 0;
let print_type () = print_out_arg am ppf ty1 in
(match lab with
| Nolabel -> ()
| Labelled l -> pp_print_string ppf l; pp_print_char ppf ':'
| Optional l -> pp_print_string ppf ("?"^l); pp_print_char ppf ':');
print_out_arg am ppf ty1;
| Nolabel -> print_type ()
| Labelled l ->
pp_print_string ppf l; pp_print_char ppf ':'; print_type ()
| Position l ->
pp_print_string ppf l;
pp_print_string ppf ":[%src_pos]"
| Optional l ->
pp_print_string ppf ("?" ^ l); pp_print_char ppf ':'; print_type ());
pp_print_string ppf " ->";
pp_print_space ppf ();
let mode = join_modes mode am in
Expand Down Expand Up @@ -515,8 +520,17 @@ let rec print_out_class_type ppf =
in
fprintf ppf "@[%a%a@]" pr_tyl tyl print_ident id
| Octy_arrow (lab, ty, cty) ->
fprintf ppf "@[%s%a ->@ %a@]" (if lab <> "" then lab ^ ":" else "")
(print_out_type_2 Oam_global) ty print_out_class_type cty
let print_type = print_out_type_2 Oam_global in
let label, print_type = match lab with
| Nolabel -> "", print_type
| Labelled l -> l ^ ":", print_type
| Position l -> l ^ ":", fun ppf _ -> pp_print_string ppf "[%src_pos]"
| Optional l -> "?" ^ l ^ ":", print_type
in
fprintf ppf "@[%s%a ->@ %a@]"
label
print_type ty
print_out_class_type cty
| Octy_signature (self_ty, csil) ->
let pr_param ppf =
function
Expand Down
7 changes: 4 additions & 3 deletions ocaml/typing/outcometree.mli
Original file line number Diff line number Diff line change
Expand Up @@ -78,8 +78,9 @@ type out_global =
(** This definition avoids a cyclic dependency between Outcometree and Types. *)
type arg_label =
| Nolabel
| Labelled of string (** [label:T -> ...] *)
| Optional of string (*** [?label:T -> ...] *)
| Labelled of string
| Optional of string
| Position of string

type out_type =
| Otyp_abstract
Expand Down Expand Up @@ -121,7 +122,7 @@ and out_alloc_mode =

type out_class_type =
| Octy_constr of out_ident * out_type list
| Octy_arrow of string * out_type * out_class_type
| Octy_arrow of arg_label * out_type * out_class_type
| Octy_signature of out_type option * out_class_sig_item list
and out_class_sig_item =
| Ocsg_constraint of out_type * out_type
Expand Down
25 changes: 14 additions & 11 deletions ocaml/typing/printtyp.ml
Original file line number Diff line number Diff line change
Expand Up @@ -508,10 +508,10 @@ let print_name ppf = function
None -> fprintf ppf "None"
| Some name -> fprintf ppf "\"%s\"" name

let string_of_label = function
Asttypes.Nolabel -> ""
| Asttypes.Labelled s -> s
| Asttypes.Optional s -> "?"^s
let string_of_label : Types.arg_label -> string = function
Nolabel -> ""
| Labelled s | Position s -> s
| Optional s -> "?"^s

let visited = ref []
let rec raw_type ppf ty =
Expand Down Expand Up @@ -1098,7 +1098,13 @@ let add_type_to_preparation = prepare_type
(* Disabled in classic mode when printing an unification error *)
let print_labels = ref true

let rec tree_of_typexp mode ty =
let transl_label : Types.arg_label -> Outcometree.arg_label = function
| Nolabel -> Nolabel
| Labelled l -> Labelled l
| Optional l -> Optional l
| Position l -> Position l

let rec tree_of_typexp mode ty =
let px = proxy ty in
if List.memq px !printed_aliases && not (List.memq px !delayed) then
let mark = is_non_gen mode ty in
Expand All @@ -1117,11 +1123,7 @@ let rec tree_of_typexp mode ty =
Otyp_var (non_gen, Names.name_of_type name_gen tty)
| Tarrow ((l, marg, mret), ty1, ty2, _) ->
let lab =
if !print_labels || is_optional l then
match l with
| Nolabel -> Nolabel
| Labelled l -> Labelled l
| Optional l -> Optional l
if !print_labels || is_optional l then transl_label l
else Nolabel
in
let t1 =
Expand Down Expand Up @@ -1761,7 +1763,8 @@ let rec tree_of_class_type mode params =
Octy_signature (self_ty, List.rev csil)
| Cty_arrow (l, ty, cty) ->
let lab =
if !print_labels || is_optional l then string_of_label l else ""
if !print_labels || is_optional l then transl_label l
else Nolabel
in
let tr =
if is_optional l then
Expand Down
2 changes: 2 additions & 0 deletions ocaml/typing/printtyped.ml
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,7 @@ let arg_label i ppf = function
| Nolabel -> line i ppf "Nolabel\n"
| Optional s -> line i ppf "Optional \"%s\"\n" s
| Labelled s -> line i ppf "Labelled \"%s\"\n" s
| Position s -> line i ppf "Position \"%s\"\n" s
;;

let typevars ppf vs =
Expand Down Expand Up @@ -244,6 +245,7 @@ let rec core_type i ppf x =
| Ttyp_package { pack_path = s; pack_fields = l } ->
line i ppf "Ttyp_package %a\n" fmt_path s;
list i package_with ppf l;
| Ttyp_src_pos -> line i ppf "Ttyp_src_pos\n";

and package_with i ppf (s, t) =
line i ppf "with type %a\n" fmt_longident s;
Expand Down
1 change: 1 addition & 0 deletions ocaml/typing/tast_iterator.ml
Original file line number Diff line number Diff line change
Expand Up @@ -470,6 +470,7 @@ let typ sub {ctyp_desc; ctyp_env; _} =
| Ttyp_variant (list, _, _) -> List.iter (sub.row_field sub) list
| Ttyp_poly (_, ct) -> sub.typ sub ct
| Ttyp_package pack -> sub.package_type sub pack
| Ttyp_src_pos -> ()

let class_structure sub {cstr_self; cstr_fields; _} =
sub.pat sub cstr_self;
Expand Down
Loading