-
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
Functor error messages: signatures are not functors #12224
Conversation
This looks great.
I don't like the wording here. I use "signature" and "interface" as basically synonyms to mean "the type of a module or functor", so opposing "a signature" and "a functor" makes no sense to me:
The following wording may work: "The first one is the signature of a structure whereas the second one is the signature of a functor". (I tried first with "a structure signature ... a functor signature" and it read less clearly.) Another wording could be: "The first signature specifies a structure whereas the second signature specifies a functor". ('specifies' or 'classifies' or 'describes') |
Terminology police here! Sir, put your hands up and away from this PR! A signature is the type of a structure. (Notice the parallel between An acceptable wording would be "The first one is the type of a structure whereas the second one is the type of a functor". However "first one" and "second one" are not quite well defined (what is "one", here?) and should perhaps be "The former" and "the latter". Could also replace "is the type of" by something more pleasant to read, e.g. "denotes", "matches", "corresponds to" ? |
Maybe
? A potentially interesting and quick to implement proposal was to completely shortcut the main error message in this case.
since this avoid speaking of the subtyping relation when the two module kinds are incomparable. But this rejoin a later complaint that is really for people where the module type constraints come from. I will have a look (after my holidays) if we can track the location of both side of the subtyping to remove this issue. I will propose to split the two commit of this PR since the application error is both the more frequent error and the more consensual change. |
Personally I find "type of a structure", as suggested in Xavier's proposal, clearer in this context than "signature" (for the reason given earlier that my own improper terminology use "signature" as a synonym for the more general "type of a module", including possibly functors). |
a971346
to
2c402ed
Compare
I have split the inclusion and application part as discussed. |
typing/includemod_errorprinter.ml
Outdated
| None -> Format.fprintf ppf "This functor application is ill-typed." | ||
| Some (Longident.Lapply _ as lid) -> | ||
Format.fprintf ppf "The functor application %a is ill-typed." | ||
Printtyp.longident lid |
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 don't understand the code here. The error message suggests that what is shown is the full functor application (so of the form Foo(Bar)
), but the code suggests that lid
in fact only denotes the functor part of the application (so only Foo
), in the case where it is an application itself. So I would expect the error message to be "off", with a problematic application ((F(x))(Y)
being reported as an error on F(X)
. But in fact the testsuite seems to suggest that the implementation is correct. What am I missing about what lid_app
means?
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.
lid_app
is a "best"-effort nominal approximation for the functor application. In particular it is either:
Some (Lapply _ )
if the functor application can be resumed as a path-with-applicationF(X(A).B)(Y)
, in practice we only recover those in the easy case of functor application at the type level (F(X).t
)Some (<Module path of the leftmost functor>)
if we are not in the case above but at least the leftmost functor has a nameNone
if there are no name for neither the functor application nor the leftmost functor
I propose to split this option into a specialized ternary variant rather than rely on its content to distinguish the two approximation cases.
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.
Yes please!
@@ -221,7 +221,7 @@ module Ord : sig type t = unit val compare : 'a -> 'b -> int end | |||
Line 2, characters 11-29: | |||
2 | module M = Map.Make(Ord)(Ord) | |||
^^^^^^^^^^^^^^^^^^ | |||
Error: The functor application is ill-typed. | |||
Error: This functor application of Map.Make is ill-typed. |
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'm not fond of the wording "This functor application of Map.Make". Alternative proposal: "The application of the functor Map.Make".
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 slightly prefer to keep the demonstrative whenever we have a dependency on the context. Nevertheless, I agree that This application of the functor
seems simpler (and thus better).
2c402ed
to
19da571
Compare
19da571
to
581f3a7
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.
Thanks! The code looks good now. Approved.
type application_name = | ||
| Anonymous_functor | ||
| Full_application_path of Longident.t | ||
| Named_leftmost_functor of Longident.t |
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 have a hunch that it might be better to keep located identifiers in the error payload. (Something about future programmatic handling of errors in third-party tools, with fixup suggestions etc.) Feel free to act on it or not.
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.
Possibly. However, I would rather add this information once it is exploitable rather than anticipate many layers of future improvements.
This PR proposes to add a specialized error message whenever some code tries to use a signature as a functor.
For instance, since OCaml 4.14,
falls in the functor error code path, resulting in this quite long
error message. Prior to OCaml 4.13, the error message was more specialized
This PR proposes to go one step further and reduces the error message to
and similarly for inclusion error
under the assumption that in this context it is better to emphasize the module kind mismatch rather than the types of the extraneous arguments.
Along the way, this PR updates the error message for functor applications to display the name of the applicand whenever possible. Previously, this name was only printed for ill-typed functor applications in type expressions:
but not at the module expression level
with this PR, this error abstract is amended to
since this change is a low hanging fruit, once the non functor case is already checking if the applicand has a human readable name.