Skip to content

TailRec transformation of inner methods in parameterized classes is broken #321

@smarter

Description

@smarter

The following code:

class Parameterized[T] {
  def outer(outerParam: T): Unit = {
    def loop(loopParam: T): Unit =
    {
      loop(outerParam)
    }
    loop(outerParam)
  }
}

Is transformed after TailRec into:

class Parameterized[T]()  extends Object() { 
   Parameterized$$T
   private[this] type T = Parameterized$$T
   def outer(val outerParam: Parameterized$$T): Unit = {
     def loop(val loopParam: Parameterized$$T): Unit = {
       def tailLabel1[type T](val $this: Parameterized[T])(val loopParam: T): 
         Unit
        = {
         tailLabel1[T]($this)(outerParam)
       }
       tailLabel1[Parameterized$$T](Parameterized.this)(loopParam)
     }
     loop(outerParam)
   }
 }
 val Parameterized: Parameterized$ = new Parameterized$()
}

This should not typecheck because outerParam in tailLabel1 has the type Parameterized$$T which is different from the type parameter T of tailLabel1. -Ycheck does not detect this problem because of a bug in the subtyping checks fixed in smarter@f9512c6 . The problem is that FullParameterization does not handle inner methods correctly.
@DarkDimius, @odersky: why is it necessary to make the labels created by TailRec fully parameterized?

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