From 7bed8912057b1bd32e7c6a1eb6a84a04a1398140 Mon Sep 17 00:00:00 2001 From: Liu Fengyun Date: Mon, 29 Mar 2021 14:10:00 +0200 Subject: [PATCH] Performance tweak for initialization check Propagate visited set properly. --- .../tools/dotc/transform/init/Checking.scala | 38 ++++++++++++------- tests/init/neg/function1.scala | 2 +- 2 files changed, 25 insertions(+), 15 deletions(-) diff --git a/compiler/src/dotty/tools/dotc/transform/init/Checking.scala b/compiler/src/dotty/tools/dotc/transform/init/Checking.scala index e47c3b08d264..cc8f95b20e8c 100644 --- a/compiler/src/dotty/tools/dotc/transform/init/Checking.scala +++ b/compiler/src/dotty/tools/dotc/transform/init/Checking.scala @@ -39,7 +39,18 @@ object Checking { safePromoted: mutable.Set[Potential], // Potentials that can be safely promoted env: Env ) { - def withOwner(sym: Symbol): State = copy(env = env.withOwner(sym)) + def withOwner[T](sym: Symbol)(op: State ?=> T): T = + val state = this.copy(env = env.withOwner(sym)) + val res = op(using state) + this.visited = state.visited + res + + + def visit[T](eff: Effect)(op: State ?=> T): T = + val state: State = this.copy(path = path :+ eff.source, visited = this.visited + eff) + val res = op(using state) + this.visited = state.visited + res def test(op: State ?=> Errors): Errors = { val savedVisited = visited @@ -58,15 +69,14 @@ object Checking { traceIndented("Already checked " + eff.show, init) Errors.empty } - else { - state.visited = state.visited + eff - val state2: State = state.copy(path = state.path :+ eff.source) - eff match { - case eff: Promote => Checking.checkPromote(eff)(using state2) - case eff: FieldAccess => Checking.checkFieldAccess(eff)(using state2) - case eff: MethodCall => Checking.checkMethodCall(eff)(using state2) + else + state.visit(eff) { + eff match { + case eff: Promote => Checking.checkPromote(eff) + case eff: FieldAccess => Checking.checkFieldAccess(eff) + case eff: MethodCall => Checking.checkMethodCall(eff) + } } - } } } @@ -118,11 +128,11 @@ object Checking { def checkConstructor(ctor: Symbol, tp: Type, source: Tree)(using state: State): Unit = traceOp("checking " + ctor.show, init) { val cls = ctor.owner val classDef = cls.defTree - if (!classDef.isEmpty) { - given State = state.withOwner(cls) - if (ctor.isPrimaryConstructor) checkClassBody(classDef.asInstanceOf[TypeDef]) - else checkSecondaryConstructor(ctor) - } + if (!classDef.isEmpty) + state.withOwner(cls) { + if (ctor.isPrimaryConstructor) checkClassBody(classDef.asInstanceOf[TypeDef]) + else checkSecondaryConstructor(ctor) + } } def checkSecondaryConstructor(ctor: Symbol)(using state: State): Unit = traceOp("checking " + ctor.show, init) { diff --git a/tests/init/neg/function1.scala b/tests/init/neg/function1.scala index 15427f3de750..e01864ae1f47 100644 --- a/tests/init/neg/function1.scala +++ b/tests/init/neg/function1.scala @@ -4,7 +4,7 @@ class Foo { val fun2: Int => Int = n => 1 + n + list.size fun2(5) - List(5, 9).map(n => 2 + n + list.size) // error + List(5, 9).map(n => 2 + n + list.size) final val list = List(1, 2, 3) // error