Consider the difference in inference of type argument A to type constructors in the following two type parameter clauses
$ scala3-repl
scala> def f[F <: List[A], A](as: F) = as
def f[F <: List[A], A](as: F): F
scala> f(List(42))
val res0: List[Int] = List(42)
scala> def f[F[_] <: List[A], A](as: F[A]) = as
def f[F[_$1] <: List[A], A](as: F[A]): F[A]
scala> f(List(42))
val res1: List[Any] = List(42)
Why is type argument A to type constructor F inferred as Any in second case?
Not a full-fledged answer, just some food for thought: I've attempted to construct a counter-example, but couldn't quite come up with anything that would actually result in unsoundness under the assumption that
Awould be inferred as the narrowest type. Still, maybe you find it interesting.Here is a function
hwith similar constraints, but instead ofList, we take slightly different type constructors.The main idea is that
Cchas two separate type parameters:_inF[_]Ain the<: Lst[A]-constraintNote that this would not compile if the
Awas inferred to be the narrowest type (Nothing):Had
Abeen inferred as the narrowest possible type satisfying the constraint of<: Lst[A], thenAwould beNothing, and the argument would have to be of typeT[Nothing] = Cc[Nothing, Nothing], which is uninhabited.I think it's interesting, but I don't see why it would actually be bad if it didn't compile.