diff --git a/compiler/src/dotty/tools/dotc/transform/Splicer.scala b/compiler/src/dotty/tools/dotc/transform/Splicer.scala index addc3edd6e07..5e44e98ce445 100644 --- a/compiler/src/dotty/tools/dotc/transform/Splicer.scala +++ b/compiler/src/dotty/tools/dotc/transform/Splicer.scala @@ -250,7 +250,7 @@ object Splicer { interpretModuleAccess(fn.symbol) else if (fn.symbol.is(Method) && fn.symbol.isStatic) { val staticMethodCall = interpretedStaticMethodCall(fn.symbol.owner, fn.symbol) - staticMethodCall(args.flatten.map(interpretTree)) + staticMethodCall(interpretArgs(args, fn.symbol.info)) } else if fn.symbol.isStatic then assert(args.isEmpty) @@ -260,7 +260,7 @@ object Splicer { interpretModuleAccess(fn.qualifier.symbol) else { val staticMethodCall = interpretedStaticMethodCall(fn.qualifier.symbol.moduleClass, fn.symbol) - staticMethodCall(args.flatten.map(interpretTree)) + staticMethodCall(interpretArgs(args, fn.symbol.info)) } else if (env.contains(fn.symbol)) env(fn.symbol) @@ -289,6 +289,32 @@ object Splicer { unexpectedTree(tree) } + private def interpretArgs(argss: List[List[Tree]], fnType: Type)(using Env): List[Object] = { + def interpretArgsGroup(args: List[Tree], argTypes: List[Type]): List[Object] = + assert(args.size == argTypes.size) + val view = + for (arg, info) <- args.lazyZip(argTypes) yield + info match + case _: ExprType => () => interpretTree(arg) // by-name argument + case _ => interpretTree(arg) // by-value argument + view.toList + + fnType.dealias match + case fnType: MethodType if fnType.isErasedMethod => interpretArgs(argss, fnType.resType) + case fnType: MethodType => + val argTypes = fnType.paramInfos + assert(argss.head.size == argTypes.size) + interpretArgsGroup(argss.head, argTypes) ::: interpretArgs(argss.tail, fnType.resType) + case fnType: AppliedType if defn.isContextFunctionType(fnType) => + val argTypes :+ resType = fnType.args + interpretArgsGroup(argss.head, argTypes) ::: interpretArgs(argss.tail, resType) + case fnType: PolyType => interpretArgs(argss, fnType.resType) + case fnType: ExprType => interpretArgs(argss, fnType.resType) + case _ => + assert(argss.isEmpty) + Nil + } + private def interpretBlock(stats: List[Tree], expr: Tree)(implicit env: Env) = { var unexpected: Option[Object] = None val newEnv = stats.foldLeft(env)((accEnv, stat) => stat match { diff --git a/tests/pos-macros/i9802/Macro_1.scala b/tests/pos-macros/i9802/Macro_1.scala new file mode 100644 index 000000000000..e2a65a507fb7 --- /dev/null +++ b/tests/pos-macros/i9802/Macro_1.scala @@ -0,0 +1,5 @@ +import scala.quoted._ + +inline def fun(inline prog: Double): Double = ${impl('prog)} + +def impl(prog: => Expr[Double])(using QuoteContext) : Expr[Double] = '{ 42.0 } diff --git a/tests/pos-macros/i9802/Test_2.scala b/tests/pos-macros/i9802/Test_2.scala new file mode 100644 index 000000000000..ee31da4d3930 --- /dev/null +++ b/tests/pos-macros/i9802/Test_2.scala @@ -0,0 +1,2 @@ + +def test: Unit = fun(4) \ No newline at end of file diff --git a/tests/run-macros/tasty-getfile-implicit-by-name-fun-context/App_2.scala b/tests/run-macros/tasty-getfile-implicit-by-name-fun-context/App_2.scala new file mode 100644 index 000000000000..ca5531badfc7 --- /dev/null +++ b/tests/run-macros/tasty-getfile-implicit-by-name-fun-context/App_2.scala @@ -0,0 +1,6 @@ + +object Test { + def main(args: Array[String]): Unit = { + println(SourceFiles.getThisFile) + } +} diff --git a/tests/run-macros/tasty-getfile-implicit-by-name-fun-context/Macro_1.scala b/tests/run-macros/tasty-getfile-implicit-by-name-fun-context/Macro_1.scala new file mode 100644 index 000000000000..41bdf97554f0 --- /dev/null +++ b/tests/run-macros/tasty-getfile-implicit-by-name-fun-context/Macro_1.scala @@ -0,0 +1,13 @@ +import scala.quoted._ + +object SourceFiles { + + type Macro[X] = (=> QuoteContext) ?=> Expr[X] + + implicit inline def getThisFile: String = + ${getThisFileImpl} + + def getThisFileImpl: Macro[String] = + Expr(qctx.tasty.Source.path.getFileName.toString) + +}