typecore: more explanations on the non-locality of type_pat search with GADTs

master
Gabriel Scherer 2019-10-16 11:53:47 +02:00
parent 4c235bc06b
commit 5f2a0695c3
1 changed files with 30 additions and 0 deletions

View File

@ -1028,6 +1028,36 @@ and counter_example_checking_info = {
of the original names.
*)
(** Due to GADT constraints, an or-pattern produced within
a counter-example may have ill-typed branches. Consider for example
type _ tag = Int : int tag | Bool : bool tag
then [Parmatch] will propose the or-pattern [Int | Bool] whenever
a pattern of type [tag] is required to form a counter-example. For
example, a function expects a (int tag option) and only [None] is
handled by the user-written pattern. [Some (Int | Bool)] is not
well-typed in this context, only the sub-pattern [Some Int] is.
In this example, the expected type coming from the context
suffices to know which or-pattern branch must be chosen.
In the general case, choosing a branch can have non-local effects
on the typability of the term. For example, consider a tuple type
['a tag * ...'a...], where the first component is a GADT. All
constructor choices for this GADT lead to a well-typed branch in
isolation (['a] is unconstrained), but choosing one of them adds
a constraint on ['a] that may make the other tuple elements
ill-typed.
In general, after choosing each possible branch of the or-pattern,
[type_pat] has to check the rest of the pattern to tell if this
choice leads to a well-typed term. This may lead to an explosion
of typing/search work -- the rest of the term may in turn contain
alternatives.
We use careful strategies to try to limit counterexample-checking
time; [splitting_mode] represents those strategies.
*)
and splitting_mode =
| Backtrack_or
(** Always backtrack in or-patterns.