Skip to content

No tailrec optimization for certain patterns #7800

@scabug

Description

@scabug

This code can't be optimized:

@annotation.tailrec
  private def foo(x: Int): Unit = try {
    bar()
  } catch {
    case _: Throwable if x < 0 => foo(x + 1)
    case _: Throwable => ()
  }

but if you s/Throwable/Exception, it will work:

@annotation.tailrec
  private def foo(x: Int): Unit = try {
    bar()
  } catch {
    case _: Exception if x < 0 => foo(x + 1)
    case _: Exception => ()
  }

It turns out that the pattern match is translated differently in the two cases. The first one looks like:

case (ex9 @ _) => {
        <synthetic> val x6: Throwable = ex9;
        case12(){
          if (x6.ne(null))
            if (x.<(0))
              matchEnd11(PreSuper.this.foo(x.+(1)))
            else
              case13()
          else
            case13()
        };
        case13(){
          if (x6.ne(null))
            matchEnd11(())
          else
            case14()
        };
        case14(){
          matchEnd11(throw ex9)
        };
        matchEnd11(x: Unit){
          x
        }
      }

The second one is:

 catch {
      case (x27 @ (_: Exception)) => if (x.<(0))
        PreSuper.this.foo(x.+(1))
      else
        ()
      case (x6 @ (_: Throwable)) => throw x6
    }

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions