Skip to content

Commit 7480582

Browse files
Improve asExprOf cast error formatting (#19195)
The intention of this change is to make it simpler to read the error message. List the expected type and actual type before the expression. This is usually the most important information and simpler to parse as the expression can get quite long. For the expected type, the actual type and the expression, we print the value in the same line if its String representation has only one line. Otherwise we print it in the next line with an indentation and extra new line at the end. Before: ``` java.lang.Exception: Expr cast exception: ((a: scala.Int) => ({ val v: scala.Int = a Binding.apply[scala.Unit](()) }: Binding[scala.Unit])) of type: scala.Function1[scala.Int, scala.Unit] did not conform to type: scala.Function1[scala.Int, Binding[scala.Unit]] at scala.quoted.runtime.impl.QuotesImpl.asExprOf(QuotesImpl.scala:76) ... ``` Example from #19191 After: ``` scala.quoted.runtime.impl.ExprCastException: Expected type: scala.Function1[scala.Int, scala.Unit] Actual type: scala.Function1[scala.Int, Binding[scala.Unit]] Expression: ((a: scala.Int) => ({ val v: scala.Int = a Binding.apply[scala.Unit](()) }: Binding[scala.Unit])) at scala.quoted.runtime.impl.QuotesImpl.asExprOf(QuotesImpl.scala:...) ... ```
1 parent a3854cb commit 7480582

File tree

2 files changed

+25
-5
lines changed

2 files changed

+25
-5
lines changed
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
package scala.quoted.runtime.impl
2+
3+
import dotty.tools.dotc.ast.tpd.Tree
4+
import dotty.tools.dotc.core.Contexts.*
5+
6+
class ExprCastException(msg: String) extends Exception(msg)
7+
8+
9+
object ExprCastException:
10+
def apply(expectedType: String, actualType: String, exprCode: String): ExprCastException =
11+
new ExprCastException(
12+
s"""|
13+
| Expected type: ${formatLines(expectedType)}
14+
| Actual type: ${formatLines(actualType)}
15+
| Expression: ${formatLines(exprCode)}
16+
|""".stripMargin)
17+
18+
private def formatLines(str: String): String =
19+
if !str.contains("\n") then str
20+
else str.linesIterator.mkString("\n ", "\n ", "\n")

compiler/src/scala/quoted/runtime/impl/QuotesImpl.scala

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ import scala.quoted.runtime.{QuoteUnpickler, QuoteMatching}
2323
import scala.quoted.runtime.impl.printers.*
2424

2525
import scala.reflect.TypeTest
26+
import dotty.tools.dotc.core.NameKinds.ExceptionBinderName
2627

2728
object QuotesImpl {
2829

@@ -70,11 +71,10 @@ class QuotesImpl private (using val ctx: Context) extends Quotes, QuoteUnpickler
7071
if self.isExprOf[X] then
7172
self.asInstanceOf[scala.quoted.Expr[X]]
7273
else
73-
throw Exception(
74-
s"""Expr cast exception: ${self.show}
75-
|of type: ${reflect.Printer.TypeReprCode.show(reflect.asTerm(self).tpe)}
76-
|did not conform to type: ${reflect.Printer.TypeReprCode.show(reflect.TypeRepr.of[X])}
77-
|""".stripMargin
74+
throw ExprCastException(
75+
expectedType = reflect.Printer.TypeReprCode.show(reflect.TypeRepr.of[X]),
76+
actualType = reflect.Printer.TypeReprCode.show(reflect.asTerm(self).tpe),
77+
exprCode = self.show
7878
)
7979
}
8080
end extension

0 commit comments

Comments
 (0)