@@ -14,98 +14,85 @@ type CaptureRoot = TermRef | CaptureRoot.Var
14
14
15
15
object CaptureRoot :
16
16
17
- case class Var ( owner : Symbol , source : Symbol = NoSymbol )( using @ constructorOnly ictx : Context ) extends CaptureRef , Showable :
17
+ private var nextId = 0
18
18
19
- var upperBound : Symbol = owner
20
- var lowerBound : Symbol = NoSymbol
21
- var upperLevel : Int = owner.ccNestingLevel
22
- var lowerLevel : Int = Int .MinValue
23
- private [CaptureRoot ] var lowerRoots : SimpleIdentitySet [Var ] = SimpleIdentitySet .empty
24
- private [CaptureRoot ] var upperRoots : SimpleIdentitySet [Var ] = SimpleIdentitySet .empty
25
- private [CaptureRoot ] var alias : CaptureRoot = this
19
+ case class Var (owner : Symbol , source : Symbol )(using @ constructorOnly ictx : Context ) extends CaptureRef , Showable :
26
20
27
- override def localRootOwner ( using Context ) = owner
28
- override def isTrackableRef ( using Context ) : Boolean = true
29
- override def captureSetOfInfo ( using Context ) = CaptureSet .universal
21
+ val id =
22
+ nextId += 1
23
+ nextId
30
24
31
- def setAlias (target : CaptureRoot ) =
32
- alias = target
25
+ var innerLimit : Symbol = owner.levelOwner
26
+ var outerLimit : Symbol = defn.RootClass
27
+ var outerRoots : SimpleIdentitySet [Var ] = SimpleIdentitySet .empty
33
28
34
- def followAlias : CaptureRoot = alias match
35
- case alias : Var if alias ne this => alias.followAlias
36
- case _ => alias
29
+ override def isTrackableRef (using Context ): Boolean = true
30
+ override def captureSetOfInfo (using Context ) = CaptureSet .universal
37
31
38
- def locallyConsistent =
39
- lowerLevel <= upperLevel
40
- && lowerRoots.forall(_.upperLevel <= upperLevel)
41
- && upperRoots.forall(_.lowerLevel >= lowerLevel)
32
+ private var myAlias : CaptureRoot = this
33
+ def alias = myAlias
34
+ def alias_= (r : CaptureRoot )(using Context ) =
35
+ // assert(id != 2, i"$this := $r")
36
+ alias match
37
+ case alias : TermRef =>
38
+ val owner = alias.localRootOwner
39
+ assert(
40
+ owner.isContainedIn(outerLimit) && innerLimit.isContainedIn(owner),
41
+ i " illegal alias $owner for $this" )
42
+ case _ =>
43
+ myAlias = r
42
44
43
45
def computeHash (bs : Binders ): Int = hash
44
46
def hash : Int = System .identityHashCode(this )
45
47
def underlying (using Context ): Type = defn.Caps_Cap .typeRef
46
48
end Var
47
49
48
- def isEnclosingRoot ( c1 : CaptureRoot , c2 : CaptureRoot )( using Context ) : Boolean =
49
- if c1 eq c2 then return true
50
- c1 match
51
- case c1 : Var if c1 .alias ne c1 => return isEnclosingRoot(c1 .alias, c2)
52
- case _ =>
53
- c2 match
54
- case c2 : Var if c2.alias ne c2 => return isEnclosingRoot(c1, c2.alias)
55
- case _ =>
56
- (c1, c2) match
57
- case ( c1 : TermRef , c2 : TermRef ) =>
58
- c1.ccNestingLevel <= c2.ccNestingLevel
59
- case ( c1 : TermRef , c2 : Var ) =>
60
- val level1 = c1.ccNestingLevel
61
- if level1 <= c2.lowerLevel then
62
- true // no change
63
- else if level1 <= c2.upperLevel && c2.upperRoots.forall(isEnclosingRoot(c1, _)) then
64
- if level1 == c2.upperLevel then
65
- c2.alias = c1
50
+ extension ( r : CaptureRoot )
51
+
52
+ def followAlias ( using Context ) : CaptureRoot = r match
53
+ case r : Var if r .alias ne r => r .alias.followAlias
54
+ case _ => r
55
+
56
+ def unifiesWith ( other : CaptureRoot )( using Context ) : Boolean =
57
+ r.encloses(other) && other.encloses(r)
58
+
59
+ def encloses ( other : CaptureRoot )( using Context ) : Boolean =
60
+ val (r1, r2) = (followAlias, other.followAlias)
61
+ (r1 eq r2) || (r1, r2). match
62
+ case ( r1 : TermRef , r2 : TermRef ) =>
63
+ r2.localRootOwner.isContainedIn(r1.localRootOwner)
64
+ case ( r1 : TermRef , r2 : Var ) =>
65
+ val r1Owner = r1.localRootOwner
66
+ if r2.outerLimit.isContainedIn(r1Owner) then true
67
+ else if ! r2.innerLimit.isContainedIn(r1Owner) then false
66
68
else
67
- c2.lowerBound = c1.symbol
68
- c2.lowerLevel = level1
69
- true
70
- else false
71
- case (c1 : Var , c2 : TermRef ) =>
72
- val level2 = c2.ccNestingLevel
73
- if c1.upperLevel <= level2 then
74
- true // no change
75
- else if c1.lowerLevel <= level2 && c1.lowerRoots.forall(isEnclosingRoot(_, c2)) then
76
- if level2 == c1.lowerLevel then
77
- c1.alias = c2
69
+ if r2.innerLimit == r1Owner then r2.alias = r1
70
+ else r2.outerLimit = r1Owner
71
+ true
72
+ case (r1 : Var , r2 : TermRef ) =>
73
+ val r2Owner = r2.localRootOwner
74
+ if r2Owner.isContainedIn(r1.innerLimit) then true
75
+ else if ! r2Owner.isContainedIn(r1.outerLimit) then false
78
76
else
79
- c1.upperBound = c2.symbol
80
- c1.upperLevel = level2
81
- true
82
- else false
83
- case (c1 : Var , c2 : Var ) =>
84
- if c1.upperRoots.contains(c2) then
85
- true // no change
86
- else if c1.lowerLevel > c2.upperLevel then
87
- false // local inconsistency
88
- else
89
- c1.upperRoots += c2 // set early to prevent infinite looping
90
- if c1.lowerRoots.forall(isEnclosingRoot(_, c2))
91
- && c2.upperRoots.forall(isEnclosingRoot(c1, _))
92
- then
93
- if c1.lowerRoots.contains(c2) then
94
- val c2a = c2.followAlias
95
- if c2a ne c1 then c1.alias = c2a
96
- else
97
- if c1.upperLevel > c2.upperLevel then
98
- c1.upperBound = c2.upperBound
99
- c1.upperLevel = c2.upperLevel
100
- if c2.lowerLevel < c1.lowerLevel then
101
- c2.lowerBound = c1.lowerBound
102
- c2.lowerLevel = c1.lowerLevel
103
- c2.lowerRoots += c1
77
+ if r1.outerLimit == r2Owner then r1.alias = r2
78
+ else r1.innerLimit = r2Owner
79
+ true
80
+ case (r1 : Var , r2 : Var ) =>
81
+ if r2.outerRoots.contains(r1) then true // no change
82
+ else if ! r2.innerLimit.isContainedIn(r1.outerLimit) then false // no overlap
83
+ else if r1.outerRoots.contains(r2) then // unify
84
+ r1.alias = r2
85
+ r2.outerLimit = r1.outerLimit.maxNested(r2.outerLimit)
86
+ r2.innerLimit = r1.innerLimit.minNested(r2.innerLimit)
104
87
true
105
88
else
106
- c1.upperRoots -= c2
107
- false
108
- end isEnclosingRoot
89
+ r2.outerRoots += r1 // set early to prevent infinite looping
90
+ if r1.outerRoots.forall(_.encloses(r2)) then true
91
+ else
92
+ r2.outerRoots -= r2
93
+ false
94
+ end encloses
95
+
109
96
end CaptureRoot
110
97
111
98
0 commit comments