From 7764f976ea9832ddab9112a57ed07201da63e52d Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Thu, 30 Jan 2020 15:26:44 +0100 Subject: [PATCH 1/3] Remove `implicit` from tasty.Reflection --- community-build/community-projects/utest | 2 +- .../ReflectionCompilerInterface.scala | 4 ++-- .../src/scala/internal/quoted/Matcher.scala | 6 +++-- library/src/scala/tasty/Reflection.scala | 22 +++++++++---------- .../tasty/reflect/CompilerInterface.scala | 4 ++-- .../macros-in-same-project-6/Foo.scala | 2 +- .../quote-matcher-runtime/quoted_1.scala | 2 +- .../quote-type-matcher/quoted_1.scala | 2 +- 8 files changed, 23 insertions(+), 21 deletions(-) diff --git a/community-build/community-projects/utest b/community-build/community-projects/utest index e1f7a918da2e..e0e59628c321 160000 --- a/community-build/community-projects/utest +++ b/community-build/community-projects/utest @@ -1 +1 @@ -Subproject commit e1f7a918da2eec8ad1740c614f9cbc6cbdb13fd5 +Subproject commit e0e59628c321e213a098feb94a7d4b258266c422 diff --git a/compiler/src/dotty/tools/dotc/tastyreflect/ReflectionCompilerInterface.scala b/compiler/src/dotty/tools/dotc/tastyreflect/ReflectionCompilerInterface.scala index 006ff0450662..b844e1067e7b 100644 --- a/compiler/src/dotty/tools/dotc/tastyreflect/ReflectionCompilerInterface.scala +++ b/compiler/src/dotty/tools/dotc/tastyreflect/ReflectionCompilerInterface.scala @@ -592,7 +592,7 @@ class ReflectionCompilerInterface(val rootContext: core.Contexts.Context) extend def Closure_copy(original: Tree)(meth: Tree, tpe: Option[Type])(given Context): Closure = tpd.cpy.Closure(original)(Nil, meth, tpe.map(tpd.TypeTree(_)).getOrElse(tpd.EmptyTree)) - def Lambda_apply(tpe: MethodType, rhsFn: List[Tree] => Tree)(implicit ctx: Context): Block = + def Lambda_apply(tpe: MethodType, rhsFn: List[Tree] => Tree)(given ctx: Context): Block = tpd.Lambda(tpe, rhsFn) type If = tpd.If @@ -1204,7 +1204,7 @@ class ReflectionCompilerInterface(val rootContext: core.Contexts.Context) extend case tpe: Types.ConstantType => Some(tpe) case _ => None } - + def ConstantType_apply(const: Constant)(given Context): ConstantType = Types.ConstantType(const) diff --git a/library/src/scala/internal/quoted/Matcher.scala b/library/src/scala/internal/quoted/Matcher.scala index 92224692bab4..b8860f150c8c 100644 --- a/library/src/scala/internal/quoted/Matcher.scala +++ b/library/src/scala/internal/quoted/Matcher.scala @@ -32,7 +32,8 @@ private[quoted] object Matcher { def termMatch(scrutineeTerm: Term, patternTerm: Term, hasTypeSplices: Boolean): Option[Tuple] = { implicit val env: Env = Map.empty if (hasTypeSplices) { - implicit val ctx: Context = internal.Context_GADT_setFreshGADTBounds(rootContext) + val ctx: Context = internal.Context_GADT_setFreshGADTBounds(rootContext) + given Context = ctx val matchings = scrutineeTerm.underlyingArgument =?= patternTerm.underlyingArgument // After matching and doing all subtype checks, we have to aproximate all the type bindings // that we have found and seal them in a quoted.Type @@ -52,7 +53,8 @@ private[quoted] object Matcher { def typeTreeMatch(scrutineeTypeTree: TypeTree, patternTypeTree: TypeTree, hasTypeSplices: Boolean): Option[Tuple] = { implicit val env: Env = Map.empty if (hasTypeSplices) { - implicit val ctx: Context = internal.Context_GADT_setFreshGADTBounds(rootContext) + val ctx: Context = internal.Context_GADT_setFreshGADTBounds(rootContext) + given Context = ctx val matchings = scrutineeTypeTree =?= patternTypeTree // After matching and doing all subtype checks, we have to aproximate all the type bindings // that we have found and seal them in a quoted.Type diff --git a/library/src/scala/tasty/Reflection.scala b/library/src/scala/tasty/Reflection.scala index 9c5f2edeb4f9..cd73378f94ef 100644 --- a/library/src/scala/tasty/Reflection.scala +++ b/library/src/scala/tasty/Reflection.scala @@ -452,7 +452,7 @@ class Reflection(private[scala] val internal: CompilerInterface) { self => ////////////// /** Context of the macro expansion */ - implicit def rootContext: Context = internal.rootContext // TODO: Use given // TODO: Should this be moved to QuoteContext? + given rootContext: Context = internal.rootContext // TODO: Use given // TODO: Should this be moved to QuoteContext? given ContextOps: extension (self: Context) { /** Returns the owner of the context */ @@ -1009,7 +1009,7 @@ class Reflection(private[scala] val internal: CompilerInterface) { self => case _ => None } - def apply(tpe: MethodType, rhsFn: List[Tree] => Tree)(implicit ctx: Context): Block = + def apply(tpe: MethodType, rhsFn: List[Tree] => Tree)(given ctx: Context): Block = internal.Lambda_apply(tpe, rhsFn) } @@ -2742,7 +2742,7 @@ class Reflection(private[scala] val internal: CompilerInterface) { self => def foldTrees(x: X, trees: Iterable[Tree])(given ctx: Context): X = trees.foldLeft(x)(foldTree) def foldOverTree(x: X, tree: Tree)(given ctx: Context): X = { - def localCtx(definition: Definition): Context = definition.symbol.localContext + lazy val localCtx: Context = tree.symbol.localContext tree match { case Ident(_) => x @@ -2785,16 +2785,16 @@ class Reflection(private[scala] val internal: CompilerInterface) { self => case Inlined(call, bindings, expansion) => foldTree(foldTrees(x, bindings), expansion) case vdef @ ValDef(_, tpt, rhs) => - implicit val ctx = localCtx(vdef) + given Context = localCtx foldTrees(foldTree(x, tpt), rhs) case ddef @ DefDef(_, tparams, vparamss, tpt, rhs) => - implicit val ctx = localCtx(ddef) + given Context = localCtx foldTrees(foldTree(vparamss.foldLeft(foldTrees(x, tparams))(foldTrees), tpt), rhs) case tdef @ TypeDef(_, rhs) => - implicit val ctx = localCtx(tdef) + given Context = localCtx foldTree(x, rhs) case cdef @ ClassDef(_, constr, parents, derived, self, body) => - implicit val ctx = localCtx(cdef) + given Context = localCtx foldTrees(foldTrees(foldTrees(foldTrees(foldTree(x, constr), parents), derived), self), body) case Import(expr, _) => foldTree(x, expr) @@ -2862,20 +2862,20 @@ class Reflection(private[scala] val internal: CompilerInterface) { self => } def transformStatement(tree: Statement)(given ctx: Context): Statement = { - def localCtx(definition: Definition): Context = definition.symbol.localContext + lazy val localCtx: Context = tree.symbol.localContext tree match { case tree: Term => transformTerm(tree) case tree: ValDef => - implicit val ctx = localCtx(tree) + given Context = localCtx val tpt1 = transformTypeTree(tree.tpt) val rhs1 = tree.rhs.map(x => transformTerm(x)) ValDef.copy(tree)(tree.name, tpt1, rhs1) case tree: DefDef => - implicit val ctx = localCtx(tree) + given Context = localCtx DefDef.copy(tree)(tree.name, transformSubTrees(tree.typeParams), tree.paramss mapConserve (transformSubTrees(_)), transformTypeTree(tree.returnTpt), tree.rhs.map(x => transformTerm(x))) case tree: TypeDef => - implicit val ctx = localCtx(tree) + given Context = localCtx TypeDef.copy(tree)(tree.name, transformTree(tree.rhs)) case tree: ClassDef => ClassDef.copy(tree)(tree.name, tree.constructor, tree.parents, tree.derived, tree.self, tree.body) diff --git a/library/src/scala/tasty/reflect/CompilerInterface.scala b/library/src/scala/tasty/reflect/CompilerInterface.scala index 7cd5e1fbdc6a..0ca5e0720e8f 100644 --- a/library/src/scala/tasty/reflect/CompilerInterface.scala +++ b/library/src/scala/tasty/reflect/CompilerInterface.scala @@ -455,7 +455,7 @@ trait CompilerInterface { def Closure_apply(meth: Term, tpe: Option[Type])(given ctx: Context): Closure def Closure_copy(original: Tree)(meth: Tree, tpe: Option[Type])(given ctx: Context): Closure - def Lambda_apply(tpe: MethodType, rhsFn: List[Tree] => Tree)(implicit ctx: Context): Block + def Lambda_apply(tpe: MethodType, rhsFn: List[Tree] => Tree)(given ctx: Context): Block /** Tree representing an if/then/else `if (...) ... else ...` in the source code */ type If <: Term @@ -1043,7 +1043,7 @@ trait CompilerInterface { def isInstanceOfPolyType(given ctx: Context): IsInstanceOf[PolyType] - def PolyType_apply(paramNames: List[String])(paramBoundsExp: PolyType => List[TypeBounds], resultTypeExp: PolyType => Type)(given ctx: Context): PolyType + def PolyType_apply(paramNames: List[String])(paramBoundsExp: PolyType => List[TypeBounds], resultTypeExp: PolyType => Type)(given ctx: Context): PolyType def PolyType_param(self: PolyType, idx: Int)(given ctx: Context): Type def PolyType_paramNames(self: PolyType)(given ctx: Context): List[String] diff --git a/tests/neg-macros/macros-in-same-project-6/Foo.scala b/tests/neg-macros/macros-in-same-project-6/Foo.scala index 116cae3a15b7..f6b18d49bfb5 100644 --- a/tests/neg-macros/macros-in-same-project-6/Foo.scala +++ b/tests/neg-macros/macros-in-same-project-6/Foo.scala @@ -5,7 +5,7 @@ object Foo { inline def myMacro(): Unit = ${ aMacroImplementation } def aMacroImplementation with (qctx: QuoteContext) : Expr[Unit] = { - import qctx.tasty._ + import qctx.tasty.{given, _} error("some error", rootPosition) throw new NoClassDefFoundError("Bar$") } diff --git a/tests/run-macros/quote-matcher-runtime/quoted_1.scala b/tests/run-macros/quote-matcher-runtime/quoted_1.scala index bc946744f502..3fec31faaf26 100644 --- a/tests/run-macros/quote-matcher-runtime/quoted_1.scala +++ b/tests/run-macros/quote-matcher-runtime/quoted_1.scala @@ -7,7 +7,7 @@ object Macros { inline def matches[A, B](inline a: A, inline b: B): Unit = ${impl('a, 'b)} private def impl[A, B](a: Expr[A], b: Expr[B]) with (qctx: QuoteContext) : Expr[Unit] = { - import qctx.tasty.{Bind => _, _} + import qctx.tasty.{Bind => _, given, _} val res = scala.internal.quoted.Expr.unapply[Tuple, Tuple](a)(b, true, qctx).map { tup => tup.toArray.toList.map { diff --git a/tests/run-macros/quote-type-matcher/quoted_1.scala b/tests/run-macros/quote-type-matcher/quoted_1.scala index 23daadda021c..425dc5948e78 100644 --- a/tests/run-macros/quote-type-matcher/quoted_1.scala +++ b/tests/run-macros/quote-type-matcher/quoted_1.scala @@ -7,7 +7,7 @@ object Macros { inline def matches[A, B]: Unit = ${ matchesExpr('[A], '[B]) } private def matchesExpr[A, B](a: Type[A], b: Type[B]) with (qctx: QuoteContext) : Expr[Unit] = { - import qctx.tasty.{Bind => _, _} + import qctx.tasty.{Bind => _, given, _} val res = scala.internal.quoted.Type.unapply[Tuple, Tuple](a)(b, true, qctx).map { tup => tup.toArray.toList.map { From e8206d7160df6bb7f4ba54ecd72988b94c6780a4 Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Thu, 30 Jan 2020 15:43:26 +0100 Subject: [PATCH 2/3] Use extension methods --- library/src/scala/tasty/Reflection.scala | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/library/src/scala/tasty/Reflection.scala b/library/src/scala/tasty/Reflection.scala index cd73378f94ef..28446495c1b2 100644 --- a/library/src/scala/tasty/Reflection.scala +++ b/library/src/scala/tasty/Reflection.scala @@ -419,32 +419,32 @@ class Reflection(private[scala] val internal: CompilerInterface) { self => // QUOTES // //////////////// - implicit class QuotedExprAPI[T](expr: scala.quoted.Expr[T]) { + given QuotedExprOps: extension (expr: scala.quoted.Expr[?]) { /** View this expression `quoted.Expr[T]` as a `Term` */ def unseal(given ctx: Context): Term = internal.QuotedExpr_unseal(expr) /** Checked cast to a `quoted.Expr[U]` */ - def cast[U: scala.quoted.Type](given ctx: Context): scala.quoted.Expr[U] = + def cast[U](given tp: scala.quoted.Type[U], ctx: Context): scala.quoted.Expr[U] = internal.QuotedExpr_cast[U](expr) } - implicit class QuotedTypeAPI[T <: AnyKind](tpe: scala.quoted.Type[T]) { + given QuotedTypeAPI: extension [T <: AnyKind](tpe: scala.quoted.Type[T]) { /** View this expression `quoted.Type[T]` as a `TypeTree` */ def unseal(given ctx: Context): TypeTree = internal.QuotedType_unseal(tpe) } - implicit class TermToQuotedAPI(term: Term) { + given TermToQuotedOps: extension (term: Term) { /** Convert `Term` to an `quoted.Expr[Any]` */ def seal(given ctx: Context): scala.quoted.Expr[Any] = internal.QuotedExpr_seal(term) } - implicit class TypeToQuotedAPI(tpe: Type) { - /** Convert `Type` to an `quoted.Type[_]` */ - def seal(given ctx: Context): scala.quoted.Type[_] = - internal.QuotedType_seal(tpe) + given TypeToQuotedOps: extension (tpe: Type) { + /** Convert `Type` to an `quoted.Type[_]` */ + def seal(given ctx: Context): scala.quoted.Type[_] = + internal.QuotedType_seal(tpe) } ////////////// From a04c9c444f45503d31838c62d3e08779bdbfa487 Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Fri, 31 Jan 2020 11:54:42 +0100 Subject: [PATCH 3/3] Address review comments --- library/src/scala/tasty/Reflection.scala | 31 +++++++++++++++--------- 1 file changed, 19 insertions(+), 12 deletions(-) diff --git a/library/src/scala/tasty/Reflection.scala b/library/src/scala/tasty/Reflection.scala index 28446495c1b2..30a47c502bd7 100644 --- a/library/src/scala/tasty/Reflection.scala +++ b/library/src/scala/tasty/Reflection.scala @@ -442,9 +442,9 @@ class Reflection(private[scala] val internal: CompilerInterface) { self => } given TypeToQuotedOps: extension (tpe: Type) { - /** Convert `Type` to an `quoted.Type[_]` */ - def seal(given ctx: Context): scala.quoted.Type[_] = - internal.QuotedType_seal(tpe) + /** Convert `Type` to an `quoted.Type[_]` */ + def seal(given ctx: Context): scala.quoted.Type[_] = + internal.QuotedType_seal(tpe) } ////////////// @@ -2742,7 +2742,7 @@ class Reflection(private[scala] val internal: CompilerInterface) { self => def foldTrees(x: X, trees: Iterable[Tree])(given ctx: Context): X = trees.foldLeft(x)(foldTree) def foldOverTree(x: X, tree: Tree)(given ctx: Context): X = { - lazy val localCtx: Context = tree.symbol.localContext + def localCtx(definition: Definition): Context = definition.symbol.localContext tree match { case Ident(_) => x @@ -2785,16 +2785,20 @@ class Reflection(private[scala] val internal: CompilerInterface) { self => case Inlined(call, bindings, expansion) => foldTree(foldTrees(x, bindings), expansion) case vdef @ ValDef(_, tpt, rhs) => - given Context = localCtx + val ctx = localCtx(vdef) + given Context = ctx foldTrees(foldTree(x, tpt), rhs) case ddef @ DefDef(_, tparams, vparamss, tpt, rhs) => - given Context = localCtx + val ctx = localCtx(ddef) + given Context = ctx foldTrees(foldTree(vparamss.foldLeft(foldTrees(x, tparams))(foldTrees), tpt), rhs) case tdef @ TypeDef(_, rhs) => - given Context = localCtx + val ctx = localCtx(tdef) + given Context = ctx foldTree(x, rhs) case cdef @ ClassDef(_, constr, parents, derived, self, body) => - given Context = localCtx + val ctx = localCtx(cdef) + given Context = ctx foldTrees(foldTrees(foldTrees(foldTrees(foldTree(x, constr), parents), derived), self), body) case Import(expr, _) => foldTree(x, expr) @@ -2862,20 +2866,23 @@ class Reflection(private[scala] val internal: CompilerInterface) { self => } def transformStatement(tree: Statement)(given ctx: Context): Statement = { - lazy val localCtx: Context = tree.symbol.localContext + def localCtx(definition: Definition): Context = definition.symbol.localContext tree match { case tree: Term => transformTerm(tree) case tree: ValDef => - given Context = localCtx + val ctx = localCtx(tree) + given Context = ctx val tpt1 = transformTypeTree(tree.tpt) val rhs1 = tree.rhs.map(x => transformTerm(x)) ValDef.copy(tree)(tree.name, tpt1, rhs1) case tree: DefDef => - given Context = localCtx + val ctx = localCtx(tree) + given Context = ctx DefDef.copy(tree)(tree.name, transformSubTrees(tree.typeParams), tree.paramss mapConserve (transformSubTrees(_)), transformTypeTree(tree.returnTpt), tree.rhs.map(x => transformTerm(x))) case tree: TypeDef => - given Context = localCtx + val ctx = localCtx(tree) + given Context = ctx TypeDef.copy(tree)(tree.name, transformTree(tree.rhs)) case tree: ClassDef => ClassDef.copy(tree)(tree.name, tree.constructor, tree.parents, tree.derived, tree.self, tree.body)