Skip to content

Commit 2f2253d

Browse files
committed
Handle package and static objects in this resolution
1 parent d94d794 commit 2f2253d

File tree

3 files changed

+35
-11
lines changed

3 files changed

+35
-11
lines changed

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ class Checker extends MiniPhase {
6464
import semantic._
6565
val tpl = tree.rhs.asInstanceOf[Template]
6666
val thisRef = ThisRef(cls)
67-
val heap = Objekt(fields = mutable.Map.empty)
67+
val heap = Objekt(cls, fields = mutable.Map.empty)
6868
val res = eval(tpl, thisRef, cls)(using heap, ctx, Vector.empty)
6969
res.errors.foreach(_.issue)
7070
}

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

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ class Semantic {
5757

5858
/** The current object under initialization
5959
*/
60-
case class Objekt(val fields: mutable.Map[Symbol, Value]) {
60+
case class Objekt(klass: ClassSymbol, val fields: mutable.Map[Symbol, Value]) {
6161
var allFieldsInitialized: Boolean = false
6262

6363
val promotedValues = mutable.Set.empty[Value]
@@ -501,7 +501,7 @@ class Semantic {
501501
ref match
502502
case Select(supert: Super, _) =>
503503
val SuperType(thisTp, superTp) = supert.tpe
504-
val thisValue2 = resolveThis(thisTp.classSymbol.asClass, thisV, klass)
504+
val thisValue2 = resolveThis(thisTp.classSymbol.asClass, thisV, klass, ref)
505505
Result(thisValue2, errors).call(ref.symbol, superTp, expr)(using heap, ctx, trace2)
506506

507507
case Select(qual, _) =>
@@ -513,7 +513,7 @@ class Semantic {
513513
case TermRef(NoPrefix, _) =>
514514
// resolve this for the local method
515515
val enclosingClass = id.symbol.owner.enclosingClass.asClass
516-
val thisValue2 = resolveThis(enclosingClass, thisV, klass)
516+
val thisValue2 = resolveThis(enclosingClass, thisV, klass, id)
517517
thisValue2 match
518518
case Hot => Result(Hot, errors)
519519
case _ =>
@@ -652,7 +652,7 @@ class Semantic {
652652
case tp @ ThisType(tref) =>
653653
if tref.symbol.is(Flags.Package) then Result(Hot, noErrors)
654654
else
655-
val value = resolveThis(tref.classSymbol.asClass, thisV, klass)
655+
val value = resolveThis(tref.classSymbol.asClass, thisV, klass, source)
656656
Result(value, noErrors)
657657

658658
case _: TermParamRef | _: RecThis =>
@@ -665,8 +665,9 @@ class Semantic {
665665
}
666666

667667
/** Resolve C.this that appear in `klass` */
668-
def resolveThis(target: ClassSymbol, thisV: Value, klass: ClassSymbol): Contextual[Value] = log("resolving " + target.show + ", this = " + thisV.show + " in " + klass.show, printer, res => res.asInstanceOf[Value].show) {
668+
def resolveThis(target: ClassSymbol, thisV: Value, klass: ClassSymbol, source: Tree): Contextual[Value] = log("resolving " + target.show + ", this = " + thisV.show + " in " + klass.show, printer, res => res.asInstanceOf[Value].show) {
669669
if target == klass then thisV
670+
else if target.is(Flags.Package) || target.isStaticOwner && target != heap.klass then Hot
670671
else
671672
thisV match
672673
case Hot | _: ThisRef => Hot
@@ -676,22 +677,24 @@ class Semantic {
676677
if tref.prefix == NoPrefix then
677678
// Current class is local, in the enclosing scope of `warm.klass`
678679
val outerCls = warm.klass.owner.enclosingClass.asClass
679-
resolveThis(target, warm.outer, outerCls)
680+
resolveThis(target, warm.outer, outerCls, source)
680681
else
681682
val outerCls = klass.owner.enclosingClass.asClass
682683
val warmOuterCls = warm.klass.owner.enclosingClass.asClass
683-
val res = cases(tref.prefix, warm.outer, warmOuterCls, EmptyTree)
684+
val res = cases(tref.prefix, warm.outer, warmOuterCls, source)
684685
assert(res.errors.isEmpty, "unexpected error " + res)
685-
resolveThis(target, res.value, outerCls)
686-
case _ => ???
686+
resolveThis(target, res.value, outerCls, source)
687+
case _ =>
688+
// report.error("unexpected thisV = " + thisV + ", target = " + target.show + ", klass = " + klass.show, source.srcPos)
689+
Cold
687690
}
688691

689692
/** Compute the outer value that correspond to `tref.prefix` */
690693
def outerValue(tref: TypeRef, thisV: Value, klass: ClassSymbol, source: Tree): Contextual[Result] =
691694
val cls = tref.classSymbol.asClass
692695
if tref.prefix == NoPrefix then
693696
val enclosing = cls.owner.lexicallyEnclosingClass.asClass
694-
val outerV = resolveThis(enclosing, thisV, klass)
697+
val outerV = resolveThis(enclosing, thisV, klass, source)
695698
Result(outerV, noErrors)
696699
else
697700
cases(tref.prefix, thisV, klass, source)

tests/init/neg/inner30.scala

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
object Scanners {
2+
enum IndentWidth {
3+
case Run(ch: Char, n: Int)
4+
case Conc(l: IndentWidth, r: Run)
5+
}
6+
7+
import IndentWidth.*
8+
9+
class Scanner {
10+
def foo() =
11+
Conc(Run('a', 3), Run('b', 4))
12+
new LookAheadScanner
13+
14+
class LookAheadScanner() extends Scanner
15+
16+
foo()
17+
}
18+
19+
val m: Int = n * 2
20+
val n = 10 // error
21+
}

0 commit comments

Comments
 (0)