aboutsummaryrefslogtreecommitdiff
path: root/src/dotty/tools/dotc/transform/ElimByName.scala
diff options
context:
space:
mode:
Diffstat (limited to 'src/dotty/tools/dotc/transform/ElimByName.scala')
-rw-r--r--src/dotty/tools/dotc/transform/ElimByName.scala129
1 files changed, 0 insertions, 129 deletions
diff --git a/src/dotty/tools/dotc/transform/ElimByName.scala b/src/dotty/tools/dotc/transform/ElimByName.scala
deleted file mode 100644
index 192227261..000000000
--- a/src/dotty/tools/dotc/transform/ElimByName.scala
+++ /dev/null
@@ -1,129 +0,0 @@
-package dotty.tools.dotc
-package transform
-
-import TreeTransforms._
-import core._
-import DenotTransformers._
-import Symbols._
-import SymDenotations._
-import Contexts._
-import Types._
-import Flags._
-import Decorators._
-import SymUtils._
-import util.Attachment
-import core.StdNames.nme
-import ast.Trees._
-
-/** This phase eliminates ExprTypes `=> T` as types of function parameters, and replaces them by
- * nullary function types. More precisely:
- *
- * For the types of parameter symbols:
- *
- * => T ==> () => T
- *
- * Note that `=> T` types are not eliminated in MethodTypes. This is done later at erasure.
- * Terms are rewritten as follows:
- *
- * x ==> x.apply() if x is a parameter that had type => T
- *
- * Arguments to call-by-name parameters are translated as follows. First, the argument is
- * rewritten by the rules
- *
- * e.apply() ==> e if e.apply() is an argument to a call-by-name parameter
- * expr ==> () => expr if other expr is an argument to a call-by-name parameter
- *
- * This makes the argument compatible with a parameter type of () => T, which will be the
- * formal parameter type at erasure. But to be -Ycheckable until then, any argument
- * ARG rewritten by the rules above is again wrapped in an application DummyApply(ARG)
- * where
- *
- * DummyApply: [T](() => T): T
- *
- * is a synthetic method defined in Definitions. Erasure will later strip these DummyApply wrappers.
- *
- * Note: This scheme to have inconsistent types between method types (whose formal types are still
- * ExprTypes and parameter valdefs (which are now FunctionTypes) is not pretty. There are two
- * other options which have been abandoned or not yet pursued.
- *
- * Option 1: Transform => T to () => T also in method and function types. The problem with this is
- * that is that it requires to look at every type, and this forces too much, causing
- * Cyclic Reference errors. Abandoned for this reason.
- *
- * Option 2: Merge ElimByName with erasure, or have it run immediately before. This has not been
- * tried yet.
- */
-class ElimByName extends MiniPhaseTransform with InfoTransformer { thisTransformer =>
- import ast.tpd._
-
- override def phaseName: String = "elimByName"
-
- override def runsAfterGroupsOf = Set(classOf[Splitter])
- // assumes idents and selects have symbols; interferes with splitter distribution
- // that's why it's "after group".
-
- /** The info of the tree's symbol at phase Nullarify (i.e. before transformation) */
- private def originalDenotation(tree: Tree)(implicit ctx: Context) =
- tree.symbol.denot(ctx.withPhase(thisTransformer))
-
- override def transformApply(tree: Apply)(implicit ctx: Context, info: TransformerInfo): Tree =
- ctx.traceIndented(s"transforming ${tree.show} at phase ${ctx.phase}", show = true) {
-
- def transformArg(arg: Tree, formal: Type): Tree = formal.dealias match {
- case formalExpr: ExprType =>
- val argType = arg.tpe.widen
- val argFun = arg match {
- case Apply(Select(qual, nme.apply), Nil)
- if qual.tpe.derivesFrom(defn.FunctionClass(0)) && isPureExpr(qual) =>
- qual
- case _ =>
- val inSuper = if (ctx.mode.is(Mode.InSuperCall)) InSuperCall else EmptyFlags
- val meth = ctx.newSymbol(
- ctx.owner, nme.ANON_FUN, Synthetic | Method | inSuper, MethodType(Nil, Nil, argType))
- Closure(meth, _ => arg.changeOwner(ctx.owner, meth))
- }
- ref(defn.dummyApply).appliedToType(argType).appliedTo(argFun)
- case _ =>
- arg
- }
-
- val MethodType(_, formals) = tree.fun.tpe.widen
- val args1 = tree.args.zipWithConserve(formals)(transformArg)
- cpy.Apply(tree)(tree.fun, args1)
- }
-
- /** If denotation had an ExprType before, it now gets a function type */
- private def exprBecomesFunction(symd: SymDenotation)(implicit ctx: Context) =
- (symd is Param) || (symd is (ParamAccessor, butNot = Method))
-
- /** Map `tree` to `tree.apply()` is `ftree` was of ExprType and becomes now a function */
- private def applyIfFunction(tree: Tree, ftree: Tree)(implicit ctx: Context) = {
- val origDenot = originalDenotation(ftree)
- if (exprBecomesFunction(origDenot) && (origDenot.info.isInstanceOf[ExprType]))
- tree.select(defn.Function0_apply).appliedToNone
- else tree
- }
-
- override def transformIdent(tree: Ident)(implicit ctx: Context, info: TransformerInfo): Tree =
- applyIfFunction(tree, tree)
-
- override def transformTypeApply(tree: TypeApply)(implicit ctx: Context, info: TransformerInfo): Tree = tree match {
- case TypeApply(Select(_, nme.asInstanceOf_), arg :: Nil) =>
- // tree might be of form e.asInstanceOf[x.type] where x becomes a function.
- // See pos/t296.scala
- applyIfFunction(tree, arg)
- case _ => tree
- }
-
- override def transformValDef(tree: ValDef)(implicit ctx: Context, info: TransformerInfo): Tree =
- if (exprBecomesFunction(tree.symbol))
- cpy.ValDef(tree)(tpt = tree.tpt.withType(tree.symbol.info))
- else tree
-
- def transformInfo(tp: Type, sym: Symbol)(implicit ctx: Context): Type = tp match {
- case ExprType(rt) if exprBecomesFunction(sym) => defn.FunctionOf(Nil, rt)
- case _ => tp
- }
-
- override def mayChange(sym: Symbol)(implicit ctx: Context): Boolean = sym.isTerm
-}