diff --git a/compiler/src/dotty/tools/dotc/ast/TreeTypeMap.scala b/compiler/src/dotty/tools/dotc/ast/TreeTypeMap.scala index d38ce8ca6888..74da63f7d7da 100644 --- a/compiler/src/dotty/tools/dotc/ast/TreeTypeMap.scala +++ b/compiler/src/dotty/tools/dotc/ast/TreeTypeMap.scala @@ -204,11 +204,23 @@ class TreeTypeMap( lazy val origCls = mapped.zip(syms).filter(_._1.isClass).toMap mapped.filter(_.isClass).foldLeft(substMap) { (tmap, cls) => val origDcls = cls.info.decls.toList.filterNot(_.is(TypeParam)) - val mappedDcls = mapSymbols(origDcls, tmap, mapAlways = true) + val tmap0 = tmap.withSubstitution(origCls(cls).typeParams, cls.typeParams) + val mappedDcls = mapSymbols(origDcls, tmap0, mapAlways = true) val tmap1 = tmap.withMappedSyms( origCls(cls).typeParams ::: origDcls, cls.typeParams ::: mappedDcls) origDcls.lazyZip(mappedDcls).foreach(cls.asClass.replace) tmap1 } + + override def toString = + def showSyms(syms: List[Symbol]) = + syms.map(sym => s"$sym#${sym.id}").mkString(", ") + s"""TreeTypeMap( + |typeMap = $typeMap + |treeMap = $treeMap + |oldOwners = ${showSyms(oldOwners)} + |newOwners = ${showSyms(newOwners)} + |substFrom = ${showSyms(substFrom)} + |substTo = ${showSyms(substTo)}""".stripMargin } 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/reporting/trace.scala b/compiler/src/dotty/tools/dotc/reporting/trace.scala index 804188b20780..10179f9d3789 100644 --- a/compiler/src/dotty/tools/dotc/reporting/trace.scala +++ b/compiler/src/dotty/tools/dotc/reporting/trace.scala @@ -76,7 +76,7 @@ trait TraceSyntax: else // Avoid evaluating question multiple time, since each evaluation // may cause some extra logging output. - val q = question.replace('\n', ' ') + val q = question val leading = s"==> $q?" val trailing = (res: T) => s"<== $q = ${showOp(res)}" var finalized = false 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/compiler/src/dotty/tools/dotc/typer/ReTyper.scala b/compiler/src/dotty/tools/dotc/typer/ReTyper.scala index 85be8c32227a..7dcaa85d529a 100644 --- a/compiler/src/dotty/tools/dotc/typer/ReTyper.scala +++ b/compiler/src/dotty/tools/dotc/typer/ReTyper.scala @@ -52,6 +52,9 @@ class ReTyper(nestingLevel: Int = 0) extends Typer(nestingLevel) with ReChecking override def typedSuper(tree: untpd.Super, pt: Type)(using Context): Tree = promote(tree) + override def typedImport(tree: untpd.Import, sym: Symbol)(using Context): Tree = + promote(tree) + override def typedTyped(tree: untpd.Typed, pt: Type)(using Context): Tree = { assertTyped(tree) diff --git a/tests/pos/i12508.scala b/tests/pos/i12508.scala new file mode 100644 index 000000000000..896801559177 --- /dev/null +++ b/tests/pos/i12508.scala @@ -0,0 +1,17 @@ +class Test { + inline def test(fun: Any): Any = ??? + test { + class Foo[X]: + def x: X = ??? + def foo: Unit = this.x.toString + } +} +class Test2 { + inline def test(fun: => Any): Any = fun + test { + case class Pair[X, Y]( + x: X, + y: Y, + ) + } +} \ No newline at end of file diff --git a/tests/pos/i12508a.scala b/tests/pos/i12508a.scala new file mode 100644 index 000000000000..fa1a77f9021f --- /dev/null +++ b/tests/pos/i12508a.scala @@ -0,0 +1,14 @@ +def fun(a: Any, b: Any = 2): Any = ??? +def test = + fun( + b = println(1), + a = { + class Foo[X]: + def x: X = ??? + def foo: Unit = this.x.toString + locally { + def x: X = ??? + println(x.toString) + } + } + ) \ No newline at end of file diff --git a/tests/pos/i12508b.scala b/tests/pos/i12508b.scala new file mode 100644 index 000000000000..f1d4836dc380 --- /dev/null +++ b/tests/pos/i12508b.scala @@ -0,0 +1,13 @@ +def fun(a: Any, b: Any = 2): Any = ??? +def test = + fun( + b = println(1), + a = { + sealed class Foo[X]: + def x: X = ??? + def foo: Unit = this.x.toString + class Bar extends Foo[String] + class Baz[Y] extends Foo[Y] + if ??? then Bar() else Baz[Int] + } + ) \ No newline at end of file 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