From b29050941303b62060ccb0b3c2853edffc083c13 Mon Sep 17 00:00:00 2001 From: Lluc Santamaria Riba Date: Sat, 13 Dec 2025 12:01:48 +0100 Subject: [PATCH] Fix inconsistent typeSize for TupleN vs nested pairs Previously, `typeSize` reported different values for standard `TupleN` types (e.g., `(A, B)`) compared to their equivalent recursive pair encodings (e.g., `A *: B *: EmptyTuple`). This discrepancy occurred because `TupleN` is a flat `AppliedType`, while the nested encoding forms a deeper tree structure. This patch modifies `TypeSizeAccumulator` to canonicalize `TupleN` types into their recursive `*:` representation before calculating the size. This ensures that the size metric is consistent regardless of whether the tuple is represented syntactically or structurally. This change is verified by a new unit test in `TypesTest`, which confirms that both `Tuple3[Int, Boolean, Double]` and its recursive equivalent `Int *: Boolean *: Double *: EmptyTuple` now yield identical `typeSize` values. Fixes #24730 --- compiler/src/dotty/tools/dotc/core/Types.scala | 2 ++ .../test/dotty/tools/dotc/core/TypesTest.scala | 18 ++++++++++++++++++ .../tools/dotc/typer/DivergenceChecker.scala | 4 ++-- 3 files changed, 22 insertions(+), 2 deletions(-) create mode 100644 compiler/test/dotty/tools/dotc/core/TypesTest.scala diff --git a/compiler/src/dotty/tools/dotc/core/Types.scala b/compiler/src/dotty/tools/dotc/core/Types.scala index dc54d14b0d4b..91335dfc11ea 100644 --- a/compiler/src/dotty/tools/dotc/core/Types.scala +++ b/compiler/src/dotty/tools/dotc/core/Types.scala @@ -7125,6 +7125,8 @@ object Types extends TypeUtils { var seen = util.HashSet[Type](initialCapacity = 8) def apply(n: Int, tp: Type): Int = tp match { + case tp: AppliedType if defn.isTupleNType(tp) => + foldOver(n + 1, tp.toNestedPairs) case tp: AppliedType => val tpNorm = tp.tryNormalize if tpNorm.exists then apply(n, tpNorm) diff --git a/compiler/test/dotty/tools/dotc/core/TypesTest.scala b/compiler/test/dotty/tools/dotc/core/TypesTest.scala new file mode 100644 index 000000000000..00336dca2b2c --- /dev/null +++ b/compiler/test/dotty/tools/dotc/core/TypesTest.scala @@ -0,0 +1,18 @@ +package dotty.tools.dotc.core + +import dotty.tools.DottyTest +import dotty.tools.dotc.core.Symbols.defn +import dotty.tools.dotc.core.TypeOps + +import org.junit.Test +import org.junit.Assert.assertEquals + +class TypesTest extends DottyTest: + + @Test def tuple3TypeSize = + val tpe = defn.TupleType(3).nn.appliedTo(List(defn.IntType, defn.BooleanType, defn.DoubleType)) + assertEquals(3, tpe.typeSize) + + @Test def tuple3ConsTypeSize = + val tpe = TypeOps.nestedPairs(List(defn.IntType, defn.BooleanType, defn.DoubleType)) + assertEquals(3, tpe.typeSize) \ No newline at end of file diff --git a/compiler/test/dotty/tools/dotc/typer/DivergenceChecker.scala b/compiler/test/dotty/tools/dotc/typer/DivergenceChecker.scala index 520b3d2de57e..da3482a43d27 100644 --- a/compiler/test/dotty/tools/dotc/typer/DivergenceChecker.scala +++ b/compiler/test/dotty/tools/dotc/typer/DivergenceChecker.scala @@ -50,8 +50,8 @@ class DivergenceCheckerTests extends DottyTest { 1, 1, 1, - 3, - 5 + 4, + 6 ) tpes.lazyZip(expectedSizes).lazyZip(expectedCoveringSets).foreach {