Skip to content

Commit cd3a120

Browse files
committed
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
1 parent 96be092 commit cd3a120

File tree

2 files changed

+27
-1
lines changed

2 files changed

+27
-1
lines changed

compiler/src/dotty/tools/dotc/core/Types.scala

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7124,7 +7124,15 @@ object Types extends TypeUtils {
71247124
class TypeSizeAccumulator(using Context) extends TypeAccumulator[Int] {
71257125
var seen = util.HashSet[Type](initialCapacity = 8)
71267126
def apply(n: Int, tp: Type): Int =
7127-
tp match {
7127+
7128+
val canonicTp = tp match
7129+
case AppliedType(_, args) if defn.isTupleNType(tp) =>
7130+
args.foldRight(defn.EmptyTupleClass.typeRef: Type) { (elemType, acc) =>
7131+
defn.PairClass.typeRef.appliedTo(elemType, acc)
7132+
}
7133+
case _ => tp
7134+
7135+
canonicTp match {
71287136
case tp: AppliedType =>
71297137
val tpNorm = tp.tryNormalize
71307138
if tpNorm.exists then apply(n, tpNorm)
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
package dotty.tools.dotc.core
2+
3+
import dotty.tools.DottyTest
4+
import dotty.tools.dotc.core.Symbols.defn
5+
import dotty.tools.dotc.core.TypeOps
6+
7+
import org.junit.Test
8+
import org.junit.Assert.assertEquals
9+
10+
class TypesTest extends DottyTest:
11+
12+
@Test def tuple3TypeSize =
13+
val tpe = defn.TupleType(3).nn.appliedTo(List(defn.IntType, defn.BooleanType, defn.DoubleType))
14+
assertEquals(3, tpe.typeSize)
15+
16+
@Test def tuple3ConsTypeSize =
17+
val tpe = TypeOps.nestedPairs(List(defn.IntType, defn.BooleanType, defn.DoubleType))
18+
assertEquals(3, tpe.typeSize)

0 commit comments

Comments
 (0)