Skip to content

Commit 87190ef

Browse files
committed
Drop old existential handling
1 parent 3c8aa5e commit 87190ef

File tree

10 files changed

+12
-372
lines changed

10 files changed

+12
-372
lines changed

compiler/src/dotty/tools/dotc/cc/CaptureOps.scala

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -204,8 +204,7 @@ extension (tp: Type)
204204
* - annotated types that represent reach or maybe capabilities
205205
*/
206206
final def isTrackableRef(using Context): Boolean = tp match
207-
case _: ThisType => true
208-
case tp: TermParamRef => !Existential.isBinderOLD(tp)
207+
case _: (ThisType | TermParamRef) => true
209208
case tp: TermRef =>
210209
((tp.prefix eq NoPrefix)
211210
|| tp.symbol.isField && !tp.symbol.isStatic && tp.prefix.isTrackableRef
@@ -215,7 +214,6 @@ extension (tp: Type)
215214
tp.symbol.isType && tp.derivesFrom(defn.Caps_CapSet)
216215
case tp: TypeParamRef =>
217216
tp.derivesFrom(defn.Caps_CapSet)
218-
case Existential.VarOLD(_) => true
219217
case Existential.Vble(_) => true
220218
case AnnotatedType(parent, annot) =>
221219
defn.capabilityWrapperAnnots.contains(annot.symbol) && parent.isTrackableRef
@@ -542,8 +540,6 @@ extension (tp: Type)
542540
// Also map existentials in results to reach capabilities if all
543541
// preceding arguments are known to be always pure
544542
t.derivedFunctionOrMethod(args, apply(Existential.toCap(res)))
545-
case Existential(_, _) =>
546-
t
547543
case _ =>
548544
mapOver(t)
549545
end narrowCaps
@@ -571,8 +567,6 @@ extension (tp: Type)
571567
case t @ AnnotatedType(parent, ann) =>
572568
// Don't traverse annotations, which includes capture sets
573569
this(x, parent)
574-
case Existential(_, _) =>
575-
false
576570
case _ =>
577571
foldOver(x, t)
578572
acc(false, tp)

compiler/src/dotty/tools/dotc/cc/CaptureRef.scala

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ import core.*
66
import Types.*, Symbols.*, Contexts.*, Decorators.*
77
import util.{SimpleIdentitySet, Property}
88
import typer.ErrorReporting.Addenda
9-
import TypeComparer.subsumesExistentiallyOLD
109
import util.common.alwaysTrue
1110
import scala.collection.mutable
1211
import CCState.*
@@ -110,7 +109,6 @@ trait CaptureRef extends TypeProxy, ValueType:
110109
*/
111110
final def isMaxCapability(using Context): Boolean = this match
112111
case tp: TermRef => tp.isCap || tp.info.derivesFrom(defn.Caps_Exists)
113-
case Existential.VarOLD(_) => true
114112
case Existential.Vble(_) => true
115113
case Fresh(_) => true
116114
case ReadOnlyCapability(tp1) => tp1.isMaxCapability
@@ -229,7 +227,6 @@ trait CaptureRef extends TypeProxy, ValueType:
229227
case _ => false
230228
|| this.match
231229
case ReachCapability(x1) => x1.subsumes(y.stripReach)
232-
case Existential.VarOLD(bv) => subsumesExistentiallyOLD(bv, y)
233230
case x: TermRef => viaInfo(x.info)(subsumingRefs(_, y))
234231
case x: TypeRef if assumedContainsOf(x).contains(y) => true
235232
case x: TypeRef if x.derivesFrom(defn.Caps_CapSet) =>

compiler/src/dotty/tools/dotc/cc/CaptureSet.scala

Lines changed: 1 addition & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,6 @@ sealed abstract class CaptureSet extends Showable:
104104

105105
final def isUnboxable(using Context) =
106106
elems.exists:
107-
case Existential.VarOLD(_) => true
108107
case Existential.Vble(_) => true
109108
case elem => elem.isRootCapability
110109

@@ -548,8 +547,6 @@ object CaptureSet:
548547
final def addThisElem(elem: CaptureRef)(using Context, VarState): CompareResult =
549548
if isConst || !recordElemsState() then // Fail if variable is solved or given VarState is frozen
550549
addIfHiddenOrFail(elem)
551-
else if Existential.isBadExistentialOLD(elem) then // Fail if `elem` is an out-of-scope existential
552-
CompareResult.Fail(this :: Nil)
553550
else if !levelOK(elem) then
554551
CompareResult.LevelError(this, elem) // or `elem` is not visible at the level of the set.
555552
else
@@ -573,14 +570,9 @@ object CaptureSet:
573570
if elem.isRootCapability then
574571
!noUniversal
575572
else elem match
576-
case Existential.VarOLD(bv) =>
577-
!noUniversal
578-
&& !TypeComparer.isOpenedExistential(bv)
579-
// Opened existentials on the left cannot be added to nested capture sets on the right
580-
// of a comparison. Test case is open-existential.scala.
581573
case elem @ Existential.Vble(mt) =>
582574
!noUniversal
583-
&& !TypeComparer.isOpenedExistential(elem)
575+
&& !CCState.openedFreshBinders.contains(elem)
584576
// Opened existentials on the left cannot be added to nested capture sets on the right
585577
// of a comparison. Test case is open-existential.scala.
586578
case elem: TermRef if level.isDefined =>
@@ -636,7 +628,6 @@ object CaptureSet:
636628
try
637629
val approx = computeApprox(origin).ensuring(_.isConst)
638630
if approx.elems.exists:
639-
case Existential.VarOLD(_) => true
640631
case Existential.Vble(_) => true
641632
case _ => false
642633
then
@@ -1325,8 +1316,6 @@ object CaptureSet:
13251316
case tp: (TypeRef | TypeParamRef) =>
13261317
if tp.derivesFrom(defn.Caps_CapSet) then tp.captureSet
13271318
else empty
1328-
case tp @ Existential.VarOLD(_) =>
1329-
tp.captureSet
13301319
case tp @ Existential.Vble(_) =>
13311320
tp.captureSet
13321321
case CapturingType(parent, refs) =>
@@ -1393,8 +1382,6 @@ object CaptureSet:
13931382
case t @ FunctionOrMethod(args, res) =>
13941383
if args.forall(_.isAlwaysPure) then this(cs, Existential.toCap(res))
13951384
else cs
1396-
case t @ Existential(_, _) =>
1397-
cs
13981385
case _ =>
13991386
foldOver(cs, t)
14001387
collect(CaptureSet.empty, tp)

compiler/src/dotty/tools/dotc/cc/CheckCaptures.scala

Lines changed: 4 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@ import CCState.*
2323
import StdNames.nme
2424
import NameKinds.{DefaultGetterName, WildcardParamName, UniqueNameKind}
2525
import reporting.{trace, Message, OverrideError}
26-
import Existential.derivedExistentialTypeOLD
2726
import Annotations.Annotation
2827

2928
/** The capture checker */
@@ -869,8 +868,6 @@ class CheckCaptures extends Recheck, SymTransformer:
869868
// can happen for curried constructors if instantiate of a previous step
870869
// added capture set to result.
871870
augmentConstructorType(parent, initCs ++ refs)
872-
case core @ Existential(boundVar, core1) =>
873-
core.derivedExistentialTypeOLD(augmentConstructorType(core1, initCs))
874871
case _ =>
875872
val (refined, cs) = addParamArgRefinements(core, initCs)
876873
refined.capturing(cs)
@@ -942,8 +939,8 @@ class CheckCaptures extends Recheck, SymTransformer:
942939
// which are less intelligible. An example is the line `a = x` in
943940
// neg-custom-args/captures/vars.scala. That's why this code is conditioned.
944941
// to apply only to closures that are not eta expansions.
945-
val res1 = Existential.toCapDeeply(res) // TODO: why toCapDeeply?
946-
val pt1 = Existential.toCapDeeply(pt)
942+
val res1 = Existential.toCap(res, deep = true) // TODO: why deep = true?
943+
val pt1 = Existential.toCap(pt, deep = true)
947944
// We need to open existentials here in order not to get vars mixed up in them
948945
// We do the proper check with existentials when we are finished with the closure block.
949946
capt.println(i"pre-check closure $expr of type $res1 against $pt1")
@@ -1450,17 +1447,9 @@ class CheckCaptures extends Recheck, SymTransformer:
14501447

14511448
def adaptStr = i"adapting $actual ${if covariant then "~~>" else "<~~"} $expected"
14521449

1453-
// Get existentials and wildcards out of the way
1454-
actual match
1455-
case actual @ Existential(_, actualUnpacked) =>
1456-
return Existential.derivedExistentialTypeOLD(actual):
1457-
recur(actualUnpacked, expected, covariant)
1458-
case _ =>
1450+
// Get wildcards out of the way
14591451
expected match
1460-
case expected @ Existential(_, expectedUnpacked) =>
1461-
return recur(actual, expectedUnpacked, covariant)
1462-
case _: WildcardType =>
1463-
return actual
1452+
case _: WildcardType => return actual
14641453
case _ =>
14651454

14661455
trace(adaptStr, capt, show = true) {

compiler/src/dotty/tools/dotc/cc/Existential.scala

Lines changed: 3 additions & 187 deletions
Original file line numberDiff line numberDiff line change
@@ -210,41 +210,6 @@ Expansion of ^:
210210
*/
211211
object Existential:
212212

213-
type CarrierOLD = RefinedType
214-
215-
def unapply(tp: CarrierOLD)(using Context): Option[(TermParamRef, Type)] =
216-
tp.refinedInfo match
217-
case mt: MethodType
218-
if isExistentialMethodOLD(mt) && defn.isNonRefinedFunction(tp.parent) =>
219-
Some(mt.paramRefs.head, mt.resultType)
220-
case _ => None
221-
222-
/** Create method type in the refinement of an existential type */
223-
private def exMethodTypeOLD(using Context)(
224-
mk: TermParamRef => Type,
225-
boundName: TermName = ExistentialBinderName.fresh()
226-
): MethodType =
227-
MethodType(boundName :: Nil)(
228-
mt => defn.Caps_Exists.typeRef :: Nil,
229-
mt => mk(mt.paramRefs.head))
230-
231-
/** Create existential */
232-
def applyOLD(mk: TermParamRef => Type)(using Context): Type =
233-
exMethodTypeOLD(mk).toFunctionType(alwaysDependent = true)
234-
235-
/** The (super-) type of existentially bound references */
236-
type VarOLD = AnnotatedType
237-
238-
/** An extractor for existentially bound references of the form ex @existential
239-
* where ex is a TermParamRef of type Exists
240-
*/
241-
object VarOLD:
242-
def apply(boundVar: TermParamRef)(using Context): VarOLD =
243-
AnnotatedType(boundVar, Annotation(defn.ExistentialAnnot, NoSpan))
244-
def unapply(tp: VarOLD)(using Context): Option[TermParamRef] = tp match
245-
case AnnotatedType(bv: TermParamRef, ann) if ann.symbol == defn.ExistentialAnnot => Some(bv)
246-
case _ => None
247-
248213
/** The (super-) type of existentially bound references */
249214
type Vble = AnnotatedType
250215

@@ -260,44 +225,6 @@ object Existential:
260225
case _ => None
261226
case _ => None
262227

263-
/** Create existential if bound variable appears in result of `mk` */
264-
def wrapOLD(mk: TermParamRef => Type)(using Context): Type =
265-
val mt = exMethodTypeOLD(mk)
266-
if mt.isResultDependent then mt.toFunctionType() else mt.resType
267-
268-
extension (tp: CarrierOLD)
269-
def derivedExistentialTypeOLD(core: Type)(using Context): Type = tp match
270-
case Existential(boundVar, unpacked) =>
271-
if core eq unpacked then tp
272-
else applyOLD(bv => core.substParam(boundVar, bv))
273-
case _ =>
274-
core
275-
276-
/** Map existentially bound references referring to `boundVar` one-to-one
277-
* to Fresh instances (OLD)
278-
*/
279-
def boundVarToCapOLD(boundVar: TermParamRef, tp: Type)(using Context) =
280-
val subst = new IdempotentCaptRefMap:
281-
val seen = EqHashMap[Annotation, CaptureRef]()
282-
def apply(t: Type): Type = t match
283-
case t @ VarOLD(`boundVar`) =>
284-
seen.getOrElseUpdate(t.annot, Fresh(NoSymbol))
285-
case _ =>
286-
mapOver(t)
287-
subst(tp)
288-
289-
/** Map existentially bound references referring to `boundVar` one-to-one
290-
* to Fresh instances
291-
*/
292-
def toCapOLD(tp: Type)(using Context): Type = tp.dealiasKeepAnnots match
293-
case Existential(boundVar, unpacked) => // (OLD)
294-
boundVarToCapOLD(boundVar, unpacked)
295-
case tp1 @ CapturingType(parent, refs) =>
296-
tp1.derivedCapturingType(toCap(parent), refs)
297-
case tp1 @ AnnotatedType(parent, ann) =>
298-
tp1.derivedAnnotatedType(toCap(parent), ann)
299-
case _ => tp
300-
301228
/** Map top-level free existential variables one-to-one to Fresh instances */
302229
def toCap(tp: Type, deep: Boolean = false)(using Context): Type =
303230
val subst = new IdempotentCaptRefMap:
@@ -320,26 +247,8 @@ object Existential:
320247
case _ =>
321248
mapOver(t)
322249

323-
if ccConfig.newScheme then subst(tp)
324-
else toCapOLD(tp)
325-
326-
/** Map existentials at the top-level and in all nested result types to `Fresh`
327-
*/
328-
def toCapDeeplyOLD(tp: Type)(using Context): Type = tp.dealiasKeepAnnots match
329-
case Existential(boundVar, unpacked) =>
330-
toCapDeeplyOLD(boundVarToCapOLD(boundVar, unpacked))
331-
case tp1 @ FunctionOrMethod(args, res) =>
332-
val tp2 = tp1.derivedFunctionOrMethod(args, toCapDeeplyOLD(res))
333-
if tp2 ne tp1 then tp2 else tp
334-
case tp1 @ CapturingType(parent, refs) =>
335-
tp1.derivedCapturingType(toCapDeeplyOLD(parent), refs)
336-
case tp1 @ AnnotatedType(parent, ann) =>
337-
tp1.derivedAnnotatedType(toCapDeeplyOLD(parent), ann)
338-
case _ => tp
339-
340-
def toCapDeeply(tp: Type)(using Context): Type =
341-
if ccConfig.newScheme then toCap(tp, deep = true)
342-
else toCapDeeplyOLD(tp)
250+
subst(tp)
251+
end toCap
343252

344253
/** Knowing that `tp` is a function type, is it an alias to a function other
345254
* than `=>`?
@@ -348,75 +257,6 @@ object Existential:
348257
case AppliedType(tycon, _) => !defn.isFunctionSymbol(tycon.typeSymbol)
349258
case _ => false
350259

351-
/** Replace all occurrences of `cap` (or fresh) in parts of this type by an existentially bound
352-
* variable. If there are such occurrences, or there might be in the future due to embedded
353-
* capture set variables, create an existential with the variable wrapping the type.
354-
* Stop at function or method types since these have been mapped before.
355-
*/
356-
def mapCapOLD(tp: Type, fail: Message => Unit)(using Context): Type =
357-
var needsWrap = false
358-
359-
abstract class CapMap extends BiTypeMap:
360-
override def mapOver(t: Type): Type = t match
361-
case t @ FunctionOrMethod(args, res) if variance > 0 && !isAliasFun(t) =>
362-
t // `t` should be mapped in this case by a different call to `mapCap`.
363-
case Existential(_, _) =>
364-
t
365-
case t: (LazyRef | TypeVar) =>
366-
mapConserveSuper(t)
367-
case _ =>
368-
super.mapOver(t)
369-
370-
class Wrap(boundVar: TermParamRef) extends CapMap:
371-
private val seen = EqHashMap[CaptureRef, VarOLD]()
372-
373-
def apply(t: Type) = t match
374-
case t: CaptureRef if t.isCapOrFresh =>
375-
if variance > 0 then
376-
needsWrap = true
377-
seen.getOrElseUpdate(t, VarOLD(boundVar))
378-
else
379-
if variance == 0 then
380-
fail(em"""$tp captures the root capability `cap` in invariant position""")
381-
// we accept variance < 0, and leave the cap as it is
382-
super.mapOver(t)
383-
case t @ CapturingType(parent, refs: CaptureSet.Var) =>
384-
if variance > 0 then needsWrap = true
385-
super.mapOver(t)
386-
case defn.FunctionNOf(args, res, contextual) if t.typeSymbol.name.isImpureFunction =>
387-
if variance > 0 then
388-
needsWrap = true
389-
super.mapOver:
390-
defn.FunctionNOf(args, res, contextual)
391-
.capturing(VarOLD(boundVar).singletonCaptureSet)
392-
else mapOver(t)
393-
case _ =>
394-
mapOver(t)
395-
//.showing(i"mapcap $t = $result")
396-
397-
lazy val inverse = new BiTypeMap:
398-
def apply(t: Type) = t match
399-
case t @ VarOLD(`boundVar`) =>
400-
// do a reverse getOrElseUpdate on `seen` to produce the
401-
// `Fresh` assosicated with `t`
402-
val it = seen.iterator
403-
var ref: CaptureRef | Null = null
404-
while it.hasNext && ref == null do
405-
val (k, v) = it.next
406-
if v.annot eq t.annot then ref = k
407-
if ref == null then
408-
ref = Fresh(NoSymbol)
409-
seen(ref) = t
410-
ref
411-
case _ => mapOver(t)
412-
def inverse = Wrap.this
413-
override def toString = "Wrap.inverse"
414-
end Wrap
415-
416-
val wrapped = applyOLD(Wrap(_)(tp))
417-
if needsWrap then wrapped else tp
418-
end mapCapOLD
419-
420260
/** Replace all occurrences of `cap` (or fresh) in parts of this type by an existentially bound
421261
* variable bound by `mt`.
422262
* Stop at function or method types since these have been mapped before.
@@ -486,37 +326,13 @@ object Existential:
486326
else t
487327
case t: MethodType if variance > 0 && t.isFreshBinder =>
488328
val t1 = mapOver(t).asInstanceOf[MethodType]
489-
t1.derivedLambdaType(resType =
490-
if ccConfig.newScheme then mapCap(t1.resType, t1, fail)
491-
else mapCapOLD(t1.resType, fail))
329+
t1.derivedLambdaType(resType = mapCap(t1.resType, t1, fail))
492330
case CapturingType(parent, refs) =>
493331
t.derivedCapturingType(this(parent), refs)
494-
case Existential(_, _) =>
495-
t
496332
case t: (LazyRef | TypeVar) =>
497333
mapConserveSuper(t)
498334
case _ =>
499335
mapFollowingAliases(t)
500336
end mapCapInResults
501337

502-
/** Is `mt` a method represnting an existential type when used in a refinement? */
503-
def isExistentialMethodOLD(mt: TermLambda)(using Context): Boolean = mt.paramInfos match
504-
case (info: TypeRef) :: rest => info.symbol == defn.Caps_Exists && rest.isEmpty
505-
case _ => false
506-
507-
/** Is `ref` a TermParamRef representing existentially bound variables? */
508-
def isBinderOLD(ref: CaptureRef)(using Context) = ref match
509-
case ref: TermParamRef => isExistentialMethodOLD(ref.binder)
510-
case _ => false
511-
512-
/** An value signalling an out-of-scope existential that should
513-
* lead to a compare failure.
514-
*/
515-
def badExistentialOLD(using Context): TermParamRef =
516-
exMethodTypeOLD(identity, nme.OOS_EXISTENTIAL).paramRefs.head
517-
518-
def isBadExistentialOLD(ref: CaptureRef) = ref match
519-
case ref: TermParamRef => ref.paramName == nme.OOS_EXISTENTIAL
520-
case _ => false
521-
522338
end Existential

0 commit comments

Comments
 (0)