-
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
Typing regression on polymorphic fields #11735
Comments
(In the discussion, @lpw25 proposed a refined criterion to lower the level not of all type variables occurring under a GADT constructor, as implemented, but all type variables that occurs in the type of a term variable that also captures an existential. This refined criterion would also reject the example, as I'm not sure about your claim that the generalization is sound (and I don't understand the semantics of first-class polymorphism well enough to tell that it is required). The following versions work: let eta (p : forall) : forall =
{ f = match p with {f = T x} -> T x }
let eta (p : forall) : forall =
let p = match p with {f = T x} -> T x in
{ f = p } but these ones do not work let eta { f = T x } = { f = T x }
let eta (p : forall) : forall =
match p with {f = T x} -> { f = T x } If I think about the logical statement you are encoding in your GADTs, I see one proof:
In this proof, I need to apply the right rule on the forall in the goal before I can apply a left rule on the hypothesis in the context. This is consistent with rejecting programs that start by opening |
On the other hand, the following program is accepted, while it would be rejected by my reasoning above: type 'a w
type forall = { f : 'a . 'a w }
let eta { f = x } = { f = x } |
Thanks for the explanation. I was confused here and misunderstood the bug and its fix, your explanation looks correct to me.
I think that matching on a polymorphic record (the pattern The same reasoning explains why this version of
Again, the left rule for forall is applied after the right rule, in the scrutinee of However, my original example contains the pattern (So there's no bug here and 4.14 and onwards are doing the right thing. I'll fix the code that triggered this, thanks for the help) |
The patch in #10959 fixed a serious soundness bug (#10907) in which the types of variables bound in patterns were being incorrectly generalised even when they refer to existentials.
However, the fix also breaks some uses of polymorphic record fields, where the generalisation is sound (and seemingly required, by the semantics of first-class polymorphism). The following program fails to typecheck since 4.14:
This is an eta-expansion of the type
forall 'a . exists 'b . ('a, 'b) t
, but since 4.14 it yields the error:because the type of the field
f
is not generalised.The text was updated successfully, but these errors were encountered: