@@ -74,6 +74,32 @@ object TypeErasure {
7474 private def erasureDependsOnArgs (sym : Symbol )(using Context ) =
7575 sym == defn.ArrayClass || sym == defn.PairClass || isDerivedValueClass(sym)
7676
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+
77103 def normalizeClass (cls : ClassSymbol )(using Context ): ClassSymbol = {
78104 if (cls.owner == defn.ScalaPackageClass ) {
79105 if (defn.specialErasure.contains(cls))
@@ -740,9 +766,7 @@ class TypeErasure(sourceLanguage: SourceLanguage, semiEraseVCs: Boolean, isConst
740766 }
741767
742768 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)
746770 if (arity < 0 ) defn.ProductClass .typeRef
747771 else if (arity <= Definitions .MaxTupleArity ) defn.TupleType (arity).nn
748772 else defn.TupleXXLClass .typeRef
0 commit comments