Skip to content

Commit c1f71db

Browse files
Merge pull request #14537 from dotty-staging/fix-12508
Fix TreeTypeMap to correctly substitute type parameters
2 parents e2f32fd + e0ff75d commit c1f71db

File tree

10 files changed

+84
-5
lines changed

10 files changed

+84
-5
lines changed

compiler/src/dotty/tools/dotc/ast/TreeTypeMap.scala

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -204,11 +204,23 @@ class TreeTypeMap(
204204
lazy val origCls = mapped.zip(syms).filter(_._1.isClass).toMap
205205
mapped.filter(_.isClass).foldLeft(substMap) { (tmap, cls) =>
206206
val origDcls = cls.info.decls.toList.filterNot(_.is(TypeParam))
207-
val mappedDcls = mapSymbols(origDcls, tmap, mapAlways = true)
207+
val tmap0 = tmap.withSubstitution(origCls(cls).typeParams, cls.typeParams)
208+
val mappedDcls = mapSymbols(origDcls, tmap0, mapAlways = true)
208209
val tmap1 = tmap.withMappedSyms(
209210
origCls(cls).typeParams ::: origDcls,
210211
cls.typeParams ::: mappedDcls)
211212
origDcls.lazyZip(mappedDcls).foreach(cls.asClass.replace)
212213
tmap1
213214
}
215+
216+
override def toString =
217+
def showSyms(syms: List[Symbol]) =
218+
syms.map(sym => s"$sym#${sym.id}").mkString(", ")
219+
s"""TreeTypeMap(
220+
|typeMap = $typeMap
221+
|treeMap = $treeMap
222+
|oldOwners = ${showSyms(oldOwners)}
223+
|newOwners = ${showSyms(newOwners)}
224+
|substFrom = ${showSyms(substFrom)}
225+
|substTo = ${showSyms(substTo)}""".stripMargin
214226
}

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

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -822,11 +822,19 @@ object Symbols {
822822
copy.info = completer
823823
copy.denot match
824824
case cd: ClassDenotation =>
825-
cd.registeredCompanion = cd.unforcedRegisteredCompanion.subst(originals, copies)
825+
cd.registeredCompanion = original.registeredCompanion.subst(originals, copies)
826826
case _ =>
827827
}
828828

829829
copies.foreach(_.ensureCompleted()) // avoid memory leak
830+
831+
// Update Child annotations of classes encountered previously to new values
832+
// if some child is among the mapped symbols
833+
for orig <- ttmap1.substFrom do
834+
if orig.is(Sealed) && orig.children.exists(originals.contains) then
835+
val sealedCopy = orig.subst(ttmap1.substFrom, ttmap1.substTo)
836+
sealedCopy.annotations = sealedCopy.annotations.mapConserve(ttmap1.apply)
837+
830838
copies
831839
}
832840

compiler/src/dotty/tools/dotc/printing/RefinedPrinter.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1037,7 +1037,7 @@ class RefinedPrinter(_ctx: Context) extends PlainPrinter(_ctx) {
10371037
else if (sym.is(ModuleClass) && sym.isPackageObject && sym.name.stripModuleClassSuffix == tpnme.PACKAGE)
10381038
nameString(sym.owner.name)
10391039
else if (sym.is(ModuleClass))
1040-
nameString(sym.name.stripModuleClassSuffix)
1040+
nameString(sym.name.stripModuleClassSuffix) + idString(sym)
10411041
else if (hasMeaninglessName(sym))
10421042
simpleNameString(sym.owner) + idString(sym)
10431043
else

compiler/src/dotty/tools/dotc/reporting/trace.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ trait TraceSyntax:
7676
else
7777
// Avoid evaluating question multiple time, since each evaluation
7878
// may cause some extra logging output.
79-
val q = question.replace('\n', ' ')
79+
val q = question
8080
val leading = s"==> $q?"
8181
val trailing = (res: T) => s"<== $q = ${showOp(res)}"
8282
var finalized = false

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,7 @@ class SyntheticMembers(thisPhase: DenotTransformer) {
140140
val parentEnum = vdef.owner.companionClass
141141
val children = parentEnum.children.zipWithIndex
142142
val candidate: Option[Int] = children.collectFirst { case (child, idx) if child == vdef => idx }
143-
assert(candidate.isDefined, i"could not find child for $vdef")
143+
assert(candidate.isDefined, i"could not find child for $vdef in ${parentEnum.children}%, % of $parentEnum")
144144
Literal(Constant(candidate.get))
145145

146146
def toStringBody(vrefss: List[List[Tree]]): Tree =

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,9 @@ class ReTyper(nestingLevel: Int = 0) extends Typer(nestingLevel) with ReChecking
5151
override def typedSuper(tree: untpd.Super, pt: Type)(using Context): Tree =
5252
promote(tree)
5353

54+
override def typedImport(tree: untpd.Import, sym: Symbol)(using Context): Tree =
55+
promote(tree)
56+
5457
override def typedTyped(tree: untpd.Typed, pt: Type)(using Context): Tree = {
5558
assertTyped(tree)
5659

tests/pos/i12508.scala

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
class Test {
2+
inline def test(fun: Any): Any = ???
3+
test {
4+
class Foo[X]:
5+
def x: X = ???
6+
def foo: Unit = this.x.toString
7+
}
8+
}
9+
class Test2 {
10+
inline def test(fun: => Any): Any = fun
11+
test {
12+
case class Pair[X, Y](
13+
x: X,
14+
y: Y,
15+
)
16+
}
17+
}

tests/pos/i12508a.scala

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
def fun(a: Any, b: Any = 2): Any = ???
2+
def test =
3+
fun(
4+
b = println(1),
5+
a = {
6+
class Foo[X]:
7+
def x: X = ???
8+
def foo: Unit = this.x.toString
9+
locally {
10+
def x: X = ???
11+
println(x.toString)
12+
}
13+
}
14+
)

tests/pos/i12508b.scala

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
def fun(a: Any, b: Any = 2): Any = ???
2+
def test =
3+
fun(
4+
b = println(1),
5+
a = {
6+
sealed class Foo[X]:
7+
def x: X = ???
8+
def foo: Unit = this.x.toString
9+
class Bar extends Foo[String]
10+
class Baz[Y] extends Foo[Y]
11+
if ??? then Bar() else Baz[Int]
12+
}
13+
)

tests/pos/i12508c.scala

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
def fun(a: Any, b: Any = 2): Any = ???
2+
3+
def test =
4+
fun(
5+
b = println(1),
6+
a = {
7+
enum Option[+X]:
8+
case Some(x: X)
9+
case None
10+
if ??? then Option.Some(1) else Option.None
11+
}
12+
)

0 commit comments

Comments
 (0)