Skip to content

Commit 4799b75

Browse files
author
EnzeXing
committed
Rewriting widen as abstract method
1 parent 340eab9 commit 4799b75

File tree

1 file changed

+34
-15
lines changed

1 file changed

+34
-15
lines changed

compiler/src/dotty/tools/dotc/transform/init/Objects.scala

Lines changed: 34 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -95,12 +95,15 @@ object Objects:
9595

9696
sealed abstract class Value:
9797
def show(using Context): String
98+
def widen(height : Int)(using Context): Value =
99+
if height == 0 then Cold else this
98100

99101
/** ValueElement are elements that can be contained in a RefSet */
100102
sealed abstract class ValueElement extends Value
101103

102104
sealed trait ThisValue extends Value:
103-
def widenThisV(height : Int)(using Context) : ThisValue = this
105+
override def widen(height : Int)(using Context) : ThisValue =
106+
if height == 0 then Cold else this
104107

105108
/**
106109
* A reference caches the values for outers and immutable fields.
@@ -166,11 +169,14 @@ object Objects:
166169
def widenedCopy(outer: Value, args: List[Value], env: Env.Data): OfClass =
167170
new OfClass(klass, outer, ctor, args, env)(this.valsMap, this.varsMap, this.outersMap)
168171

169-
override def widenThisV(height: Int)(using Context): ThisValue =
170-
val outer2 = outer.widen(height - 1)
171-
val args2 = args.map(_.widen(height - 1))
172-
val env2 = env.widen(height - 1)
173-
widenedCopy(outer2, args2, env2)
172+
override def widen(height: Int)(using Context): ThisValue =
173+
if height == 0 then
174+
Cold
175+
else
176+
val outer2 = outer.widen(height - 1)
177+
val args2 = args.map(_.widen(height - 1))
178+
val env2 = env.widen(height - 1)
179+
widenedCopy(outer2, args2, env2)
174180

175181
def show(using Context) =
176182
val valFields = vals.map(_.show + " -> " + _.show)
@@ -211,6 +217,9 @@ object Objects:
211217
case class Fun(code: Tree, thisV: ThisValue, klass: ClassSymbol, env: Env.Data) extends ValueElement:
212218
def show(using Context) = "Fun(" + code.show + ", " + thisV.show + ", " + klass.show + ")"
213219

220+
override def widen(height: Int)(using Context): Value =
221+
Fun(code, thisV.widen(height), klass, env.widen(height))
222+
214223
/**
215224
* Represents a set of values
216225
*
@@ -219,11 +228,17 @@ object Objects:
219228
case class RefSet(refs: ListSet[ValueElement]) extends Value:
220229
def show(using Context) = refs.map(_.show).mkString("[", ",", "]")
221230

231+
override def widen(height: Int)(using Context): Value =
232+
if height == 0 then
233+
Cold
234+
else
235+
refs.map(ref => ref.widen(height)).join
236+
222237
/** A cold alias which should not be used during initialization.
223238
*
224239
* Cold is not ValueElement since RefSet containing Cold is equivalent to Cold
225240
*/
226-
case object Cold extends Value with ThisValue:
241+
case object Cold extends ThisValue:
227242
def show(using Context) = "Cold"
228243

229244
val Bottom = RefSet(ListSet.empty)
@@ -435,7 +450,7 @@ object Objects:
435450
ref.outer match
436451
case outer : ThisValue =>
437452
resolveEnv(meth, outer, ref.env)
438-
case _ => // This is the case for top-level classes and local classes
453+
case _ => // This is the case for top-level
439454
None
440455
case _ =>
441456
None
@@ -576,7 +591,7 @@ object Objects:
576591
case (RefSet(refs), b : ValueElement) => RefSet(refs + b)
577592
case (a : ValueElement, b : ValueElement) => RefSet(ListSet(a, b))
578593

579-
def widen(height: Int)(using Context): Value =
594+
/* def widen(height: Int)(using Context): Value =
580595
if height == 0 then Cold
581596
else
582597
a match
@@ -591,7 +606,7 @@ object Objects:
591606
case ref : Ref =>
592607
ref.widenThisV(height)
593608
594-
case _ => a
609+
case _ => a */
595610

596611
extension (values: Iterable[Value])
597612
def join: Value = if values.isEmpty then Bottom else values.reduce { (v1, v2) => v1.join(v2) }
@@ -859,11 +874,15 @@ object Objects:
859874
else
860875
// Widen the outer to finitize the domain. Arguments already widened in `evalArgs`.
861876
val (outerWidened, envWidened) =
862-
if klass.owner.isClass then // For top-level classes, klass.owner is the enclosing package, which is a class
863-
(outer.widen(1), Env.NoEnv)
864-
else
865-
// klass.enclosingMethod returns its primary constructor
866-
Env.resolveEnv(klass.owner.enclosingMethod, outer.asInstanceOf[ThisValue], summon[Env.Data]).getOrElse(Cold -> Env.NoEnv)
877+
value match
878+
case _ : Bottom.type => // For top-level classes
879+
(Bottom, Env.NoEnv)
880+
case thisV : ThisValue =>
881+
if klass.owner.isClass then // For top-level classes, klass.owner is the enclosing package, which is a class
882+
(thisV.widen(1), Env.NoEnv)
883+
else
884+
// klass.enclosingMethod returns its primary constructor
885+
Env.resolveEnv(klass.owner.enclosingMethod, thisV, summon[Env.Data]).getOrElse(Cold -> Env.NoEnv)
867886

868887
val instance = OfClass(klass, outerWidened, ctor, args.map(_.value), envWidened)
869888
callConstructor(instance, ctor, args)

0 commit comments

Comments
 (0)