@@ -283,6 +283,22 @@ class Synthesizer(typer: Typer)(using @constructorOnly c: Context):
283283 case OrType (tp1, tp2) => acceptable(tp1, cls) && acceptable(tp2, cls)
284284 case _ => tp.classSymbol eq cls
285285
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+
286302 def makeProductMirror (cls : Symbol ): Tree =
287303 val accessors = cls.caseAccessors.filterNot(_.isAllOf(PrivateLocal ))
288304 val elemLabels = accessors.map(acc => ConstantType (Constant (acc.name.toString)))
@@ -300,7 +316,7 @@ class Synthesizer(typer: Typer)(using @constructorOnly c: Context):
300316 .refinedWith(tpnme.MirroredElemTypes , TypeAlias (elemsType))
301317 .refinedWith(tpnme.MirroredElemLabels , TypeAlias (elemsLabels))
302318 val mirrorRef =
303- if (cls.is( Scala2x ) || cls.linkedClass.is( Case )) anonymousMirror(monoType, ExtendsProductMirror , span)
319+ if (genAnonyousMirror( cls)) anonymousMirror(monoType, ExtendsProductMirror , span)
304320 else companionPath(mirroredType, span)
305321 mirrorRef.cast(mirrorType)
306322 end makeProductMirror
@@ -321,8 +337,13 @@ class Synthesizer(typer: Typer)(using @constructorOnly c: Context):
321337 modulePath.cast(mirrorType)
322338 else
323339 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
326347 end productMirror
327348
328349 private def sumMirror (mirroredType : Type , formal : Type , span : Span )(using Context ): Tree =
0 commit comments