Skip to content

Commit

Permalink
Handle & and | types when computing tuple arity
Browse files Browse the repository at this point in the history
  • Loading branch information
nicolasstucki committed Jun 9, 2022
1 parent aa5ea92 commit 2917667
Show file tree
Hide file tree
Showing 3 changed files with 24 additions and 3 deletions.
9 changes: 6 additions & 3 deletions compiler/src/dotty/tools/dotc/transform/TypeUtils.scala
Original file line number Diff line number Diff line change
Expand Up @@ -62,10 +62,13 @@ object TypeUtils {
if self.termSymbol == defn.EmptyTupleModule then 0 else -1
case self: TypeRef if relaxEmptyTuple && self.classSymbol == defn.EmptyTupleModule.moduleClass =>
0
case self if defn.isTupleClass(self.classSymbol) =>
self.dealias.argInfos.length
case self: AndOrType =>
val arity1 = self.tp1.tupleArity(relaxEmptyTuple)
val arity2 = self.tp2.tupleArity(relaxEmptyTuple)
if arity1 == arity2 then arity1 else -1
case _ =>
-1
if defn.isTupleClass(self.classSymbol) then self.dealias.argInfos.length
else -1
}

/** The element types of this tuple type, which can be made up of EmptyTuple, TupleX and `*:` pairs */
Expand Down
6 changes: 6 additions & 0 deletions tests/run/i15302a.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
inline def flatConcat2[A, B](a: A, b: B) =
b match
case bs: *:[bh, bt] => a *: bs

@main def Test =
val x: (Int, Int, Int) = flatConcat2(1, (2,3))
12 changes: 12 additions & 0 deletions tests/run/i15302b.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
@main def Test =
val tup2: Any = (1, 2)
val x1: (Int, Int) = tup2.asInstanceOf[(Int *: Int *: EmptyTuple) & (Int, Int)]
val x2: (Int, Int) = tup2.asInstanceOf[(Int *: Int *: Tuple) & (Int, Int)]
val x3: (Int, Int) = tup2.asInstanceOf[(Int *: Int *: EmptyTuple) | (Int, Int)]
val x4: Tuple = tup2.asInstanceOf[(Int *: Int *: Tuple) | (Int, Int)]

val tup3: Any = (1, 2, 3)
val x5: (Int, Int, Int) = tup3.asInstanceOf[Int *: ((Int *: Int *: EmptyTuple) & (Int, Int))]
val x6: (Int, Int, Int) = tup3.asInstanceOf[Int *: ((Int *: Int *: Tuple) & (Int, Int))]
val x7: (Int, Int, Int) = tup3.asInstanceOf[Int *: ((Int *: Int *: EmptyTuple) | (Int, Int))]
val x8: Tuple = tup3.asInstanceOf[Int *: ((Int *: Int *: Tuple) | (Int, Int))]

0 comments on commit 2917667

Please # to comment.