@@ -10,8 +10,8 @@ import StdNames._
1010
1111import ast .tpd ._
1212import util .SourcePosition
13- import config .Printers .{ init => printer }
14- import reporting .trace
13+ import config .Printers .init as printer
14+ import reporting .trace as log
1515
1616import Errors ._
1717import Util ._
@@ -118,24 +118,32 @@ class Semantic {
118118
119119 def + (error : Error ): Result = this .copy(errors = this .errors :+ error)
120120
121- def ensureHot (msg : String , source : Tree ): Result =
121+ def ensureHot (msg : String , source : Tree )( using Trace ) : Result =
122122 if value == Hot then this
123123 else
124124 // TODO: define a new error
125- this + PromoteCold (source, Vector (source) )
125+ this + PromoteCold (source, trace )
126126
127- def select (f : Symbol , source : Tree )(using Context ): Result =
127+ def select (f : Symbol , source : Tree )(using Context , Trace ): Result =
128128 value.select(f, source) ++ errors
129129
130- def call (meth : Symbol , superType : Type , source : Tree )(using Context ): Result =
130+ def call (meth : Symbol , superType : Type , source : Tree )(using Context , Trace ): Result =
131131 value.call(meth, superType, source) ++ errors
132132
133- def instantiate (klass : ClassSymbol , ctor : Symbol , source : Tree )(using Context ): Result =
133+ def instantiate (klass : ClassSymbol , ctor : Symbol , source : Tree )(using Context , Trace ): Result =
134134 value.instantiate(klass, ctor, source) ++ errors
135135 }
136136
137+ // ----- Error Handling -----------------------------------
138+ type Trace = Vector [Tree ]
139+
137140 val noErrors = Nil
138141
142+ extension (trace : Trace )
143+ def add (node : Tree ): Trace = trace :+ node
144+
145+ def trace (using t : Trace ): Trace = t
146+
139147// ----- Operations on domains -----------------------------
140148 extension (a : Value )
141149 def join (b : Value ): Value =
@@ -157,21 +165,21 @@ class Semantic {
157165 def join : Value = values.reduce { (v1, v2) => v1.join(v2) }
158166
159167 extension (value : Value )
160- def select (f : Symbol , source : Tree )(using Context ): Result =
168+ def select (f : Symbol , source : Tree )(using Context , Trace ): Result =
161169 value match {
162170 case Hot =>
163171 Result (Hot , noErrors)
164172
165173 case Cold =>
166- val error = AccessCold (f, source, Vector (source) )
174+ val error = AccessCold (f, source, trace )
167175 Result (Hot , error :: Nil )
168176
169177 case addr : Addr =>
170178 val obj = heap(addr)
171179 if obj.fields.contains(f) then
172180 Result (obj.fields(f), Nil )
173181 else
174- val error = AccessNonInit (f, Vector (source))
182+ val error = AccessNonInit (f, trace.add (source))
175183 Result (Hot , error :: Nil )
176184
177185 case _ : Fun =>
@@ -184,13 +192,13 @@ class Semantic {
184192 Result (value2, errors)
185193 }
186194
187- def call (meth : Symbol , superType : Type , source : Tree )(using Context ): Result =
195+ def call (meth : Symbol , superType : Type , source : Tree )(using Context , Trace ): Result =
188196 value match {
189197 case Hot =>
190198 Result (Hot , noErrors)
191199
192200 case Cold =>
193- val error = CallCold (meth, source, Vector (source) )
201+ val error = CallCold (meth, source, trace )
194202 Result (Hot , error :: Nil )
195203
196204 case addr : Addr =>
@@ -208,13 +216,13 @@ class Semantic {
208216 val rhs = target.defTree.asInstanceOf [DefDef ].rhs
209217 eval(rhs, addr, target.owner.asClass)
210218 else
211- val error = CallUnknown (target, source, Vector (source) )
219+ val error = CallUnknown (target, source, trace )
212220 Result (Hot , error :: Nil )
213221 else
214222 if obj.fields.contains(target) then
215223 Result (obj.fields(target), Nil )
216224 else
217- val error = AccessNonInit (target, Vector (source))
225+ val error = AccessNonInit (target, trace.add (source))
218226 Result (Hot , error :: Nil )
219227
220228 case Fun (body, thisV, klass) =>
@@ -229,13 +237,13 @@ class Semantic {
229237 Result (value2, errors)
230238 }
231239
232- def instantiate (klass : ClassSymbol , ctor : Symbol , source : Tree )(using Context ): Result =
240+ def instantiate (klass : ClassSymbol , ctor : Symbol , source : Tree )(using Context , Trace ): Result =
233241 value match {
234242 case Hot =>
235243 Result (Hot , noErrors)
236244
237245 case Cold =>
238- val error = CallCold (ctor, source, Vector (source) )
246+ val error = CallCold (ctor, source, trace )
239247 Result (Hot , error :: Nil )
240248
241249 case addr : Addr =>
@@ -276,7 +284,7 @@ class Semantic {
276284 *
277285 * This method only handles cache logic and delegates the work to `cases`.
278286 */
279- def eval (expr : Tree , thisV : Value , klass : ClassSymbol )(using Context ): Result = trace (" evaluating " + expr.show, printer, res => res.asInstanceOf [Result ].show) {
287+ def eval (expr : Tree , thisV : Value , klass : ClassSymbol )(using Context , Trace ): Result = log (" evaluating " + expr.show, printer, res => res.asInstanceOf [Result ].show) {
280288 val cfg = Config (thisV, expr.sourcePos)
281289 if (cache.contains(cfg)) Result (cache(cfg), noErrors)
282290 else {
@@ -292,14 +300,14 @@ class Semantic {
292300 }
293301
294302 /** Evaluate a list of expressions */
295- def eval (exprs : List [Tree ], thisV : Value , klass : ClassSymbol )(using Context ): List [Result ] =
303+ def eval (exprs : List [Tree ], thisV : Value , klass : ClassSymbol )(using Context , Trace ): List [Result ] =
296304 exprs.map { expr => eval(expr, thisV, klass) }
297305
298306 /** Handles the evaluation of different expressions
299307 *
300308 * Note: Recursive call should go to `eval` instead of `cases`.
301309 */
302- def cases (expr : Tree , thisV : Value , klass : ClassSymbol )(using Context ): Result =
310+ def cases (expr : Tree , thisV : Value , klass : ClassSymbol )(using Context , Trace ): Result =
303311 expr match {
304312 case Ident (nme.WILDCARD ) =>
305313 // TODO: disallow `var x: T = _`
@@ -333,11 +341,11 @@ class Semantic {
333341 case Select (supert : Super , _) =>
334342 val SuperType (thisTp, superTp) = supert.tpe
335343 val thisValue2 = resolveThis(thisTp.classSymbol.asClass, thisV, klass)
336- Result (thisValue2, errors).call(ref.symbol, superTp, expr)
344+ Result (thisValue2, errors).call(ref.symbol, superTp, expr)( using ctx, trace.add(expr))
337345
338346 case Select (qual, _) =>
339347 val res = eval(qual, thisV, klass) ++ errors
340- res.call(ref.symbol, superType = NoType , source = expr)
348+ res.call(ref.symbol, superType = NoType , source = expr)( using ctx, trace.add(expr))
341349
342350 case id : Ident =>
343351 id.tpe match
@@ -349,10 +357,10 @@ class Semantic {
349357 case Hot => Result (Hot , errors)
350358 case _ =>
351359 val rhs = id.symbol.defTree.asInstanceOf [DefDef ].rhs
352- eval(rhs, thisValue2, enclosingClass)
360+ eval(rhs, thisValue2, enclosingClass)( using ctx, trace.add(expr))
353361 case TermRef (prefix, _) =>
354362 val res = cases(prefix, thisV, klass, id) ++ errors
355- res.call(id.symbol, superType = NoType , source = expr)
363+ res.call(id.symbol, superType = NoType , source = expr)( using ctx, trace.add(expr))
356364
357365 case Select (qualifier, name) =>
358366 eval(qualifier, thisV, klass).select(expr.symbol, expr)
@@ -463,7 +471,7 @@ class Semantic {
463471 }
464472
465473 /** Handle semantics of leaf nodes */
466- def cases (tp : Type , thisV : Value , klass : ClassSymbol , source : Tree )(using Context ): Result = trace (" evaluating " + tp.show, printer, res => res.asInstanceOf [Result ].show) {
474+ def cases (tp : Type , thisV : Value , klass : ClassSymbol , source : Tree )(using Context , Trace ): Result = log (" evaluating " + tp.show, printer, res => res.asInstanceOf [Result ].show) {
467475 tp match {
468476 case _ : ConstantType =>
469477 Result (Hot , noErrors)
@@ -495,7 +503,7 @@ class Semantic {
495503 }
496504
497505 /** Resolve C.this that appear in `klass` */
498- def resolveThis (target : ClassSymbol , thisV : Value , klass : ClassSymbol )(using Context ): Value = trace (" resolving " + target.show + " , this = " + thisV.show + " in " + klass.show, printer, res => res.asInstanceOf [Value ].show) {
506+ def resolveThis (target : ClassSymbol , thisV : Value , klass : ClassSymbol )(using Context , Trace ): Value = log (" resolving " + target.show + " , this = " + thisV.show + " in " + klass.show, printer, res => res.asInstanceOf [Value ].show) {
499507 if target == klass then thisV
500508 else
501509 thisV match
@@ -508,7 +516,7 @@ class Semantic {
508516 }
509517
510518 /** Compute the outer value that correspond to `tref.prefix` */
511- def outerValue (tref : TypeRef , thisV : Value , klass : ClassSymbol , source : Tree )(using Context ): Result =
519+ def outerValue (tref : TypeRef , thisV : Value , klass : ClassSymbol , source : Tree )(using Context , Trace ): Result =
512520 val cls = tref.classSymbol.asClass
513521 if (tref.prefix == NoPrefix ) then
514522 val enclosing = cls.owner.lexicallyEnclosingClass.asClass
@@ -518,7 +526,7 @@ class Semantic {
518526 cases(tref.prefix, thisV, klass, source)
519527
520528 /** Initialize part of an abstract object in `klass` of the inheritance chain */
521- def init (klass : ClassSymbol , thisV : Addr )(using Context ): Result = trace (" init " + klass.show, printer, res => res.asInstanceOf [Result ].show) {
529+ def init (klass : ClassSymbol , thisV : Addr )(using Context , Trace ): Result = log (" init " + klass.show, printer, res => res.asInstanceOf [Result ].show) {
522530 val errorBuffer = new mutable.ArrayBuffer [Error ]
523531
524532 val tpl = klass.defTree.asInstanceOf [TypeDef ].rhs.asInstanceOf [Template ]
0 commit comments