diff options
author | Paul Phillips <paulp@improving.org> | 2011-04-23 15:14:59 +0000 |
---|---|---|
committer | Paul Phillips <paulp@improving.org> | 2011-04-23 15:14:59 +0000 |
commit | ffe789dd78c24dc82a74553f2634c6ebb1a32e38 (patch) | |
tree | db6d44a39877ec89c0a4ed3f1017f5a14dacf4f7 | |
parent | 6af1d5c526a6394065bb8d42ff1df36e8cb4272b (diff) | |
download | scala-ffe789dd78c24dc82a74553f2634c6ebb1a32e38.tar.gz scala-ffe789dd78c24dc82a74553f2634c6ebb1a32e38.tar.bz2 scala-ffe789dd78c24dc82a74553f2634c6ebb1a32e38.zip |
Strip unused pattern variable bindings out befo...
Strip unused pattern variable bindings out before performing match
translation. Closes #4269, no review.
-rw-r--r-- | src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala | 22 | ||||
-rw-r--r-- | test/files/pos/bug4269.scala | 5 |
2 files changed, 22 insertions, 5 deletions
diff --git a/src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala b/src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala index f7fa9f57ee..8969196da1 100644 --- a/src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala +++ b/src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala @@ -68,6 +68,13 @@ abstract class ExplicitOuter extends InfoTransform result } + class RemoveBindingsTransformer(toRemove: Set[Symbol]) extends Transformer { + override def transform(tree: Tree) = tree match { + case Bind(_, body) if toRemove(tree.symbol) => super.transform(body) + case _ => super.transform(tree) + } + } + /** Issue a migration warning for instance checks which might be on an Array and * for which the type parameter conforms to Seq, because these answers changed in 2.8. */ @@ -374,18 +381,23 @@ abstract class ExplicitOuter extends InfoTransform val nguard = new ListBuffer[Tree] val ncases = - for (CaseDef(p, guard, b) <- cases) yield { + for (CaseDef(pat, guard, body) <- cases) yield { + // Strip out any unused pattern bindings up front + val patternIdents = for (b @ Bind(_, _) <- pat) yield b.symbol + val references: Set[Symbol] = Set(guard, body) flatMap { t => for (id @ Ident(name) <- t) yield id.symbol } + val (used, unused) = patternIdents partition references + val strippedPat = if (unused.isEmpty) pat else new RemoveBindingsTransformer(unused.toSet) transform pat + val gdcall = if (guard == EmptyTree) EmptyTree else { - val vs = Pattern(p).deepBoundVariables - val guardDef = makeGuardDef(vs, guard) + val guardDef = makeGuardDef(used, guard) nguard += transform(guardDef) // building up list of guards - localTyper typed (Ident(guardDef.symbol) APPLY (vs map Ident)) + localTyper typed (Ident(guardDef.symbol) APPLY (used map Ident)) } - (CASE(transform(p)) IF gdcall) ==> transform(b) + (CASE(transform(strippedPat)) IF gdcall) ==> transform(body) } def isUncheckedAnnotation(tpe: Type) = tpe hasAnnotation UncheckedClass diff --git a/test/files/pos/bug4269.scala b/test/files/pos/bug4269.scala new file mode 100644 index 0000000000..99a30785b4 --- /dev/null +++ b/test/files/pos/bug4269.scala @@ -0,0 +1,5 @@ +class A { + PartialFunction.condOpt(Nil) { + case items@List(_*) if true => + } +} |