Skip to content

Commit 1e00117

Browse files
committed
Fix -Ytest-pickler with super trees
in t247.scala, `super[Tree]` was typed as `SuperType(TreeMap, Tree)` but the unpickled type was reconstructed as `SuperType(TreeMap, Tree[KEY, Entry])` leading to a -Ytest-pickler failure. We fix this by tweaking TypeAssigner for Super, and while we're at it we also add some checks related to Super in TreeChecker.
1 parent 62684d0 commit 1e00117

File tree

4 files changed

+19
-2
lines changed

4 files changed

+19
-2
lines changed

compiler/src/dotty/tools/dotc/core/tasty/TreePickler.scala

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -451,6 +451,7 @@ class TreePickler(pickler: TastyPickler) {
451451
withLength {
452452
pickleTree(qual);
453453
if (!mix.isEmpty) {
454+
// mixinType being a TypeRef when mix is non-empty is enforced by TreeChecker#checkSuper
454455
val SuperType(_, mixinType: TypeRef) = tree.tpe: @unchecked
455456
pickleTree(mix.withType(mixinType))
456457
}

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

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -305,9 +305,26 @@ class TreeChecker extends Phase with SymTransformer {
305305
override def excludeFromDoubleDeclCheck(sym: Symbol)(using Context): Boolean =
306306
sym.isEffectivelyErased && sym.is(Private) && !sym.initial.is(Private)
307307

308+
/** Check that all invariants related to Super and SuperType are met */
309+
def checkSuper(tree: Tree)(implicit ctx: Context): Unit = tree match
310+
case Super(qual, mix) =>
311+
tree.tpe match
312+
case tp @ SuperType(thistpe, supertpe) =>
313+
if (!mix.isEmpty)
314+
assert(supertpe.isInstanceOf[TypeRef],
315+
s"Precondition of pickling violated: the supertpe in $tp is not a TypeRef even though $tree has a non-empty mix")
316+
case tp =>
317+
assert(false, s"The type of a Super tree must be a SuperType, but $tree has type $tp")
318+
case _ =>
319+
tree.tpe match
320+
case tp: SuperType =>
321+
assert(false, s"The type of a non-Super tree must not be a SuperType, but $tree has type $tp")
322+
case _ =>
323+
308324
override def typed(tree: untpd.Tree, pt: Type = WildcardType)(using Context): Tree = {
309325
val tpdTree = super.typed(tree, pt)
310326
Typer.assertPositioned(tree)
327+
checkSuper(tpdTree)
311328
if (ctx.erasedTypes)
312329
// Can't be checked in earlier phases since `checkValue` is only run in
313330
// Erasure (because running it in Typer would force too much)

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -255,7 +255,7 @@ trait TypeAssigner {
255255
errorType("ambiguous parent class qualifier", pos)
256256
}
257257
val owntype =
258-
if (mixinClass.exists) mixinClass.appliedRef
258+
if (mixinClass.exists) mixinClass.typeRef
259259
else if (!mix.isEmpty) findMixinSuper(cls.info)
260260
else if (ctx.erasedTypes) cls.info.firstParent.typeConstructor
261261
else {

compiler/test/dotc/pos-test-pickling.blacklist

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ i94-nada.scala
22
i1812.scala
33
i1867.scala
44
i3067.scala
5-
t247.scala
65
t2712-5.scala
76
t284-pos.scala
87
t3249

0 commit comments

Comments
 (0)