Skip to content

Commit e4ad8a1

Browse files
nicolasstuckiKordyjan
authored andcommitted
Simplify avoidance of non-picklable types of Hole
[Cherry-picked 8764778]
1 parent 17e595d commit e4ad8a1

File tree

1 file changed

+12
-36
lines changed

1 file changed

+12
-36
lines changed

compiler/src/dotty/tools/dotc/transform/PickleQuotes.scala

Lines changed: 12 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,13 @@ import dotty.tools.dotc.ast.tpd
1717
import dotty.tools.dotc.ast.untpd
1818
import dotty.tools.dotc.config.ScalaRelease.*
1919

20-
import scala.collection.mutable
2120
import dotty.tools.dotc.core.Annotations._
2221
import dotty.tools.dotc.core.StdNames._
2322
import dotty.tools.dotc.quoted._
2423
import dotty.tools.dotc.inlines.Inlines
2524

2625
import scala.annotation.constructorOnly
26+
import scala.collection.mutable
2727

2828
/** Translates quoted terms and types to `unpickleExprV2` or `unpickleType` method calls.
2929
*
@@ -106,16 +106,19 @@ class PickleQuotes extends MacroTransform {
106106
private def extractHolesContents(quote: tpd.Quote)(using Context): (List[Tree], tpd.Quote) =
107107
class HoleContentExtractor extends Transformer:
108108
private val holeContents = List.newBuilder[Tree]
109+
private val stagedClasses = mutable.HashSet.empty[Symbol]
109110
override def transform(tree: tpd.Tree)(using Context): tpd.Tree =
110111
tree match
111112
case tree @ Hole(isTerm, _, _, content) =>
112113
assert(isTerm)
113114
assert(!content.isEmpty)
114115
holeContents += content
115-
val holeType = getTermHoleType(tree.tpe)
116+
val holeType = getPicklableHoleType(tree.tpe, stagedClasses)
116117
val hole = untpd.cpy.Hole(tree)(content = EmptyTree).withType(holeType)
117118
cpy.Inlined(tree)(EmptyTree, Nil, hole)
118119
case tree: DefTree =>
120+
if tree.symbol.isClass then
121+
stagedClasses += tree.symbol
119122
val newAnnotations = tree.symbol.annotations.mapconserve { annot =>
120123
annot.derivedAnnotation(transform(annot.tree)(using ctx.withOwner(tree.symbol)))
121124
}
@@ -134,19 +137,6 @@ class PickleQuotes extends MacroTransform {
134137
}
135138
}
136139

137-
/** Remove references to local types that will not be defined in this quote */
138-
private def getTermHoleType(using Context) = new TypeMap() {
139-
override def apply(tp: Type): Type = tp match
140-
case tp @ TypeRef(NoPrefix, _) =>
141-
// reference to term with a type defined in outer quote
142-
getTypeHoleType(tp)
143-
case tp @ TermRef(NoPrefix, _) =>
144-
// widen term refs to terms defined in outer quote
145-
apply(tp.widenTermRefExpr)
146-
case tp =>
147-
mapOver(tp)
148-
}
149-
150140
/** Get the holeContents of the transformed tree */
151141
def getContents() =
152142
val res = holeContents.result
@@ -196,11 +186,11 @@ class PickleQuotes extends MacroTransform {
196186
cpy.Quote(quote)(Block(tdefs, body1), quote.tags)
197187

198188
private def mkTagSymbolAndAssignType(typeArg: Tree, idx: Int)(using Context): TypeDef = {
199-
val holeType = getTypeHoleType(typeArg.tpe.select(tpnme.Underlying))
189+
val holeType = getPicklableHoleType(typeArg.tpe.select(tpnme.Underlying), _ => false)
200190
val hole = untpd.cpy.Hole(typeArg)(isTerm = false, idx, Nil, EmptyTree).withType(holeType)
201191
val local = newSymbol(
202192
owner = ctx.owner,
203-
name = UniqueName.fresh(hole.tpe.dealias.typeSymbol.name.toTypeName),
193+
name = UniqueName.fresh(typeArg.symbol.name.toTypeName),
204194
flags = Synthetic,
205195
info = TypeAlias(typeArg.tpe.select(tpnme.Underlying)),
206196
coord = typeArg.span
@@ -209,25 +199,11 @@ class PickleQuotes extends MacroTransform {
209199
ctx.typeAssigner.assignType(untpd.TypeDef(local.name, hole), local).withSpan(typeArg.span)
210200
}
211201

212-
/** Remove references to local types that will not be defined in this quote */
213-
private def getTypeHoleType(using Context) = new TypeMap() {
214-
override def apply(tp: Type): Type = tp match
215-
case tp: TypeRef if tp.typeSymbol.isTypeSplice =>
216-
apply(tp.dealias)
217-
case tp @ TypeRef(pre, _) if isLocalPath(pre) =>
218-
val hiBound = tp.typeSymbol.info match
219-
case info: ClassInfo => info.parents.reduce(_ & _)
220-
case info => info.hiBound
221-
apply(hiBound)
222-
case tp =>
223-
mapOver(tp)
224-
225-
private def isLocalPath(tp: Type): Boolean = tp match
226-
case NoPrefix => true
227-
case tp: TermRef if !tp.symbol.is(Package) => isLocalPath(tp.prefix)
228-
case tp => false
229-
}
230-
202+
/** Avoid all non-static types except those defined in the quote. */
203+
private def getPicklableHoleType(tpe: Type, isStagedClasses: Symbol => Boolean)(using Context) =
204+
new TypeOps.AvoidMap {
205+
def toAvoid(tp: NamedType) = !isStagedClasses(tp.typeSymbol) && !isStaticPrefix(tp)
206+
}.apply(tpe)
231207
}
232208

233209
object PickleQuotes {

0 commit comments

Comments
 (0)