From ace7c9a2dbe6ed4b80a5ea91afa4414a81472f88 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zieli=C5=84ski=20Patryk?= <75637004+zielinsky@users.noreply.github.com> Date: Thu, 9 Oct 2025 13:42:07 +0200 Subject: [PATCH] Fix "Regression in zio/zio-schema for typer/implicit resolution" (#24156) Fixes implicit divergence checking regression by correcting how `TypeSizeAccumulator` handles `TypeParamRef` bounds. Instead of adding both upper and lower bounds to the type size, we now take the maximum of both bound sizes. Fixes https://github.com/scala/scala3/issues/24007 [Cherry-picked 0afa50da6128b04289c108bc54ecf338f3e3e115] --- .../src/dotty/tools/dotc/core/Types.scala | 5 ++- tests/pos/i24007.scala | 33 +++++++++++++++++++ 2 files changed, 37 insertions(+), 1 deletion(-) create mode 100644 tests/pos/i24007.scala diff --git a/compiler/src/dotty/tools/dotc/core/Types.scala b/compiler/src/dotty/tools/dotc/core/Types.scala index 54bfeaadb179..c280d28bcb22 100644 --- a/compiler/src/dotty/tools/dotc/core/Types.scala +++ b/compiler/src/dotty/tools/dotc/core/Types.scala @@ -6605,7 +6605,10 @@ object Types extends TypeUtils { case tp: TypeRef if tp.info.isTypeAlias => apply(n, tp.superType) case tp: TypeParamRef => - apply(n, TypeComparer.bounds(tp)) + val bounds = TypeComparer.bounds(tp) + val loSize = apply(n, bounds.lo) + val hiSize = apply(n, bounds.hi) + hiSize max loSize case tp: LazyRef => if seen.contains(tp) then n else diff --git a/tests/pos/i24007.scala b/tests/pos/i24007.scala new file mode 100644 index 000000000000..86d94211d273 --- /dev/null +++ b/tests/pos/i24007.scala @@ -0,0 +1,33 @@ +sealed trait CaseSet: + type EnumType + +object CaseSet { + def caseOf[A, Z >: A]: Cons[A, Empty[Z], Z] = ??? + type Aux[EnumType0] = CaseSet { type EnumType = EnumType0 } + + final class Empty[Z] extends CaseSet: + type EnumType = Z + + final class Cons[A, +T <: CaseSet.Aux[Z], Z](head: A, tail: T) extends CaseSet: + type EnumType = Z + def ++[That](that: That)(implicit append: Append[Z, Cons[A, T, Z], That]): append.Out = ??? +} + +sealed trait Append[EnumType, -Left, -Right]: + type Out <: CaseSet.Aux[EnumType] + +object Append: + type WithOut[EnumType, Left, Right, Out0] = Append[EnumType, Left, Right] { type Out = Out0 } + + implicit def AppendCons[A, Z, T <: CaseSet.Aux[Z], That <: CaseSet.Aux[Z]](implicit + append: Append[Z, T, That] + ): Append.WithOut[Z, CaseSet.Cons[A, T, Z], That, CaseSet.Cons[A, append.Out, Z]] = ??? + + implicit def AppendEmptyLeft[T <: CaseSet.Aux[Z], Z]: Append.WithOut[Z, CaseSet.Empty[Z], T, T] = + ??? + +object Test: + type UnionValue = Int | Boolean | String + val _ = CaseSet.caseOf[Int, UnionValue] ++ + CaseSet.caseOf[Boolean, UnionValue] ++ + CaseSet.caseOf[String, UnionValue] \ No newline at end of file