Skip to content

Commit 4dc8b49

Browse files
committed
Add error reporting
1 parent ab2e265 commit 4dc8b49

File tree

2 files changed

+43
-33
lines changed

2 files changed

+43
-33
lines changed

compiler/src/dotty/tools/dotc/transform/init/Checking.scala

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,10 @@ object Checking {
140140

141141
private def checkEffectsIn(effs: Effects, cls: ClassSymbol)(implicit state: State): Unit = {
142142
val rebased = Effects.asSeenFrom(effs, ThisRef(state.thisClass)(null), cls, Potentials.empty)
143-
rebased.foreach { check(_) }
143+
for {
144+
eff <- rebased
145+
error <- check(eff)
146+
} error.report
144147
}
145148

146149
private def check(eff: Effect)(implicit state: State): Errors =
@@ -162,8 +165,11 @@ object Checking {
162165

163166
case Fun(pots, effs) =>
164167
val errs1 = effs.flatMap { check(_) }
165-
val errs2 = pots.flatMap { pot => check(Promote(pot)(eff.source)) }
166-
UnsafePromotion(pot, eff.source, state.path, errs1 ++ errs2).toErrors
168+
val errs2 = pots.flatMap { pot => check(Promote(pot)(eff.source))(state.copy(path = Vector.empty)) }
169+
if (errs1.nonEmpty || errs2.nonEmpty)
170+
UnsafePromotion(pot, eff.source, state.path, errs1 ++ errs2).toErrors
171+
else
172+
Errors.empty
167173

168174
case pot =>
169175
val pots = expand(pot)

compiler/src/dotty/tools/dotc/transform/init/Errors.scala

Lines changed: 34 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import ast.tpd._
77
import core._
88
import Decorators._
99
import Types._, Symbols._, Contexts._
10+
import util.NoSourcePosition
1011

1112
import Effects._, Potentials._
1213

@@ -18,13 +19,16 @@ object Errors {
1819
errs.map(_.show).mkString(", ")
1920

2021
sealed trait Error {
22+
def source: Tree
2123
def trace: Vector[Tree]
22-
def report(implicit ctx: Context): Unit
2324
def show(implicit ctx: Context): String
2425

26+
def report(implicit ctx: Context): Unit =
27+
ctx.warning(show + " Calling trace:\n" + stacktrace, source.sourcePos)
28+
2529
def toErrors: Errors = Set(this)
2630

27-
def stacktrace(implicit ctx: Context): String = {
31+
def stacktrace(implicit ctx: Context): String = if (trace.isEmpty) "" else " Calling trace:\n" + {
2832
var indentCount = 0
2933
var last = ""
3034
val sb = new StringBuilder
@@ -43,68 +47,68 @@ object Errors {
4347
}
4448
sb.toString
4549
}
50+
51+
/** Flatten UnsafePromotion errors
52+
*/
53+
def flatten: Errors = this match {
54+
case unsafe: UnsafePromotion => unsafe.errors.flatMap(_.flatten)
55+
case _ => Set(this)
56+
}
4657
}
4758

4859
/** Access non-initialized field */
4960
case class AccessNonInit(field: Symbol, trace: Vector[Tree]) extends Error {
61+
def source: Tree = trace.last
5062
def show(implicit ctx: Context): String =
51-
"Access non-initialized field " + field.show + ". Calling trace:\n" + stacktrace
63+
"Access non-initialized field " + field.show + "."
5264

53-
def report(implicit ctx: Context): Unit = ???
65+
override def report(implicit ctx: Context): Unit = ctx.error(show + stacktrace, field.sourcePos)
5466
}
5567

5668
/** Promote `this` under initialization to fully-initialized */
5769
case class PromoteThis(pot: ThisRef, source: Tree, trace: Vector[Tree]) extends Error {
58-
def show(implicit ctx: Context): String = "Promote `this` to be initialized while it is not. Calling trace:\n" + stacktrace
59-
def report(implicit ctx: Context): Unit = ???
70+
def show(implicit ctx: Context): String = "Promote `this` to be initialized while it is not."
6071
}
6172

6273
/** Promote `this` under initialization to fully-initialized */
6374
case class PromoteWarm(pot: Warm, source: Tree, trace: Vector[Tree]) extends Error {
6475
def show(implicit ctx: Context): String =
65-
"Promoting the value under initialization to be initialized: " + source.show +
66-
". Calling trace:\n" + stacktrace
67-
68-
def report(implicit ctx: Context): Unit = ???
76+
"Promoting the value under initialization to be initialized: " + source.show + "."
6977
}
7078

7179
/** Promote a cold value under initialization to fully-initialized */
7280
case class PromoteCold(source: Tree, trace: Vector[Tree]) extends Error {
7381
def show(implicit ctx: Context): String =
74-
"Promoting the value " + source.show + " to be initialized while it is under initialization" +
75-
". Calling trace:\n" + stacktrace
76-
77-
def report(implicit ctx: Context): Unit = ???
82+
"Promoting the value " + source.show + " to be initialized while it is under initialization" + "."
7883
}
7984

8085
case class AccessCold(field: Symbol, source: Tree, trace: Vector[Tree]) extends Error {
8186
def show(implicit ctx: Context): String =
82-
"Access field " + source.show + " on a value under unknown initialization status" +
83-
". Calling trace:\n" + stacktrace
84-
85-
def report(implicit ctx: Context): Unit = ???
87+
"Access field " + source.show + " on a value under unknown initialization status" + "."
8688
}
8789

8890
case class CallCold(meth: Symbol, source: Tree, trace: Vector[Tree]) extends Error {
8991
def show(implicit ctx: Context): String =
90-
"Call method " + source.show + " on a value under unknown initialization" +
91-
". Calling trace:\n" + stacktrace
92-
93-
def report(implicit ctx: Context): Unit = ???
92+
"Call method " + source.show + " on a value under unknown initialization" + "."
9493
}
9594

9695
case class CallUnknown(meth: Symbol, source: Tree, trace: Vector[Tree]) extends Error {
9796
def show(implicit ctx: Context): String =
98-
"Calling the external method " + meth.show +
99-
" may cause initialization errors" + ". Calling trace:\n" + stacktrace
100-
101-
def report(implicit ctx: Context): Unit = ???
97+
"Calling the external method " + meth.show + " may cause initialization errors" + "."
10298
}
10399

104100
/** Promote a value under initialization to fully-initialized */
105-
case class UnsafePromotion(pot: Potential, source: Tree, trace: Vector[Tree], errors: Set[Error]) extends Error {
106-
def show(implicit ctx: Context): String = ???
107-
108-
def report(implicit ctx: Context): Unit = ???
101+
case class UnsafePromotion(pot: Potential, source: Tree, trace: Vector[Tree], errors: Errors) extends Error {
102+
assert(errors.nonEmpty)
103+
104+
def show(implicit ctx: Context): String = {
105+
var index = 0
106+
"Promoting the value " + source.show + " to initialized is unsafe.\n" + stacktrace +
107+
"\n The unsafe promotion is caused by the following problem(s):" +
108+
errors.map { error =>
109+
index += 1
110+
s"\n $index" + error.show + error.stacktrace
111+
}.mkString
112+
}
109113
}
110114
}

0 commit comments

Comments
 (0)