diff options
-rw-r--r-- | src/dotty/tools/dotc/typer/Implicits.scala | 9 | ||||
-rw-r--r-- | tests/pos/t1500a.scala | 28 | ||||
-rw-r--r-- | tests/run/t1500b.scala | 21 | ||||
-rw-r--r-- | tests/run/t1500c.scala | 19 |
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) + } +} |