Skip to content

Add tasty seal methods #5603

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 3 commits into from
Dec 13, 2018
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
6 changes: 5 additions & 1 deletion compiler/src/dotty/tools/dotc/core/Types.scala
Original file line number Diff line number Diff line change
Expand Up @@ -1442,9 +1442,13 @@ object Types {
val formals1 = if (dropLast == 0) mt.paramInfos else mt.paramInfos dropRight dropLast
val isImplicit = mt.isImplicitMethod && !ctx.erasedTypes
val isErased = mt.isErasedMethod && !ctx.erasedTypes
val result1 = mt.nonDependentResultApprox match {
case res: MethodType => res.toFunctionType()
case res => res
}
val funType = defn.FunctionOf(
formals1 mapConserve (_.underlyingIfRepeated(mt.isJavaMethod)),
mt.nonDependentResultApprox, isImplicit, isErased)
result1, isImplicit, isErased)
if (mt.isResultDependent) RefinedType(funType, nme.apply, mt)
else funType
}
Expand Down
23 changes: 12 additions & 11 deletions compiler/src/dotty/tools/dotc/core/quoted/PickledQuotes.scala
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,8 @@ object PickledQuotes {
case value => Literal(Constant(value))
}
case expr: TastyTreeExpr[Tree] @unchecked => healOwner(expr.tree)
case expr: FunctionAppliedTo[_, _] =>
functionAppliedTo(quotedExprToTree(expr.f), quotedExprToTree(expr.x))
case expr: FunctionAppliedTo[_] =>
functionAppliedTo(quotedExprToTree(expr.f), expr.args.map(arg => quotedExprToTree(arg)).toList)
}

/** Transform the expression into its fully spliced TypeTree */
Expand Down Expand Up @@ -127,26 +127,27 @@ object PickledQuotes {
TypeTree(tpe)
}

private def functionAppliedTo(f: Tree, x: Tree)(implicit ctx: Context): Tree = {
val x1 = SyntheticValDef(NameKinds.UniqueName.fresh("x".toTermName), x)
def x1Ref() = ref(x1.symbol)
def rec(f: Tree): Tree = f match {
private def functionAppliedTo(fn: Tree, args: List[Tree])(implicit ctx: Context): Tree = {
val argVals = args.map(arg => SyntheticValDef(NameKinds.UniqueName.fresh("x".toTermName), arg))
def argRefs() = argVals.map(argVal => ref(argVal.symbol))
def rec(fn: Tree): Tree = fn match {
case Inlined(call, bindings, expansion) =>
// this case must go before closureDef to avoid dropping the inline node
cpy.Inlined(f)(call, bindings, rec(expansion))
cpy.Inlined(fn)(call, bindings, rec(expansion))
case closureDef(ddef) =>
val paramSym = ddef.vparamss.head.head.symbol
val paramSyms = ddef.vparamss.head.map(param => param.symbol)
val paramToVals = paramSyms.zip(argRefs()).toMap
new TreeTypeMap(
oldOwners = ddef.symbol :: Nil,
newOwners = ctx.owner :: Nil,
treeMap = tree => if (tree.symbol == paramSym) x1Ref().withPos(tree.pos) else tree
treeMap = tree => paramToVals.get(tree.symbol).map(_.withPos(tree.pos)).getOrElse(tree)
).transform(ddef.rhs)
case Block(stats, expr) =>
seq(stats, rec(expr))
case _ =>
f.select(nme.apply).appliedTo(x1Ref())
fn.select(nme.apply).appliedToArgs(argRefs())
}
Block(x1 :: Nil, rec(f))
Block(argVals, rec(fn))
}

private def classToType(clazz: Class[_])(implicit ctx: Context): Type = {
Expand Down
32 changes: 25 additions & 7 deletions compiler/src/dotty/tools/dotc/tastyreflect/QuotedOpsImpl.scala
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
package dotty.tools.dotc.tastyreflect

import dotty.tools.dotc.ast.tpd
import dotty.tools.dotc.ast.Trees
import dotty.tools.dotc.core.Flags._
import dotty.tools.dotc.core.Symbols.defn
import dotty.tools.dotc.core.StdNames.nme
import dotty.tools.dotc.core.quoted.PickledQuotes
import dotty.tools.dotc.core.Types

trait QuotedOpsImpl extends scala.tasty.reflect.QuotedOps with CoreImpl {

Expand All @@ -15,16 +21,28 @@ trait QuotedOpsImpl extends scala.tasty.reflect.QuotedOps with CoreImpl {
def TermToQuoteDeco(term: Term): TermToQuotedAPI = new TermToQuotedAPI {

def seal[T: scala.quoted.Type](implicit ctx: Context): scala.quoted.Expr[T] = {
typecheck()
new scala.quoted.Exprs.TastyTreeExpr(term).asInstanceOf[scala.quoted.Expr[T]]
}

private def typecheck[T: scala.quoted.Type]()(implicit ctx: Context): Unit = {
val tpt = QuotedTypeDeco(implicitly[scala.quoted.Type[T]]).unseal
if (!(term.tpe <:< tpt.tpe)) {
val expectedType = QuotedTypeDeco(implicitly[scala.quoted.Type[T]]).unseal.tpe

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
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems this does handle param blocks > 2?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It was working properly but did not fully convert to the lambda type. I changed toFunctionType to make sure it never leaves MethodTypes as result type.

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
}

val expanded = etaExpand(term)
if (expanded.tpe <:< expectedType) {
new scala.quoted.Exprs.TastyTreeExpr(expanded).asInstanceOf[scala.quoted.Expr[T]]
} else {
throw new scala.tasty.TastyTypecheckError(
s"""Term: ${term.show}
|did not conform to type: ${tpt.tpe.show}
|did not conform to type: ${expectedType.show}
|""".stripMargin
)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,18 @@ trait TypeOrBoundsOpsImpl extends scala.tasty.reflect.TypeOrBoundsOps with CoreI
def TypeDeco(tpe: Type): TypeAPI = new TypeAPI {
def =:=(other: Type)(implicit ctx: Context): Boolean = tpe =:= other
def <:<(other: Type)(implicit ctx: Context): Boolean = tpe <:< other

/** Widen from singleton type to its underlying non-singleton
* base type by applying one or more `underlying` dereferences,
* Also go from => T to T.
* Identity for all other types. Example:
*
* class Outer { class C ; val x: C }
* def o: Outer
* <o.x.type>.widen = o.C
*/
def widen(implicit ctx: Context): Type = tpe.widen

}

def ConstantTypeDeco(x: ConstantType): Type.ConstantTypeAPI = new Type.ConstantTypeAPI {
Expand Down
12 changes: 6 additions & 6 deletions docs/docs/reference/principled-meta-programming.md
Original file line number Diff line number Diff line change
Expand Up @@ -130,26 +130,26 @@ PCP. This is explained further in a later section.

### From `Expr`s to Functions and Back

The `Expr` companion object contains an "AsFunction" decorator that turns a tree
The `Expr` companion object contains an `AsFunctionN` (for 0 <= N < 23) decorator that turns a tree
describing a function into a function mapping trees to trees.

object Expr {
...
implicit class AsFunction[T, U](f: Expr[T => U]) extends AnyVal {
implicit class AsFunction1[T, U](f: Expr[T => U]) extends AnyVal {
def apply(x: Expr[T]): Expr[U] = ???
}
}

This decorator gives `Expr` the `apply` operation of an applicative functor, where `Expr`s
over function types can be applied to `Expr` arguments. The definition
of `AsFunction(f).apply(x)` is assumed to be functionally the same as
of `AsFunction1(f).apply(x)` is assumed to be functionally the same as
`'((~f)(~x))`, however it should optimize this call by returning the
result of beta-reducing `f(x)` if `f` is a known lambda expression
result of beta-reducing `f(x)` if `f` is a known lambda expression.

The `AsFunction` decorator distributes applications of `Expr` over function
The `AsFunction1` decorator distributes applications of `Expr` over function
arrows:

AsFunction(_).apply: Expr[S => T] => (Expr[S] => Expr[T])
AsFunction1(_).apply: Expr[S => T] => (Expr[S] => Expr[T])

Its dual, let’s call it `reflect`, can be defined as follows:

Expand Down
103 changes: 98 additions & 5 deletions library/src/scala/quoted/Expr.scala
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,98 @@ object Expr {
def apply[T](x: T): Expr[T] =
throw new Error("Internal error: this method call should have been replaced by the compiler")

implicit class AsFunction[T, U](private val f: Expr[T => U]) extends AnyVal {
def apply(x: Expr[T]): Expr[U] = new Exprs.FunctionAppliedTo[T, U](f, x)
// TODO simplify using new extension methods

implicit class AsFunction0[R](private val f: Expr[() => R]) extends AnyVal {
def apply(): Expr[R] = new Exprs.FunctionAppliedTo[R](f, Array.empty)
}

implicit class AsFunction1[T1, R](private val f: Expr[(T1) => R]) extends AnyVal {
def apply(x1: Expr[T1]): Expr[R] = new Exprs.FunctionAppliedTo[R](f, Array(x1))
}

implicit class AsFunction2[T1, T2, R](private val f: Expr[(T1, T2) => R]) extends AnyVal {
def apply(x1: Expr[T1], x2: Expr[T2]): Expr[R] = new Exprs.FunctionAppliedTo[R](f, Array(x1, x2))
}

implicit class AsFunction3[T1, T2, T3, R](private val f: Expr[(T1, T2, T3) => R]) extends AnyVal {
def apply(x1: Expr[T1], x2: Expr[T2], x3: Expr[T3]): Expr[R] = new Exprs.FunctionAppliedTo[R](f, Array(x1, x2, x3))
}

implicit class AsFunction4[T1, T2, T3, T4, R](private val f: Expr[(T1, T2, T3, T4) => R]) extends AnyVal {
def apply(x1: Expr[T1], x2: Expr[T2], x3: Expr[T3], x4: Expr[T4]): Expr[R] = new Exprs.FunctionAppliedTo[R](f, Array(x1, x2, x3, x4))
}

implicit class AsFunction5[T1, T2, T3, T4, T5, R](private val f: Expr[(T1, T2, T3, T4, T5) => R]) extends AnyVal {
def apply(x1: Expr[T1], x2: Expr[T2], x3: Expr[T3], x4: Expr[T4], x5: Expr[T5]): Expr[R] = new Exprs.FunctionAppliedTo[R](f, Array(x1, x2, x3, x4, x5))
}

implicit class AsFunction6[T1, T2, T3, T4, T5, T6, R](private val f: Expr[(T1, T2, T3, T4, T5, T6) => R]) extends AnyVal {
def apply(x1: Expr[T1], x2: Expr[T2], x3: Expr[T3], x4: Expr[T4], x5: Expr[T5], x6: Expr[T6]): Expr[R] = new Exprs.FunctionAppliedTo[R](f, Array(x1, x2, x3, x4, x5, x6))
}

implicit class AsFunction7[T1, T2, T3, T4, T5, T6, T7, R](private val f: Expr[(T1, T2, T3, T4, T5, T6, T7) => R]) extends AnyVal {
def apply(x1: Expr[T1], x2: Expr[T2], x3: Expr[T3], x4: Expr[T4], x5: Expr[T5], x6: Expr[T6], x7: Expr[T7]): Expr[R] = new Exprs.FunctionAppliedTo[R](f, Array(x1, x2, x3, x4, x5, x6, x7))
}

implicit class AsFunction8[T1, T2, T3, T4, T5, T6, T7, T8, R](private val f: Expr[(T1, T2, T3, T4, T5, T6, T7, T8) => R]) extends AnyVal {
def apply(x1: Expr[T1], x2: Expr[T2], x3: Expr[T3], x4: Expr[T4], x5: Expr[T5], x6: Expr[T6], x7: Expr[T7], x8: Expr[T8]): Expr[R] = new Exprs.FunctionAppliedTo[R](f, Array(x1, x2, x3, x4, x5, x6, x7, x8))
}

implicit class AsFunction9[T1, T2, T3, T4, T5, T6, T7, T8, T9, R](private val f: Expr[(T1, T2, T3, T4, T5, T6, T7, T8, T9) => R]) extends AnyVal {
def apply(x1: Expr[T1], x2: Expr[T2], x3: Expr[T3], x4: Expr[T4], x5: Expr[T5], x6: Expr[T6], x7: Expr[T7], x8: Expr[T8], x9: Expr[T9]): Expr[R] = new Exprs.FunctionAppliedTo[R](f, Array(x1, x2, x3, x4, x5, x6, x7, x8, x9))
}

implicit class AsFunction10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, R](private val f: Expr[(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10) => R]) extends AnyVal {
def apply(x1: Expr[T1], x2: Expr[T2], x3: Expr[T3], x4: Expr[T4], x5: Expr[T5], x6: Expr[T6], x7: Expr[T7], x8: Expr[T8], x9: Expr[T9], x10: Expr[T10]): Expr[R] = new Exprs.FunctionAppliedTo[R](f, Array(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10))
}

implicit class AsFunction11[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, R](private val f: Expr[(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11) => R]) extends AnyVal {
def apply(x1: Expr[T1], x2: Expr[T2], x3: Expr[T3], x4: Expr[T4], x5: Expr[T5], x6: Expr[T6], x7: Expr[T7], x8: Expr[T8], x9: Expr[T9], x10: Expr[T10], x11: Expr[T11]): Expr[R] = new Exprs.FunctionAppliedTo[R](f, Array(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11))
}

implicit class AsFunction12[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, R](private val f: Expr[(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12) => R]) extends AnyVal {
def apply(x1: Expr[T1], x2: Expr[T2], x3: Expr[T3], x4: Expr[T4], x5: Expr[T5], x6: Expr[T6], x7: Expr[T7], x8: Expr[T8], x9: Expr[T9], x10: Expr[T10], x11: Expr[T11], x12: Expr[T12]): Expr[R] = new Exprs.FunctionAppliedTo[R](f, Array(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12))
}

implicit class AsFunction13[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, R](private val f: Expr[(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13) => R]) extends AnyVal {
def apply(x1: Expr[T1], x2: Expr[T2], x3: Expr[T3], x4: Expr[T4], x5: Expr[T5], x6: Expr[T6], x7: Expr[T7], x8: Expr[T8], x9: Expr[T9], x10: Expr[T10], x11: Expr[T11], x12: Expr[T12], x13: Expr[T13]): Expr[R] = new Exprs.FunctionAppliedTo[R](f, Array(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13))
}

implicit class AsFunction14[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, R](private val f: Expr[(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14) => R]) extends AnyVal {
def apply(x1: Expr[T1], x2: Expr[T2], x3: Expr[T3], x4: Expr[T4], x5: Expr[T5], x6: Expr[T6], x7: Expr[T7], x8: Expr[T8], x9: Expr[T9], x10: Expr[T10], x11: Expr[T11], x12: Expr[T12], x13: Expr[T13], x14: Expr[T14]): Expr[R] = new Exprs.FunctionAppliedTo[R](f, Array(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14))
}

implicit class AsFunction15[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, R](private val f: Expr[(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15) => R]) extends AnyVal {
def apply(x1: Expr[T1], x2: Expr[T2], x3: Expr[T3], x4: Expr[T4], x5: Expr[T5], x6: Expr[T6], x7: Expr[T7], x8: Expr[T8], x9: Expr[T9], x10: Expr[T10], x11: Expr[T11], x12: Expr[T12], x13: Expr[T13], x14: Expr[T14], x15: Expr[T15]): Expr[R] = new Exprs.FunctionAppliedTo[R](f, Array(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15))
}

implicit class AsFunction16[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, R](private val f: Expr[(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16) => R]) extends AnyVal {
def apply(x1: Expr[T1], x2: Expr[T2], x3: Expr[T3], x4: Expr[T4], x5: Expr[T5], x6: Expr[T6], x7: Expr[T7], x8: Expr[T8], x9: Expr[T9], x10: Expr[T10], x11: Expr[T11], x12: Expr[T12], x13: Expr[T13], x14: Expr[T14], x15: Expr[T15], x16: Expr[T16]): Expr[R] = new Exprs.FunctionAppliedTo[R](f, Array(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16))
}

implicit class AsFunction17[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, R](private val f: Expr[(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17) => R]) extends AnyVal {
def apply(x1: Expr[T1], x2: Expr[T2], x3: Expr[T3], x4: Expr[T4], x5: Expr[T5], x6: Expr[T6], x7: Expr[T7], x8: Expr[T8], x9: Expr[T9], x10: Expr[T10], x11: Expr[T11], x12: Expr[T12], x13: Expr[T13], x14: Expr[T14], x15: Expr[T15], x16: Expr[T16], x17: Expr[T17]): Expr[R] = new Exprs.FunctionAppliedTo[R](f, Array(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17))
}

implicit class AsFunction18[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, R](private val f: Expr[(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18) => R]) extends AnyVal {
def apply(x1: Expr[T1], x2: Expr[T2], x3: Expr[T3], x4: Expr[T4], x5: Expr[T5], x6: Expr[T6], x7: Expr[T7], x8: Expr[T8], x9: Expr[T9], x10: Expr[T10], x11: Expr[T11], x12: Expr[T12], x13: Expr[T13], x14: Expr[T14], x15: Expr[T15], x16: Expr[T16], x17: Expr[T17], x18: Expr[T18]): Expr[R] = new Exprs.FunctionAppliedTo[R](f, Array(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18))
}

implicit class AsFunction19[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, R](private val f: Expr[(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19) => R]) extends AnyVal {
def apply(x1: Expr[T1], x2: Expr[T2], x3: Expr[T3], x4: Expr[T4], x5: Expr[T5], x6: Expr[T6], x7: Expr[T7], x8: Expr[T8], x9: Expr[T9], x10: Expr[T10], x11: Expr[T11], x12: Expr[T12], x13: Expr[T13], x14: Expr[T14], x15: Expr[T15], x16: Expr[T16], x17: Expr[T17], x18: Expr[T18], x19: Expr[T19]): Expr[R] = new Exprs.FunctionAppliedTo[R](f, Array(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18, x19))
}

implicit class AsFunction20[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, R](private val f: Expr[(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20) => R]) extends AnyVal {
def apply(x1: Expr[T1], x2: Expr[T2], x3: Expr[T3], x4: Expr[T4], x5: Expr[T5], x6: Expr[T6], x7: Expr[T7], x8: Expr[T8], x9: Expr[T9], x10: Expr[T10], x11: Expr[T11], x12: Expr[T12], x13: Expr[T13], x14: Expr[T14], x15: Expr[T15], x16: Expr[T16], x17: Expr[T17], x18: Expr[T18], x19: Expr[T19], x20: Expr[T20]): Expr[R] = new Exprs.FunctionAppliedTo[R](f, Array(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18, x19, x20))
}

implicit class AsFunction21[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, R](private val f: Expr[(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21) => R]) extends AnyVal {
def apply(x1: Expr[T1], x2: Expr[T2], x3: Expr[T3], x4: Expr[T4], x5: Expr[T5], x6: Expr[T6], x7: Expr[T7], x8: Expr[T8], x9: Expr[T9], x10: Expr[T10], x11: Expr[T11], x12: Expr[T12], x13: Expr[T13], x14: Expr[T14], x15: Expr[T15], x16: Expr[T16], x17: Expr[T17], x18: Expr[T18], x19: Expr[T19], x20: Expr[T20], x21: Expr[T21]): Expr[R] = new Exprs.FunctionAppliedTo[R](f, Array(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18, x19, x20, x21))
}

implicit class AsFunction22[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, R](private val f: Expr[(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22) => R]) extends AnyVal {
def apply(x1: Expr[T1], x2: Expr[T2], x3: Expr[T3], x4: Expr[T4], x5: Expr[T5], x6: Expr[T6], x7: Expr[T7], x8: Expr[T8], x9: Expr[T9], x10: Expr[T10], x11: Expr[T11], x12: Expr[T12], x13: Expr[T13], x14: Expr[T14], x15: Expr[T15], x16: Expr[T16], x17: Expr[T17], x18: Expr[T18], x19: Expr[T19], x20: Expr[T20], x21: Expr[T21], x22: Expr[T22]): Expr[R] = new Exprs.FunctionAppliedTo[R](f, Array(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18, x19, x20, x21, x22))
}

}
Expand Down Expand Up @@ -53,8 +143,11 @@ object Exprs {
override def toString: String = s"Expr(<tasty tree>)"
}

/** An Expr representing `'{(~f).apply(~x)}` but it is beta-reduced when the closure is known */
final class FunctionAppliedTo[T, +U](val f: Expr[T => U], val x: Expr[T]) extends Expr[U] {
override def toString: String = s"Expr($f <applied to> $x)"
// TODO Use a List in FunctionAppliedTo(val f: Expr[_], val args: List[Expr[_]])
// FIXME: Having the List in the code above trigers an assertion error while testing dotty.tools.dotc.reporting.ErrorMessagesTests.i3187
// This test does redefine `scala.collection`. Further investigation is needed.
/** An Expr representing `'{(~f).apply(~x1, ..., ~xn)}` but it is beta-reduced when the closure is known */
final class FunctionAppliedTo[+R](val f: Expr[_], val args: Array[Expr[_]]) extends Expr[R] {
override def toString: String = s"Expr($f <applied to> ${args.toList})"
}
}
1 change: 1 addition & 0 deletions library/src/scala/tasty/reflect/TypeOrBoundsOps.scala
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ trait TypeOrBoundsOps extends Core {
trait TypeAPI {
def =:=(other: Type)(implicit ctx: Context): Boolean
def <:<(other: Type)(implicit ctx: Context): Boolean
def widen(implicit ctx: Context): Type
}

val IsType: IsTypeModule
Expand Down
Loading