Conversation
bytecomp/matching.ml
Outdated
| let patv = Array.make num_fields omega in | ||
| List.iter (fun (_, lbl, pat) -> patv.(lbl.lbl_pos) <- pat) lbl_pat_list; | ||
| Array.to_list patv | ||
| with Invalid_argument _ -> assert false |
There was a problem hiding this comment.
It's not clear at all, to me, where this Invalid_argument _ exception would be raised. If you mean that lbl.lbl_pos is always a valid index for patv, why don't you just write assert (lbl.lbl_pos < Array.length patv) in the loop?
gasche
left a comment
There was a problem hiding this comment.
From the patch I have no idea what the problem really is, and I find it very surprising that the problem is specific to extension constructors (there is no rebinding going on for example). Why is forget_extension_with_arg a good idea (can you remind us what as_matrix is doing?). Now that you understand the bug, does the reproduction case really need to be that large, or can you write a smaller program that runs in the same argument-typing issue with extension constructors?
The fix you comment was not a good idea, I have committed a new fix. The new fix simply avoids to extract arguments from pattern matrices when type mismatch on arguments may occur. A more radical fix would change the approximate constructor equality function
This can be done, but well... |
|
The point in a smaller repro case is that it also increases the chance that someone else than you understands what the problem is: looking at the repro case is an interesting part of understanding the whole fix when the repro case has no unnecessary cruft that obscures understanding. From your second message I understand the problem better: because we equate I find it ironic that this seems very related to the refinement of Types, like patterns, can be "equal", "known to be different" ("incompatible"), and "maybe equal" ("not incompatible"), so two extension constructions with not-incompatible types may be equal. If my intuition of what you say is correct, the issue here only comes up when argument types on both sides can have sub-patterns that clearly belong to distinct types, and this is only possible if the types are really incompatible; so maybe accepting in may_equal_constr argument types that are not incompatible but are not known to be equal either is not an issue, and the further restriction I previously suggested is a good fix. |
It may be a good fix, but I do not know to implement it. |
…mega, when type inconsistency my occur, due to approximate extension constructor matching.
I might give it a try tomorrow, I have a long flight ahead of me. Btw, a smaller code reproducing the problem could be: |
|
Note: the central code pattern in the last fix proposed by Luc if Types.may_equal_constr cstr cstr' then begin
if Types.equal_tag cstr.cstr_tag cstr'.cstr_tag
then ...
else ...
end else ...would have been nicely represented as pattern-matching on a three-way return type: match Types.compare_constr cstr cstr' with
| Equal -> ...
| Compatible -> ...
| Incompatible -> ... |
|
Ok I use @trefis example as an additional test. |
|
I had a look at how to define a "non-incompatibility test" for types, and it's not easy to implement (just as @maranget thought!). In particular, the comment #1468 (comment) by @garrigue suggests that In this context, I agree with the idea of finishing the current patch and merging it (to fix the issue), before we try to refine |
|
I think the underlying issue here was misunderstood (the bug can be reproduced without matching on extensible types) and this PR, while fixing the issue in the context of extensible variants is incomplete. Before getting into more details, I'd like to clarify the context. If I understand the issue correctly, I think @gasche's previous intuition
is not exactly correct/correctly formulated: we never have One could then assume that the issue is that because of extensible types we've allowed things of incompatible types (that is: unreachable trap handlers) to remain in our list of reachable trap handlers and that is what causes our specializing function to crash (because it makes the assumption that things are of the same type). In this PR, Luc proposes to fix this problem by making the matrices we put in our list of reachable trap handlers more lax when specializing with constructor of extensible types, to avoid such issues in recursive calls (which IIUC means that we're disabling optimizations allowing us to skip some tests). However:
Considering this I would suggest
|
|
@trefis "Bien vu", I need to think about it, I acknowledge you comment. |
|
Another one: type _ repr = R1 : int repr | R2 : string repr
let f (type a) (r1 : a repr) (r2 : a repr) (a : a) =
match r1, r2, a with
| R1, _, 0 -> ()
| _, R2, "coucou" -> ()yields "assertion failed" somewhere in parmatch. The fact is that PM code assumes that patterns of different types "just don't mix". Obviously, this is untrue. |
|
Note: the fact that |
I wouldn't do that. |
|
We know of no code in the wild that is affected by the miscompilation bug (some may exist, but we don't know about it, and the fact that the bug was undercover for so long suggests that no path that people actually test is affected). Keeping the bug in trunk for a few more weeks seems harmless to me. The alternative you propose requires (1) to prepare a PR for jbuilder to work-around that may reduce code readability and will only ever makes sense for a couple week, (2) explain to the jbuilder developers why they should merge this PR while their code is obviously correct, (3) make a release of jbuilder to reach opam-repository. This is strictly more work for a handful of people and, I think, not a good example of how upstream should deal with its own issues. |
|
Sorry, I wasn't actually suggesting to "fix" anything in jbuilder. |
|
Oh, I misunderstood. That sounds reasonable to me. If you can make a fix to unblock jbuilder, is not a waste of time, and is submitted and reviewed relatively swiftly (this week? next week?), I think that's a good option. If that does not sound realistic, then I will propose reverting again. |
|
Just FYI I've started working on a full fix. I'll make a PR before the end of the day (potentially with some bits left missing). |
|
Superseeded by #1538 . |
This is a fix relative to the re-opening of MPR#7661.
The example in PR have been reduced and is included in the test suite.