Skip to content

Commit 90afb95

Browse files
committed
Fix semantics for object access
1 parent b2944e3 commit 90afb95

File tree

1 file changed

+21
-9
lines changed

1 file changed

+21
-9
lines changed

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

Lines changed: 21 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -175,9 +175,11 @@ class Objects {
175175
def instantiate(klass: ClassSymbol, ctor: Symbol, args: List[Value], source: Tree): Contextual[Result] =
176176
value.instantiate(klass, ctor, args, source) ++ errors
177177

178-
def ensureAccess(source: Tree): Contextual[Result] =
178+
def ensureAccess(klass: ClassSymbol, source: Tree): Contextual[Result] =
179179
value match
180-
case obj: ObjectRef => obj.access(source) ++ errors
180+
case obj: ObjectRef =>
181+
if obj.klass == klass then this
182+
else obj.access(source) ++ errors
181183
case _ => this
182184
}
183185

@@ -528,7 +530,7 @@ class Objects {
528530
val fun = Fun(arg.tree, Nil, thisV, klass, env)
529531
Result(fun, Nil)
530532
else
531-
eval(arg.tree, thisV, klass).ensureAccess(arg.tree)
533+
eval(arg.tree, thisV, klass)
532534
}
533535

534536
/** Handles the evaluation of different expressions
@@ -584,7 +586,9 @@ class Objects {
584586
res.call(id.symbol, argsValues, superType = NoType, source = expr)
585587

586588
case Select(qualifier, name) =>
587-
eval(qualifier, thisV, klass).select(expr.symbol, expr)
589+
val sym = expr.symbol
590+
if sym.isStaticObjectRef then Result(ObjectRef(sym.moduleClass.asClass), Nil).ensureAccess(klass, expr)
591+
else eval(qualifier, thisV, klass).select(expr.symbol, expr)
588592

589593
case _: This =>
590594
cases(expr.tpe, thisV, klass, expr)
@@ -696,8 +700,13 @@ class Objects {
696700
throw new Exception("unexpected tree: " + expr.show)
697701
}
698702

699-
/** Handle semantics of leaf nodes */
700-
def cases(tp: Type, thisV: Value, klass: ClassSymbol, source: Tree): Contextual[Result] = log("evaluating " + tp.show, printer, res => res.asInstanceOf[Result].show) {
703+
/** Handle semantics of leaf nodes
704+
*
705+
* @param elideObjectAccess Whether object access should be omitted
706+
*
707+
* It happens when the object access is used as a prefix in `new o.C`
708+
*/
709+
def cases(tp: Type, thisV: Value, klass: ClassSymbol, source: Tree, elideObjectAccess: Boolean = false): Contextual[Result] = log("evaluating " + tp.show, printer, res => res.asInstanceOf[Result].show) {
701710
tp match {
702711
case _: ConstantType =>
703712
Result(Bottom, Errors.empty)
@@ -720,15 +729,17 @@ class Objects {
720729
case tmref: TermRef =>
721730
val sym = tmref.symbol
722731
if sym.isStaticObjectRef then
723-
Result(ObjectRef(sym.moduleClass.asClass), Nil)
732+
val res = Result(ObjectRef(sym.moduleClass.asClass), Nil)
733+
if elideObjectAccess then res else res.ensureAccess(klass, source)
724734
else
725735
cases(tmref.prefix, thisV, klass, source).select(tmref.symbol, source)
726736

727737
case tp @ ThisType(tref) =>
728738
val sym = tref.symbol
729739
if sym.is(Flags.Package) then Result(Bottom, Errors.empty)
730740
else if sym.isStaticObjectRef && sym != klass then
731-
Result(ObjectRef(sym.moduleClass.asClass), Nil)
741+
val res = Result(ObjectRef(sym.moduleClass.asClass), Nil)
742+
if elideObjectAccess then res else res.ensureAccess(klass, source)
732743
else
733744
val value = resolveThis(tref.classSymbol.asClass, thisV, klass, source)
734745
Result(value, Errors.empty)
@@ -772,7 +783,8 @@ class Objects {
772783
Result(outerV, Errors.empty)
773784
else
774785
if cls.isAllOf(Flags.JavaInterface) then Result(Bottom, Nil)
775-
else cases(tref.prefix, thisV, klass, source)
786+
else
787+
cases(tref.prefix, thisV, klass, source, elideObjectAccess = cls.isStatic)
776788

777789
/** Initialize part of an abstract object in `klass` of the inheritance chain */
778790
def init(tpl: Template, thisV: Addr, klass: ClassSymbol): Contextual[Result] = log("init " + klass.show, printer, res => res.asInstanceOf[Result].show) {

0 commit comments

Comments
 (0)