Skip to content

Commit 94970a0

Browse files
Merge pull request #9918 from dotty-staging/add-Reflection-Term-betaReduce
Add Reflection.Term.betaReduce
2 parents 19cf871 + cee37e5 commit 94970a0

File tree

4 files changed

+33
-21
lines changed

4 files changed

+33
-21
lines changed

compiler/src/dotty/tools/dotc/quoted/QuoteContextImpl.scala

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -295,7 +295,20 @@ class QuoteContextImpl private (ctx: Context) extends QuoteContext:
295295
case _ => None
296296
end TermTypeTest
297297

298-
object Term extends TermModule
298+
object Term extends TermModule:
299+
def betaReduce(tree: Term): Option[Term] =
300+
tree match
301+
case app @ tpd.Apply(tpd.Select(fn, nme.apply), args) if dotc.core.Symbols.defn.isFunctionType(fn.tpe) =>
302+
val app1 = dotc.transform.BetaReduce(app, fn, args)
303+
if app1 eq app then None
304+
else Some(app1.withSpan(tree.span))
305+
case tpd.Block(Nil, expr) =>
306+
for e <- betaReduce(expr) yield tpd.cpy.Block(tree)(Nil, e)
307+
case tpd.Inlined(_, Nil, expr) =>
308+
betaReduce(expr)
309+
case _ =>
310+
None
311+
end Term
299312

300313
object TermMethodsImpl extends TermMethods:
301314
extension (self: Term):
@@ -2655,19 +2668,6 @@ class QuoteContextImpl private (ctx: Context) extends QuoteContext:
26552668
def Definitions_InternalQuotedPatterns_patternHole: Symbol = dotc.core.Symbols.defn.InternalQuotedPatterns_patternHole
26562669
def Definitions_InternalQuotedPatterns_higherOrderHole: Symbol = dotc.core.Symbols.defn.InternalQuotedPatterns_higherOrderHole
26572670

2658-
def betaReduce(tree: Term): Option[Term] =
2659-
tree match
2660-
case app @ tpd.Apply(tpd.Select(fn, nme.apply), args) if dotc.core.Symbols.defn.isFunctionType(fn.tpe) =>
2661-
val app1 = dotc.transform.BetaReduce(app, fn, args)
2662-
if app1 eq app then None
2663-
else Some(app1.withSpan(tree.span))
2664-
case tpd.Block(Nil, expr) =>
2665-
for e <- betaReduce(expr) yield tpd.cpy.Block(tree)(Nil, e)
2666-
case tpd.Inlined(_, Nil, expr) =>
2667-
betaReduce(expr)
2668-
case _ =>
2669-
None
2670-
26712671
def compilerId: Int = rootContext.outersIterator.toList.last.hashCode()
26722672

26732673
end tasty

library/src-bootstrapped/scala/quoted/Expr.scala

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -72,13 +72,15 @@ object Expr {
7272
end extension
7373

7474
/** `e.betaReduce` returns an expression that is functionally equivalent to `e`,
75-
* however if `e` is of the form `((y1, ..., yn) => e2)(x1, ..., xn)`
75+
* however if `e` is of the form `((y1, ..., yn) => e2)(e1, ..., en)`
7676
* then it optimizes this the top most call by returning the result of beta-reducing the application.
7777
* Otherwise returns `expr`.
78+
*
79+
* To retain semantics the argument `ei` is bound as `val yi = ei` and by-name arguments to `def yi = ei`.
80+
* Some bindings may be elided as an early optimization.
7881
*/
7982
def betaReduce[T](expr: Expr[T])(using qctx: QuoteContext): Expr[T] =
80-
val qctx2 = quoteContextWithCompilerInterface(qctx)
81-
qctx2.tasty.betaReduce(expr.unseal) match
83+
qctx.tasty.Term.betaReduce(expr.unseal) match
8284
case Some(expr1) => expr1.seal.asInstanceOf[Expr[T]]
8385
case _ => expr
8486

library/src/scala/internal/tasty/CompilerInterface.scala

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -61,9 +61,6 @@ trait CompilerInterface { self: scala.tasty.Reflection =>
6161
/** Symbol of scala.internal.quoted.Patterns.higherOrderHole */
6262
def Definitions_InternalQuotedPatterns_higherOrderHole: Symbol
6363

64-
/** Returns Some with a beta-reduced application or None */
65-
def betaReduce(tree: Term): Option[Term]
66-
6764
def compilerId: Int
6865

6966
}

library/src/scala/tasty/Reflection.scala

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -362,7 +362,20 @@ trait Reflection { reflection =>
362362

363363
val Term: TermModule
364364

365-
trait TermModule { this: Term.type => }
365+
trait TermModule { this: Term.type =>
366+
367+
/** Returns a term that is functionally equivalent to `t`,
368+
* however if `t` is of the form `((y1, ..., yn) => e2)(e1, ..., en)`
369+
* then it optimizes this the top most call by returning the `Some`
370+
* with the result of beta-reducing the application.
371+
* Otherwise returns `None`.
372+
*
373+
* To retain semantics the argument `ei` is bound as `val yi = ei` and by-name arguments to `def yi = ei`.
374+
* Some bindings may be elided as an early optimization.
375+
*/
376+
def betaReduce(term: Term): Option[Term]
377+
378+
}
366379

367380
given TermMethods as TermMethods = TermMethodsImpl
368381
protected val TermMethodsImpl: TermMethods

0 commit comments

Comments
 (0)