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
Fix tricky typing bug with type substitutions #11931
Conversation
I think that this is a reasonable fix. It's not quite clear to me under which conditions |
Well, |
After looking carefully at the code in |
I tried doing a specialised version of this for Does the new |
The approach looks correct, but give me a bit more time to check it. |
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 did a new check, and see nothing wrong in this PR.
I have a few comments, but they are not strict requirements.
It would still be a good idea to fix Typemod.params_are_constrained
, as the current code may break invariants you assume here.
possibly an interaction with (copy more) below? *) | ||
| Tconstr _ | Tnil -> | ||
copy more | ||
| Tvar _ | Tunivar _ -> |
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 you want to check invariants, then I suppose that Tvar
should be an error here, and also for get_desc ty
: there should not be unbound type variables in a type abbreviation.
Since this should indeed be the case, you could just remove it here to make it clear.
in | ||
let row = | ||
match get_desc more' with (* PR#6163 *) | ||
Tconstr (x,_,_) when not (is_fixed row) -> |
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 was not sure this case was needed here.
Looking at Ctype.add_gadt_equation
, Subst.type_expr
gets called when we add local constraints during unification, so if this were done by Subst.typexp
, there would be no need to do it here.
Before such a change, it seems safer to assume that this is still needed.
0a36644
to
d47890a
Compare
@gasche , that was a problem due to the change of ocamltest syntax. I have pushed a version of the PR with the right test syntax. |
The following code crashes the compiler with
Fatal error: fold Tsubst
:The bug concerns the cached type expansion abbreviations in
Ctype.simple_abbrevs
. The sequence of events, as far as I can follow it, is:simple_abbrevs
entries:t = bool
andt2 = t
.The three occurrences of
t
(one ins
, two in simple_abbrevs) are physically equaltype_expr
nodes.The two occurrences of
t2
(one ins
, one in simple_abbrevs) are physically equaltype_expr
nodes.t2 := t
to the definition ofs
, and traverse the tuplet * t2 * 'a
inSubst.tyexp
Subst.tyexp
visitst
, sees that there is no transformation to apply, so copiest
to a freshtype_expr
node (alsot
) and mutates the original to be aTsubst
.NB: Since this
t
is shared withsimple_abbrevs
, we now havet2 = Tsubst ...
insimple_abbrevs
.Subst.tyexp
visitst2
, sees that it must apply the transformationt2 := t
, so callsCtype.apply
.Ctype.apply
tries to expandt2
by callinginstance_parameterized_type
instance_parameterized_type
notices that it has asimple_abbrevs
to hand, and so expandst2
not tot
but toTsubst ...
Ctype.apply
feeds the result to the unifier, which explodes upon seeing aTsubst
.Since
Ctype.apply
is called from the middle of substitution (during which types are temporarily changed to Tsubst), it seems dangerous to use the sharedsimple_abbrevs
cache. So, the patch here is to clear that cache inapply
.This makes the issue go away, but I'm not convinced it's the right fix as I barely understand how any of the abbrevs / simple_abbrevs machinery works. Opinions? (cc @garrigue @lpw25)