Details

    • Type: Bug
    • Status: Open
    • Priority: Critical
    • Resolution: Unresolved
    • Affects Version/s: Scala 2.11.1
    • Fix Version/s: None
    • Component/s: Compiler (Misc)
    • Labels:

      Description

      The phase assembly, which is responsible for ensuring correct execution order of internal as well as user-defined compiler components, is severely broken.

      How to reproduce

      I have written a small compiler plugin which can be configured to instantiate an arbitrary number of noop components with user-defined phase constraints. For installing it locally, perform

      $ git clone git@github.com:misberner/dummyphase.git
      $ cd dummyphase
      $ sbt publishLocal
      

      The syntax for defining phases is: phase1(after;rightAfter;before)|phase2(after;rightAfter;before)|....
      Here, after and before are comma-separated lists of phase names. The phase definition is specified as the property dummyphase.phases. Example invocations can be found below (note that the "parser" is extremely fragile).

      If components specify no constraints, they are ignored

      Every phase should run after "parser" and before "terminal". However, if a component specifies empty lists for both runsAfter and runsBefore, it is ignored entirely.

      To make matters worse, a component is considered if it declares that it runs after parser, but not if it declares to run before terminal.

      # A phase without any constraints, ignored
      $ scalac -Xplugin ~/.ivy2/local/dummyphase/dummyphase_2.11/0.1-SNAPSHOT/jars/dummyphase_2.11.jar \
        -Ddummyphase.phases='phase(;;)' -Xshow-phases
      # A phase that specifies it runs after the parser phase, shows up
      $ scalac -Xplugin ~/.ivy2/local/dummyphase/dummyphase_2.11/0.1-SNAPSHOT/jars/dummyphase_2.11.jar \
        -Ddummyphase.phases='phase(parser;;)' -Xshow-phases
      # A phase that specifies it runs before the terminal phase, ignored
      $ scalac -Xplugin ~/.ivy2/local/dummyphase/dummyphase_2.11/0.1-SNAPSHOT/jars/dummyphase_2.11.jar \
        -Ddummyphase.phases='phase(;;terminal)' -Xshow-phases
      

      If components specify runsRightAfter, all other constraints are ignored

      This leads to wrong phase orders without any kind of warning.

      # phase1 needs to run after delambdafy, phase2 needs to run *right after* phase1 and before icode.
      # Since icode does not need to run *right* after delambdafy, a valid order would be:
      # delambdafy, phase1, phase2, icode
      $ scalac -Xplugin ~/.ivy2/local/dummyphase/dummyphase_2.11/0.1-SNAPSHOT/jars/dummyphase_2.11.jar \
        -Ddummyphase.phases='phase1(delambdafy;;)|phase2(;phase1;icode)' \
        -Xshow-phases
      ...
          delambdafy  22  remove lambdas
               icode  23  generate portable intermediate code
              phase1  24
              phase2  25
      ...
      

      Solvable constraint systems are rejected

      The current phase assembly fails if a phase that defines a rightAfter dependency has another outgoing edge. Due to the above, this cannot be shown by specifying an after and a rightAfter dependency, but a rightAfter in combination with a before exposes this.

      $ scalac -Xplugin ~/.ivy2/local/dummyphase/dummyphase_2.11/0.1-SNAPSHOT/jars/dummyphase_2.11.jar \
        -Ddummyphase.phases='phase1(;patmat;)|phase2(parser;;phase1)' \
        -Xshow-phases
      error: scala.reflect.internal.FatalError: Phase phase1 can't follow patmat, created phase-order.dot
      

      As can be seen in the attached phase-order.png, the constraint system is satisfiable.

      The implementation has bugs

      The implementation modifies variable members of case classes (that are used for hashCode calculation), without removing them from containing HashSet s. This leads to erroneous phase graphs. See attached file phase-4.png, where the posterasure node is still present even though it was collapsed into another node.

      Note that no user-defined phases are necessary to expose this behavior.

      $ scalac -Xshow-phases -Xgenerate-phase-graph phase
      $ dot -Tpng phase-4.dot >phase-4.png
      

        Attachments

          Activity

            People

            • Assignee:
              Unassigned
              Reporter:
              misberner Malte Isberner
            • Votes:
              0 Vote for this issue
              Watchers:
              2 Start watching this issue

              Dates

              • Created:
                Updated: