Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make sure inner classes are checked first #15527

Merged
merged 2 commits into from
Jun 27, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions compiler/src/dotty/tools/dotc/transform/init/Semantic.scala
Original file line number Diff line number Diff line change
Expand Up @@ -1143,10 +1143,10 @@ object Semantic:
case class Task(value: ThisRef)

class WorkList private[Semantic]():
private var pendingTasks: List[Task] = Nil
private val pendingTasks: mutable.ArrayBuffer[Task] = new mutable.ArrayBuffer

def addTask(task: Task): Unit =
if !pendingTasks.contains(task) then pendingTasks = task :: pendingTasks
if !pendingTasks.contains(task) then pendingTasks.append(task)

/** Process the worklist until done */
final def work()(using Cache, Context): Unit =
Expand Down
24 changes: 12 additions & 12 deletions tests/init/neg/cycle-structure.check
Original file line number Diff line number Diff line change
@@ -1,30 +1,30 @@
-- Error: tests/init/neg/cycle-structure.scala:9:13 --------------------------------------------------------------------
9 | val x = A(this) // error
-- Error: tests/init/neg/cycle-structure.scala:3:13 --------------------------------------------------------------------
3 | val x = B(this) // error
| ^^^^^^^
| Problematic object instantiation: arg 1 is not fully initialized. Calling trace:
| -> case class B(a: A) { [ cycle-structure.scala:7 ]
| -> case class A(b: B) { [ cycle-structure.scala:1 ]
| ^
| -> val x = A(this) // error [ cycle-structure.scala:9 ]
| -> val x = B(this) // error [ cycle-structure.scala:3 ]
| ^^^^^^^
|
| It leads to the following error during object initialization:
| Access field on a value with an unknown initialization status. Calling trace:
| -> case class A(b: B) { [ cycle-structure.scala:1 ]
| -> case class B(a: A) { [ cycle-structure.scala:7 ]
| ^
| -> val x1 = b.x [ cycle-structure.scala:2 ]
| -> val x1 = a.x [ cycle-structure.scala:8 ]
| ^^^
-- Error: tests/init/neg/cycle-structure.scala:3:13 --------------------------------------------------------------------
3 | val x = B(this) // error
-- Error: tests/init/neg/cycle-structure.scala:9:13 --------------------------------------------------------------------
9 | val x = A(this) // error
| ^^^^^^^
| Problematic object instantiation: arg 1 is not fully initialized. Calling trace:
| -> case class A(b: B) { [ cycle-structure.scala:1 ]
| -> case class B(a: A) { [ cycle-structure.scala:7 ]
| ^
| -> val x = B(this) // error [ cycle-structure.scala:3 ]
| -> val x = A(this) // error [ cycle-structure.scala:9 ]
| ^^^^^^^
|
| It leads to the following error during object initialization:
| Access field on a value with an unknown initialization status. Calling trace:
| -> case class B(a: A) { [ cycle-structure.scala:7 ]
| -> case class A(b: B) { [ cycle-structure.scala:1 ]
| ^
| -> val x1 = a.x [ cycle-structure.scala:8 ]
| -> val x1 = b.x [ cycle-structure.scala:2 ]
| ^^^
4 changes: 0 additions & 4 deletions tests/init/neg/inherit-non-hot.check
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,6 @@
6 | if b == null then b = new B(this) // error
| ^^^^^^^^^^^
| The RHS of reassignment must be fully initialized. Calling trace:
| -> object Foo { [ inherit-non-hot.scala:2 ]
| ^
| -> val c = new C [ inherit-non-hot.scala:19 ]
| ^^^^^
| -> class C extends A { [ inherit-non-hot.scala:15 ]
| ^
| -> val bAgain = toB.getBAgain [ inherit-non-hot.scala:16 ]
Expand Down
9 changes: 9 additions & 0 deletions tests/init/neg/inner-first.check
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
-- Error: tests/init/neg/inner-first.scala:3:12 ------------------------------------------------------------------------
3 | println(this) // error
| ^^^^
| Cannot prove the argument is fully initialized. Only fully initialized values are safe to leak.
| Non initialized field(s): value n. Calling trace:
| -> class B: [ inner-first.scala:2 ]
| ^
| -> println(this) // error [ inner-first.scala:3 ]
| ^^^^
7 changes: 7 additions & 0 deletions tests/init/neg/inner-first.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
class A:
class B:
println(this) // error
val n = 10
def foo() = println(m)
new B
val m = 20
44 changes: 19 additions & 25 deletions tests/init/neg/secondary-ctor4.check
Original file line number Diff line number Diff line change
@@ -1,32 +1,26 @@
-- Error: tests/init/neg/secondary-ctor4.scala:54:14 -------------------------------------------------------------------
54 | val c = new C(b, 5) // error
| ^^^^^^^^^^^
| Problematic object instantiation: the outer M.this and arg 1 are not fully initialized. Calling trace:
| -> class N(d: D) extends M(d) { [ secondary-ctor4.scala:59 ]
| ^
| -> def this(d: D) = { [ secondary-ctor4.scala:7 ]
| ^
| -> new A(new B(new D)) // error [ secondary-ctor4.scala:42 ]
| ^^^^^
| -> class D { [ secondary-ctor4.scala:52 ]
| ^
| -> val c = new C(b, 5) // error [ secondary-ctor4.scala:54 ]
| ^^^^^^^^^^^
| Problematic object instantiation: arg 1 is not fully initialized. Calling trace:
| -> class D { [ secondary-ctor4.scala:52 ]
| ^
| -> val c = new C(b, 5) // error [ secondary-ctor4.scala:54 ]
| ^^^^^^^^^^^
|
| It leads to the following error during object initialization:
| Access field on a value with an unknown initialization status. Calling trace:
| -> def this(b: B, x: Int) = this(b) [ secondary-ctor4.scala:49 ]
| ^^^^^^^
| -> class C(b: B) extends A(b) with T { [ secondary-ctor4.scala:48 ]
| ^
| -> def this(b: B) = { [ secondary-ctor4.scala:17 ]
| ^
| -> Inner().foo() [ secondary-ctor4.scala:26 ]
| ^^^^^^^
| -> class Inner() { [ secondary-ctor4.scala:21 ]
| ^
| -> println(b.n) [ secondary-ctor4.scala:23 ]
| ^^^
| It leads to the following error during object initialization:
| Access field on a value with an unknown initialization status. Calling trace:
| -> def this(b: B, x: Int) = this(b) [ secondary-ctor4.scala:49 ]
| ^^^^^^^
| -> class C(b: B) extends A(b) with T { [ secondary-ctor4.scala:48 ]
| ^
| -> def this(b: B) = { [ secondary-ctor4.scala:17 ]
| ^
| -> Inner().foo() [ secondary-ctor4.scala:26 ]
| ^^^^^^^
| -> class Inner() { [ secondary-ctor4.scala:21 ]
| ^
| -> println(b.n) [ secondary-ctor4.scala:23 ]
| ^^^
-- Error: tests/init/neg/secondary-ctor4.scala:42:4 --------------------------------------------------------------------
42 | new A(new B(new D)) // error
| ^^^^^^^^^^^^^^^^^^^
Expand Down