Skip to content

Commit a41c598

Browse files
committed
warn when anonymous mirror.sum generated
1 parent 95dddfd commit a41c598

File tree

4 files changed

+35
-2
lines changed

4 files changed

+35
-2
lines changed

compiler/src/dotty/tools/dotc/reporting/ErrorMessageID.scala

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -169,7 +169,8 @@ enum ErrorMessageID extends java.lang.Enum[ErrorMessageID] {
169169
InvalidReferenceInImplicitNotFoundAnnotationID,
170170
TraitMayNotDefineNativeMethodID,
171171
JavaEnumParentArgsID,
172-
AlreadyDefinedID
172+
AlreadyDefinedID,
173+
MissingCompanionForMirrorID
173174

174175
def errorNumber = ordinal - 2
175176
}

compiler/src/dotty/tools/dotc/reporting/messages.scala

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -235,6 +235,23 @@ import transform.SymUtils._
235235
}
236236
}
237237

238+
239+
240+
class MissingCompanionForMirror(cls: Symbol, isSum: Boolean)(using Context)
241+
extends DeclarationMsg(MissingCompanionForMirrorID) {
242+
def msg = em"""|an anonymous ${if isSum then "sum" else "product"} type Mirror will be generated for $cls,
243+
|which does not declare a companion object.""".stripMargin
244+
def explain =
245+
em"""|$cls is a type declared without a companion object.
246+
|This means that summoning its Mirror from the context
247+
|will synthesize a new anonymous instance at each callsite.
248+
|In general, a class under the control of the Scala compiler
249+
|will have its Mirror cached in its companion object,
250+
|if one exists, leading to fewer allocations.
251+
|Adding a deriving clause to $cls will create a
252+
|companion object even if one is not explicitly declared.""".stripMargin
253+
}
254+
238255
class TypeMismatch(found: Type, expected: Type, addenda: => String*)(using Context)
239256
extends TypeMismatchMsg(TypeMismatchID):
240257

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

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -321,7 +321,10 @@ class Synthesizer(typer: Typer)(using @constructorOnly c: Context):
321321
.refinedWith(tpnme.MirroredElemLabels, TypeAlias(TypeOps.nestedPairs(elemLabels)))
322322
val mirrorRef =
323323
if useCompanion then companionPath(mirroredType, span)
324-
else anonymousMirror(monoType, ExtendsSumMirror, span)
324+
else
325+
if !cls.is(Scala2x) then
326+
report.warning(new reporting.MissingCompanionForMirror(cls, isSum = true), ctx.source.atSpan(span))
327+
anonymousMirror(monoType, ExtendsSumMirror, span)
325328
mirrorRef.cast(mirrorType)
326329
else EmptyTree
327330
end sumMirror
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
class Test {
2+
3+
sealed trait Parent
4+
case class Foo(x: Int, y: Int, s: String) extends Parent
5+
case class Bar(x: Int, y: Int) extends Parent
6+
7+
println(summon[deriving.Mirror.Of[Parent]]) // error: anonymous Mirror generated.
8+
}
9+
10+
class Test2 {
11+
println(summon[deriving.Mirror.Of[List[Int]]]) // ok: List is Scala 2 defined
12+
}

0 commit comments

Comments
 (0)