E024: Illegal Variable In Pattern Alternative

This error is emitted when a variable binding is used in a pattern alternative (|). Variables are not allowed in alternative patterns.

When you use the | operator to combine patterns, each alternative must match independently, and Scala cannot guarantee that a variable bound in one alternative would have the same value or even be bound in another alternative.


Example

def test(pair: (Int, Int)): Int = pair match
  case (1, n) | (n, 1) => n
  case _ => 0

Error

-- [E024] Syntax Error: example.scala:2:11 -------------------------------------
2 |  case (1, n) | (n, 1) => n
  |           ^
  |           Illegal variable n in pattern alternative
  |-----------------------------------------------------------------------------
  | Explanation (enabled by `-explain`)
  |- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  | Variables are not allowed within alternate pattern matches. You can workaround
  | this issue by adding additional cases for each alternative. For example, the
  | illegal function:
  |
  | def g(pair: (Int,Int)): Int = pair match {
  |   case (1, n) | (n, 1) => n
  |   case _ => 0
  | }
  | could be implemented by moving each alternative into a separate case:
  |
  | def g(pair: (Int,Int)): Int = pair match {
  |   case (1, n) => n
  |   case (n, 1) => n
  |   case _ => 0
  | }
   -----------------------------------------------------------------------------
-- [E024] Syntax Error: example.scala:2:17 -------------------------------------
2 |  case (1, n) | (n, 1) => n
  |                 ^
  |                 Illegal variable n in pattern alternative
  |-----------------------------------------------------------------------------
  | Explanation (enabled by `-explain`)
  |- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  | Variables are not allowed within alternate pattern matches. You can workaround
  | this issue by adding additional cases for each alternative. For example, the
  | illegal function:
  |
  | def g(pair: (Int,Int)): Int = pair match {
  |   case (1, n) | (n, 1) => n
  |   case _ => 0
  | }
  | could be implemented by moving each alternative into a separate case:
  |
  | def g(pair: (Int,Int)): Int = pair match {
  |   case (1, n) => n
  |   case (n, 1) => n
  |   case _ => 0
  | }
   -----------------------------------------------------------------------------

Solution

// Split into separate cases
def test(pair: (Int, Int)): Int = pair match
  case (1, n) => n
  case (n, 1) => n
  case _ => 0
// Use wildcards if you don't need the value
def isEdge(pair: (Int, Int)): Boolean = pair match
  case (1, _) | (_, 1) => true
  case _ => false
// Use a guard for more complex conditions
def test(pair: (Int, Int)): Int = pair match
  case (a, b) if a == 1 || b == 1 => if a == 1 then b else a
  case _ => 0