Skip to content

Commit 7cff6a8

Browse files
authored
Merge pull request #1504 from OlivierBlanvillain/fix-1500
Partially fix #1500: Implicit search breaks at a certain depth
2 parents 75f4400 + fe09615 commit 7cff6a8

File tree

4 files changed

+73
-4
lines changed

4 files changed

+73
-4
lines changed

src/dotty/tools/dotc/typer/Implicits.scala

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -801,14 +801,15 @@ class SearchHistory(val searchDepth: Int, val seen: Map[ClassSymbol, Int]) {
801801
def updateMap(csyms: List[ClassSymbol], seen: Map[ClassSymbol, Int]): SearchHistory = csyms match {
802802
case csym :: csyms1 =>
803803
seen get csym match {
804+
// proto complexity is >= than the last time it was seen → diverge
804805
case Some(prevSize) if size >= prevSize => this
805806
case _ => updateMap(csyms1, seen.updated(csym, size))
806807
}
807-
case nil =>
808-
if (csyms.isEmpty) this
809-
else new SearchHistory(searchDepth + 1, seen)
808+
case _ =>
809+
new SearchHistory(searchDepth + 1, seen)
810810
}
811-
updateMap(proto.classSymbols, seen)
811+
if (proto.classSymbols.isEmpty) this
812+
else updateMap(proto.classSymbols, seen)
812813
}
813814
}
814815
}

tests/pos/t1500a.scala

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
trait Step0
2+
trait Step1
3+
trait Step2
4+
trait Step3
5+
trait Step4
6+
trait Step5
7+
trait Step6
8+
9+
object Steps {
10+
implicit val Step0: Step0 = new Step0 {}
11+
implicit def Step1(implicit p: Step0): Step1 = new Step1 {}
12+
implicit def Step2(implicit p: Step1): Step2 = new Step2 {}
13+
implicit def Step3(implicit p: Step2): Step3 = new Step3 {}
14+
implicit def Step4(implicit p: Step3): Step4 = new Step4 {}
15+
implicit def Step5(implicit p: Step4): Step5 = new Step5 {}
16+
implicit def Step6(implicit p: Step5): Step6 = new Step6 {}
17+
}
18+
19+
object StepsTest {
20+
import Steps._
21+
22+
implicitly[Step0]
23+
implicitly[Step1]
24+
implicitly[Step2]
25+
implicitly[Step3]
26+
implicitly[Step4]
27+
implicitly[Step6]
28+
}

tests/run/t1500b.scala

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
sealed trait Nat
2+
sealed trait Succ[Prev <: Nat] extends Nat
3+
sealed trait Zero extends Nat
4+
5+
case class ToInt[N <: Nat](value: Int)
6+
7+
object ToInt {
8+
implicit val caseZero: ToInt[Zero] = ToInt(0)
9+
implicit def caseSucc[Prev <: Nat](implicit e: ToInt[Prev]): ToInt[Succ[Prev]] = ToInt(e.value + 1)
10+
}
11+
12+
object Test {
13+
def main(args: Array[String]): Unit = {
14+
assert(implicitly[ToInt[Zero]].value == 0)
15+
assert(implicitly[ToInt[Succ[Zero]]].value == 1)
16+
assert(implicitly[ToInt[Succ[Succ[Zero]]]].value == 2)
17+
assert(implicitly[ToInt[Succ[Succ[Succ[Zero]]]]].value == 3)
18+
assert(implicitly[ToInt[Succ[Succ[Succ[Succ[Zero]]]]]].value == 4)
19+
assert(implicitly[ToInt[Succ[Succ[Succ[Succ[Succ[Zero]]]]]]].value == 5)
20+
}
21+
}

tests/run/t1500c.scala

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
sealed trait HList
2+
sealed trait HNil extends HList
3+
sealed trait ::[H, T <: HList] extends HList
4+
5+
case class Size[L <: HList](value: Int)
6+
7+
object Size {
8+
implicit val caseHNil: Size[HNil] = Size(0)
9+
implicit def caseHCons[H, T <: HList](implicit e: Size[T]): Size[H :: T] = Size(e.value + 1)
10+
}
11+
12+
object Test {
13+
def main(args: Array[String]): Unit = {
14+
assert(implicitly[Size[HNil]].value == 0)
15+
assert(implicitly[Size[Int :: HNil]].value == 1)
16+
assert(implicitly[Size[Int :: Int :: HNil]].value == 2)
17+
assert(implicitly[Size[Int :: Int :: Int :: HNil]].value == 3)
18+
}
19+
}

0 commit comments

Comments
 (0)