Skip to content

Commit 050b133

Browse files
committed
Add new QUOTEHOLE to TASTy format
This is a new encoding of HOLE that differentiates between type and term arguments of the hole.
1 parent 5f10dfb commit 050b133

File tree

4 files changed

+30
-21
lines changed

4 files changed

+30
-21
lines changed

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,7 @@ class TastyPrinter(bytes: Array[Byte]) {
131131
printName(); printTrees()
132132
case REFINEDtype | TERMREFin | TYPEREFin | SELECTin =>
133133
printName(); printTree(); printTrees()
134-
case RETURN | HOLE =>
134+
case RETURN | HOLE | QUOTEHOLE =>
135135
printNat(); printTrees()
136136
case METHODtype | POLYtype | TYPELAMBDAtype =>
137137
printTree()

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

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -666,14 +666,13 @@ class TreePickler(pickler: TastyPickler) {
666666
pickleTree(alias)
667667
}
668668
case Hole(_, idx, targs, args, _, tpt) =>
669-
writeByte(HOLE)
669+
writeByte(QUOTEHOLE)
670670
withLength {
671671
writeNat(idx)
672-
pickleType(tpt.tpe, richTypes = true)
673-
targs.foreach(pickleTree)
672+
pickleTree(untpd.AppliedTypeTree(tpt, targs))
674673
args.foreach(pickleTree)
675674
}
676-
}
675+
}
677676
catch {
678677
case ex: TypeError =>
679678
report.error(ex.toMessage, tree.srcPos.focus)

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

Lines changed: 17 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1435,11 +1435,8 @@ class TreeUnpickler(reader: TastyReader,
14351435
val hi = if currentAddr == end then lo else readTpt()
14361436
val alias = if currentAddr == end then EmptyTree else readTpt()
14371437
createNullableTypeBoundsTree(lo, hi, alias)
1438-
case HOLE =>
1439-
val idx = readNat()
1440-
val tpe = readType()
1441-
val args = until(end)(readTerm())
1442-
PickledHole(true, idx, args, TypeTree(tpe)).withType(tpe)
1438+
case HOLE | QUOTEHOLE =>
1439+
readHole(tag, end, isTerm = true)
14431440
case _ =>
14441441
readPathTerm()
14451442
}
@@ -1467,13 +1464,8 @@ class TreeUnpickler(reader: TastyReader,
14671464
val aliases = readStats(ctx.owner, end)
14681465
val tpt = typeReader.readTpt()
14691466
Block(aliases, tpt)
1470-
case HOLE =>
1471-
readByte()
1472-
val end = readEnd()
1473-
val idx = readNat()
1474-
val tpe = readType()
1475-
val args = until(end)(readTerm())
1476-
PickledHole(false, idx, args, TypeTree(tpe)).withType(tpe)
1467+
case HOLE | QUOTEHOLE =>
1468+
readHole(readByte(), readEnd(), isTerm = false)
14771469
case _ =>
14781470
if (isTypeTreeTag(nextByte)) readTerm()
14791471
else {
@@ -1517,6 +1509,19 @@ class TreeUnpickler(reader: TastyReader,
15171509
owner => new LazyReader(localReader, owner, mode, source, op)
15181510
}
15191511

1512+
def readHole(tag: Int, end: Addr, isTerm: Boolean)(using Context): Tree = tag match {
1513+
case QUOTEHOLE =>
1514+
val idx = readNat()
1515+
val AppliedTypeTree(tpt, targs) = readTerm(): @unchecked
1516+
val args = until(end)(readTerm())
1517+
PickledHole(isTerm, idx, targs ::: args, tpt).withType(tpt.tpe)
1518+
case HOLE =>
1519+
val idx = readNat()
1520+
val tpe = readType()
1521+
val args = until(end)(readTerm())
1522+
PickledHole(isTerm, idx, args, TypeTree(tpe)).withType(tpe)
1523+
}
1524+
15201525
// ------ Setting positions ------------------------------------------------
15211526

15221527
/** Pickled span for `addr`. */

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

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -122,7 +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 arg_Tree* -- Hole where a splice goes with sequence number idx, splice is applied to arguments `arg`s
125+
QUOTEHOLE Length idx_Nat tptTargs_Tree arg_Tree* -- Splice hole with index `idx`, the type of the hole `tpt`, type arguments `targ`s and term arguments `args`s
126+
-- tptTargs=APPLIEDtpt(tpt,targ*), this is not a true type application. Reused for its structure.
127+
HOLE Length idx_Nat tpe_Type arg_Tree* -- Splice hole with index `idx`, the type of the hole `tpe`, type and term arguments `args`s
126128
127129
CaseDef = CASEDEF Length pat_Term rhs_Tree guard_Tree? -- case pat if guard => rhs
128130
ImplicitArg = IMPLICITARG arg_Term -- implicit unapply argument
@@ -585,12 +587,14 @@ object TastyFormat {
585587
final val MATCHtpt = 191
586588
final val MATCHCASEtype = 192
587589

588-
final val HOLE = 255
590+
final val QUOTEHOLE = 254
591+
final val HOLE = 255 // Used from 3.0 to 3.3, repaced with QUOTEHOLE in 3.4+
589592

590593
final val firstNatTreeTag = SHAREDterm
591594
final val firstASTTreeTag = THIS
592595
final val firstNatASTTreeTag = IDENT
593596
final val firstLengthTreeTag = PACKAGE
597+
final val firstQuoteTag = QUOTEHOLE
594598

595599
/** Useful for debugging */
596600
def isLegalTag(tag: Int): Boolean =
@@ -599,7 +603,7 @@ object TastyFormat {
599603
firstASTTreeTag <= tag && tag <= BOUNDED ||
600604
firstNatASTTreeTag <= tag && tag <= NAMEDARG ||
601605
firstLengthTreeTag <= tag && tag <= MATCHtpt ||
602-
tag == HOLE
606+
firstQuoteTag <= tag && tag <= HOLE
603607

604608
def isParamTag(tag: Int): Boolean = tag == PARAM || tag == TYPEPARAM
605609

@@ -802,6 +806,7 @@ object TastyFormat {
802806
case ANNOTATION => "ANNOTATION"
803807
case PRIVATEqualified => "PRIVATEqualified"
804808
case PROTECTEDqualified => "PROTECTEDqualified"
809+
case QUOTEHOLE => "QUOTEHOLE"
805810
case HOLE => "HOLE"
806811
}
807812

@@ -810,7 +815,7 @@ object TastyFormat {
810815
*/
811816
def numRefs(tag: Int): Int = tag match {
812817
case VALDEF | DEFDEF | TYPEDEF | TYPEPARAM | PARAM | NAMEDARG | RETURN | BIND |
813-
SELFDEF | REFINEDtype | TERMREFin | TYPEREFin | SELECTin | HOLE => 1
818+
SELFDEF | REFINEDtype | TERMREFin | TYPEREFin | SELECTin | QUOTEHOLE | HOLE => 1
814819
case RENAMED | PARAMtype => 2
815820
case POLYtype | TYPELAMBDAtype | METHODtype => -1
816821
case _ => 0

0 commit comments

Comments
 (0)