Skip to content

Match type forgets kindness of variable extending wildcarded trait #19904

Open
@s5bug

Description

@s5bug

Compiler version

3.4.0, 3.4.1-RC1

Minimized code

sealed trait Wrap[A <: AnyKind]

trait Foo[T <: AnyKind, X[_ <: T]]

trait Bar[T <: AnyKind, X[_ <: T]] {

  def foo: Foo[
    Wrap[? <: T],
    [x <: Wrap[? <: T]] =>> x match { case Wrap[a] => X[a] }
  ]

}

object Qux extends Bar[Any, [_] =>> Unit] {

  override def foo: Foo[
    Wrap[? <: Any],
    [x <: Wrap[? <: Any]] =>> x match { case Wrap[a] => Unit }
  ] = ???

}

Output

error overriding method foo in trait Bar of type =>
  Foo[Wrap[?],
    [x <: Wrap[?]] =>>
      x match {
        case Wrap[a] => Unit
      }
  ];
  method foo of type =>
  Foo[Wrap[?],
    [x <: Wrap[?]] =>>
      x match {
        case Wrap[a] => Unit
      }
  ] has incompatible type

Explanation
===========
I tried to show that
  =>
  Foo[Wrap[?],
    [x <: Wrap[?]] =>>
      x match {
        case Wrap[a] => Unit
      }
  ]
conforms to
  =>
  Foo[Wrap[?],
    [x <: Wrap[?]] =>>
      x match {
        case Wrap[a] => Unit
      }
  ]
but none of the attempts shown below succeeded:

  ==> =>   Foo[Wrap[?],     [x <: Wrap[?]] =>>       x match {         case Wrap[a] => Unit       }   ]  <:  =>   Foo[Wrap[?],     [x <: Wrap[?]] =>>       x match {         case Wrap[a] => Unit       }   ]
    ==> Foo[Wrap[?],   [x <: Wrap[?]] =>>     x match {       case Wrap[a] => Unit     } ]  <:  Foo[Wrap[?],   [x <: Wrap[?]] =>>     x match {       case Wrap[a] => Unit     } ]
      ==> [x <: Wrap[?]] =>>   x match {     case Wrap[a] => Unit   }  <:  [x <: Wrap[?]] =>>   x match {     case Wrap[a] => Unit   }
        ==> x match {   case Wrap[a] => Unit }  <:  x match {   case Wrap[a] => Unit }
          ==> Any  <:  x match {   case Wrap[a] => Unit }  = false
          ==> [a] =>> scala.runtime.MatchCase[Wrap[a], Unit]  <:  [a <: AnyKind] =>> scala.runtime.MatchCase[Wrap[a], Unit]
            ==> type bounds [ <: AnyKind]  <:  type bounds []
              ==> AnyKind  <:  Any  = false

The tests were made under the empty constraint

Expectation

This should compile. Notably, the 3rd and 4th lines in the trace show equivalent types (==> T <: T).

Replacing the the bound x <: Wrap[? <: T] with x <: (Wrap[? <: T] & Any) causes the code to compile, even though Wrap[? <: T] is always a subtype of Any (and so Wrap[? <: T] & Any should be equivalent to Wrap[? <: T]).

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions