@@ -9,26 +9,21 @@ import util.SourcePosition
9
9
import Decorators ._ , printing .SyntaxHighlighting
10
10
import Types ._ , Symbols ._ , Contexts ._
11
11
12
- object Errors {
13
- type Errors = Seq [Error ]
14
- val empty : Errors = Nil
15
-
16
- def show (errs : Errors )(using Context ): String =
17
- errs.map(_.show).mkString(" , " )
12
+ import scala .collection .mutable
18
13
14
+ object Errors :
19
15
sealed trait Error {
20
- def source : Tree
21
16
def trace : Seq [Tree ]
22
17
def show (using Context ): String
23
18
24
- def issue (using Context ): Unit =
25
- report.warning(show + stacktrace, source.srcPos)
19
+ def pos (using Context ): SourcePosition = trace.last.sourcePos
26
20
27
- def toErrors : Errors = this :: Nil
21
+ def issue (using Context ): Unit =
22
+ report.warning(show + stacktrace, this .pos)
28
23
29
- def stacktrace (using Context ): String = if ( trace.isEmpty) " " else " Calling trace:\n " + {
30
- var last : String = " "
31
- val sb = new StringBuilder
24
+ def stacktrace (using Context ): String = if trace.isEmpty then " " else " Calling trace:\n " + {
25
+ var lastLineNum = - 1
26
+ var lines : mutable. ArrayBuffer [ String ] = new mutable. ArrayBuffer
32
27
trace.foreach { tree =>
33
28
val pos = tree.sourcePos
34
29
val prefix = " -> "
@@ -44,10 +39,16 @@ object Errors {
44
39
positionMarker(pos)
45
40
else " "
46
41
47
- if (last != line) sb.append(prefix + line + " \n " + positionMarkerLine )
42
+ // always use the more precise trace location
43
+ if lastLineNum == pos.line then
44
+ lines.dropRightInPlace(1 )
48
45
49
- last = line
46
+ lines += (prefix + line + " \n " + positionMarkerLine)
47
+
48
+ lastLineNum = pos.line
50
49
}
50
+ val sb = new StringBuilder
51
+ for line <- lines do sb.append(line)
51
52
sb.toString
52
53
}
53
54
@@ -65,13 +66,6 @@ object Errors {
65
66
s " $padding$carets\n "
66
67
}
67
68
68
- /** Flatten UnsafePromotion errors
69
- */
70
- def flatten : Errors = this match {
71
- case unsafe : UnsafePromotion => unsafe.errors.flatMap(_.flatten)
72
- case _ => this :: Nil
73
- }
74
-
75
69
override def toString () = this .getClass.getName.nn
76
70
}
77
71
@@ -81,42 +75,37 @@ object Errors {
81
75
def show (using Context ): String =
82
76
" Access non-initialized " + field.show + " ."
83
77
84
- override def issue (using Context ): Unit =
85
- report.warning(show + stacktrace, field.srcPos)
78
+ override def pos (using Context ): SourcePosition = field.sourcePos
86
79
}
87
80
88
- /** Promote `this` under initialization to fully-initialized */
89
- case class PromoteError (msg : String , source : Tree , trace : Seq [Tree ]) extends Error {
90
- def show (using Context ): String = " Cannot prove that the value is fully initialized. " + msg + " . "
81
+ /** Promote a value under initialization to fully-initialized */
82
+ case class PromoteError (msg : String , trace : Seq [Tree ]) extends Error {
83
+ def show (using Context ): String = msg
91
84
}
92
85
93
- case class AccessCold (field : Symbol , source : Tree , trace : Seq [Tree ]) extends Error {
86
+ case class AccessCold (field : Symbol , trace : Seq [Tree ]) extends Error {
94
87
def show (using Context ): String =
95
- " Access field " + source.show + " on a value with an unknown initialization status."
88
+ " Access field on a value with an unknown initialization status."
96
89
}
97
90
98
- case class CallCold (meth : Symbol , source : Tree , trace : Seq [Tree ]) extends Error {
91
+ case class CallCold (meth : Symbol , trace : Seq [Tree ]) extends Error {
99
92
def show (using Context ): String =
100
- " Call method " + source.show + " on a value with an unknown initialization" + " ."
93
+ " Call method on a value with an unknown initialization" + " ."
101
94
}
102
95
103
- case class CallUnknown (meth : Symbol , source : Tree , trace : Seq [Tree ]) extends Error {
96
+ case class CallUnknown (meth : Symbol , trace : Seq [Tree ]) extends Error {
104
97
def show (using Context ): String =
105
98
val prefix = if meth.is(Flags .Method ) then " Calling the external method " else " Accessing the external field"
106
99
prefix + meth.show + " may cause initialization errors" + " ."
107
100
}
108
101
109
102
/** Promote a value under initialization to fully-initialized */
110
- case class UnsafePromotion (msg : String , source : Tree , trace : Seq [Tree ], errors : Errors ) extends Error {
111
- assert(errors.nonEmpty)
103
+ case class UnsafePromotion (msg : String , trace : Seq [Tree ], error : Error ) extends Error {
112
104
override def issue (using Context ): Unit =
113
- report.warning(show, source.srcPos )
105
+ report.warning(show, this .pos )
114
106
115
- def show (using Context ): String = {
116
- var index = 0
117
- " Cannot prove that the value is fully initialized. " + msg + " .\n " + stacktrace +
118
- " \n The unsafe promotion may cause the following problem:\n " +
119
- errors.head.show + errors.head.stacktrace
120
- }
107
+ def show (using Context ): String =
108
+ msg + stacktrace + " \n " +
109
+ " Promoting the value to fully initialized failed due to the following problem:\n " +
110
+ error.show + error.stacktrace
121
111
}
122
- }
0 commit comments