Skip to content

Commit b0b2383

Browse files
committed
Fix owner of newSym
Need to take current context instead of global Inliner context.
1 parent b939933 commit b0b2383

File tree

2 files changed

+90
-4
lines changed

2 files changed

+90
-4
lines changed

compiler/src/dotty/tools/dotc/typer/Inliner.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -237,7 +237,7 @@ class Inliner(call: tpd.Tree, rhsToInline: tpd.Tree)(implicit ctx: Context) {
237237
/** A buffer for bindings that define proxies for actual arguments */
238238
private val bindingsBuf = new mutable.ListBuffer[ValOrDefDef]
239239

240-
private def newSym(name: Name, flags: FlagSet, info: Type): Symbol =
240+
private def newSym(name: Name, flags: FlagSet, info: Type)(implicit ctx: Context): Symbol =
241241
ctx.newSymbol(ctx.owner, name, flags, info, coord = call.span)
242242

243243
/** A binding for the parameter of an inline method. This is a `val` def for

tests/run/typeclass-derivation2b.scala

Lines changed: 89 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,12 @@ object TypeLevel {
1616
def apply(n: Int): Any = elems.productElement(n)
1717
}
1818

19+
object EmptyProduct extends Product {
20+
def canEqual(that: Any): Boolean = true
21+
def productElement(n: Int) = throw new IndexOutOfBoundsException
22+
def productArity = 0
23+
}
24+
1925
object Mirror {
2026

2127
/** A mirror of case with ordinal number `ordinal` and elements as given by `Product` */
@@ -67,16 +73,30 @@ object TypeLevel {
6773
* It informs that type `T` has shape `S` and also implements runtime reflection on `T`.
6874
*/
6975
abstract class Generic[T] {
70-
7176
/** The shape of the `T` */
7277
type Shape <: TypeLevel.Shape
7378

79+
7480
/** The case mirror corresponding to ADT instance `x` */
7581
def reflect(x: T): Mirror
7682

7783
/** The ADT instance corresponding to given `mirror` */
7884
def reify(mirror: Mirror): T
7985
}
86+
87+
abstract class Generic2[T] {
88+
type Shape <: Tuple
89+
}
90+
91+
abstract class GenericSum[S] extends Generic2[S] {
92+
def ordinal(x: S): Int
93+
def alternative(n: Int): GenericProduct[_ <: S] = ???
94+
}
95+
96+
abstract class GenericProduct[P] extends Generic2[P] {
97+
def toProduct(x: P): Product
98+
def fromProduct(p: Product): P
99+
}
80100
}
81101

82102
// An algebraic datatype
@@ -101,10 +121,41 @@ object Lst {
101121
}
102122
}
103123

124+
class Generic2Lst[T] extends GenericSum[Lst[T]] {
125+
override type Shape = (Cons[T], Nil.type)
126+
def ordinal(x: Lst[T]) = x match {
127+
case x: Cons[_] => 0
128+
case Nil => 1
129+
}
130+
inline override def alternative(inline n: Int) <: GenericProduct[_ <: Lst[T]] =
131+
inline n match {
132+
case 0 => Cons.GenericCons[T]
133+
case 1 => Nil.GenericNil
134+
}
135+
}
136+
104137
implicit def GenericLst[T]: GenericLst[T] = new GenericLst[T]
138+
implicit def Generic2Lst[T]: Generic2Lst[T] = new Generic2Lst[T]
105139

106140
case class Cons[T](hd: T, tl: Lst[T]) extends Lst[T]
107-
case object Nil extends Lst[Nothing]
141+
142+
object Cons {
143+
class GenericCons[T] extends GenericProduct[Cons[T]] {
144+
type Shape = (T, Lst[T])
145+
def toProduct(x: Cons[T]): Product = x
146+
def fromProduct(p: Product): Cons[T] =
147+
Cons(p.productElement(0).asInstanceOf, p.productElement(1).asInstanceOf)
148+
}
149+
implicit def GenericCons[T]: GenericCons[T] = new GenericCons[T]
150+
}
151+
case object Nil extends Lst[Nothing] {
152+
class GenericNil extends GenericProduct[Nil.type] {
153+
type Shape = Unit
154+
def toProduct(x: Nil.type): Product = EmptyProduct
155+
def fromProduct(p: Product): Nil.type = Nil
156+
}
157+
implicit def GenericNil: GenericNil = new GenericNil
158+
}
108159

109160
// three clauses that could be generated from a `derives` clause
110161
implicit def derived$Eq[T: Eq]: Eq[Lst[T]] = Eq.derived
@@ -143,7 +194,42 @@ object Eq {
143194
false
144195
}
145196

146-
inline def derived[T, S <: Shape](implicit ev: Generic[T]): Eq[T] = new {
197+
inline def eqlProducts[Elems <: Tuple](x: Product, y: Product, n: Int): Boolean =
198+
inline erasedValue[Elems] match {
199+
case _: (elem *: elems1) =>
200+
tryEql[elem](x.productElement(n).asInstanceOf, y.productElement(n).asInstanceOf) &&
201+
eqlProducts[elems1](x, y, n + 1)
202+
case _: Unit =>
203+
true
204+
}
205+
206+
inline def eqlAlts[T, Alts <: Tuple](x: T, y: T, genSum: GenericSum[T], ord: Int, inline n: Int): Boolean =
207+
inline erasedValue[Alts] match {
208+
case _: (alt *: alts1) =>
209+
if (ord == n)
210+
inline genSum.alternative(n) match {
211+
case genProd => eqlProducts[genProd.Shape](
212+
genProd.toProduct(x.asInstanceOf),
213+
genProd.toProduct(y.asInstanceOf), 0)
214+
}
215+
else eqlAlts[T, alts1](x, y, genSum, ord, n + 1)
216+
case _: Unit =>
217+
false
218+
}
219+
220+
inline def derived[T](implicit ev: Generic2[T]): Eq[T] = new Eq[T] {
221+
def eql(x: T, y: T): Boolean = {
222+
inline ev match {
223+
case evv: GenericSum[T] =>
224+
val ord = evv.ordinal(x)
225+
ord == evv.ordinal(y) && eqlAlts[T, evv.Shape](x, y, evv, ord, 0)
226+
case evv: GenericProduct[T] =>
227+
eqlProducts[evv.Shape](evv.toProduct(x), evv.toProduct(y), 0)
228+
}
229+
}
230+
}
231+
232+
inline def derived2[T, S <: Shape](implicit ev: Generic[T]): Eq[T] = new {
147233
def eql(x: T, y: T): Boolean = {
148234
val xm = ev.reflect(x)
149235
val ym = ev.reflect(y)

0 commit comments

Comments
 (0)