Skip to content

Commit

Permalink
Add new HOLETYPES to TASTy format
Browse files Browse the repository at this point in the history
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
```
  • Loading branch information
nicolasstucki committed Apr 11, 2023
1 parent 738c3aa commit 68343c1
Show file tree
Hide file tree
Showing 3 changed files with 25 additions and 11 deletions.
6 changes: 5 additions & 1 deletion compiler/src/dotty/tools/dotc/core/tasty/TreePickler.scala
Original file line number Diff line number Diff line change
Expand Up @@ -670,7 +670,11 @@ class TreePickler(pickler: TastyPickler) {
withLength {
writeNat(idx)
pickleType(tpt.tpe, richTypes = true)
targs.foreach(pickleTree)
if targs.nonEmpty then
writeByte(HOLETYPES)
withLength {
targs.foreach(targ => pickleType(targ.tpe))
}
args.foreach(pickleTree)
}
}
Expand Down
22 changes: 14 additions & 8 deletions compiler/src/dotty/tools/dotc/core/tasty/TreeUnpickler.scala
Original file line number Diff line number Diff line change
Expand Up @@ -1436,10 +1436,7 @@ class TreeUnpickler(reader: TastyReader,
val alias = if currentAddr == end then EmptyTree else readTpt()
createNullableTypeBoundsTree(lo, hi, alias)
case HOLE =>
val idx = readNat()
val tpe = readType()
val args = until(end)(readTerm())
TastyQuoteHole(true, idx, args, TypeTree(tpe)).withType(tpe)
readHole(end, isTerm = true)
case _ =>
readPathTerm()
}
Expand Down Expand Up @@ -1470,10 +1467,7 @@ class TreeUnpickler(reader: TastyReader,
case HOLE =>
readByte()
val end = readEnd()
val idx = readNat()
val tpe = readType()
val args = until(end)(readTerm())
TastyQuoteHole(false, idx, args, TypeTree(tpe)).withType(tpe)
readHole(end, isTerm = false)
case _ =>
if (isTypeTreeTag(nextByte)) readTerm()
else {
Expand Down Expand Up @@ -1506,6 +1500,18 @@ class TreeUnpickler(reader: TastyReader,
setSpan(start, CaseDef(pat, guard, rhs))
}

def readHole(end: Addr, isTerm: Boolean)(using Context): Tree =
val idx = readNat()
val tpe = readType()
val targs =
if nextByte == HOLETYPES then
readByte()
val typesEnd = readEnd()
until(typesEnd)(readType()).map(TypeTree(_))
else Nil
val args = until(end)(readTerm())
TastyQuoteHole(true, idx, targs ::: args, TypeTree(tpe)).withType(tpe)

def readLater[T <: AnyRef](end: Addr, op: TreeReader => Context ?=> T)(using Context): Trees.Lazy[T] =
readLaterWithOwner(end, op)(ctx.owner)

Expand Down
8 changes: 6 additions & 2 deletions tasty/src/dotty/tools/tasty/TastyFormat.scala
Original file line number Diff line number Diff line change
Expand Up @@ -122,8 +122,9 @@ Standard-Section: "ASTs" TopLevelStat*
MATCHtpt Length bound_Term? sel_Term CaseDef* -- sel match { CaseDef } where `bound` is optional upper bound of all rhs
BYNAMEtpt underlying_Term -- => underlying
SHAREDterm term_ASTRef -- Link to previously serialized term
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
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
-- Note: From 3.0 to 3.3 `args` could contain type arguments as well. This is no longer the case.
CaseDef = CASEDEF Length pat_Term rhs_Tree guard_Tree? -- case pat if guard => rhs
ImplicitArg = IMPLICITARG arg_Term -- implicit unapply argument
Expand Down Expand Up @@ -586,6 +587,7 @@ object TastyFormat {
final val MATCHtpt = 191
final val MATCHCASEtype = 192

final val HOLETYPES = 254
final val HOLE = 255

final val firstNatTreeTag = SHAREDterm
Expand All @@ -600,6 +602,7 @@ object TastyFormat {
firstASTTreeTag <= tag && tag <= BOUNDED ||
firstNatASTTreeTag <= tag && tag <= NAMEDARG ||
firstLengthTreeTag <= tag && tag <= MATCHtpt ||
tag == HOLETYPES ||
tag == HOLE

def isParamTag(tag: Int): Boolean = tag == PARAM || tag == TYPEPARAM
Expand Down Expand Up @@ -804,6 +807,7 @@ object TastyFormat {
case PRIVATEqualified => "PRIVATEqualified"
case PROTECTEDqualified => "PROTECTEDqualified"
case HOLE => "HOLE"
case HOLETYPES => "HOLETYPES"
}

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

0 comments on commit 68343c1

Please sign in to comment.