Skip to content

Overzealous pattern elimination for try expressions. #746

Closed
@odersky

Description

@odersky

Trying to fix NonLocalReturns I tried to compile this:

object Test {

  def f(x: Int) = try {
    ???
  }
  catch {
    case ex: scala.runtime.NonLocalReturnControl[T @scala.unchecked] =>
      ???
  }
}

and got this output:

result of test.scala after TreeTransform:{patternMatcher, explicitOuter, splitter}:
package <empty> {
  final lazy module val Test: Test$ = new Test$()
  final module class Test$() extends Object() { this: Test.type => 
    def f(x: Int): Nothing = 
      try {
        ???
      } catch {
        case ex1 @ _ => 
          case val selector11: Throwable = ex1
          {
            def case11(): Nothing = {
              def case21(): Nothing = {
                def matchFail11(): Nothing = throw new MatchError(selector11)
                {
                  throw ex1
                }
              }
              if 
                selector11.isInstanceOf[
                  runtime.NonLocalReturnControl[T @unchecked]
                ]
               then {
                val ex: runtime.NonLocalReturnControl[T @unchecked] = 
                  selector11.asInstanceOf[
                    runtime.NonLocalReturnControl[T @unchecked](ex)
                  ]
                {
                  {
                    ???
                  }
                }
              } else case21()
            }
            case11()
          }
      }
  }
}

Needless to say, this makes every try very expensive. We need to back off here and keep typed patterns until the backend can convert them into proper exception handlers.

This currently blocks the implementation of non local returns because I do not know what code should be generated; i.e. what the precise code of the given example is after pattern matching.

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions