Skip to content

Commit 68343c1

Browse files
committed
Add new HOLETYPES to TASTy format
This is a new encoding of HOLE that differentiates between type and term arguments of the hole. ``` HOLE Length idx_Nat tpe_Type (HOLETYPES Length targ_Type*)? arg_Tree* -- Splice hole with index `idx`, the type of the hole `tpe`, type arguments of the hole `targ`s and term arguments of the hole `arg`s ```
1 parent 738c3aa commit 68343c1

File tree

3 files changed

+25
-11
lines changed

3 files changed

+25
-11
lines changed

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

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -670,7 +670,11 @@ class TreePickler(pickler: TastyPickler) {
670670
withLength {
671671
writeNat(idx)
672672
pickleType(tpt.tpe, richTypes = true)
673-
targs.foreach(pickleTree)
673+
if targs.nonEmpty then
674+
writeByte(HOLETYPES)
675+
withLength {
676+
targs.foreach(targ => pickleType(targ.tpe))
677+
}
674678
args.foreach(pickleTree)
675679
}
676680
}

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

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1436,10 +1436,7 @@ class TreeUnpickler(reader: TastyReader,
14361436
val alias = if currentAddr == end then EmptyTree else readTpt()
14371437
createNullableTypeBoundsTree(lo, hi, alias)
14381438
case HOLE =>
1439-
val idx = readNat()
1440-
val tpe = readType()
1441-
val args = until(end)(readTerm())
1442-
TastyQuoteHole(true, idx, args, TypeTree(tpe)).withType(tpe)
1439+
readHole(end, isTerm = true)
14431440
case _ =>
14441441
readPathTerm()
14451442
}
@@ -1470,10 +1467,7 @@ class TreeUnpickler(reader: TastyReader,
14701467
case HOLE =>
14711468
readByte()
14721469
val end = readEnd()
1473-
val idx = readNat()
1474-
val tpe = readType()
1475-
val args = until(end)(readTerm())
1476-
TastyQuoteHole(false, idx, args, TypeTree(tpe)).withType(tpe)
1470+
readHole(end, isTerm = false)
14771471
case _ =>
14781472
if (isTypeTreeTag(nextByte)) readTerm()
14791473
else {
@@ -1506,6 +1500,18 @@ class TreeUnpickler(reader: TastyReader,
15061500
setSpan(start, CaseDef(pat, guard, rhs))
15071501
}
15081502

1503+
def readHole(end: Addr, isTerm: Boolean)(using Context): Tree =
1504+
val idx = readNat()
1505+
val tpe = readType()
1506+
val targs =
1507+
if nextByte == HOLETYPES then
1508+
readByte()
1509+
val typesEnd = readEnd()
1510+
until(typesEnd)(readType()).map(TypeTree(_))
1511+
else Nil
1512+
val args = until(end)(readTerm())
1513+
TastyQuoteHole(true, idx, targs ::: args, TypeTree(tpe)).withType(tpe)
1514+
15091515
def readLater[T <: AnyRef](end: Addr, op: TreeReader => Context ?=> T)(using Context): Trees.Lazy[T] =
15101516
readLaterWithOwner(end, op)(ctx.owner)
15111517

tasty/src/dotty/tools/tasty/TastyFormat.scala

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -122,8 +122,9 @@ Standard-Section: "ASTs" TopLevelStat*
122122
MATCHtpt Length bound_Term? sel_Term CaseDef* -- sel match { CaseDef } where `bound` is optional upper bound of all rhs
123123
BYNAMEtpt underlying_Term -- => underlying
124124
SHAREDterm term_ASTRef -- Link to previously serialized term
125-
HOLE Length idx_Nat tpe_Type arg_Tree* -- Splice hole with index `idx`, the type of the hole `tpe`, type and term arguments of the hole `arg`s
126-
125+
HOLE Length idx_Nat tpe_Type (HOLETYPES Length targ_Type*)? arg_Tree*
126+
-- Splice hole with index `idx`, the type of the hole `tpe`, type arguments of the hole `targ`s and term arguments of the hole `arg`s
127+
-- Note: From 3.0 to 3.3 `args` could contain type arguments as well. This is no longer the case.
127128
128129
CaseDef = CASEDEF Length pat_Term rhs_Tree guard_Tree? -- case pat if guard => rhs
129130
ImplicitArg = IMPLICITARG arg_Term -- implicit unapply argument
@@ -586,6 +587,7 @@ object TastyFormat {
586587
final val MATCHtpt = 191
587588
final val MATCHCASEtype = 192
588589

590+
final val HOLETYPES = 254
589591
final val HOLE = 255
590592

591593
final val firstNatTreeTag = SHAREDterm
@@ -600,6 +602,7 @@ object TastyFormat {
600602
firstASTTreeTag <= tag && tag <= BOUNDED ||
601603
firstNatASTTreeTag <= tag && tag <= NAMEDARG ||
602604
firstLengthTreeTag <= tag && tag <= MATCHtpt ||
605+
tag == HOLETYPES ||
603606
tag == HOLE
604607

605608
def isParamTag(tag: Int): Boolean = tag == PARAM || tag == TYPEPARAM
@@ -804,6 +807,7 @@ object TastyFormat {
804807
case PRIVATEqualified => "PRIVATEqualified"
805808
case PROTECTEDqualified => "PROTECTEDqualified"
806809
case HOLE => "HOLE"
810+
case HOLETYPES => "HOLETYPES"
807811
}
808812

809813
/** @return If non-negative, the number of leading references (represented as nats) of a length/trees entry.

0 commit comments

Comments
 (0)