diff options
author | Martin Odersky <odersky@gmail.com> | 2013-12-27 16:27:39 +0100 |
---|---|---|
committer | Martin Odersky <odersky@gmail.com> | 2013-12-27 16:27:45 +0100 |
commit | fdfe8f1d067bbc62037708d563b3686cc84fc4a7 (patch) | |
tree | b1765b1e4044e8923de16a88aa02207ecac949b4 /src/dotty | |
parent | 1cf1ee2fbe2f56cf404d157825a956aa0956405f (diff) | |
download | dotty-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.scala | 8 | ||||
-rw-r--r-- | src/dotty/tools/dotc/ast/TreeInfo.scala | 10 |
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] => |