Skip to content

checkNonCyclic does not analyze prefixes of TypeRefs #1185

Closed
@odersky

Description

@odersky

We get a stack overflow when compiling this program, courtesy of Roland Kuhn:

object Test {
  import language.higherKinds

  class NotUsed

  trait FO[+Out, +Mat] { self =>
    type Repr[+O] <: FO[O, Mat] {
      type Repr[+OO] = self.Repr[OO]
    }
    def map[T](f: Out => T): Repr[T] = ???
  }

  class Source[+O, +M] extends FO[O, M] {
    type Repr[+OO] <: Source[OO, M]
  }

  class Flow[-I, +O, +M] extends FO[O, M] {
    type Repr[+OO] <: Flow[I, OO, M]
  }

  implicit class x[O, M, F[o, m] <: FO[o, m]](val f: F[O, M]) extends AnyVal {
    def xx(i: Int): f.Repr[O] = f.map(identity)
  }

  type IntFlow[O, M] = Flow[Int, O, M]

  val s1 = new Source[Int, NotUsed].xx(12)
  val s2: Source[Int, NotUsed] = s1
  val f1 = x[Int, NotUsed, IntFlow](new Flow[Int, Int, NotUsed]).xx(12)
  val f2: Flow[Int, Int, NotUsed] = f1
}

The problem is that the F-bound cycle goes through a hk type appliction (which takes the form of an #Apply node) and we do not traverse prefixes of TypeRefs. So the cycle is not detected and therefore fails to be mitigated with a LazyRef.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions