Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Expr.valueOrAbort and reflect.report.errorAndAbort #12056

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions compiler/src/dotty/tools/dotc/transform/Splicer.scala
Original file line number Diff line number Diff line change
Expand Up @@ -63,8 +63,10 @@ object Splicer {
catch {
case ex: CompilationUnit.SuspendException =>
throw ex
case ex: scala.quoted.runtime.StopMacroExpansion if ctx.reporter.hasErrors =>
// errors have been emitted
case ex: scala.quoted.runtime.StopMacroExpansion =>
if !ctx.reporter.hasErrors then
report.error("Macro expansion was aborted by the macro without any errors reported. Macros should issue errors to end-users to facilitate debugging when aborting a macro expansion.", splicePos)
// errors have been emitted
EmptyTree
case ex: StopInterpretation =>
report.error(ex.msg, ex.pos)
Expand Down Expand Up @@ -546,4 +548,3 @@ object Splicer {
}
}
}

21 changes: 19 additions & 2 deletions compiler/src/scala/quoted/runtime/impl/QuotesImpl.scala
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,14 @@ class QuotesImpl private (using val ctx: Context) extends Quotes, QuoteUnpickler
def matches(that: scala.quoted.Expr[Any]): Boolean =
treeMatch(reflect.asTerm(self), reflect.asTerm(that)).nonEmpty

def valueOrAbort(using fromExpr: FromExpr[T]): T =
def reportError =
val tree = reflect.asTerm(self)
val code = reflect.Printer.TreeCode.show(tree)
val msg = s"Expected a known value. \n\nThe value of: $code\ncould not be extracted using $fromExpr"
reflect.report.throwError(msg, self)
fromExpr.unapply(self)(using QuotesImpl.this).getOrElse(reportError)

end extension

extension (self: scala.quoted.Expr[Any])
Expand Down Expand Up @@ -2750,14 +2758,23 @@ class QuotesImpl private (using val ctx: Context) extends Quotes, QuoteUnpickler
dotc.report.error(msg, pos)

def throwError(msg: String): Nothing =
errorAndAbort(msg)

def throwError(msg: String, expr: Expr[Any]): Nothing =
errorAndAbort(msg, expr)

def throwError(msg: String, pos: Position): Nothing =
errorAndAbort(msg, pos)

def errorAndAbort(msg: String): Nothing =
error(msg)
throw new scala.quoted.runtime.StopMacroExpansion

def throwError(msg: String, expr: Expr[Any]): Nothing =
def errorAndAbort(msg: String, expr: Expr[Any]): Nothing =
error(msg, expr)
throw new scala.quoted.runtime.StopMacroExpansion

def throwError(msg: String, pos: Position): Nothing =
def errorAndAbort(msg: String, pos: Position): Nothing =
error(msg, pos)
throw new scala.quoted.runtime.StopMacroExpansion

Expand Down
2 changes: 1 addition & 1 deletion docs/docs/reference/metaprogramming/macros.md
Original file line number Diff line number Diff line change
Expand Up @@ -460,7 +460,7 @@ aspect is also important for macro expansion.

To get values out of expressions containing constants `Expr` provides the method
`value` (or `valueOrError`). This will convert the `Expr[T]` into a `Some[T]` (or `T`) when the
expression contains value. Otherwise it will retrun `None` (or emit an error).
expression contains value. Otherwise it will return `None` (or emit an error).
To avoid having incidental val bindings generated by the inlining of the `def`
it is recommended to use an inline parameter. To illustrate this, consider an
implementation of the `power` function that makes use of a statically known exponent:
Expand Down
30 changes: 29 additions & 1 deletion library/src/scala/quoted/Quotes.scala
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,8 @@ trait Quotes { self: runtime.QuoteUnpickler & runtime.QuoteMatching =>
* Emits an error and throws if the expression does not represent a value or possibly contains side effects.
* Otherwise returns the value.
*/
// TODO: deprecate in 3.1.0 and remove @experimental from valueOrAbort
// @deprecated("Use valueOrThrow", "3.1.0")
def valueOrError(using FromExpr[T]): T =
val fromExpr = summon[FromExpr[T]]
def reportError =
Expand All @@ -62,6 +64,14 @@ trait Quotes { self: runtime.QuoteUnpickler & runtime.QuoteMatching =>
given Quotes = Quotes.this
fromExpr.unapply(self).getOrElse(reportError)

/** Return the value of this expression.
*
* Emits an error and aborts if the expression does not represent a value or possibly contains side effects.
* Otherwise returns the value.
*/
@experimental
def valueOrAbort(using FromExpr[T]): T
nicolasstucki marked this conversation as resolved.
Show resolved Hide resolved

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd suggest the method to take a message for indicating the reason why it's aborted. It helps end-users in debugging and saves the efforts of macro-authors in writing error-handling code.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The question then is if we should keep the version with the default error message. The idea if this signature was also to make the authors not need to write the error message.

Currently the can do

x.value match
  case Some(n) => ...
  case None => reflect.report.error("......", x)

or just

if x.valueOrAbort == 0 then ...
else 

the proposed one would need to add the message

if x.valueOrAbort(".........") == 0 then
else ...

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Indeed, the version with the error message does not look better in code and can be a little annoying for prototyping. For macro authors, it's not clear that it's better.

Macros can be subtle to use, more debuggability to end-users will make them more friendly for usage. However, if the gain for end-users is small, maybe it's not worth the complication.

The question then is if we should keep the version with the default error message

We probably only want to keep one of the two.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We could add an valueOrAbortWith("....") later or users will just define their own in the meantime. We should probably wait and see what users define themselves to know what is preferable in paractice.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Meanwhile, they can just define something like this in their projects

extension [T: FromExpr](expr: Expr[T]) 
  def valueOrAbortWith(msg: String)(using Quotes) = 
    x.value match
      case Some(n) => n
      case None => reflect.report.errorAndAbort(msg, x)
Expr(1).valueOrAbortWith("expected a constant")

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree, it's better to wait and do it later.

end extension

// Extension methods for `Expr[Any]` that take another explicit type parameter
Expand Down Expand Up @@ -4169,12 +4179,30 @@ trait Quotes { self: runtime.QuoteUnpickler & runtime.QuoteMatching =>
def error(msg: String, pos: Position): Unit

/** Report an error at the position of the macro expansion and throw a StopMacroExpansion */
@experimental
def errorAndAbort(msg: String): Nothing

/** Report an error at the position of `expr` and throw a StopMacroExpansion */
@experimental
def errorAndAbort(msg: String, expr: Expr[Any]): Nothing

/** Report an error message at the given position and throw a StopMacroExpansion */
@experimental
def errorAndAbort(msg: String, pos: Position): Nothing

/** Report an error at the position of the macro expansion and throw a StopMacroExpansion */
// TODO: deprecate in 3.1.0 and remove @experimental from errorAndAbort
// @deprecated("Use errorAndAbort", "3.1.0")
def throwError(msg: String): Nothing

/** Report an error at the position of `expr` */
/** Report an error at the position of `expr` and throw a StopMacroExpansion */
// TODO: deprecate in 3.1.0 and remove @experimental from errorAndAbort
// @deprecated("Use errorAndAbort", "3.1.0")
def throwError(msg: String, expr: Expr[Any]): Nothing

/** Report an error message at the given position and throw a StopMacroExpansion */
// TODO: deprecate in 3.1.0 and remove @experimental from errorAndAbort
// @deprecated("Use errorAndAbort", "3.1.0")
def throwError(msg: String, pos: Position): Nothing

/** Report a warning at the position of the macro expansion */
Expand Down
9 changes: 7 additions & 2 deletions library/src/scala/quoted/runtime/StopMacroExpansion.scala
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
package scala.quoted.runtime

/** Throwable used to stop the expansion of a macro after an error was reported */
class StopMacroExpansion extends Throwable
/** Throwable used to abort the expansion of a macro after an error was reported */
class StopMacroExpansion extends Throwable:

// Do not fill the stacktrace for performance.
// We know that the stacktrace will be ignored
// and only the reported error message will be used.
override def fillInStackTrace(): Throwable = this
7 changes: 7 additions & 0 deletions project/MiMaFilters.scala
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,22 @@ import com.typesafe.tools.mima.core.ProblemFilters._
object MiMaFilters {
val Library: Seq[ProblemFilter] = Seq(
// New APIs marked @experimental in 3.0.1
exclude[DirectMissingMethodProblem]("scala.quoted.Quotes.valueOrAbort"),
exclude[DirectMissingMethodProblem]("scala.quoted.Quotes#reflectModule#reportModule.errorAndAbort"),
exclude[DirectMissingMethodProblem]("scala.quoted.Quotes#reflectModule#SymbolMethods.fieldMember"),
exclude[DirectMissingMethodProblem]("scala.quoted.Quotes#reflectModule#SymbolMethods.fieldMembers"),
exclude[DirectMissingMethodProblem]("scala.quoted.Quotes#reflectModule#SymbolMethods.methodMember"),
exclude[DirectMissingMethodProblem]("scala.quoted.Quotes#reflectModule#SymbolMethods.methodMembers"),
exclude[DirectMissingMethodProblem]("scala.quoted.Quotes#reflectModule#SymbolMethods.typeMember"),
exclude[DirectMissingMethodProblem]("scala.quoted.Quotes#reflectModule#SymbolMethods.typeMembers"),
exclude[DirectMissingMethodProblem]("scala.quoted.Quotes#reflectModule#TermParamClauseMethods.isErased"),
exclude[DirectMissingMethodProblem]("scala.quoted.Quotes#reflectModule#TermParamClauseMethods.isErased"),
exclude[MissingClassProblem]("scala.annotation.experimental"),
exclude[MissingClassProblem]("scala.annotation.experimental"),
exclude[MissingClassProblem]("scala.annotation.internal.ErasedParam"),
exclude[MissingClassProblem]("scala.annotation.internal.ErasedParam"),
exclude[ReversedMissingMethodProblem]("scala.quoted.Quotes.valueOrAbort"),
exclude[ReversedMissingMethodProblem]("scala.quoted.Quotes#reflectModule#reportModule.errorAndAbort"),
exclude[ReversedMissingMethodProblem]("scala.quoted.Quotes#reflectModule#SymbolMethods.fieldMember"),
exclude[ReversedMissingMethodProblem]("scala.quoted.Quotes#reflectModule#SymbolMethods.fieldMembers"),
exclude[ReversedMissingMethodProblem]("scala.quoted.Quotes#reflectModule#SymbolMethods.methodMember"),
Expand Down
2 changes: 1 addition & 1 deletion tests/bench/power-macro/PowerMacro.scala
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ object PowerMacro {
inline def power(inline n: Long, x: Double) = ${ powerCode('n, 'x) }

def powerCode(n: Expr[Long], x: Expr[Double])(using Quotes): Expr[Double] =
powerCode(n.valueOrError, x)
powerCode(n.valueOrAbort, x)

def powerCode(n: Long, x: Expr[Double])(using Quotes): Expr[Double] =
if (n == 0) '{1.0}
Expand Down
2 changes: 1 addition & 1 deletion tests/neg-macros/i9014/Macros_1.scala
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import scala.quoted.*
trait Bar
inline given Bar = ${ impl }
def impl(using Quotes): Expr[Bar] = quotes.reflect.report.throwError("Failed to expand!")
def impl(using Quotes): Expr[Bar] = quotes.reflect.report.errorAndAbort("Failed to expand!")
2 changes: 1 addition & 1 deletion tests/neg-macros/i9014b/Macros_1.scala
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import scala.quoted._
trait Bar
transparent inline given Bar = ${ impl }
def impl(using Quotes): Expr[Bar] = quotes.reflect.report.throwError("Failed to expand!")
def impl(using Quotes): Expr[Bar] = quotes.reflect.report.errorAndAbort("Failed to expand!")
6 changes: 6 additions & 0 deletions tests/neg-macros/ill-abort.check
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@

-- Error: tests/neg-macros/ill-abort/quoted_2.scala:1:15 ---------------------------------------------------------------
1 |def test = fail() // error
| ^^^^^^
|Macro expansion was aborted by the macro without any errors reported. Macros should issue errors to end-users to facilitate debugging when aborting a macro expansion.
| This location contains code that was inlined from quoted_1.scala:3
7 changes: 7 additions & 0 deletions tests/neg-macros/ill-abort/quoted_1.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import scala.quoted.*

inline def fail(): Unit = ${ impl }

private def impl(using Quotes) : Expr[Unit] =
// should never be done without reporting error before (see docs)
throw new scala.quoted.runtime.StopMacroExpansion
1 change: 1 addition & 0 deletions tests/neg-macros/ill-abort/quoted_2.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
def test = fail() // error
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ object E {

inline def eval[T](inline x: E[T]): T = ${ impl('x) }

def impl[T: Type](x: Expr[E[T]]) (using Quotes): Expr[T] = x.valueOrError.lift
def impl[T: Type](x: Expr[E[T]]) (using Quotes): Expr[T] = x.valueOrAbort.lift

implicit def ev1[T: Type]: FromExpr[E[T]] = new FromExpr {
def unapply(x: Expr[E[T]])(using Quotes) = x match {
Expand Down
2 changes: 1 addition & 1 deletion tests/neg-macros/inline-option/Macro_1.scala
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
import scala.quoted.*

object Macro {
def impl(opt: Expr[Option[Int]]) (using Quotes): Expr[Int] = opt.valueOrError match {
def impl(opt: Expr[Option[Int]]) (using Quotes): Expr[Int] = opt.valueOrAbort match {
case Some(i) => Expr(i)
case None => '{-1}
}
Expand Down
44 changes: 22 additions & 22 deletions tests/neg-macros/inline-tuples-1/Macro_1.scala
Original file line number Diff line number Diff line change
Expand Up @@ -2,26 +2,26 @@
import scala.quoted.*

object Macros {
def tup1(tup: Expr[Tuple1[Int]]) (using Quotes): Expr[Int] = Expr(tup.valueOrError.productIterator.map(_.asInstanceOf[Int]).sum)
def tup2(tup: Expr[Tuple2[Int, Int]]) (using Quotes): Expr[Int] = Expr(tup.valueOrError.productIterator.map(_.asInstanceOf[Int]).sum)
def tup3(tup: Expr[Tuple3[Int, Int, Int]]) (using Quotes): Expr[Int] = Expr(tup.valueOrError.productIterator.map(_.asInstanceOf[Int]).sum)
def tup4(tup: Expr[Tuple4[Int, Int, Int, Int]]) (using Quotes): Expr[Int] = Expr(tup.valueOrError.productIterator.map(_.asInstanceOf[Int]).sum)
def tup5(tup: Expr[Tuple5[Int, Int, Int, Int, Int]]) (using Quotes): Expr[Int] = Expr(tup.valueOrError.productIterator.map(_.asInstanceOf[Int]).sum)
def tup6(tup: Expr[Tuple6[Int, Int, Int, Int, Int, Int]]) (using Quotes): Expr[Int] = Expr(tup.valueOrError.productIterator.map(_.asInstanceOf[Int]).sum)
def tup7(tup: Expr[Tuple7[Int, Int, Int, Int, Int, Int, Int]]) (using Quotes): Expr[Int] = Expr(tup.valueOrError.productIterator.map(_.asInstanceOf[Int]).sum)
def tup8(tup: Expr[Tuple8[Int, Int, Int, Int, Int, Int, Int, Int]]) (using Quotes): Expr[Int] = Expr(tup.valueOrError.productIterator.map(_.asInstanceOf[Int]).sum)
def tup9(tup: Expr[Tuple9[Int, Int, Int, Int, Int, Int, Int, Int, Int]]) (using Quotes): Expr[Int] = Expr(tup.valueOrError.productIterator.map(_.asInstanceOf[Int]).sum)
def tup10(tup: Expr[Tuple10[Int, Int, Int, Int, Int, Int, Int, Int, Int, Int]]) (using Quotes): Expr[Int] = Expr(tup.valueOrError.productIterator.map(_.asInstanceOf[Int]).sum)
def tup11(tup: Expr[Tuple11[Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int]]) (using Quotes): Expr[Int] = Expr(tup.valueOrError.productIterator.map(_.asInstanceOf[Int]).sum)
def tup12(tup: Expr[Tuple12[Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int]]) (using Quotes): Expr[Int] = Expr(tup.valueOrError.productIterator.map(_.asInstanceOf[Int]).sum)
def tup13(tup: Expr[Tuple13[Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int]]) (using Quotes): Expr[Int] = Expr(tup.valueOrError.productIterator.map(_.asInstanceOf[Int]).sum)
def tup14(tup: Expr[Tuple14[Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int]]) (using Quotes): Expr[Int] = Expr(tup.valueOrError.productIterator.map(_.asInstanceOf[Int]).sum)
def tup15(tup: Expr[Tuple15[Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int]]) (using Quotes): Expr[Int] = Expr(tup.valueOrError.productIterator.map(_.asInstanceOf[Int]).sum)
def tup16(tup: Expr[Tuple16[Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int]]) (using Quotes): Expr[Int] = Expr(tup.valueOrError.productIterator.map(_.asInstanceOf[Int]).sum)
def tup17(tup: Expr[Tuple17[Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int]]) (using Quotes): Expr[Int] = Expr(tup.valueOrError.productIterator.map(_.asInstanceOf[Int]).sum)
def tup18(tup: Expr[Tuple18[Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int]]) (using Quotes): Expr[Int] = Expr(tup.valueOrError.productIterator.map(_.asInstanceOf[Int]).sum)
def tup19(tup: Expr[Tuple19[Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int]]) (using Quotes): Expr[Int] = Expr(tup.valueOrError.productIterator.map(_.asInstanceOf[Int]).sum)
def tup20(tup: Expr[Tuple20[Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int]]) (using Quotes): Expr[Int] = Expr(tup.valueOrError.productIterator.map(_.asInstanceOf[Int]).sum)
def tup21(tup: Expr[Tuple21[Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int]]) (using Quotes): Expr[Int] = Expr(tup.valueOrError.productIterator.map(_.asInstanceOf[Int]).sum)
def tup22(tup: Expr[Tuple22[Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int]]) (using Quotes): Expr[Int] = Expr(tup.valueOrError.productIterator.map(_.asInstanceOf[Int]).sum)
def tup1(tup: Expr[Tuple1[Int]]) (using Quotes): Expr[Int] = Expr(tup.valueOrAbort.productIterator.map(_.asInstanceOf[Int]).sum)
def tup2(tup: Expr[Tuple2[Int, Int]]) (using Quotes): Expr[Int] = Expr(tup.valueOrAbort.productIterator.map(_.asInstanceOf[Int]).sum)
def tup3(tup: Expr[Tuple3[Int, Int, Int]]) (using Quotes): Expr[Int] = Expr(tup.valueOrAbort.productIterator.map(_.asInstanceOf[Int]).sum)
def tup4(tup: Expr[Tuple4[Int, Int, Int, Int]]) (using Quotes): Expr[Int] = Expr(tup.valueOrAbort.productIterator.map(_.asInstanceOf[Int]).sum)
def tup5(tup: Expr[Tuple5[Int, Int, Int, Int, Int]]) (using Quotes): Expr[Int] = Expr(tup.valueOrAbort.productIterator.map(_.asInstanceOf[Int]).sum)
def tup6(tup: Expr[Tuple6[Int, Int, Int, Int, Int, Int]]) (using Quotes): Expr[Int] = Expr(tup.valueOrAbort.productIterator.map(_.asInstanceOf[Int]).sum)
def tup7(tup: Expr[Tuple7[Int, Int, Int, Int, Int, Int, Int]]) (using Quotes): Expr[Int] = Expr(tup.valueOrAbort.productIterator.map(_.asInstanceOf[Int]).sum)
def tup8(tup: Expr[Tuple8[Int, Int, Int, Int, Int, Int, Int, Int]]) (using Quotes): Expr[Int] = Expr(tup.valueOrAbort.productIterator.map(_.asInstanceOf[Int]).sum)
def tup9(tup: Expr[Tuple9[Int, Int, Int, Int, Int, Int, Int, Int, Int]]) (using Quotes): Expr[Int] = Expr(tup.valueOrAbort.productIterator.map(_.asInstanceOf[Int]).sum)
def tup10(tup: Expr[Tuple10[Int, Int, Int, Int, Int, Int, Int, Int, Int, Int]]) (using Quotes): Expr[Int] = Expr(tup.valueOrAbort.productIterator.map(_.asInstanceOf[Int]).sum)
def tup11(tup: Expr[Tuple11[Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int]]) (using Quotes): Expr[Int] = Expr(tup.valueOrAbort.productIterator.map(_.asInstanceOf[Int]).sum)
def tup12(tup: Expr[Tuple12[Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int]]) (using Quotes): Expr[Int] = Expr(tup.valueOrAbort.productIterator.map(_.asInstanceOf[Int]).sum)
def tup13(tup: Expr[Tuple13[Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int]]) (using Quotes): Expr[Int] = Expr(tup.valueOrAbort.productIterator.map(_.asInstanceOf[Int]).sum)
def tup14(tup: Expr[Tuple14[Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int]]) (using Quotes): Expr[Int] = Expr(tup.valueOrAbort.productIterator.map(_.asInstanceOf[Int]).sum)
def tup15(tup: Expr[Tuple15[Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int]]) (using Quotes): Expr[Int] = Expr(tup.valueOrAbort.productIterator.map(_.asInstanceOf[Int]).sum)
def tup16(tup: Expr[Tuple16[Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int]]) (using Quotes): Expr[Int] = Expr(tup.valueOrAbort.productIterator.map(_.asInstanceOf[Int]).sum)
def tup17(tup: Expr[Tuple17[Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int]]) (using Quotes): Expr[Int] = Expr(tup.valueOrAbort.productIterator.map(_.asInstanceOf[Int]).sum)
def tup18(tup: Expr[Tuple18[Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int]]) (using Quotes): Expr[Int] = Expr(tup.valueOrAbort.productIterator.map(_.asInstanceOf[Int]).sum)
def tup19(tup: Expr[Tuple19[Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int]]) (using Quotes): Expr[Int] = Expr(tup.valueOrAbort.productIterator.map(_.asInstanceOf[Int]).sum)
def tup20(tup: Expr[Tuple20[Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int]]) (using Quotes): Expr[Int] = Expr(tup.valueOrAbort.productIterator.map(_.asInstanceOf[Int]).sum)
def tup21(tup: Expr[Tuple21[Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int]]) (using Quotes): Expr[Int] = Expr(tup.valueOrAbort.productIterator.map(_.asInstanceOf[Int]).sum)
def tup22(tup: Expr[Tuple22[Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int]]) (using Quotes): Expr[Int] = Expr(tup.valueOrAbort.productIterator.map(_.asInstanceOf[Int]).sum)
}
2 changes: 1 addition & 1 deletion tests/neg-macros/quote-error-2/Macro_1.scala
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import quoted.*
object Macro_1 {
inline def foo(inline b: Boolean): Unit = ${ fooImpl('b) }
def fooImpl(b: Expr[Boolean])(using Quotes): Expr[Unit] =
'{println(${msg(b.valueOrError)})}
'{println(${msg(b.valueOrAbort)})}

def msg(b: Boolean)(using Quotes): Expr[String] =
if (b) '{"foo(true)"}
Expand Down
2 changes: 1 addition & 1 deletion tests/neg-macros/quote-error/Macro_1.scala
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,6 @@ import quoted.*
object Macro_1 {
inline def foo(inline b: Boolean): Unit = ${fooImpl('b)}
def fooImpl(b: Expr[Boolean])(using Quotes) : Expr[Unit] =
if (b.valueOrError) '{println("foo(true)")}
if (b.valueOrAbort) '{println("foo(true)")}
else { quotes.reflect.report.error("foo cannot be called with false"); '{ ??? } }
}
2 changes: 1 addition & 1 deletion tests/neg-macros/quote-exception/Macro_1.scala
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,6 @@ import quoted.*
object Macro_1 {
inline def foo(inline b: Boolean): Unit = ${fooImpl('b)}
def fooImpl(b: Expr[Boolean]) (using Quotes): Expr[Unit] =
if (b.valueOrError) '{println("foo(true)")}
if (b.valueOrAbort) '{println("foo(true)")}
else ???
}
2 changes: 1 addition & 1 deletion tests/neg-macros/quote-whitebox/Macro_1.scala
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import scala.quoted.*

object Macros {
transparent inline def defaultOf(inline str: String): Any = ${ defaultOfImpl('str) }
def defaultOfImpl(str: Expr[String]) (using Quotes): Expr[Any] = str.valueOrError match {
def defaultOfImpl(str: Expr[String]) (using Quotes): Expr[Any] = str.valueOrAbort match {
case "int" => '{1}
case "string" => '{"a"}
}
Expand Down
2 changes: 1 addition & 1 deletion tests/neg-macros/reflect-inline/assert_1.scala
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,6 @@ object api {
${ stripImpl('x) }

private def stripImpl(x: Expr[String])(using Quotes): Expr[String] =
Expr(x.valueOrError.stripMargin)
Expr(x.valueOrAbort.stripMargin)

}
Loading