11import scala .collection .mutable
22import scala .annotation .tailrec
33
4+ object _typelevel {
5+ final abstract class Type [- A , + B ]
6+ type Subtype [t] = Type [_, t]
7+ type Supertype [t] = Type [t, _]
8+ type Exactly [t] = Type [t, t]
9+ erased def typeOf [T ]: Type [T , T ] = ???
10+ }
11+
412trait Deriving {
513 import Deriving ._
614
@@ -177,6 +185,7 @@ trait Eq[T] {
177185object Eq {
178186 import scala .typelevel ._
179187 import Deriving ._
188+ import _typelevel ._
180189
181190 inline def tryEql [T ](x : T , y : T ) = implicit match {
182191 case eq : Eq [T ] => eq.eql(x, y)
@@ -197,14 +206,19 @@ object Eq {
197206 inline def eqlCases [T , Alts <: Tuple ](r : Reflected [T ], x : T , y : T ): Boolean =
198207 inline erasedValue[Alts ] match {
199208 case _ : (Shape .Case [alt, elems] *: alts1) =>
200- x match {
201- case x : `alt` =>
202- y match {
203- case y : `alt` => eqlCase[T , elems](r, x, y)
204- case _ => false
209+ inline typeOf[alt] match {
210+ case _ : Subtype [T ] =>
211+ x match {
212+ case x : `alt` =>
213+ y match {
214+ case y : `alt` => eqlCase[T , elems](r, x, y)
215+ case _ => false
216+ }
217+ case _ => eqlCases[T , alts1](r, x, y)
205218 }
206- case _ => eqlCases[T , alts1](r, x, y)
207- }
219+ case _ =>
220+ error(" invalid call to eqlCases: one of Alts is not a subtype of T" )
221+ }
208222 case _ : Unit =>
209223 false
210224 }
@@ -232,6 +246,7 @@ trait Pickler[T] {
232246object Pickler {
233247 import scala .typelevel ._
234248 import Deriving ._
249+ import _typelevel ._
235250
236251 def nextInt (buf : mutable.ListBuffer [Int ]): Int = try buf.head finally buf.trimStart(1 )
237252
@@ -253,12 +268,17 @@ object Pickler {
253268 inline def pickleCases [T , Alts <: Tuple ](r : Reflected [T ], buf : mutable.ListBuffer [Int ], x : T , n : Int ): Unit =
254269 inline erasedValue[Alts ] match {
255270 case _ : (Shape .Case [alt, elems] *: alts1) =>
256- x match {
257- case x : `alt` =>
258- buf += n
259- pickleCase[T , elems](r, buf, x)
271+ inline typeOf[alt] match {
272+ case _ : Subtype [T ] =>
273+ x match {
274+ case x : `alt` =>
275+ buf += n
276+ pickleCase[T , elems](r, buf, x)
277+ case _ =>
278+ pickleCases[T , alts1](r, buf, x, n + 1 )
279+ }
260280 case _ =>
261- pickleCases[ T , alts1](r, buf, x, n + 1 )
281+ error( " invalid pickleCases call: one of Alts is not a subtype of T " )
262282 }
263283 case _ : Unit =>
264284 }
@@ -323,6 +343,7 @@ trait Show[T] {
323343object Show {
324344 import scala .typelevel ._
325345 import Deriving ._
346+ import _typelevel ._
326347
327348 inline def tryShow [T ](x : T ): String = implicit match {
328349 case s : Show [T ] => s.show(x)
@@ -347,9 +368,14 @@ object Show {
347368 inline def showCases [T , Alts <: Tuple ](r : Reflected [T ], x : T ): String =
348369 inline erasedValue[Alts ] match {
349370 case _ : (Shape .Case [alt, elems] *: alts1) =>
350- x match {
351- case x : `alt` => showCase[T , elems](r, x)
352- case _ => showCases[T , alts1](r, x)
371+ inline typeOf[alt] match {
372+ case _ : Subtype [T ] =>
373+ x match {
374+ case x : `alt` => showCase[T , elems](r, x)
375+ case _ => showCases[T , alts1](r, x)
376+ }
377+ case _ =>
378+ error(" invalid call to showCases: one of Alts is not a subtype of T" )
353379 }
354380 case _ : Unit =>
355381 throw new MatchError (x)
@@ -424,4 +450,4 @@ object Test extends App {
424450 println(implicitly[Show [T ]].show(x))
425451 showPrintln(xs)
426452 showPrintln(xss)
427- }
453+ }
0 commit comments