Skip to content

Commit 13487ca

Browse files
Merge pull request #4899 from dotty-staging/fix-#4515
Fix #4515: Synthesize implicit type tags in transparent methods
2 parents 2e834ea + ef22195 commit 13487ca

File tree

31 files changed

+69
-45
lines changed

31 files changed

+69
-45
lines changed

compiler/src/dotty/tools/dotc/core/Definitions.scala

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -686,8 +686,11 @@ class Definitions {
686686
def Unpickler_liftedExpr = ctx.requiredMethod("scala.runtime.quoted.Unpickler.liftedExpr")
687687
def Unpickler_unpickleType = ctx.requiredMethod("scala.runtime.quoted.Unpickler.unpickleType")
688688

689-
lazy val TastyTopLevelSpliceModule = ctx.requiredModule("scala.tasty.TopLevelSplice")
690-
lazy val TastyTopLevelSplice_tastyContext = TastyTopLevelSpliceModule.requiredMethod("tastyContext")
689+
lazy val TastyTastyType = ctx.requiredClassRef("scala.tasty.Tasty")
690+
def TastyTastyClass(implicit ctx: Context) = TastyTastyType.symbol.asClass
691+
692+
lazy val TastyTastyModule = ctx.requiredModule("scala.tasty.Tasty")
693+
lazy val TastyTasty_macroContext = TastyTastyModule.requiredMethod("macroContext")
691694

692695
lazy val EqType = ctx.requiredClassRef("scala.Eq")
693696
def EqClass(implicit ctx: Context) = EqType.symbol.asClass

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -237,7 +237,7 @@ class ReifyQuotes extends MacroTransformWithImplicits {
237237
def levelOK(sym: Symbol)(implicit ctx: Context): Boolean = levelOf.get(sym) match {
238238
case Some(l) =>
239239
l == level ||
240-
level == -1 && sym == defn.TastyTopLevelSplice_tastyContext
240+
level == -1 && sym == defn.TastyTasty_macroContext
241241
case None =>
242242
!sym.is(Param) || levelOK(sym.owner)
243243
}

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

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -268,7 +268,7 @@ object Splicer {
268268
case Literal(Constant(value)) =>
269269
interpretLiteral(value)
270270

271-
case _ if tree.symbol == defn.TastyTopLevelSplice_tastyContext =>
271+
case _ if tree.symbol == defn.TastyTasty_macroContext =>
272272
interpretTastyContext()
273273

274274
case StaticMethodCall(fn, args) =>
@@ -286,6 +286,8 @@ object Splicer {
286286
case NamedArg(_, arg) => interpretTree(arg)
287287
case Ident(name) if env.contains(name) => env(name)
288288

289+
case Inlined(EmptyTree, Nil, expansion) => interpretTree(expansion)
290+
289291
case _ => unexpectedTree(tree)
290292
}
291293

compiler/src/dotty/tools/dotc/typer/Implicits.scala

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -620,10 +620,16 @@ trait Implicits { self: Typer =>
620620
val tag = bindFreeVars(arg)
621621
if (bindFreeVars.ok) ref(defn.QuotedType_apply).appliedToType(tag)
622622
else EmptyTree
623+
case arg :: Nil if ctx.inRewriteMethod =>
624+
ref(defn.QuotedType_apply).appliedToType(arg)
623625
case _ =>
624626
EmptyTree
625627
}
626628

629+
def synthesizedTastyContext(formal: Type): Tree =
630+
if (ctx.inRewriteMethod || enclosingInlineds.nonEmpty) ref(defn.TastyTasty_macroContext)
631+
else EmptyTree
632+
627633
/** If `formal` is of the form Eq[T, U], where no `Eq` instance exists for
628634
* either `T` or `U`, synthesize `Eq.eqAny[T, U]` as solution.
629635
*/
@@ -694,7 +700,8 @@ trait Implicits { self: Typer =>
694700
else
695701
trySpecialCase(defn.ClassTagClass, synthesizedClassTag,
696702
trySpecialCase(defn.QuotedTypeClass, synthesizedTypeTag,
697-
trySpecialCase(defn.EqClass, synthesizedEq, failed)))
703+
trySpecialCase(defn.TastyTastyClass, synthesizedTastyContext,
704+
trySpecialCase(defn.EqClass, synthesizedEq, failed))))
698705
}
699706
}
700707

library/src/scala/tasty/Tasty.scala

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,3 +19,8 @@ abstract class Tasty
1919
with TreeOps
2020
with TypeOrBoundsTreeOps
2121
with TypeOrBoundsOps
22+
23+
object Tasty {
24+
/** Compiler tasty context available in a top level ~ of a transparent macro */
25+
def macroContext: Tasty = throw new Exception("Not in transparent macro.")
26+
}

library/src/scala/tasty/TopLevelSplice.scala

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

tests/neg/tasty-macro-assert/quoted_1.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ object Asserts {
1212
object Ops
1313

1414
rewrite def macroAssert(cond: => Boolean): Unit =
15-
~impl('(cond))(TopLevelSplice.tastyContext) // FIXME infer TopLevelSplice.tastyContext within top level ~
15+
~impl('(cond))
1616

1717
def impl(cond: Expr[Boolean])(implicit tasty: Tasty): Expr[Unit] = {
1818
import tasty._

tests/run-with-compiler/tasty-extractors-constants-2/quoted_1.scala

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,7 @@ import scala.tasty.util._
66

77
object Macros {
88

9-
rewrite def testMacro: Unit =
10-
~impl(TopLevelSplice.tastyContext) // FIXME infer TopLevelSplice.tastyContext within top level ~
9+
rewrite def testMacro: Unit = ~impl
1110

1211
def impl(implicit tasty: Tasty): Expr[Unit] = {
1312
// 2 is a lifted constant

tests/run/i4515/Macro_1.scala

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
2+
object Macro {
3+
rewrite def foo[X](x: X): Unit = ~fooImpl('(x))
4+
def fooImpl[X: quoted.Type](x: quoted.Expr[X]): quoted.Expr[Unit] = '()
5+
}

tests/run/i4515/Test_2.scala

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
2+
object Test {
3+
def main(args: Array[String]): Unit = {
4+
Macro.foo(4)
5+
}
6+
}

0 commit comments

Comments
 (0)