diff --git a/compiler/src/dotty/tools/dotc/quoted/PickledQuotes.scala b/compiler/src/dotty/tools/dotc/quoted/PickledQuotes.scala index f40f010391cc..a6aca70e2b60 100644 --- a/compiler/src/dotty/tools/dotc/quoted/PickledQuotes.scala +++ b/compiler/src/dotty/tools/dotc/quoted/PickledQuotes.scala @@ -39,14 +39,14 @@ object PickledQuotes { /** Transform the expression into its fully spliced Tree */ def quotedExprToTree[T](expr: quoted.Expr[T])(using Context): Tree = { - val expr1 = expr.asInstanceOf[scala.internal.quoted.Expr[Tree]] + val expr1 = expr.asInstanceOf[scala.quoted.internal.Expr] expr1.checkScopeId(QuoteContextImpl.scopeId) changeOwnerOfTree(expr1.tree, ctx.owner) } /** Transform the expression into its fully spliced TypeTree */ def quotedTypeToTree(tpe: quoted.Type[?])(using Context): Tree = { - val tpe1 = tpe.asInstanceOf[scala.internal.quoted.Type[Tree]] + val tpe1 = tpe.asInstanceOf[scala.quoted.internal.Type] tpe1.checkScopeId(QuoteContextImpl.scopeId) changeOwnerOfTree(tpe1.typeTree, ctx.owner) } @@ -75,8 +75,8 @@ object PickledQuotes { override def transform(tree: tpd.Tree)(using Context): tpd.Tree = tree match { case Hole(isTerm, idx, args) => val reifiedArgs = args.map { arg => - if (arg.isTerm) (using qctx: QuoteContext) => new scala.internal.quoted.Expr(arg, QuoteContextImpl.scopeId) - else new scala.internal.quoted.Type(arg, QuoteContextImpl.scopeId) + if (arg.isTerm) (using qctx: QuoteContext) => new scala.quoted.internal.Expr(arg, QuoteContextImpl.scopeId) + else new scala.quoted.internal.Type(arg, QuoteContextImpl.scopeId) } if isTerm then val quotedExpr = pickledQuote.exprSplice(idx)(reifiedArgs)(dotty.tools.dotc.quoted.QuoteContextImpl()) diff --git a/compiler/src/dotty/tools/dotc/quoted/QuoteContextImpl.scala b/compiler/src/dotty/tools/dotc/quoted/QuoteContextImpl.scala index 668fa7d71547..9a067b77a19f 100644 --- a/compiler/src/dotty/tools/dotc/quoted/QuoteContextImpl.scala +++ b/compiler/src/dotty/tools/dotc/quoted/QuoteContextImpl.scala @@ -72,7 +72,7 @@ class QuoteContextImpl private (ctx: Context) extends QuoteContext, scala.intern case _ => false def asExpr: scala.quoted.Expr[Any] = if self.isExpr then - new scala.internal.quoted.Expr(self, QuoteContextImpl.this.hashCode) + new scala.quoted.internal.Expr(self, QuoteContextImpl.this.hashCode) else self match case TermTypeTest(self) => throw new Exception("Expected an expression. This is a partially applied Term. Try eta-expanding the term first.") case _ => throw new Exception("Expected a Term but was: " + self) @@ -316,11 +316,11 @@ class QuoteContextImpl private (ctx: Context) extends QuoteContext, scala.intern object TermMethodsImpl extends TermMethods: extension (self: Term): def seal: scala.quoted.Expr[Any] = - if self.isExpr then new scala.internal.quoted.Expr(self, QuoteContextImpl.this.hashCode) + if self.isExpr then new scala.quoted.internal.Expr(self, QuoteContextImpl.this.hashCode) else throw new Exception("Cannot seal a partially applied Term. Try eta-expanding the term first.") def sealOpt: Option[scala.quoted.Expr[Any]] = - if self.isExpr then Some(new scala.internal.quoted.Expr(self, QuoteContextImpl.this.hashCode)) + if self.isExpr then Some(new scala.quoted.internal.Expr(self, QuoteContextImpl.this.hashCode)) else None def tpe: TypeRepr = self.tpe @@ -1003,7 +1003,7 @@ class QuoteContextImpl private (ctx: Context) extends QuoteContext, scala.intern object TypeTree extends TypeTreeModule: def of[T <: AnyKind](using tp: scala.quoted.Type[T]): TypeTree = - tp.asInstanceOf[scala.internal.quoted.Type[TypeTree]].typeTree + tp.asInstanceOf[scala.quoted.internal.Type].typeTree end TypeTree object TypeTreeMethodsImpl extends TypeTreeMethods: @@ -1572,7 +1572,7 @@ class QuoteContextImpl private (ctx: Context) extends QuoteContext, scala.intern object TypeRepr extends TypeReprModule: def of[T <: AnyKind](using tp: scala.quoted.Type[T]): TypeRepr = - tp.asInstanceOf[scala.internal.quoted.Type[TypeTree]].typeTree.tpe + tp.asInstanceOf[scala.quoted.internal.Type].typeTree.tpe def typeConstructorOf(clazz: Class[?]): TypeRepr = if (clazz.isPrimitive) if (clazz == classOf[Boolean]) dotc.core.Symbols.defn.BooleanType @@ -1609,7 +1609,7 @@ class QuoteContextImpl private (ctx: Context) extends QuoteContext, scala.intern def seal: scala.quoted.Type[_] = self.asType def asType: scala.quoted.Type[?] = - new scala.internal.quoted.Type(Inferred(self), QuoteContextImpl.this.hashCode) + new scala.quoted.internal.Type(Inferred(self), QuoteContextImpl.this.hashCode) def =:=(that: TypeRepr): Boolean = self =:= that def <:<(that: TypeRepr): Boolean = self <:< that @@ -2633,11 +2633,11 @@ class QuoteContextImpl private (ctx: Context) extends QuoteContext, scala.intern def unpickleExpr[T](pickledQuote: PickledQuote): scala.quoted.Expr[T] = val tree = PickledQuotes.unpickleTerm(pickledQuote)(using reflect.rootContext) - new scala.internal.quoted.Expr(tree, hash).asInstanceOf[scala.quoted.Expr[T]] + new scala.quoted.internal.Expr(tree, hash).asInstanceOf[scala.quoted.Expr[T]] def unpickleType[T <: AnyKind](pickledQuote: PickledQuote): scala.quoted.Type[T] = val tree = PickledQuotes.unpickleTypeTree(pickledQuote)(using reflect.rootContext) - new scala.internal.quoted.Type(tree, hash).asInstanceOf[scala.quoted.Type[T]] + new scala.quoted.internal.Type(tree, hash).asInstanceOf[scala.quoted.Type[T]] object ExprMatch extends ExprMatchModule: def unapply[TypeBindings <: Tuple, Tup <: Tuple](scrutinee: scala.quoted.Expr[Any])(using pattern: scala.quoted.Expr[Any]): Option[Tup] = diff --git a/compiler/src/dotty/tools/dotc/transform/Splicer.scala b/compiler/src/dotty/tools/dotc/transform/Splicer.scala index 5784e543cd30..ef9840ebe27c 100644 --- a/compiler/src/dotty/tools/dotc/transform/Splicer.scala +++ b/compiler/src/dotty/tools/dotc/transform/Splicer.scala @@ -323,10 +323,10 @@ object Splicer { } private def interpretQuote(tree: Tree)(implicit env: Env): Object = - new scala.internal.quoted.Expr(Inlined(EmptyTree, Nil, QuoteUtils.changeOwnerOfTree(tree, ctx.owner)).withSpan(tree.span), QuoteContextImpl.scopeId) + new scala.quoted.internal.Expr(Inlined(EmptyTree, Nil, QuoteUtils.changeOwnerOfTree(tree, ctx.owner)).withSpan(tree.span), QuoteContextImpl.scopeId) private def interpretTypeQuote(tree: Tree)(implicit env: Env): Object = - new scala.internal.quoted.Type(QuoteUtils.changeOwnerOfTree(tree, ctx.owner), QuoteContextImpl.scopeId) + new scala.quoted.internal.Type(QuoteUtils.changeOwnerOfTree(tree, ctx.owner), QuoteContextImpl.scopeId) private def interpretLiteral(value: Any)(implicit env: Env): Object = value.asInstanceOf[Object] diff --git a/library/src-bootstrapped/scala/internal/quoted/Expr.scala b/compiler/src/scala/quoted/internal/Expr.scala similarity index 76% rename from library/src-bootstrapped/scala/internal/quoted/Expr.scala rename to compiler/src/scala/quoted/internal/Expr.scala index 2472dfd068a5..59dabafa6cc0 100644 --- a/library/src-bootstrapped/scala/internal/quoted/Expr.scala +++ b/compiler/src/scala/quoted/internal/Expr.scala @@ -1,7 +1,9 @@ -package scala.internal.quoted +package scala.quoted.internal import scala.quoted._ +import dotty.tools.dotc.ast.tpd + /** An Expr backed by a tree. Only the current compiler trees are allowed. * * These expressions are used for arguments of macros. They contain and actual tree @@ -9,9 +11,9 @@ import scala.quoted._ * * May contain references to code defined outside this Expr instance. */ -final class Expr[Tree](val tree: Tree, val scopeId: Int) extends scala.quoted.Expr[Any] { +final class Expr(val tree: tpd.Tree, val scopeId: Int) extends scala.quoted.Expr[Any] { override def equals(that: Any): Boolean = that match { - case that: Expr[_] => + case that: Expr => // Expr are wrappers around trees, therefore they are equals if their trees are equal. // All scopeId should be equal unless two different runs of the compiler created the trees. tree == that.tree && scopeId == that.scopeId @@ -24,7 +26,7 @@ final class Expr[Tree](val tree: Tree, val scopeId: Int) extends scala.quoted.Ex def checkScopeId(expectedScopeId: Int): Unit = if expectedScopeId != scopeId then - throw new Exception("Cannot call `scala.quoted.staging.run(...)` within a macro or another `run(...)`") + throw new ScopeException("Cannot call `scala.quoted.staging.run(...)` within a macro or another `run(...)`") override def hashCode: Int = tree.hashCode override def toString: String = "'{ ... }" diff --git a/compiler/src/scala/quoted/internal/ScopeException.scala b/compiler/src/scala/quoted/internal/ScopeException.scala new file mode 100644 index 000000000000..e99c77ffb727 --- /dev/null +++ b/compiler/src/scala/quoted/internal/ScopeException.scala @@ -0,0 +1,3 @@ +package scala.quoted.internal + +class ScopeException(msg: String) extends Exception(msg) diff --git a/library/src-bootstrapped/scala/internal/quoted/Type.scala b/compiler/src/scala/quoted/internal/Type.scala similarity index 72% rename from library/src-bootstrapped/scala/internal/quoted/Type.scala rename to compiler/src/scala/quoted/internal/Type.scala index 1f17299f3a01..9eb3c1f55b28 100644 --- a/library/src-bootstrapped/scala/internal/quoted/Type.scala +++ b/compiler/src/scala/quoted/internal/Type.scala @@ -1,11 +1,13 @@ -package scala.internal.quoted +package scala.quoted.internal import scala.quoted._ +import dotty.tools.dotc.ast.tpd + /** Quoted type (or kind) `T` backed by a tree */ -final class Type[Tree](val typeTree: Tree, val scopeId: Int) extends scala.quoted.Type[Any] { +final class Type(val typeTree: tpd.Tree, val scopeId: Int) extends scala.quoted.Type[?] { override def equals(that: Any): Boolean = that match { - case that: Type[_] => typeTree == + case that: Type => typeTree == // TastyTreeExpr are wrappers around trees, therfore they are equals if their trees are equal. // All scopeId should be equal unless two different runs of the compiler created the trees. that.typeTree && scopeId == that.scopeId @@ -19,7 +21,7 @@ final class Type[Tree](val typeTree: Tree, val scopeId: Int) extends scala.quote def checkScopeId(expectedScopeId: Int): Unit = if expectedScopeId != scopeId then - throw new Exception("Cannot call `scala.quoted.staging.run(...)` within a macro or another `run(...)`") + throw new ScopeException("Cannot call `scala.quoted.staging.run(...)` within a macro or another `run(...)`") override def hashCode: Int = typeTree.hashCode override def toString: String = "'[ ... ]" diff --git a/staging/src/scala/quoted/staging/Toolbox.scala b/staging/src/scala/quoted/staging/Toolbox.scala index c0128b151dcb..f9d5f8faa05e 100644 --- a/staging/src/scala/quoted/staging/Toolbox.scala +++ b/staging/src/scala/quoted/staging/Toolbox.scala @@ -3,6 +3,8 @@ package staging import scala.annotation.implicitNotFound +import scala.quoted.internal.ScopeException + @implicitNotFound("Could not find implicit scala.quoted.staging.Toolbox.\n\nDefault toolbox can be instantiated with:\n `given scala.quoted.staging.Toolbox = scala.quoted.staging.Toolbox.make(getClass.getClassLoader)`\n\n") trait Toolbox: def run[T](expr: QuoteContext => Expr[T]): T @@ -31,7 +33,7 @@ object Toolbox: def run[T](exprBuilder: QuoteContext => Expr[T]): T = synchronized { try if (running) // detected nested run - throw new Exception("Cannot call `scala.quoted.staging.run(...)` within a another `run(...)`") + throw new ScopeException("Cannot call `scala.quoted.staging.run(...)` within a another `run(...)`") running = true driver.run(exprBuilder, settings) finally diff --git a/tests/run-staging/i4730.scala b/tests/run-staging/i4730.scala index 36540d2c8082..19a373d78ebf 100644 --- a/tests/run-staging/i4730.scala +++ b/tests/run-staging/i4730.scala @@ -5,7 +5,7 @@ object Test { given Toolbox = Toolbox.make(getClass.getClassLoader) def ret(using QuoteContext): Expr[Int => Int] = '{ (x: Int) => ${ - val z = run('{x + 1}) // throws Exception("Cannot call `scala.quoted.staging.run(...)` within a another `run(...)`") + val z = run('{x + 1}) // throws scala.quoted.internal.ScopeException => Expr(z) } } @@ -21,7 +21,7 @@ package scala { run(Test.ret).apply(10) throw new Exception } catch { - case ex: Exception if ex.getMessage == "Cannot call `scala.quoted.staging.run(...)` within a another `run(...)`" => + case ex: Exception if ex.getClass.getName == "scala.quoted.internal.ScopeException" => // ok } } diff --git a/tests/run-staging/i6754.scala b/tests/run-staging/i6754.scala index 1a228bfff698..7261e734b75e 100644 --- a/tests/run-staging/i6754.scala +++ b/tests/run-staging/i6754.scala @@ -22,7 +22,7 @@ package scala { throw new Exception } catch { case ex: java.lang.reflect.InvocationTargetException => - assert(ex.getTargetException.getMessage == "Cannot call `scala.quoted.staging.run(...)` within a another `run(...)`") + assert(ex.getTargetException.getClass.getName == "scala.quoted.internal.ScopeException") } } } diff --git a/tests/run-staging/i6992/Macro_1.scala b/tests/run-staging/i6992/Macro_1.scala index b7b115cce1d2..7a5bf0317676 100644 --- a/tests/run-staging/i6992/Macro_1.scala +++ b/tests/run-staging/i6992/Macro_1.scala @@ -25,7 +25,7 @@ package scala { case '{$x: Foo} => Expr(run(x).x) } } catch { - case ex: Exception if ex.getMessage == "Cannot call `scala.quoted.staging.run(...)` within a macro or another `run(...)`" => + case ex: Exception if ex.getClass.getName == "scala.quoted.internal.ScopeException" => '{"OK"} } }