Skip to content

Split eta-expansion from seal #7536

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,18 @@ class ReflectionCompilerInterface(val rootContext: core.Contexts.Context) extend
def Term_underlyingArgument(self: Term)(given Context): Term = self.underlyingArgument
def Term_underlying(self: Term)(given Context): Term = self.underlying

def Term_etaExpand(term: Term): Term = term.tpe.widen match {
case mtpe: Types.MethodType if !mtpe.isParamDependent =>
val closureResType = mtpe.resType match {
case t: Types.MethodType => t.toFunctionType()
case t => t
}
val closureTpe = Types.MethodType(mtpe.paramNames, mtpe.paramInfos, closureResType)
val closureMethod = ctx.newSymbol(ctx.owner, nme.ANON_FUN, Synthetic | Method, closureTpe)
tpd.Closure(closureMethod, tss => Term_etaExpand(new tpd.TreeOps(term).appliedToArgs(tss.head)))
case _ => term
}

type Ref = tpd.RefTree

def matchRef(tree: Tree)(given Context): Option[Ref] = tree match {
Expand Down Expand Up @@ -1591,19 +1603,9 @@ class ReflectionCompilerInterface(val rootContext: core.Contexts.Context) extend
PickledQuotes.quotedTypeToTree(self)

/** Convert `Term` to an `quoted.Expr[Any]` */
def QuotedExpr_seal(self: Term)(given ctx: Context): scala.quoted.Expr[Any] = {
def etaExpand(term: Term): Term = term.tpe.widen match {
case mtpe: Types.MethodType if !mtpe.isParamDependent =>
val closureResType = mtpe.resType match {
case t: Types.MethodType => t.toFunctionType()
case t => t
}
val closureTpe = Types.MethodType(mtpe.paramNames, mtpe.paramInfos, closureResType)
val closureMethod = ctx.newSymbol(ctx.owner, nme.ANON_FUN, Synthetic | Method, closureTpe)
tpd.Closure(closureMethod, tss => etaExpand(new tpd.TreeOps(term).appliedToArgs(tss.head)))
case _ => term
}
new scala.internal.quoted.TastyTreeExpr(etaExpand(self), compilerId)
def QuotedExpr_seal(self: Term)(given ctx: Context): scala.quoted.Expr[Any] = self.tpe.widen match {
case _: Types.MethodType | _: Types.PolyType => throw new Exception("Cannot seal a partially applied Term. Try eta-expanding the term first.")
case _ => new scala.internal.quoted.TastyTreeExpr(self, compilerId)
}

/** Checked cast to a `quoted.Expr[U]` */
Expand Down
1 change: 1 addition & 0 deletions library/src/scala/tasty/reflect/CompilerInterface.scala
Original file line number Diff line number Diff line change
Expand Up @@ -283,6 +283,7 @@ trait CompilerInterface {
def Term_tpe(self: Term)(given ctx: Context): Type
def Term_underlyingArgument(self: Term)(given ctx: Context): Term
def Term_underlying(self: Term)(given ctx: Context): Term
def Term_etaExpand(term: Term): Term

/** Tree representing a reference to definition */
type Ref <: Term
Expand Down
1 change: 1 addition & 0 deletions library/src/scala/tasty/reflect/TreeOps.scala
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,7 @@ trait TreeOps extends Core {
def tpe(given ctx: Context): Type = internal.Term_tpe(self)
def underlyingArgument(given ctx: Context): Term = internal.Term_underlyingArgument(self)
def underlying(given ctx: Context): Term = internal.Term_underlying(self)
def etaExpand(given ctx: Context): Term = internal.Term_etaExpand(self)

/** A unary apply node with given argument: `tree(arg)` */
def appliedTo(arg: Term)(given ctx: Context): Term =
Expand Down
16 changes: 8 additions & 8 deletions tests/run-macros/tasty-seal-method/quoted_1.scala
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,10 @@ object Asserts {
fn.tpe.widen match {
case IsMethodType(_) =>
args.size match {
case 0 => Expr.betaReduce(fn.seal.cast[() => Int])()
case 1 => Expr.betaReduce(fn.seal.cast[Int => Int])('{0})
case 2 => Expr.betaReduce(fn.seal.cast[(Int, Int) => Int])('{0}, '{0})
case 3 => Expr.betaReduce(fn.seal.cast[(Int, Int, Int) => Int])('{0}, '{0}, '{0})
case 0 => Expr.betaReduce(fn.etaExpand.seal.cast[() => Int])()
case 1 => Expr.betaReduce(fn.etaExpand.seal.cast[Int => Int])('{0})
case 2 => Expr.betaReduce(fn.etaExpand.seal.cast[(Int, Int) => Int])('{0}, '{0})
case 3 => Expr.betaReduce(fn.etaExpand.seal.cast[(Int, Int, Int) => Int])('{0}, '{0}, '{0})
}
}
case _ => x
Expand All @@ -35,10 +35,10 @@ object Asserts {
case Apply(fn, args) =>
val pre = rec(fn)
args.size match {
case 0 => Expr.betaReduce(pre.seal.cast[() => Any])().unseal
case 1 => Expr.betaReduce(pre.seal.cast[Int => Any])('{0}).unseal
case 2 => Expr.betaReduce(pre.seal.cast[(Int, Int) => Any])('{0}, '{0}).unseal
case 3 => Expr.betaReduce(pre.seal.cast[(Int, Int, Int) => Any])('{0}, '{0}, '{0}).unseal
case 0 => Expr.betaReduce(pre.etaExpand.seal.cast[() => Any])().unseal
case 1 => Expr.betaReduce(pre.etaExpand.seal.cast[Int => Any])('{0}).unseal
case 2 => Expr.betaReduce(pre.etaExpand.seal.cast[(Int, Int) => Any])('{0}, '{0}).unseal
case 3 => Expr.betaReduce(pre.etaExpand.seal.cast[(Int, Int, Int) => Any])('{0}, '{0}, '{0}).unseal
}
case _ => term
}
Expand Down