Skip to content

Different successful compilation depending on setting of -Xmin-implicit-search-depth #5236

Closed
@milessabin

Description

@milessabin

This will go away once the SIP'd divergence rules are implemented, but leaving this for posterity ...

Given,

object Test {
  trait Foo[T, U]
  object Foo {
    implicit def diverge[T](implicit ev: Foo[T, T]): Foo[T, T] = ???
    implicit def foo[T, U]: Foo[T, U] = ???
  }

  implicitly[Foo[Int, Int]]
}

With the default -Xmin-implicit-search-depth of 5 the implicitly compiles as,

/* inlined from dotty.DottyPredef$ */ 
  {
    val ev: Test4.Foo[Int, Int] = 
      Test.Foo.diverge[Int](
        Test.Foo.diverge[Int](
          Test.Foo.diverge[Int](
            Test.Foo.diverge[Int](
              Test.Foo.diverge[Int](Test4.Foo.foo[Int, Int])
            )
          )
        )
      )
    ev
  }

With -Xmin-implicit-search-depth set to 2 it compiles as,

/* inlined from dotty.DottyPredef$ */ 
  {
    val ev: Test4.Foo[Int, Int] = 
      Test.Foo.diverge[Int](
        Test.Foo.diverge[Int](Test4.Foo.foo[Int, Int])
      )
    ev
  }

ie. each increment in the value adds an additional call of the diverging implicit before we fail back to the convergent one. We get the expected result only if the parameter is set to 0.

Clearly the entire divergent path should be discarded. It remains to be seen if it's possible to reliably unwind a divergent path or if it would be better to abort the entire search and retry with unconditional divergence checking.

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions