dotty.tools.dotc.transform

Members list

Type members

Classlikes

abstract class AccessProxies

A utility class for generating access proxies. Currently used for inline accessors and protected accessors.

A utility class for generating access proxies. Currently used for inline accessors and protected accessors.

Attributes

Companion
object
Supertypes
class Object
trait Matchable
class Any
Known subtypes
object AccessProxies

Attributes

Companion
class
Supertypes
class Object
trait Matchable
class Any
Self type
class ArrayApply extends MiniPhase

This phase rewrites calls to Array.apply to a direct instantiation of the array in the bytecode.

This phase rewrites calls to Array.apply to a direct instantiation of the array in the bytecode.

Transforms scala.Array.apply([....]) and scala.Array.apply(..., [....]) into [...]

Attributes

Companion
object
Supertypes
class MiniPhase
class Phase
class Object
trait Matchable
class Any
object ArrayApply

Attributes

Companion
class
Supertypes
class Object
trait Matchable
class Any
Self type
ArrayApply.type

This phase rewrites calls to array constructors to newArray method in Dotty.runtime.Arrays module.

This phase rewrites calls to array constructors to newArray method in Dotty.runtime.Arrays module.

It assummes that generic arrays have already been handled by typer(see Applications.convertNewGenericArray). Additionally it optimizes calls to scala.Array.ofDim functions by replacing them with calls to newArray with specific dimensions

Attributes

Companion
object
Supertypes
class MiniPhase
class Phase
class Object
trait Matchable
class Any

Attributes

Companion
class
Supertypes
class Object
trait Matchable
class Any
Self type
class BeanProperties(thisPhase: DenotTransformer)

Attributes

Supertypes
class Object
trait Matchable
class Any
class BetaReduce extends MiniPhase

Rewrite an application

Rewrite an application

(([X1, ..., Xm] => (x1, ..., xn) => b): T)[T1, ..., Tm](y1, ..., yn)

where

  • all yi are pure references without a prefix
  • the closure can also be contextual or erased, but cannot be a SAM type
  • the type parameters Xi and type arguments Ti are optional
  • the type ascription ...: T is optional

to

[xi := yi]b

This is more limited than beta reduction in inlining since it only works for simple variables yi. It is more general since it also works for type-ascripted closures.

A typical use case is eliminating redundant closures for blackbox macros that return context functions. See i6375.scala.

Attributes

Companion
object
Supertypes
class MiniPhase
class Phase
class Object
trait Matchable
class Any
object BetaReduce

Attributes

Companion
class
Supertypes
class Object
trait Matchable
class Any
Self type
BetaReduce.type
class Bridges(root: ClassSymbol, thisPhase: DenotTransformer)(using x$3: Context)

A helper class for generating bridge methods in class root.

A helper class for generating bridge methods in class root.

Attributes

Supertypes
class Object
trait Matchable
class Any

This phase translates variables that are captured in closures to heap-allocated refs.

This phase translates variables that are captured in closures to heap-allocated refs.

Attributes

Companion
object
Supertypes
class MiniPhase
class Phase
class Object
trait Matchable
class Any
Show all
Self type
object CapturedVars

Attributes

Companion
class
Supertypes
class Object
trait Matchable
class Any
Self type

Attributes

Companion
class
Supertypes
class Object
trait Matchable
class Any
Self type

Checks that some definitions do not call themselves in an infinite loop This is an incomplete check, designed to catch some likely bugs instead of being exhaustive. The situations where infinite loops are diagnosed are

Checks that some definitions do not call themselves in an infinite loop This is an incomplete check, designed to catch some likely bugs instead of being exhaustive. The situations where infinite loops are diagnosed are

  1. A given method should not directly call itself
  2. An apply method in a given object should not directly call itself
  3. A lazy val should not directly force itself
  4. An extension method should not directly call itself

In all these cases, there are some situations which would not lead to an infinite loop at runtime. For instance, the call could go at runtime to an overriding version of the method or val which breaks the loop. That's why this phase only issues warnings, not errors, and also why we restrict checks to the 4 cases above, where a recursion is somewhat hidden. There are also other more complicated calling patterns that could also be diagnosed as loops with more effort. This could be improved in the future.

Attributes

Companion
object
Supertypes
class MiniPhase
class Phase
class Object
trait Matchable
class Any
Self type

Attributes

Companion
class
Supertypes
class Object
trait Matchable
class Any
Self type
class CheckNoSuperThis extends MiniPhase

Checks that super and this calls do not pass this as (part of) an argument.

Checks that super and this calls do not pass this as (part of) an argument.

Attributes

Companion
object
Supertypes
class MiniPhase
class Phase
class Object
trait Matchable
class Any
Self type
class CheckReentrant extends MiniPhase

A no-op transform that checks whether the compiled sources are re-entrant. If -Ycheck:reentrant is set, the phase makes sure that there are no variables that are accessible from a global object. It excludes from checking paths that are labeled with one of the annotations

A no-op transform that checks whether the compiled sources are re-entrant. If -Ycheck:reentrant is set, the phase makes sure that there are no variables that are accessible from a global object. It excludes from checking paths that are labeled with one of the annotations

Attributes

Companion
object
Supertypes
class MiniPhase
class Phase
class Object
trait Matchable
class Any

Attributes

Companion
class
Supertypes
class Object
trait Matchable
class Any
Self type
class CheckStatic extends MiniPhase

A transformer that check that requirements of Static fields\methods are implemented:

A transformer that check that requirements of Static fields\methods are implemented:

  1. Only objects can have members annotated with @static
  2. The fields annotated with @static should precede any non-@static fields. This ensures that we do not introduce surprises for users in initialization order.
  3. If a member foo of an object C is annotated with @static, the companion class C is not allowed to define term members with name foo.
  4. If a member foo of an object C is annotated with @static, the companion class C is not allowed to inherit classes that define a term member with name foo.
  5. Only @static methods and vals are supported in companions of traits. Java8 supports those, but not vars, and JavaScript does not have interfaces at all.
  6. @static Lazy vals are currently unsupported.

Attributes

Companion
object
Supertypes
class MiniPhase
class Phase
class Object
trait Matchable
class Any
object CheckStatic

Attributes

Companion
class
Supertypes
class Object
trait Matchable
class Any
Self type
class CheckUnused extends MiniPhase

A compiler phase that checks for unused imports or definitions

A compiler phase that checks for unused imports or definitions

Basically, it gathers definition/imports and their usage. If a definition/imports does not have any usage, then it is reported.

Attributes

Companion
object
Supertypes
class MiniPhase
class Phase
class Object
trait Matchable
class Any
Known subtypes
class PostInlining
class PostTyper
object CheckUnused

Attributes

Companion
class
Supertypes
class Object
trait Matchable
class Any
Self type

Small phase to be run to collect main classes and store them in the context. The general rule to run this phase is:

Small phase to be run to collect main classes and store them in the context. The general rule to run this phase is:

  • The output of compilation is JarArchive
  • There is no -Xmain-class defined

The following flags affect this phase: -d path.jar -Xmain-class

Attributes

Companion
object
Supertypes
class MiniPhase
class Phase
class Object
trait Matchable
class Any

Attributes

Companion
class
Supertypes
class Object
trait Matchable
class Any
Self type

Attributes

Companion
class
Supertypes
class Object
trait Matchable
class Any
Self type

Collect fields that can be nulled out after use in lazy initialization.

Collect fields that can be nulled out after use in lazy initialization.

This information is used during lazy val transformation to assign null to private fields that are only used within a lazy val initializer. This is not just an optimization, but is needed for correctness to prevent memory leaks. E.g.

class TestByNameLazy(byNameMsg: => String) {
  lazy val byLazyValMsg = byNameMsg
}

Here byNameMsg should be null out once byLazyValMsg is initialised.

A field is nullable if all the conditions below hold:

  • belongs to a non trait-class
  • is private[this]
  • is not lazy
  • its type is nullable after erasure
  • is only used in a lazy val initializer
  • defined in the same class as the lazy val

Attributes

Companion
object
Supertypes
class MiniPhase
class Phase
class Object
trait Matchable
class Any

Attributes

Companion
class
Supertypes
class Object
trait Matchable
class Any
Self type

For Scala enums that inherit from java.lang.Enum: Add constructor parameters for name and ordinal to pass from each case to the java.lang.Enum class.

For Scala enums that inherit from java.lang.Enum: Add constructor parameters for name and ordinal to pass from each case to the java.lang.Enum class.

Attributes

Companion
object
Supertypes
class MiniPhase
class Phase
class Object
trait Matchable
class Any
Show all
Self type
object Constructors

Attributes

Companion
class
Supertypes
class Object
trait Matchable
class Any
Self type

This transform

This transform

  • moves initializers from body to constructor.
  • makes all supercalls explicit
  • also moves private fields that are accessed only from constructor into the constructor if possible.

Attributes

Companion
object
Supertypes
class MiniPhase
class Phase
class Object
trait Matchable
class Any
Show all
Self type

Attributes

Supertypes
class Object
trait Matchable
class Any
Self type
class CookComments extends MiniPhase

Attributes

Companion
object
Supertypes
class MiniPhase
class Phase
class Object
trait Matchable
class Any
object CookComments

Attributes

Companion
class
Supertypes
class Object
trait Matchable
class Any
Self type

Attributes

Companion
class
Supertypes
class Object
trait Matchable
class Any
Self type

Counts number of accesses to outer accessors and outer fields of classes that are visible only within one source file. The info is collected in outerAccessCount and used in the subsequent DropOuterAccessors phase

Counts number of accesses to outer accessors and outer fields of classes that are visible only within one source file. The info is collected in outerAccessCount and used in the subsequent DropOuterAccessors phase

Attributes

Companion
object
Supertypes
class MiniPhase
class Phase
class Object
trait Matchable
class Any
Self type

Attributes

Companion
object
Supertypes
class MiniPhase
class Phase
class Object
trait Matchable
class Any

Attributes

Companion
class
Supertypes
class Object
trait Matchable
class Any
Self type
class CtxLazy[T](expr: Context ?=> T)

Utility class for lazy values whose evaluation depends on a context. This should be used whenever the evaluation of a lazy expression depends on some context, but the value can be re-used afterwards with a different context.

Utility class for lazy values whose evaluation depends on a context. This should be used whenever the evaluation of a lazy expression depends on some context, but the value can be re-used afterwards with a different context.

A typical use case is a lazy val in a phase object which exists once per root context where the expression intiializing the lazy val depends only on the root context, but not any changes afterwards.

Attributes

Supertypes
class Object
trait Matchable
class Any
abstract class Dependencies(root: Tree, rootContext: Context)

Exposes the dependencies of the root tree in three functions or maps: freeVars, tracked, and logicalOwner.

Exposes the dependencies of the root tree in three functions or maps: freeVars, tracked, and logicalOwner.

Attributes

Companion
object
Supertypes
class Object
trait Matchable
class Any
object Dependencies

Attributes

Companion
class
Supertypes
class Object
trait Matchable
class Any
Self type
object DropBreaks

Attributes

Companion
class
Supertypes
class Object
trait Matchable
class Any
Self type
DropBreaks.type
class DropBreaks extends MiniPhase

Rewrites local Break throws to labeled returns. Drops try statements on breaks if no other uses of its label remain. A Break throw with a Label created by some enclosing boundary is replaced with a labeled return if

Rewrites local Break throws to labeled returns. Drops try statements on breaks if no other uses of its label remain. A Break throw with a Label created by some enclosing boundary is replaced with a labeled return if

  • the throw and the boundary are in the same method, and
  • there is no try expression inside the boundary that encloses the throw.

Attributes

Companion
object
Supertypes
class MiniPhase
class Phase
class Object
trait Matchable
class Any

Attributes

Companion
class
Supertypes
class Object
trait Matchable
class Any
Self type

Drops unused outer accessors of inner classes that are visible only in one toplevel class. For other classes, we can't tell whether an outer accessor is used or not. It could for instance be used in a type test in some other source.

Drops unused outer accessors of inner classes that are visible only in one toplevel class. For other classes, we can't tell whether an outer accessor is used or not. It could for instance be used in a type test in some other source.

Attributes

Companion
object
Supertypes
class MiniPhase
class Phase
class Object
trait Matchable
class Any
Show all
Self type

This phase implements the following transformations:

This phase implements the following transformations:

  1. For types of method and class parameters:

    => T becomes () ?=> T

  2. For references to cbn-parameters:

    x becomes x.apply()

  3. For arguments to cbn parameters

    e becomes () ?=> e

An optimization is applied: If the argument e to a cbn parameter is already of type () ?=> T and is a pure expression, we avoid (2) and (3), i.e. we pass e directly instead of () ?=> e.apply().

Note that () ?=> T cannot be written in source since user-defined context functions must have at least one parameter. We use the type here as a convenient marker of something that will erase to Function0, and where we know that it came from a by-name parameter.

Note also that the transformation applies only to types of parameters, not to other occurrences of ExprTypes. In particular, embedded occurrences in function types such as (=> T) => U are left as-is here (they are eliminated in erasure). Trying to convert these as well would mean traversing all the types, and that leads to cyclic reference errors in many cases. This can cause problems in that we might have sometimes a () ?=> T where a => T is expected. To compensate, there is a new clause in TypeComparer#subArg that declares () ?=> T to be a subtype of => T for arguments of type applications at any point after this phase and up to erasure.

Attributes

Companion
object
Supertypes
class MiniPhase
class Phase
class Object
trait Matchable
class Any
Show all
Self type
object ElimByName

Attributes

Companion
class
Supertypes
class Object
trait Matchable
class Any
Self type
ElimByName.type

Attributes

Companion
class
Supertypes
class Object
trait Matchable
class Any
Self type

This phase erases ErasedValueType to their underlying type. It also removes the synthetic cast methods u2evt$ and evt2u$ which are no longer needed afterwards. Finally, it checks that we don't introduce "double definitions" of pairs of methods that now have the same signature but were not considered matching before erasure.

This phase erases ErasedValueType to their underlying type. It also removes the synthetic cast methods u2evt$ and evt2u$ which are no longer needed afterwards. Finally, it checks that we don't introduce "double definitions" of pairs of methods that now have the same signature but were not considered matching before erasure.

Attributes

Companion
object
Supertypes
class MiniPhase
class Phase
class Object
trait Matchable
class Any
Show all
Self type
object ElimOpaque

Attributes

Companion
class
Supertypes
class Object
trait Matchable
class Any
Self type
ElimOpaque.type

Rewrites opaque type aliases to normal alias types

Rewrites opaque type aliases to normal alias types

Attributes

Companion
object
Supertypes
class MiniPhase
class Phase
class Object
trait Matchable
class Any
Show all
Self type
class ElimOuterSelect extends MiniPhase

This phase rewrites outer selects E.n_<outer> which were introduced by inlining to outer paths.

This phase rewrites outer selects E.n_<outer> which were introduced by inlining to outer paths.

Attributes

Companion
object
Supertypes
class MiniPhase
class Phase
class Object
trait Matchable
class Any

Attributes

Companion
class
Supertypes
class Object
trait Matchable
class Any
Self type

Eliminates syntactic references to package terms as prefixes of classes, so that there's no chance they accidentally end up in the backend.

Eliminates syntactic references to package terms as prefixes of classes, so that there's no chance they accidentally end up in the backend.

Attributes

Companion
object
Supertypes
class MiniPhase
class Phase
class Object
trait Matchable
class Any

Attributes

Companion
class
Supertypes
class Object
trait Matchable
class Any
Self type

This phase rewrite PolyFunction subclasses to FunctionN subclasses

This phase rewrite PolyFunction subclasses to FunctionN subclasses

class Foo extends PolyFunction {
    def apply(x_1: P_1, ..., x_N: P_N): R = rhs
}

becomes: class Foo extends FunctionN { def apply(x_1: P_1, ..., x_N: P_N): R = rhs }

Attributes

Companion
object
Supertypes
class MiniPhase
class Phase
class Object
trait Matchable
class Any
Show all

Attributes

Companion
class
Supertypes
class Object
trait Matchable
class Any
Self type
object ElimRepeated

Attributes

Companion
class
Supertypes
class Object
trait Matchable
class Any
Self type

A transformer that eliminates repeated parameters (T*) from all types, replacing them with Seq or Array types and adapting repeated arguments to conform to the transformed type if needed.

A transformer that eliminates repeated parameters (T*) from all types, replacing them with Seq or Array types and adapting repeated arguments to conform to the transformed type if needed.

Attributes

Companion
object
Supertypes
class MiniPhase
class Phase
class Object
trait Matchable
class Any
Show all
Self type
class ElimStaticThis extends MiniPhase

Replace This references to module classes in static methods by global identifiers to the corresponding modules.

Replace This references to module classes in static methods by global identifiers to the corresponding modules.

Attributes

Companion
object
Supertypes
class MiniPhase
class Phase
class Object
trait Matchable
class Any

Attributes

Companion
class
Supertypes
class Object
trait Matchable
class Any
Self type
class EmptyPhase extends Phase

A phase that can be inserted directly after a phase that cannot be checked, to enable a -Ycheck as soon as possible afterwards

A phase that can be inserted directly after a phase that cannot be checked, to enable a -Ycheck as soon as possible afterwards

Attributes

Supertypes
class Phase
class Object
trait Matchable
class Any
class Erasure extends Phase, DenotTransformer

Attributes

Companion
object
Supertypes
class Phase
class Object
trait Matchable
class Any
object Erasure

Attributes

Companion
class
Supertypes
class Object
trait Matchable
class Any
Self type
Erasure.type
class EtaReduce extends MiniPhase

Rewrite (x1, ... xN) => f(x1, ... xN) for N >= 0 to f, provided f is a pure path of function type.

Rewrite (x1, ... xN) => f(x1, ... xN) for N >= 0 to f, provided f is a pure path of function type.

This optimization is crucial for context functions. The compiler produces a contextual closure around values passed as arguments where a context function is expected, unless that value has the syntactic form of a context function literal.

Also handle variants of eta-expansions where

  • result f.apply(X_1,...,X_n) is subject to a synthetic cast, or
  • the application uses a specialized apply method, or
  • the closure is adapted (see Erasure#adaptClosure)

Without this phase, when a contextual function is passed as an argument to a recursive function, that would have the unfortunate effect of a linear growth in transient thunks of identical type wrapped around each other, leading to performance degradation, and in some cases, stack overflows.

Attributes

Companion
object
Supertypes
class MiniPhase
class Phase
class Object
trait Matchable
class Any
object EtaReduce

Attributes

Companion
class
Supertypes
class Object
trait Matchable
class Any
Self type
EtaReduce.type

Make private term members that are accessed from another class non-private by resetting the Private flag and expanding their name.

Make private term members that are accessed from another class non-private by resetting the Private flag and expanding their name.

Make private accessor in value class not-private. This is necessary to unbox the value class when accessing it from separate compilation units

Also, make non-private any private parameter forwarders that forward to an inherited public or protected parameter accessor with the same name as the forwarder. This is necessary since private methods are not allowed to have the same name as inherited public ones.

See discussion in https://github.com/lampepfl/dotty/pull/784 and https://github.com/lampepfl/dotty/issues/783

Attributes

Companion
object
Supertypes
class MiniPhase
class Phase
class Object
trait Matchable
class Any
Show all
Self type
object ExpandPrivate

Attributes

Companion
class
Supertypes
class Object
trait Matchable
class Any
Self type
object ExpandSAMs

Expand SAM closures that cannot be represented by the JVM as lambdas to anonymous classes. These fall into five categories

Expand SAM closures that cannot be represented by the JVM as lambdas to anonymous classes. These fall into five categories

  1. Partial function closures, we need to generate isDefinedAt and applyOrElse methods for these.
  2. Closures implementing non-trait classes
  3. Closures implementing classes that inherit from a class other than Object (a lambda cannot not be a run-time subtype of such a class)
  4. Closures that implement traits which run initialization code.
  5. Closures that get synthesized abstract methods in the transformation pipeline. These methods can be (1) superaccessors, (2) outer references, (3) accessors for fields.

However, implicit function types do not count as SAM types.

Attributes

Companion
class
Supertypes
class Object
trait Matchable
class Any
Self type
ExpandSAMs.type
class ExpandSAMs extends MiniPhase

Attributes

Companion
object
Supertypes
class MiniPhase
class Phase
class Object
trait Matchable
class Any

This phase adds outer accessors to classes and traits that need them. Compared to Scala 2.x, it tries to minimize the set of classes that take outer accessors by scanning class implementations for outer references.

This phase adds outer accessors to classes and traits that need them. Compared to Scala 2.x, it tries to minimize the set of classes that take outer accessors by scanning class implementations for outer references.

The following things are delayed until erasure and are performed by class OuterOps:

  • add outer parameters to constructors
  • pass outer arguments in constructor calls

replacement of outer this by outer paths is done in Erasure. needs to run after pattern matcher as it can add outer checks and force creation of $outer

Attributes

Companion
object
Supertypes
class MiniPhase
class Phase
class Object
trait Matchable
class Any
Show all
Self type
object ExplicitOuter

Attributes

Companion
class
Supertypes
class Object
trait Matchable
class Any
Self type
class ExplicitSelf extends MiniPhase

Transform references of the form

Transform references of the form

C.this.m

where C is a class with explicit self type and C is not a subclass of the owner of m to

C.this.asInstanceOf[S & C.this.type].m

where S is the self type of C. See run/i789.scala for a test case why this is needed.

Also replaces idents referring to the self type with ThisTypes.

Attributes

Companion
object
Supertypes
class MiniPhase
class Phase
class Object
trait Matchable
class Any
object ExplicitSelf

Attributes

Companion
class
Supertypes
class Object
trait Matchable
class Any
Self type

Perform Step 1 in the inline classes SIP: Creates extension methods for all methods in a value class, except parameter or super accessors, or constructors.

Perform Step 1 in the inline classes SIP: Creates extension methods for all methods in a value class, except parameter or super accessors, or constructors.

Additionally, for a value class V, let U be the underlying type after erasure. We add to the companion module of V two cast methods: def u2evt$(x0: U): ErasedValueType(V, U) def evt2u$(x0: ErasedValueType(V, U)): U The casts are used in Erasure to make it typecheck, they are then removed in ElimErasedValueType. This is different from the implementation of value classes in Scala 2 (see SIP-15) which uses asInstanceOf which does not typecheck.

Finally, if the constructor of a value class is private pr protected it is widened to public.

Also, drop the Local flag from all private[this] and protected[this] members that will be moved to the companion object.

Attributes

Companion
object
Supertypes
class MiniPhase
class Phase
class Object
trait Matchable
class Any
Show all
Self type

Attributes

Companion
class
Supertypes
class Object
trait Matchable
class Any
Self type

Attributes

Companion
class
Supertypes
class Object
trait Matchable
class Any
Self type

The first tree transform

The first tree transform

  • eliminates some kinds of trees: Imports other than language imports, Exports, NamedArgs, type trees other than TypeTree
  • stubs out native methods
  • eliminates self tree in Template and self symbol in ClassInfo
  • collapses all type trees to trees of class TypeTree
  • converts idempotent expressions with constant types
  • drops branches of ifs using the rules if (true) A else B ==> A if (false) A else B ==> B

Attributes

Companion
object
Supertypes
class MiniPhase
class Phase
class Object
trait Matchable
class Any
Show all
Self type

Lift nested classes to toplevel

Lift nested classes to toplevel

Attributes

Companion
object
Supertypes
class MiniPhase
class Phase
class Object
trait Matchable
class Any
Show all
object Flatten

Attributes

Companion
class
Supertypes
class Object
trait Matchable
class Any
Self type
Flatten.type

Attributes

Companion
class
Supertypes
class Object
trait Matchable
class Any
Self type
class ForwardDepChecks extends MiniPhase

Attributes

Companion
object
Supertypes
class MiniPhase
class Phase
class Object
trait Matchable
class Any

Provides methods to produce fully parameterized versions of instance methods, where the this of the enclosing class is abstracted out in an extra leading $this parameter and type parameters of the class become additional type parameters of the fully parameterized method.

Provides methods to produce fully parameterized versions of instance methods, where the this of the enclosing class is abstracted out in an extra leading $this parameter and type parameters of the class become additional type parameters of the fully parameterized method.

Example usage scenarios are:

  • extension methods of value classes
  • implementations of trait methods
  • static protected accessors
  • local methods produced by tailrec transform

Note that the methods lift out type parameters of the class containing the instance method, but not type parameters of enclosing classes. The fully instantiated method therefore needs to be put in a scope "close" to the original method, i.e. they need to share the same outer pointer. Examples of legal positions are: in the companion object, or as a local method inside the original method.

Note: The scheme does not handle yet methods where type parameter bounds depend on value parameters of the enclosing class, as in:

class C(val a: String) extends AnyVal {
  def foo[U <: a.type]: Unit = ...
}

The expansion of method foo would lead to

def foo$extension[U <: $this.a.type]($this: C): Unit = ...

which is not typable. Not clear yet what to do. Maybe allow PolyTypes to follow method parameters and translate to the following:

def foo$extension($this: C)[U <: $this.a.type]: Unit = ...

Attributes

See also

class-dependent-extension-method.scala in pending/pos.

Companion
object
Supertypes
class Object
trait Matchable
class Any
Known subtypes

Attributes

Companion
trait
Supertypes
class Object
trait Matchable
class Any
Self type

This phase adds forwarder for XXL functions apply methods that are implemented with a method with explicit parameters (not in Array[Object]).

This phase adds forwarder for XXL functions apply methods that are implemented with a method with explicit parameters (not in Array[Object]).

In particular for every method def apply(x1: T1, ... xn: Tn): R in class M subtype of FunctionN[T1, ..., Tn, R] with N > 22 a forwarder def apply(xs: Array[Object]): R = this.apply(xs(0).asInstanceOf[T1], ..., xs(n-1).asInstanceOf[Tn]).asInstanceOf[R] is generated.

Attributes

Companion
object
Supertypes
class MiniPhase
class Phase
class Object
trait Matchable
class Any
Show all

Attributes

Companion
class
Supertypes
class Object
trait Matchable
class Any
Self type

Helper object to generate generic java signatures, as defined in the Java Virtual Machine Specification, §4.3.4

Helper object to generate generic java signatures, as defined in the Java Virtual Machine Specification, §4.3.4

Attributes

Supertypes
class Object
trait Matchable
class Any
Self type

Performs the following rewritings for fields of a class:

Performs the following rewritings for fields of a class:

val x: T = e --> def x: T = e var x: T = e --> def x: T = e

val x: T --> def x: T

lazy val x: T = e --> lazy def x: T =e

var x: T --> def x: T

non-static val x$ = e --> def x$ = e

Also, generate setters for fields that are private but not private[this] The form of a setter is

def x_=(init: T): Unit = ()

Omitted from the rewritings are

  • private[this] fields in classes (excluding traits, value classes)
  • fields generated for static modules (TODO: needed?)
  • parameters, static fields, and fields coming from Java

The rhs is computed later, in phase Memoize.

Furthermore, assignments to mutable vars with setters are replaced by setter calls

p.x = e --> p.x_=(e)

No fields are generated yet. This is done later in phase Memoize.

Also, drop the Local flag from all private[this] and protected[this] members. This allows subsequent code motions in Flatten.

Attributes

Companion
object
Supertypes
class MiniPhase
class Phase
class Object
trait Matchable
class Any
Show all
Self type
object Getters

Attributes

Companion
class
Supertypes
class Object
trait Matchable
class Any
Self type
Getters.type

Attributes

Companion
class
Supertypes
class Object
trait Matchable
class Any
Self type

This phase hoists complex arguments of supercalls and this-calls out of the enclosing class. Example:

This phase hoists complex arguments of supercalls and this-calls out of the enclosing class. Example:

class B(y: Int) extends A({ def f(x: Int) = x * x; f(y)})

is translated to

class B(y: Int) extends A(B#B$superArg$1(this.y)) {
  private <static> def B$superArg$1(y: Int): Int = {
    def f(x: Int): Int = x.*(x); f(y)
  }
}

An argument is complex if it contains a method or template definition, a this or a new, or it contains an identifier which needs a this prefix to be accessed. This is the case if the identifier has neither a global reference nor a reference to a parameter of the enclosing class.

Attributes

See also

needsHoist for an implementation. A hoisted argument definition gets the parameters of the class it is hoisted from as method parameters. The definition is installed in the scope enclosing the class, or, if that is a package, it is made a static method of the class itself.

Companion
object
Supertypes
class MiniPhase
class Phase
class Object
trait Matchable
class Any
Show all
Self type
class InlinePatterns extends MiniPhase

Rewrite an application

Rewrite an application

{new { def unapply(x0: X0)(x1: X1,..., xn: Xn) = b }}.unapply(y0)(y1, ..., yn)

where

  • the method is unapply or unapplySeq
  • the method does not have type parameters

to

[xi := yi]b

This removes placeholders added by inline unapply/unapplySeq patterns.

Attributes

Companion
object
Supertypes
class MiniPhase
class Phase
class Object
trait Matchable
class Any

Attributes

Companion
class
Supertypes
class Object
trait Matchable
class Any
Self type
class InlineVals extends MiniPhase

Check that tree.rhs can be right hand-side of an inline value definition.

Check that tree.rhs can be right hand-side of an inline value definition.

Attributes

Companion
object
Supertypes
class MiniPhase
class Phase
class Object
trait Matchable
class Any
object InlineVals

Attributes

Companion
class
Supertypes
class Object
trait Matchable
class Any
Self type
InlineVals.type
class Inlining extends MacroTransform

Inlines all calls to inline methods that are not in an inline method or a quote

Inlines all calls to inline methods that are not in an inline method or a quote

Attributes

Companion
object
Supertypes
class Phase
class Object
trait Matchable
class Any
object Inlining

Attributes

Companion
class
Supertypes
class Object
trait Matchable
class Any
Self type
Inlining.type

Implements code coverage by inserting calls to scala.runtime.coverage.Invoker ("instruments" the source code). The result can then be consumed by the Scoverage tool.

Implements code coverage by inserting calls to scala.runtime.coverage.Invoker ("instruments" the source code). The result can then be consumed by the Scoverage tool.

Attributes

Companion
object
Supertypes
class Phase
class Object
trait Matchable
class Any
Show all

Attributes

Companion
class
Supertypes
class Object
trait Matchable
class Any
Self type
class Instrumentation extends MiniPhase

The phase is enabled if the -Yinstrument option is set. If enabled, it counts the number of closures or allocations for each source position. It does this by generating a call to dotty.tools.dotc.util.Stats.doRecord.

The phase is enabled if the -Yinstrument option is set. If enabled, it counts the number of closures or allocations for each source position. It does this by generating a call to dotty.tools.dotc.util.Stats.doRecord.

Attributes

Companion
object
Supertypes
class MiniPhase
class Phase
class Object
trait Matchable
class Any
Self type

Attributes

Companion
class
Supertypes
class Object
trait Matchable
class Any
Self type

Attributes

Companion
class
Supertypes
class Object
trait Matchable
class Any
Self type

Replace member references as follows:

Replace member references as follows:

  • x != y for != in class Any becomes !(x == y) with == in class Any.
  • x.## for ## in NullClass becomes 0
  • x.## for ## in Any becomes calls to ScalaRunTime.hash, using the most precise overload available

Attributes

Companion
object
Supertypes
class MiniPhase
class Phase
class Object
trait Matchable
class Any
object LambdaLift

Attributes

Companion
class
Supertypes
class Object
trait Matchable
class Any
Self type
LambdaLift.type

This phase performs the necessary rewritings to eliminate classes and methods nested in other methods. In detail:

This phase performs the necessary rewritings to eliminate classes and methods nested in other methods. In detail:

  1. It adds all free variables of local functions as additional parameters (proxies).
  2. It rebinds references to free variables to the corresponding proxies,
  3. It lifts all local functions and classes out as far as possible, but at least to the enclosing class.
  4. It stores free variables of non-trait classes as additional fields of the class. The fields serve as proxies for methods in the class, which avoids the need of passing additional parameters to these methods.

A particularly tricky case are local traits. These cannot store free variables as field proxies, because LambdaLift runs after Mixin, so the fields cannot be expanded anymore. Instead, methods of local traits get free variables of the trait as additional proxy parameters. The difference between local classes and local traits is illustrated by the two rewritings below.

def f(x: Int) = { def f(x: Int) = new C(x).f2 class C { ==> class C(x$1: Int) { def f2 = x def f2 = x$1 } } new C().f2 }

def f(x: Int) = { def f(x: Int) = new C().f2(x) trait T { ==> trait T def f2 = x def f2(x$1: Int) = x$1 } } class C extends T class C extends T new C().f2 }

Attributes

Companion
object
Supertypes
class MiniPhase
class Phase
class Object
trait Matchable
class Any
Show all
Self type

Attributes

Companion
object
Supertypes
class MiniPhase
class Phase
class Object
trait Matchable
class Any
Show all
object LazyVals

Attributes

Companion
class
Supertypes
class Object
trait Matchable
class Any
Self type
LazyVals.type
class LetOverApply extends MiniPhase

Rewrite { stats; expr}.f(args) to { stats; expr.f(args) } and { stats; expr }(args) to { stats; expr(args) } before proceeding, but leave closures alone. This is necessary to be able to collapse applies of IFTs (this is done in Erasure).

Rewrite { stats; expr}.f(args) to { stats; expr.f(args) } and { stats; expr }(args) to { stats; expr(args) } before proceeding, but leave closures alone. This is necessary to be able to collapse applies of IFTs (this is done in Erasure).

Attributes

Companion
object
Supertypes
class MiniPhase
class Phase
class Object
trait Matchable
class Any
object LetOverApply

Attributes

Companion
class
Supertypes
class Object
trait Matchable
class Any
Self type

Lifts try's that might be executed on non-empty expression stacks to their own methods. I.e.

Lifts try's that might be executed on non-empty expression stacks to their own methods. I.e.

try body catch handler

is lifted to

{ def liftedTree$n() = try body catch handler; liftedTree$n() }

However, don't lift try's without catch expressions (try-finally). Lifting is needed only for try-catch expressions that are evaluated in a context where the stack might not be empty. finally does not attempt to continue evaluation after an exception, so the fact that values on the stack are 'lost' does not matter (copied from https://github.com/scala/scala/pull/922).

Attributes

Companion
object
Supertypes
class MiniPhase
class Phase
class Object
trait Matchable
class Any
Show all
Self type
object LiftTry

Attributes

Companion
class
Supertypes
class Object
trait Matchable
class Any
Self type
LiftTry.type

Attributes

Companion
object
Supertypes
class Object
trait Matchable
class Any

Attributes

Companion
class
Supertypes
class Object
trait Matchable
class Any
Self type
abstract class MacroTransform extends Phase

A base class for transforms. A transform contains a compiler phase which applies a tree transformer.

A base class for transforms. A transform contains a compiler phase which applies a tree transformer.

Attributes

Supertypes
class Phase
class Object
trait Matchable
class Any
Known subtypes
class Inlining
class PickleQuotes
class PostInlining
class PostTyper
class Splicing
class Staging
Show all
object MegaPhase

A MegaPhase combines a number of mini-phases which are all executed in a single tree traversal.

A MegaPhase combines a number of mini-phases which are all executed in a single tree traversal.

This is an evolution of the previous "TreeTransformers.scala", which was written by @DarkDimius and is described in his thesis.

Attributes

Companion
class
Supertypes
class Object
trait Matchable
class Any
Self type
MegaPhase.type
class MegaPhase(val miniPhases: Array[MiniPhase]) extends Phase

Attributes

Companion
object
Supertypes
class Phase
class Object
trait Matchable
class Any
object Memoize

Attributes

Companion
class
Supertypes
class Object
trait Matchable
class Any
Self type
Memoize.type

Provides the implementations of all getters and setters, introducing fields to hold the value accessed by them. TODO: Make LazyVals a part of this phase?

Provides the implementations of all getters and setters, introducing fields to hold the value accessed by them. TODO: Make LazyVals a part of this phase?

def x(): T = e --> private val x: T = e def x(): T = x

def x(): T = e --> private[this] var x: T = e def x(): T = x

def x_=(y: T): Unit = () --> def x_=(y: T): Unit = x = y

Attributes

Companion
object
Supertypes
class MiniPhase
class Phase
class Object
trait Matchable
class Any
Show all
Self type
object Mixin

Attributes

Companion
class
Supertypes
class Object
trait Matchable
class Any
Self type
Mixin.type
class Mixin extends MiniPhase, SymTransformer

This phase performs the following transformations:

This phase performs the following transformations:

  1. (done in traitDefs and transformSym) For every concrete trait getter

    def x(): T = expr

make it non-private, and add the definition of its trait setter:

 <mods> def TraitName$_setter_$x(v: T): Unit
  1. (done in traitDefs) Make every concrete trait setter

    def x_=(y: T) = ()

deferred by mapping it to

<mods> def x_=(y: T)
  1. (done in transformSym) For every module class constructor in traits, remove its Private flag (but do not expand its name), since it will have to be instantiated in the classes that mix in the trait.

  2. For a non-trait class C:

    For every trait M directly implemented by the class (see SymUtils.mixin), in reverse linearization order, add the following definitions to C:

    4.1 (done in `traitInits`) For every parameter accessor `<mods> def x(): T` in M,
        in order of textual occurrence, add
    
         <mods> def x() = e
    
        where `e` is the constructor argument in C that corresponds to `x`. Issue
        an error if no such argument exists.
    
    4.2 (done in `traitInits`) For every concrete trait getter `<mods> def x(): T` in M
        which is not a parameter accessor, in order of textual occurrence, produce the following:
    
        4.2.1 If `x` is also a member of `C`, and is a lazy val,
    
          <mods> lazy val x: T = super[M].x
    
        4.2.2 If `x` is also a member of `C`, and is a module,
    
          <mods> lazy module val x: T = new T$(this)
    
        4.2.3 If `x` is also a member of `C`, and is something else:
    
          <mods> def x(): T = _
    
        4.2.5 If `x` is not a member of `C`, nothing gets added.
    
    4.3 (done in `superCallOpt`) The call:
    
          super[M].$init$()
    
    4.4 (done in `setters`) For every concrete setter `<mods> def x_=(y: T)` in M:
    
          <mods> def x_=(y: T) = ()
    
    4.5 (done in `mixinForwarders`) For every method
    `<mods> def f[Ts](ps1)...(psN): U` imn M` that needs to be disambiguated:
    
          <mods> def f[Ts](ps1)...(psN): U = super[M].f[Ts](ps1)...(psN)
    
    A method in M needs to be disambiguated if it is concrete, not overridden in C,
    and if it overrides another concrete method.
    
  3. (done in transformTemplate and transformSym) Drop all parameters from trait constructors, and rename them to nme.TRAIT_CONSTRUCTOR.

  4. (done in transformSym) Drop ParamAccessor flag from all parameter accessors in traits.

Conceptually, this is the second half of the previous mixin phase. It needs to run after erasure because it copies references to possibly private inner classes and objects into enclosing classes where they are not visible. This can only be done if all references are symbolic.

Attributes

Companion
object
Supertypes
class MiniPhase
class Phase
class Object
trait Matchable
class Any
Show all
Self type
class MixinOps(cls: ClassSymbol, thisPhase: DenotTransformer)(using x$3: Context)

Attributes

Supertypes
class Object
trait Matchable
class Any

Move static methods from companion to the class itself

Move static methods from companion to the class itself

Attributes

Companion
object
Supertypes
class MiniPhase
class Phase
class Object
trait Matchable
class Any
Show all
object MoveStatics

Attributes

Companion
class
Supertypes
class Object
trait Matchable
class Any
Self type

Attributes

Companion
class
Supertypes
class Object
trait Matchable
class Any
Self type
class NonLocalReturns extends MiniPhase

Implement non-local returns using NonLocalReturnControl exceptions.

Implement non-local returns using NonLocalReturnControl exceptions.

Attributes

Companion
object
Supertypes
class MiniPhase
class Phase
class Object
trait Matchable
class Any

A module that can produce a kind of iterator (Cursor), which yields all pairs of overriding/overridden symbols that are visible in some baseclass, unless there's a parent class that already contains the same pairs.

A module that can produce a kind of iterator (Cursor), which yields all pairs of overriding/overridden symbols that are visible in some baseclass, unless there's a parent class that already contains the same pairs.

Adapted from the 2.9 version of OverridingPairs. The 2.10 version is IMO way too unwieldy to be maintained.

Attributes

Supertypes
class Object
trait Matchable
class Any
Self type

For all private parameter accessors

For all private parameter accessors

private val x: T = ...

If there is a chain of parameter accessors starting with x such that (1) The last parameter accessor in the chain is a field that's accessible from the current class, and (2) each preceding parameter is forwarded in the supercall of its class to a parameter that's also named x then change the accessor to

private def x$accessor: T = super.x'.asInstanceOf[T]

where x' is a reference to the final parameter in the chain. Property (1) is established by the @see forwardParamAccessors method in PostTyper.

The reason for renaming x to x$accessor is that private methods in the JVM cannot override public ones.

The aim of this transformation is to avoid redundant parameter accessor fields.

Attributes

Companion
object
Supertypes
class MiniPhase
class Phase
class Object
trait Matchable
class Any
Show all

Attributes

Companion
class
Supertypes
class Object
trait Matchable
class Any
Self type
class PatternMatcher extends MiniPhase

The pattern matching transform. After this phase, the only Match nodes remaining in the code are simple switches where every pattern is an integer or string constant

The pattern matching transform. After this phase, the only Match nodes remaining in the code are simple switches where every pattern is an integer or string constant

Attributes

Companion
object
Supertypes
class MiniPhase
class Phase
class Object
trait Matchable
class Any

Attributes

Companion
class
Supertypes
class Object
trait Matchable
class Any
Self type

Translates quoted terms and types to unpickleExprV2 or unpickleType method calls.

Translates quoted terms and types to unpickleExprV2 or unpickleType method calls.

Transforms top level quote

 '<a,b>{ ...
    val x1: U1 = ???
    val x2: U2 = ???
    ...
    {{{ 3 | x1 | holeContents0 | T0 
}}}
 // hole
    ...
{{{
 4 | x2 | holeContents1 | T1 
}}}
 // hole
    ...
{{{
 5 | x1, x2 | holeContents2 | T2 
}}}
 // hole
    ...
  }

to

   unpickleExprV2(
     pickled = [[ // PICKLED TASTY

Attributes

Companion
object
Supertypes
class Phase
class Object
trait Matchable
class Any
object PickleQuotes

Attributes

Companion
class
Supertypes
class Object
trait Matchable
class Any
Self type
object Pickler

Attributes

Companion
class
Supertypes
class Object
trait Matchable
class Any
Self type
Pickler.type
class Pickler extends Phase

This phase pickles trees

This phase pickles trees

Attributes

Companion
object
Supertypes
class Phase
class Object
trait Matchable
class Any

A phase that adds mirror support for anonymous mirrors created at inlining.

A phase that adds mirror support for anonymous mirrors created at inlining.

Attributes

Companion
object
Supertypes
class Phase
class Object
trait Matchable
class Any
Show all
Self type
object PostInlining

Attributes

Companion
class
Supertypes
class Object
trait Matchable
class Any
Self type
object PostTyper

Attributes

Companion
class
Supertypes
class Object
trait Matchable
class Any
Self type
PostTyper.type

A macro transform that runs immediately after typer and that performs the following functions:

A macro transform that runs immediately after typer and that performs the following functions:

(1) Add super accessors (@see SuperAccessors)

(2) Convert parameter fields that have the same name as a corresponding public parameter field in a superclass to a forwarder to the superclass field (corresponding = super class field is initialized with subclass field)

Attributes

See also

forwardParamAccessors. (3) Add synthetic members (@see SyntheticMembers) (4) Check that New nodes can be instantiated, and that annotations are valid (5) Convert all trees representing types to TypeTrees. (6) Check the bounds of AppliedTypeTrees (7) Insert .package for selections of package object members (8) Replaces self references by name with this (9) Adds SourceFile annotations to all top-level classes and objects (10) Adds Child annotations to all sealed classes (11) Minimizes call fields of Inlined nodes to just point to the toplevel class from which code was inlined. The reason for making this a macro transform is that some functions (in particular super and protected accessors and instantiation checks) are naturally top-down and don't lend themselves to the bottom-up approach of a mini phase. The other two functions (forwarding param accessors and synthetic methods) only apply to templates and fit mini-phase or subfunction of a macro phase equally well. But taken by themselves they do not warrant their own group of miniphases before pickling.

Companion
object
Supertypes
class Phase
class Object
trait Matchable
class Any
Show all
Self type
abstract class PreRecheck extends Phase, DenotTransformer

A base class for a phase that precedes a rechecker and that allows installing new types for local symbols.

A base class for a phase that precedes a rechecker and that allows installing new types for local symbols.

Attributes

Supertypes
class Phase
class Object
trait Matchable
class Any
Known subtypes
class Pre
class Pre

Add accessors for all protected accesses. An accessor is needed if according to the rules of the JVM a protected class member is not accessible from the point of access, but is accessible if the access is from an enclosing class. In this point a public access method is placed in that enclosing class.

Add accessors for all protected accesses. An accessor is needed if according to the rules of the JVM a protected class member is not accessible from the point of access, but is accessible if the access is from an enclosing class. In this point a public access method is placed in that enclosing class.

Attributes

Companion
class
Supertypes
class Object
trait Matchable
class Any
Self type

Attributes

Companion
object
Supertypes
class MiniPhase
class Phase
class Object
trait Matchable
class Any

This phase makes all erased term members of classes private so that they cannot conflict with non-erased members. This is needed so that subsequent phases like ResolveSuper that inspect class members work correctly. The phase also replaces all expressions that appear in an erased context by default values. This is necessary so that subsequent checking phases such as IsInstanceOfChecker don't give false negatives.

This phase makes all erased term members of classes private so that they cannot conflict with non-erased members. This is needed so that subsequent phases like ResolveSuper that inspect class members work correctly. The phase also replaces all expressions that appear in an erased context by default values. This is necessary so that subsequent checking phases such as IsInstanceOfChecker don't give false negatives.

Attributes

Companion
object
Supertypes
class MiniPhase
class Phase
class Object
trait Matchable
class Any
Show all
Self type

Attributes

Companion
class
Supertypes
class Object
trait Matchable
class Any
Self type
object PureStats

Attributes

Companion
class
Supertypes
class Object
trait Matchable
class Any
Self type
PureStats.type
class PureStats extends MiniPhase

Remove pure statements in blocks

Remove pure statements in blocks

Attributes

Companion
object
Supertypes
class MiniPhase
class Phase
class Object
trait Matchable
class Any
object Recheck

Attributes

Companion
class
Supertypes
class Object
trait Matchable
class Any
Self type
Recheck.type
abstract class Recheck extends Phase, SymTransformer

A base class that runs a simplified typer pass over an already re-typed program. The pass does not transform trees but returns instead the re-typed type of each tree as it is traversed. The Recheck phase must be directly preceded by a phase of type PreRecheck.

A base class that runs a simplified typer pass over an already re-typed program. The pass does not transform trees but returns instead the re-typed type of each tree as it is traversed. The Recheck phase must be directly preceded by a phase of type PreRecheck.

Attributes

Companion
object
Supertypes
class Phase
class Object
trait Matchable
class Any
Show all
Known subtypes
Self type

Helper methods to construct trees calling methods in Quotes.reflect based on the current quotes tree

Helper methods to construct trees calling methods in Quotes.reflect based on the current quotes tree

Attributes

Supertypes
class Object
trait Matchable
class Any

Attributes

Companion
object
Supertypes
class MiniPhase
class Phase
class Object
trait Matchable
class Any

Attributes

Companion
class
Supertypes
class Object
trait Matchable
class Any
Self type

This phase implements super accessors in classes that need them.

This phase implements super accessors in classes that need them.

For every trait M directly implemented by the class (see SymUtils.mixin), in reverse linearization order, add the following definitions to C:

For every superAccessor <mods> def super$f[Ts](ps1)...(psN): U in M:

 <mods> def super$f[Ts](ps1)...(psN): U = super[S].f[Ts](ps1)...(psN)

where S is the superclass of M in the linearization of C.

This is the first part of what was the mixin phase. It is complemented by Mixin, which runs after erasure.

Attributes

Companion
object
Supertypes
class MiniPhase
class Phase
class Object
trait Matchable
class Any
Show all
Self type
object ResolveSuper

Attributes

Companion
class
Supertypes
class Object
trait Matchable
class Any
Self type

The preceding lambda lift and flatten phases move symbols to different scopes and rename them. This miniphase cleans up afterwards and makes sure that all class scopes contain the symbols defined in them.

The preceding lambda lift and flatten phases move symbols to different scopes and rename them. This miniphase cleans up afterwards and makes sure that all class scopes contain the symbols defined in them.

Attributes

Companion
object
Supertypes
class MiniPhase
class Phase
class Object
trait Matchable
class Any
Show all
Self type
object RestoreScopes

Attributes

Companion
class
Supertypes
class Object
trait Matchable
class Any
Self type

Removes Selects that would be compiled into GetStatic.

Removes Selects that would be compiled into GetStatic.

Otherwise, the backend needs to be aware that some qualifiers need to be dropped.

A tranformation similar to what this phase does seems to be performed by flatten in nsc.

The side effects of the qualifier of a dropped Select is normally retained. As an exception, the qualifier is completely dropped if it is a reference to a static owner (see isStaticOwnerRef). Concretely, this means that in

object Foo {
  println("side effects")

  object Bar
  class Baz
}

Foo.Bar
new Foo.Baz()

the Foo qualifiers will be dropped, since it is a static object. The println("side effects") will therefore not be executed.

This intended behavior is equivalent to what scalac does.

Attributes

Authors:

Dmytro Petrashko

Companion
object
Supertypes
class MiniPhase
class Phase
class Object
trait Matchable
class Any
Show all
object SelectStatic

Attributes

Companion
class
Supertypes
class Object
trait Matchable
class Any
Self type
class SeqLiterals extends MiniPhase

A transformer that eliminates SeqLiteral's, transforming SeqLiteral(elems) to an operation equivalent to

A transformer that eliminates SeqLiteral's, transforming SeqLiteral(elems) to an operation equivalent to

JavaSeqLiteral(elems).toSeq

Instead of toSeq, which takes an implicit, the appropriate "wrapArray" method is called directly. The reason for this step is that JavaSeqLiterals, being arrays keep a precise type after erasure, whereas SeqLiterals only get the erased type Seq,

Attributes

Companion
object
Supertypes
class MiniPhase
class Phase
class Object
trait Matchable
class Any
object SeqLiterals

Attributes

Companion
class
Supertypes
class Object
trait Matchable
class Any
Self type
class SetRootTree extends Phase

Set the rootTreeOrProvider property of class symbols.

Set the rootTreeOrProvider property of class symbols.

Attributes

Companion
object
Supertypes
class Phase
class Object
trait Matchable
class Any
object SetRootTree

Attributes

Companion
class
Supertypes
class Object
trait Matchable
class Any
Self type

This phase synthesizes specialized methods for FunctionN, this is done since there are no scala signatures in the bytecode for the specialized methods.

This phase synthesizes specialized methods for FunctionN, this is done since there are no scala signatures in the bytecode for the specialized methods.

We know which specializations exist for the different arities, therefore we can hardcode them. This should, however be removed once we're using a different standard library.

Attributes

Companion
object
Supertypes
class MiniPhase
class Phase
class Object
trait Matchable
class Any
Show all

Attributes

Companion
class
Supertypes
class Object
trait Matchable
class Any
Self type

Specializes classes that inherit from FunctionN where there exists a specialized form.

Specializes classes that inherit from FunctionN where there exists a specialized form.

Attributes

Companion
object
Supertypes
class MiniPhase
class Phase
class Object
trait Matchable
class Any

Attributes

Companion
class
Supertypes
class Object
trait Matchable
class Any
Self type
class SpecializeTuples extends MiniPhase

Specializes Tuples by replacing tuple construction and selection trees.

Specializes Tuples by replacing tuple construction and selection trees.

Specifically:

  1. Replaces (1, 1) (which is Tuple2.apply[Int, Int](1, 1)) and new Tuple2[Int, Int](1, 1) with new Tuple2$mcII$sp(1, 1).
  2. Replaces (_: Tuple2[Int, Int])._1 with (_: Tuple2[Int, Int])._1$mcI$sp

Attributes

Companion
object
Supertypes
class MiniPhase
class Phase
class Object
trait Matchable
class Any

Attributes

Companion
class
Supertypes
class Object
trait Matchable
class Any
Self type
object Splicer

Utility class to splice quoted expressions

Utility class to splice quoted expressions

Attributes

Supertypes
class Object
trait Matchable
class Any
Self type
Splicer.type
object Splicing

Attributes

Companion
class
Supertypes
class Object
trait Matchable
class Any
Self type
Splicing.type
class Splicing extends MacroTransform

Transforms level 1 splices into holes. To do so it transforms the contents of the splice into a lambda that receives all cross-quote references.

Transforms level 1 splices into holes. To do so it transforms the contents of the splice into a lambda that receives all cross-quote references.

Cross-quote reference is a reference to a definition that is not defined in the current quote. Those references appear in quotes that are nested in a splice.

After this phase we have the invariant where all splices have the following shape

{{{ <holeIdx> | <holeType> | <captures>* | (<capturedTerms>*) => <spliceContent> 
}}}

where <spliceContent> does not contain any free references to quoted definitions and <captures>* contains the quotes with references to all cross-quote references. There are some special rules for references in the LHS of assignments and cross-quote method references.

In the following code example x1 and x2 are cross-quote references.

'{ ...
  val x1: T1 = ???
  val x2: T2 = ???
  ${ (q: Quotes) ?=> f('{ g(x1, x2) }) }: T3
}

This phase identifies cross-quote references such as x1 and replaces it with an ${x1$}. All cross-quote arguments are directly applied in the lambda.

'{ ...
   val x1: T1 = ???
   val x2: T2 = ???
{{{
 0 | T3 | x1, x2 |
     (x1$: Expr[T1], x2$: Expr[T2]) => // body of this lambda does not contain references to x1 or x2
       (q: Quotes) ?=> f('{ g(${x1$}, ${x2$}) })

}}}
 }

and then performs the same transformation on '{ g(${x1$}, ${x2$}) }.

Attributes

Companion
object
Supertypes
class Phase
class Object
trait Matchable
class Any
class Staging extends MacroTransform

Checks that staging level consistency holds and heals types used in higher levels.

Checks that staging level consistency holds and heals types used in higher levels.

See CrossStageSafety

Attributes

Companion
object
Supertypes
class Phase
class Object
trait Matchable
class Any
object Staging

Attributes

Companion
class
Supertypes
class Object
trait Matchable
class Any
Self type
Staging.type
class SuperAccessors(thisPhase: DenotTransformer)

This class adds super accessors for all super calls that either appear in a trait or have as a target a member of some outer class.

This class adds super accessors for all super calls that either appear in a trait or have as a target a member of some outer class.

It also checks that:

(1) Symbols accessed from super are not abstract, or are overridden by an abstract override.

(2) If a symbol accessed from super is defined in a real class (not a trait), there are no abstract members which override this member in Java's rules (see SI-4989; such an access would lead to illegal bytecode)

(3) Super calls do not go to some synthetic members of Any (see isDisallowed)

(4) Super calls do not go to synthetic field accessors

Attributes

Supertypes
class Object
trait Matchable
class Any
object SymUtils

Attributes

Supertypes
class Object
trait Matchable
class Any
Self type
SymUtils.type

Attributes

Companion
class
Supertypes
class Object
trait Matchable
class Any
Self type

Synthetic method implementations for case classes, case objects, and value classes.

Synthetic method implementations for case classes, case objects, and value classes.

Selectively added to case classes/objects, unless a non-default implementation already exists: def equals(other: Any): Boolean def hashCode(): Int def canEqual(other: Any): Boolean def toString(): String def productElement(i: Int): Any def productArity: Int def productPrefix: String

Add to serializable static objects, unless an implementation already exists: private def writeReplace(): AnyRef

Selectively added to value classes, unless a non-default implementation already exists: def equals(other: Any): Boolean def hashCode(): Int

Attributes

Companion
object
Supertypes
class Object
trait Matchable
class Any
class TailRec extends MiniPhase

A Tail Rec Transformer.

A Tail Rec Transformer.

What it does:

Finds method calls in tail-position and replaces them with jumps. A call is in a tail-position if it is the last instruction to be executed in the body of a method. This includes being in tail-position of a return from a Labeled block which is itself in tail-position (which is critical for tail-recursive calls in the cases of a match). To identify tail positions, we recurse over the trees that may contain calls in tail-position (trees that can't contain such calls are not transformed).

When a method contains at least one tail-recursive call, its rhs is wrapped in the following structure:

var localForParam1: T1 = param1
...
while (<empty>) {
  tailResult[ResultType]: {
    return {
      // original rhs with tail recursive calls transformed (see below)
    }
  }
}

Self-recursive calls in tail-position are then replaced by (a) reassigning the local vars substituting formal parameters and (b) a return from the tailResult labeled block, which has the net effect of looping back to the beginning of the method. If the receiver is modifed in a recursive call, an additional var is used to replace this.

As a complete example of the transformation, the classical fact function, defined as:

def fact(n: Int, acc: Int): Int =
  if (n == 0) acc
  else fact(n - 1, acc * n)

is rewritten as:

def fact(n: Int, acc: Int): Int = {
  var acc$tailLocal1: Int = acc
  var n$tailLocal1: Int = n
  while (<empty>) {
    tailLabel1[Unit]: {
      return {
        if (n$tailLocal1 == 0)
          acc$tailLocal1
        else {
          val n$tailLocal1$tmp1: Int = n$tailLocal1 - 1
          val acc$tailLocal1$tmp1: Int = acc$tailLocal1 * n$tailLocal1
          n$tailLocal1 = n$tailLocal1$tmp1
          acc$tailLocal1 = acc$tailLocal1$tmp1
          (return[tailLabel1] ()): Int
        }
      }
    }
  }
}

As the JVM provides no way to jump from a method to another one, non-recursive calls in tail-position are not optimized.

A method call is self-recursive if it calls the current method and the method is final (otherwise, it could be a call to an overridden method in a subclass). Recursive calls on a different instance are optimized.

This phase has been moved after erasure to allow the use of vars for the parameters combined with a WhileDo. This is also beneficial to support polymorphic tail-recursive calls.

In scalac, if the method had type parameters, the call must contain the same parameters as type arguments. This is no longer the case in dotc thanks to being located after erasure. In scalac, this is named tailCall but it does only provide optimization for self recursive functions, that's why it's renamed to tailrec

Attributes

Authors:

Erik Stenman, Iulian Dragos, ported and heavily modified for dotty by Dmitry Petrashko moved after erasure and adapted to emit Labeled blocks by Sébastien Doeraene

Companion
object
Supertypes
class MiniPhase
class Phase
class Object
trait Matchable
class Any
object TailRec

Attributes

Companion
class
Supertypes
class Object
trait Matchable
class Any
Self type
TailRec.type
object TestRecheck

A class that can be used to test basic rechecking without any customaization

A class that can be used to test basic rechecking without any customaization

Attributes

Companion
class
Supertypes
class Object
trait Matchable
class Any
Self type
class TestRecheck extends Recheck

Attributes

Companion
object
Supertypes
class Recheck
class Phase
class Object
trait Matchable
class Any
Show all

This phase transforms wildcards in valdefs with their default value. In particular for every valdef that is declared: val x : T = _ to val x : T = <zero of T>

This phase transforms wildcards in valdefs with their default value. In particular for every valdef that is declared: val x : T = _ to val x : T = <zero of T>

Attributes

Companion
object
Supertypes
class MiniPhase
class Phase
class Object
trait Matchable
class Any
Show all

Attributes

Companion
class
Supertypes
class Object
trait Matchable
class Any
Self type

Run by -Ycheck option after a given phase, this class retypes all syntax trees and verifies that the type of each tree node so obtained conforms to the type found in the tree node. It also performs the following checks:

Run by -Ycheck option after a given phase, this class retypes all syntax trees and verifies that the type of each tree node so obtained conforms to the type found in the tree node. It also performs the following checks:

  • The owner of each definition is the same as the owner of the current typing context.
  • Ident nodes do not refer to a denotation that would need a select to be accessible (see tpd.needsSelect).
  • After typer, identifiers and select nodes refer to terms only (all types should be represented as TypeTrees then).

Attributes

Companion
object
Supertypes
class Phase
class Object
trait Matchable
class Any
Show all
object TreeChecker

Attributes

Companion
class
Supertypes
class Object
trait Matchable
class Any
Self type

Attributes

Supertypes
class Object
trait Matchable
class Any
Self type
class TryCatchPatterns extends MiniPhase

Compiles the cases that can not be handled by primitive catch cases as a common pattern match.

Compiles the cases that can not be handled by primitive catch cases as a common pattern match.

The following code:

  try { <code> }
  catch {
    <tryCases> // Cases that can be handled by catch
    <patternMatchCases> // Cases starting with first one that can't be handled by catch
  }

will become:

  try { <code> }
  catch {
    <tryCases>
    case e => e match {
      <patternMatchCases>
    }
  }

Cases that are not supported include:

  • Applies and unapplies
  • Idents
  • Alternatives
  • case _: T => where T is not Throwable

Attributes

Companion
object
Supertypes
class MiniPhase
class Phase
class Object
trait Matchable
class Any

Attributes

Companion
class
Supertypes
class Object
trait Matchable
class Any
Self type

Optimize generic operations on tuples

Optimize generic operations on tuples

Attributes

Companion
object
Supertypes
class MiniPhase
class Phase
class Object
trait Matchable
class Any
Show all

Attributes

Companion
class
Supertypes
class Object
trait Matchable
class Any
Self type

This transform normalizes type tests and type casts, also replacing type tests with singleton argument type with reference equality check Any remaining type tests

This transform normalizes type tests and type casts, also replacing type tests with singleton argument type with reference equality check Any remaining type tests

  • use the object methods $isInstanceOf and $asInstanceOf
  • have a reference type as receiver
  • can be translated directly to machine instructions

Unfortunately this phase ended up being not Y-checkable unless types are erased. A cast to an ConstantType(3) or x.type cannot be rewritten before erasure. That's why TypeTestsCasts is called from Erasure.

Attributes

Supertypes
class Object
trait Matchable
class Any
Self type
object TypeUtils

Attributes

Supertypes
class Object
trait Matchable
class Any
Self type
TypeUtils.type

Attributes

Companion
class
Supertypes
class Object
trait Matchable
class Any
Self type

This phase optimizes alias givens represented as lazy vals to be uncached if that does not change runtime behavior. A definition does not need to be cached if its right hand side has a stable type and is of one of them forms

This phase optimizes alias givens represented as lazy vals to be uncached if that does not change runtime behavior. A definition does not need to be cached if its right hand side has a stable type and is of one of them forms

this this.y y

Attributes

Companion
object
Supertypes
class MiniPhase
class Phase
class Object
trait Matchable
class Any
Show all
Self type

This phase replaces compiletime.uninitialized on the right hand side of a mutable field definition by _. This avoids a

This phase replaces compiletime.uninitialized on the right hand side of a mutable field definition by _. This avoids a

"@compileTimeOnly("`uninitialized` can only be used as the right hand side of a mutable field definition")`

error in Erasure and communicates to Constructors that the variable does not have an initializer.

Attributes

Companion
object
Supertypes
class MiniPhase
class Phase
class Object
trait Matchable
class Any

Attributes

Companion
class
Supertypes
class Object
trait Matchable
class Any
Self type

This phase elides unnecessary value class allocations

This phase elides unnecessary value class allocations

For a value class V defined as: class V(val underlying: U) extends AnyVal we avoid unnecessary allocations: new V(u1) == new V(u2) => u1 == u2 provided V does not redefine equals (new V(u)).underlying() => u

Attributes

Companion
object
Supertypes
class MiniPhase
class Phase
class Object
trait Matchable
class Any
Show all

Attributes

Companion
class
Supertypes
class Object
trait Matchable
class Any
Self type

This phase inlines calls to methods of value classes.

This phase inlines calls to methods of value classes.

A value class V after ExtensionMethods will look like: class V[A, B, ...](val underlying: U) extends AnyVal { def foo[T, S, ...](arg1: A1, arg2: A2, ...) = V.foo$extensionT, S, ..., A, B, ...(arg1, arg2, ...)

 ...

}

Let e have type V, if e is a stable prefix or if V does not have any class type parameter, then we can rewrite: e.fooX, Y, ... as: V.foo$extensionX, Y, ..., A', B', ...(args) where A', B', ... are the class type parameters A, B, ... as seen from e. Otherwise, we need to evaluate e first: { val ev = e V.foo$extensionX, Y, ..., A', B', ...(args) }

This phase needs to be placed after phases which may introduce calls to value class methods (like PatternMatcher). This phase uses name mangling to find the correct extension method corresponding to a value class method (see ExtensionMethods.extensionMethod), therefore we choose to place it before phases which may perform their own name mangling on value class methods (like TypeSpecializer), this way VCInlineMethods does not need to have any knowledge of the name mangling done by other phases.

Attributes

Companion
object
Supertypes
class MiniPhase
class Phase
class Object
trait Matchable
class Any
Show all

Attributes

Companion
class
Supertypes
class Object
trait Matchable
class Any
Self type
object ValueClasses

Methods that apply to user-defined value classes

Methods that apply to user-defined value classes

Attributes

Supertypes
class Object
trait Matchable
class Any
Self type
class YCheckPositions extends Phase

Ycheck inlined positions

Ycheck inlined positions

Attributes

Companion
object
Supertypes
class Phase
class Object
trait Matchable
class Any

Attributes

Companion
class
Supertypes
class Object
trait Matchable
class Any
Self type