Skip to content

Commit

Permalink
Allow more β-reductions
Browse files Browse the repository at this point in the history
  • Loading branch information
nicolasstucki committed Mar 31, 2020
1 parent aa755f5 commit efc258d
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 21 deletions.
37 changes: 17 additions & 20 deletions compiler/src/dotty/tools/dotc/transform/BetaReduce.scala
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package dotc
package transform

import core._
import Flags._
import MegaPhase._
import Symbols._, Contexts._, Types._, Decorators._
import StdNames.nme
Expand Down Expand Up @@ -46,38 +47,34 @@ class BetaReduce extends MiniPhase:
fn match
case Typed(expr, _) => betaReduce(tree, expr, args)
case Block(Nil, expr) => betaReduce(tree, expr, args)
case Block((anonFun: DefDef) :: Nil, closure: Closure) => BetaReduce(tree)(anonFun, args, true)
case Block((anonFun: DefDef) :: Nil, closure: Closure) => BetaReduce(anonFun, args)
case _ => tree

object BetaReduce:
import ast.tpd._

/** Beta-reduces a call to `ddef` with arguments `argSyms` */
def apply(tree: Tree)(ddef: DefDef, args: List[Tree], noBindings: Boolean)(using ctx: Context) =
def apply(ddef: DefDef, args: List[Tree])(using ctx: Context) =
val bindings = List.newBuilder[ValDef]
val vparams = ddef.vparamss.iterator.flatten.toList
assert(args.hasSameLengthAs(vparams))
val argSyms =
for (arg, param) <- args.zip(vparams) yield
arg.tpe.dealias match
case ref @ TermRef(NoPrefix, _) if isPurePath(arg) =>
ref.symbol
case _ =>
if noBindings then // TODO always generate bindings
NoSymbol
else
val binding = SyntheticValDef(param.name, arg)
bindings += binding
binding.symbol
val flags = Synthetic | (param.symbol.flags & Erased)
val binding = ValDef(ctx.newSymbol(ctx.owner, param.name, flags, arg.tpe.widen, coord = arg.span), arg)
bindings += binding
binding.symbol

if argSyms.forall(_.exists) && argSyms.hasSameLengthAs(vparams) then // TODO assert rather than fail silently
seq(
bindings.result(),
TreeTypeMap(
oldOwners = ddef.symbol :: Nil,
newOwners = ctx.owner :: Nil,
substFrom = vparams.map(_.symbol),
substTo = argSyms
).transform(ddef.rhs)
)
else
tree
val expansion = TreeTypeMap(
oldOwners = ddef.symbol :: Nil,
newOwners = ctx.owner :: Nil,
substFrom = vparams.map(_.symbol),
substTo = argSyms
).transform(ddef.rhs)

seq(bindings.result(), expansion)
end apply
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,6 @@ class InlinePatterns extends MiniPhase:
fn match
case Block(TypeDef(_, template: Template) :: Nil, Apply(Select(New(_),_), Nil)) if template.constr.rhs.isEmpty =>
template.body match
case List(ddef @ DefDef(`name`, _, _, _, _)) => BetaReduce(tree)(ddef, args, false)
case List(ddef @ DefDef(`name`, _, _, _, _)) => BetaReduce(ddef, args)
case _ => tree
case _ => tree

0 comments on commit efc258d

Please sign in to comment.