this.type incorrectly compiled?

101 Views Asked by At

When porting my project from Scala 2.10 to 2.11 I got a sudden compilation error with type parametrization. I tried to modify and pinpoint; still something strange went wrong. Could someone explain? BTW I was happy with this regression (or progression), since it motivated me to simplify the code.

trait TNode {type N <:  Node {type T = this.type}}
trait  Node {type T <: TNode {type N = this.type}; def t: T}

trait TNodeCode[R] extends TNode {type N <:  NodeCode[R]; val code: ()=>N=>R}
trait  NodeCode[R] extends  Node {type T <: TNodeCode[R]}

object Test {
  def executeCode[R](n: Node, code: =>()=>R): R = {null.asInstanceOf[R]}

  def executeTCode[N <: NodeCode[R], R](n: N): R = {
    executeCode(n, ()=>n.t.code.apply.apply(n))
    // compile error:                       ^
    //   type mismatch; found: n.type (with underlying type N) required: _1.N where val _1: n.T
  }
}
1

There are 1 best solutions below

0
On

I have a hasty partial answer:

When you change the bound on T in NodeCode, you lose the information that the previous bound was a refinement with N tied to this.type.

The last bound wins.

This is the question I was thinking of.

This may not suit your needs:

trait TNode0 {type N <:  Node0 }
trait  Node0 {type T <: TNode0 ; def t: T}

trait TNode extends TNode0 {type N <:  Node {type T = this.type}}
trait  Node extends Node0  {type T <: TNode {type N = this.type}}

trait TNodeCode[R] extends TNode0 {type N <:  NodeCode[R] {type T = this.type}; val code: ()=>N=>R}
trait  NodeCode[R] extends  Node0 {type T <: TNodeCode[R] {type N = this.type}}

Edit: that doesn't seem to help, sorry. Something else is going on.