From 9066ffa93eee761b2bfdb0953d9fe695402de425 Mon Sep 17 00:00:00 2001 From: Paul Phillips Date: Tue, 19 Oct 2010 22:55:04 +0000 Subject: As pointed out to me by plocinic, the pattern m... As pointed out to me by plocinic, the pattern matcher has been indiscriminately clearing the MUTABLE flag on synthetic vals because it is signalling itself with that bit and it didn't think anyone else would ever notice. Someone did. Closes #3699, review by plocinic. --- src/compiler/scala/tools/nsc/matching/Matrix.scala | 18 ++++++++++++++++-- .../scala/tools/nsc/matching/MatrixAdditions.scala | 12 +----------- test/files/run/bug3699.scala | 11 +++++++++++ 3 files changed, 28 insertions(+), 13 deletions(-) create mode 100644 test/files/run/bug3699.scala diff --git a/src/compiler/scala/tools/nsc/matching/Matrix.scala b/src/compiler/scala/tools/nsc/matching/Matrix.scala index f7f7b2cc41..800200b897 100644 --- a/src/compiler/scala/tools/nsc/matching/Matrix.scala +++ b/src/compiler/scala/tools/nsc/matching/Matrix.scala @@ -8,6 +8,7 @@ package matching import transform.ExplicitOuter import symtab.Flags +import scala.collection.mutable trait Matrix extends MatrixAdditions { self: ExplicitOuter with ParallelMatching => @@ -16,7 +17,7 @@ trait Matrix extends MatrixAdditions { import analyzer.Typer import CODE._ import Debug._ - import Flags.{ TRANS_FLAG, SYNTHETIC } + import Flags.{ TRANS_FLAG, SYNTHETIC, MUTABLE } /** Translation of match expressions. * @@ -117,6 +118,19 @@ trait Matrix extends MatrixAdditions { // TRANS_FLAG communicates there should be no exhaustiveness checking private def flags(checked: Boolean) = if (checked) Nil else List(TRANS_FLAG) + // Recording the symbols of the synthetics we create so we don't go clearing + // anyone else's mutable flags. + private val _syntheticSyms = mutable.HashSet[Symbol]() + def clearSyntheticSyms() = { + _syntheticSyms foreach (_ resetFlag (TRANS_FLAG|MUTABLE)) + log("Cleared TRANS_FLAG/MUTABLE on " + _syntheticSyms.size + " synthetic symbols.") + _syntheticSyms.clear() + } + def recordSyntheticSym(sym: Symbol): Symbol = { + _syntheticSyms += sym + sym + } + case class MatrixInit( roots: List[PatternVar], cases: List[CaseDef], @@ -235,7 +249,7 @@ trait Matrix extends MatrixAdditions { { val n: Name = if (name == null) newName("temp") else name // careful: pos has special meaning - owner.newVariable(pos, n) setInfo tpe setFlag (SYNTHETIC.toLong /: flags)(_|_) + recordSyntheticSym(owner.newVariable(pos, n) setInfo tpe setFlag (SYNTHETIC.toLong /: flags)(_|_)) } def typedValDef(x: Symbol, rhs: Tree) = diff --git a/src/compiler/scala/tools/nsc/matching/MatrixAdditions.scala b/src/compiler/scala/tools/nsc/matching/MatrixAdditions.scala index 55613c5bd7..ee4eb64e89 100644 --- a/src/compiler/scala/tools/nsc/matching/MatrixAdditions.scala +++ b/src/compiler/scala/tools/nsc/matching/MatrixAdditions.scala @@ -127,18 +127,8 @@ trait MatrixAdditions extends ast.TreeDSL }) } } - object resetTraverser extends Traverser { - import Flags._ - def reset(vd: ValDef) = - if (vd.symbol hasFlag SYNTHETIC) vd.symbol resetFlag (TRANS_FLAG|MUTABLE) - - override def traverse(x: Tree): Unit = x match { - case vd: ValDef => reset(vd) - case _ => super.traverse(x) - } - } - returning(lxtt transform tree)(resetTraverser traverse _) + returning(lxtt transform tree)(_ => clearSyntheticSyms()) } } diff --git a/test/files/run/bug3699.scala b/test/files/run/bug3699.scala new file mode 100644 index 0000000000..0475353887 --- /dev/null +++ b/test/files/run/bug3699.scala @@ -0,0 +1,11 @@ +object Test { + def act: Int => Int = { + case _ => + lazy val (a, b) = (3,9) + a + b + } + def main(args: Array[String]) = { + assert(act(1) == 9) + } +} \ No newline at end of file -- cgit v1.2.3