diff options
author | James Iry <jamesiry@gmail.com> | 2013-02-08 07:35:28 -0800 |
---|---|---|
committer | James Iry <jamesiry@gmail.com> | 2013-02-08 07:35:28 -0800 |
commit | 3b6300b14b8aaac4c6bb7c70b51ef1df3dc3c536 (patch) | |
tree | a61374b070df32a04643be7d2ac348034d8cdf77 /src | |
parent | c0d1bc4cc4cb2958af69305d286ff684306617a5 (diff) | |
parent | 5258b63740c9fb1be3c531e1dc1399fb0dc55569 (diff) | |
download | scala-3b6300b14b8aaac4c6bb7c70b51ef1df3dc3c536.tar.gz scala-3b6300b14b8aaac4c6bb7c70b51ef1df3dc3c536.tar.bz2 scala-3b6300b14b8aaac4c6bb7c70b51ef1df3dc3c536.zip |
Merge pull request #2092 from lrytz/t7096
SI-7096 SubstSymMap copies trees before modifying their symbols
Diffstat (limited to 'src')
-rw-r--r-- | src/reflect/scala/reflect/internal/Types.scala | 42 |
1 files changed, 29 insertions, 13 deletions
diff --git a/src/reflect/scala/reflect/internal/Types.scala b/src/reflect/scala/reflect/internal/Types.scala index b708ca0fd6..fb493fabd8 100644 --- a/src/reflect/scala/reflect/internal/Types.scala +++ b/src/reflect/scala/reflect/internal/Types.scala @@ -4698,23 +4698,39 @@ trait Types extends api.Types { self: SymbolTable => } } - override def mapOver(tree: Tree, giveup: ()=>Nothing): Tree = { - object trans extends TypeMapTransformer { + object mapTreeSymbols extends TypeMapTransformer { + val strictCopy = newStrictTreeCopier - def termMapsTo(sym: Symbol) = from indexOf sym match { - case -1 => None - case idx => Some(to(idx)) - } + def termMapsTo(sym: Symbol) = from indexOf sym match { + case -1 => None + case idx => Some(to(idx)) + } - override def transform(tree: Tree) = { - termMapsTo(tree.symbol) match { - case Some(tosym) => tree.symbol = tosym - case None => () - } - super.transform(tree) + // if tree.symbol is mapped to another symbol, passes the new symbol into the + // constructor `trans` and sets the symbol and the type on the resulting tree. + def transformIfMapped(tree: Tree)(trans: Symbol => Tree) = termMapsTo(tree.symbol) match { + case Some(toSym) => trans(toSym) setSymbol toSym setType tree.tpe + case None => tree + } + + // changes trees which refer to one of the mapped symbols. trees are copied before attributes are modified. + override def transform(tree: Tree) = { + // super.transform maps symbol references in the types of `tree`. it also copies trees where necessary. + super.transform(tree) match { + case id @ Ident(_) => + transformIfMapped(id)(toSym => + strictCopy.Ident(id, toSym.name)) + + case sel @ Select(qual, name) => + transformIfMapped(sel)(toSym => + strictCopy.Select(sel, qual, toSym.name)) + + case tree => tree } } - trans.transform(tree) + } + override def mapOver(tree: Tree, giveup: ()=>Nothing): Tree = { + mapTreeSymbols.transform(tree) } } |