Skip to content

Commit ba0d1ec

Browse files
committed
remove prefix splice in companionref
1 parent 57cde46 commit ba0d1ec

File tree

6 files changed

+43
-17
lines changed

6 files changed

+43
-17
lines changed

compiler/src/dotty/tools/dotc/core/TypeOps.scala

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -874,6 +874,10 @@ object TypeOps:
874874
if term.widen.classSymbol eq cls then Some(pre)
875875
else loopThisType(cls, term.prefix)
876876

877+
case supTpe: SuperType =>
878+
if supTpe.thistpe.classSymbol.isSubClass(cls) then Some(pre)
879+
else None
880+
877881
case _ => None
878882

879883
end PrefixSplice

compiler/src/dotty/tools/dotc/transform/TypeUtils.scala

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,11 @@ object TypeUtils {
9292
val r2 = tp2.mirrorCompanionRef
9393
assert(r1.symbol == r2.symbol, em"mirrorCompanionRef mismatch for $self: $r1, $r2 did not have the same symbol")
9494
r1
95+
case AndType(tp1, tp2) =>
96+
val c1 = tp1.classSymbol
97+
val c2 = tp2.classSymbol
98+
if c1.isSubClass(c2) then tp1.mirrorCompanionRef
99+
else tp2.mirrorCompanionRef // precondition: the parts of the AndType have already been checked to be non-overlapping
95100
case self @ TypeRef(prefix, _) if self.symbol.isClass =>
96101
prefix.select(self.symbol.companionModule).asInstanceOf[TermRef]
97102
case self: TypeProxy =>

compiler/src/dotty/tools/dotc/typer/Synthesizer.scala

Lines changed: 4 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -250,11 +250,8 @@ class Synthesizer(typer: Typer)(using @constructorOnly c: Context):
250250
.refinedWith(tpnme.MirroredLabel, TypeAlias(ConstantType(Constant(label.toString))))
251251

252252
/** A path referencing the companion of class type `clsType` */
253-
private def companionPath(mirroredType: Type, cls: Symbol, pre: Type, span: Span)(using Context) =
254-
val clsType =
255-
// ok to assume healPrefix will succeed because `cls` and `pre` derive from the same type.
256-
// TODO: will fail, e.g. for value alias to case object - we still need to support `scala.package.None.type`
257-
TypeOps.healPrefix(mirroredType.mirrorCompanionRef, pre).toOption.get
253+
private def companionPath(mirroredType: Type, cls: Symbol, span: Span)(using Context) =
254+
val clsType = mirroredType.mirrorCompanionRef
258255
val ref = pathFor(clsType)
259256
assert(ref.symbol.is(Module) && (cls.is(ModuleClass) || (ref.symbol.companionClass == cls)))
260257
ref.withSpan(span)
@@ -328,7 +325,7 @@ class Synthesizer(typer: Typer)(using @constructorOnly c: Context):
328325
if (genAnonyousMirror(cls))
329326
// TODO: scan for problematic prefix
330327
anonymousMirror(monoType, mirroredType, ExtendsProductMirror, pre, span)
331-
else companionPath(mirroredType, cls, pre, span)
328+
else companionPath(mirroredType, cls, span)
332329
withNoErrors(mirrorRef.cast(mirrorType))
333330
end makeProductMirror
334331

@@ -342,10 +339,6 @@ class Synthesizer(typer: Typer)(using @constructorOnly c: Context):
342339
i"$cls is not a generic product $reason"
343340
end getError
344341

345-
if pre == NoPrefix then
346-
report.error(i"$mirroredType is not a valid prod type, because it does not have a prefix")
347-
else
348-
report.warning(i"prod mirror with $mirroredType: pre $pre")
349342
mirroredType match
350343
case AndType(tp1, tp2) =>
351344
orElse(productMirror(tp1, formal, span), productMirror(tp2, formal, span))
@@ -375,10 +368,6 @@ class Synthesizer(typer: Typer)(using @constructorOnly c: Context):
375368
val pre = TypeOps.extractPrefix(mirroredType) match
376369
case pre if pre.exists => pre
377370
case _ => return EmptyTreeNoError
378-
// if pre == NoPrefix then
379-
// report.error(i"$mirroredType is not a valid sum type, because it does not have a prefix")
380-
// else
381-
// report.warning(i"sum mirror with $mirroredType: pre $pre")
382371
val cls = mirroredType.classSymbol
383372
val useCompanion = cls.useCompanionAsSumMirror
384373
val declScope = if useCompanion then cls.linkedClass else ctx.owner
@@ -456,7 +445,7 @@ class Synthesizer(typer: Typer)(using @constructorOnly c: Context):
456445
.refinedWith(tpnme.MirroredElemTypes, TypeAlias(elemsType))
457446
.refinedWith(tpnme.MirroredElemLabels, TypeAlias(TypeOps.nestedPairs(elemLabels)))
458447
val mirrorRef =
459-
if useCompanion then companionPath(mirroredType, cls, pre, span)
448+
if useCompanion then companionPath(mirroredType, cls, span)
460449
else anonymousMirror(monoType, mirroredType, ExtendsSumMirror, pre, span)
461450
withNoErrors(mirrorRef.cast(mirrorType))
462451
else if !cls.isGenericSum(pre, if useCompanion then cls.linkedClass else ctx.owner) then

tests/run/anon-mirror-gen-dep-i.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ class Outer {
99
case class Seed() extends Item
1010
}
1111

12-
lazy val o = new Outer() // infinite init
12+
final lazy val o = new Outer() // infinite init
1313

1414
def hello: Unit = {
1515

tests/run/anon-mirror-gen-dep-j.scala

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import scala.deriving.Mirror
2+
import scala.CanEqual.derived
3+
4+
class Outer {
5+
6+
sealed trait Item
7+
case class Fruit(seed: Seed) extends Item
8+
case class Seed() extends Item
9+
10+
final lazy val o = new Outer() // infinite init
11+
12+
def hello: Unit = {
13+
14+
val mFruit = summon[Mirror.Of[o.Item & o.Fruit]]
15+
type derivedSeed = Tuple.Head[mFruit.MirroredElemTypes]
16+
val mSeed = summon[Mirror.Of[derivedSeed]]
17+
18+
assert(mFruit.fromProduct(Tuple(o.Seed())) == o.Fruit(o.Seed()))
19+
assert(mSeed.fromProduct(EmptyTuple) == o.Seed()) // careful to ensure that correct outer is captured
20+
}
21+
22+
}
23+
24+
@main def Test = {
25+
val o = new Outer()
26+
o.hello
27+
}

tests/neg/anon-mirror-gen-super-a.scala renamed to tests/run/anon-mirror-gen-super-a.scala

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,8 @@ import scala.deriving.Mirror
88
}
99

1010
class Bar extends Foo {
11-
summon[Mirror.Of[Bar.super.foo.type]] //
11+
val mQux = summon[Mirror.Of[Bar.super.foo.type]]
12+
assert(mQux.fromProduct(EmptyTuple) == Qux)
1213
}
1314

1415
}

0 commit comments

Comments
 (0)