@@ -913,16 +913,34 @@ object desugar {
913913 case IdPattern (named, tpt) =>
914914 derivedValDef(original, named, tpt, rhs, mods)
915915 case _ =>
916- val rhsUnchecked = makeAnnotated(" scala.unchecked" , rhs)
917- val vars = getVariables(pat)
916+ def isTuplePattern (arity : Int ): Boolean = pat match {
917+ case Tuple (pats) if pats.size == arity =>
918+ pats.forall(id => id.isInstanceOf [Ident ] && isVarPattern(id))
919+ case _ => false
920+ }
918921 val isMatchingTuple : Tree => Boolean = {
919- case Tuple (es) => es.length == vars.length
922+ case Tuple (es) => isTuplePattern( es.length)
920923 case _ => false
921924 }
925+
926+ // We can only optimize `val pat = if (...) e1 else e2` if:
927+ // - `e1` and `e2` are both tuples of arity N
928+ // - `pat` is a tuple of N variables or wildcard patterns like `(x1, x2, ..., xN)`
929+ val tupleOptimizable = forallResults(rhs, isMatchingTuple)
930+
931+ val rhsUnchecked = makeAnnotated(" scala.unchecked" , rhs)
932+ val vars =
933+ if (tupleOptimizable) // include `_`
934+ pat match {
935+ case Tuple (pats) =>
936+ pats.map { case id : Ident => id -> TypeTree () }
937+ }
938+ else getVariables(pat) // no `_`
939+
922940 val ids = for ((named, _) <- vars) yield Ident (named.name)
923941 val caseDef = CaseDef (pat, EmptyTree , makeTuple(ids))
924942 val matchExpr =
925- if (forallResults(rhs, isMatchingTuple) ) rhs
943+ if (tupleOptimizable ) rhs
926944 else Match (rhsUnchecked, caseDef :: Nil )
927945 vars match {
928946 case Nil =>
@@ -938,7 +956,7 @@ object desugar {
938956 .withSpan(pat.span.union(rhs.span)).withMods(patMods)
939957 def selector (n : Int ) = Select (Ident (tmpName), nme.selectorName(n))
940958 val restDefs =
941- for (((named, tpt), n) <- vars.zipWithIndex)
959+ for (((named, tpt), n) <- vars.zipWithIndex if named.name != nme. WILDCARD )
942960 yield
943961 if (mods is Lazy ) derivedDefDef(original, named, tpt, selector(n), mods &~ Lazy )
944962 else derivedValDef(original, named, tpt, selector(n), mods)
0 commit comments