File tree Expand file tree Collapse file tree 7 files changed +59
-19
lines changed
compiler/src/dotty/tools/dotc/transform/init Expand file tree Collapse file tree 7 files changed +59
-19
lines changed Original file line number Diff line number Diff line change @@ -1006,6 +1006,19 @@ object Semantic:
10061006 }
10071007 }
10081008
1009+ def nonInitFields (): Contextual [List [Symbol ]] =
1010+ val obj = ref.objekt
1011+ ref.klass.baseClasses.flatMap { klass =>
1012+ if klass.hasSource then
1013+ klass.info.decls.filter { member =>
1014+ ! member.isOneOf(Flags .Method | Flags .Lazy | Flags .Deferred )
1015+ && ! member.isType
1016+ && ! obj.hasField(member)
1017+ }
1018+ else
1019+ Nil
1020+ }
1021+
10091022 end extension
10101023
10111024 extension (thisRef : ThisRef )
@@ -1032,8 +1045,12 @@ object Semantic:
10321045 reporter.report(PromoteError (msg, trace.toVector))
10331046
10341047 case thisRef : ThisRef =>
1035- if ! thisRef.tryPromoteCurrentObject() then
1036- reporter.report(PromoteError (msg, trace.toVector))
1048+ val emptyFields = thisRef.nonInitFields()
1049+ if emptyFields.isEmpty then
1050+ promoted.promoteCurrent(thisRef)
1051+ else
1052+ val fields = " Non initialized field(s): " + emptyFields.map(_.show).mkString(" , " ) + " ."
1053+ reporter.report(PromoteError (msg + " \n " + fields, trace.toVector))
10371054
10381055 case warm : Warm =>
10391056 if ! promoted.contains(warm) then
Original file line number Diff line number Diff line change 88 | ^^^^^^^^^^^^^^^^^
99 |
1010 | Promoting the value to fully initialized failed due to the following problem:
11- | Cannot prove the argument is fully initialized. Only fully initialized values are safe to leak. Calling trace:
11+ | Cannot prove the argument is fully initialized. Only fully initialized values are safe to leak.
12+ | Non initialized field(s): value p. Calling trace:
1213 | -> l.foreach(a => a.addX(this)) // error [ closureLeak.scala:11 ]
1314 | ^^^^
Original file line number Diff line number Diff line change 11-- Error: tests/init/neg/default-this.scala:9:8 ------------------------------------------------------------------------
229 | compare() // error
33 | ^^^^^^^
4- | Cannot prove the argument is fully initialized. Only fully initialized values are safe to leak. Calling trace:
5- | -> class B extends A { [ default-this.scala:6 ]
6- | ^
7- | -> val result = updateThenCompare(5) [ default-this.scala:11 ]
8- | ^^^^^^^^^^^^^^^^^^^^
9- | -> def updateThenCompare(c: Int): Boolean = { [ default-this.scala:7 ]
10- | ^
11- | -> compare() // error [ default-this.scala:9 ]
12- | ^^^^^^^
4+ | Cannot prove the argument is fully initialized. Only fully initialized values are safe to leak.
5+ | Non initialized field(s): value result. Calling trace:
6+ | -> class B extends A { [ default-this.scala:6 ]
7+ | ^
8+ | -> val result = updateThenCompare(5) [ default-this.scala:11 ]
9+ | ^^^^^^^^^^^^^^^^^^^^
10+ | -> def updateThenCompare(c: Int): Boolean = { [ default-this.scala:7 ]
11+ | ^
12+ | -> compare() // error [ default-this.scala:9 ]
13+ | ^^^^^^^
Original file line number Diff line number Diff line change 1+ -- Error: tests/init/neg/i15459.scala:3:10 -----------------------------------------------------------------------------
2+ 3 | println(this) // error
3+ | ^^^^
4+ | Cannot prove the argument is fully initialized. Only fully initialized values are safe to leak.
5+ | Non initialized field(s): value b. Calling trace:
6+ | -> class Sub extends Sup: [ i15459.scala:5 ]
7+ | ^
8+ | -> class Sup: [ i15459.scala:1 ]
9+ | ^
10+ | -> println(this) // error [ i15459.scala:3 ]
11+ | ^^^^
Original file line number Diff line number Diff line change 1+ class Sup :
2+ val a = 10
3+ println(this ) // error
4+
5+ class Sub extends Sup :
6+ val b = 20
7+
8+ override def toString () = " a = " + a + " , b = " + b
Original file line number Diff line number Diff line change 11-- Error: tests/init/neg/inlined-method.scala:8:45 ---------------------------------------------------------------------
228 | scala.runtime.Scala3RunTime.assertFailed(message) // error
33 | ^^^^^^^
4- | Cannot prove the argument is fully initialized. Only fully initialized values are safe to leak. Calling trace:
5- | -> class InlineError { [ inlined-method.scala:1 ]
6- | ^
7- | -> Assertion.failAssert(this) [ inlined-method.scala:2 ]
8- | ^^^^^^^^^^^^^^^^^^^^^^^^^^
9- | -> scala.runtime.Scala3RunTime.assertFailed(message) // error [ inlined-method.scala:8 ]
10- | ^^^^^^^
4+ | Cannot prove the argument is fully initialized. Only fully initialized values are safe to leak.
5+ | Non initialized field(s): value v. Calling trace:
6+ | -> class InlineError { [ inlined-method.scala:1 ]
7+ | ^
8+ | -> Assertion.failAssert(this) [ inlined-method.scala:2 ]
9+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^
10+ | -> scala.runtime.Scala3RunTime.assertFailed(message) // error [ inlined-method.scala:8 ]
11+ | ^^^^^^^
Original file line number Diff line number Diff line change 99 |
1010 | Promoting the value to fully initialized failed due to the following problem:
1111 | Cannot prove that the field val outer is fully initialized.
12+ | Non initialized field(s): value n.
You can’t perform that action at this time.
0 commit comments