Skip to content

Commit

Permalink
Allow Tuple.Head and Tuple.Tail to accept any Tuple
Browse files Browse the repository at this point in the history
  • Loading branch information
Decel authored and dwijnand committed Mar 31, 2023
1 parent cabfa68 commit 4983ebb
Show file tree
Hide file tree
Showing 4 changed files with 14 additions and 2 deletions.
2 changes: 2 additions & 0 deletions compiler/test/dotc/pos-test-pickling.blacklist
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ i15181.scala
i15922.scala
t5031_2.scala
i16997.scala
i17186.scala
i11982a.scala

# Tree is huge and blows stack for printing Text
i7034.scala
Expand Down
9 changes: 7 additions & 2 deletions library/src/scala/Tuple.scala
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,11 @@ object Tuple {
}

/** Type of the head of a tuple */
type Head[X <: NonEmptyTuple] = X match {
// Only bounded by `<: Tuple` not `<: NonEmptyTuple`
// even though it only matches non-empty tuples.
// This allows an irreducible type like `Tuple.Head[Tuple.Tail[X]]`
// to avoid running into type bounds violation checks.
type Head[X <: Tuple] = X match {
case x *: _ => x
}

Expand All @@ -101,7 +105,8 @@ object Tuple {
}

/** Type of the tail of a tuple */
type Tail[X <: NonEmptyTuple] <: Tuple = X match {
// See Head for why not `<: NonEmptyTuple`
type Tail[X <: Tuple] <: Tuple = X match {
case _ *: xs => xs
}

Expand Down
File renamed without changes.
5 changes: 5 additions & 0 deletions tests/pos/i17186.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
type SecondOfTwo[X <: Tuple2[Any, Any]] = Tuple.Head[Tuple.Tail[X]]
val a = implicitly[SecondOfTwo[Tuple2[Int, String]] =:= String]

type LastOfThree[X <: Tuple3[Any, Any, Any]] = Tuple.Tail[Tuple.Tail[X]]
val b = implicitly[LastOfThree[Tuple3[Int, String, Boolean]] =:= Tuple1[Boolean]]

0 comments on commit 4983ebb

Please sign in to comment.