Skip to content

Regression from Scala 2: Type variable in pattern match works with invariant type, fails with covariant #14739

Closed
@SethTisue

Description

@SethTisue

Scala 2.13.8 accepts both of these:

scala> def foo[T](xs: Set[T]): T = xs match { case xs: Set[u] => xs.head: u }
def foo[T](xs: Set[T]): T

scala> def foo[T](xs: List[T]): T = xs match { case xs: List[u] => xs.head: u }
def foo[T](xs: List[T]): T

Scala 3 accepts the Set one, but fails on the List version. with -explain for verbosity,

scala> def foo[T](xs: List[T]): T = xs match { case xs: List[u] => xs.head: u }
-- [E007] Type Mismatch Error: -------------------------------------------------
1 |def foo[T](xs: List[T]): T = xs match { case xs: List[u] => xs.head: u }
  |                                                            ^^^^^^^^^^
  |                                                            Found:    u
  |                                                            Required: T
  |-----------------------------------------------------------------------------
  | Explanation (enabled by `-explain`)
  |- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  |
  | Tree: xs.head:u
  | I tried to show that
  |   u
  | conforms to
  |   T
  | but the comparison trace ended with `false`:
  |
  |   ==> u  <:  T
  |     ==> u  <:  Nothing in frozen constraint
  |       ==> Any  <:  Nothing (left is approximated) in frozen constraint
  |       <== Any  <:  Nothing (left is approximated) in frozen constraint = false
  |       ==> Any  <:  Nothing in frozen constraint
  |       <== Any  <:  Nothing in frozen constraint = false
  |     <== u  <:  Nothing in frozen constraint = false
  |     ==> Any  <:  T (left is approximated)
  |       ==> Any  <:  Nothing in frozen constraint
  |       <== Any  <:  Nothing in frozen constraint = false
  |     <== Any  <:  T (left is approximated) = false
  |     ==> Any  <:  T in frozen constraint
  |       ==> Any  <:  Nothing in frozen constraint
  |       <== Any  <:  Nothing in frozen constraint = false
  |     <== Any  <:  T in frozen constraint = false
  |   <== u  <:  T = false
  |
  | The tests were made under the empty constraint
   -----------------------------------------------------------------------------

I assume that the difference between Set and List here is that Set is invariant, List covariant.

(fyi @dwijnand; this came up during one of our pairing sessions)

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions