diff --git a/compiler/src/dotty/tools/dotc/core/Types.scala b/compiler/src/dotty/tools/dotc/core/Types.scala index eeffc41d4159..68a603563ecd 100644 --- a/compiler/src/dotty/tools/dotc/core/Types.scala +++ b/compiler/src/dotty/tools/dotc/core/Types.scala @@ -6896,25 +6896,20 @@ object Types extends TypeUtils { } class TypeSizeAccumulator(using Context) extends TypeAccumulator[Int] { - var seen = util.HashSet[Type](initialCapacity = 8) def apply(n: Int, tp: Type): Int = - if seen.contains(tp) then n - else { - seen += tp - tp match { - case tp: AppliedType => - val tpNorm = tp.tryNormalize - if tpNorm.exists then apply(n, tpNorm) - else foldOver(n + 1, tp) - case tp: RefinedType => - foldOver(n + 1, tp) - case tp: TypeRef if tp.info.isTypeAlias => - apply(n, tp.superType) - case tp: TypeParamRef => - apply(n, TypeComparer.bounds(tp)) - case _ => - foldOver(n, tp) - } + tp match { + case tp: AppliedType => + val tpNorm = tp.tryNormalize + if tpNorm.exists then apply(n, tpNorm) + else foldOver(n + 1, tp) + case tp: RefinedType => + foldOver(n + 1, tp) + case tp: TypeRef if tp.info.isTypeAlias => + apply(n, tp.superType) + case tp: TypeParamRef => + apply(n, TypeComparer.bounds(tp)) + case _ => + foldOver(n, tp) } } diff --git a/tests/pos/i15692.scala b/tests/pos/i15692.scala new file mode 100644 index 000000000000..11b69e3bd377 --- /dev/null +++ b/tests/pos/i15692.scala @@ -0,0 +1,24 @@ +sealed trait Nat +sealed trait Succ[Prev <: Nat] extends Nat +sealed trait Zero extends Nat + +class Sum[M <: Nat, N <: Nat] { + type Out <: Nat +} + +object Sum { + type Aux[M <: Nat, N <: Nat, R <: Nat] = Sum[M, N] { type Out = R } + + implicit def sum0[N <: Nat]: Sum.Aux[Zero, N, N] = new Sum[Zero, N] { type Out = N } + implicit def sum1[M <: Nat, N <: Nat, R <: Nat](implicit sum: Sum.Aux[M, Succ[N], R]): Sum.Aux[Succ[M], N, R] = + new Sum[Succ[M], N] { type Out = R } +} + +object Test { + def main(args: Array[String]): Unit = { + type _3 = Succ[Succ[Succ[Zero]]] + type _5 = Succ[Succ[_3]] + + implicitly[Sum[_3, _5]] + } +}