diff --git a/compiler/test/dotc/pos-test-pickling.blacklist b/compiler/test/dotc/pos-test-pickling.blacklist index 94e510e04396..a856a5b84d92 100644 --- a/compiler/test/dotc/pos-test-pickling.blacklist +++ b/compiler/test/dotc/pos-test-pickling.blacklist @@ -67,7 +67,6 @@ mt-redux-norm.perspective.scala i18211.scala 10867.scala named-tuples1.scala -named-tuples-strawman-2.scala # Opaque type i5720.scala diff --git a/compiler/test/dotc/run-test-pickling.blacklist b/compiler/test/dotc/run-test-pickling.blacklist index 954a64db1b66..dacbc63bb520 100644 --- a/compiler/test/dotc/run-test-pickling.blacklist +++ b/compiler/test/dotc/run-test-pickling.blacklist @@ -45,4 +45,5 @@ t6138-2 i12656.scala trait-static-forwarder i17255 +named-tuples-strawman-2.scala diff --git a/library/src/scala/Tuple.scala b/library/src/scala/Tuple.scala index 30f0e44ecf45..364124481db7 100644 --- a/library/src/scala/Tuple.scala +++ b/library/src/scala/Tuple.scala @@ -21,43 +21,43 @@ sealed trait Tuple extends Product: inline def toIArray: IArray[Object] = runtime.Tuples.toIArray(this) - /** Return a copy of `this` tuple with an element appended */ - inline def :* [This >: this.type <: Tuple, L] (x: L): Append[This, L] = - runtime.Tuples.append(x, this).asInstanceOf[Append[This, L]] - /** Return a new tuple by prepending the element to `this` tuple. * This operation is O(this.size) */ - inline def *: [H, This >: this.type <: Tuple] (x: H): H *: This = + inline def *: [H, This >: this.type <: Tuple](x: H): H *: This = runtime.Tuples.cons(x, this).asInstanceOf[H *: This] - /** Return a new tuple by concatenating `this` tuple with `that` tuple. - * This operation is O(this.size + that.size) - */ - inline def ++ [This >: this.type <: Tuple](that: Tuple): Concat[This, that.type] = - runtime.Tuples.concat(this, that).asInstanceOf[Concat[This, that.type]] + /** Return a copy of `this` tuple with an element appended */ + inline def :* [This >: this.type <: Tuple, L](x: L): This :* L = + runtime.Tuples.append(x, this).asInstanceOf[Append[This, L]] /** Return the size (or arity) of the tuple */ inline def size[This >: this.type <: Tuple]: Size[This] = runtime.Tuples.size(this).asInstanceOf[Size[This]] - /** Given two tuples, `(a1, ..., an)` and `(a1, ..., an)`, returns a tuple - * `((a1, b1), ..., (an, bn))`. If the two tuples have different sizes, - * the extra elements of the larger tuple will be disregarded. - * The result is typed as `((A1, B1), ..., (An, Bn))` if at least one of the - * tuple types has a `EmptyTuple` tail. Otherwise the result type is - * `(A1, B1) *: ... *: (Ai, Bi) *: Tuple` + /** Get the i-th element of this tuple. + * Equivalent to productElement but with a precise return type. */ - inline def zip[This >: this.type <: Tuple, T2 <: Tuple](t2: T2): Zip[This, T2] = - runtime.Tuples.zip(this, t2).asInstanceOf[Zip[This, T2]] + inline def apply[This >: this.type <: Tuple](n: Int): Elem[This, n.type] = + runtime.Tuples.apply(this, n).asInstanceOf[Elem[This, n.type]] - /** Called on a tuple `(a1, ..., an)`, returns a new tuple `(f(a1), ..., f(an))`. - * The result is typed as `(F[A1], ..., F[An])` if the tuple type is fully known. - * If the tuple is of the form `a1 *: ... *: Tuple` (that is, the tail is not known - * to be the cons type. + /** Get the head of this tuple */ + inline def head[This >: this.type <: Tuple]: Head[This] = + runtime.Tuples.apply(this, 0).asInstanceOf[Head[This]] + + /** Get the tail of this tuple. + * This operation is O(this.size) */ - inline def map[F[_]](f: [t] => t => F[t]): Map[this.type, F] = - runtime.Tuples.map(this, f).asInstanceOf[Map[this.type, F]] + inline def tail[This >: this.type <: Tuple]: Tail[This] = + runtime.Tuples.tail(this).asInstanceOf[Tail[This]] + + /** Get the last of this tuple */ + inline def last[This >: this.type <: Tuple]: Last[This] = + runtime.Tuples.last(this).asInstanceOf[Last[This]] + + /** Get the initial part of the tuple without its last element */ + inline def init[This >: this.type <: Tuple]: Init[This] = + runtime.Tuples.init(this).asInstanceOf[Init[This]] /** Given a tuple `(a1, ..., am)`, returns the tuple `(a1, ..., an)` consisting * of its first n elements. @@ -78,40 +78,73 @@ sealed trait Tuple extends Product: inline def splitAt[This >: this.type <: Tuple](n: Int): Split[This, n.type] = runtime.Tuples.splitAt(this, n).asInstanceOf[Split[This, n.type]] - /** Given a tuple `(a1, ..., am)`, returns the reversed tuple `(am, ..., a1)` - * consisting all its elements. + /** Return a new tuple by concatenating `this` tuple with `that` tuple. + * This operation is O(this.size + that.size) */ - inline def reverse[This >: this.type <: Tuple]: Reverse[This] = - runtime.Tuples.reverse(this).asInstanceOf[Reverse[This]] + // Contrarily to `this`, `that` does not need a type parameter + // since `++` is covariant in its second argument. + inline def ++ [This >: this.type <: Tuple](that: Tuple): This ++ that.type = + runtime.Tuples.concat(this, that).asInstanceOf[Concat[This, that.type]] - /** A tuple with the elements of this tuple in reversed order added in front of `acc` */ - inline def reverseOnto[This >: this.type <: Tuple, Acc <: Tuple](acc: Acc): ReverseOnto[This, Acc] = - (this.reverse ++ acc).asInstanceOf[ReverseOnto[This, Acc]] + /** Given two tuples, `(a1, ..., an)` and `(a1, ..., an)`, returns a tuple + * `((a1, b1), ..., (an, bn))`. If the two tuples have different sizes, + * the extra elements of the larger tuple will be disregarded. + * The result is typed as `((A1, B1), ..., (An, Bn))` if at least one of the + * tuple types has a `EmptyTuple` tail. Otherwise the result type is + * `(A1, B1) *: ... *: (Ai, Bi) *: Tuple` + */ + inline def zip[This >: this.type <: Tuple, T2 <: Tuple](t2: T2): Zip[This, T2] = + runtime.Tuples.zip(this, t2).asInstanceOf[Zip[This, T2]] + + /** Called on a tuple `(a1, ..., an)`, returns a new tuple `(f(a1), ..., f(an))`. + * The result is typed as `(F[A1], ..., F[An])` if the tuple type is fully known. + * If the tuple is of the form `a1 *: ... *: Tuple` (that is, the tail is not known + * to be the cons type. + */ + inline def map[F[_]](f: [t] => t => F[t]): Map[this.type, F] = + runtime.Tuples.map(this, f).asInstanceOf[Map[this.type, F]] /** A tuple consisting of all elements of this tuple that have types * for which the given type level predicate `P` reduces to the literal * constant `true`. */ - inline def filter[This >: this.type <: Tuple, P[_] <: Boolean]: Filter[This, P] = + inline def filter[This >: this.type <: Tuple, P[_ <: Union[This]] <: Boolean]: Filter[This, P] = val toInclude = constValueTuple[IndicesWhere[This, P]].toArray val arr = new Array[Object](toInclude.length) - for i <- 0 until toInclude.length do + for i <- toInclude.indices do arr(i) = this.productElement(toInclude(i).asInstanceOf[Int]).asInstanceOf[Object] Tuple.fromArray(arr).asInstanceOf[Filter[This, P]] + /** Given a tuple `(a1, ..., am)`, returns the reversed tuple `(am, ..., a1)` + * consisting all its elements. + */ + inline def reverse[This >: this.type <: Tuple]: Reverse[This] = + runtime.Tuples.reverse(this).asInstanceOf[Reverse[This]] + + /** A tuple with the elements of this tuple in reversed order added in front of `acc` */ + inline def reverseOnto[This >: this.type <: Tuple, Acc <: Tuple](acc: Acc): ReverseOnto[This, Acc] = + (this.reverse ++ acc).asInstanceOf[ReverseOnto[This, Acc]] + object Tuple: + /** Type of a tuple with an element appended */ + type Append[X <: Tuple, +Y] <: NonEmptyTuple = X match + case EmptyTuple => Y *: EmptyTuple + case x *: xs => x *: Append[xs, Y] + + /** An infix shorthand for `Append[X, Y]` */ + infix type :*[X <: Tuple, +Y] = Append[X, Y] + /** The size of a tuple, represented as a literal constant subtype of Int */ type Size[X <: Tuple] <: Int = X match case EmptyTuple => 0 - case x *: xs => S[Size[xs]] + case _ *: xs => S[Size[xs]] /** The type of the element at position N in the tuple X */ type Elem[X <: Tuple, N <: Int] = X match - case x *: xs => - N match - case 0 => x - case S[n1] => Elem[xs, n1] + case x *: xs => N match + case 0 => x + case S[n1] => Elem[xs, n1] /** The type of the first element of a tuple */ // Only bounded by `<: Tuple` not `<: NonEmptyTuple` @@ -122,20 +155,19 @@ object Tuple: type Head[X <: Tuple] = X match case x *: _ => x + /** The type of a tuple consisting of all elements of tuple X except the first one */ + type Tail[X <: Tuple] <: Tuple = X match + case _ *: xs => xs + /** The type of the last element of a tuple */ type Last[X <: Tuple] = X match case x *: EmptyTuple => x case _ *: xs => Last[xs] - /** The type of a tuple consisting of all elements of tuple X except the first one */ - type Tail[X <: Tuple] <: Tuple = X match - case _ *: xs => xs - /** The type of the initial part of a tuple without its last element */ type Init[X <: Tuple] <: Tuple = X match case _ *: EmptyTuple => EmptyTuple - case x *: xs => - x *: Init[xs] + case x *: xs => x *: Init[xs] /** The type of the tuple consisting of the first `N` elements of `X`, * or all elements if `N` exceeds `Size[X]`. @@ -149,84 +181,24 @@ object Tuple: /** The type of the tuple consisting of all elements of `X` except the first `N` ones, * or no elements if `N` exceeds `Size[X]`. */ - type Drop[X <: Tuple, N <: Int] <: Tuple = N match { + type Drop[X <: Tuple, N <: Int] <: Tuple = N match case 0 => X - case S[n1] => X match { + case S[n1] => X match case EmptyTuple => EmptyTuple - case x *: xs => Drop[xs, n1] - } - } + case _ *: xs => Drop[xs, n1] /** The pair type `(Take(X, N), Drop[X, N]). */ type Split[X <: Tuple, N <: Int] = (Take[X, N], Drop[X, N]) - /** Type of a tuple with an element appended */ - type Append[X <: Tuple, Y] <: NonEmptyTuple = X match { - case EmptyTuple => Y *: EmptyTuple - case x *: xs => x *: Append[xs, Y] - } - /** Type of the concatenation of two tuples `X` and `Y` */ + // Can be covariant in `Y` since it never appears as a match type scrutinee. type Concat[X <: Tuple, +Y <: Tuple] <: Tuple = X match case EmptyTuple => Y - case x1 *: xs1 => x1 *: Concat[xs1, Y] + case x *: xs => x *: Concat[xs, Y] /** An infix shorthand for `Concat[X, Y]` */ infix type ++[X <: Tuple, +Y <: Tuple] = Concat[X, Y] - /** The index of `Y` in tuple `X` as a literal constant Int, - * or `Size[X]` if `Y` does not occur in `X` - */ - type IndexOf[X <: Tuple, Y] <: Int = X match - case Y *: _ => 0 - case x *: xs => S[IndexOf[xs, Y]] - case EmptyTuple => 0 - - /** Fold a tuple `(T1, ..., Tn)` into `F[T1, F[... F[Tn, Z]...]]]` */ - type Fold[Tup <: Tuple, Z, F[_, _]] = Tup match - case EmptyTuple => Z - case h *: t => F[h, Fold[t, Z, F]] - - /** The type of tuple `X` mapped with the type-level function `F`. - * If `X = (T1, ..., Ti)` then `Map[X, F] = `(F[T1], ..., F[Ti])`. - */ - type Map[Tup <: Tuple, F[_ <: Union[Tup]]] <: Tuple = Tup match - case EmptyTuple => EmptyTuple - case h *: t => F[h] *: Map[t, F] - - /** The type of tuple `X` flat-mapped with the type-level function `F`. - * If `X = (T1, ..., Ti)` then `FlatMap[X, F] = `F[T1] ++ ... ++ F[Ti]` - */ - type FlatMap[Tup <: Tuple, F[_ <: Union[Tup]] <: Tuple] <: Tuple = Tup match - case EmptyTuple => EmptyTuple - case h *: t => Concat[F[h], FlatMap[t, F]] - // TODO: implement term level analogue - - /** The type of the tuple consisting of all elements of tuple `X` that have types - * for which the given type level predicate `P` reduces to the literal - * constant `true`. A predicate `P[X]` is a type that can be either `true` - * or `false`. For example: - * ```scala - * type IsString[x] <: Boolean = x match { - * case String => true - * case _ => false - * } - * summon[Tuple.Filter[(1, "foo", 2, "bar"), IsString] =:= ("foo", "bar")] - * ``` - * @syntax markdown - */ - type Filter[X <: Tuple, P[_] <: Boolean] <: Tuple = X match - case EmptyTuple => EmptyTuple - case h *: t => P[h] match - case true => h *: Filter[t, P] - case false => Filter[t, P] - - /** A tuple consisting of those indices `N` of tuple `X` where the predicate `P` - * is true for `Elem[X, N]`. Indices are type level values <: Int. - */ - type IndicesWhere[X <: Tuple, P[_] <: Boolean] = - helpers.IndicesWhereHelper[X, P, 0] - /** The type of the tuple consisting of all element values of * tuple `X` zipped with corresponding elements of tuple `Y`. * If the two tuples have different sizes, @@ -242,17 +214,22 @@ object Tuple: * ``` * @syntax markdown */ - type Zip[T1 <: Tuple, T2 <: Tuple] <: Tuple = (T1, T2) match - case (h1 *: t1, h2 *: t2) => (h1, h2) *: Zip[t1, t2] + type Zip[X <: Tuple, Y <: Tuple] <: Tuple = (X, Y) match + case (x *: xs, y *: ys) => (x, y) *: Zip[xs, ys] case (EmptyTuple, _) => EmptyTuple case (_, EmptyTuple) => EmptyTuple - case _ => Tuple + + /** The type of tuple `X` mapped with the type-level function `F`. + * If `X = (T1, ..., Ti)` then `Map[X, F] = `(F[T1], ..., F[Ti])`. + */ + type Map[X <: Tuple, F[_ <: Union[X]]] <: Tuple = X match + case EmptyTuple => EmptyTuple + case x *: xs => F[x] *: Map[xs, F] /** Converts a tuple `(F[T1], ..., F[Tn])` to `(T1, ... Tn)` */ - type InverseMap[X <: Tuple, F[_]] <: Tuple = X match { - case F[x] *: t => x *: InverseMap[t, F] + type InverseMap[X <: Tuple, F[_]] <: Tuple = X match + case F[x] *: xs => x *: InverseMap[xs, F] case EmptyTuple => EmptyTuple - } /** Implicit evidence. IsMappedBy[F][X] is present in the implicit scope iff * X is a tuple for which each element's type is constructed via `F`. E.g. @@ -261,6 +238,32 @@ object Tuple: */ type IsMappedBy[F[_]] = [X <: Tuple] =>> X =:= Map[InverseMap[X, F], F] + /** The type of tuple `X` flat-mapped with the type-level function `F`. + * If `X = (T1, ..., Ti)` then `FlatMap[X, F] = `F[T1] ++ ... ++ F[Ti]` + */ + type FlatMap[X <: Tuple, F[_ <: Union[X]] <: Tuple] <: Tuple = X match + case EmptyTuple => EmptyTuple + case x *: xs => Concat[F[x], FlatMap[xs, F]] + // TODO: implement term level analogue + + /** The type of the tuple consisting of all elements of tuple `X` that have types + * for which the given type level predicate `P` reduces to the literal + * constant `true`. A predicate `P[X]` is a type that can be either `true` + * or `false`. For example: + * ```scala + * type IsString[x] <: Boolean = x match + * case String => true + * case _ => false + * summon[Tuple.Filter[(1, "foo", 2, "bar"), IsString] =:= ("foo", "bar")] + * ``` + * @syntax markdown + */ + type Filter[X <: Tuple, P[_ <: Union[X]] <: Boolean] <: Tuple = X match + case EmptyTuple => EmptyTuple + case x *: xs => P[x] match + case true => x *: Filter[xs, P] + case false => Filter[xs, P] + /** A tuple with the elements of tuple `X` in reversed order */ type Reverse[X <: Tuple] = ReverseOnto[X, EmptyTuple] @@ -269,18 +272,37 @@ object Tuple: case x *: xs => ReverseOnto[xs, x *: Acc] case EmptyTuple => Acc + /** Fold a tuple `(T1, ..., Tn)` into `F[T1, F[... F[Tn, Z]...]]]` */ + type Fold[X <: Tuple, Z, F[_, _]] = X match + case EmptyTuple => Z + case x *: xs => F[x, Fold[xs, Z, F]] + /** Given a tuple `(T1, ..., Tn)`, returns a union of its * member types: `T1 | ... | Tn`. Returns `Nothing` if the tuple is empty. */ type Union[T <: Tuple] = Fold[T, Nothing, [x, y] =>> x | y] + /** The index of `Y` in tuple `X` as a literal constant Int, + * or `Size[X]` if `Y` is disjoint from all element types in `X`. + */ + type IndexOf[X <: Tuple, Y] <: Int = X match + case Y *: _ => 0 + case _ *: xs => S[IndexOf[xs, Y]] + case EmptyTuple => 0 + + /** A tuple consisting of those indices `N` of tuple `X` where the predicate `P` + * is true for `Elem[X, N]`. Indices are type level values <: Int. + */ + type IndicesWhere[X <: Tuple, P[_ <: Union[X]] <: Boolean] = + helpers.IndicesWhereHelper[X, P, 0] + /** A type level Boolean indicating whether the tuple `X` has an element * that matches `Y`. * @pre The elements of `X` are assumed to be singleton types */ type Contains[X <: Tuple, Y] <: Boolean = X match case Y *: _ => true - case x *: xs => Contains[xs, Y] + case _ *: xs => Contains[xs, Y] case EmptyTuple => false /** A type level Boolean indicating whether the type `Y` contains @@ -288,10 +310,9 @@ object Tuple: * @pre The elements of `X` and `Y` are assumed to be singleton types */ type Disjoint[X <: Tuple, Y <: Tuple] <: Boolean = X match - case x *: xs => - Contains[Y, x] match - case true => false - case false => Disjoint[xs, Y] + case x *: xs => Contains[Y, x] match + case true => false + case false => Disjoint[xs, Y] case EmptyTuple => true /** Empty tuple */ @@ -308,26 +329,21 @@ object Tuple: fromArray(xs, xs.length) /** Convert the first `n` elements of an array into a tuple of unknown arity and types */ - def fromArray[T](xs: Array[T], n: Int): Tuple = { - val xs2 = xs match { + def fromArray[T](xs: Array[T], n: Int): Tuple = + val xs2 = xs match case xs: Array[Object] => xs case xs => xs.map(_.asInstanceOf[Object]) - } runtime.Tuples.fromArray(xs2, n) - } /** Convert an immutable array into a tuple of unknown arity and types */ def fromIArray[T](xs: IArray[T]): Tuple = fromIArray(xs, xs.length) /** Convert the first `n` elements of an immutable array into a tuple of unknown arity and types */ - def fromIArray[T](xs: IArray[T], n: Int): Tuple = { - val xs2: IArray[Object] = xs match { + def fromIArray[T](xs: IArray[T], n: Int): Tuple = + val xs2: IArray[Object] = xs match case xs: IArray[Object] @unchecked => xs - case _ => - xs.map(_.asInstanceOf[Object]) - } + case _ => xs.map(_.asInstanceOf[Object]) runtime.Tuples.fromIArray(xs2, n) - } /** Convert a Product into a tuple of unknown arity and types */ def fromProduct(product: Product): Tuple = @@ -335,14 +351,13 @@ object Tuple: extension [X <: Tuple](inline x: X) - /** The index (starting at 0) of the first occurrence of y.type in the type `X` of `x` - * or Size[X] if no such element exists. + /** The index (starting at 0) of the first occurrence of `y.type` in the type `X` of `x` + * or `Size[X]` if no such element exists. */ - transparent inline def indexOf(y: Any): Int = constValue[IndexOf[X, y.type]] + inline def indexOf(y: Any): IndexOf[X, y.type] = constValue[IndexOf[X, y.type]] - /** A boolean indicating whether there is an element `y.type` in the type `X` of `x` - */ - transparent inline def contains(y: Any): Boolean = constValue[Contains[X, y.type]] + /** A boolean indicating whether there is an element `y.type` in the type `X` of `x` */ + inline def contains(y: Any): Contains[X, y.type] = constValue[Contains[X, y.type]] end extension @@ -357,7 +372,7 @@ object Tuple: private object helpers: /** Used to implement IndicesWhere */ - type IndicesWhereHelper[X <: Tuple, P[_] <: Boolean, N <: Int] <: Tuple = X match + type IndicesWhereHelper[X <: Tuple, P[_ <: Union[X]] <: Boolean, N <: Int] <: Tuple = X match case EmptyTuple => EmptyTuple case h *: t => P[h] match case true => N *: IndicesWhereHelper[t, P, S[N]] @@ -370,42 +385,14 @@ end Tuple type EmptyTuple = EmptyTuple.type /** A tuple of 0 elements. */ -case object EmptyTuple extends Tuple { +case object EmptyTuple extends Tuple: override def toString(): String = "()" -} /** Tuple of arbitrary non-zero arity */ -sealed trait NonEmptyTuple extends Tuple { - import Tuple.* - - /** Get the i-th element of this tuple. - * Equivalent to productElement but with a precise return type. - */ - inline def apply[This >: this.type <: NonEmptyTuple](n: Int): Elem[This, n.type] = - runtime.Tuples.apply(this, n).asInstanceOf[Elem[This, n.type]] - - /** Get the head of this tuple */ - inline def head[This >: this.type <: NonEmptyTuple]: Head[This] = - runtime.Tuples.apply(this, 0).asInstanceOf[Head[This]] - - /** Get the initial part of the tuple without its last element */ - inline def init[This >: this.type <: NonEmptyTuple]: Init[This] = - runtime.Tuples.init(this).asInstanceOf[Init[This]] - - /** Get the last of this tuple */ - inline def last[This >: this.type <: NonEmptyTuple]: Last[This] = - runtime.Tuples.last(this).asInstanceOf[Last[This]] - - /** Get the tail of this tuple. - * This operation is O(this.size) - */ - inline def tail[This >: this.type <: NonEmptyTuple]: Tail[This] = - runtime.Tuples.tail(this).asInstanceOf[Tail[This]] -} +sealed trait NonEmptyTuple extends Tuple @showAsInfix sealed abstract class *:[+H, +T <: Tuple] extends NonEmptyTuple -object *: { +object `*:`: def unapply[H, T <: Tuple](x: H *: T): (H, T) = (x.head, x.tail) -} diff --git a/library/src/scala/runtime/Tuples.scala b/library/src/scala/runtime/Tuples.scala index be6904b9d1d0..8da21c777943 100644 --- a/library/src/scala/runtime/Tuples.scala +++ b/library/src/scala/runtime/Tuples.scala @@ -357,7 +357,7 @@ object Tuples { } } - def tail(self: NonEmptyTuple): Tuple = (self: Any) match { + def tail(self: Tuple): Tuple = (self: Any) match { case xxl: TupleXXL => xxlTail(xxl) case _ => specialCaseTail(self) } @@ -565,16 +565,16 @@ object Tuples { } } - def init(self: NonEmptyTuple): Tuple = (self: Any) match { + def init(self: Tuple): Tuple = (self: Any) match { case xxl: TupleXXL => xxlInit(xxl) case _ => specialCaseInit(self) } - def last(self: NonEmptyTuple): Any = (self: Any) match { + def last(self: Tuple): Any = (self: Any) match { case self: Product => self.productElement(self.productArity - 1) } - def apply(self: NonEmptyTuple, n: Int): Any = + def apply(self: Tuple, n: Int): Any = self.productElement(n) // Benchmarks showed that this is faster than doing (it1 zip it2).copyToArray(...) diff --git a/tests/neg/print-tuple-union.check b/tests/neg/print-tuple-union.check index f3754aa5b17e..7d2c019de5a6 100644 --- a/tests/neg/print-tuple-union.check +++ b/tests/neg/print-tuple-union.check @@ -13,6 +13,6 @@ | and cannot be shown to be disjoint from it either. | Therefore, reduction cannot advance to the remaining case | - | case h *: t => h | Tuple.Fold[t, Nothing, [x, y] =>> x | y] + | case x *: xs => x | Tuple.Fold[xs, Nothing, [x, y] =>> x | y] | | longer explanation available when compiling with `-explain` diff --git a/tests/neg/wildcard-match.check b/tests/neg/wildcard-match.check index d405326c3d2b..fd20443c0a9f 100644 --- a/tests/neg/wildcard-match.check +++ b/tests/neg/wildcard-match.check @@ -87,8 +87,7 @@ | trying to reduce shapeless.tuples.length[T2] | trying to reduce Tuple.Size[shapeless.tuples.to[T2]] | failed since selector shapeless.tuples.to[T2] - | does not uniquely determine parameters x, xs in - | case x *: xs => scala.compiletime.ops.int.S[Tuple.Size[xs]] - | The computed bounds for the parameters are: - | x <: Int + | does not uniquely determine parameter xs in + | case _ *: xs => scala.compiletime.ops.int.S[Tuple.Size[xs]] + | The computed bounds for the parameter are: | xs <: (Int, Int) diff --git a/tests/pos/fieldsOf.scala b/tests/pos/fieldsOf.scala index 08f20a1f7e8e..2594dae2cbf7 100644 --- a/tests/pos/fieldsOf.scala +++ b/tests/pos/fieldsOf.scala @@ -1,3 +1,5 @@ +import language.experimental.namedTuples + case class Person(name: String, age: Int) type PF = NamedTuple.From[Person] diff --git a/tests/pos/tuple-filter.scala b/tests/pos/tuple-filter.scala index 2c9638b2e47b..0964d2e982d9 100644 --- a/tests/pos/tuple-filter.scala +++ b/tests/pos/tuple-filter.scala @@ -8,3 +8,6 @@ def Test = summon[Tuple.Filter[(1, 2, 3, 4), P] =:= (1, 2, 4)] summon[Tuple.Filter[(1, 2, 3, 4), RejectAll] =:= EmptyTuple] summon[Tuple.Filter[EmptyTuple, P] =:= EmptyTuple] + + import compiletime.ops.int.< + summon[Tuple.Filter[(1, 4, 7, 2, 10, 3, 4), [X <: Int] =>> X < 5] =:= (1, 4, 2, 3, 4)] diff --git a/tests/pos/named-tuples-strawman-2.scala b/tests/run/named-tuples-strawman-2.scala similarity index 100% rename from tests/pos/named-tuples-strawman-2.scala rename to tests/run/named-tuples-strawman-2.scala