scalatypesselftype-systems

Why did the Scala compiler get more strict regarding self types in 2.10?


I have the following code:

  trait TFn1B {
    type In
    type Out
    type Apply[T <: In] <: Out
  }

  trait TFn1[I, O] extends TFn1B {
    type In = I
    type Out = O
  }

  trait >>[F1 <: TFn1[_, _], F2 <: TFn1[_, _]] extends TFn1[F1#In, F2#Out] {
    type Apply[T] = F2#Apply[F1#Apply[T]]
  }

It compiles on Scala 2.9.1 without a warning or an error.

But on the current 2.10 build, I get the following error message:

Fun.scala:12: error: illegal inheritance;
 self-type this.>>[F1,F2] does not conform to this.TFn1[_$1,_$4]'s selftype this.TFn1[_$1,_$4]
  trait >>[F1 <: TFn1[_, _], F2 <: TFn1[_, _]] extends TFn1[F1#In, F2#Out] {
                                                       ^
one error found

Is this a regression or is the code unsound and the compiler just started to catch it lately? If the code is wrong, what would be a work-around to make it work again?


Solution

  • It looks like a bug to me. There's no constraints on the type parameters of the super classes, but, more to the point, the trace for -explaintypes looks suspicious to me:

    scala>   trait >>[F1 <: TFn1[_, _], F2 <: TFn1[_, _]] extends TFn1[F1#In, F2#Out] {
         |     type Apply[T] = F2#Apply[F1#Apply[T]]
         |   }
    <console>:9: error: illegal inheritance;
     self-type >>[F1,F2] does not conform to TFn1[_$1,_$4]'s selftype TFn1[_$1,_$4]
             trait >>[F1 <: TFn1[_, _], F2 <: TFn1[_, _]] extends TFn1[F1#In, F2#Out] {
                                                                  ^
    >>[F1,F2] <: TFn1[_$1,_$4]?
      TFn1[_$1,_$4] <: TFn1[_$1,_$4]?
        _$1 <: _$1?
          _$1 <: Nothing?
            <notype> <: Nothing?
            false
            Any <: Nothing?
              <notype> <: Nothing?
              false
            false
          false
          Any <: _$1?
            Any <: Nothing?
              <notype> <: Nothing?
              false
            false
          false
        false
      false
    false
    

    Specifically, I don't understand how or why it cannot prove that TFn1[_$1,_$4] <: TFn1[_$1,_$4] or even _$1 <: _$1.