Skip to content

Include sealed traits and classes as elements of Sum Mirrors #11851

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
4 changes: 2 additions & 2 deletions compiler/src/dotty/tools/dotc/transform/SymUtils.scala
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ object SymUtils:
* - none of its children are anonymous classes
* - all of its children are addressable through a path from the parent class
* and also the location of the generated mirror.
* - all of its children are generic products or singletons
* - all of its children are generic products, singletons, or sealed traits ar classes
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
* - all of its children are generic products, singletons, or sealed traits ar classes
* - all of its children are generic products, singletons, or sealed traits or classes

*/
def whyNotGenericSum(declScope: Symbol)(using Context): String =
if (!self.is(Sealed))
Expand All @@ -112,7 +112,7 @@ object SymUtils:

if (child == self) "it has anonymous or inaccessible subclasses"
else if (!isAccessible(child.owner)) i"its child $child is not accessible"
else if (!child.isClass) ""
else if !child.isClass || child.is(Sealed) then ""
else {
val s = child.whyNotGenericProduct
if (s.isEmpty) s
Expand Down
16 changes: 8 additions & 8 deletions compiler/src/dotty/tools/dotc/typer/Synthesizer.scala
Original file line number Diff line number Diff line change
Expand Up @@ -278,12 +278,12 @@ class Synthesizer(typer: Typer)(using @constructorOnly c: Context):
val elemLabels = cls.children.map(c => ConstantType(Constant(c.name.toString)))

def solve(sym: Symbol): Type = sym match
case caseClass: ClassSymbol =>
assert(caseClass.is(Case))
if caseClass.is(Module) then
caseClass.sourceModule.termRef
case childClass: ClassSymbol =>
assert(childClass.isOneOf(Case | Sealed))
if childClass.is(Module) then
childClass.sourceModule.termRef
else
caseClass.primaryConstructor.info match
childClass.primaryConstructor.info match
case info: PolyType =>
// Compute the the full child type by solving the subtype constraint
// `C[X1, ..., Xn] <: P`, where
Expand All @@ -300,13 +300,13 @@ class Synthesizer(typer: Typer)(using @constructorOnly c: Context):
case tp => tp
resType <:< target
val tparams = poly.paramRefs
val variances = caseClass.typeParams.map(_.paramVarianceSign)
val variances = childClass.typeParams.map(_.paramVarianceSign)
val instanceTypes = tparams.lazyZip(variances).map((tparam, variance) =>
TypeComparer.instanceType(tparam, fromBelow = variance < 0))
resType.substParams(poly, instanceTypes)
instantiate(using ctx.fresh.setExploreTyperState().setOwner(caseClass))
instantiate(using ctx.fresh.setExploreTyperState().setOwner(childClass))
case _ =>
caseClass.typeRef
childClass.typeRef
case child => child.termRef
end solve

Expand Down
13 changes: 13 additions & 0 deletions tests/i9276.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import scala.deriving.*

sealed trait A

case class C() extends A

sealed trait B extends A

case class D() extends B

@main def Test =
summon[Mirror.Of[A]]
summon[Mirror.Of[B]]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we maybe add another test like the following?

val mirrorA = summon[Mirror.Of[A]]
summon[mirrorA.MirroredElemTypes <:< (C *: B *: EmptyTuple)]