Skip to content

Commit d262e99

Browse files
committed
Move errors and warnings out of QuoteContext
1 parent 5aec4f8 commit d262e99

File tree

22 files changed

+79
-68
lines changed

22 files changed

+79
-68
lines changed

compiler/src/dotty/tools/dotc/transform/Splicer.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ object Splicer {
5252
catch {
5353
case ex: CompilationUnit.SuspendException =>
5454
throw ex
55-
case ex: scala.quoted.StopQuotedContext if ctx.reporter.hasErrors =>
55+
case ex: scala.quoted.Reporting.StopQuotedContext if ctx.reporter.hasErrors =>
5656
// errors have been emitted
5757
EmptyTree
5858
case ex: StopInterpretation =>
@@ -389,7 +389,7 @@ object Splicer {
389389
throw new StopInterpretation(sw.toString, pos)
390390
case ex: InvocationTargetException =>
391391
ex.getTargetException match {
392-
case ex: scala.quoted.StopQuotedContext =>
392+
case ex: scala.quoted.Reporting.StopQuotedContext =>
393393
throw ex
394394
case MissingClassDefinedInCurrentRun(sym) =>
395395
if (ctx.settings.XprintSuspension.value)

docs/docs/reference/metaprogramming/macros.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -727,14 +727,14 @@ private def showMeExpr(sc: Expr[StringContext], argsExpr: Expr[Seq[Any]])(using
727727
val showTp = '[Show[$tp]]
728728
Expr.summon(using showTp) match {
729729
case Some(showExpr) => '{ $showExpr.show($arg) }
730-
case None => qctx.error(s"could not find implicit for ${showTp.show}", arg); '{???}
730+
case None => Reporting.error(s"could not find implicit for ${showTp.show}", arg); '{???}
731731
}
732732
}
733733
val newArgsExpr = Varargs(argShowedExprs)
734734
'{ $sc.s($newArgsExpr: _*) }
735735
case _ =>
736736
// `new StringContext(...).showMeExpr(args: _*)` not an explicit `showMeExpr"..."`
737-
qctx.error(s"Args must be explicit", argsExpr)
737+
Reporting.error(s"Args must be explicit", argsExpr)
738738
'{???}
739739
}
740740
}

docs/docs/reference/metaprogramming/tasty-reflect.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,13 +46,13 @@ def natConstImpl(x: Expr[Int])(using qctx: QuoteContext): Expr[Int] = {
4646
xTree match {
4747
case Inlined(_, _, Literal(Constant(n: Int))) =>
4848
if (n <= 0) {
49-
qctx.error("Parameter must be natural number")
49+
Reporting.error("Parameter must be natural number")
5050
'{0}
5151
} else {
5252
xTree.seal.cast[Int]
5353
}
5454
case _ =>
55-
qctx.error("Parameter must be a known constant")
55+
Reporting.error("Parameter must be a known constant")
5656
'{0}
5757
}
5858
}

library/src-bootstrapped/dotty/internal/CompileTimeMacros.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,4 +8,4 @@ object CompileTimeMacros:
88
case (Expr.StringContext(Consts(parts)), Varargs(args2)) =>
99
Expr(StringContext(parts: _*).s(args2.map(_.show): _*))
1010
case _ =>
11-
qctx.throwError("compiletime.code must be used as a string interpolator `code\"...\"`")
11+
Reporting.throwError("compiletime.code must be used as a string interpolator `code\"...\"`")

library/src-bootstrapped/dotty/internal/StringContextMacro.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,12 +63,12 @@ object StringContextMacro {
6363

6464
val (partsExpr, parts) = strCtxExpr match {
6565
case Expr.StringContext(p1 @ Consts(p2)) => (p1.toList, p2.toList)
66-
case _ => qctx.throwError("Expected statically known String Context", strCtxExpr)
66+
case _ => Reporting.throwError("Expected statically known String Context", strCtxExpr)
6767
}
6868

6969
val args = argsExpr match {
7070
case Varargs(args) => args
71-
case _ => qctx.throwError("Expected statically known argument list", argsExpr)
71+
case _ => Reporting.throwError("Expected statically known argument list", argsExpr)
7272
}
7373

7474
val reporter = new Reporter{

library/src-bootstrapped/scala/quoted/Expr.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ class Expr[+T] private[scala] {
4343
* Otherwise returns the value.
4444
*/
4545
final def unliftOrError[U >: T](using qctx: QuoteContext, unlift: Unliftable[U]): U =
46-
unlift(this).getOrElse(qctx.throwError(s"Expected a known value. \n\nThe value of: $show\ncould not be unlifted using $unlift", this))
46+
unlift(this).getOrElse(Reporting.throwError(s"Expected a known value. \n\nThe value of: $show\ncould not be unlifted using $unlift", this))
4747

4848
/** Pattern matches `this` against `that`. Effectively performing a deep equality check.
4949
* It does the equivalent of

library/src-bootstrapped/scala/quoted/QuoteContext.scala

Lines changed: 5 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -34,31 +34,10 @@ trait QuoteContext { self =>
3434
val tasty: self.tasty.type
3535
}
3636

37-
/** Report an error at the position of the macro expansion */
38-
def error(msg: => String): Unit =
39-
tasty.error(msg, tasty.rootPosition)
40-
41-
/** Report an error at the on the position of `expr` */
42-
def error(msg: => String, expr: Expr[Any]): Unit =
43-
tasty.error(msg, expr.unseal(using this).pos)
44-
45-
/** Report an error at the position of the macro expansion and throws a StopQuotedContext */
46-
def throwError(msg: => String): Nothing = {
47-
error(msg)
48-
throw new StopQuotedContext
49-
}
50-
/** Report an error at the on the position of `expr` and throws a StopQuotedContext */
51-
def throwError(msg: => String, expr: Expr[Any]): Nothing = {
52-
error(msg, expr)
53-
throw new StopQuotedContext
54-
}
55-
56-
/** Report a warning */
57-
def warning(msg: => String): Unit =
58-
tasty.warning(msg, tasty.rootPosition)
59-
60-
/** Report a warning at the on the position of `expr` */
61-
def warning(msg: => String, expr: Expr[Any]): Unit =
62-
tasty.warning(msg, expr.unseal(using this).pos)
37+
}
6338

39+
object QuoteContext {
40+
// TODO remove in 0.26.0
41+
@deprecated("Errors and warnings have been moved to scala.quoted.Reporting", "0.25.0")
42+
given error_and_warining_on_QuoteContext as Conversion[QuoteContext, Reporting.type] = _ => Reporting
6443
}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
package scala.quoted
2+
3+
object Reporting {
4+
5+
/** Report an error at the position of the macro expansion */
6+
def error(msg: => String)(using qctx: QuoteContext): Unit =
7+
qctx.tasty.error(msg, qctx.tasty.rootPosition)
8+
9+
/** Report an error at the on the position of `expr` */
10+
def error(msg: => String, expr: Expr[Any])(using qctx: QuoteContext): Unit =
11+
qctx.tasty.error(msg, expr.unseal.pos)
12+
13+
/** Report an error at the position of the macro expansion and throws a StopQuotedContext */
14+
def throwError(msg: => String)(using qctx: QuoteContext): Nothing = {
15+
error(msg)
16+
throw new StopQuotedContext
17+
}
18+
/** Report an error at the on the position of `expr` and throws a StopQuotedContext */
19+
def throwError(msg: => String, expr: Expr[Any])(using qctx: QuoteContext): Nothing = {
20+
error(msg, expr)
21+
throw new StopQuotedContext
22+
}
23+
24+
/** Report a warning */
25+
def warning(msg: => String)(using qctx: QuoteContext): Unit =
26+
qctx.tasty.warning(msg, qctx.tasty.rootPosition)
27+
28+
/** Report a warning at the on the position of `expr` */
29+
def warning(msg: => String, expr: Expr[_])(using qctx: QuoteContext): Unit =
30+
qctx.tasty.warning(msg, expr.unseal.pos)
31+
32+
/** Throwable used to stop the expansion of a macro after an error was reported */
33+
class StopQuotedContext extends Throwable
34+
35+
}

library/src/scala/quoted/StopQuotedContext.scala

Lines changed: 0 additions & 4 deletions
This file was deleted.

tests/neg-macros/quote-error-2/Macro_1.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,6 @@ object Macro_1 {
77

88
def msg(b: Boolean)(using qctx: QuoteContext): Expr[String] =
99
if (b) '{"foo(true)"}
10-
else { qctx.error("foo cannot be called with false"); '{ ??? } }
10+
else { Reporting.error("foo cannot be called with false"); '{ ??? } }
1111

1212
}

tests/neg-macros/quote-error/Macro_1.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,5 @@ object Macro_1 {
44
inline def foo(inline b: Boolean): Unit = ${fooImpl('b)}
55
def fooImpl(b: Expr[Boolean])(using qctx: QuoteContext) : Expr[Unit] =
66
if (b.unliftOrError) '{println("foo(true)")}
7-
else { qctx.error("foo cannot be called with false"); '{ ??? } }
7+
else { Reporting.error("foo cannot be called with false"); '{ ??? } }
88
}

tests/neg-staging/i5941/macro_1.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ object Lens {
3333
apply($getter)(setter)
3434
}
3535
case _ =>
36-
qctx.error("Unsupported syntax. Example: `GenLens[Address](_.streetNumber)`")
36+
Reporting.error("Unsupported syntax. Example: `GenLens[Address](_.streetNumber)`")
3737
'{???}
3838
}
3939
}

tests/run-macros/f-interpolation-1/FQuote_1.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ object FQuote {
3939
values.forall(isStringConstant) =>
4040
values.collect { case Literal(Constant(value: String)) => value }
4141
case tree =>
42-
qctx.error(s"String literal expected, but ${tree.showExtractors} found")
42+
Reporting.error(s"String literal expected, but ${tree.showExtractors} found")
4343
return '{???}
4444
}
4545

tests/run-macros/i5941/macro_1.scala

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ object Lens {
5353
apply($getter)(setter)
5454
}
5555
case _ =>
56-
qctx.error("Unsupported syntax. Example: `GenLens[Address](_.streetNumber)`")
56+
Reporting.error("Unsupported syntax. Example: `GenLens[Address](_.streetNumber)`")
5757
'{???}
5858
}
5959
}
@@ -95,7 +95,7 @@ object Iso {
9595
// 2. A must be a tuple
9696
// 3. The parameters of S must match A
9797
if (tpS.classSymbol.flatMap(cls => if (cls.flags.is(Flags.Case)) Some(true) else None).isEmpty) {
98-
qctx.error("Only support generation for case classes")
98+
Reporting.error("Only support generation for case classes")
9999
return '{???}
100100
}
101101

@@ -106,13 +106,13 @@ object Iso {
106106
}
107107

108108
if (cls.caseFields.size != 1) {
109-
qctx.error("Use GenIso.fields for case classes more than one parameter")
109+
Reporting.error("Use GenIso.fields for case classes more than one parameter")
110110
return '{???}
111111
}
112112

113113
val fieldTp = tpS.memberType(cls.caseFields.head)
114114
if (!(fieldTp =:= tpA)) {
115-
qctx.error(s"The type of case class field $fieldTp does not match $tpA")
115+
Reporting.error(s"The type of case class field $fieldTp does not match $tpA")
116116
'{???}
117117
} else '{
118118
// (p: S) => p._1
@@ -139,7 +139,7 @@ object Iso {
139139
val cls = tpS.classSymbol.get
140140

141141
if (cls.caseFields.size != 0) {
142-
qctx.error("Use GenIso.fields for case classes more than one parameter")
142+
Reporting.error("Use GenIso.fields for case classes more than one parameter")
143143
return '{???}
144144
}
145145

@@ -154,7 +154,7 @@ object Iso {
154154
}
155155
}
156156
else {
157-
qctx.error("Only support generation for case classes or singleton types")
157+
Reporting.error("Only support generation for case classes or singleton types")
158158
'{???}
159159
}
160160
}

tests/run-macros/i8671/Macro_1.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,11 @@ object FileName {
1818
case Right(fn) =>
1919
'{FileName.unsafe(${Expr(fn.name)})} // Or `Expr(fn)` if there is a `Liftable[FileName]`
2020
case Left(_) =>
21-
qctx.throwError(s"$s is not a valid file name! It must not contain a /", fileName)
21+
Reporting.throwError(s"$s is not a valid file name! It must not contain a /", fileName)
2222
}
2323

2424
case _ =>
25-
qctx.throwError(s"$fileName is not a valid file name. It must be a literal string", fileName)
25+
Reporting.throwError(s"$fileName is not a valid file name. It must be a literal string", fileName)
2626
}
2727
}
2828

tests/run-macros/refined-selectable-macro/Macro_1.scala

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ object Macro {
2323
case _: TypeBounds =>
2424
rec(parent)
2525
case _: MethodType | _: PolyType | _: TypeBounds | _: ByNameType =>
26-
qctx.warning(s"Ignored `$name` as a field of the record", s)
26+
Reporting.warning(s"Ignored `$name` as a field of the record", s)
2727
rec(parent)
2828
case info: Type =>
2929
(name, info) :: rec(parent)
@@ -57,10 +57,10 @@ object Macro {
5757
// Tuple2(S, T) where S must be a constant string type
5858
case AppliedType(parent, ConstantType(Constant(name: String)) :: (info: Type) :: Nil) if (parent.typeSymbol == defn.TupleClass(2)) =>
5959
if seen(name) then
60-
qctx.error(s"Repeated record name: $name", s)
60+
Reporting.error(s"Repeated record name: $name", s)
6161
(seen + name, (name, info))
6262
case _ =>
63-
qctx.error("Tuple type was not explicit expected `(S, T)` where S is a singleton string", s)
63+
Reporting.error("Tuple type was not explicit expected `(S, T)` where S is a singleton string", s)
6464
(seen, ("<error>", defn.AnyType))
6565
}
6666
}
@@ -79,7 +79,7 @@ object Macro {
7979
})._2
8080
// Tuple
8181
case _ =>
82-
qctx.error("Tuple type must be of known size", s)
82+
Reporting.error("Tuple type must be of known size", s)
8383
Nil
8484
}
8585
}

tests/run-macros/string-context-implicits/Macro_1.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,14 +11,14 @@ private def showMeExpr(sc: Expr[StringContext], argsExpr: Expr[Seq[Any]])(using
1111
val showTp = '[Show[$tp]]
1212
Expr.summon(using showTp) match {
1313
case Some(showExpr) => '{ $showExpr.show($arg) }
14-
case None => qctx.error(s"could not find implicit for ${showTp.show}", arg); '{???}
14+
case None => Reporting.error(s"could not find implicit for ${showTp.show}", arg); '{???}
1515
}
1616
}
1717
val newArgsExpr = Varargs(argShowedExprs)
1818
'{ $sc.s($newArgsExpr: _*) }
1919
case _ =>
2020
// `new StringContext(...).showMeExpr(args: _*)` not an explicit `showMeExpr"..."`
21-
qctx.error(s"Args must be explicit", argsExpr)
21+
Reporting.error(s"Args must be explicit", argsExpr)
2222
'{???}
2323
}
2424
}

tests/run-macros/tasty-interpolation-1/Macro.scala

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
import scala.quoted._
33
import scala.language.implicitConversions
44
import scala.quoted.autolift
5+
import scala.quoted.Reporting.error
56

67
object Macro {
78

@@ -36,15 +37,15 @@ abstract class MacroStringInterpolator[T] {
3637
catch {
3738
case ex: NotStaticlyKnownError =>
3839
// TODO use ex.expr to recover the position
39-
qctx.error(ex.getMessage)
40+
error(ex.getMessage)
4041
'{???}
4142
case ex: StringContextError =>
4243
// TODO use ex.idx to recover the position
43-
qctx.error(ex.getMessage)
44+
error(ex.getMessage)
4445
'{???}
4546
case ex: ArgumentError =>
4647
// TODO use ex.idx to recover the position
47-
qctx.error(ex.getMessage)
48+
error(ex.getMessage)
4849
'{???}
4950
}
5051
}

tests/run-macros/tasty-macro-const/quoted_1.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,13 @@ object Macros {
1010
xTree match {
1111
case Inlined(_, _, Literal(Constant(n: Int))) =>
1212
if (n <= 0) {
13-
qctx.error("Parameter must be natural number")
13+
Reporting.error("Parameter must be natural number")
1414
'{0}
1515
} else {
1616
xTree.seal.cast[Int]
1717
}
1818
case _ =>
19-
qctx.error("Parameter must be a known constant")
19+
Reporting.error("Parameter must be a known constant")
2020
'{0}
2121
}
2222
}

tests/run-macros/xml-interpolation-1/XmlQuote_1.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ object XmlQuote {
4949
values.forall(isStringConstant) =>
5050
values.collect { case Literal(Constant(value: String)) => value }
5151
case tree =>
52-
qctx.error(s"String literal expected, but ${tree.showExtractors} found")
52+
Reporting.error(s"String literal expected, but ${tree.showExtractors} found")
5353
return '{ ??? }
5454
}
5555

tests/run-macros/xml-interpolation-2/XmlQuote_1.scala

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -44,15 +44,15 @@ object XmlQuote {
4444
values.iterator.map {
4545
case Literal(Constant(value: String)) => value
4646
case _ =>
47-
qctx.error("Expected statically known String")
47+
Reporting.error("Expected statically known String")
4848
return '{???}
4949
}.toList
5050
case _ =>
51-
qctx.error("Expected statically known StringContext")
51+
Reporting.error("Expected statically known StringContext")
5252
return '{???}
5353
}
5454
case _ =>
55-
qctx.error("Expected statically known SCOps")
55+
Reporting.error("Expected statically known SCOps")
5656
return '{???}
5757
}
5858

tests/run-staging/staged-tuples/StagedTuple.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,7 @@ object StagedTuple {
131131
else {
132132
def fallbackApply(): Expr[Elem[Tup, N]] = nValue match {
133133
case Some(n) =>
134-
qctx.error("index out of bounds: " + n, tup)
134+
Reporting.error("index out of bounds: " + n, tup)
135135
'{ throw new IndexOutOfBoundsException(${Expr(n.toString)}) }
136136
case None => '{dynamicApply($tup, $n)}
137137
}

0 commit comments

Comments
 (0)