Skip to content

Commit 7b132f3

Browse files
committed
Avoid tree sharing with substituteThis
The underlying transformer has a by-name parameter for the to provide the `to` tree, but this was strict in the layers of API above. Tree sharing is frowned upon in general as it leads to cross talk when, e.g., the erasure typechecker mutates the `tpe` field of the shared tree in different context.
1 parent 8f567bc commit 7b132f3

File tree

3 files changed

+5
-5
lines changed

3 files changed

+5
-5
lines changed

src/reflect/scala/reflect/api/Internals.scala

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@ trait Internals { self: Universe =>
116116
/** Substitute given tree `to` for occurrences of nodes that represent
117117
* `C.this`, where `C` refers to the given class `clazz`.
118118
*/
119-
def substituteThis(tree: Tree, clazz: Symbol, to: Tree): Tree
119+
def substituteThis(tree: Tree, clazz: Symbol, to: => Tree): Tree
120120

121121
/** A factory method for `ClassDef` nodes.
122122
*/
@@ -391,7 +391,7 @@ trait Internals { self: Universe =>
391391
def substituteTypes(from: List[Symbol], to: List[Type]): Tree = internal.substituteTypes(tree, from, to)
392392

393393
/** @see [[internal.substituteThis]] */
394-
def substituteThis(clazz: Symbol, to: Tree): Tree = internal.substituteThis(tree, clazz, to)
394+
def substituteThis(clazz: Symbol, to: => Tree): Tree = internal.substituteThis(tree, clazz, to)
395395
}
396396

397397
/** Extension methods for symbols */
@@ -1143,7 +1143,7 @@ trait Internals { self: Universe =>
11431143

11441144
/** @see [[InternalApi.substituteThis]] */
11451145
@deprecated("use `internal.substituteThis` instead or import `internal.decorators._` for infix syntax", "2.11.0")
1146-
def substituteThis(clazz: Symbol, to: Tree): Tree = internal.substituteThis(tree, clazz, to)
1146+
def substituteThis(clazz: Symbol, to: => Tree): Tree = internal.substituteThis(tree, clazz, to)
11471147
}
11481148

11491149
/** Scala 2.10 compatibility enrichments for Tree. */

src/reflect/scala/reflect/internal/Internals.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ trait Internals extends api.Internals {
2929
def freeTypes(tree: Tree): List[FreeTypeSymbol] = tree.freeTypes
3030
def substituteSymbols(tree: Tree, from: List[Symbol], to: List[Symbol]): Tree = tree.substituteSymbols(from, to)
3131
def substituteTypes(tree: Tree, from: List[Symbol], to: List[Type]): Tree = tree.substituteTypes(from, to)
32-
def substituteThis(tree: Tree, clazz: Symbol, to: Tree): Tree = tree.substituteThis(clazz, to)
32+
def substituteThis(tree: Tree, clazz: Symbol, to: => Tree): Tree = tree.substituteThis(clazz, to)
3333
def attachments(tree: Tree): Attachments { type Pos = Position } = tree.attachments
3434
def updateAttachment[T: ClassTag](tree: Tree, attachment: T): tree.type = tree.updateAttachment(attachment)
3535
def removeAttachment[T: ClassTag](tree: Tree): tree.type = tree.removeAttachment[T]

src/reflect/scala/reflect/internal/Trees.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -181,7 +181,7 @@ trait Trees extends api.Trees {
181181
def substituteTypes(from: List[Symbol], to: List[Type]): Tree =
182182
new TreeTypeSubstituter(from, to)(this)
183183

184-
def substituteThis(clazz: Symbol, to: Tree): Tree =
184+
def substituteThis(clazz: Symbol, to: => Tree): Tree =
185185
new ThisSubstituter(clazz, to) transform this
186186

187187
def hasExistingSymbol = (symbol ne null) && (symbol ne NoSymbol)

0 commit comments

Comments
 (0)