Skip to content

Commit f8aa09e

Browse files
committed
Simplify the pickled tree after unpickler
1 parent 5471074 commit f8aa09e

File tree

2 files changed

+43
-24
lines changed

2 files changed

+43
-24
lines changed

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

Lines changed: 16 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1194,10 +1194,6 @@ class TreeUnpickler(reader: TastyReader,
11941194
res.withAttachment(SuppressedApplyToNone, ())
11951195
else res
11961196

1197-
def simplifyLub(tree: Tree): Tree =
1198-
tree.overwriteType(tree.tpe.simplified)
1199-
tree
1200-
12011197
def readLengthTerm(): Tree = {
12021198
val end = readEnd()
12031199
val result =
@@ -1236,37 +1232,34 @@ class TreeUnpickler(reader: TastyReader,
12361232
val expansion = exprReader.readTerm() // need bindings in scope, so needs to be read before
12371233
Inlined(call, bindings, expansion)
12381234
case IF =>
1239-
simplifyLub(
1240-
if (nextByte == INLINE) {
1241-
readByte()
1242-
InlineIf(readTerm(), readTerm(), readTerm())
1243-
}
1244-
else
1245-
If(readTerm(), readTerm(), readTerm()))
1235+
if (nextByte == INLINE) {
1236+
readByte()
1237+
InlineIf(readTerm(), readTerm(), readTerm())
1238+
}
1239+
else
1240+
If(readTerm(), readTerm(), readTerm())
12461241
case LAMBDA =>
12471242
val meth = readTerm()
12481243
val tpt = ifBefore(end)(readTpt(), EmptyTree)
12491244
Closure(Nil, meth, tpt)
12501245
case MATCH =>
1251-
simplifyLub(
1252-
if (nextByte == IMPLICIT) {
1253-
readByte()
1254-
InlineMatch(EmptyTree, readCases(end))
1255-
}
1256-
else if (nextByte == INLINE) {
1257-
readByte()
1258-
InlineMatch(readTerm(), readCases(end))
1259-
}
1260-
else Match(readTerm(), readCases(end)))
1246+
if (nextByte == IMPLICIT) {
1247+
readByte()
1248+
InlineMatch(EmptyTree, readCases(end))
1249+
}
1250+
else if (nextByte == INLINE) {
1251+
readByte()
1252+
InlineMatch(readTerm(), readCases(end))
1253+
}
1254+
else Match(readTerm(), readCases(end))
12611255
case RETURN =>
12621256
val from = readSymRef()
12631257
val expr = ifBefore(end)(readTerm(), EmptyTree)
12641258
Return(expr, Ident(from.termRef))
12651259
case WHILE =>
12661260
WhileDo(readTerm(), readTerm())
12671261
case TRY =>
1268-
simplifyLub(
1269-
Try(readTerm(), readCases(end), ifBefore(end)(readTerm(), EmptyTree)))
1262+
Try(readTerm(), readCases(end), ifBefore(end)(readTerm(), EmptyTree))
12701263
case SELECTouter =>
12711264
val levels = readNat()
12721265
readTerm().outerSelect(levels, SkolemType(readType()))

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

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,8 @@ class Pickler extends Phase {
4949
private val beforePickling = new mutable.HashMap[ClassSymbol, String]
5050
private val picklers = new mutable.HashMap[ClassSymbol, TastyPickler]
5151

52+
private val typeSimplifier = new TypeSimplifier
53+
5254
/** Drop any elements of this list that are linked module classes of other elements in the list */
5355
private def dropCompanionModuleClasses(clss: List[ClassSymbol])(using Context): List[ClassSymbol] = {
5456
val companionModuleClasses =
@@ -97,6 +99,13 @@ class Pickler extends Phase {
9799
println(i"**** pickled info of $cls")
98100
println(TastyPrinter.showContents(pickled, ctx.settings.color.value == "never"))
99101
}
102+
// println(i"**** pickled info of $cls")
103+
// println(TastyPrinter.showContents(pickled, ctx.settings.color.value == "never"))
104+
if cls.show.contains("MainGenericRunner") then
105+
import java.nio.file.{Paths, Files}
106+
import java.nio.charset.StandardCharsets
107+
108+
Files.write(Paths.get("debug.txt"), TastyPrinter.showContents(pickled, true).getBytes(StandardCharsets.UTF_8))
100109
pickled
101110
}(using ExecutionContext.global)
102111
}
@@ -135,7 +144,7 @@ class Pickler extends Phase {
135144
}
136145
pickling.println("************* entered toplevel ***********")
137146
for ((cls, unpickler) <- unpicklers) {
138-
val unpickled = unpickler.rootTrees
147+
val unpickled = typeSimplifier.transform(unpickler.rootTrees)
139148
testSame(i"$unpickled%\n%", beforePickling(cls), cls)
140149
}
141150
}
@@ -151,4 +160,21 @@ class Pickler extends Phase {
151160
|
152161
| diff before-pickling.txt after-pickling.txt""".stripMargin)
153162
end testSame
163+
164+
// Overwrite types of If, Match, and Try nodes with simplified types
165+
// to avoid inconsistencies in unsafe nulls
166+
class TypeSimplifier extends TreeMapWithPreciseStatContexts:
167+
override def transform(tree: Tree)(using Context): Tree =
168+
try tree match
169+
case _: If | _: Match | _: Try =>
170+
val newTree = super.transform(tree)
171+
newTree.overwriteType(newTree.tpe.simplified)
172+
newTree
173+
case _ =>
174+
super.transform(tree)
175+
catch
176+
case ex: TypeError =>
177+
report.error(ex, tree.srcPos)
178+
tree
179+
end TypeSimplifier
154180
}

0 commit comments

Comments
 (0)