From cb5433cb05e1e70602062090b418f930d3cc8b7a Mon Sep 17 00:00:00 2001 From: David Hua Date: Mon, 13 Nov 2023 02:09:50 +0100 Subject: [PATCH 1/4] Make init checker skip global objects --- compiler/src/dotty/tools/dotc/transform/init/Semantic.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/src/dotty/tools/dotc/transform/init/Semantic.scala b/compiler/src/dotty/tools/dotc/transform/init/Semantic.scala index 499c2d289783..caf3435608d2 100644 --- a/compiler/src/dotty/tools/dotc/transform/init/Semantic.scala +++ b/compiler/src/dotty/tools/dotc/transform/init/Semantic.scala @@ -1140,7 +1140,7 @@ object Semantic: */ def checkClasses(classes: List[ClassSymbol])(using Context): Unit = given Cache.Data() - for classSym <- classes if isConcreteClass(classSym) do + for classSym <- classes if isConcreteClass(classSym) && !classSym.isStaticObject do checkClass(classSym) // ----- Semantic definition -------------------------------- From 10c4e9178f83e688e191a44879bc499c40be96e7 Mon Sep 17 00:00:00 2001 From: David Hua Date: Mon, 13 Nov 2023 02:31:22 +0100 Subject: [PATCH 2/4] Fix init checking tests to use classes instead of objects --- tests/init/neg/apply2.scala | 2 +- tests/init/neg/final-fields.scala | 10 +++++----- tests/init/neg/i12544.scala | 25 +++++++++++++++---------- tests/init/neg/i15883.scala | 6 ++++-- tests/init/neg/i4031.scala | 2 +- tests/init/neg/inner30.scala | 2 +- tests/init/neg/inner9.scala | 31 +++++++++++++++++-------------- tests/init/neg/leak-warm.check | 2 +- tests/init/neg/leak-warm.scala | 2 +- tests/init/neg/t3273.check | 8 ++++---- tests/init/neg/t3273.scala | 2 +- 11 files changed, 51 insertions(+), 41 deletions(-) diff --git a/tests/init/neg/apply2.scala b/tests/init/neg/apply2.scala index c6c7fe5fedd2..ea312ac6e8c7 100755 --- a/tests/init/neg/apply2.scala +++ b/tests/init/neg/apply2.scala @@ -1,4 +1,4 @@ -object O: +class O: case class A(b: B): println(n) diff --git a/tests/init/neg/final-fields.scala b/tests/init/neg/final-fields.scala index 174ee9eeb79d..7154673058b7 100644 --- a/tests/init/neg/final-fields.scala +++ b/tests/init/neg/final-fields.scala @@ -12,14 +12,14 @@ trait U { val f2: Int } -object Test0 extends U { +class Test0 extends U { final val f1 = 1 final val f2 = 2 final val f3 = f1 + f2 val f4: 3 = f3 } -object Test1 extends U { +class Test1 extends U { final val f1 = 1 final val f3 = f1 + f2 final val f2 = 2 @@ -28,7 +28,7 @@ object Test1 extends U { } -object Test extends T { +class Test extends T { override final val f1 = /*super.f1*/ 1 + f2 // error override final val f2 = 2 // error override final val f3 = {println(3); 3} // error @@ -37,7 +37,7 @@ object Test extends T { def g: 3 = { println("g"); 3 } final val x = g + 1 def main(args: Array[String]): Unit = { - Test0 - Test1 + new Test0 + new Test1 } } diff --git a/tests/init/neg/i12544.scala b/tests/init/neg/i12544.scala index 2692c27134e0..2cc35b12a7c2 100644 --- a/tests/init/neg/i12544.scala +++ b/tests/init/neg/i12544.scala @@ -2,18 +2,23 @@ enum Enum: case Case case Case2(x: Int) -def g(b: Enum.B): Int = b.foo() +class Outer: + val e = new Enum2 // error + def g(b: e.B): Int = b.foo() -object Enum: - object nested: - val a: Enum = Case + class Enum2: + class nested: + val a: Enum = Enum.Case - val b: Enum = f(nested.a) + val b: Enum = f((new nested).a) - def f(e: Enum): Enum = e + def f(e: Enum): Enum = e - class B() { def foo() = n + 1 } - g(new B()) // error - val n: Int = 10 + class B() { def foo() = n + 1 } + g(new e.B()) + val n: Int = 10 -@main def main(): Unit = println(Enum.b) +@main def main(): Unit = { + val o = new Outer + print(o.e.b) +} diff --git a/tests/init/neg/i15883.scala b/tests/init/neg/i15883.scala index 6f6e3066a878..880ba457e18e 100644 --- a/tests/init/neg/i15883.scala +++ b/tests/init/neg/i15883.scala @@ -1,2 +1,4 @@ -val a = b -val b = 1 // error +class A { + val a = b + val b = 1 // error +} diff --git a/tests/init/neg/i4031.scala b/tests/init/neg/i4031.scala index 8340296340e7..ed3f18ac931a 100644 --- a/tests/init/neg/i4031.scala +++ b/tests/init/neg/i4031.scala @@ -1,4 +1,4 @@ -object App { +class App { trait A { type L >: Any} def upcast(a: A, x: Any): a.L = x val p: A { type L <: Nothing } = p // error diff --git a/tests/init/neg/inner30.scala b/tests/init/neg/inner30.scala index 01bb5754d485..87d8888437da 100644 --- a/tests/init/neg/inner30.scala +++ b/tests/init/neg/inner30.scala @@ -1,4 +1,4 @@ -object Scanners { +class Scanners { enum IndentWidth { case Run(ch: Char, n: Int) case Conc(l: IndentWidth, r: Run) diff --git a/tests/init/neg/inner9.scala b/tests/init/neg/inner9.scala index db5198ea0138..b572c8cb49d3 100644 --- a/tests/init/neg/inner9.scala +++ b/tests/init/neg/inner9.scala @@ -1,20 +1,23 @@ -object Flags { - class Inner { - println(b) - } +class Outer: + val flags = new Flags // error - new Flags.Inner + class Flags { + class Inner { + println(b) + } - val a = this.b + 3 - val b = 5 // error -} + new flags.Inner -object Flags2 { - class Inner { - println(b) + val a = this.b + 3 + val b = 5 // error } + class Flags2 { + class Inner { + println(b) + } + - lazy val a = 3 - val b = 5 -} + lazy val a = 3 + val b = 5 + } diff --git a/tests/init/neg/leak-warm.check b/tests/init/neg/leak-warm.check index c2fc561a3668..851285514281 100644 --- a/tests/init/neg/leak-warm.check +++ b/tests/init/neg/leak-warm.check @@ -2,7 +2,7 @@ 19 | val l2 = l.map(_.m()) // error | ^^^^^^^^^^^^ | Call method method map on an uninitialized (Cold) object. Calling trace: - | -> object leakWarm { [ leak-warm.scala:1 ] + | -> class leakWarm { [ leak-warm.scala:1 ] | ^ | -> val l2 = l.map(_.m()) // error [ leak-warm.scala:19 ] | ^^^^^^^^^^^^ diff --git a/tests/init/neg/leak-warm.scala b/tests/init/neg/leak-warm.scala index bc5539ce9c0b..9bfbe2e4f285 100644 --- a/tests/init/neg/leak-warm.scala +++ b/tests/init/neg/leak-warm.scala @@ -1,4 +1,4 @@ -object leakWarm { +class leakWarm { abstract class A(tag: Int) { class B(x: Int) { val y = x diff --git a/tests/init/neg/t3273.check b/tests/init/neg/t3273.check index 0fe7ea78871c..a6a494215803 100644 --- a/tests/init/neg/t3273.check +++ b/tests/init/neg/t3273.check @@ -1,8 +1,8 @@ -- Error: tests/init/neg/t3273.scala:4:42 ------------------------------------------------------------------------------ 4 | val num1: LazyList[Int] = 1 #:: num1.map(_ + 1) // error | ^^^^^^^^^^^^^^^ - |Could not verify that the method argument is transitively initialized (Hot). It was found to be a function where "this" is (the original object of type (object Test) where initialization checking started). Only transitively initialized arguments may be passed to methods (except constructors). Calling trace: - |-> object Test { [ t3273.scala:3 ] + |Could not verify that the method argument is transitively initialized (Hot). It was found to be a function where "this" is (the original object of type (class Test) where initialization checking started). Only transitively initialized arguments may be passed to methods (except constructors). Calling trace: + |-> class Test { [ t3273.scala:3 ] | ^ |-> val num1: LazyList[Int] = 1 #:: num1.map(_ + 1) // error [ t3273.scala:4 ] | ^^^^^^^^^^^^^^^ @@ -14,8 +14,8 @@ -- Error: tests/init/neg/t3273.scala:5:61 ------------------------------------------------------------------------------ 5 | val num2: LazyList[Int] = 1 #:: num2.iterator.map(_ + 1).to(LazyList) // error | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - |Could not verify that the method argument is transitively initialized (Hot). It was found to be a function where "this" is (the original object of type (object Test) where initialization checking started). Only transitively initialized arguments may be passed to methods (except constructors). Calling trace: - |-> object Test { [ t3273.scala:3 ] + |Could not verify that the method argument is transitively initialized (Hot). It was found to be a function where "this" is (the original object of type (class Test) where initialization checking started). Only transitively initialized arguments may be passed to methods (except constructors). Calling trace: + |-> class Test { [ t3273.scala:3 ] | ^ |-> val num2: LazyList[Int] = 1 #:: num2.iterator.map(_ + 1).to(LazyList) // error [ t3273.scala:5 ] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/init/neg/t3273.scala b/tests/init/neg/t3273.scala index 141e544bdfeb..af1df70c471e 100644 --- a/tests/init/neg/t3273.scala +++ b/tests/init/neg/t3273.scala @@ -1,6 +1,6 @@ import scala.language.implicitConversions -object Test { +class Test { val num1: LazyList[Int] = 1 #:: num1.map(_ + 1) // error val num2: LazyList[Int] = 1 #:: num2.iterator.map(_ + 1).to(LazyList) // error From de96b5b1f199cdbb1eab3e4ef0b5274450830644 Mon Sep 17 00:00:00 2001 From: David Hua Date: Sun, 19 Nov 2023 20:21:53 +0100 Subject: [PATCH 3/4] Move test case --- tests/init-global/neg/i15883.scala | 2 ++ tests/init/neg/i15883.scala | 4 ---- 2 files changed, 2 insertions(+), 4 deletions(-) create mode 100644 tests/init-global/neg/i15883.scala delete mode 100644 tests/init/neg/i15883.scala diff --git a/tests/init-global/neg/i15883.scala b/tests/init-global/neg/i15883.scala new file mode 100644 index 000000000000..80051c13b92b --- /dev/null +++ b/tests/init-global/neg/i15883.scala @@ -0,0 +1,2 @@ +val a = b // error +val b = 1 diff --git a/tests/init/neg/i15883.scala b/tests/init/neg/i15883.scala deleted file mode 100644 index 880ba457e18e..000000000000 --- a/tests/init/neg/i15883.scala +++ /dev/null @@ -1,4 +0,0 @@ -class A { - val a = b - val b = 1 // error -} From e493494bc3df248dc3e940253301de62d01fa270 Mon Sep 17 00:00:00 2001 From: David Hua Date: Mon, 20 Nov 2023 15:30:01 +0100 Subject: [PATCH 4/4] Adjust negative test case --- tests/init/neg/i12544.scala | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/init/neg/i12544.scala b/tests/init/neg/i12544.scala index 2cc35b12a7c2..695e57e1d42a 100644 --- a/tests/init/neg/i12544.scala +++ b/tests/init/neg/i12544.scala @@ -3,8 +3,7 @@ enum Enum: case Case2(x: Int) class Outer: - val e = new Enum2 // error - def g(b: e.B): Int = b.foo() + val e = new Enum2 class Enum2: class nested: @@ -15,7 +14,8 @@ class Outer: def f(e: Enum): Enum = e class B() { def foo() = n + 1 } - g(new e.B()) + def g(b: B): Int = b.foo() + g(new B()) // error val n: Int = 10 @main def main(): Unit = {