Skip to content

Commit f758994

Browse files
Merge pull request #5261 from dotty-staging/fix-#5247
Fix #5247: Support type blocks and fix generic tuples
2 parents 791d9bb + d5828c2 commit f758994

File tree

13 files changed

+91
-27
lines changed

13 files changed

+91
-27
lines changed

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

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -484,8 +484,10 @@ object Trees {
484484

485485
/** { stats; expr } */
486486
case class Block[-T >: Untyped] private[ast] (stats: List[Tree[T]], expr: Tree[T])
487-
extends TermTree[T] {
487+
extends Tree[T] {
488488
type ThisTree[-T >: Untyped] = Block[T]
489+
override def isTerm: Boolean = expr.isTerm
490+
override def isType: Boolean = expr.isType
489491
}
490492

491493
/** if cond then thenp else elsep */

compiler/src/dotty/tools/dotc/config/Printers.scala

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ object Printers {
2828
val overload: Printer = noPrinter
2929
val patmatch: Printer = noPrinter
3030
val pickling: Printer = noPrinter
31+
val quotePickling: Printer = noPrinter
3132
val plugins: Printer = noPrinter
3233
val simplify: Printer = noPrinter
3334
val subtyping: Printer = noPrinter

compiler/src/dotty/tools/dotc/core/quoted/PickledQuotes.scala

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -89,20 +89,20 @@ object PickledQuotes {
8989
if (tree.pos.exists)
9090
new PositionPickler(pickler, treePkl.buf.addrOfTree).picklePositions(tree :: Nil)
9191

92-
if (pickling ne noPrinter)
92+
if (quotePickling ne noPrinter)
9393
println(i"**** pickling quote of \n${tree.show}")
9494

9595
val pickled = pickler.assembleParts()
9696

97-
if (pickling ne noPrinter)
97+
if (quotePickling ne noPrinter)
9898
new TastyPrinter(pickled).printContents()
9999

100100
pickled
101101
}
102102

103103
/** Unpickle TASTY bytes into it's tree */
104104
private def unpickle(bytes: Array[Byte], splices: Seq[Any], isType: Boolean)(implicit ctx: Context): Tree = {
105-
if (pickling ne noPrinter) {
105+
if (quotePickling ne noPrinter) {
106106
println(i"**** unpickling quote from TASTY")
107107
new TastyPrinter(bytes).printContents()
108108
}
@@ -112,7 +112,7 @@ object PickledQuotes {
112112
unpickler.enter(Set.empty)
113113
val tree = unpickler.tree
114114

115-
if (pickling ne noPrinter)
115+
if (quotePickling ne noPrinter)
116116
println(i"**** unpickle quote ${tree.show}")
117117

118118
tree

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

Lines changed: 40 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -4,25 +4,35 @@ package core
44
package tasty
55

66
import Comments.CommentsContext
7-
import Contexts._, Symbols._, Types._, Scopes._, SymDenotations._, Names._, NameOps._
8-
import StdNames._, Flags._, Constants._, Annotations._
7+
import Contexts._
8+
import Symbols._
9+
import Types._
10+
import Scopes._
11+
import SymDenotations._
12+
import Names._
13+
import NameOps._
14+
import StdNames._
15+
import Flags._
16+
import Constants._
17+
import Annotations._
918
import NameKinds._
1019
import typer.Checking.checkNonCyclic
1120
import util.Positions._
12-
import ast.{tpd, untpd, Trees}
21+
import ast.{TreeTypeMap, Trees, tpd, untpd}
1322
import Trees._
1423
import Decorators._
1524
import transform.SymUtils._
1625
import TastyBuffer._
17-
import scala.annotation.{tailrec, switch}
26+
27+
import scala.annotation.{switch, tailrec}
1828
import scala.collection.mutable.ListBuffer
1929
import scala.collection.mutable
2030
import config.Printers.pickling
2131
import core.quoted.PickledQuotes
32+
2233
import scala.quoted
2334
import scala.quoted.Types.TreeType
2435
import scala.quoted.Exprs.TastyTreeExpr
25-
2636
import scala.annotation.internal.sharable
2737

2838
/** Unpickler for typed trees
@@ -353,8 +363,6 @@ class TreeUnpickler(reader: TastyReader,
353363
readTypeRef() match {
354364
case binder: LambdaType => binder.paramRefs(readNat())
355365
}
356-
case HOLE =>
357-
readHole(end, isType = true).tpe
358366
}
359367
assert(currentAddr == end, s"$start $currentAddr $end ${astTagToString(tag)}")
360368
result
@@ -1166,17 +1174,32 @@ class TreeUnpickler(reader: TastyReader,
11661174
setPos(start, tree)
11671175
}
11681176

1169-
def readTpt()(implicit ctx: Context): Tree =
1170-
if (nextByte == SHAREDterm) {
1171-
readByte()
1172-
forkAt(readAddr()).readTpt()
1173-
}
1174-
else if (isTypeTreeTag(nextByte)) readTerm()
1175-
else {
1176-
val start = currentAddr
1177-
val tp = readType()
1178-
if (tp.exists) setPos(start, TypeTree(tp)) else EmptyTree
1177+
def readTpt()(implicit ctx: Context): Tree = {
1178+
nextByte match {
1179+
case SHAREDterm =>
1180+
readByte()
1181+
forkAt(readAddr()).readTpt()
1182+
case BLOCK =>
1183+
readByte()
1184+
val end = readEnd()
1185+
val typeReader = fork
1186+
skipTree()
1187+
val aliases = readStats(ctx.owner, end)
1188+
val tpt = typeReader.readTpt()
1189+
Block(aliases, tpt)
1190+
case HOLE =>
1191+
readByte()
1192+
val end = readEnd()
1193+
readHole(end, isType = true)
1194+
case _ =>
1195+
if (isTypeTreeTag(nextByte)) readTerm()
1196+
else {
1197+
val start = currentAddr
1198+
val tp = readType()
1199+
if (tp.exists) setPos(start, TypeTree(tp)) else EmptyTree
1200+
}
11791201
}
1202+
}
11801203

11811204
def readCases(end: Addr)(implicit ctx: Context): List[CaseDef] =
11821205
collectWhile((nextUnsharedTag == CASEDEF) && currentAddr != end) {

compiler/src/dotty/tools/dotc/tastyreflect/TypeOrBoundsTreesOpsImpl.scala

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,13 @@ trait TypeOrBoundsTreesOpsImpl extends scala.tasty.reflect.TypeOrBoundsTreeOps w
120120
case _ => None
121121
}
122122
}
123+
124+
object Block extends BlockExtractor {
125+
def unapply(x: TypeTree)(implicit ctx: Context): Option[(List[TypeDef], TypeTree)] = x match {
126+
case x: tpd.Block => Some((x.stats.map { case alias: TypeDef => alias }, x.expr))
127+
case _ => None
128+
}
129+
}
123130
}
124131

125132
// ----- TypeBoundsTrees ------------------------------------------------

library/src-scala3/scala/StagedTuple.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -208,7 +208,7 @@ object StagedTuple {
208208
that
209209
case Some(1) =>
210210
if (thatSize.contains(0)) self
211-
else stagedCons(that, self.as[Tuple1[_]], thatSize)
211+
else stagedCons(that, '((~self).asInstanceOf[Tuple1[_]]._1), thatSize)
212212
case Some(2) =>
213213
val self2 = self.as[Tuple2[_, _]]
214214
thatSize match {

library/src-scala3/scala/Tuple.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ object Tuple {
2626
inline val $MaxSpecialized = 22
2727
inline private val XXL = $MaxSpecialized + 1
2828

29-
final val specialize = false
29+
final val specialize = true
3030

3131
type Head[+X <: NonEmptyTuple] = X match {
3232
case x *: _ => x

library/src/scala/tasty/reflect/TypeOrBoundsTreeOps.scala

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,11 @@ trait TypeOrBoundsTreeOps extends TastyCore {
9191
abstract class BindExtractor{
9292
def unapply(typeOrBoundsTree: TypeOrBoundsTree)(implicit ctx: Context): Option[(String, TypeBoundsTree)]
9393
}
94+
95+
val Block: BlockExtractor
96+
abstract class BlockExtractor{
97+
def unapply(typeOrBoundsTree: TypeOrBoundsTree)(implicit ctx: Context): Option[(List[TypeDef], TypeTree)]
98+
}
9499
}
95100

96101
// ----- TypeBoundsTrees ------------------------------------------------

library/src/scala/tasty/util/ShowExtractors.scala

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -116,9 +116,11 @@ class ShowExtractors[T <: Tasty with Singleton](tasty0: T) extends Show[T](tasty
116116
case TypeTree.Annotated(arg, annot) =>
117117
this += "TypeTree.Annotated(" += arg += ", " += annot += ")"
118118
case TypeTree.TypeLambdaTree(tparams, body) =>
119-
this += "LambdaTypeTree(" ++= tparams += ", " += body += ")"
119+
this += "TypeTree.LambdaTypeTree(" ++= tparams += ", " += body += ")"
120120
case TypeTree.Bind(name, bounds) =>
121-
this += "Bind(" += name += ", " += bounds += ")"
121+
this += "TypeTree.Bind(" += name += ", " += bounds += ")"
122+
case TypeTree.Block(aliases, tpt) =>
123+
this += "TypeTree.Block(" ++= aliases += ", " += tpt += ")"
122124
case TypeBoundsTree(lo, hi) =>
123125
this += "TypeBoundsTree(" += lo += ", " += hi += ")"
124126
case SyntheticBounds() =>

library/src/scala/tasty/util/ShowSourceCode.scala

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -829,6 +829,12 @@ class ShowSourceCode[T <: Tasty with Singleton](tasty0: T) extends Show[T](tasty
829829
case TypeTree.Bind(name, _) =>
830830
this += highlightTypeDef(name, color)
831831

832+
case TypeTree.Block(aliases, tpt) =>
833+
inBlock {
834+
printTrees(aliases, lineBreak())
835+
printTypeTree(tpt)
836+
}
837+
832838
case _ =>
833839
throw new MatchError(tree.show)
834840

tests/run-with-compiler/i5247.check

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
null.asInstanceOf[lang.Object]
2+
null.asInstanceOf[scala.List[lang.Object]]

tests/run-with-compiler/i5247.scala

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import scala.quoted._
2+
object Test {
3+
def main(args: Array[String]): Unit = {
4+
implicit val toolbox: scala.quoted.Toolbox = scala.quoted.Toolbox.make
5+
println(foo[Object].show)
6+
println(bar[Object].show)
7+
}
8+
def foo[H : Type]: Expr[H] = {
9+
val t = '[H]
10+
'{ null.asInstanceOf[~t] }
11+
}
12+
def bar[H : Type]: Expr[List[H]] = {
13+
val t = '[List[H]]
14+
'{ null.asInstanceOf[~t] }
15+
}
16+
}

tests/run-with-compiler/quote-owners-2.check

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
{
33
def ff: scala.Int = {
44
val a: immutable.List[scala.Int] = {
5-
type T = immutable.List[scala.Int]
5+
type T = scala.List[scala.Int]
66
val b: T = scala.Nil.::[scala.Int](3)
77
(b: collection.immutable.List[scala.Int])
88
}

0 commit comments

Comments
 (0)