Skip to content

Commit 9b192c4

Browse files
authored
Merge pull request #5603 from dotty-staging/add-tasty-seal-methods
Add tasty seal methods
2 parents e656b1f + be138ad commit 9b192c4

File tree

11 files changed

+595
-30
lines changed

11 files changed

+595
-30
lines changed

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

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1442,9 +1442,13 @@ object Types {
14421442
val formals1 = if (dropLast == 0) mt.paramInfos else mt.paramInfos dropRight dropLast
14431443
val isImplicit = mt.isImplicitMethod && !ctx.erasedTypes
14441444
val isErased = mt.isErasedMethod && !ctx.erasedTypes
1445+
val result1 = mt.nonDependentResultApprox match {
1446+
case res: MethodType => res.toFunctionType()
1447+
case res => res
1448+
}
14451449
val funType = defn.FunctionOf(
14461450
formals1 mapConserve (_.underlyingIfRepeated(mt.isJavaMethod)),
1447-
mt.nonDependentResultApprox, isImplicit, isErased)
1451+
result1, isImplicit, isErased)
14481452
if (mt.isResultDependent) RefinedType(funType, nme.apply, mt)
14491453
else funType
14501454
}

compiler/src/dotty/tools/dotc/core/quoted/PickledQuotes.scala

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -47,8 +47,8 @@ object PickledQuotes {
4747
case value => Literal(Constant(value))
4848
}
4949
case expr: TastyTreeExpr[Tree] @unchecked => healOwner(expr.tree)
50-
case expr: FunctionAppliedTo[_, _] =>
51-
functionAppliedTo(quotedExprToTree(expr.f), quotedExprToTree(expr.x))
50+
case expr: FunctionAppliedTo[_] =>
51+
functionAppliedTo(quotedExprToTree(expr.f), expr.args.map(arg => quotedExprToTree(arg)).toList)
5252
}
5353

5454
/** Transform the expression into its fully spliced TypeTree */
@@ -127,26 +127,27 @@ object PickledQuotes {
127127
TypeTree(tpe)
128128
}
129129

130-
private def functionAppliedTo(f: Tree, x: Tree)(implicit ctx: Context): Tree = {
131-
val x1 = SyntheticValDef(NameKinds.UniqueName.fresh("x".toTermName), x)
132-
def x1Ref() = ref(x1.symbol)
133-
def rec(f: Tree): Tree = f match {
130+
private def functionAppliedTo(fn: Tree, args: List[Tree])(implicit ctx: Context): Tree = {
131+
val argVals = args.map(arg => SyntheticValDef(NameKinds.UniqueName.fresh("x".toTermName), arg))
132+
def argRefs() = argVals.map(argVal => ref(argVal.symbol))
133+
def rec(fn: Tree): Tree = fn match {
134134
case Inlined(call, bindings, expansion) =>
135135
// this case must go before closureDef to avoid dropping the inline node
136-
cpy.Inlined(f)(call, bindings, rec(expansion))
136+
cpy.Inlined(fn)(call, bindings, rec(expansion))
137137
case closureDef(ddef) =>
138-
val paramSym = ddef.vparamss.head.head.symbol
138+
val paramSyms = ddef.vparamss.head.map(param => param.symbol)
139+
val paramToVals = paramSyms.zip(argRefs()).toMap
139140
new TreeTypeMap(
140141
oldOwners = ddef.symbol :: Nil,
141142
newOwners = ctx.owner :: Nil,
142-
treeMap = tree => if (tree.symbol == paramSym) x1Ref().withPos(tree.pos) else tree
143+
treeMap = tree => paramToVals.get(tree.symbol).map(_.withPos(tree.pos)).getOrElse(tree)
143144
).transform(ddef.rhs)
144145
case Block(stats, expr) =>
145146
seq(stats, rec(expr))
146147
case _ =>
147-
f.select(nme.apply).appliedTo(x1Ref())
148+
fn.select(nme.apply).appliedToArgs(argRefs())
148149
}
149-
Block(x1 :: Nil, rec(f))
150+
Block(argVals, rec(fn))
150151
}
151152

152153
private def classToType(clazz: Class[_])(implicit ctx: Context): Type = {

compiler/src/dotty/tools/dotc/tastyreflect/QuotedOpsImpl.scala

Lines changed: 25 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,12 @@
11
package dotty.tools.dotc.tastyreflect
22

3+
import dotty.tools.dotc.ast.tpd
4+
import dotty.tools.dotc.ast.Trees
5+
import dotty.tools.dotc.core.Flags._
6+
import dotty.tools.dotc.core.Symbols.defn
7+
import dotty.tools.dotc.core.StdNames.nme
38
import dotty.tools.dotc.core.quoted.PickledQuotes
9+
import dotty.tools.dotc.core.Types
410

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

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

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

22-
private def typecheck[T: scala.quoted.Type]()(implicit ctx: Context): Unit = {
23-
val tpt = QuotedTypeDeco(implicitly[scala.quoted.Type[T]]).unseal
24-
if (!(term.tpe <:< tpt.tpe)) {
25+
val expectedType = QuotedTypeDeco(implicitly[scala.quoted.Type[T]]).unseal.tpe
26+
27+
def etaExpand(term: Term): Term = term.tpe.widen match {
28+
case mtpe: Types.MethodType if !mtpe.isParamDependent =>
29+
val closureResType = mtpe.resType match {
30+
case t: Types.MethodType => t.toFunctionType()
31+
case t => t
32+
}
33+
val closureTpe = Types.MethodType(mtpe.paramNames, mtpe.paramInfos, closureResType)
34+
val closureMethod = ctx.newSymbol(ctx.owner, nme.ANON_FUN, Synthetic | Method, closureTpe)
35+
tpd.Closure(closureMethod, tss => etaExpand(new tpd.TreeOps(term).appliedToArgs(tss.head)))
36+
case _ => term
37+
}
38+
39+
val expanded = etaExpand(term)
40+
if (expanded.tpe <:< expectedType) {
41+
new scala.quoted.Exprs.TastyTreeExpr(expanded).asInstanceOf[scala.quoted.Expr[T]]
42+
} else {
2543
throw new scala.tasty.TastyTypecheckError(
2644
s"""Term: ${term.show}
27-
|did not conform to type: ${tpt.tpe.show}
45+
|did not conform to type: ${expectedType.show}
2846
|""".stripMargin
2947
)
3048
}

compiler/src/dotty/tools/dotc/tastyreflect/TypeOrBoundsOpsImpl.scala

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,18 @@ trait TypeOrBoundsOpsImpl extends scala.tasty.reflect.TypeOrBoundsOps with CoreI
77
def TypeDeco(tpe: Type): TypeAPI = new TypeAPI {
88
def =:=(other: Type)(implicit ctx: Context): Boolean = tpe =:= other
99
def <:<(other: Type)(implicit ctx: Context): Boolean = tpe <:< other
10+
11+
/** Widen from singleton type to its underlying non-singleton
12+
* base type by applying one or more `underlying` dereferences,
13+
* Also go from => T to T.
14+
* Identity for all other types. Example:
15+
*
16+
* class Outer { class C ; val x: C }
17+
* def o: Outer
18+
* <o.x.type>.widen = o.C
19+
*/
20+
def widen(implicit ctx: Context): Type = tpe.widen
21+
1022
}
1123

1224
def ConstantTypeDeco(x: ConstantType): Type.ConstantTypeAPI = new Type.ConstantTypeAPI {

docs/docs/reference/principled-meta-programming.md

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -130,26 +130,26 @@ PCP. This is explained further in a later section.
130130

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

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

136136
object Expr {
137137
...
138-
implicit class AsFunction[T, U](f: Expr[T => U]) extends AnyVal {
138+
implicit class AsFunction1[T, U](f: Expr[T => U]) extends AnyVal {
139139
def apply(x: Expr[T]): Expr[U] = ???
140140
}
141141
}
142142

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

149-
The `AsFunction` decorator distributes applications of `Expr` over function
149+
The `AsFunction1` decorator distributes applications of `Expr` over function
150150
arrows:
151151

152-
AsFunction(_).apply: Expr[S => T] => (Expr[S] => Expr[T])
152+
AsFunction1(_).apply: Expr[S => T] => (Expr[S] => Expr[T])
153153

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

library/src/scala/quoted/Expr.scala

Lines changed: 98 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,98 @@ object Expr {
2020
def apply[T](x: T): Expr[T] =
2121
throw new Error("Internal error: this method call should have been replaced by the compiler")
2222

23-
implicit class AsFunction[T, U](private val f: Expr[T => U]) extends AnyVal {
24-
def apply(x: Expr[T]): Expr[U] = new Exprs.FunctionAppliedTo[T, U](f, x)
23+
// TODO simplify using new extension methods
24+
25+
implicit class AsFunction0[R](private val f: Expr[() => R]) extends AnyVal {
26+
def apply(): Expr[R] = new Exprs.FunctionAppliedTo[R](f, Array.empty)
27+
}
28+
29+
implicit class AsFunction1[T1, R](private val f: Expr[(T1) => R]) extends AnyVal {
30+
def apply(x1: Expr[T1]): Expr[R] = new Exprs.FunctionAppliedTo[R](f, Array(x1))
31+
}
32+
33+
implicit class AsFunction2[T1, T2, R](private val f: Expr[(T1, T2) => R]) extends AnyVal {
34+
def apply(x1: Expr[T1], x2: Expr[T2]): Expr[R] = new Exprs.FunctionAppliedTo[R](f, Array(x1, x2))
35+
}
36+
37+
implicit class AsFunction3[T1, T2, T3, R](private val f: Expr[(T1, T2, T3) => R]) extends AnyVal {
38+
def apply(x1: Expr[T1], x2: Expr[T2], x3: Expr[T3]): Expr[R] = new Exprs.FunctionAppliedTo[R](f, Array(x1, x2, x3))
39+
}
40+
41+
implicit class AsFunction4[T1, T2, T3, T4, R](private val f: Expr[(T1, T2, T3, T4) => R]) extends AnyVal {
42+
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))
43+
}
44+
45+
implicit class AsFunction5[T1, T2, T3, T4, T5, R](private val f: Expr[(T1, T2, T3, T4, T5) => R]) extends AnyVal {
46+
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))
47+
}
48+
49+
implicit class AsFunction6[T1, T2, T3, T4, T5, T6, R](private val f: Expr[(T1, T2, T3, T4, T5, T6) => R]) extends AnyVal {
50+
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))
51+
}
52+
53+
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 {
54+
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))
55+
}
56+
57+
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 {
58+
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))
59+
}
60+
61+
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 {
62+
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))
63+
}
64+
65+
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 {
66+
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))
67+
}
68+
69+
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 {
70+
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))
71+
}
72+
73+
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 {
74+
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))
75+
}
76+
77+
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 {
78+
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))
79+
}
80+
81+
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 {
82+
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))
83+
}
84+
85+
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 {
86+
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))
87+
}
88+
89+
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 {
90+
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))
91+
}
92+
93+
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 {
94+
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))
95+
}
96+
97+
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 {
98+
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))
99+
}
100+
101+
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 {
102+
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))
103+
}
104+
105+
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 {
106+
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))
107+
}
108+
109+
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 {
110+
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))
111+
}
112+
113+
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 {
114+
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))
25115
}
26116

27117
}
@@ -53,8 +143,11 @@ object Exprs {
53143
override def toString: String = s"Expr(<tasty tree>)"
54144
}
55145

56-
/** An Expr representing `'{(~f).apply(~x)}` but it is beta-reduced when the closure is known */
57-
final class FunctionAppliedTo[T, +U](val f: Expr[T => U], val x: Expr[T]) extends Expr[U] {
58-
override def toString: String = s"Expr($f <applied to> $x)"
146+
// TODO Use a List in FunctionAppliedTo(val f: Expr[_], val args: List[Expr[_]])
147+
// FIXME: Having the List in the code above trigers an assertion error while testing dotty.tools.dotc.reporting.ErrorMessagesTests.i3187
148+
// This test does redefine `scala.collection`. Further investigation is needed.
149+
/** An Expr representing `'{(~f).apply(~x1, ..., ~xn)}` but it is beta-reduced when the closure is known */
150+
final class FunctionAppliedTo[+R](val f: Expr[_], val args: Array[Expr[_]]) extends Expr[R] {
151+
override def toString: String = s"Expr($f <applied to> ${args.toList})"
59152
}
60153
}

library/src/scala/tasty/reflect/TypeOrBoundsOps.scala

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ trait TypeOrBoundsOps extends Core {
5252
trait TypeAPI {
5353
def =:=(other: Type)(implicit ctx: Context): Boolean
5454
def <:<(other: Type)(implicit ctx: Context): Boolean
55+
def widen(implicit ctx: Context): Type
5556
}
5657

5758
val IsType: IsTypeModule

0 commit comments

Comments
 (0)