summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJason Zaugg <jzaugg@gmail.com>2016-05-31 15:19:49 +1000
committerJason Zaugg <jzaugg@gmail.com>2016-05-31 15:49:33 +1000
commit7b132f39b82e4fc47cd95eadce9e3f22da8c8d82 (patch)
treeb4f07a4be51dd1e92e8fdfc0b6756bc4946065e3
parent8f567bc9c01e29624f5b7fcce40a0ee7fe261c08 (diff)
downloadscala-7b132f39b82e4fc47cd95eadce9e3f22da8c8d82.tar.gz
scala-7b132f39b82e4fc47cd95eadce9e3f22da8c8d82.tar.bz2
scala-7b132f39b82e4fc47cd95eadce9e3f22da8c8d82.zip
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.
-rw-r--r--src/reflect/scala/reflect/api/Internals.scala6
-rw-r--r--src/reflect/scala/reflect/internal/Internals.scala2
-rw-r--r--src/reflect/scala/reflect/internal/Trees.scala2
3 files changed, 5 insertions, 5 deletions
diff --git a/src/reflect/scala/reflect/api/Internals.scala b/src/reflect/scala/reflect/api/Internals.scala
index 9b7112f011..2c8f84be0b 100644
--- a/src/reflect/scala/reflect/api/Internals.scala
+++ b/src/reflect/scala/reflect/api/Internals.scala
@@ -116,7 +116,7 @@ trait Internals { self: Universe =>
/** Substitute given tree `to` for occurrences of nodes that represent
* `C.this`, where `C` refers to the given class `clazz`.
*/
- def substituteThis(tree: Tree, clazz: Symbol, to: Tree): Tree
+ def substituteThis(tree: Tree, clazz: Symbol, to: => Tree): Tree
/** A factory method for `ClassDef` nodes.
*/
@@ -391,7 +391,7 @@ trait Internals { self: Universe =>
def substituteTypes(from: List[Symbol], to: List[Type]): Tree = internal.substituteTypes(tree, from, to)
/** @see [[internal.substituteThis]] */
- def substituteThis(clazz: Symbol, to: Tree): Tree = internal.substituteThis(tree, clazz, to)
+ def substituteThis(clazz: Symbol, to: => Tree): Tree = internal.substituteThis(tree, clazz, to)
}
/** Extension methods for symbols */
@@ -1143,7 +1143,7 @@ trait Internals { self: Universe =>
/** @see [[InternalApi.substituteThis]] */
@deprecated("use `internal.substituteThis` instead or import `internal.decorators._` for infix syntax", "2.11.0")
- def substituteThis(clazz: Symbol, to: Tree): Tree = internal.substituteThis(tree, clazz, to)
+ def substituteThis(clazz: Symbol, to: => Tree): Tree = internal.substituteThis(tree, clazz, to)
}
/** Scala 2.10 compatibility enrichments for Tree. */
diff --git a/src/reflect/scala/reflect/internal/Internals.scala b/src/reflect/scala/reflect/internal/Internals.scala
index 1a48701ca7..a07441e3ca 100644
--- a/src/reflect/scala/reflect/internal/Internals.scala
+++ b/src/reflect/scala/reflect/internal/Internals.scala
@@ -29,7 +29,7 @@ trait Internals extends api.Internals {
def freeTypes(tree: Tree): List[FreeTypeSymbol] = tree.freeTypes
def substituteSymbols(tree: Tree, from: List[Symbol], to: List[Symbol]): Tree = tree.substituteSymbols(from, to)
def substituteTypes(tree: Tree, from: List[Symbol], to: List[Type]): Tree = tree.substituteTypes(from, to)
- def substituteThis(tree: Tree, clazz: Symbol, to: Tree): Tree = tree.substituteThis(clazz, to)
+ def substituteThis(tree: Tree, clazz: Symbol, to: => Tree): Tree = tree.substituteThis(clazz, to)
def attachments(tree: Tree): Attachments { type Pos = Position } = tree.attachments
def updateAttachment[T: ClassTag](tree: Tree, attachment: T): tree.type = tree.updateAttachment(attachment)
def removeAttachment[T: ClassTag](tree: Tree): tree.type = tree.removeAttachment[T]
diff --git a/src/reflect/scala/reflect/internal/Trees.scala b/src/reflect/scala/reflect/internal/Trees.scala
index c9dfd0c337..77097d892d 100644
--- a/src/reflect/scala/reflect/internal/Trees.scala
+++ b/src/reflect/scala/reflect/internal/Trees.scala
@@ -181,7 +181,7 @@ trait Trees extends api.Trees {
def substituteTypes(from: List[Symbol], to: List[Type]): Tree =
new TreeTypeSubstituter(from, to)(this)
- def substituteThis(clazz: Symbol, to: Tree): Tree =
+ def substituteThis(clazz: Symbol, to: => Tree): Tree =
new ThisSubstituter(clazz, to) transform this
def hasExistingSymbol = (symbol ne null) && (symbol ne NoSymbol)