Type Mismatch with generic type parameter

Why does the following code fail to compile, and how can I make it compile without giving up any type safety?

Scastie (scala-lang.org)

Shouldn’t the compiler be able to prove that T is exactly Derived1/2 and can’t be anything else, since Base is a closed ADT.

The issue is that, even if T <: Base this does not mean that ValueBase[T] <: ValueBase[Base]. It has to be covariant.

First way (hacky):
I made this change to the return type:

private def foo[T <: Base](t: T): ValueBase[? <: Base]

Second way (better):
Change ValueBase[+T <: Base] to be covariant, then change the return type to ValueBase[Base]:

sealed trait ValueBase[+T <: Base]
private def foo[T <: Base](t: T): ValueBase[Base]

Third way: you can simplify further:

// now ValueBase[+T] is sufficient, <: Base not needed
private def foo(t: Base): ValueBase[Base]