From e0ff75d7e3d609087990f77f5f1046d34ee5bb7e Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Tue, 22 Feb 2022 20:21:35 +0100 Subject: [PATCH] Properly map children of mapped classes If sealed classes are mapped in TypeTreeMap or mapSymbols, their children have to be mapped accordingly. --- compiler/src/dotty/tools/dotc/core/Symbols.scala | 10 +++++++++- .../dotty/tools/dotc/printing/RefinedPrinter.scala | 2 +- .../tools/dotc/transform/SyntheticMembers.scala | 2 +- tests/pos/i12508c.scala | 12 ++++++++++++ 4 files changed, 23 insertions(+), 3 deletions(-) create mode 100644 tests/pos/i12508c.scala diff --git a/compiler/src/dotty/tools/dotc/core/Symbols.scala b/compiler/src/dotty/tools/dotc/core/Symbols.scala index 7f0969d55f07..93255f8d757d 100644 --- a/compiler/src/dotty/tools/dotc/core/Symbols.scala +++ b/compiler/src/dotty/tools/dotc/core/Symbols.scala @@ -826,11 +826,19 @@ object Symbols { copy.info = completer copy.denot match case cd: ClassDenotation => - cd.registeredCompanion = cd.unforcedRegisteredCompanion.subst(originals, copies) + cd.registeredCompanion = original.registeredCompanion.subst(originals, copies) case _ => } copies.foreach(_.ensureCompleted()) // avoid memory leak + + // Update Child annotations of classes encountered previously to new values + // if some child is among the mapped symbols + for orig <- ttmap1.substFrom do + if orig.is(Sealed) && orig.children.exists(originals.contains) then + val sealedCopy = orig.subst(ttmap1.substFrom, ttmap1.substTo) + sealedCopy.annotations = sealedCopy.annotations.mapConserve(ttmap1.apply) + copies } diff --git a/compiler/src/dotty/tools/dotc/printing/RefinedPrinter.scala b/compiler/src/dotty/tools/dotc/printing/RefinedPrinter.scala index cf5942a178f0..23c7f3b0e3e0 100644 --- a/compiler/src/dotty/tools/dotc/printing/RefinedPrinter.scala +++ b/compiler/src/dotty/tools/dotc/printing/RefinedPrinter.scala @@ -1040,7 +1040,7 @@ class RefinedPrinter(_ctx: Context) extends PlainPrinter(_ctx) { else if (sym.is(ModuleClass) && sym.isPackageObject && sym.name.stripModuleClassSuffix == tpnme.PACKAGE) nameString(sym.owner.name) else if (sym.is(ModuleClass)) - nameString(sym.name.stripModuleClassSuffix) + nameString(sym.name.stripModuleClassSuffix) + idString(sym) else if (hasMeaninglessName(sym)) simpleNameString(sym.owner) + idString(sym) else diff --git a/compiler/src/dotty/tools/dotc/transform/SyntheticMembers.scala b/compiler/src/dotty/tools/dotc/transform/SyntheticMembers.scala index 3a94a78b3d8e..eb6fc2feff7e 100644 --- a/compiler/src/dotty/tools/dotc/transform/SyntheticMembers.scala +++ b/compiler/src/dotty/tools/dotc/transform/SyntheticMembers.scala @@ -140,7 +140,7 @@ class SyntheticMembers(thisPhase: DenotTransformer) { val parentEnum = vdef.owner.companionClass val children = parentEnum.children.zipWithIndex val candidate: Option[Int] = children.collectFirst { case (child, idx) if child == vdef => idx } - assert(candidate.isDefined, i"could not find child for $vdef") + assert(candidate.isDefined, i"could not find child for $vdef in ${parentEnum.children}%, % of $parentEnum") Literal(Constant(candidate.get)) def toStringBody(vrefss: List[List[Tree]]): Tree = diff --git a/tests/pos/i12508c.scala b/tests/pos/i12508c.scala new file mode 100644 index 000000000000..97c81cd61fcd --- /dev/null +++ b/tests/pos/i12508c.scala @@ -0,0 +1,12 @@ +def fun(a: Any, b: Any = 2): Any = ??? + +def test = + fun( + b = println(1), + a = { + enum Option[+X]: + case Some(x: X) + case None + if ??? then Option.Some(1) else Option.None + } + ) \ No newline at end of file