Skip to content

Commit 2e9bb8d

Browse files
Revert doing tuple runtime operations based on a term level predicates
1 parent 5fcebd8 commit 2e9bb8d

File tree

2 files changed

+15
-22
lines changed

2 files changed

+15
-22
lines changed

library/src/scala/Tuple.scala

Lines changed: 14 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -104,10 +104,15 @@ sealed trait Tuple extends Product:
104104
inline def map[F[_]](f: [t] => t => F[t]): Map[this.type, F] =
105105
runtime.Tuples.map(this, f).asInstanceOf[Map[this.type, F]]
106106

107-
/** A tuple consisting of all elements of this tuple that satisfy the predicate `p`. */
108-
inline def filter[This >: this.type <: Tuple, P[_ <: Union[This]] <: Boolean]
109-
(p: (x: Union[This]) => P[x.type]): Filter[This, P] =
110-
val arr = this.toArray.filter(x => p(x.asInstanceOf[Union[This]]))
107+
/** A tuple consisting of all elements of this tuple that have types
108+
* for which the given type level predicate `P` reduces to the literal
109+
* constant `true`.
110+
*/
111+
inline def filter[This >: this.type <: Tuple, P[_ <: Union[This]] <: Boolean]: Filter[This, P] =
112+
val toInclude = constValueTuple[IndicesWhere[This, P]].toArray
113+
val arr = new Array[Object](toInclude.length)
114+
for i <- toInclude.indices do
115+
arr(i) = this.productElement(toInclude(i).asInstanceOf[Int]).asInstanceOf[Object]
111116
Tuple.fromArray(arr).asInstanceOf[Filter[This, P]]
112117

113118
/** Given a tuple `(a1, ..., am)`, returns the reversed tuple `(am, ..., a1)`
@@ -345,23 +350,14 @@ object Tuple:
345350
runtime.Tuples.fromProduct(product)
346351

347352
extension [X <: Tuple](inline x: X)
348-
// Note the two methods are not equivalent to using `constValue`,
349-
// since they also allow cases unknown at compiletime.
350-
// Also note it would be unsound to use a type parameter for `y` in the type level
351-
// operations, since they are rightfully not covariant in their second parameter.
352353

353-
/** The index (starting at 0) of the first occurrence of `y` in `x`
354-
* or its size if no such element exists.
354+
/** The index (starting at 0) of the first occurrence of `y.type` in the type `X` of `x`
355+
* or `Size[X]` if no such element exists.
355356
*/
356-
inline def indexOf(y: Any): IndexOf[X, y.type] =
357-
val i = x.productIterator.indexOf(y)
358-
(if i >= 0 then i else x.size).asInstanceOf[IndexOf[X, y.type]]
359-
360-
/** A boolean indicating whether `x` contains the element `y` */
361-
inline def contains(y: Any): Contains[X, y.type] =
362-
x.productIterator.contains(y).asInstanceOf[Contains[X, y.type]]
357+
inline def indexOf(y: Any): IndexOf[X, y.type] = constValue[IndexOf[X, y.type]]
363358

364-
// TODO indexOfType & containsType ?
359+
/** A boolean indicating whether there is an element `y.type` in the type `X` of `x` */
360+
inline def contains(y: Any): Contains[X, y.type] = constValue[Contains[X, y.type]]
365361

366362
end extension
367363

tests/pos/named-tuples-strawman-2.scala

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -60,10 +60,7 @@ object TupleOps:
6060
case EmptyTuple => X
6161

6262
inline def concatDistinct[X <: Tuple, Y <: Tuple](xs: X, ys: Y): ConcatDistinct[X, Y] =
63-
// Note the type parameter is needed due to the invariance of compiletime.ops.boolean.!
64-
extension [B <: Boolean](self: B) def negated: ![B] = (!self).asInstanceOf
65-
val ysDistinct = ys.filter[Y, [y] =>> ![Contains[X, y]]](xs.contains(_).negated)
66-
(xs ++ ysDistinct).asInstanceOf[ConcatDistinct[X, Y]]
63+
(xs ++ ys.filter[Y, [Elem] =>> ![Contains[X, Elem]]]).asInstanceOf[ConcatDistinct[X, Y]]
6764

6865
object NamedTupleDecomposition:
6966
import NamedTupleOps.*

0 commit comments

Comments
 (0)