Skip to content

Commit 7d4f934

Browse files
committed
Fix spliced-captured this
1 parent 2731ec5 commit 7d4f934

File tree

4 files changed

+44
-5
lines changed

4 files changed

+44
-5
lines changed

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -203,6 +203,9 @@ class PickleQuotes extends MacroTransform {
203203
private def getPicklableHoleType(tpe: Type, isStagedClasses: Symbol => Boolean)(using Context) =
204204
new TypeOps.AvoidMap {
205205
def toAvoid(tp: NamedType) = !isStagedClasses(tp.typeSymbol) && !isStaticPrefix(tp)
206+
override def apply(tp: Type): Type = tp match
207+
case tp: ThisType /*if isStagedClasses(tp.typeSymbol)*/ => super.apply(tp.widen) // FIXME: isStagedClasses is empty when transforming the inner splice.
208+
case _ => super.apply(tp)
206209
}.apply(tpe)
207210
}
208211

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

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -167,14 +167,15 @@ class Splicing extends MacroTransform:
167167
* ```
168168
*/
169169
private class SpliceTransformer(spliceOwner: Symbol, isCaptured: Symbol => Boolean) extends Transformer:
170-
private var refBindingMap = mutable.LinkedHashMap.empty[Symbol, (Tree, Symbol)]
170+
private var refTermBindingMap = mutable.LinkedHashMap.empty[Symbol, (Tree, Symbol)]
171+
private var refTypeBindingMap = mutable.LinkedHashMap.empty[Symbol, (Tree, Symbol)]
171172
/** Reference to the `Quotes` instance of the current level 1 splice */
172173
private var quotes: Tree | Null = null // TODO: add to the context
173174

174175
def transformSplice(tree: tpd.Tree, tpe: Type, holeIdx: Int)(using Context): tpd.Tree =
175176
assert(level == 0)
176177
val newTree = transform(tree)
177-
val (refs, bindings) = refBindingMap.values.toList.unzip
178+
val (refs, bindings) = (refTypeBindingMap.values ++ refTermBindingMap.values).toList.unzip
178179
val bindingsTypes = bindings.map(_.termRef.widenTermRefExpr)
179180
val methType = MethodType(bindingsTypes, newTree.tpe)
180181
val meth = newSymbol(spliceOwner, nme.ANON_FUN, Synthetic | Method, methType)
@@ -212,6 +213,11 @@ class Splicing extends MacroTransform:
212213
case _: TypeTree | _: SingletonTypeTree =>
213214
if containsCapturedType(tree.tpe) && level >= 1 then getTagRefFor(tree)
214215
else tree
216+
case _: This =>
217+
if isCaptured(tree.symbol) then
218+
val tag = getTagRefFor(tree)
219+
spliced(tag.tpe)(capturedTerm(tree))
220+
else super.transform(tree)
215221
case tree @ Assign(lhs: RefTree, rhs) =>
216222
if isCaptured(lhs.symbol) then transformSplicedAssign(tree)
217223
else super.transform(tree)
@@ -302,7 +308,7 @@ class Splicing extends MacroTransform:
302308
Param,
303309
defn.QuotedExprClass.typeRef.appliedTo(tpe),
304310
)
305-
val bindingSym = refBindingMap.getOrElseUpdate(tree.symbol, (tree, newBinding))._2
311+
val bindingSym = refTermBindingMap.getOrElseUpdate(tree.symbol, (tree, newBinding))._2
306312
ref(bindingSym)
307313

308314
private def newQuotedTypeClassBinding(tpe: Type)(using Context) =
@@ -314,14 +320,14 @@ class Splicing extends MacroTransform:
314320
)
315321

316322
private def capturedType(tree: Tree)(using Context): Symbol =
317-
refBindingMap.getOrElseUpdate(tree.symbol, (TypeTree(tree.tpe), newQuotedTypeClassBinding(tree.tpe)))._2
323+
refTypeBindingMap.getOrElseUpdate(tree.symbol, (TypeTree(tree.tpe), newQuotedTypeClassBinding(tree.tpe)))._2
318324

319325
private def capturedPartTypes(quote: Quote)(using Context): Tree =
320326
val (tags, body1) = inContextWithQuoteTypeTags {
321327
val capturePartTypes = new TypeMap {
322328
def apply(tp: Type) = tp match {
323329
case typeRef: TypeRef if containsCapturedType(typeRef) =>
324-
val termRef = refBindingMap
330+
val termRef = refTypeBindingMap
325331
.getOrElseUpdate(typeRef.symbol, (TypeTree(typeRef), newQuotedTypeClassBinding(typeRef)))._2.termRef
326332
val tagRef = getTagRef(termRef)
327333
tagRef
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
import scala.quoted.*
2+
3+
object Macro:
4+
inline def generateCode: Unit = ${ testThisPaths }
5+
6+
def testThisPaths(using Quotes): Expr[Unit] =
7+
'{
8+
trait E extends G:
9+
type V
10+
val f: F
11+
${
12+
val expr = '{
13+
// println(this) // FIXME: this should work
14+
// println(f) // FIXME: this should work
15+
// println(this.f) // FIXME: this should work
16+
// println(??? : this.type) // FIXME: this should work
17+
println(??? : V)
18+
println(??? : this.V)
19+
println(??? : this.f.V)
20+
println(??? : this.f.type)
21+
}
22+
expr
23+
}
24+
trait F:
25+
type V
26+
}
27+
28+
trait G:
29+
val f: Any
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
@main def test = Macro.generateCode

0 commit comments

Comments
 (0)