def foo[T](x: T): T = x
foo(1) // How is this typed?
1. Typing foo creates a type variable T?
foo[T?]
2. Typing foo[T?](1) adds a constraint to T?
foo[T?](1) // T? >: Int
3. Instantiating T? = Int respects the constraints
foo[Int](1)
def foo[T](…): RetType = …
foo[T?](…) // T? >: Lo <: Hi
.bar(…)
T? right after typing foo[T?](…) ?T appears in RetTypeT appears |
Safe? | T? = |
| nowhere | Yes | Lo (arbitrarily) |
| covariantly | Yes | Lo |
| contravariantly | Yes | Hi |
| co- and contravariantly or invariantly |
No | ¯\_(ツ)_/¯ |