I'm trying to compile the code below which looks correct, although the compiler refuses it. I'm probably doing something wrong or I need to hint the compiler somehow.
sealed trait Foo[A]
case class Bar[A, B <: A]() extends Foo[A]
class Visitor[A](foo: Foo[A]) {
def onBar[B <: A](bar: Bar[A, B]) = ???
def run = foo match
case b: Bar[A, b] => onBar[b](b)
}
The error is
Type argument b does not conform to upper bound A
This issue is currently being discussed at scala/scala3#20040, and the question's code's validity will be confirmed upon resolution of that report. For the present, there exists two workarounds:
Foo
and Bar
, you can write a fold
method to circumvent the need for a pattern match:sealed trait Foo[A] {
def fold[R](caseBar: [B <: A] => Bar[A, B] => R): R
}
case class Bar[A, B <: A]() extends Foo[A] {
override final def fold[R](caseBar: [B <: A] => Bar[A, B] => R) =
caseBar[B](this)
}
class Visitor[A](foo: Foo[A]) {
def onBar[B <: A](bar: Bar[A, B]) = ???
def run = foo.fold([B <: A] => (b: Bar[A, B]) => onBar[B](b))
}
match
layer that forces the compiler to remember B
is related to A
:sealed trait Foo[A]
case class Bar[A, B <: A]() extends Foo[A]
class Visitor[A](foo: Foo[A]) {
def onBar[B <: A](bar: Bar[A, B]) = ???
def run = foo match {
case bar1: Bar[A, ? <: A] =>
bar1 match {
case bar2: Bar[A, b] =>
onBar[b](bar2)
}
}
}