Skip to content

Don't generate mirrors for local classes #12355

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion compiler/src/dotty/tools/dotc/typer/Synthesizer.scala
Original file line number Diff line number Diff line change
Expand Up @@ -346,7 +346,10 @@ class Synthesizer(typer: Typer)(using @constructorOnly c: Context):
(using Context): Tree =
if checkFormal(formal) then
formal.member(tpnme.MirroredType).info match
case TypeBounds(mirroredType, _) => synth(mirroredType.stripTypeVar, formal, span)
case TypeBounds(mirroredType, _)
if mirroredType.classSymbol.maybeOwner.isType =>
// local classes do not support mirrors, see neg/12328.scala for a test case.
synth(mirroredType.stripTypeVar, formal, span)
case other => EmptyTree
else EmptyTree

Expand Down
4 changes: 3 additions & 1 deletion docs/docs/reference/contextual/derivation.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ We say that `Tree` is the _deriving type_ and that the `Eq`, `Ordering` and `Sho

All data types can have a `derives` clause. This document focuses primarily on data types which also have a given instance
of the `Mirror` type class available. Instances of the `Mirror` type class are generated automatically by the compiler
for,
for:

+ enums and enum cases
+ case classes and case objects
Expand All @@ -39,6 +39,8 @@ for,
They also provide minimal term level infrastructure to allow higher level libraries to provide comprehensive
derivation support.

*Note*: Mirror instances are not generated for classes in a local context (i.e. classes that are not members of packages or other classes).

```scala
sealed trait Mirror:

Expand Down
35 changes: 35 additions & 0 deletions tests/neg/i12328.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import scala.deriving.Mirror
import scala.compiletime._

trait Schema[T]

object Schema {
inline def recurse[A <: Tuple]: List[Schema[Any]] =
inline erasedValue[A] match {
case _: (t *: ts) => summonInline[Schema[t]].asInstanceOf[Schema[Any]] :: recurse[ts]
case EmptyTuple => Nil
}

inline def derived[T]: Schema[T] =
inline summonInline[Mirror.Of[T]] match {
case m: Mirror.SumOf[T] =>
val subTypes = recurse[m.MirroredElemTypes]
new Schema[T] { }
case m: Mirror.ProductOf[T] =>
val fields = recurse[m.MirroredElemTypes]
new Schema[T] { }
}

inline given gen[T]: Schema[T] = derived
}

@main def hello: Unit = {

sealed trait Item
object Item {
case object A extends Item
case object B extends Item
}

summon[Schema[Item]] // error
}
8 changes: 4 additions & 4 deletions tests/neg/multi-param-derives.scala
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import scala.deriving.*

object Test extends App {
{
object test1 {
trait Show[T]
object Show {
given Show[Int]()
Expand All @@ -19,7 +19,7 @@ object Test extends App {
case class Poly3[A, B, C](a: A, b: B, c: C) derives Show
}

{
object test2 {
trait Functor[F[_]]
object Functor {
given [C]: Functor[[T] =>> C]()
Expand All @@ -37,7 +37,7 @@ object Test extends App {
case class Poly3[A, B, C](a: A, b: B, c: C) derives Functor
}

{
object test3 {
trait FunctorK[F[_[_]]]
object FunctorK {
given [C]: FunctorK[[F[_]] =>> C]()
Expand All @@ -53,7 +53,7 @@ object Test extends App {
case class Poly3[A, B, C](a: A, b: B, c: C) derives FunctorK // error
}

{
object test4 {
trait Bifunctor[F[_, _]]
object Bifunctor {
given [C]: Bifunctor[[T, U] =>> C]()
Expand Down
8 changes: 4 additions & 4 deletions tests/run/poly-kinded-derives.scala
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import scala.deriving.*

object Test extends App {
{
object test1 {
trait Show[T]
object Show {
given Show[Int]()
Expand All @@ -19,7 +19,7 @@ object Test extends App {
case class Poly3[A, B, C](a: A, b: B, c: C) derives Show
}

{
object test2 {
trait Functor[F[_]]
object Functor {
given [C]: Functor[[T] =>> C]()
Expand All @@ -37,7 +37,7 @@ object Test extends App {
case class Poly3[A, B, C](a: A, b: B, c: C) derives Functor
}

{
object test3 {
trait FunctorK[F[_[_]]]
object FunctorK {
given [C]: FunctorK[[F[_]] =>> C]()
Expand All @@ -53,7 +53,7 @@ object Test extends App {
//case class Poly3[A, B, C](a: A, b: B, c: C) derives FunctorK
}

{
object test4 {
trait Bifunctor[F[_, _]]
object Bifunctor {
given [C]: Bifunctor[[T, U] =>> C]()
Expand Down