File tree 7 files changed +59
-19
lines changed
compiler/src/dotty/tools/dotc/transform/init
7 files changed +59
-19
lines changed Original file line number Diff line number Diff line change @@ -1006,6 +1006,19 @@ object Semantic:
1006
1006
}
1007
1007
}
1008
1008
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
+
1009
1022
end extension
1010
1023
1011
1024
extension (thisRef : ThisRef )
@@ -1032,8 +1045,12 @@ object Semantic:
1032
1045
reporter.report(PromoteError (msg, trace.toVector))
1033
1046
1034
1047
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))
1037
1054
1038
1055
case warm : Warm =>
1039
1056
if ! promoted.contains(warm) then
Original file line number Diff line number Diff line change 8
8
| ^^^^^^^^^^^^^^^^^
9
9
|
10
10
| 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:
12
13
| -> l.foreach(a => a.addX(this)) // error [ closureLeak.scala:11 ]
13
14
| ^^^^
Original file line number Diff line number Diff line change 1
1
-- Error: tests/init/neg/default-this.scala:9:8 ------------------------------------------------------------------------
2
2
9 | compare() // error
3
3
| ^^^^^^^
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 1
1
-- Error: tests/init/neg/inlined-method.scala:8:45 ---------------------------------------------------------------------
2
2
8 | scala.runtime.Scala3RunTime.assertFailed(message) // error
3
3
| ^^^^^^^
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 9
9
|
10
10
| Promoting the value to fully initialized failed due to the following problem:
11
11
| 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