Skip to content

Commit d84f342

Browse files
committed
WIP More refinements to type pickling
Many files compile now when checkTypePositions is enabled, but far from all. It looks complicated to track types and trees precisely in all cases.
1 parent 64ba394 commit d84f342

File tree

5 files changed

+57
-31
lines changed

5 files changed

+57
-31
lines changed

src/dotty/tools/dotc/ast/Trees.scala

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,7 @@ object Trees {
114114
*/
115115
def withType(tpe: Type)(implicit ctx: Context): ThisTree[Type] = {
116116
if (tpe == ErrorType) assert(ctx.reporter.errorsReported)
117+
//if (this.isInstanceOf[Ident[_]]) assert(!tpe.isInstanceOf[TypeBounds])
117118
withTypeUnchecked(tpe)
118119
}
119120

src/dotty/tools/dotc/ast/TypePositions.scala

Lines changed: 47 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,8 @@ object TypePositions {
9898
convert(body, tpe.resultType))
9999
case (TypeDef(name, rhs), tpe @ TypeAlias(alias)) =>
100100
PointPos.add(tree, tpe.derivedTypeAlias(convert(rhs, alias)))
101+
case (TypeDef(name, rhs), tpe: PolyType) if !rhs.isInstanceOf[PolyTypeTree] =>
102+
PointPos.add(tree, tpe.derivedPolyType(resType = convert(rhs, tpe.resultType)))
101103
case (TypeDef(name, rhs), tpe) =>
102104
PointPos.add(tree, convert(rhs, tpe))
103105
case (ValDef(name, tpt, _), tpe) =>
@@ -121,14 +123,16 @@ object TypePositions {
121123
case (_, tpe) =>
122124
tpe
123125
}
124-
tpe1 match {
126+
val res = tpe1 match {
125127
case AnnotatedType(_, _: PosAnnot) => tpe1
126128
case _ => if (tree.pos.exists) AnnotatedType(tpe1, PosAnnot(tree.pos)) else tpe1
127129
}
130+
//println(i"convert $tree: ${tree.tpe} / $tpe -> $tpe1 -> $res")
131+
res
128132
}
129133
convert(tree, tree.tpe)
130134
}
131-
135+
132136
/** Given a type produce a corresponding definition with defined name `name`
133137
*/
134138
def toDef(name: Name, tpe: Type)(implicit ctx: Context): MemberDef = {
@@ -185,12 +189,15 @@ object TypePositions {
185189
*/
186190
def toTree(tpe: Type, hasPos: Boolean = false)(implicit ctx: Context): Tree = tpe match {
187191
case AnnotatedType(tpe1, PosAnnot(pos)) =>
188-
val tree = toTree(tpe1, hasPos = true) match {
189-
case t @ Select(qual, name) if name.length == pos.end - pos.start =>
190-
untpd.Ident(name).withType(t.tpe)
191-
case t => t
192+
def addPos(tree: Tree): Tree = tree match {
193+
case tree @ SingletonTypeTree(ref) =>
194+
untpd.SingletonTypeTree(addPos(ref)).withType(tree.tpe)
195+
case tree @ Select(qual, name) if name.length == pos.end - pos.start =>
196+
untpd.Ident(name).withType(tree.tpe).withPos(pos.toSynthetic)
197+
case _ =>
198+
tree.withPos(pos.toSynthetic)
192199
}
193-
tree.withPos(pos.toSynthetic)
200+
addPos(toTree(tpe1, hasPos = true))
194201
case tpe =>
195202
val utree: untpd.Tree = {
196203
import untpd._
@@ -264,12 +271,42 @@ object TypePositions {
264271
utree.withType(tpe)
265272
}
266273

267-
def refPositions(tree: Tree)(implicit ctx: Context): List[(Name, Position)] = {
268-
val b = new mutable.ListBuffer[(Name, Position)]
274+
def adapt(rhs: Tree, tp: Type, tparams: List[untpd.TypeDef])(implicit ctx: Context): Tree = {
275+
val rhs1: untpd.Tree = tp match {
276+
case TypeAlias(alias) if !rhs.isInstanceOf[TypeBoundsTree] =>
277+
val rhs0 = adapt(rhs, alias, tparams)
278+
TypeBoundsTree(rhs0, rhs0)
279+
case tp: PolyType if !rhs.isInstanceOf[PolyTypeTree] =>
280+
assert(tparams.length == tp.paramNames.length, i"bad poly $tp, $tparams")
281+
PolyTypeTree(tparams, rhs)
282+
case _ =>
283+
rhs
284+
}
285+
rhs1.withType(tp)
286+
}
287+
288+
def refPositions(tree: Tree)(implicit ctx: Context): List[(String, Position)] = {
289+
val b = new mutable.ListBuffer[(String, Position)]
290+
def essentialSuffix(name: Name): String =
291+
name.drop(name.lastIndexOf('$') + 1).toString
269292
tree foreachSubTree {
270-
case t: RefTree => b += ((t.name, t.pos.toSynthetic))
293+
case t: RefTree => b += ((essentialSuffix(t.name), t.pos.toSynthetic))
271294
case _ =>
272295
}
273296
b.toList
274297
}
298+
299+
def checkTypePositions(posType: Type, tpt: Tree)(implicit ctx: Context) = {
300+
val tree = TypePositions.toTree(posType)
301+
val origRefs = TypePositions.refPositions(tpt)
302+
val newRefs = TypePositions.refPositions(tree)
303+
assert(origRefs.map(_._2).toSet subsetOf newRefs.map(_._2).toSet,
304+
i"""tpt = $tpt
305+
|tptStr = ${tpt.toString}
306+
|posType = $posType
307+
|posTypeStr = ${posType.toString}
308+
|tree = $tree
309+
|origRefs = $origRefs%, %
310+
|newRefs = $newRefs%, %""")
311+
}
275312
}

src/dotty/tools/dotc/core/Types.scala

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -764,6 +764,7 @@ object Types {
764764
}
765765

766766
def & (that: Type)(implicit ctx: Context): Type = track("&") {
767+
//println(i"$this & $that")
767768
ctx.typeComparer.glb(this, that)
768769
}
769770

@@ -2200,6 +2201,7 @@ object Types {
22002201
object AndType {
22012202
def apply(tp1: Type, tp2: Type)(implicit ctx: Context) = {
22022203
assert(tp1.isValueType && tp2.isValueType, i"$tp1 & $tp2 / " + s"$tp1 & $tp2")
2204+
//assert(tp1.typeSymbol.name.toString != "B" || tp2.typeSymbol.name.toString != "A")
22032205
unchecked(tp1, tp2)
22042206
}
22052207
def unchecked(tp1: Type, tp2: Type)(implicit ctx: Context) = {

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

Lines changed: 5 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -51,9 +51,11 @@ class TreePickler(pickler: TastyPickler) {
5151
}
5252
}
5353

54-
def rhs(tdef: TypeDef)(implicit ctx: Context) =
54+
def rhs(tdef: TypeDef)(implicit ctx: Context): Tree =
5555
if (tdef.symbol.isClass) tdef.rhs
56-
else tdef.rhs.withType(tdef.symbol.info)
56+
else if (true) tdef.rhs.withType(tdef.symbol.info)
57+
else TypePositions.adapt(tdef.rhs, tdef.symbol.info, tdef.tparams)
58+
5759

5860
private def pickleName(name: Name): Unit = writeNat(nameIndex(name).index)
5961
private def pickleName(name: TastyName): Unit = writeNat(nameIndex(name).index)
@@ -324,23 +326,7 @@ class TreePickler(pickler: TastyPickler) {
324326

325327
/** Pickle positioned type associated with type tree `tpt`. */
326328
private def picklePosTypeOfTree(posType: Type, tpt: Tree)(implicit ctx: Context): Unit = {
327-
def checkTypePositions() = {
328-
val tree = TypePositions.toTree(posType)
329-
val origRefs = TypePositions.refPositions(tpt)
330-
val newRefs = TypePositions.refPositions(tree)
331-
assert(TypePositions.refPositions(tpt).toSet subsetOf TypePositions.refPositions(tree).toSet,
332-
i"""$tpt
333-
|-->
334-
|$posType
335-
|-->
336-
|$tree
337-
|/
338-
|${posType.toString}
339-
|/
340-
|${tree.toString}""")
341-
342-
}
343-
if (false) checkTypePositions
329+
if (false) TypePositions.checkTypePositions(posType, tpt)
344330
positioned.register(tpt, posType)
345331
pickleType(posType)
346332
}

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -167,8 +167,8 @@ class RefinedPrinter(_ctx: Context) extends PlainPrinter(_ctx) {
167167
//
168168
// test/new/annot.scala
169169
//
170-
// override def toText(annot: Annotation): Text =
171-
// if (annot.tree.isEmpty) annot.toString else constrText(annot.tree)
170+
override def toText(annot: Annotation): Text =
171+
if (annot.tree.isEmpty) annot.toString else super.toText(annot)//constrText(annot.tree)
172172

173173
override def toText[T >: Untyped](tree: Tree[T]): Text = controlled {
174174

0 commit comments

Comments
 (0)