Skip to content

Commit a27caa4

Browse files
oderskyWojciechMazur
authored andcommitted
Add test cases
[Cherry-picked 125612f]
1 parent e90d376 commit a27caa4

File tree

2 files changed

+78
-0
lines changed

2 files changed

+78
-0
lines changed

tests/neg-macros/i18695.scala

+75
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
import scala.annotation.{tailrec, unused}
2+
import scala.deriving.Mirror
3+
import scala.quoted.*
4+
5+
trait TypeLength[A] {
6+
type Length <: Int
7+
def length: Length
8+
}
9+
object TypeLength extends TypeLengthLowPriority:
10+
type Aux[A, Length0 <: Int] = TypeLength[A] {
11+
type Length = Length0
12+
}
13+
14+
transparent inline given fromMirror[A](using m: Mirror.Of[A]): TypeLength[A] =
15+
${ macroImpl[A, m.MirroredElemTypes] }
16+
17+
@tailrec
18+
private def typesOfTuple(
19+
using q: Quotes
20+
)(tpe: q.reflect.TypeRepr, acc: List[q.reflect.TypeRepr]): List[q.reflect.TypeRepr] =
21+
import q.reflect.*
22+
val cons = Symbol.classSymbol("scala.*:")
23+
tpe.widenTermRefByName.dealias match
24+
case AppliedType(fn, tpes) if defn.isTupleClass(fn.typeSymbol) =>
25+
tpes.reverse_:::(acc)
26+
case AppliedType(tp, List(headType, tailType)) if tp.derivesFrom(cons) =>
27+
typesOfTuple(tailType, headType :: acc)
28+
case tpe =>
29+
if tpe.derivesFrom(Symbol.classSymbol("scala.EmptyTuple")) then acc.reverse
30+
else report.errorAndAbort(s"Unknown type encountered in tuple ${tpe.show}")
31+
32+
def macroImpl[A: Type, T <: Tuple: scala.quoted.Type](
33+
using q: scala.quoted.Quotes
34+
): scala.quoted.Expr[TypeLength[A]] =
35+
import q.reflect.*
36+
val l = typesOfTuple(TypeRepr.of[T], Nil).length
37+
ConstantType(IntConstant(l)).asType match
38+
case '[lt] =>
39+
val le = Expr[Int](l).asExprOf[lt & Int]
40+
'{
41+
val r: TypeLength.Aux[A, lt & Int] = new TypeLength[A] {
42+
type Length = lt & Int
43+
val length: Length = ${ le }
44+
}
45+
r
46+
}
47+
48+
transparent inline given fromTuple[T <: Tuple]: TypeLength[T] =
49+
${ macroImpl[T, T] }
50+
51+
trait TypeLengthLowPriority:
52+
self: TypeLength.type =>
53+
given tupleFromMirrorAndLength[A, T <: Tuple](
54+
using @unused m: Mirror.Of[A] { type MirroredElemTypes = T },
55+
length: TypeLength[A]
56+
): TypeLength.Aux[T, length.Length] = length.asInstanceOf[TypeLength.Aux[T, length.Length]]
57+
58+
trait HKDSumGeneric[A]
59+
object HKDSumGeneric:
60+
type NotZero[N <: Int] = N match
61+
case 0 => false
62+
case _ => true
63+
64+
transparent inline given derived[A](using m: Mirror.SumOf[A], typeLength: TypeLength[A])(
65+
using NotZero[typeLength.Length] =:= true
66+
): HKDSumGeneric[A] =
67+
derivedImpl[A, m.MirroredElemTypes, m.MirroredLabel] // error
68+
69+
def derivedImpl[A, ElemTypes <: Tuple, Label <: String](
70+
using m: Mirror.SumOf[A] {
71+
type MirroredElemTypes = ElemTypes; type MirroredLabel = Label;
72+
},
73+
typeLength: TypeLength[ElemTypes],
74+
nz: NotZero[typeLength.Length] =:= true
75+
): HKDSumGeneric[A] = ???

tests/neg/i18695.scala

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
trait Foo { type Num <: Int }
2+
given derived[A](using foo: Foo): Any = derivedImpl(foo) // error
3+
def derivedImpl(foo: Foo)(using bar: foo.Num =:= Int): Any = ???

0 commit comments

Comments
 (0)