package dotty.tools.dotc.transform

Constructors

Members

[+] class ArrayConstructors

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

It assummes that generic arrays have already been ha...

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

This phase augments Scala2 traits with implementation classes and with additional members needed for mixin composition. These symbols would have been ad...

    This phase augments Scala2 traits with implementation classes and with additional members needed for mixin composition. These symbols would have been added between Unpickling and Mixin in the Scala2 pipeline. Specifcally, it adds

    • an implementation class which defines a trait constructor and trait method implementations
    • trait setters for vals defined in traits

    Furthermore, it expands the names of all private getters and setters as well as super accessors in the trait and makes them not-private.

    [+] class CapturedVars
    [+] class CheckReentrant

    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 variable...

    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

    [+] class CheckStatic

    A transformer that check that requirements of Static fields\methods are implemented: 1. Only objects can have members annotated with @static 2. The fiel...

    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 preceed 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.

    [+] class ClassOf

    Rewrite classOf calls as follow:

    For every primitive class C whose boxed class is called B: classOf[C] -> B.TYPE For every non-primitive class D: classOf[D]

    Rewrite classOf calls as follow:

    For every primitive class C whose boxed class is called B: classOf[C] -> B.TYPE For every non-primitive class D: classOf[D] -> Literal(Constant(erasure(D)))

    [+] class CollectEntryPoints
    [+] class Constructors

    This transform - moves initializers from body to constructor. - makes all supercalls explicit - also moves private fields that are accessed only from con...

    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.

    [+] class CrossCastAnd

    This transform makes sure that all private member selections from AndTypes are performed from the first component of AndType. This is needed for correct...

    This transform makes sure that all private member selections from AndTypes are performed from the first component of AndType. This is needed for correctness of erasure. See tests/run/PrivateAnd.scala

    [+] class CtxLazy

    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 co...

    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.

    [+] class DropInlined

    Drop Inlined nodes

    Drop Inlined nodes

    [+] class ElimByName

    This phase eliminates ExprTypes => T as types of function parameters, and replaces them by nullary function types. More precisely:

    For the types of par...

    => T        ==>    () => T
    

    x           ==>    x.apply()   if x is a parameter that had type => T
    

    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
    

    [T]

    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.

    This phase erases ErasedValueType to their underlying type. It also removes the synthetic cast methods u2evt$ and evt2u$ which are no longer needed afte...

    This phase erases ErasedValueType to their underlying type. It also removes the synthetic cast methods u2evt$ and evt2u$ which are no longer needed afterwards.

    [+] class ElimRepeated

    A transformer that removes repeated parameters (T*) from all types, replacing them with Seq types.

    A transformer that removes repeated parameters (T*) from all types, replacing them with Seq types.

    [+] class ElimStaticThis

    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.

    [+] class Erasure
    [+] final object Erasure
    [+] class ExpandPrivate

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

    Make private accessor...

    https://github.com/lampepfl/dotty/pull/784 https://github.com/lampepfl/dotty/issues/783

    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. Ihis 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

    [+] class ExpandSAMs

    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 a isDefinedAt method 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.

    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 a isDefinedAt method 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.
    [+] class ExplicitOuter

    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 acc...

      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

      [+] final object ExplicitOuter
      [+] class ExplicitSelf

      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.asInstanceOfS & C...

      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.

      [+] class ExtensionMethods

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

      [Erasure] [ElimErasedValueType]

      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.

      [+] final object ExtensionMethods
      [+] class FirstTransform

      The first tree transform - ensures there are companion objects for all classes except module classes - eliminates some kinds of trees: Imports, NamedArg...

      The first tree transform - ensures there are companion objects for all classes except module classes - eliminates some kinds of trees: Imports, NamedArgs - stubs out native methods - eliminates self tree in Template and self symbol in ClassInfo - collapsess all type trees to trees of class TypeTree - converts idempotent expressions with constant types

      [+] class Flatten

      Lift nested classes to toplevel

      Lift nested classes to toplevel

      [+] final object FullParameterization

      Provides methods to produce fully parameterized versions of instance methods, where the this of the enclosing class is abstracted out in an extra leadi...

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

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

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

        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 = ...
        

        Rewires closures to implement more specific types of Functions.

        Rewires closures to implement more specific types of Functions.

        [+] class GetClass

        Rewrite getClass calls as follow:

        For every instance of primitive class C whose boxed class is called B: instanceC.getClass -> B.TYPE For every instan...

        Rewrite getClass calls as follow:

        For every instance of primitive class C whose boxed class is called B: instanceC.getClass -> B.TYPE For every instance of non-primitive class D: instanceD.getClass -> instanceD.getClass

        [+] class Getters

        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

        laz...

          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

          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

          Furthermore, assignments to mutable vars are replaced by setter calls

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

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

          [+] class InterceptedMethods

          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
          • x.getClass for getClass in primitives becomes x.getClass with getClass in class Object.

          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
          • x.getClass for getClass in primitives becomes x.getClass with getClass in class Object.

          Implements partial evaluation of sc.isInstanceOf[Sel] according to:

          Sel\sctraitclassfinal class

            Implements partial evaluation of sc.isInstanceOf[Sel] according to:

            Sel\sctraitclassfinal class
            trait??statically known
            class?false if classes unrelatedstatically known
            final classfalse if classes unrelatedfalse if classes unrelatedstatically known

            This is a generalized solution to raising an error on unreachable match cases and warnings on other statically known results of isInstanceOf.

            Steps taken:

            1. evalTypeApply will establish the matrix and choose the appropriate handling for the case:
              • Sel/sc is a value class or scrutinee is Any
              • handleStaticallyKnown
              • falseIfUnrelated with scrutinee <:< selector
              • handleFalseUnrelated
              • leave as is (happens)
            2. Rewrite according to steps taken in 1
            [+] class LambdaLift

            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...

            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 }

            [+] final object LambdaLift
            [+] class LazyVals
            [+] final object LazyVals
            [+] class LiftTry

            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() }
            

            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() }
            

            Rewrite calls

            super[M].f(args)

            where M is a Scala2 trait implemented by the current class to

            M$class.f(this, args)

            provided the implementation class M$class...

            Rewrite calls

            super[M].f(args)

            where M is a Scala2 trait implemented by the current class to

            M$class.f(this, args)

            provided the implementation class M$class defines a corresponding function f.

            [+] abstract class MacroTransform

            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.

            [+] class Memoize

            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 var x: T = e def x(): T = x

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

            [+] class Mixin

            This phase performs the following transformations:

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

              def x(): T = expr

            to the pair of definitions:

             <mods> def x(): T
             protected def initial$x(): T = { stats; expr }
            

            where stats comprises all statements between either the start of the tr...

              <mods> def x_=(y: T)
              

                This phase performs the following transformations:

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

                  def x(): T = expr

                to the pair of definitions:

                 <mods> def x(): T
                 protected def initial$x(): T = { stats; expr }
                

                where stats comprises all statements between either the start of the trait or the previous field definition which are not definitions (i.e. are executed for their side effects).

                1. (done in traitDefs) Make every concrete trait setter

                  def x_=(y: T) = ()

                deferred by mapping it to

                <mods> def x_=(y: T)
                
                1. 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:

                  3.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.
                  
                  3.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:
                  
                      3.2.1 If `x` is also a member of `C`, and M is a Dotty trait:
                  
                        <mods> def x(): T = super[M].initial$x()
                  
                      3.2.2 If `x` is also a member of `C`, and M is a Scala 2.x trait:
                  
                        <mods> def x(): T = _
                  
                      3.2.3 If `x` is not a member of `C`, and M is a Dotty trait:
                  
                        super[M].initial$x()
                  
                      3.2.4 If `x` is not a member of `C`, and M is a Scala2.x trait, nothing gets added.
                  
                  
                  3.3 (done in `superCallOpt`) The call:
                  
                        super[M].<init>
                  
                  3.4 (done in `setters`) For every concrete setter `<mods> def x_=(y: T)` in M:
                  
                        <mods> def x_=(y: T) = ()
                  
                2. (done in transformTemplate and transformSym) Drop all parameters from trait constructors.

                3. (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.

                [+] class MixinOps
                [+] class MoveStatics

                Move static methods from companion to the class itself

                Move static methods from companion to the class itself

                [+] class NonLocalReturns

                Implement non-local returns using NonLocalReturnControl exceptions.

                Implement non-local returns using NonLocalReturnControl exceptions.

                [+] final object NonLocalReturns
                [+] class NormalizeFlags
                1. Widens all private[this] and protected[this] qualifiers to just private/protected
                2. Sets PureInterface flag for traits that only have pure interface members and that do not have initialization code. A pure interface member is either an abstract or alias type definition or a deferred val or def.
                1. Widens all private[this] and protected[this] qualifiers to just private/protected
                2. Sets PureInterface flag for traits that only have pure interface members and that do not have initialization code. A pure interface member is either an abstract or alias type definition or a deferred val or def.
                [+] final object OverridingPairs

                A module that can produce a kind of iterator (Cursor), which yields all pairs of overriding/overridden symbols that are visible in some baseclass, unles...

                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.

                [+] class ParamForwarding

                For all parameter accessors

                val x: T = ...
                

                if (1) x is forwarded in the supercall to a parameter that's also named x (2) the superclass parameter accessor for x is acce...

                def x: T = super.x.asInstanceOf[T]
                

                For all parameter accessors

                val x: T = ...
                

                if (1) x is forwarded in the supercall to a parameter that's also named x (2) the superclass parameter accessor for x is accessible from the current class change the accessor to

                def x: T = super.x.asInstanceOf[T]
                

                Do the same also if there are intermediate inaccessible parameter accessor forwarders. The aim of this transformation is to avoid redundant parameter accessor fields.

                [+] class PatternMatcher

                This transform eliminates patterns. Right now it's a dummy. Awaiting the real pattern matcher. elimRepeated is required TODO: outer tests are not generat...

                This transform eliminates patterns. Right now it's a dummy. Awaiting the real pattern matcher. elimRepeated is required TODO: outer tests are not generated yet.

                [+] class Pickler

                This phase pickles trees

                This phase pickles trees

                [+] class PostTyper

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

                (1) Add super accessors and protected accessors (@see Su...

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

                (1) Add super accessors and protected 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) (@see ForwardParamAccessors)

                (3) Add synthetic methods (@see SyntheticMethods)

                (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 Inline 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.

                This phase adds forwarder where mixedin generic and primitive typed methods have a missmatch. In particular for every method that is declared both as g...

                [N]

                This phase adds forwarder where mixedin generic and primitive typed methods have a missmatch. In particular for every method that is declared both as generic with a primitive type and with a primitive type <mods> def f[Ts](ps1)...(psN): U in trait Mand def fTs...(psN): V = ...in implemented in N where U is a primitive and V a polymorphic type (or vice versa) needs:

                def fTs...(psN): U = super[N].fTs...(psN)

                IMPORTANT: When\If Valhalla happens, we'll need to move mixin before erasure and than this code will need to be rewritten as it will instead change super-class.

                [+] class ResolveSuper

                This phase adds super accessors and method overrides where linearization differs from Java's rule for default methods in interfaces. In particular:

                  For every trait M directly implemented by the class (see SymUtils.mixin), in
                  reverse linearization order, add the following definitions to C:
                
                    3.1 (done in `superAccessors`) 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`.
                
                    3.2 (done in `methodOverrides`) For every method
                        `<mods> def f[Ts](ps1)...(psN): U` in 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.
                

                This...

                This phase adds super accessors and method overrides where linearization differs from Java's rule for default methods in interfaces. In particular:

                  For every trait M directly implemented by the class (see SymUtils.mixin), in
                  reverse linearization order, add the following definitions to C:
                
                    3.1 (done in `superAccessors`) 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`.
                
                    3.2 (done in `methodOverrides`) For every method
                        `<mods> def f[Ts](ps1)...(psN): U` in 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.
                

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

                [+] final object ResolveSuper
                [+] class RestoreScopes

                The preceding lambda lift and flatten phases move symbols to different scopes and rename them. This miniphase cleans up afterwards and makes sure that...

                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.

                [+] class SelectStatic

                Removes selects that would be compiled into GetStatic otherwise backend needs to be aware that some qualifiers need to be dropped. Similar transformatio...

                Removes selects that would be compiled into GetStatic otherwise backend needs to be aware that some qualifiers need to be dropped. Similar transformation seems to be performed by flatten in nsc

                [+] class SeqLiterals

                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...

                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,

                [+] class ShortcutImplicits

                This phase optimizes code using implicit function types, by applying two rewrite rules. Let IF be the implicit function type

                implicit Us => R
                

                (1) A method definition

                def m(xs: Ts): IF = implicit (ys: Us) => E
                

                is e...

                def m(xs: Ts): IF = implicit (ys: Us) => m$direct(xs)(ys)
                def m$direct(xs: Ts)(ys: Us): R = E
                

                This phase optimizes code using implicit function types, by applying two rewrite rules. Let IF be the implicit function type

                implicit Us => R
                

                (1) A method definition

                def m(xs: Ts): IF = implicit (ys: Us) => E
                

                is expanded to two methods:

                def m(xs: Ts): IF = implicit (ys: Us) => m$direct(xs)(ys)
                def m$direct(xs: Ts)(ys: Us): R = E
                

                (and equivalently for methods with type parameters or a different number of value parameter lists). An abstract method definition

                def m(xs: Ts): IF

                is expanded to:

                def m(xs: Ts): IF def m$direct(xs: Ts)(ys: Us): R

                (2) A reference qual.apply where qual has implicit function type and qual refers to a method m is rewritten to a reference to m$direct, keeping the same type and value arguments as they are found in qual.

                [+] class Splitter

                Distribute applications into Block and If nodes

                Distribute applications into Block and If nodes

                [+] class SuperAccessors

                This class performs the following functions:

                (1) Adds super accessors for all super calls that either appear in a trait or have as a target a member of...

                This class performs the following functions:

                (1) Adds super accessors for all super calls that either appear in a trait or have as a target a member of some outer class.

                (2) Adds protected accessors if the access to the protected member happens in a class which is not a subclass of the member's owner.

                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

                [+] final class SymUtils

                A decorator that provides methods on symbols that are needed in the transformer pipeline.

                A decorator that provides methods on symbols that are needed in the transformer pipeline.

                [+] final object SymUtils
                [+] class SymbolOrdering
                [+] class SyntheticMethods

                Synthetic method implementations for case classes, case objects, and value classes. Selectively added to case classes/objects, unless a non-default imple...

                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 productArity: Int def productPrefix: String Special handling: protected def readResolve(): AnyRef

                Selectively added to value classes, unless a non-default implementation already exists:

                def equals(other: Any): Boolean def hashCode(): Int

                [+] class TailRec

                A Tail Rec Transformer

                A Tail Rec Transformer

                [+] final object TailRec
                [+] class TreeChecker

                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...

                  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).
                  [+] final object TreeExtractors
                  [+] final object TreeGen
                  [+] final object TreeTransforms
                  [+] class TryCatchPatterns

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

                  The following code:

                  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

                  [+] trait TypeTestsCasts

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

                  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.

                  [+] final class TypeUtils

                  A decorator that provides methods on types that are needed in the transformer pipeline.

                  A decorator that provides methods on types that are needed in the transformer pipeline.

                  [+] final object TypeUtils
                  [+] class VCElideAllocations

                  This phase elides unnecessary value class allocations

                  For a value class V defined as: class V(val underlying: U) extends AnyVal we avoid unnecessary allo...

                  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 (new V(u)).underlying() => u

                  [+] class VCInlineMethods

                  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) exten... [T, S, ...]

                   ...
                  

                  [PatternMatcher] [ExtensionMethods.extensionMethod] [TypeSpecializer][VCInlineMethods]

                  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, ..., e.A, e.B, ...(args) Otherwise, we need to evaluate e first: { val ev = e V.foo$extensionX, Y, ..., ev.A, ev.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.

                  [+] final object ValueClasses

                  Methods that apply to user-defined value classes

                  Methods that apply to user-defined value classes