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

Allow explicit binders for type variables #10437

Merged
merged 7 commits into from
Jun 30, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 2 additions & 0 deletions .depend
Original file line number Diff line number Diff line change
Expand Up @@ -1109,6 +1109,7 @@ typing/printtyped.cmo : \
typing/types.cmi \
typing/typedtree.cmi \
parsing/printast.cmi \
parsing/pprintast.cmi \
typing/path.cmi \
parsing/parsetree.cmi \
parsing/longident.cmi \
Expand All @@ -1121,6 +1122,7 @@ typing/printtyped.cmx : \
typing/types.cmx \
typing/typedtree.cmx \
parsing/printast.cmx \
parsing/pprintast.cmx \
typing/path.cmx \
parsing/parsetree.cmi \
parsing/longident.cmx \
Expand Down
3 changes: 3 additions & 0 deletions Changes
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@ Working version
----------------
### Language features:

- #10437: Allow explicit binders for type variables.
(Stephen Dolan, review by Leo White)

### Runtime system:

### Code generation and optimizations:
Expand Down
6,797 changes: 3,479 additions & 3,318 deletions boot/menhir/parser.ml

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions ocamldoc/odoc_ast.ml
Original file line number Diff line number Diff line change
Expand Up @@ -1294,7 +1294,7 @@ module Analyser =
let ext_loc_end = tt_ext.ext_loc.Location.loc_end.Lexing.pos_cnum in
let new_xt =
match tt_ext.ext_kind with
Text_decl(args, ret_type) ->
Text_decl(_, args, ret_type) ->
let xt_args =
Sig.get_cstr_args new_env ext_loc_end args in
{
Expand Down Expand Up @@ -1350,7 +1350,7 @@ module Analyser =
let new_env = Odoc_env.add_extension env complete_name in
let new_ext =
match tt_ext.Typedtree.tyexn_constructor.ext_kind with
Text_decl(tt_args, tt_ret_type) ->
Text_decl(_, tt_args, tt_ret_type) ->
let loc_start = loc.Location.loc_start.Lexing.pos_cnum in
let loc_end = loc.Location.loc_end.Lexing.pos_cnum in
let ex_args =
Expand Down
7 changes: 4 additions & 3 deletions parsing/ast_helper.ml
Original file line number Diff line number Diff line change
Expand Up @@ -529,9 +529,10 @@ module Type = struct
}

let constructor ?(loc = !default_loc) ?(attrs = []) ?(info = empty_info)
?(args = Pcstr_tuple []) ?res name =
?(vars = []) ?(args = Pcstr_tuple []) ?res name =
{
pcd_name = name;
pcd_vars = vars;
pcd_args = args;
pcd_res = res;
pcd_loc = loc;
Expand Down Expand Up @@ -581,10 +582,10 @@ module Te = struct
}

let decl ?(loc = !default_loc) ?(attrs = []) ?(docs = empty_docs)
?(info = empty_info) ?(args = Pcstr_tuple []) ?res name =
?(info = empty_info) ?(vars = []) ?(args = Pcstr_tuple []) ?res name =
{
pext_name = name;
pext_kind = Pext_decl(args, res);
pext_kind = Pext_decl(vars, args, res);
pext_loc = loc;
pext_attributes = add_docs_attrs docs (add_info_attrs info attrs);
}
Expand Down
6 changes: 4 additions & 2 deletions parsing/ast_helper.mli
Original file line number Diff line number Diff line change
Expand Up @@ -211,7 +211,8 @@ module Type:
type_declaration

val constructor: ?loc:loc -> ?attrs:attrs -> ?info:info ->
?args:constructor_arguments -> ?res:core_type -> str ->
?vars:str list -> ?args:constructor_arguments -> ?res:core_type ->
str ->
constructor_declaration
val field: ?loc:loc -> ?attrs:attrs -> ?info:info ->
?mut:mutable_flag -> str -> core_type -> label_declaration
Expand All @@ -231,7 +232,8 @@ module Te:
str -> extension_constructor_kind -> extension_constructor

val decl: ?loc:loc -> ?attrs:attrs -> ?docs:docs -> ?info:info ->
?args:constructor_arguments -> ?res:core_type -> str ->
?vars:str list -> ?args:constructor_arguments -> ?res:core_type ->
str ->
extension_constructor
val rebind: ?loc:loc -> ?attrs:attrs -> ?docs:docs -> ?info:info ->
str -> lid -> extension_constructor
Expand Down
10 changes: 7 additions & 3 deletions parsing/ast_iterator.ml
Original file line number Diff line number Diff line change
Expand Up @@ -182,8 +182,10 @@ module T = struct
sub.attributes sub ptyexn_attributes

let iter_extension_constructor_kind sub = function
Pext_decl(ctl, cto) ->
iter_constructor_arguments sub ctl; iter_opt (sub.typ sub) cto
Pext_decl(vars, ctl, cto) ->
List.iter (iter_loc sub) vars;
iter_constructor_arguments sub ctl;
iter_opt (sub.typ sub) cto
| Pext_rebind li ->
iter_loc sub li

Expand Down Expand Up @@ -639,8 +641,10 @@ let default_iterator =


constructor_declaration =
(fun this {pcd_name; pcd_args; pcd_res; pcd_loc; pcd_attributes} ->
(fun this {pcd_name; pcd_vars; pcd_args;
pcd_res; pcd_loc; pcd_attributes} ->
iter_loc this pcd_name;
List.iter (iter_loc this) pcd_vars;
T.iter_constructor_arguments this pcd_args;
iter_opt (this.typ this) pcd_res;
this.location this pcd_loc;
Expand Down
10 changes: 7 additions & 3 deletions parsing/ast_mapper.ml
Original file line number Diff line number Diff line change
Expand Up @@ -206,8 +206,10 @@ module T = struct
(sub.extension_constructor sub ptyexn_constructor)

let map_extension_constructor_kind sub = function
Pext_decl(ctl, cto) ->
Pext_decl(map_constructor_arguments sub ctl, map_opt (sub.typ sub) cto)
Pext_decl(vars, ctl, cto) ->
Pext_decl(List.map (map_loc sub) vars,
map_constructor_arguments sub ctl,
map_opt (sub.typ sub) cto)
| Pext_rebind li ->
Pext_rebind (map_loc sub li)

Expand Down Expand Up @@ -698,9 +700,11 @@ let default_mapper =


constructor_declaration =
(fun this {pcd_name; pcd_args; pcd_res; pcd_loc; pcd_attributes} ->
(fun this {pcd_name; pcd_vars; pcd_args;
pcd_res; pcd_loc; pcd_attributes} ->
Type.constructor
(map_loc this pcd_name)
~vars:(List.map (map_loc this) pcd_vars)
~args:(T.map_constructor_arguments this pcd_args)
?res:(map_opt (this.typ this) pcd_res)
~loc:(this.location this pcd_loc)
Expand Down
2 changes: 1 addition & 1 deletion parsing/depend.ml
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ let add_type_declaration bv td =

let add_extension_constructor bv ext =
match ext.pext_kind with
Pext_decl(args, rty) ->
Pext_decl(_, args, rty) ->
add_constructor_arguments bv args;
Option.iter (add_type bv) rty
| Pext_rebind lid -> add bv lid
Expand Down
53 changes: 27 additions & 26 deletions parsing/parser.mly
Original file line number Diff line number Diff line change
Expand Up @@ -2499,15 +2499,11 @@ let_binding_body_no_punning:
let patloc = ($startpos($1), $endpos($2)) in
(ghpat ~loc:patloc (Ppat_constraint(v, typ)),
mkexp_constraint ~loc:$sloc $4 $2) }
| let_ident COLON typevar_list DOT core_type EQUAL seq_expr
(* TODO: could replace [typevar_list DOT core_type]
with [mktyp(poly(core_type))]
and simplify the semantic action? *)
{ let typloc = ($startpos($3), $endpos($5)) in
let patloc = ($startpos($1), $endpos($5)) in
| let_ident COLON poly(core_type) EQUAL seq_expr
{ let patloc = ($startpos($1), $endpos($3)) in
(ghpat ~loc:patloc
(Ppat_constraint($1, ghtyp ~loc:typloc (Ptyp_poly($3,$5)))),
$7) }
(Ppat_constraint($1, ghtyp ~loc:($loc($3)) $3)),
$5) }
| let_ident COLON TYPE lident_list DOT core_type EQUAL seq_expr
{ let exp, poly =
wrap_type_annotation ~loc:$sloc $4 $6 $8 in
Expand Down Expand Up @@ -2870,7 +2866,7 @@ value_description:
attrs1 = attributes
id = mkrhs(val_ident)
COLON
ty = core_type
ty = possibly_poly(core_type)
attrs2 = post_item_attributes
{ let attrs = attrs1 @ attrs2 in
let loc = make_loc $sloc in
Expand All @@ -2887,7 +2883,7 @@ primitive_declaration:
attrs1 = attributes
id = mkrhs(val_ident)
COLON
ty = core_type
ty = possibly_poly(core_type)
EQUAL
prim = raw_string+
attrs2 = post_item_attributes
Expand Down Expand Up @@ -3065,20 +3061,20 @@ constructor_declarations:
generic_constructor_declaration(opening):
opening
cid = mkrhs(constr_ident)
args_res = generalized_constructor_arguments
vars_args_res = generalized_constructor_arguments
attrs = attributes
{
let args, res = args_res in
let vars, args, res = vars_args_res in
let info = symbol_info $endpos in
let loc = make_loc $sloc in
cid, args, res, attrs, loc, info
cid, vars, args, res, attrs, loc, info
}
;
%inline constructor_declaration(opening):
d = generic_constructor_declaration(opening)
{
let cid, args, res, attrs, loc, info = d in
Type.constructor cid ~args ?res ~attrs ~loc ~info
let cid, vars, args, res, attrs, loc, info = d in
Type.constructor cid ~vars ~args ?res ~attrs ~loc ~info
}
;
str_exception_declaration:
Expand All @@ -3103,28 +3099,33 @@ sig_exception_declaration:
ext = ext
attrs1 = attributes
id = mkrhs(constr_ident)
args_res = generalized_constructor_arguments
vars_args_res = generalized_constructor_arguments
attrs2 = attributes
attrs = post_item_attributes
{ let args, res = args_res in
{ let vars, args, res = vars_args_res in
let loc = make_loc ($startpos, $endpos(attrs2)) in
let docs = symbol_docs $sloc in
Te.mk_exception ~attrs
(Te.decl id ~args ?res ~attrs:(attrs1 @ attrs2) ~loc ~docs)
(Te.decl id ~vars ~args ?res ~attrs:(attrs1 @ attrs2) ~loc ~docs)
, ext }
;
%inline let_exception_declaration:
mkrhs(constr_ident) generalized_constructor_arguments attributes
{ let args, res = $2 in
Te.decl $1 ~args ?res ~attrs:$3 ~loc:(make_loc $sloc) }
{ let vars, args, res = $2 in
Te.decl $1 ~vars ~args ?res ~attrs:$3 ~loc:(make_loc $sloc) }
;
generalized_constructor_arguments:
/*empty*/ { (Pcstr_tuple [],None) }
| OF constructor_arguments { ($2,None) }
/*empty*/ { ([],Pcstr_tuple [],None) }
| OF constructor_arguments { ([],$2,None) }
| COLON constructor_arguments MINUSGREATER atomic_type %prec below_HASH
{ ($2,Some $4) }
{ ([],$2,Some $4) }
| COLON typevar_list DOT constructor_arguments MINUSGREATER atomic_type
%prec below_HASH
{ ($2,$4,Some $6) }
| COLON atomic_type %prec below_HASH
{ (Pcstr_tuple [],Some $2) }
{ ([],Pcstr_tuple [],Some $2) }
| COLON typevar_list DOT atomic_type %prec below_HASH
{ ($2,Pcstr_tuple [],Some $4) }
;

constructor_arguments:
Expand Down Expand Up @@ -3189,8 +3190,8 @@ label_declaration_semi:
%inline extension_constructor_declaration(opening):
d = generic_constructor_declaration(opening)
{
let cid, args, res, attrs, loc, info = d in
Te.decl cid ~args ?res ~attrs ~loc ~info
let cid, vars, args, res, attrs, loc, info = d in
Te.decl cid ~vars ~args ?res ~attrs ~loc ~info
}
;
extension_constructor_rebind(opening):
Expand Down
12 changes: 8 additions & 4 deletions parsing/parsetree.mli
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,8 @@ and core_type_desc =
- As the pld_type field of a label_declaration.

- As a core_type of a Ptyp_object node.

- As the pval_type field of a value_description.
*)

| Ptyp_package of package_type
Expand Down Expand Up @@ -477,6 +479,7 @@ and label_declaration =
and constructor_declaration =
{
pcd_name: string loc;
pcd_vars: string loc list;
pcd_args: constructor_arguments;
pcd_res: core_type option;
pcd_loc: Location.t;
Expand Down Expand Up @@ -526,11 +529,12 @@ and type_exception =
}

and extension_constructor_kind =
Pext_decl of constructor_arguments * core_type option
Pext_decl of string loc list * constructor_arguments * core_type option
(*
| C of T1 * ... * Tn ([T1; ...; Tn], None)
| C: T0 ([], Some T0)
| C: T1 * ... * Tn -> T0 ([T1; ...; Tn], Some T0)
| C of T1 * ... * Tn ([], [T1; ...; Tn], None)
| C: T0 ([], [], Some T0)
| C: T1 * ... * Tn -> T0 ([], [T1; ...; Tn], Some T0)
| C: 'a... . T1... -> T0 (['a;...]; [T1;...], Some T0)
*)
| Pext_rebind of Longident.t loc
(*
Expand Down
17 changes: 12 additions & 5 deletions parsing/pprintast.ml
Original file line number Diff line number Diff line change
Expand Up @@ -1544,7 +1544,8 @@ and type_declaration ctxt f x =
let constructor_declaration f pcd =
pp f "|@;";
constructor_declaration ctxt f
(pcd.pcd_name.txt, pcd.pcd_args, pcd.pcd_res, pcd.pcd_attributes)
(pcd.pcd_name.txt, pcd.pcd_vars,
pcd.pcd_args, pcd.pcd_res, pcd.pcd_attributes)
in
let repr f =
let intro f =
Expand Down Expand Up @@ -1587,11 +1588,15 @@ and type_extension ctxt f x =
x.ptyext_constructors
(item_attributes ctxt) x.ptyext_attributes

and constructor_declaration ctxt f (name, args, res, attrs) =
and constructor_declaration ctxt f (name, vars, args, res, attrs) =
let name =
match name with
| "::" -> "(::)"
| s -> s in
let pp_vars f vs =
match vs with
| [] -> ()
| vs -> pp f "%a@;.@;" (list tyvar_loc ~sep:"@;") vs in
match res with
| None ->
pp f "%s%a@;%a" name
Expand All @@ -1603,7 +1608,8 @@ and constructor_declaration ctxt f (name, args, res, attrs) =
) args
(attributes ctxt) attrs
| Some r ->
pp f "%s:@;%a@;%a" name
pp f "%s:@;%a%a@;%a" name
pp_vars vars
(fun f -> function
| Pcstr_tuple [] -> core_type1 ctxt f r
| Pcstr_tuple l -> pp f "%a@;->@;%a"
Expand All @@ -1618,8 +1624,9 @@ and constructor_declaration ctxt f (name, args, res, attrs) =
and extension_constructor ctxt f x =
(* Cf: #7200 *)
match x.pext_kind with
| Pext_decl(l, r) ->
constructor_declaration ctxt f (x.pext_name.txt, l, r, x.pext_attributes)
| Pext_decl(v, l, r) ->
constructor_declaration ctxt f
(x.pext_name.txt, v, l, r, x.pext_attributes)
| Pext_rebind li ->
pp f "%s@;=@;%a%a" x.pext_name.txt
longident_loc li
Expand Down
15 changes: 8 additions & 7 deletions parsing/printast.ml
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,9 @@ let arg_label i ppf = function
| Labelled s -> line i ppf "Labelled \"%s\"\n" s
;;

let typevars ppf vs =
List.iter (fun x -> fprintf ppf " %a" Pprintast.tyvar x.txt) vs

let rec core_type i ppf x =
line i ppf "core_type %a\n" fmt_location x.ptyp_loc;
attributes i ppf x.ptyp_attributes;
Expand Down Expand Up @@ -189,11 +192,7 @@ let rec core_type i ppf x =
line i ppf "Ptyp_alias \"%s\"\n" s;
core_type i ppf ct;
| Ptyp_poly (sl, ct) ->
line i ppf "Ptyp_poly%a\n"
(fun ppf ->
List.iter (fun x -> fprintf ppf " %a" Pprintast.tyvar x.txt)
)
sl;
line i ppf "Ptyp_poly%a\n" typevars sl;
core_type i ppf ct;
| Ptyp_package (s, l) ->
line i ppf "Ptyp_package %a\n" fmt_longident_loc s;
Expand Down Expand Up @@ -489,8 +488,9 @@ and extension_constructor i ppf x =

and extension_constructor_kind i ppf x =
match x with
Pext_decl(a, r) ->
Pext_decl(v, a, r) ->
line i ppf "Pext_decl\n";
if v <> [] then line (i+1) ppf "vars%a\n" typevars v;
constructor_arguments (i+1) ppf a;
option (i+1) core_type ppf r;
| Pext_rebind li ->
Expand Down Expand Up @@ -887,9 +887,10 @@ and core_type_x_core_type_x_location i ppf (ct1, ct2, l) =
core_type (i+1) ppf ct2;

and constructor_decl i ppf
{pcd_name; pcd_args; pcd_res; pcd_loc; pcd_attributes} =
{pcd_name; pcd_vars; pcd_args; pcd_res; pcd_loc; pcd_attributes} =
line i ppf "%a\n" fmt_location pcd_loc;
line (i+1) ppf "%a\n" fmt_string_loc pcd_name;
if pcd_vars <> [] then line (i+1) ppf "pcd_vars =%a\n" typevars pcd_vars;
attributes i ppf pcd_attributes;
constructor_arguments (i+1) ppf pcd_args;
option (i+1) core_type ppf pcd_res
Expand Down