Skip to content

Commit 344738f

Browse files
committed
Add back outer-sensitivity
This helps reduce more than 20 errors: [error] -- Error: /Users/fliu/Documents/dotty/compiler/src/dotty/tools/dotc/core/StdNames.scala:665:34 [error] 665 | final val MINUS_STAR : N = "-*" [error] | ^^^^ [error] |Call method dotty.tools.dotc.core.StdNames.ScalaNames.this.fromString("-*") on a value with an unknown initialization. Calling trace: [error] | -> package object printing { [ package.scala:6 ] [error] | -> val AndTypePrec: Int = parsing.precedence(tpnme.raw.AMP) [ package.scala:11 ] [error] | -> object raw { [ StdNames.scala:649 ]
1 parent 3dfcf51 commit 344738f

File tree

1 file changed

+33
-7
lines changed

1 file changed

+33
-7
lines changed

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

+33-7
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ class Objects {
4949
case class ObjectRef(klass: ClassSymbol) extends Addr
5050

5151
/** An ClassAbs of class */
52-
case class ClassAbs(klass: ClassSymbol) extends Addr
52+
case class ClassAbs(klass: ClassSymbol, outer: Value) extends Addr
5353

5454
/** A function value */
5555
case class Fun(expr: Tree, thisV: Value, klass: ClassSymbol) extends Value
@@ -68,7 +68,7 @@ class Objects {
6868
*
6969
* Note: Object is NOT a value.
7070
*/
71-
case class Objekt(klass: ClassSymbol, fields: mutable.Map[Symbol, Value])
71+
case class Objekt(klass: ClassSymbol, fields: mutable.Map[Symbol, Value], outers: mutable.Map[Symbol, Value])
7272

7373
/** Abstract heap stores abstract objects
7474
*
@@ -93,7 +93,8 @@ class Objects {
9393
def updateField(field: Symbol, value: Value): Contextual[Unit] =
9494
heap(ref).fields(field) = value
9595

96-
def updateOuter(klass: ClassSymbol, value: Value): Contextual[Unit] = ()
96+
def updateOuter(klass: ClassSymbol, value: Value): Contextual[Unit] =
97+
heap(ref).outers(klass) = value
9798
end extension
9899
}
99100
type Heap = Heap.Heap
@@ -192,6 +193,11 @@ class Objects {
192193
case (RefSet(refs), b) => RefSet(b :: refs)
193194
case (a, b) => RefSet(a :: b :: Nil)
194195

196+
def widen(using Context): Value = a.match
197+
case RefSet(refs) => refs.map(_.widen).join
198+
case ClassAbs(klass, outer: ClassAbs) => ClassAbs(klass, TypeAbs(outer.klass.typeRef))
199+
case _ => a
200+
195201
extension (values: Seq[Value])
196202
def join: Value =
197203
if values.isEmpty then Bottom
@@ -227,7 +233,7 @@ class Objects {
227233
eval(rhs, addr, target.owner.asClass, cacheResult = true)
228234
else
229235
given Trace = trace1
230-
val obj = if heap.contains(addr) then heap(addr) else Objekt(addr.klass, mutable.Map.empty)
236+
val obj = if heap.contains(addr) then heap(addr) else Objekt(addr.klass, mutable.Map.empty, mutable.Map.empty)
231237
if obj.fields.contains(target) then
232238
Result(obj.fields(target), Nil)
233239
else if target.is(Flags.ParamAccessor) then
@@ -318,14 +324,15 @@ class Objects {
318324

319325
case Bottom | _: TypeAbs | _: ClassAbs | _: ObjectRef =>
320326
given Trace = trace1
327+
val outer = value.widen
321328
val addr =
322329
if klass.isStaticObjectRef then
323330
ObjectRef(klass)
324331
else
325-
ClassAbs(klass)
332+
ClassAbs(klass, outer)
326333

327334
if !heap.contains(addr) then
328-
val obj = Objekt(klass, fields = mutable.Map.empty)
335+
val obj = Objekt(klass, fields = mutable.Map.empty, outers = mutable.Map(klass -> outer))
329336
heap.update(addr, obj)
330337

331338
val res = addr.call(ctor, args, superType = NoType, source)
@@ -658,7 +665,26 @@ class Objects {
658665
val res = Result(ObjectRef(target.moduleClass.asClass), Nil)
659666
if target == klass || elideObjectAccess then res
660667
else res.ensureAccess(klass, source)
661-
else Result(TypeAbs(target.typeRef), Nil)
668+
else
669+
thisV match
670+
case Bottom => Result(Bottom, Nil)
671+
case addr: Addr =>
672+
val obj = heap(addr)
673+
val outerCls = klass.owner.enclosingClass.asClass
674+
if !obj.outers.contains(klass) then
675+
val error = PromoteError("outer not yet initialized, target = " + target + ", klass = " + klass, source, trace.toVector)
676+
report.error(error.show + error.stacktrace, source)
677+
Result(Bottom, Nil)
678+
else
679+
resolveThis(target, obj.outers(klass), outerCls, source)
680+
case RefSet(refs) =>
681+
val ress = refs.map(ref => resolveThis(target, ref, klass, source))
682+
Result(ress.map(_.value).join, ress.flatMap(_.errors))
683+
case fun: Fun =>
684+
report.warning("unexpected thisV = " + thisV + ", target = " + target.show + ", klass = " + klass.show, source.srcPos)
685+
Result(TypeAbs(defn.AnyType), Nil)
686+
case TypeAbs(tp) =>
687+
Result(TypeAbs(target.info), Nil)
662688
}
663689

664690
/** Compute the outer value that correspond to `tref.prefix` */

0 commit comments

Comments
 (0)