@@ -5,6 +5,7 @@ import dotty.tools.dotc.ast.{TreeTypeMap, tpd}
5
5
import dotty .tools .dotc .config .Printers ._
6
6
import dotty .tools .dotc .core .Contexts ._
7
7
import dotty .tools .dotc .core .Decorators ._
8
+ import dotty .tools .dotc .core .Flags ._
8
9
import dotty .tools .dotc .core .Mode
9
10
import dotty .tools .dotc .core .Symbols ._
10
11
import dotty .tools .dotc .core .Types ._
@@ -248,23 +249,39 @@ object PickledQuotes {
248
249
case pickled : String => TastyString .unpickle(pickled)
249
250
case pickled : List [String ] => TastyString .unpickle(pickled)
250
251
251
- quotePickling.println(s " **** unpickling quote from TASTY \n ${TastyPrinter .showContents(bytes, ctx.settings.color.value == " never" )}" )
252
+ val unpicklingContext =
253
+ if ctx.owner.isClass then
254
+ // When a quote is unpickled with a Quotes context that that has a class `spliceOwner`
255
+ // we need to use a dummy owner to unpickle it. Otherwise any definitions defined
256
+ // in the quoted block would be accidentally entered in the class.
257
+ // This owner is replaced with the correct owner when at the splice site.
258
+ //
259
+ // Quotes context that that has a class `spliceOwner` can come from a macro annotation
260
+ // or a user setting it explicitly using `Symbol.asQuotes`.
261
+ ctx.withOwner(newSymbol(ctx.owner, " $quoteOwnedByClass$" .toTermName, Private , defn.AnyType , NoSymbol ))
262
+ else ctx
252
263
253
- val mode = if (isType) UnpickleMode .TypeTree else UnpickleMode .Term
254
- val unpickler = new DottyUnpickler (bytes, mode)
255
- unpickler.enter(Set .empty)
264
+ inContext(unpicklingContext) {
256
265
257
- val tree = unpickler.tree
258
- QuotesCache (pickled) = tree
266
+ quotePickling.println(s " **** unpickling quote from TASTY \n ${TastyPrinter .showContents(bytes, ctx.settings.color.value == " never" )}" )
259
267
260
- // Make sure trees and positions are fully loaded
261
- new TreeTraverser {
262
- def traverse (tree : Tree )(using Context ): Unit = traverseChildren(tree)
263
- }.traverse(tree)
268
+ val mode = if (isType) UnpickleMode .TypeTree else UnpickleMode .Term
269
+ val unpickler = new DottyUnpickler (bytes, mode)
270
+ unpickler.enter(Set .empty)
264
271
265
- quotePickling.println(i " **** unpickled quote \n $tree" )
272
+ var tree = unpickler.tree
273
+ QuotesCache (pickled) = tree
274
+
275
+ // Make sure trees and positions are fully loaded
276
+ new TreeTraverser {
277
+ def traverse (tree : Tree )(using Context ): Unit = traverseChildren(tree)
278
+ }.traverse(tree)
279
+
280
+ quotePickling.println(i " **** unpickled quote \n $tree" )
281
+
282
+ tree
283
+ }
266
284
267
- tree
268
285
}
269
286
270
287
}
0 commit comments