Skip to content

Commit 40b741c

Browse files
committed
Bound tuple sizes when possible
1 parent 54b0584 commit 40b741c

File tree

1 file changed

+11
-10
lines changed

1 file changed

+11
-10
lines changed

compiler/src/dotty/tools/dotc/transform/TuplesOptimizations.scala

+11-10
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ class TuplesOptimizations extends MiniPhase with IdentityDenotTransformer {
6464

6565
private def transformTupleTail(tree: tpd.Apply)(implicit ctx: Context): Tree = {
6666
val Apply(TypeApply(_, tpt :: Nil), tup :: Nil) = tree
67-
tupleTypes(tpt.tpe) match { // TODO tupleBoundedTypes
67+
tupleTypes(tpt.tpe, MaxTupleArity + 1) match {
6868
case Some(tpes) =>
6969
// Generate a the tuple directly with TupleN-1.apply
7070
val size = tpes.size
@@ -154,7 +154,7 @@ class TuplesOptimizations extends MiniPhase with IdentityDenotTransformer {
154154
if (n < 0 || n >= size) {
155155
ctx.error("index out of bounds: " + n, nTree.underlyingArgument.sourcePos)
156156
tree
157-
} else if (size <= Definitions.MaxTupleArity) {
157+
} else if (size <= MaxTupleArity) {
158158
// tup._n
159159
Typed(tup, TypeTree(defn.tupleType(tpes))).select(nme.selectorName(n))
160160
} else {
@@ -173,13 +173,13 @@ class TuplesOptimizations extends MiniPhase with IdentityDenotTransformer {
173173

174174
private def transformTupleToArray(tree: tpd.Apply)(implicit ctx: Context): Tree = {
175175
val Apply(_, tup :: Nil) = tree
176-
tupleTypes(tup.tpe.widen) match { // TODO tupleBoundedTypes
176+
tupleTypes(tup.tpe.widen, MaxTupleArity) match {
177177
case Some(tpes) =>
178178
val size = tpes.size
179179
if (size == 0) {
180180
// Array.emptyObjectArray
181181
ref(defn.ArrayModule.companionModule).select("emptyObjectArray".toTermName).ensureApplied
182-
} else if (size <= Definitions.MaxTupleArity) {
182+
} else if (size <= MaxTupleArity) {
183183
// DynamicTuple.productToArray(tup.asInstanceOf[Product])
184184
ref(defn.DynamicTuple_productToArray).appliedTo(tup.asInstance(defn.ProductType))
185185
} else {
@@ -196,7 +196,7 @@ class TuplesOptimizations extends MiniPhase with IdentityDenotTransformer {
196196
/** Create a TupleN (1 <= N < 23) from the elements */
197197
private def knownTupleFromElements(tpes: List[Type], elements: List[Tree])(implicit ctx: Context) = {
198198
val size = elements.size
199-
assert(0 < size && size <= Definitions.MaxTupleArity)
199+
assert(0 < size && size <= MaxTupleArity)
200200
val tupleModule = defn.TupleType(size).classSymbol.companionModule
201201
ref(tupleModule).select(nme.apply).appliedToTypes(tpes).appliedToArgs(elements)
202202
}
@@ -206,7 +206,7 @@ class TuplesOptimizations extends MiniPhase with IdentityDenotTransformer {
206206
// Unit for empty tuple
207207
Literal(Constant(())) // TODO should this code be here? Or assert(size > specializedSize)
208208
}
209-
else if (size <= Definitions.MaxTupleArity) {
209+
else if (size <= MaxTupleArity) {
210210
// TupleN(it.next(), ..., it.next())
211211

212212
// TODO outline this code for the 22 alternatives (or less, may not need the smallest ones)?
@@ -222,13 +222,14 @@ class TuplesOptimizations extends MiniPhase with IdentityDenotTransformer {
222222
}
223223
}
224224

225-
private def tupleTypes(tp: Type)(implicit ctx: Context): Option[List[Type]] = {
226-
@tailrec def rec(tp: Type, acc: List[Type]): Option[List[Type]] = tp match {
227-
case tp: AppliedType if defn.PairClass == tp.classSymbol => rec(tp.args(1), tp.args(0) :: acc)
225+
private def tupleTypes(tp: Type, bound: Int = Int.MaxValue)(implicit ctx: Context): Option[List[Type]] = {
226+
@tailrec def rec(tp: Type, acc: List[Type], bound: Int): Option[List[Type]] = tp match {
227+
case _ if bound < 0 => Some(acc.reverse)
228+
case tp: AppliedType if defn.PairClass == tp.classSymbol => rec(tp.args(1), tp.args.head :: acc, bound - 1)
228229
case tp: AppliedType if defn.isTupleClass(tp.tycon.classSymbol) => Some(acc.reverse ::: tp.args)
229230
case tp if tp.classSymbol == defn.UnitClass => Some(acc.reverse)
230231
case _ => None
231232
}
232-
rec(tp.stripTypeVar, Nil)
233+
rec(tp.stripTypeVar, Nil, bound)
233234
}
234235
}

0 commit comments

Comments
 (0)