Skip to content
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

OCaml5 merge conflicts: typing/typecore.ml #213

Merged
merged 2 commits into from
Oct 30, 2023

Conversation

ccasin
Copy link
Contributor

@ccasin ccasin commented Oct 24, 2023

The beginning parts of this PR are not so bad, but towards the end I think it will be hard to review by reading the diff. When looking over the completed version myself, I found the easiest thing was to first create a file containing the (pat)diffs between (this file and the old ocaml-jst version) and another with the diff between (this file and the upstream version). Then, when reading a resolved diff, I would mainly look at those other files to understand how the diff was resolved and check nothing was dropped. (Though I confess past a certain point I ran out of steam for carefully reading what I'd written - will continue looking tomorrow)

Some major sources of conflicts:

  • 5.1 has some of Nick's cleanup work in typecore (Remove arity-interrupting elaboration of module unpacks ocaml/ocaml#12117) but not all of it (Remove global state for typechecking patterns ocaml/ocaml#12229). This is mainly in the checking of patterns, and results in conflicts when PRs in both categories change the same line, and what we have is already ahead of upstream 5.1.

  • type_pat has been split into two functions upstream: type_pat and check_counter_example_pat. These are meant to be kept in sync, but we didn't have the latter until now. I've tried to make sure check_counter_example_pat has anything relevant we've added to type_pat, and we discussed the modes question elsewhere.

  • Now that type_pat doesn't take a ~mode argument to distingish it from check_counter_example_pat, it's very tempting to rename its ~alloc_mode argument to ~mode. But it seemed like that would make for confusing diff here, so it should be done separately.

  • We've completely rewritten type_argument internally, and there are upstream changes in it. I proceeded by taking ours and then manually applying changes that had happened upstream. It looks like there are three main upstream PRs that have touched this code:

  • type_let has been completely refactored upstream, and we've made a bunch of changes to it for layouts and modes. Nothing too surprising here, just big diffs with confusing markers.

@ccasin ccasin requested a review from lpw25 October 24, 2023 18:38
@ncik-roberts
Copy link
Contributor

I said I might merge this prior to Leo's review, but there a number of other open PRs we'll need before this is useful, so I'll hold off.

Copy link
Contributor

@ncik-roberts ncik-roberts left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I didn't actually read this. I'm only approving so I can merge this now, even though Leo isn't done reviewing — he'll flag any further issues to Chris.

@ncik-roberts ncik-roberts merged commit 9e85b20 into ocaml-flambda:main Oct 30, 2023
2 checks passed
Copy link
Contributor

@lpw25 lpw25 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't see any bugs but there are a few things that I think should be improved.

Arg (Eliminated_optional_arg { next_arg_loc })) ->
next_arg_loc
| (_, Omitted _) -> None)
|> Option.value ~default:funct.exp_loc
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the upstream code here is just wrong. The comment is incorrect: the arguments are not in reverse order of appearance. I also think that next_arg_loc is not a sensible value here -- again this is also true of upstreams version. We should get rid of next_arg_loc now, and fix the rest later. Maybe leave a CR by the comment pointing out that it is wrong.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree next_arg_loc is kind of nonsense and will get rid of it.

To check: I believe rev_args are in reverse order of appearance in the type of the function. I think the point you are making is that may be different than the reverse order of the argument terms in the program due to labeled/optional argument. Correct?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's right. I think that when they differ this upstream code is going to produce confusing error locations.

| None -> Not_a_function(ty_fun, explanation)
end
=======
let ty_arg, ty_res =
with_local_level_iter_if separate ~post:generalize_structure begin fun () ->
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This would probably be slightly easier to read if it used with_local_level_if and had an ad-hoc post function.

@@ -9408,10 +7127,9 @@ and type_construct env (expected_mode : expected_mode) loc lid sarg
(instance ty_expected));
end
in
((ty_args, ty_res, texp), ty_res::ty_args)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe better to just use with_local_level_if and write our own post function. That List.map offends my sensibilities.

Pat.constraint_ ~loc:{pat.ppat_loc with Location.loc_ghost=true} pat sty
| _ -> pat
in
let pat_mode, exp_mode =
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure it makes much sense to pull this code out into this function. It seems to mix two separate concerns:

  1. Converting constraints within value bindings into equivalent constraints on patterns.
  2. Working out what modes the pattern and expression should be typed at

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I waffled on this originally. The advantage of this approach is that it saves iterating and allocating an additional list, but now the name is bad and it does two unrelated things. We do want to build this list eventually, for later use by type_pattern_list.

In the absence of upstream, I think I would change the name of vb_pat_constraint to find_pat_constraints_and_modes (or something) and have it call two helpers that do the two things. But the cost of the extra list is small, and it's nice to stay in sync with upstream, so I'll just do what you suggest (leave vb_pat_constraint alone and build an extra list).

<<<<<<< HEAD
if !Clflags.principal then begin_def ();
let op_path, op_desc = type_binding_op_ident env sop in
let op_type = op_desc.val_type in
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We've lost the removal of the call to instance on this line. The call is harmless but also not needed and potentially confusing since this is a difference between our type_ident and the one upstream. We should also probably remove it from the other call site of type_binding_op_ident.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants