aboutsummaryrefslogtreecommitdiff
path: root/src/dotty
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2013-12-27 16:27:39 +0100
committerMartin Odersky <odersky@gmail.com>2013-12-27 16:27:45 +0100
commitfdfe8f1d067bbc62037708d563b3686cc84fc4a7 (patch)
treeb1765b1e4044e8923de16a88aa02207ecac949b4 /src/dotty
parent1cf1ee2fbe2f56cf404d157825a956aa0956405f (diff)
downloaddotty-fdfe8f1d067bbc62037708d563b3686cc84fc4a7.tar.gz
dotty-fdfe8f1d067bbc62037708d563b3686cc84fc4a7.tar.bz2
dotty-fdfe8f1d067bbc62037708d563b3686cc84fc4a7.zip
Avoiding redundant tuple formations.
In a case like val (x, y) = if (...) (a, b) else (c, d) we can pass the tuples directly. Previously, this would have been translated to val (x, y) = (if (...) (a, b) else (c, d): @unchecked) match { case (s, t) => (s, t) }
Diffstat (limited to 'src/dotty')
-rw-r--r--src/dotty/tools/dotc/ast/Desugar.scala8
-rw-r--r--src/dotty/tools/dotc/ast/TreeInfo.scala10
2 files changed, 17 insertions, 1 deletions
diff --git a/src/dotty/tools/dotc/ast/Desugar.scala b/src/dotty/tools/dotc/ast/Desugar.scala
index b74b455eb..54d668193 100644
--- a/src/dotty/tools/dotc/ast/Desugar.scala
+++ b/src/dotty/tools/dotc/ast/Desugar.scala
@@ -355,9 +355,15 @@ object desugar {
case _ =>
val rhsUnchecked = makeAnnotated(defn.UncheckedAnnot, rhs)
val vars = getVariables(pat)
+ val isMatchingTuple: Tree => Boolean = {
+ case Tuple(es) => es.length == vars.length
+ case _ => false
+ }
val ids = for ((named, _) <- vars) yield Ident(named.name)
val caseDef = CaseDef(pat, EmptyTree, makeTuple(ids))
- val matchExpr = Match(rhsUnchecked, caseDef :: Nil)
+ val matchExpr =
+ if (forallResults(rhs, isMatchingTuple)) rhs
+ else Match(rhsUnchecked, caseDef :: Nil)
vars match {
case Nil =>
matchExpr
diff --git a/src/dotty/tools/dotc/ast/TreeInfo.scala b/src/dotty/tools/dotc/ast/TreeInfo.scala
index 29ff492d4..e1715ae26 100644
--- a/src/dotty/tools/dotc/ast/TreeInfo.scala
+++ b/src/dotty/tools/dotc/ast/TreeInfo.scala
@@ -260,6 +260,16 @@ trait TreeInfo[T >: Untyped] { self: Trees.Instance[T] =>
case Bind(_, y) => unbind(y)
case y => y
}
+
+ /** Checks whether predicate `p` is true for all result parts of this epression,
+ * where we zoom into Ifs, Matches, and Blocks.
+ */
+ def forallResults(tree: Tree, p: Tree => Boolean): Boolean = tree match {
+ case If(_, thenp, elsep) => forallResults(thenp, p) && forallResults(elsep, p)
+ case Match(_, cases) => cases forall (c => forallResults(c.body, p))
+ case Block(_, expr) => forallResults(expr, p)
+ case _ => p(tree)
+ }
}
trait TypedTreeInfo extends TreeInfo[Type] {self: Trees.Instance[Type] =>