@@ -74,6 +74,32 @@ object TypeErasure {
74
74
private def erasureDependsOnArgs (sym : Symbol )(using Context ) =
75
75
sym == defn.ArrayClass || sym == defn.PairClass || isDerivedValueClass(sym)
76
76
77
+ /** The arity of this tuple type, which can be made up of EmptyTuple, TupleX and `*:` pairs.
78
+ *
79
+ * NOTE: This method is used to determine how to erase tuples, so it can
80
+ * only be changed in very limited ways without breaking
81
+ * binary-compatibility. In particular, note that it returns -1 for
82
+ * all tuples that end with the `EmptyTuple` type alias instead of
83
+ * `EmptyTuple.type` because of a missing dealias, but this is now
84
+ * impossible to fix.
85
+ *
86
+ * @return The arity if it can be determined or -1 otherwise.
87
+ */
88
+ def tupleArity (tp : Type )(using Context ): Int = tp/* .dealias*/ match {
89
+ case AppliedType (tycon, _ :: tl :: Nil ) if tycon.isRef(defn.PairClass ) =>
90
+ val arity = tupleArity(tl)
91
+ if (arity < 0 ) arity else arity + 1
92
+ case tp : SingletonType =>
93
+ if tp.termSymbol == defn.EmptyTupleModule then 0 else - 1
94
+ case tp : AndOrType =>
95
+ val arity1 = tupleArity(tp.tp1)
96
+ val arity2 = tupleArity(tp.tp2)
97
+ if arity1 == arity2 then arity1 else - 1
98
+ case _ =>
99
+ if defn.isTupleNType(tp) then tp.dealias.argInfos.length
100
+ else - 1
101
+ }
102
+
77
103
def normalizeClass (cls : ClassSymbol )(using Context ): ClassSymbol = {
78
104
if (cls.owner == defn.ScalaPackageClass ) {
79
105
if (defn.specialErasure.contains(cls))
@@ -740,9 +766,7 @@ class TypeErasure(sourceLanguage: SourceLanguage, semiEraseVCs: Boolean, isConst
740
766
}
741
767
742
768
private def erasePair (tp : Type )(using Context ): Type = {
743
- // NOTE: `tupleArity` does not consider TypeRef(EmptyTuple$) equivalent to EmptyTuple.type,
744
- // we fix this for printers, but type erasure should be preserved.
745
- val arity = tp.tupleArity
769
+ val arity = tupleArity(tp)
746
770
if (arity < 0 ) defn.ProductClass .typeRef
747
771
else if (arity <= Definitions .MaxTupleArity ) defn.TupleType (arity).nn
748
772
else defn.TupleXXLClass .typeRef
0 commit comments