@@ -283,6 +283,22 @@ class Synthesizer(typer: Typer)(using @constructorOnly c: Context):
283
283
case OrType (tp1, tp2) => acceptable(tp1, cls) && acceptable(tp2, cls)
284
284
case _ => tp.classSymbol eq cls
285
285
286
+ /** for a case class, if it will have an anonymous mirror,
287
+ * check that its constructor can be accessed
288
+ * from the calling scope.
289
+ */
290
+ def canAccessCtor (cls : Symbol ): Boolean =
291
+ ! genAnonyousMirror(cls) || {
292
+ def isAccessible (sym : Symbol ): Boolean = ctx.owner.isContainedIn(sym)
293
+ def isSub (sym : Symbol ): Boolean = ctx.owner.ownersIterator.exists(_.derivesFrom(sym))
294
+ val ctor = cls.primaryConstructor
295
+ (! ctor.isOneOf(Private | Protected ) || isSub(cls)) // we cant access the ctor because we do not extend cls
296
+ && (! ctor.privateWithin.exists || isAccessible(ctor.privateWithin)) // check scope is compatible
297
+ }
298
+
299
+ def genAnonyousMirror (cls : Symbol ): Boolean =
300
+ cls.is(Scala2x ) || cls.linkedClass.is(Case )
301
+
286
302
def makeProductMirror (cls : Symbol ): Tree =
287
303
val accessors = cls.caseAccessors.filterNot(_.isAllOf(PrivateLocal ))
288
304
val elemLabels = accessors.map(acc => ConstantType (Constant (acc.name.toString)))
@@ -300,7 +316,7 @@ class Synthesizer(typer: Typer)(using @constructorOnly c: Context):
300
316
.refinedWith(tpnme.MirroredElemTypes , TypeAlias (elemsType))
301
317
.refinedWith(tpnme.MirroredElemLabels , TypeAlias (elemsLabels))
302
318
val mirrorRef =
303
- if (cls.is( Scala2x ) || cls.linkedClass.is( Case )) anonymousMirror(monoType, ExtendsProductMirror , span)
319
+ if (genAnonyousMirror( cls)) anonymousMirror(monoType, ExtendsProductMirror , span)
304
320
else companionPath(mirroredType, span)
305
321
mirrorRef.cast(mirrorType)
306
322
end makeProductMirror
@@ -321,8 +337,13 @@ class Synthesizer(typer: Typer)(using @constructorOnly c: Context):
321
337
modulePath.cast(mirrorType)
322
338
else
323
339
val cls = mirroredType.classSymbol
324
- if acceptable(mirroredType, cls) && cls.isGenericProduct then makeProductMirror(cls)
325
- else EmptyTree
340
+ if acceptable(mirroredType, cls)
341
+ && cls.isGenericProduct
342
+ && canAccessCtor(cls)
343
+ then
344
+ makeProductMirror(cls)
345
+ else
346
+ EmptyTree
326
347
end productMirror
327
348
328
349
private def sumMirror (mirroredType : Type , formal : Type , span : Span )(using Context ): Tree =
0 commit comments