Skip to content

Commit 3c9f377

Browse files
committed
Fix #8203: handle intersection type in parent registration
An enum value may have the type `A & B`, in such cases we need to register for both `A` and `B`.
1 parent b0aac8c commit 3c9f377

File tree

2 files changed

+33
-17
lines changed

2 files changed

+33
-17
lines changed

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

Lines changed: 14 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -901,28 +901,25 @@ class Namer { typer: Typer =>
901901
def registerIfChild(denot: SymDenotation)(implicit ctx: Context): Unit = {
902902
val sym = denot.symbol
903903

904-
def register(child: Symbol, parent: Type) = {
905-
val cls = parent.classSymbol
906-
if (cls.is(Sealed))
907-
if ((child.isInaccessibleChildOf(cls) || child.isAnonymousClass) && !sym.hasAnonymousChild)
908-
addChild(cls, cls)
909-
else if (!cls.is(ChildrenQueried))
910-
addChild(cls, child)
904+
def register(child: Symbol, parentCls: ClassSymbol) = {
905+
if (parentCls.is(Sealed))
906+
if ((child.isInaccessibleChildOf(parentCls) || child.isAnonymousClass) && !sym.hasAnonymousChild)
907+
addChild(parentCls, parentCls)
908+
else if (!parentCls.is(ChildrenQueried))
909+
addChild(parentCls, child)
911910
else
912-
ctx.error(em"""children of $cls were already queried before $sym was discovered.
913-
|As a remedy, you could move $sym on the same nesting level as $cls.""",
911+
ctx.error(em"""children of $parentCls were already queried before $sym was discovered.
912+
|As a remedy, you could move $sym on the same nesting level as $parentCls.""",
914913
child.sourcePos)
915914
}
916915

917-
if (denot.isClass && !sym.isEnumAnonymClass && !sym.isRefinementClass)
918-
denot.asClass.classParents.foreach { parent =>
919-
val child = if (denot.is(Module)) denot.sourceModule else denot.symbol
920-
register(child, parent)
921-
}
922-
else if (denot.is(CaseVal, butNot = Method | Module)) {
916+
if denot.isClass && !sym.isEnumAnonymClass && !sym.isRefinementClass then
917+
val child = if (denot.is(Module)) denot.sourceModule else denot.symbol
918+
denot.asClass.classParents.foreach { parent => register(child, parent.classSymbol.asClass) }
919+
else if denot.is(CaseVal, butNot = Method | Module) then
923920
assert(denot.is(Enum), denot)
924-
register(denot.symbol, denot.info)
925-
}
921+
denot.info.classSymbols.foreach { parent => register(denot.symbol, parent) }
922+
end if
926923
}
927924

928925
/** Intentionally left without `implicit ctx` parameter. We need

tests/patmat/i8203.scala

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
sealed trait Pretty { self: Color => }
2+
sealed trait Dull { self: Color => }
3+
enum Color {
4+
case Pink extends Color with Pretty
5+
case Red extends Color with Dull
6+
}
7+
8+
def describe(c: Color) = c match {
9+
case Color.Pink => "Amazing!"
10+
case Color.Red => "Yawn..."
11+
}
12+
13+
def describe2(c: Pretty) = c match {
14+
case Color.Pink => "Amazing!"
15+
}
16+
17+
def describe3(c: Dull) = c match {
18+
case Color.Red => "Yawn..."
19+
}

0 commit comments

Comments
 (0)