=================================
Tuple struct patterns
=================================

match x {
  Some(x) => "some",
  std::None() => "none"
}

---

(source_file
  (match_expression (identifier) (match_block
    (match_arm
      (match_pattern (tuple_struct_pattern (identifier) (identifier)))
      (string_literal))
    (match_arm
      (match_pattern (tuple_struct_pattern (scoped_identifier (identifier) (identifier))))
      (string_literal)))))

=================================
Reference patterns
=================================

match x {
  A(ref x) => x.0,
  ref mut y => y,
  & mut  z => z,
}

---

(source_file
  (match_expression (identifier) (match_block
    (match_arm
      (match_pattern (tuple_struct_pattern (identifier) (ref_pattern (identifier))))
      (field_expression (identifier) (integer_literal)))
    (match_arm
      (match_pattern (ref_pattern (mut_pattern (mutable_specifier) (identifier))))
      (identifier))
    (match_arm
      (match_pattern (reference_pattern (mutable_specifier) (identifier)))
      (identifier)))))

=================================
Struct patterns
=================================

match x {
  Person{name, age} if age < 5 => ("toddler", name),
  Person{name: adult_name, age: _} => ("adult", adult_name),
}

---

(source_file
  (match_expression (identifier) (match_block
    (match_arm
      (match_pattern (struct_pattern
        (type_identifier)
        (field_pattern (shorthand_field_identifier))
        (field_pattern (shorthand_field_identifier)))
        (binary_expression (identifier) (integer_literal)))
      (tuple_expression (string_literal) (identifier)))
    (match_arm
      (match_pattern
        (struct_pattern
          (type_identifier)
          (field_pattern (field_identifier) (identifier))
          (field_pattern (field_identifier))))
      (tuple_expression (string_literal) (identifier))))))

=================================
Ignored patterns
=================================

match x {
  (a, ..) => a,
  B(..) => c,
  D::E{f: g, ..} => g
}

---

(source_file
  (match_expression (identifier) (match_block
    (match_arm
      (match_pattern
        (tuple_pattern (identifier) (remaining_field_pattern)))
      (identifier))
    (match_arm
      (match_pattern
        (tuple_struct_pattern (identifier) (remaining_field_pattern)))
      (identifier))
    (match_arm
      (match_pattern
        (struct_pattern
          (scoped_type_identifier (identifier) (type_identifier))
          (field_pattern (field_identifier) (identifier))
          (remaining_field_pattern)))
      (identifier)))))

=================================
Captured patterns
=================================

match x {
  a @ A(_) | b @ B(..) => a,
  a @ 1 ... 5 => a,
  Some(1 ... 5) => a,
  a @ b...c => a,
  a @ b..=c => a,
}

---

(source_file
  (match_expression
    value: (identifier)
    body: (match_block
      (match_arm
        pattern: (match_pattern
          (or_pattern
            (captured_pattern
              (identifier)
              (tuple_struct_pattern
                type: (identifier)))
            (captured_pattern
              (identifier)
              (tuple_struct_pattern
                type: (identifier)
                (remaining_field_pattern)))))
        value: (identifier))
      (match_arm
        pattern: (match_pattern
          (captured_pattern
            (identifier)
            (range_pattern
              (integer_literal)
              (integer_literal))))
        value: (identifier))
      (match_arm
        pattern: (match_pattern
          (tuple_struct_pattern
            type: (identifier)
            (range_pattern
              (integer_literal)
              (integer_literal))))
        value: (identifier))
      (match_arm
        pattern: (match_pattern
          (captured_pattern
            (identifier)
            (range_pattern
              (identifier)
              (identifier))))
        value: (identifier))
      (match_arm
        pattern: (match_pattern
          (captured_pattern
            (identifier)
            (range_pattern
              (identifier)
              (identifier))))
        value: (identifier)))))

=================================
Or patterns
=================================

if let A(x) | B(x) = expr {
    do_stuff_with(x);
}

while let A(x) | B(x) = expr {
    do_stuff_with(x);
}

let Ok(index) | Err(index) = slice.binary_search(&x);

for ref a | b in c {}

let Ok(x) | Err(x) = binary_search(x);

for A | B | C in c {}

|(Ok(x) | Err(x))| expr();

let ref mut x @ (A | B | C);

fn foo((1 | 2 | 3): u8) {}

// Discomment after box pattern land on master
// let box (A | B | C);

// Not handled cause devs didn't got into agreement if should be acceptd or not
// |Ok(x) | Err(x)| expr();

---

(source_file
  (if_let_expression
    pattern: (or_pattern
      (tuple_struct_pattern
        type: (identifier)
        (identifier))
      (tuple_struct_pattern
        type: (identifier)
        (identifier)))
    value: (identifier)
    consequence: (block
      (call_expression
        function: (identifier)
        arguments: (arguments
          (identifier)))))
  (while_let_expression
    pattern: (or_pattern
      (tuple_struct_pattern
        type: (identifier)
        (identifier))
      (tuple_struct_pattern
        type: (identifier)
        (identifier)))
    value: (identifier)
    body: (block
      (call_expression
        function: (identifier)
        arguments: (arguments
          (identifier)))))
  (let_declaration
    pattern: (or_pattern
      (tuple_struct_pattern
        type: (identifier)
        (identifier))
      (tuple_struct_pattern
        type: (identifier)
        (identifier)))
    value: (call_expression
      function: (field_expression
        value: (identifier)
        field: (field_identifier))
      arguments: (arguments
        (reference_expression
          value: (identifier)))))
  (for_expression
    pattern: (or_pattern
      (ref_pattern
        (identifier))
      (identifier))
    value: (identifier)
    body: (block))
  (let_declaration
    pattern: (or_pattern
      (tuple_struct_pattern
        type: (identifier)
        (identifier))
      (tuple_struct_pattern
        type: (identifier)
        (identifier)))
    value: (call_expression
      function: (identifier)
      arguments: (arguments
        (identifier))))
  (for_expression
    pattern: (or_pattern
      (or_pattern
        (identifier)
        (identifier))
      (identifier))
    value: (identifier)
    body: (block))
  (closure_expression
    parameters: (closure_parameters
      (tuple_pattern
        (or_pattern
          (tuple_struct_pattern
            type: (identifier)
            (identifier))
          (tuple_struct_pattern
            type: (identifier)
            (identifier)))))
    body: (call_expression
      function: (identifier)
      arguments: (arguments)))
  (let_declaration
    pattern: (ref_pattern
      (mut_pattern
        (mutable_specifier)
        (captured_pattern
          (identifier)
          (tuple_pattern
            (or_pattern
              (or_pattern
                (identifier)
                (identifier))
              (identifier)))))))
  (function_item
    name: (identifier)
    parameters: (parameters
      (parameter
        pattern: (tuple_pattern
          (or_pattern
            (or_pattern
              (integer_literal)
              (integer_literal))
            (integer_literal)))
        type: (primitive_type)))
    body: (block))
  (line_comment)
  (line_comment)
  (line_comment)
  (line_comment))

===========================================
Inline const or Const blocks as pattern
===========================================

fn foo(x: i32) {
    const CUBE: i32 = 3.pow(3);
    match x {
        CUBE => println!("three cubed"),
        _ => {}
    }
}

fn foo(x: i32) {
    match x {
        const { 3.pow(3) } => println!("three cubed"),
        _ => {}
    }
}

---

(source_file
  (function_item
    name: (identifier)
    parameters: (parameters
      (parameter
        pattern: (identifier)
        type: (primitive_type)))
    body: (block
      (const_item
        name: (identifier)
        type: (primitive_type)
        value: (call_expression
          function: (field_expression
            value: (integer_literal)
            field: (field_identifier))
          arguments: (arguments
            (integer_literal))))
      (match_expression
        value: (identifier)
        body: (match_block
          (match_arm
            pattern: (match_pattern
              (identifier))
            value: (macro_invocation
              macro: (identifier)
              (token_tree
                (string_literal))))
          (match_arm
            pattern: (match_pattern)
            value: (block))))))
  (function_item
    name: (identifier)
    parameters: (parameters
      (parameter
        pattern: (identifier)
        type: (primitive_type)))
    body: (block
      (match_expression
        value: (identifier)
        body: (match_block
          (match_arm
            pattern: (match_pattern
              (const_block
                body: (block
                  (call_expression
                    function: (field_expression
                      value: (integer_literal)
                      field: (field_identifier))
                    arguments: (arguments
                      (integer_literal))))))
            value: (macro_invocation
              macro: (identifier)
              (token_tree
                (string_literal))))
          (match_arm
            pattern: (match_pattern)
            value: (block)))))))