Skip to content

Commit 164005a

Browse files
committed
Address review comments on Tuple.scala
1 parent 6d2ab58 commit 164005a

File tree

4 files changed

+13
-57
lines changed

4 files changed

+13
-57
lines changed

library/src/scala/NamedTuple.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -184,8 +184,8 @@ object NamedTuple:
184184
* @syntax markdown
185185
*/
186186
type Zip[X <: AnyNamedTuple, Y <: AnyNamedTuple] =
187-
Tuple.Conforms[Names[X], Names[Y]] match
188-
case true =>
187+
Names[X] match
188+
case Names[Y] =>
189189
NamedTuple[Names[X], Tuple.Zip[DropNames[X], DropNames[Y]]]
190190

191191
/** A type specially treated by the compiler to represent all fields of a

library/src/scala/Tuple.scala

Lines changed: 7 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,7 @@ object Tuple:
118118
// even though it only matches non-empty tuples.
119119
// Avoids bounds check failures from an irreducible type
120120
// like `Tuple.Head[Tuple.Tail[X]]`
121+
// Other types that don't reduce for empty tuples follow the same principle.
121122
type Head[X <: Tuple] = X match
122123
case x *: _ => x
123124

@@ -273,22 +274,6 @@ object Tuple:
273274
*/
274275
type Union[T <: Tuple] = Fold[T, Nothing, [x, y] =>> x | y]
275276

276-
/** A type level Boolean indicating whether the tuple `X` conforms
277-
* to the tuple `Y`. This means:
278-
* - the two tuples have the same number of elements
279-
* - for corresponding elements `x` in `X` and `y` in `Y`, `x` matches `y`.
280-
* @pre The elements of `X` are assumed to be singleton types
281-
*/
282-
type Conforms[X <: Tuple, Y <: Tuple] <: Boolean = Y match
283-
case EmptyTuple =>
284-
X match
285-
case EmptyTuple => true
286-
case _ => false
287-
case y *: ys =>
288-
X match
289-
case `y` *: xs => Conforms[xs, ys]
290-
case _ => false
291-
292277
/** A type level Boolean indicating whether the tuple `X` has an element
293278
* that matches `Y`.
294279
* @pre The elements of `X` are assumed to be singleton types
@@ -350,25 +335,14 @@ object Tuple:
350335

351336
extension [X <: Tuple](inline x: X)
352337

353-
/** The index (starting at 0) of the first element in the type `X` of `x`
354-
* that matches type `Y`.
338+
/** The index (starting at 0) of the first occurrence of y.type in the type `X` of `x`
339+
* or Size[X] if no such element exists.
355340
*/
356-
inline def indexOfType[Y] = constValue[IndexOf[X, Y]]
341+
transparent inline def indexOf(y: Any): Int = constValue[IndexOf[X, y.type]]
357342

358-
/** A boolean indicating whether there is an element in the type `X` of `x`
359-
* that matches type `Y`.
343+
/** A boolean indicating whether there is an element `y.type` in the type `X` of `x`
360344
*/
361-
inline def containsType[Y] = constValue[Contains[X, Y]]
362-
363-
/* Note: It would be nice to add the following two extension methods:
364-
365-
inline def indexOf[Y: Precise](y: Y) = constValue[IndexOf[X, Y]]
366-
inline def containsType[Y: Precise](y: Y) = constValue[Contains[X, Y]]
367-
368-
because we could then move indexOf/contains completely to the value level.
369-
But this requires `Y` to be inferred precisely, and therefore a mechanism
370-
like the `Precise` context bound used above, which does not yet exist.
371-
*/
345+
transparent inline def contains(y: Any): Boolean = constValue[Contains[X, y.type]]
372346

373347
end extension
374348

@@ -380,7 +354,7 @@ object Tuple:
380354
using eqHead: CanEqual[H1, H2], eqTail: CanEqual[T1, T2]
381355
): CanEqual[H1 *: T1, H2 *: T2] = CanEqual.derived
382356

383-
object helpers:
357+
private object helpers:
384358

385359
/** Used to implement IndicesWhere */
386360
type IndicesWhereHelper[X <: Tuple, P[_] <: Boolean, N <: Int] <: Tuple = X match

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

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ object TupleOps:
5252
case EmptyTuple => Y *: EmptyTuple
5353

5454
inline def appendIfDistinct[X <: Tuple, Y](xs: X, y: Y): AppendIfDistinct[X, Y] =
55-
(if xs.containsType[Y] then xs else xs :* y).asInstanceOf[AppendIfDistinct[X, Y]]
55+
(if xs.contains(y) then xs else xs :* y).asInstanceOf[AppendIfDistinct[X, Y]]
5656

5757
/** `X` with all elements from `Y` that do not occur in `X` appended */
5858
type ConcatDistinct[X <: Tuple, Y <: Tuple] <: Tuple = Y match
@@ -137,10 +137,10 @@ object NamedTupleOps:
137137
val x1: IndexOf[Names, "first"] = constValue
138138
val _: 0 = x1
139139

140-
val x2: IndexOf[Names, "age"] = names.indexOfType["age"]
140+
val x2: IndexOf[Names, "age"] = names.indexOf("age")
141141
val _: 2 = x2
142142

143-
val x3: IndexOf[Names, "what?"] = names.indexOfType["what?"]
143+
val x3: IndexOf[Names, "what?"] = names.indexOf("what?")
144144
val _: 3 = x3
145145

146146
type Releases = "first" *: "middle" *: EmptyTuple
@@ -149,7 +149,7 @@ object NamedTupleOps:
149149
val releases: Releases = ("first", "middle")
150150
val releaseValues: ReleaseValues = (1.0, true)
151151

152-
val x4 = values.updateOrAppend(names.indexOfType["age"], 11)
152+
val x4 = values.updateOrAppend(names.indexOf("age"), 11)
153153
//updateOrAppend[Values](values)[IndexOf[Names, "age"], 11](indexOf[Names](names)["age"]("age"), 11)
154154
val _: ("Bob", "Miller", 11) = x4
155155
assert(("Bob", "Miller", 11) == x4)

tests/pos/tuple-ops.scala

Lines changed: 0 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -2,18 +2,6 @@ import language.experimental.namedTuples
22
import Tuple.*
33

44
def test =
5-
val x1: Conforms[(1, 2), (1, 2)] = ???
6-
val _: true = x1
7-
8-
val x2: Conforms[(1, 2), (1, 3)] = ???
9-
val _: false = x2
10-
11-
val x3: Conforms[(1, 2), (1, 2, 4)] = ???
12-
val _: false = x2
13-
14-
val x4: Conforms[(1, 2, 4), (1, 2)] = ???
15-
val _: false = x2
16-
175
summon[Disjoint[(1, 2, 3), (4, 5)] =:= true]
186
summon[Disjoint[(1, 2, 6), (4, 5)] =:= true]
197
summon[Disjoint[(1, 2, 6), EmptyTuple] =:= true]
@@ -23,12 +11,6 @@ def test =
2311
summon[Contains[(1, 2, 3), 2] =:= true]
2412
summon[Contains[(1, 2, 3), 4] =:= false]
2513

26-
summon[Conforms[(1, 2, 3), (1, 2, 3)] =:= true]
27-
summon[Conforms[(1, 2, 3), (1, 2)] =:= false]
28-
summon[Conforms[(1, 2, 3), (1, 2, 4)] =:= false]
29-
summon[Conforms[(1, 2, 3), (Int, 2, 3)] =:= true]
30-
// summon[Conforms[(Int, 2, 3), (1, 2, 3)] =:= true] // error, reduction gets stuck
31-
3214
summon[Disjoint[(1, 2, 3), (4, 2)] =:= false]
3315
summon[Disjoint[("a", "b"), ("b", "c")] =:= false]
3416
summon[Disjoint[(1, 2, 6), Tuple1[2]] =:= false]

0 commit comments

Comments
 (0)