@@ -939,16 +939,34 @@ object desugar {
939939 case IdPattern (named, tpt) =>
940940 derivedValDef(original, named, tpt, rhs, mods)
941941 case _ =>
942- val rhsUnchecked = makeAnnotated(" scala.unchecked" , rhs)
943- val vars = getVariables(pat)
942+ def isTuplePattern (arity : Int ): Boolean = pat match {
943+ case Tuple (pats) if pats.size == arity =>
944+ pats.forall(isVarPattern)
945+ case _ => false
946+ }
944947 val isMatchingTuple : Tree => Boolean = {
945- case Tuple (es) => es.length == vars.length
948+ case Tuple (es) => isTuplePattern( es.length)
946949 case _ => false
947950 }
951+
952+ // We can only optimize `val pat = if (...) e1 else e2` if:
953+ // - `e1` and `e2` are both tuples of arity N
954+ // - `pat` is a tuple of N variables or wildcard patterns like `(x1, x2, ..., xN)`
955+ val tupleOptimizable = forallResults(rhs, isMatchingTuple)
956+
957+ def rhsUnchecked = makeAnnotated(" scala.unchecked" , rhs)
958+ val vars =
959+ if (tupleOptimizable) // include `_`
960+ pat match {
961+ case Tuple (pats) =>
962+ pats.map { case id : Ident => id -> TypeTree () }
963+ }
964+ else getVariables(pat) // no `_`
965+
948966 val ids = for ((named, _) <- vars) yield Ident (named.name)
949967 val caseDef = CaseDef (pat, EmptyTree , makeTuple(ids))
950968 val matchExpr =
951- if (forallResults(rhs, isMatchingTuple) ) rhs
969+ if (tupleOptimizable ) rhs
952970 else Match (rhsUnchecked, caseDef :: Nil )
953971 vars match {
954972 case Nil =>
@@ -964,7 +982,7 @@ object desugar {
964982 .withSpan(pat.span.union(rhs.span)).withMods(patMods)
965983 def selector (n : Int ) = Select (Ident (tmpName), nme.selectorName(n))
966984 val restDefs =
967- for (((named, tpt), n) <- vars.zipWithIndex)
985+ for (((named, tpt), n) <- vars.zipWithIndex if named.name != nme. WILDCARD )
968986 yield
969987 if (mods is Lazy ) derivedDefDef(original, named, tpt, selector(n), mods &~ Lazy )
970988 else derivedValDef(original, named, tpt, selector(n), mods)
0 commit comments