aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/dotty/tools/dotc/typer/Implicits.scala9
-rw-r--r--tests/pos/t1500a.scala28
-rw-r--r--tests/run/t1500b.scala21
-rw-r--r--tests/run/t1500c.scala19
4 files changed, 73 insertions, 4 deletions
diff --git a/src/dotty/tools/dotc/typer/Implicits.scala b/src/dotty/tools/dotc/typer/Implicits.scala
index 0a3307140..2a1c18f7d 100644
--- a/src/dotty/tools/dotc/typer/Implicits.scala
+++ b/src/dotty/tools/dotc/typer/Implicits.scala
@@ -801,14 +801,15 @@ class SearchHistory(val searchDepth: Int, val seen: Map[ClassSymbol, Int]) {
def updateMap(csyms: List[ClassSymbol], seen: Map[ClassSymbol, Int]): SearchHistory = csyms match {
case csym :: csyms1 =>
seen get csym match {
+ // proto complexity is >= than the last time it was seen → diverge
case Some(prevSize) if size >= prevSize => this
case _ => updateMap(csyms1, seen.updated(csym, size))
}
- case nil =>
- if (csyms.isEmpty) this
- else new SearchHistory(searchDepth + 1, seen)
+ case _ =>
+ new SearchHistory(searchDepth + 1, seen)
}
- updateMap(proto.classSymbols, seen)
+ if (proto.classSymbols.isEmpty) this
+ else updateMap(proto.classSymbols, seen)
}
}
}
diff --git a/tests/pos/t1500a.scala b/tests/pos/t1500a.scala
new file mode 100644
index 000000000..adf46329a
--- /dev/null
+++ b/tests/pos/t1500a.scala
@@ -0,0 +1,28 @@
+trait Step0
+trait Step1
+trait Step2
+trait Step3
+trait Step4
+trait Step5
+trait Step6
+
+object Steps {
+ implicit val Step0: Step0 = new Step0 {}
+ implicit def Step1(implicit p: Step0): Step1 = new Step1 {}
+ implicit def Step2(implicit p: Step1): Step2 = new Step2 {}
+ implicit def Step3(implicit p: Step2): Step3 = new Step3 {}
+ implicit def Step4(implicit p: Step3): Step4 = new Step4 {}
+ implicit def Step5(implicit p: Step4): Step5 = new Step5 {}
+ implicit def Step6(implicit p: Step5): Step6 = new Step6 {}
+}
+
+object StepsTest {
+ import Steps._
+
+ implicitly[Step0]
+ implicitly[Step1]
+ implicitly[Step2]
+ implicitly[Step3]
+ implicitly[Step4]
+ implicitly[Step6]
+}
diff --git a/tests/run/t1500b.scala b/tests/run/t1500b.scala
new file mode 100644
index 000000000..8b52731a5
--- /dev/null
+++ b/tests/run/t1500b.scala
@@ -0,0 +1,21 @@
+sealed trait Nat
+sealed trait Succ[Prev <: Nat] extends Nat
+sealed trait Zero extends Nat
+
+case class ToInt[N <: Nat](value: Int)
+
+object ToInt {
+ implicit val caseZero: ToInt[Zero] = ToInt(0)
+ implicit def caseSucc[Prev <: Nat](implicit e: ToInt[Prev]): ToInt[Succ[Prev]] = ToInt(e.value + 1)
+}
+
+object Test {
+ def main(args: Array[String]): Unit = {
+ assert(implicitly[ToInt[Zero]].value == 0)
+ assert(implicitly[ToInt[Succ[Zero]]].value == 1)
+ assert(implicitly[ToInt[Succ[Succ[Zero]]]].value == 2)
+ assert(implicitly[ToInt[Succ[Succ[Succ[Zero]]]]].value == 3)
+ assert(implicitly[ToInt[Succ[Succ[Succ[Succ[Zero]]]]]].value == 4)
+ assert(implicitly[ToInt[Succ[Succ[Succ[Succ[Succ[Zero]]]]]]].value == 5)
+ }
+}
diff --git a/tests/run/t1500c.scala b/tests/run/t1500c.scala
new file mode 100644
index 000000000..5c33b7a2f
--- /dev/null
+++ b/tests/run/t1500c.scala
@@ -0,0 +1,19 @@
+sealed trait HList
+sealed trait HNil extends HList
+sealed trait ::[H, T <: HList] extends HList
+
+case class Size[L <: HList](value: Int)
+
+object Size {
+ implicit val caseHNil: Size[HNil] = Size(0)
+ implicit def caseHCons[H, T <: HList](implicit e: Size[T]): Size[H :: T] = Size(e.value + 1)
+}
+
+object Test {
+ def main(args: Array[String]): Unit = {
+ assert(implicitly[Size[HNil]].value == 0)
+ assert(implicitly[Size[Int :: HNil]].value == 1)
+ assert(implicitly[Size[Int :: Int :: HNil]].value == 2)
+ assert(implicitly[Size[Int :: Int :: Int :: HNil]].value == 3)
+ }
+}