From be53c7910a0ccfad38664b9d63f70357f6867643 Mon Sep 17 00:00:00 2001 From: Liu Fengyun Date: Sun, 29 Nov 2020 23:39:23 +0100 Subject: [PATCH] Fix #9176: Handle parent call argument effects in full mode --- .../tools/dotc/transform/init/Checking.scala | 28 +++++++++++-------- .../dotty/tools/dotc/CompilationTests.scala | 1 - tests/init/full/neg/global-cycle1.scala | 10 +++++++ tests/init/{ => full}/neg/hybrid2.scala | 0 tests/init/full/neg/i9176.scala | 9 ++++++ 5 files changed, 36 insertions(+), 12 deletions(-) create mode 100644 tests/init/full/neg/global-cycle1.scala rename tests/init/{ => full}/neg/hybrid2.scala (100%) create mode 100644 tests/init/full/neg/i9176.scala diff --git a/compiler/src/dotty/tools/dotc/transform/init/Checking.scala b/compiler/src/dotty/tools/dotc/transform/init/Checking.scala index e52a283a7702..d5287d6612f4 100644 --- a/compiler/src/dotty/tools/dotc/transform/init/Checking.scala +++ b/compiler/src/dotty/tools/dotc/transform/init/Checking.scala @@ -141,11 +141,14 @@ object Checking { checkSecondaryConstructor(ctor) } - (stats :+ expr).foreach { stat => - val summary = Summarization.analyze(stat)(theEnv.withOwner(ctor)) + checkStats(stats :+ expr, ctor) + } + + def checkStats(stats: List[Tree], owner: Symbol)(using state: State): Unit = + stats.foreach { stat => + val summary = Summarization.analyze(stat)(theEnv.withOwner(owner)) checkEffects(summary.effs) } - } cls.paramAccessors.foreach { acc => if (!acc.is(Flags.Method)) { @@ -155,16 +158,19 @@ object Checking { } tpl.parents.foreach { - case tree @ Block(_, parent) => - val (ctor, _, _) = decomposeCall(parent) + case tree @ Block(stats, parent) => + val (ctor, _, argss) = decomposeCall(parent) + if theEnv.isFullMode then checkStats((stats :: argss).flatten, cls) checkConstructor(ctor.symbol, parent.tpe, tree) - case tree @ Apply(Block(_, parent), _) => - val (ctor, _, _) = decomposeCall(parent) + case tree @ Apply(Block(stats, parent), args) => + val (ctor, _, argss) = decomposeCall(parent) + if theEnv.isFullMode then checkStats((stats :: argss).flatten, cls) checkConstructor(ctor.symbol, tree.tpe, tree) case parent : Apply => val (ctor, _, argss) = decomposeCall(parent) + if theEnv.isFullMode then checkStats(argss.flatten, cls) checkConstructor(ctor.symbol, parent.tpe, parent) case ref => @@ -203,13 +209,13 @@ object Checking { val errors = state.check(MethodCall(pot, sym)(source)) if errors.nonEmpty then return errors - // if sym.name.isTermName && !sym.isOneOf(Flags.Method | Flags.Private) && sym.hasSource then - // val errors = state.check(Promote(FieldReturn(pot, sym)(source))(source)) - // if errors.nonEmpty then return errors + if sym.name.isTermName && !sym.isOneOf(Flags.Method | Flags.Private) && sym.hasSource then + val errors = state.check(Promote(FieldReturn(pot, sym)(source))(source)) + if errors.nonEmpty then return errors } // best-effort in fast mode - // if !theEnv.isFullMode then return Errors.empty + if !theEnv.isFullMode then return Errors.empty val excludedFlags = Flags.Deferred | Flags.Private | Flags.Protected diff --git a/compiler/test/dotty/tools/dotc/CompilationTests.scala b/compiler/test/dotty/tools/dotc/CompilationTests.scala index cb8a2347b323..9af6e664bf19 100644 --- a/compiler/test/dotty/tools/dotc/CompilationTests.scala +++ b/compiler/test/dotty/tools/dotc/CompilationTests.scala @@ -321,7 +321,6 @@ class CompilationTests { compileFilesInDir("tests/init/neg", options).checkExpectedErrors() compileFilesInDir("tests/init/full/neg", options).checkExpectedErrors() compileFilesInDir("tests/init/pos", options).checkCompile() - compileFilesInDir("tests/init/crash", options.without("-Xfatal-warnings")).checkCompile() } } diff --git a/tests/init/full/neg/global-cycle1.scala b/tests/init/full/neg/global-cycle1.scala new file mode 100644 index 000000000000..ebd667c51ba0 --- /dev/null +++ b/tests/init/full/neg/global-cycle1.scala @@ -0,0 +1,10 @@ +object A { + val a: Int = B.b // error +} + +object B { + val b: Int = A.a // error +} + +@main +def Test = print(A.a) \ No newline at end of file diff --git a/tests/init/neg/hybrid2.scala b/tests/init/full/neg/hybrid2.scala similarity index 100% rename from tests/init/neg/hybrid2.scala rename to tests/init/full/neg/hybrid2.scala diff --git a/tests/init/full/neg/i9176.scala b/tests/init/full/neg/i9176.scala new file mode 100644 index 000000000000..abb8a6394dd2 --- /dev/null +++ b/tests/init/full/neg/i9176.scala @@ -0,0 +1,9 @@ +class Foo(val opposite: Foo) +case object A extends Foo(B) // error +case object B extends Foo(A) // error +object Test { + def main(args: Array[String]): Unit = { + println(A.opposite) + println(B.opposite) + } +} \ No newline at end of file