@@ -26,7 +26,7 @@ class Synthesizer(typer: Typer)(using @constructorOnly c: Context):
26
26
/** Handlers to synthesize implicits for special types */
27
27
type SpecialHandler = (Type , Span ) => Context ?=> TreeWithErrors
28
28
private type SpecialHandlers = List [(ClassSymbol , SpecialHandler )]
29
-
29
+
30
30
val synthesizedClassTag : SpecialHandler = (formal, span) =>
31
31
formal.argInfos match
32
32
case arg :: Nil =>
@@ -285,22 +285,6 @@ class Synthesizer(typer: Typer)(using @constructorOnly c: Context):
285
285
case OrType (tp1, tp2) => acceptable(tp1, cls) && acceptable(tp2, cls)
286
286
case _ => tp.classSymbol eq cls
287
287
288
- /** for a case class, if it will have an anonymous mirror,
289
- * check that its constructor can be accessed
290
- * from the calling scope.
291
- */
292
- def canAccessCtor (cls : Symbol ): Boolean =
293
- ! genAnonyousMirror(cls) || {
294
- def isAccessible (sym : Symbol ): Boolean = ctx.owner.isContainedIn(sym)
295
- def isSub (sym : Symbol ): Boolean = ctx.owner.ownersIterator.exists(_.derivesFrom(sym))
296
- val ctor = cls.primaryConstructor
297
- (! ctor.isOneOf(Private | Protected ) || isSub(cls)) // we cant access the ctor because we do not extend cls
298
- && (! ctor.privateWithin.exists || isAccessible(ctor.privateWithin)) // check scope is compatible
299
- }
300
-
301
- def genAnonyousMirror (cls : Symbol ): Boolean =
302
- cls.is(Scala2x ) || cls.linkedClass.is(Case )
303
-
304
288
def makeProductMirror (cls : Symbol ): TreeWithErrors =
305
289
val accessors = cls.caseAccessors.filterNot(_.isAllOf(PrivateLocal ))
306
290
val elemLabels = accessors.map(acc => ConstantType (Constant (acc.name.toString)))
@@ -318,21 +302,11 @@ class Synthesizer(typer: Typer)(using @constructorOnly c: Context):
318
302
.refinedWith(tpnme.MirroredElemTypes , TypeAlias (elemsType))
319
303
.refinedWith(tpnme.MirroredElemLabels , TypeAlias (elemsLabels))
320
304
val mirrorRef =
321
- if (genAnonyousMirror( cls)) anonymousMirror(monoType, ExtendsProductMirror , span)
322
- else companionPath(mirroredType , span)
305
+ if cls.useCompanionAsProductMirror then companionPath(mirroredType , span)
306
+ else anonymousMirror(monoType, ExtendsProductMirror , span)
323
307
withNoErrors(mirrorRef.cast(mirrorType))
324
308
end makeProductMirror
325
309
326
- def getError (cls : Symbol ): String =
327
- val reason = if ! cls.isGenericProduct then
328
- i " because ${cls.whyNotGenericProduct}"
329
- else if ! canAccessCtor(cls) then
330
- i " because the constructor of $cls is innaccessible from the calling scope. "
331
- else
332
- " "
333
- i " $cls is not a generic product $reason"
334
- end getError
335
-
336
310
mirroredType match
337
311
case AndType (tp1, tp2) =>
338
312
orElse(productMirror(tp1, formal, span), productMirror(tp2, formal, span))
@@ -349,21 +323,19 @@ class Synthesizer(typer: Typer)(using @constructorOnly c: Context):
349
323
withNoErrors(modulePath.cast(mirrorType))
350
324
else
351
325
val cls = mirroredType.classSymbol
352
- if acceptable(mirroredType, cls)
353
- && cls.isGenericProduct
354
- && canAccessCtor(cls)
355
- then
326
+ val clsIsGenericProduct = cls.isGenericProduct
327
+ if acceptable(mirroredType, cls) && clsIsGenericProduct then
356
328
makeProductMirror(cls)
329
+ else if ! clsIsGenericProduct then
330
+ (EmptyTree , List (i " $cls is not a generic product because ${cls.whyNotGenericProduct}" ))
357
331
else
358
- ( EmptyTree , List (getError(cls)))
332
+ EmptyTreeNoError
359
333
end productMirror
360
334
361
335
private def sumMirror (mirroredType : Type , formal : Type , span : Span )(using Context ): TreeWithErrors =
362
336
363
337
val cls = mirroredType.classSymbol
364
- val useCompanion = cls.useCompanionAsSumMirror
365
- val declScope = if useCompanion then cls.linkedClass else ctx.owner
366
- val clsIsGenericSum = cls.isGenericSum(declScope)
338
+ val clsIsGenericSum = cls.isGenericSum
367
339
368
340
def acceptable (tp : Type ): Boolean = tp match
369
341
case tp : TermRef => false
@@ -423,12 +395,12 @@ class Synthesizer(typer: Typer)(using @constructorOnly c: Context):
423
395
.refinedWith(tpnme.MirroredElemTypes , TypeAlias (elemsType))
424
396
.refinedWith(tpnme.MirroredElemLabels , TypeAlias (TypeOps .nestedPairs(elemLabels)))
425
397
val mirrorRef =
426
- if useCompanion then companionPath(mirroredType, span)
398
+ if cls.useCompanionAsSumMirror then companionPath(mirroredType, span)
427
399
else anonymousMirror(monoType, ExtendsSumMirror , span)
428
400
withNoErrors(mirrorRef.cast(mirrorType))
429
401
else if ! clsIsGenericSum then
430
- (EmptyTree , List (i " $cls is not a generic sum because ${cls.whyNotGenericSum(declScope) }" ))
431
- else
402
+ (EmptyTree , List (i " $cls is not a generic sum because ${cls.whyNotGenericSum}" ))
403
+ else
432
404
EmptyTreeNoError
433
405
end sumMirror
434
406
@@ -595,7 +567,7 @@ class Synthesizer(typer: Typer)(using @constructorOnly c: Context):
595
567
tp.baseType(cls)
596
568
val base = baseWithRefinements(formal)
597
569
val result =
598
- if (base <:< formal.widenExpr)
570
+ if (base <:< formal.widenExpr)
599
571
// With the subtype test we enforce that the searched type `formal` is of the right form
600
572
handler(base, span)
601
573
else EmptyTreeNoError
@@ -609,19 +581,19 @@ end Synthesizer
609
581
610
582
object Synthesizer :
611
583
612
- /** Tuple used to store the synthesis result with a list of errors. */
584
+ /** Tuple used to store the synthesis result with a list of errors. */
613
585
type TreeWithErrors = (Tree , List [String ])
614
586
private def withNoErrors (tree : Tree ): TreeWithErrors = (tree, List .empty)
615
587
616
588
private val EmptyTreeNoError : TreeWithErrors = withNoErrors(EmptyTree )
617
589
618
590
private def orElse (treeWithErrors1 : TreeWithErrors , treeWithErrors2 : => TreeWithErrors ): TreeWithErrors = treeWithErrors1 match
619
- case (tree, errors) if tree eq genericEmptyTree =>
591
+ case (tree, errors) if tree eq genericEmptyTree =>
620
592
val (tree2, errors2) = treeWithErrors2
621
593
(tree2, errors ::: errors2)
622
594
case _ => treeWithErrors1
623
595
624
- private def clearErrorsIfNotEmpty (treeWithErrors : TreeWithErrors ) = treeWithErrors match
596
+ private def clearErrorsIfNotEmpty (treeWithErrors : TreeWithErrors ) = treeWithErrors match
625
597
case (tree, _) if tree eq genericEmptyTree => treeWithErrors
626
598
case (tree, _) => withNoErrors(tree)
627
599
0 commit comments