diff --git a/compiler/src/scala/quoted/runtime/impl/ExprCastException.scala b/compiler/src/scala/quoted/runtime/impl/ExprCastException.scala new file mode 100644 index 000000000000..ba870808cee3 --- /dev/null +++ b/compiler/src/scala/quoted/runtime/impl/ExprCastException.scala @@ -0,0 +1,20 @@ +package scala.quoted.runtime.impl + +import dotty.tools.dotc.ast.tpd.Tree +import dotty.tools.dotc.core.Contexts.* + +class ExprCastException(msg: String) extends Exception(msg) + + +object ExprCastException: + def apply(expectedType: String, actualType: String, exprCode: String): ExprCastException = + new ExprCastException( + s"""| + | Expected type: ${formatLines(expectedType)} + | Actual type: ${formatLines(actualType)} + | Expression: ${formatLines(exprCode)} + |""".stripMargin) + + private def formatLines(str: String): String = + if !str.contains("\n") then str + else str.linesIterator.mkString("\n ", "\n ", "\n") diff --git a/compiler/src/scala/quoted/runtime/impl/QuotesImpl.scala b/compiler/src/scala/quoted/runtime/impl/QuotesImpl.scala index 04472647b9fc..6aa279129f2b 100644 --- a/compiler/src/scala/quoted/runtime/impl/QuotesImpl.scala +++ b/compiler/src/scala/quoted/runtime/impl/QuotesImpl.scala @@ -23,6 +23,7 @@ import scala.quoted.runtime.{QuoteUnpickler, QuoteMatching} import scala.quoted.runtime.impl.printers.* import scala.reflect.TypeTest +import dotty.tools.dotc.core.NameKinds.ExceptionBinderName object QuotesImpl { @@ -70,11 +71,10 @@ class QuotesImpl private (using val ctx: Context) extends Quotes, QuoteUnpickler if self.isExprOf[X] then self.asInstanceOf[scala.quoted.Expr[X]] else - throw Exception( - s"""Expr cast exception: ${self.show} - |of type: ${reflect.Printer.TypeReprCode.show(reflect.asTerm(self).tpe)} - |did not conform to type: ${reflect.Printer.TypeReprCode.show(reflect.TypeRepr.of[X])} - |""".stripMargin + throw ExprCastException( + expectedType = reflect.Printer.TypeReprCode.show(reflect.TypeRepr.of[X]), + actualType = reflect.Printer.TypeReprCode.show(reflect.asTerm(self).tpe), + exprCode = self.show ) } end extension