Skip to content

Commit 9e7b57f

Browse files
authored
Merge pull request #14100 from dotty-staging/backport-14035
2 parents 3c3329b + f1ba8e2 commit 9e7b57f

File tree

7 files changed

+50
-4
lines changed

7 files changed

+50
-4
lines changed

compiler/src/dotty/tools/dotc/transform/SymUtils.scala

+15-3
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,19 @@ object SymUtils:
112112
self.isCoDefinedGiven(res.typeSymbol)
113113
self.isAllOf(Given | Method) && isCodefined(self.info)
114114

115-
def useCompanionAsMirror(using Context): Boolean = self.linkedClass.exists && !self.is(Scala2x)
115+
def useCompanionAsSumMirror(using Context): Boolean =
116+
self.linkedClass.exists
117+
&& !self.is(Scala2x)
118+
&& (
119+
// If the sum type is compiled from source, and `self` is a "generic sum"
120+
// then its companion object will become a sum mirror in `posttyper`. (This method
121+
// can be called from `typer` when summoning a Mirror.)
122+
// However if `self` is from a prior run then we should check that its companion subclasses `Mirror.Sum`.
123+
// e.g. before Scala 3.1, hierarchical sum types were not considered "generic sums", so their
124+
// companion would not cache the mirror. Companions from TASTy will already be typed as `Mirror.Sum`.
125+
self.isDefinedInCurrentRun
126+
|| self.linkedClass.isSubClass(defn.Mirror_SumClass)
127+
)
116128

117129
/** Is this a sealed class or trait for which a sum mirror is generated?
118130
* It must satisfy the following conditions:
@@ -129,7 +141,7 @@ object SymUtils:
129141
s"it is not an abstract class"
130142
else {
131143
val children = self.children
132-
val companionMirror = self.useCompanionAsMirror
144+
val companionMirror = self.useCompanionAsSumMirror
133145
assert(!(companionMirror && (declScope ne self.linkedClass)))
134146
def problem(child: Symbol) = {
135147

@@ -144,7 +156,7 @@ object SymUtils:
144156
val s = child.whyNotGenericProduct
145157
if (s.isEmpty) s
146158
else if (child.is(Sealed)) {
147-
val s = child.whyNotGenericSum(if child.useCompanionAsMirror then child.linkedClass else ctx.owner)
159+
val s = child.whyNotGenericSum(if child.useCompanionAsSumMirror then child.linkedClass else ctx.owner)
148160
if (s.isEmpty) s
149161
else i"its child $child is not a generic sum because $s"
150162
} else i"its child $child is not a generic product because $s"

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

+1-1
Original file line numberDiff line numberDiff line change
@@ -279,7 +279,7 @@ class Synthesizer(typer: Typer)(using @constructorOnly c: Context):
279279

280280
private def sumMirror(mirroredType: Type, formal: Type, span: Span)(using Context): Tree =
281281
val cls = mirroredType.classSymbol
282-
val useCompanion = cls.useCompanionAsMirror
282+
val useCompanion = cls.useCompanionAsSumMirror
283283

284284
if cls.isGenericSum(if useCompanion then cls.linkedClass else ctx.owner) then
285285
val elemLabels = cls.children.map(c => ConstantType(Constant(c.name.toString)))
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
package app
2+
3+
import scala.deriving.Mirror
4+
5+
object Main:
6+
def main(args: Array[String]): Unit =
7+
val mirrorTop = summon[Mirror.SumOf[lib.Top]]
8+
assert(mirrorTop.ordinal(lib.Middle()) == 0)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
lazy val lib = project.in(file("lib"))
2+
.settings(
3+
scalaVersion := "3.0.2"
4+
)
5+
6+
lazy val app = project.in(file("app"))
7+
.dependsOn(lib)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
package lib
2+
3+
sealed trait Top
4+
object Top // companion is necessary
5+
6+
case class Middle() extends Top with Bottom
7+
sealed trait Bottom extends Top
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import sbt._
2+
import Keys._
3+
4+
object DottyInjectedPlugin extends AutoPlugin {
5+
override def requires = plugins.JvmPlugin
6+
override def trigger = allRequirements
7+
8+
override val projectSettings = Seq(
9+
scalaVersion := sys.props("plugin.scalaVersion")
10+
)
11+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
> app/run

0 commit comments

Comments
 (0)