-
Notifications
You must be signed in to change notification settings - Fork 1.1k
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
Signature local bindings #2122
Signature local bindings #2122
Conversation
Also: the code to remove these local bindings calls @lpw25 just voiced (offline) that he'd rather not use |
IMO, that would be better. |
Did you consider introducing new constructors in the AST (Parsetree and Typedtree) instead of adding a component to a tuple? That would reduce the impact on e.g. ppx rewriting, and should not make the code really more complex. Also, at the Typedtree level, you could use a more precise representation than the generic one (just a type expression, not a type declaration). |
I had a first implementation doing just that, but the churn was actually much bigger and I eventually gave up on it. As for allowing the forbidden construction to parse and reject them later: I'll make the change; but I'd like to revisit that once we get menhir to generate nice syntax error messages. |
Even with good support for error messages, LR messages will detect a situation of the sort So you can reasonably hope to get "we were expecting a type (expression) here", but not "you are trying to write a type declaration, but only type synonyms are accepted", I think. |
a8889c2
to
fdc51ef
Compare
I'm not sure we'll have the control, as for the courage: we have it right now to produce it from a different part of the compiler, so I don't think it would make much difference. I updated the code to emit a proper error message from typemod (doing it in |
12d72ea
to
0db1c35
Compare
I pushed two new commits:
|
OK I now also introduced a new constructor for type substitutions.
Which was very painful. I'm currently not doing that, I still use a type declaration but that's precisely what destructive substitution uses. This should now be ready for review: the history is a bit less clean than I'd have hoped, but the whole diff should be easy to read. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There's a few things that need fixing, but other than those this looks good to merge.
parsing/parsetree.mli
Outdated
and module_substitution = | ||
{ | ||
pms_name: string loc; | ||
pms_synonym: Longident.t loc; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe pms_manifest
to match the type declaration case?
parsing/parsetree.mli
Outdated
@@ -719,13 +719,18 @@ and signature_item_desc = | |||
external x: T = "s1" ... "sn" | |||
*) | |||
| Psig_type of rec_flag * type_declaration list | |||
(* type t1 = ... and ... and tn = ... *) | |||
(* type t1 = ... and ... and tn = ... *) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Accidental change to whitespace.
parsing/parsetree.mli
Outdated
@@ -719,13 +719,18 @@ and signature_item_desc = | |||
external x: T = "s1" ... "sn" | |||
*) | |||
| Psig_type of rec_flag * type_declaration list | |||
(* type t1 = ... and ... and tn = ... *) | |||
(* type t1 = ... and ... and tn = ... *) | |||
| Psig_typesubst of rec_flag * type_declaration list |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This rec_flag
should be removed because substitutions should all be "nonrec".
ocamldoc/odoc_sig.ml
Outdated
@@ -904,7 +908,8 @@ module Analyser = | |||
let new_env = Odoc_env.add_extension env e.ex_name in | |||
(maybe_more, new_env, [ Element_exception e ]) | |||
|
|||
| Parsetree.Psig_type (rf, name_type_decl_list) -> | |||
| Parsetree.Psig_type (rf, name_type_decl_list) | |||
| Parsetree.Psig_typesubst (rf, name_type_decl_list) (* FIXME *) -> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe we can do better here. Perhaps @Octachron would like to think about how we want to display these in OCamldoc's output.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I will try to have a look.
typing/typemod.ml
Outdated
user_kind: Sig_component_kind.t; | ||
user_loc: Location.t; | ||
} | ||
type hidding_error = |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Misspelling
typing/typemod.ml
Outdated
@@ -92,6 +93,7 @@ type error = | |||
| Cannot_scrape_alias of Path.t | |||
| Badly_formed_signature of string * Typedecl.error | |||
| Cannot_hide_id of hidding_error | |||
| Invalid_subst_rhs of [ `Module | `Type ] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No real need for a polymorphic variant here.
Line 3, characters 15-18: | ||
3 | module M1 := sig end | ||
^^^ | ||
Error: Syntax error: 'end' expected |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think you need an error production in the parser to give this a better error message
^^^^ | ||
Error: Unbound module N | ||
|}] | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I suggest adding tests for type ... and
and potentially recursive substitutions somewhere in this file.
typing/typemod.ml
Outdated
Typedecl.transl_type_decl env rec_flag sdecls | ||
in | ||
List.iter (fun td -> | ||
if td.typ_kind <> Ttype_abstract || td.typ_manifest = None |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What about private?
`Substituted_away (Subst.add_module id path Subst.identity) | ||
in | ||
Signature_names.check_module ~info names pms.pms_name.loc id; | ||
let newenv = Env.enter_module_declaration id md env in |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should sometimes be an alias.
093143e
to
4f3638f
Compare
OK I pushed a few more commits addressing @lpw25's comments (there should be one commit per review comment). |
type [params] id := type_expr { and [params] id := type_expr } module Uid := extended-module-path
ceb5802
to
912b841
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this is ready to merge now.
This is the revamped version of #2016: it allows some type and module aliases to be bound in a signature without being exported.
The chosen syntax is the one that @garrigue proposed, which is reminiscent of destructive substitution:
A few things to note:
type t := { x : int }
the error message will be pretty bad.I could allow it in the parser and reject it later, e.g. from
Ast_invariants
, with a decent error message. But I'm hopeful that we could get good syntax error messages soon. Am I too optimistic?