Skip to content

Recursive match type used as a bound diverges, OK as type constraint #5535

Open
@milessabin

Description

@milessabin

In the following example, call sites using p1 (which uses the match type as a bound) diverge, whereas call sites using p2 (which uses the match type as a constraint) compile successfully.

object Test {
  // The identity on types of the form N | P[a, P[b, ... P[z, N]]]
  type Nested[X, P[_, _], N] = X match {
    case N => N
    case P[a, b] => P[a, Nested[b, P, N]]
  }

  // Type bound:
  //   Recursion limit exceeded.
  //   Maybe there is an illegal cyclic reference?
  def p1[T <: Nested[T, Tuple2, Unit]](t: T): T = t
  p1(())
  p1((23, ()))
  p1(("foo", (23, ())))

  // Type constraint: OK
  def p2[T](t: T)(erased implicit ev: T <:< Nested[T, Tuple2, Unit]): T = t
  p2(())
  p2((23, ()))
  p2(("foo", (23, ())))
}

It's not immediately obvious to me why the two cases should differ.

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions