@@ -249,7 +249,7 @@ class Synthesizer(typer: Typer)(using @constructorOnly c: Context):
249
249
250
250
/** A path referencing the companion of class type `clsType` */
251
251
private def companionPath (clsType : Type , span : Span )(using Context ) =
252
- val ref = pathFor(clsType.companionRef )
252
+ val ref = pathFor(clsType.mirrorCompanionRef )
253
253
assert(ref.symbol.is(Module ) && (clsType.classSymbol.is(ModuleClass ) || (ref.symbol.companionClass == clsType.classSymbol)))
254
254
ref.withSpan(span)
255
255
@@ -275,6 +275,36 @@ class Synthesizer(typer: Typer)(using @constructorOnly c: Context):
275
275
monoMap(mirroredType.resultType)
276
276
277
277
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 : HKTypeLambda if tp.resultType.isInstanceOf [HKTypeLambda ] => false
282
+ case tp : TypeProxy => acceptable(tp.underlying, cls)
283
+ case OrType (tp1, tp2) => acceptable(tp1, cls) && acceptable(tp2, cls)
284
+ case _ => tp.classSymbol eq cls
285
+
286
+ def makeProductMirror (cls : Symbol ): Tree =
287
+ val accessors = cls.caseAccessors.filterNot(_.isAllOf(PrivateLocal ))
288
+ val elemLabels = accessors.map(acc => ConstantType (Constant (acc.name.toString)))
289
+ val nestedPairs = TypeOps .nestedPairs(accessors.map(mirroredType.resultType.memberInfo(_).widenExpr))
290
+ val (monoType, elemsType) = mirroredType match
291
+ case mirroredType : HKTypeLambda =>
292
+ (mkMirroredMonoType(mirroredType), mirroredType.derivedLambdaType(resType = nestedPairs))
293
+ case _ =>
294
+ (mirroredType, nestedPairs)
295
+ val elemsLabels = TypeOps .nestedPairs(elemLabels)
296
+ checkRefinement(formal, tpnme.MirroredElemTypes , elemsType, span)
297
+ checkRefinement(formal, tpnme.MirroredElemLabels , elemsLabels, span)
298
+ val mirrorType =
299
+ mirrorCore(defn.Mirror_ProductClass , monoType, mirroredType, cls.name, formal)
300
+ .refinedWith(tpnme.MirroredElemTypes , TypeAlias (elemsType))
301
+ .refinedWith(tpnme.MirroredElemLabels , TypeAlias (elemsLabels))
302
+ val mirrorRef =
303
+ if (cls.is(Scala2x ) || cls.linkedClass.is(Case )) anonymousMirror(monoType, ExtendsProductMirror , span)
304
+ else companionPath(mirroredType, span)
305
+ mirrorRef.cast(mirrorType)
306
+ end makeProductMirror
307
+
278
308
mirroredType match
279
309
case AndType (tp1, tp2) =>
280
310
productMirror(tp1, formal, span).orElse(productMirror(tp2, formal, span))
@@ -289,28 +319,10 @@ class Synthesizer(typer: Typer)(using @constructorOnly c: Context):
289
319
else
290
320
val mirrorType = mirrorCore(defn.Mirror_SingletonClass , mirroredType, mirroredType, module.name, formal)
291
321
modulePath.cast(mirrorType)
292
- else if mirroredType.classSymbol.isGenericProduct then
322
+ else
293
323
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
324
+ if acceptable(mirroredType, cls) && cls.isGenericProduct then makeProductMirror(cls)
325
+ else EmptyTree
314
326
end productMirror
315
327
316
328
private def sumMirror (mirroredType : Type , formal : Type , span : Span )(using Context ): Tree =
@@ -319,6 +331,7 @@ class Synthesizer(typer: Typer)(using @constructorOnly c: Context):
319
331
320
332
def acceptable (tp : Type ): Boolean = tp match
321
333
case tp : TermRef => false
334
+ case tp : HKTypeLambda if tp.resultType.isInstanceOf [HKTypeLambda ] => false
322
335
case tp : TypeProxy => acceptable(tp.underlying)
323
336
case OrType (tp1, tp2) => acceptable(tp1) && acceptable(tp2)
324
337
case _ => tp.classSymbol eq cls
0 commit comments