================================================================================
The unit type
================================================================================

type A = ();

--------------------------------------------------------------------------------

(source_file
  (type_item
    (type_identifier)
    (unit_type)))

================================================================================
Tuple types
================================================================================

type A = (i32, String);

--------------------------------------------------------------------------------

(source_file
  (type_item
    (type_identifier)
    (tuple_type
      (primitive_type)
      (type_identifier))))

================================================================================
Reference types
================================================================================

type A = &B;
type C = &'a str;
type D = &'a mut str;

--------------------------------------------------------------------------------

(source_file
  (type_item
    (type_identifier)
    (reference_type
      (type_identifier)))
  (type_item
    (type_identifier)
    (reference_type
      (lifetime
        (identifier))
      (primitive_type)))
  (type_item
    (type_identifier)
    (reference_type
      (lifetime
        (identifier))
      (mutable_specifier)
      (primitive_type))))

================================================================================
Raw pointer types
================================================================================

type A = *mut B;
type C = *const str;

--------------------------------------------------------------------------------

(source_file
  (type_item
    (type_identifier)
    (pointer_type
      (mutable_specifier)
      (type_identifier)))
  (type_item
    (type_identifier)
    (pointer_type
      (primitive_type))))

================================================================================
Generic types
================================================================================

type A = B<C>;
type D = E<F, str>;
type G = H<'a, I>;
type J = H<K=L>;

--------------------------------------------------------------------------------

(source_file
  (type_item
    (type_identifier)
    (generic_type
      (type_identifier)
      (type_arguments
        (type_identifier))))
  (type_item
    (type_identifier)
    (generic_type
      (type_identifier)
      (type_arguments
        (type_identifier)
        (primitive_type))))
  (type_item
    (type_identifier)
    (generic_type
      (type_identifier)
      (type_arguments
        (lifetime
          (identifier))
        (type_identifier))))
  (type_item
    (type_identifier)
    (generic_type
      (type_identifier)
      (type_arguments
        (type_binding
          (type_identifier)
          (type_identifier))))))

================================================================================
Scoped types
================================================================================

type A = B::C;
type D = E::F::G;
type H = I::J<K>;
type L = M<N>::O;

--------------------------------------------------------------------------------

(source_file
  (type_item
    (type_identifier)
    (scoped_type_identifier
      (identifier)
      (type_identifier)))
  (type_item
    (type_identifier)
    (scoped_type_identifier
      (scoped_identifier
        (identifier)
        (identifier))
      (type_identifier)))
  (type_item
    (type_identifier)
    (generic_type
      (scoped_type_identifier
        (identifier)
        (type_identifier))
      (type_arguments
        (type_identifier))))
  (type_item
    (type_identifier)
    (scoped_type_identifier
      (generic_type
        (type_identifier)
        (type_arguments
          (type_identifier)))
      (type_identifier))))

================================================================================
Array types
================================================================================

type A = [B; 4];
type C = &[D];

--------------------------------------------------------------------------------

(source_file
  (type_item
    (type_identifier)
    (array_type
      (type_identifier)
      (integer_literal)))
  (type_item
    (type_identifier)
    (reference_type
      (array_type
        (type_identifier)))))

================================================================================
Function types
================================================================================

fn high_order1(value: i32, f: fn(i32)) -> i32 {}

fn high_order2(value: i32, f: fn(i32) -> i32) -> i32 {
    f(value)
}

fn high_order3(value: i32, f: &FnOnce(i32) -> i32) -> i32 {
    f(value)
}

type F = for<'a, 'b> fn(x: &'a A, y: &'a mut B<'i, 't>,) -> C;

--------------------------------------------------------------------------------

(source_file
  (function_item
    (identifier)
    (parameters
      (parameter
        (identifier)
        (primitive_type))
      (parameter
        (identifier)
        (function_type
          (parameters
            (primitive_type)))))
    (primitive_type)
    (block))
  (function_item
    (identifier)
    (parameters
      (parameter
        (identifier)
        (primitive_type))
      (parameter
        (identifier)
        (function_type
          (parameters
            (primitive_type))
          (primitive_type))))
    (primitive_type)
    (block
      (call_expression
        (identifier)
        (arguments
          (identifier)))))
  (function_item
    (identifier)
    (parameters
      (parameter
        (identifier)
        (primitive_type))
      (parameter
        (identifier)
        (reference_type
          (function_type
            (type_identifier)
            (parameters
              (primitive_type))
            (primitive_type)))))
    (primitive_type)
    (block
      (call_expression
        (identifier)
        (arguments
          (identifier)))))
  (type_item
    (type_identifier)
    (function_type
      (for_lifetimes
        (lifetime
          (identifier))
        (lifetime
          (identifier)))
      (parameters
        (parameter
          (identifier)
          (reference_type
            (lifetime
              (identifier))
            (type_identifier)))
        (parameter
          (identifier)
          (reference_type
            (lifetime
              (identifier))
            (mutable_specifier)
            (generic_type
              (type_identifier)
              (type_arguments
                (lifetime
                  (identifier))
                (lifetime
                  (identifier)))))))
      (type_identifier))))

================================================================================
Unsafe and extern function types
================================================================================

type a = extern "C" fn(*mut c_void);
type b = unsafe extern "C" fn() -> *mut c_void;

--------------------------------------------------------------------------------

(source_file
  (type_item
    (type_identifier)
    (function_type
      (function_modifiers
        (extern_modifier
          (string_literal)))
      (parameters
        (pointer_type
          (mutable_specifier)
          (type_identifier)))))
  (type_item
    (type_identifier)
    (function_type
      (function_modifiers
        (extern_modifier
          (string_literal)))
      (parameters)
      (pointer_type
        (mutable_specifier)
        (type_identifier)))))

================================================================================
Trait objects
================================================================================

type a = Box<Something + 'a>;
type b = Rc<dyn Something>;
type c = A<&dyn Fn(&B) -> C>;

--------------------------------------------------------------------------------

(source_file
  (type_item
    (type_identifier)
    (generic_type
      (type_identifier)
      (type_arguments
        (bounded_type
          (type_identifier)
          (lifetime
            (identifier))))))
  (type_item
    (type_identifier)
    (generic_type
      (type_identifier)
      (type_arguments
        (dynamic_type
          (type_identifier)))))
  (type_item
    (type_identifier)
    (generic_type
      (type_identifier)
      (type_arguments
        (reference_type
          (dynamic_type
            (function_type
              (type_identifier)
              (parameters
                (reference_type
                  (type_identifier)))
              (type_identifier))))))))

================================================================================
Type cast expressions with generics
================================================================================

a as B<C>;
d as *mut E<<F as E>::G>;

--------------------------------------------------------------------------------

(source_file
  (expression_statement
    (type_cast_expression
      (identifier)
      (generic_type
        (type_identifier)
        (type_arguments
          (type_identifier)))))
  (expression_statement
    (type_cast_expression
      (identifier)
      (pointer_type
        (mutable_specifier)
        (generic_type
          (type_identifier)
          (type_arguments
            (scoped_type_identifier
              (bracketed_type
                (qualified_type
                  (type_identifier)
                  (type_identifier)))
              (type_identifier))))))))
