@@ -249,7 +249,7 @@ class Synthesizer(typer: Typer)(using @constructorOnly c: Context):
249249
250250 /** A path referencing the companion of class type `clsType` */
251251 private def companionPath (clsType : Type , span : Span )(using Context ) =
252- val ref = pathFor(clsType.companionRef )
252+ val ref = pathFor(clsType.mirrorCompanionRef )
253253 assert(ref.symbol.is(Module ) && (clsType.classSymbol.is(ModuleClass ) || (ref.symbol.companionClass == clsType.classSymbol)))
254254 ref.withSpan(span)
255255
@@ -275,6 +275,35 @@ class Synthesizer(typer: Typer)(using @constructorOnly c: Context):
275275 monoMap(mirroredType.resultType)
276276
277277 private def productMirror (mirroredType : Type , formal : Type , span : Span )(using Context ): Tree =
278+
279+ /** do all parts match the class symbol? */
280+ def acceptable (tp : Type , cls : Symbol ): Boolean = tp match
281+ case tp : TypeProxy => acceptable(tp.underlying, cls)
282+ case OrType (tp1, tp2) => acceptable(tp1, cls) && acceptable(tp2, cls)
283+ case _ => tp.classSymbol eq cls
284+
285+ def makeProductMirror (cls : Symbol ): Tree =
286+ val accessors = cls.caseAccessors.filterNot(_.isAllOf(PrivateLocal ))
287+ val elemLabels = accessors.map(acc => ConstantType (Constant (acc.name.toString)))
288+ val nestedPairs = TypeOps .nestedPairs(accessors.map(mirroredType.resultType.memberInfo(_).widenExpr))
289+ val (monoType, elemsType) = mirroredType match
290+ case mirroredType : HKTypeLambda =>
291+ (mkMirroredMonoType(mirroredType), mirroredType.derivedLambdaType(resType = nestedPairs))
292+ case _ =>
293+ (mirroredType, nestedPairs)
294+ val elemsLabels = TypeOps .nestedPairs(elemLabels)
295+ checkRefinement(formal, tpnme.MirroredElemTypes , elemsType, span)
296+ checkRefinement(formal, tpnme.MirroredElemLabels , elemsLabels, span)
297+ val mirrorType =
298+ mirrorCore(defn.Mirror_ProductClass , monoType, mirroredType, cls.name, formal)
299+ .refinedWith(tpnme.MirroredElemTypes , TypeAlias (elemsType))
300+ .refinedWith(tpnme.MirroredElemLabels , TypeAlias (elemsLabels))
301+ val mirrorRef =
302+ if (cls.is(Scala2x ) || cls.linkedClass.is(Case )) anonymousMirror(monoType, ExtendsProductMirror , span)
303+ else companionPath(mirroredType, span)
304+ mirrorRef.cast(mirrorType)
305+ end makeProductMirror
306+
278307 mirroredType match
279308 case AndType (tp1, tp2) =>
280309 productMirror(tp1, formal, span).orElse(productMirror(tp2, formal, span))
@@ -289,28 +318,10 @@ class Synthesizer(typer: Typer)(using @constructorOnly c: Context):
289318 else
290319 val mirrorType = mirrorCore(defn.Mirror_SingletonClass , mirroredType, mirroredType, module.name, formal)
291320 modulePath.cast(mirrorType)
292- else if mirroredType.classSymbol.isGenericProduct then
321+ else
293322 val cls = mirroredType.classSymbol
294- val accessors = cls.caseAccessors.filterNot(_.isAllOf(PrivateLocal ))
295- val elemLabels = accessors.map(acc => ConstantType (Constant (acc.name.toString)))
296- val nestedPairs = TypeOps .nestedPairs(accessors.map(mirroredType.resultType.memberInfo(_).widenExpr))
297- val (monoType, elemsType) = mirroredType match
298- case mirroredType : HKTypeLambda =>
299- (mkMirroredMonoType(mirroredType), mirroredType.derivedLambdaType(resType = nestedPairs))
300- case _ =>
301- (mirroredType, nestedPairs)
302- val elemsLabels = TypeOps .nestedPairs(elemLabels)
303- checkRefinement(formal, tpnme.MirroredElemTypes , elemsType, span)
304- checkRefinement(formal, tpnme.MirroredElemLabels , elemsLabels, span)
305- val mirrorType =
306- mirrorCore(defn.Mirror_ProductClass , monoType, mirroredType, cls.name, formal)
307- .refinedWith(tpnme.MirroredElemTypes , TypeAlias (elemsType))
308- .refinedWith(tpnme.MirroredElemLabels , TypeAlias (elemsLabels))
309- val mirrorRef =
310- if (cls.is(Scala2x ) || cls.linkedClass.is(Case )) anonymousMirror(monoType, ExtendsProductMirror , span)
311- else companionPath(mirroredType, span)
312- mirrorRef.cast(mirrorType)
313- else EmptyTree
323+ if acceptable(mirroredType, cls) && cls.isGenericProduct then makeProductMirror(cls)
324+ else EmptyTree
314325 end productMirror
315326
316327 private def sumMirror (mirroredType : Type , formal : Type , span : Span )(using Context ): Tree =
0 commit comments