Printing polymorphic mode variables #3396
Open
+1,174
−41
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Prints polymorphic mode variables and their constraints. In general, mode variables is printed in
[...]
containing its lower and upper bounds and constraints as follows:[< ... & ... > ... | ...]
. Lower and upper bounds refer to the constant bounds on the polymorphic variable, and constraints might refer to other mode variables.If a mode variable has no bounds or constraints, it is printed as a fresh mode variable name:
'm
,'n
,'o
, etc.Printing mode variables requires an expensive pre-processing step, which is only applied when
-extension -mode_polymorphism_alpha
is on.Below are some examples:
val id : 'a @ [< 'm] -> 'a @ [> 'm]
let fst x y = x
involves currying, and gets printed toval fst : 'a @ [< 'm & global many > aliased] -> 'b @ 'n -> 'a @ [> 'm | aliased]
. Here, since the curry mode is zapped to legacy, the first parameter gets constrained toglobal many aliased
.let fst x = fun y -> x
on the other hand is eta-expanded, and has slightly different constrains:'a @ [< 'm & global many] -> ('b @ 'n -> 'a @ [> 'm | aliased]) @ [> nonportable]
. The returned closure is polymorphic, but must benonportable
since it must account for the case where the input isuncontended
.type 'a mytyp = { a : 'a @@ portable }
thenlet f x = x.a
is inferred and printed asval f : 'a mytyp @ [< 'm] -> 'a @ [> 'm mod portable]
. Heremod portable
stands for a meet, and the type expresses the output is lower bounded by'm
, except for the portability axis, which is lower bounded byportable
.