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
Warn user when a type variable in a type constraint has been instantiated. #6
Conversation
If we accepted |
@gasche do you know why
I disagree. I'd be surprised to see people use I really like the idea of this PR btw! |
Let's formulate this differently: you cannot willingly forget 20 years of (admittedly dubious but voluntary) flexible variable semantics and claim that it's actually a mistake to use them that way. It may seem surprising to you but some people are familiar with the current semantics of type variables and have used it in their codebases -- note that there is no alternative, while it is now possible to explicitly enforce rigid variables with ( I like the idea as well. I did a code review but, besides the universal pattern Thomas spotted already, I couldn't comment much, as I'm not familiar with the type-checker codebase. Alain may have more to tell. I wondered whether this should be a delayed check or not, but my understanding is that the implementation only check variables at "safe points" (after checking a toplevel phrase or complete module structure) where it is a precondition that all local inference constraints have been solved. |
Disabling the warning for type variables like |
Actually, there would be some consistency in having no warnings on |
Note that -- because of structural types -- some things can only be expressed in OCaml using unification variables. For example, this (nonsense) function can only be written using unification variables: # let rec f n (x : < m: 'b. 'b -> 'a > as 'a) =
if n < 0 then x
else if n = 0 then f (n - 2) (x#m 5)
else f (n - 2) (x#m 6.0);;
val f : int -> (< m : 'b. 'b -> 'a > as 'a) -> 'a = <fun> I'm not sure that we should add a warning which goes off for any possible definition of perfectly valid functions. I also think, that unification variables are used more often than people think: almost every use of My preferred approach to helping people to understand the difference between unification variables and type variables would be to have the compiler accept the syntax: val id: 'a. 'a -> 'a for value specifications, and also to print value specifications with that syntax by default. This would mean that type variables were consistently bound in OCaml, and unification variables were consistently unbound. |
I think your patch still gives a warning for uses of # let rec f (x : < m: int; .. > as 'a) : 'a option =
if x#m < 0 then None
else Some x;;
val f : (< m : int; .. > as 'a) -> 'a option = <fun> which I think are very common. |
Indeed, your example should not trigger a warning. I forgot that case, thanks. I have updated the patch to handle this case. Maybe not the best implementation, but it should be sufficient to test. |
Oops, I had only seen the changes to |
Unfortunatly, it isn't. |
Here is an updated version, with proper 'scope handling' for aliased variables. |
@@ -249,7 +250,7 @@ module MakeIterator(Iter : IteratorArgument) : sig | |||
exp.exp_extra; | |||
begin | |||
match exp.exp_desc with | |||
Texp_ident (path, _, _) -> () | |||
| Texp_ident (path, _, _) -> () |
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.
Even if I don't like it, the implicit coding rules of the compiler forbid this |
and the rule have been enforced in other merge request.
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 are many occurrences of '|' on the first branch in the compiler code base. I don't think anyone would complain about this style.
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.
Great! Thank you, I'm happy to hear it. I will stop removing them from my patch.
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.
If anything, I would complain about the absence of the first |
. But I've learned not to complain too much.
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.
However, changing just this is more of a concern, as the diff is unnecessary!
Fix error on IA32
@garrigue It's been more than three years since the most recent update of this patch, as far as I can see. Is it going to be merged? If not then I think we should close the pull request until someone steps forward to bring the code to a mergeable state. |
We are not going to introduce this change, as it is not "backward compatible" (i.e., doesn't fit well with the existing codebase). |
Emit low-level location information for FDO: use discriminators (2/2)
Add units for metrics and switch to v2 schema
It seems to be a common misunderstanding amongst beginners that type variables in type constraint are unification variables and that they should be explicitly quantified when desired.
This small patch adds a warning when such non-quantified variable has been instantiated by the type checker. The verification is made /a posteriori/ by looking for type constraints in the typed tree.
I'm not sure this warning is really a desired feature, but it is probably worth discussion. For instance, ocamlyacc-generated files use such variables on purpose.