@@ -33,9 +33,9 @@ In Setup:
33
33
34
34
- Conversion is done with a BiTypeMap in `Existential.mapCap`.
35
35
36
- In adapt :
36
+ In reckeckApply and recheckTypeApply :
37
37
38
- - If an EX is toplevel in actual type, replace its bound variable
38
+ - If an EX is toplevel in the result type, replace its bound variable
39
39
occurrences with `cap`.
40
40
41
41
Level checking and avoidance:
@@ -54,6 +54,7 @@ Level checking and avoidance:
54
54
don't, the others do.
55
55
56
56
- Capture set variables do not accept elements of level higher than the variable's level
57
+
57
58
- We use avoidance to heal such cases: If the level-incorrect ref appears
58
59
+ covariantly: widen to underlying capture set, reject if that is cap and the variable does not allow it
59
60
+ contravariantly: narrow to {}
@@ -65,10 +66,9 @@ In cv-computation (markFree):
65
66
the owning method. They have to be widened to dcs(x), or, where this is not
66
67
possible, it's an error.
67
68
68
- In well-formedness checking of explicitly written type T :
69
+ In box adaptation :
69
70
70
- - If T is not the type of a parameter, check that no cap occurrence or EX-bound variable appears
71
- under a box.
71
+ - Check that existential variables are not boxed or unboxed.
72
72
73
73
Subtype rules
74
74
@@ -129,6 +129,18 @@ Subtype checking algorithm, steps to add for tp1 <:< tp2:
129
129
assocExistentials(tp2).isDefined
130
130
&& (assocExistentials(tp2).contains(tp1) || tp1 is not existentially bound)
131
131
132
+ Subtype checking algorithm, comparing two capture sets CS1 <:< CS2:
133
+
134
+ We need to map the (possibly to-be-added) existentials in CS1 to existentials
135
+ in CS2 so that we can compare them. We use `assocExistentals` for that:
136
+ To map an EX-variable V1 in CS1, pick the last (i.e. outermost, leading to the smallest
137
+ type) EX-variable in `assocExistentials` that has V1 in its possible instances.
138
+ To go the other way (and therby produce a BiTypeMap), map an EX-variable
139
+ V2 in CS2 to the first (i.e. innermost) EX-variable it can be instantiated to.
140
+ If either direction is not defined, we choose a special "bad-existetal" value
141
+ that represents and out-of-scope existential. This leads to failure
142
+ of the comparison.
143
+
132
144
Existential source syntax:
133
145
134
146
Existential types are ususally not written in source, since we still allow the `^`
@@ -142,7 +154,8 @@ Existential source syntax:
142
154
Existential types can only at the top level of the result type
143
155
of a function or method.
144
156
145
- Restrictions on Existential Types:
157
+ Restrictions on Existential Types: (to be implemented if we want to
158
+ keep the source syntax for users).
146
159
147
160
- An existential capture ref must be the only member of its set. This is
148
161
intended to model the idea that existential variables effectibely range
@@ -353,11 +366,14 @@ object Existential:
353
366
case ref : TermParamRef => isExistentialMethod(ref.binder)
354
367
case _ => false
355
368
369
+ /** An value signalling an out-of-scope existential that should
370
+ * lead to a compare failure.
371
+ */
372
+ def badExistential (using Context ): TermParamRef =
373
+ exMethodType(identity, nme.OOS_EXISTENTIAL ).paramRefs.head
374
+
356
375
def isBadExistential (ref : CaptureRef ) = ref match
357
376
case ref : TermParamRef => ref.paramName == nme.OOS_EXISTENTIAL
358
377
case _ => false
359
378
360
- def badExistential (using Context ): TermParamRef =
361
- exMethodType(identity, nme.OOS_EXISTENTIAL ).paramRefs.head
362
-
363
379
end Existential
0 commit comments