Skip to content

Commit

Permalink
Merge pull request #15584 from dotty-staging/fix-init-error
Browse files Browse the repository at this point in the history
Underline assignment correctly in error message
  • Loading branch information
olhotak authored Jul 8, 2022
2 parents ae83f76 + 675fcb1 commit 80f67df
Show file tree
Hide file tree
Showing 6 changed files with 49 additions and 53 deletions.
36 changes: 25 additions & 11 deletions compiler/src/dotty/tools/dotc/transform/init/Semantic.scala
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,17 @@ object Semantic:
*
*/
sealed abstract class Value:
def show: String = this.toString()
def show(using Context): String = this match
case ThisRef(klass) =>
"ThisRef[" + klass.show + "]"
case Warm(klass, outer, ctor, args) =>
"Warm[" + klass.show + "] { outer = " + outer.show + ", args = " + args.map(_.show).mkString("(", ", ", ")") + " }"
case Fun(expr, thisV, klass) =>
"Fun { this = " + thisV.show + ", owner = " + klass.show + " }"
case RefSet(values) =>
values.map(_.show).mkString("Set { ", ", ", " }")
case _ =>
this.toString()

def isHot = this == Hot
def isCold = this == Cold
Expand Down Expand Up @@ -792,8 +802,11 @@ object Semantic:
else
// no source code available
promoteArgs()
val error = CallUnknown(target, trace.toVector)
reporter.report(error)
// try promoting the receiver as last resort
val hasErrors = Reporter.hasErrors { ref.promote("try promote value to hot") }
if hasErrors then
val error = CallUnknown(target, trace.toVector)
reporter.report(error)
Hot
else
// method call resolves to a field
Expand Down Expand Up @@ -1036,9 +1049,9 @@ object Semantic:
extension (value: Value)
/** Promotion of values to hot */
def promote(msg: String): Contextual[Unit] = log("promoting " + value + ", promoted = " + promoted, printer) {
if promoted.isCurrentObjectPromoted then Nil else
if !promoted.isCurrentObjectPromoted then

value.match
value match
case Hot =>

case Cold =>
Expand Down Expand Up @@ -1099,8 +1112,9 @@ object Semantic:
*/
def tryPromote(msg: String): Contextual[List[Error]] = log("promote " + warm.show + ", promoted = " + promoted, printer) {
val classRef = warm.klass.appliedRef
if classRef.memberClasses.nonEmpty || !warm.isFullyFilled then
return PromoteError(msg, trace.toVector) :: Nil
val hasInnerClass = classRef.memberClasses.filter(_.symbol.hasSource).nonEmpty
if hasInnerClass then
return PromoteError(msg + "Promotion cancelled as the value contains inner classes. ", trace.toVector) :: Nil

val errors = Reporter.stopEarly {
for klass <- warm.klass.baseClasses if klass.hasSource do
Expand Down Expand Up @@ -1352,13 +1366,13 @@ object Semantic:
case Select(qual, _) =>
eval(qual, thisV, klass)
val res = eval(rhs, thisV, klass)
extendTrace(rhs) {
res.ensureHot("The RHS of reassignment must be fully initialized.")
extendTrace(expr) {
res.ensureHot("The RHS of reassignment must be fully initialized. Found = " + res.show + ". ")
}
case id: Ident =>
val res = eval(rhs, thisV, klass)
extendTrace(rhs) {
res.ensureHot("The RHS of reassignment must be fully initialized.")
extendTrace(expr) {
res.ensureHot("The RHS of reassignment must be fully initialized. Found = " + res.show + ". ")
}

case closureDef(ddef) =>
Expand Down
4 changes: 2 additions & 2 deletions tests/init/neg/apply2.scala
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ object O:
println(n)

class B:
val a = A(this) // error
val a = A(this)

val b = new B
val n = 10
val n = 10 // error
end O
26 changes: 13 additions & 13 deletions tests/init/neg/inherit-non-hot.check
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
-- Error: tests/init/neg/inherit-non-hot.scala:6:34 --------------------------------------------------------------------
-- Error: tests/init/neg/inherit-non-hot.scala:6:32 --------------------------------------------------------------------
6 | if b == null then b = new B(this) // error
| ^^^^^^^^^^^
| The RHS of reassignment must be fully initialized. Calling trace:
| -> class C extends A { [ inherit-non-hot.scala:15 ]
| ^
| -> val bAgain = toB.getBAgain [ inherit-non-hot.scala:16 ]
| ^^^
| -> def toB: B = [ inherit-non-hot.scala:5 ]
| ^
| -> if b == null then b = new B(this) // error [ inherit-non-hot.scala:6 ]
| ^^^^^^^^^^^
| ^^^^^^^^^^^^^^^
|The RHS of reassignment must be fully initialized. Found = Warm[class B] { outer = Hot, args = (Cold) }. Calling trace:
|-> class C extends A { [ inherit-non-hot.scala:15 ]
| ^
|-> val bAgain = toB.getBAgain [ inherit-non-hot.scala:16 ]
| ^^^
|-> def toB: B = [ inherit-non-hot.scala:5 ]
| ^
|-> if b == null then b = new B(this) // error [ inherit-non-hot.scala:6 ]
| ^^^^^^^^^^^^^^^
|
| Promoting the value to fully initialized failed due to the following problem:
| Cannot prove that the field val a is fully initialized.
|Promoting the value to fully initialized failed due to the following problem:
|Cannot prove that the field val a is fully initialized.
26 changes: 0 additions & 26 deletions tests/init/neg/local-warm4.check

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ object localWarm {
override def increment(): Unit = {
def updateA(): Unit = {
val newA = new A(y)
a = newA // error
a = newA // ok: newA can be promoted to hot
}
y = y + 1
updateA()
Expand Down
8 changes: 8 additions & 0 deletions tests/init/pos/patternMatcher.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import scala.collection.mutable

class Translater:
val count = new mutable.HashMap[Int, Int] {
override def default(key: Int) = 0
}
count.get(10)
val n = 10

0 comments on commit 80f67df

Please sign in to comment.