From e8a85e6ebae39a10c2dd9e257f045725925f4d47 Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Wed, 25 Oct 2023 13:36:24 +0200 Subject: [PATCH] Properly handle by-name function types in repl Fixes #18756 --- .../dotty/tools/dotc/transform/ElimByName.scala | 15 +++++++++++---- .../dotc/transform/SpecializeFunctions.scala | 5 ++++- compiler/test-resources/repl/i18756 | 5 +++++ 3 files changed, 20 insertions(+), 5 deletions(-) create mode 100644 compiler/test-resources/repl/i18756 diff --git a/compiler/src/dotty/tools/dotc/transform/ElimByName.scala b/compiler/src/dotty/tools/dotc/transform/ElimByName.scala index 151e841f0e48..225541ba813a 100644 --- a/compiler/src/dotty/tools/dotc/transform/ElimByName.scala +++ b/compiler/src/dotty/tools/dotc/transform/ElimByName.scala @@ -131,12 +131,19 @@ class ElimByName extends MiniPhase, InfoTransformer: override def transformApply(tree: Apply)(using Context): Tree = trace(s"transforming ${tree.show} at phase ${ctx.phase}", show = true) { - + def stripTyped(t: Tree): Tree = t match + case Typed(expr, _) => stripTyped(expr) + case _ => t def transformArg(arg: Tree, formal: Type): Tree = formal match case defn.ByNameFunction(formalResult) => - def stripTyped(t: Tree): Tree = t match - case Typed(expr, _) => stripTyped(expr) - case _ => t + stripTyped(arg) match + case Apply(Select(qual, nme.apply), Nil) + if isByNameRef(qual) && (isPureExpr(qual) || qual.symbol.isAllOf(InlineParam)) => + qual + case _ => + if isByNameRef(arg) || arg.symbol.name.is(SuperArgName) then arg + else byNameClosure(arg, formalResult) + case ExprType(formalResult) => stripTyped(arg) match case Apply(Select(qual, nme.apply), Nil) if isByNameRef(qual) && (isPureExpr(qual) || qual.symbol.isAllOf(InlineParam)) => diff --git a/compiler/src/dotty/tools/dotc/transform/SpecializeFunctions.scala b/compiler/src/dotty/tools/dotc/transform/SpecializeFunctions.scala index c50eaddd3213..4eef58b77a5e 100644 --- a/compiler/src/dotty/tools/dotc/transform/SpecializeFunctions.scala +++ b/compiler/src/dotty/tools/dotc/transform/SpecializeFunctions.scala @@ -71,7 +71,10 @@ class SpecializeFunctions extends MiniPhase { override def transformApply(tree: Apply)(using Context) = tree match { case Apply(fun: NameTree, args) if fun.name == nme.apply && args.size <= 3 && fun.symbol.maybeOwner.isType => - val argTypes = fun.tpe.widen.firstParamTypes.map(_.widenSingleton.dealias) + val argTypes = fun.tpe.widen.firstParamTypes.map(_.widenSingleton.dealias).map { + case ExprType(resType) => defn.FunctionOf(Nil, resType, isContextual = true) + case arg => arg + } val retType = tree.tpe.widenSingleton.dealias val isSpecializable = defn.isSpecializableFunction( diff --git a/compiler/test-resources/repl/i18756 b/compiler/test-resources/repl/i18756 new file mode 100644 index 000000000000..722c665999b6 --- /dev/null +++ b/compiler/test-resources/repl/i18756 @@ -0,0 +1,5 @@ +scala> def f: ( => Int) => Int = i => i ; f(1) +def f: (=> Int) => Int +val res0: Int = 1 +scala> f(1) +val res1: Int = 1