Skip to content

Commit 04b8f94

Browse files
committed
Refine the logic for accessing secondary ctor params
1 parent a41fa4f commit 04b8f94

File tree

1 file changed

+12
-19
lines changed

1 file changed

+12
-19
lines changed

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

Lines changed: 12 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -596,7 +596,7 @@ object Semantic:
596596
}
597597
}
598598

599-
def call(meth: Symbol, args: List[ArgInfo], receiver: Type, superType: Type, needResolve: Boolean = true): Contextual[Value] = log("call " + meth.show + ", args = " + args, printer, (_: Value).show) {
599+
def call(meth: Symbol, args: List[ArgInfo], receiver: Type, superType: Type, needResolve: Boolean = true): Contextual[Value] = log("call " + meth.show + ", args = " + args.map(_.value.show), printer, (_: Value).show) {
600600
def promoteArgs(): Contextual[Unit] = args.foreach(_.promote)
601601

602602
def isSyntheticApply(meth: Symbol) =
@@ -718,7 +718,7 @@ object Semantic:
718718
}
719719
}
720720

721-
def callConstructor(ctor: Symbol, args: List[ArgInfo]): Contextual[Value] = log("call " + ctor.show + ", args = " + args, printer, (_: Value).show) {
721+
def callConstructor(ctor: Symbol, args: List[ArgInfo]): Contextual[Value] = log("call " + ctor.show + ", args = " + args.map(_.value.show), printer, (_: Value).show) {
722722
// init "fake" param fields for the secondary constructor
723723
def addParamsAsFields(env: Env, ref: Ref, ctorDef: DefDef) = {
724724
val paramSyms = ctorDef.termParamss.flatten.map(_.symbol)
@@ -775,7 +775,7 @@ object Semantic:
775775
}
776776

777777
/** Handle a new expression `new p.C` where `p` is abstracted by `value` */
778-
def instantiate(klass: ClassSymbol, ctor: Symbol, args: List[ArgInfo]): Contextual[Value] = log("instantiating " + klass.show + ", value = " + value + ", args = " + args, printer, (_: Value).show) {
778+
def instantiate(klass: ClassSymbol, ctor: Symbol, args: List[ArgInfo]): Contextual[Value] = log("instantiating " + klass.show + ", value = " + value + ", args = " + args.map(_.value.show), printer, (_: Value).show) {
779779
if promoted.isCurrentObjectPromoted then Hot
780780
else value match {
781781
case Hot =>
@@ -838,21 +838,14 @@ object Semantic:
838838
val sym = tmref.symbol
839839

840840
if sym.is(Flags.Param) && sym.owner.isConstructor then
841-
// if we can get the field from the Ref (which can only possibly be
842-
// a secondary constructor parameter), then use it.
843-
if (ref.objekt.hasField(sym))
844-
ref.objekt.field(sym)
845-
// instances of local classes inside secondary constructors cannot
846-
// reach here, as those values are abstracted by Cold instead of Warm.
847-
// This enables us to simplify the domain without sacrificing
848-
// expressiveness nor soundess, as local classes inside secondary
849-
// constructors are uncommon.
850-
else if sym.isContainedIn(klass) then
851-
env.lookup(sym)
852-
else
853-
// We don't know much about secondary constructor parameters in outer scope.
854-
// It's always safe to approximate them with `Cold`.
855-
Cold
841+
val enclosingClass = sym.owner.enclosingClass.asClass
842+
val thisValue2 = resolveThis(enclosingClass, ref, klass)
843+
thisValue2 match
844+
case Hot => Hot
845+
case ref: Ref => ref.objekt.field(sym)
846+
case _ =>
847+
report.error("unexpected this value accessing local variable, sym = " + sym.show + ", thisValue = " + thisValue2.show, trace.toVector.last)
848+
Hot
856849
else if sym.is(Flags.Param) then
857850
Hot
858851
else
@@ -869,7 +862,7 @@ object Semantic:
869862
case ref: Ref => eval(vdef.rhs, ref, enclosingClass)
870863

871864
case _ =>
872-
report.error("unexpected defTree when accessing local variable, sym = " + sym.show + ", defTree = " + sym.defTree.show, trace.toVector.last)
865+
report.error("unexpected this value when accessing local variable, sym = " + sym.show + ", thisValue = " + thisValue2.show, trace.toVector.last)
873866
Hot
874867
end match
875868

0 commit comments

Comments
 (0)