Skip to content

Commit 08f040c

Browse files
committed
Support Value.source for friendly error message
1 parent 5a82985 commit 08f040c

File tree

1 file changed

+26
-3
lines changed

1 file changed

+26
-3
lines changed

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

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -55,8 +55,29 @@ class Semantic {
5555
* V ⊑ R if V ∈ R
5656
*
5757
*/
58-
sealed abstract class Value {
58+
sealed abstract class Value extends Cloneable {
5959
def show: String = this.toString()
60+
61+
/** Source code where the value originates from
62+
*
63+
* It is used for displaying friendly messages
64+
*/
65+
private var mySource: Tree = EmptyTree
66+
67+
def source: Tree = mySource
68+
69+
def attachSource(source: Tree): this.type =
70+
assert(mySource.isEmpty, "Update existing source of value " + this)
71+
mySource = source
72+
this
73+
74+
def withSource(source: Tree): Value =
75+
if mySource.isEmpty then attachSource(source)
76+
else {
77+
val value2 = this.clone.asInstanceOf[Value]
78+
value2.mySource = source
79+
value2
80+
}
6081
}
6182

6283
/** A transitively initialized object */
@@ -238,6 +259,8 @@ class Semantic {
238259

239260
def instantiate(klass: ClassSymbol, ctor: Symbol, args: List[Value], source: Tree): Contextual[Result] =
240261
value.instantiate(klass, ctor, args, source) ++ errors
262+
263+
def withSource(source: Tree): Result = Result(value.withSource(source), errors)
241264
}
242265

243266
/** The state that threads through the interpreter */
@@ -626,9 +649,9 @@ class Semantic {
626649
val ress = args.map { arg =>
627650
if arg.isByName then
628651
val fun = Fun(arg.tree, Nil, thisV, klass, env)
629-
Result(fun, Nil)
652+
Result(fun, Nil).withSource(arg.tree)
630653
else
631-
eval(arg.tree, thisV, klass)
654+
eval(arg.tree, thisV, klass).withSource(arg.tree)
632655
}
633656
(ress.flatMap(_.errors), ress.map(_.value))
634657

0 commit comments

Comments
 (0)