@@ -9,26 +9,21 @@ import util.SourcePosition
99import Decorators ._ , printing .SyntaxHighlighting
1010import Types ._ , Symbols ._ , Contexts ._
1111
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
1813
14+ object Errors :
1915 sealed trait Error {
20- def source : Tree
2116 def trace : Seq [Tree ]
2217 def show (using Context ): String
2318
24- def issue (using Context ): Unit =
25- report.warning(show + stacktrace, source.srcPos)
19+ def pos (using Context ): SourcePosition = trace.last.sourcePos
2620
27- def toErrors : Errors = this :: Nil
21+ def issue (using Context ): Unit =
22+ report.warning(show + stacktrace, this .pos)
2823
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
3227 trace.foreach { tree =>
3328 val pos = tree.sourcePos
3429 val prefix = " -> "
@@ -44,10 +39,16 @@ object Errors {
4439 positionMarker(pos)
4540 else " "
4641
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 )
4845
49- last = line
46+ lines += (prefix + line + " \n " + positionMarkerLine)
47+
48+ lastLineNum = pos.line
5049 }
50+ val sb = new StringBuilder
51+ for line <- lines do sb.append(line)
5152 sb.toString
5253 }
5354
@@ -65,13 +66,6 @@ object Errors {
6566 s " $padding$carets\n "
6667 }
6768
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-
7569 override def toString () = this .getClass.getName.nn
7670 }
7771
@@ -81,42 +75,37 @@ object Errors {
8175 def show (using Context ): String =
8276 " Access non-initialized " + field.show + " ."
8377
84- override def issue (using Context ): Unit =
85- report.warning(show + stacktrace, field.srcPos)
78+ override def pos (using Context ): SourcePosition = field.sourcePos
8679 }
8780
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
9184 }
9285
93- case class AccessCold (field : Symbol , source : Tree , trace : Seq [Tree ]) extends Error {
86+ case class AccessCold (field : Symbol , trace : Seq [Tree ]) extends Error {
9487 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."
9689 }
9790
98- case class CallCold (meth : Symbol , source : Tree , trace : Seq [Tree ]) extends Error {
91+ case class CallCold (meth : Symbol , trace : Seq [Tree ]) extends Error {
9992 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" + " ."
10194 }
10295
103- case class CallUnknown (meth : Symbol , source : Tree , trace : Seq [Tree ]) extends Error {
96+ case class CallUnknown (meth : Symbol , trace : Seq [Tree ]) extends Error {
10497 def show (using Context ): String =
10598 val prefix = if meth.is(Flags .Method ) then " Calling the external method " else " Accessing the external field"
10699 prefix + meth.show + " may cause initialization errors" + " ."
107100 }
108101
109102 /** 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 {
112104 override def issue (using Context ): Unit =
113- report.warning(show, source.srcPos )
105+ report.warning(show, this .pos )
114106
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
121111 }
122- }
0 commit comments