Skip to content

Commit

Permalink
Merge pull request #15467 from dotty-staging/fix-scala-js-init
Browse files Browse the repository at this point in the history
Try promotion while widening arguments
  • Loading branch information
liufengyun authored Jun 17, 2022
2 parents 13d9359 + 4969b26 commit f58c158
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 8 deletions.
24 changes: 16 additions & 8 deletions compiler/src/dotty/tools/dotc/transform/init/Semantic.scala
Original file line number Diff line number Diff line change
Expand Up @@ -479,10 +479,16 @@ object Semantic:
RefSet(refs1 ++ diff)

/** Conservatively approximate the value with `Cold` or `Hot` */
def widenArg: Value =
def widenArg: Contextual[Value] =
a match
case _: Ref | _: Fun => Cold
case RefSet(refs) => refs.map(_.widenArg).join
case _: Ref | _: Fun =>
val errors = Reporter.stopEarly { a.promote("Argument cannot be promoted to hot") }
if errors.isEmpty then Hot
else Cold

case RefSet(refs) =>
refs.map(_.widenArg).join

case _ => a


Expand All @@ -491,7 +497,7 @@ object Semantic:
if values.isEmpty then Hot
else values.reduce { (v1, v2) => v1.join(v2) }

def widenArgs: List[Value] = values.map(_.widenArg).toList
def widenArgs: Contextual[List[Value]] = values.map(_.widenArg).toList


extension (ref: Ref)
Expand Down Expand Up @@ -738,12 +744,13 @@ object Semantic:
if ctor.hasSource then
val cls = ctor.owner.enclosingClass.asClass
val ddef = ctor.defTree.asInstanceOf[DefDef]
given Env = Env(ddef, args.map(_.value).widenArgs)
val env2 = Env(ddef, args.map(_.value).widenArgs)
if ctor.isPrimaryConstructor then
given Env = env2
val tpl = cls.defTree.asInstanceOf[TypeDef].rhs.asInstanceOf[Template]
extendTrace(cls.defTree) { init(tpl, ref, cls) }
else
addParamsAsFields(env, ref, ddef)
addParamsAsFields(env2, ref, ddef)
val initCall = ddef.rhs match
case Block(call :: _, _) => call
case call => call
Expand All @@ -756,13 +763,14 @@ object Semantic:
if ctor.hasSource then
val cls = ctor.owner.enclosingClass.asClass
val ddef = ctor.defTree.asInstanceOf[DefDef]
given Env = Env(ddef, args.map(_.value).widenArgs)
val env2 = Env(ddef, args.map(_.value).widenArgs)
if ctor.isPrimaryConstructor then
given Env = env2
val tpl = cls.defTree.asInstanceOf[TypeDef].rhs.asInstanceOf[Template]
extendTrace(cls.defTree) { eval(tpl, ref, cls, cacheResult = true) }
ref
else
addParamsAsFields(env, ref, ddef)
addParamsAsFields(env2, ref, ddef)
extendTrace(ddef) { eval(ddef.rhs, ref, cls, cacheResult = true) }
else if ref.canIgnoreMethodCall(ctor) then
Hot
Expand Down
12 changes: 12 additions & 0 deletions tests/init/neg/promote-warm.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
class PromoteWarm:
class A:
def foo() = PromoteWarm.this.foo()

class B(a: A):
a.foo()

val a = new A
val b = new B(a) // error
val n = 10

def foo() = println(n)
12 changes: 12 additions & 0 deletions tests/init/pos/promote-warm.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
class PromoteWarm:
class A:
def foo() = PromoteWarm.this.foo()

class B(a: A):
a.foo()

val n = 10
val a = new A
val b = new B(a)

def foo() = println(n)

0 comments on commit f58c158

Please sign in to comment.