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

Remove global state for typechecking patterns #1281

Conversation

ncik-roberts
Copy link
Contributor

@ncik-roberts ncik-roberts commented Mar 30, 2023

Replace global variables managed by type_pat with a (mutable) state value that's explicitly passed around. There are a few benefits apart from the obvious "global mutable state is bad":

  • now pattern typing is re-entrant, there is a clearer path to supporting module patterns in array/list comprehension
  • the checking of or-patterns is a little more straightforward
  • this makes it more obviously correct to remove the unnecessary module_patterns_restriction argument from partial_pred, exposed in the mli. (And, I do remove it in this PR.) These two things don't interact in an interesting way (module patterns, exhaustivity checking), and the explicit scoping of the type_pat_state value makes it obvious that we can just ignore module patterns here.

Implementation

The previous discipline was something like:

  1. Call reset_pattern to reset the global state
  2. Call type_pat (which writes into the global state)
  3. Read out the results from the pieces of global state (the global variables pattern_variables, module_variables, and pattern_force)

The discipline is now:

  1. Call create_type_pat_state to create tps, a fresh copy of pattern-checking state
  2. Call type_pat on tps (which writes into its fields)
  3. Read out the results from the fields of tps

Review

I think waiting for @goldfirere makes most sense here, but I'm open to suggestions.

Upstream status

I'm labeling this as "to upstream" but I have a patch ready to do this, so no further action from anyone else is required.

@ncik-roberts ncik-roberts requested a review from goldfirere March 30, 2023 19:33
@ncik-roberts ncik-roberts added the to upstream PR should be sent to upstream OCaml label Mar 30, 2023
Copy link
Contributor

@antalsz antalsz left a comment

Choose a reason for hiding this comment

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

I gave this a read and it looks good to me; while I don't understand the pattern-matching code, I believe this correctly refactors it to make all the mutable state local

ocaml/typing/typecore.ml Outdated Show resolved Hide resolved
ocaml/typing/typecore.ml Show resolved Hide resolved
@ncik-roberts ncik-roberts force-pushed the nroberts.remove-global-type_pat-state branch 2 times, most recently from 84256e0 to 6f6c459 Compare April 4, 2023 16:18
@ncik-roberts ncik-roberts changed the base branch from main to nroberts.upstream-feedback.remove-typedtree-module-elaboration April 5, 2023 15:21
@ncik-roberts ncik-roberts force-pushed the nroberts.remove-global-type_pat-state branch from 6f6c459 to 73e0da2 Compare April 5, 2023 15:21
@ncik-roberts ncik-roberts force-pushed the nroberts.remove-global-type_pat-state branch from 73e0da2 to f67d084 Compare April 5, 2023 15:21
@ncik-roberts
Copy link
Contributor Author

I talked to Richard, and he doesn't feel like he needs to review this given Antal's and Leo's review. I'll merge this and prepare the corresponding upstream patch.

@ncik-roberts ncik-roberts merged commit ff538aa into nroberts.upstream-feedback.remove-typedtree-module-elaboration Apr 13, 2023
@ncik-roberts ncik-roberts deleted the nroberts.remove-global-type_pat-state branch April 13, 2023 18:42
ncik-roberts added a commit that referenced this pull request Apr 13, 2023
@ncik-roberts ncik-roberts restored the nroberts.remove-global-type_pat-state branch April 13, 2023 18:44
@ncik-roberts
Copy link
Contributor Author

Ah, actually I spotted a bug in this. This hasn't yet been merged to main so this is easy to fix --- I'll do so in the branch I merged it into (nroberts.upstream-feedback.remove-typedtree-module-elaboration).

The new code only propagates the pattern_forces generated in the first branch of an or-pattern, which leads to this program being accepted:

type 'a t = G of 'a

let f ((x : 'a) | (x : 'a t)) = ()

(* val f : 'a t -> unit *)

(I don't understand pattern_forces well enough to state whether this is a soundness issue, but it's at minimum a surprising change in behavior, so I'll fix it.)

ncik-roberts added a commit that referenced this pull request May 3, 2023
* Remove global state for typechecking patterns

* These comments can go

* Two copies of `type_pat_state` when checking or-patterns
ncik-roberts added a commit that referenced this pull request May 3, 2023
* Incorporate garrigue's comment

It's closer to the old impl to check let-defs for scope escape rather
than only let-bound vars. We might as well continue to do that.

* Respond to more of garrigue's comments

* Remove global state for typechecking patterns (#1281)

* Remove global state for typechecking patterns

* These comments can go

* Two copies of `type_pat_state` when checking or-patterns

* Fix bug where `pattern_force` was dropped in or-patterns

* Respond to review

* remove the (we believe) unneeded call to generalize_structure
@ncik-roberts ncik-roberts deleted the nroberts.remove-global-type_pat-state branch December 12, 2023 20:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
to upstream PR should be sent to upstream OCaml
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants