class ElimByName
extends MiniPhaseTransform with InfoTransformer

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.

Constructors

ElimByName ( )

Members

private def applyIfFunction ( tree: Tree , ftree: Tree ) ( implicit ctx: Context ) : Tree

Map tree to tree.apply() is ftree was of ExprType and becomes now a function

Map tree to tree.apply() is ftree was of ExprType and becomes now a function

private def exprBecomesFunction ( symd: SymDenotation ) ( implicit ctx: Context ) : Boolean

If denotation had an ExprType before, it now gets a function type

If denotation had an ExprType before, it now gets a function type

[+] override def mayChange ( sym: Symbol ) ( implicit ctx: Context ) : Boolean

Denotations with a symbol where mayChange is false are guaranteed to be unaffected by this transform, so transformInfo need not be run. This can save ti...

Denotations with a symbol where mayChange is false are guaranteed to be unaffected by this transform, so transformInfo need not be run. This can save time, and more importantly, can help avoid forcing symbol completers.

private def originalDenotation ( tree: Tree ) ( implicit ctx: Context ) : SymDenotation

The info of the tree's symbol at phase Nullarify (i.e. before transformation)

The info of the tree's symbol at phase Nullarify (i.e. before transformation)

[+] override def phaseName : String

A name given to the Phase that can be used to debug the compiler. For instance, it is possible to print trees after a given phase using:

A name given to the Phase that can be used to debug the compiler. For instance, it is possible to print trees after a given phase using:

$ ./bin/dotc -Xprint:<phaseNameHere> sourceFile.scala
override def runsAfterGroupsOf : Set [ Class [ Nothing <: Phase ] ]

List of names of phases that should have finished their processing of all compilation units before this phase starts

List of names of phases that should have finished their processing of all compilation units before this phase starts

override def transformApply ( tree: Apply ) ( implicit ctx: Context , info: TransformerInfo ) : Tree
override def transformIdent ( tree: Ident ) ( implicit ctx: Context , info: TransformerInfo ) : Tree
def transformInfo ( tp: Type , sym: Symbol ) ( implicit ctx: Context ) : Type
override def transformTypeApply ( tree: TypeApply ) ( implicit ctx: Context , info: TransformerInfo ) : Tree
override def transformValDef ( tree: ValDef ) ( implicit ctx: Context , info: TransformerInfo ) : Tree